From: abn Date: Fri, 11 Dec 2015 14:42:51 +0000 (+0100) Subject: Removing separated medtool sources. X-Git-Tag: V8_0_0a1~5^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=096deaf22f2d333579eca53e41365f4633596965;p=modules%2Fmed.git Removing separated medtool sources. --- diff --git a/medtool/CMakeLists.txt b/medtool/CMakeLists.txt deleted file mode 100644 index 0bf0392c2..000000000 --- a/medtool/CMakeLists.txt +++ /dev/null @@ -1,310 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.2 FATAL_ERROR) -#INCLUDE(CMakeDependentOption) -PROJECT(MEDCoupling C CXX) - -# Ensure a proper linker behavior: -CMAKE_POLICY(SET CMP0003 NEW) - -# Versioning -# =========== -# Project name, upper case -STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) - -SET(${PROJECT_NAME_UC}_MAJOR_VERSION 1) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 0) -SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) -SET(${PROJECT_NAME_UC}_VERSION - ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) -SET(${PROJECT_NAME_UC}_VERSION_DEV 1) - -# Our own set of macros: -LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_files") -INCLUDE(MEDCouplingMacros) - -# -# User options -# ============ -INCLUDE(CMakeDependentOption) -OPTION(MEDCOUPLING_MED_MICROMED "Build MED without MED file dependancy." OFF) -OPTION(MEDCOUPLING_MED_ENABLE_PYTHON "Build PYTHON bindings." ON) -OPTION(MEDCOUPLING_MED_ENABLE_PARTITIONER "Build MEDPartitioner." ON) -OPTION(MEDCOUPLING_MED_ENABLE_RENUMBER "Build Renumber." ON) -OPTION(MEDCOUPLING_MED_WITH_FILE_EXAMPLES "Install examples of files containing meshes and fields of different formats." ON) -OPTION(MEDCOUPLING_USE_MPI "(Use MPI containers) - For MED this triggers the build of ParaMEDMEM." OFF) -OPTION(MEDCOUPLING_BUILD_TESTS "Build MED tests." ON) -OPTION(MEDCOUPLING_BUILD_DOC "Build MED doc." ON) -CMAKE_DEPENDENT_OPTION(MEDCOUPLING_MED_PARTITIONER_METIS "Enable metis graph library in MEDPartitioner." ON "MEDCOUPLING_MED_ENABLE_PARTITIONER" OFF) -CMAKE_DEPENDENT_OPTION(MEDCOUPLING_MED_PARTITIONER_SCOTCH "Enable scotch graph library in MEDPartitioner." ON "MEDCOUPLING_MED_ENABLE_PARTITIONER;NOT MEDCOUPLING_USE_MPI" OFF) -CMAKE_DEPENDENT_OPTION(MEDCOUPLING_MED_PARTITIONER_PARMETIS "Enable parmetis graph library in MEDPartitioner." ON "MEDCOUPLING_MED_ENABLE_PARTITIONER;MEDCOUPLING_USE_MPI" OFF) -IF(WIN32) - CMAKE_DEPENDENT_OPTION(MEDCOUPLING_MED_MEDLOADER_USE_XDR "Enable use of XDR for SauvReader." ON "NOT MEDCOUPLING_MED_MICROMED" OFF) -ENDIF(WIN32) - -# -# Set list of prerequisites -# ========================= - -IF(NOT MEDCOUPLING_MED_MICROMED) - FIND_PACKAGE(HDF5 REQUIRED) - FIND_PACKAGE(MEDFile REQUIRED) - # XDR stuff - IF(NOT WIN32) - FIND_PACKAGE(XDR REQUIRED) - ELSE(NOT WIN32) - IF(MEDCOUPLING_MED_MEDLOADER_USE_XDR) - FIND_PACKAGE(XDR REQUIRED) - ENDIF(MEDCOUPLING_MED_MEDLOADER_USE_XDR) - ENDIF(NOT WIN32) - # End of XDR Stuff - IF(MEDCOUPLING_MED_ENABLE_PARTITIONER) - IF(DEFINED ENV{LIBXML2_ROOT_DIR}) - SET(LIBXML2_ROOT_DIR $ENV{LIBXML2_ROOT_DIR} CACHE PATH "Path to the LibXml2.") - LIST(APPEND CMAKE_PREFIX_PATH "${LIBXML2_ROOT_DIR}") - ENDIF() - FIND_PACKAGE(LibXml2) - IF(MEDCOUPLING_MED_PARTITIONER_METIS) - FIND_PACKAGE(Metis) - ADD_DEFINITIONS("-DMED_ENABLE_METIS") - ENDIF(MEDCOUPLING_MED_PARTITIONER_METIS) - IF(MEDCOUPLING_MED_PARTITIONER_SCOTCH) - FIND_PACKAGE(Scotch) - ADD_DEFINITIONS("-DMED_ENABLE_SCOTCH") - ENDIF(MEDCOUPLING_MED_PARTITIONER_SCOTCH) - ENDIF(MEDCOUPLING_MED_ENABLE_PARTITIONER) -ENDIF(NOT MEDCOUPLING_MED_MICROMED) - -ENABLE_TESTING() # let it outsite because even if MEDCOUPLING_BUILD_TESTS is OFF, python tests that not need additional compilation can be run. - -IF(MEDCOUPLING_BUILD_TESTS) - FIND_PACKAGE(CppUnit) -ENDIF(MEDCOUPLING_BUILD_TESTS) - -IF(MEDCOUPLING_USE_MPI) - FIND_PACKAGE(MPI REQUIRED) - ADD_DEFINITIONS("-DHAVE_MPI") - SET(MPI_INCLUDE_DIRS ${MPI_C_INCLUDE_PATH} ${MPI_CXX_INCLUDE_PATH}) - SET(MPI_LIBRARIES ${MPI_C_LIBRARIES} ${MPI_CXX_LIBRARIES}) - SET(MPI_DEFINITIONS "${MPI_CXX_COMPILE_FLAGS}") - - IF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) - FIND_PACKAGE(ParMetis) - ADD_DEFINITIONS("-DMED_ENABLE_PARMETIS") - ENDIF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) -ENDIF(MEDCOUPLING_USE_MPI) - -IF(MEDCOUPLING_MED_ENABLE_RENUMBER) - IF(DEFINED ENV{BOOST_ROOT_DIR}) - SET(BOOST_ROOT_DIR $ENV{BOOST_ROOT_DIR} CACHE PATH "Path to the Boost.") - LIST(APPEND CMAKE_PREFIX_PATH "${BOOST_ROOT_DIR}") - ENDIF() - SET(Boost_USE_STATIC_LIBS OFF) - SET(Boost_USE_MULTITHREADED ON) - SET(Boost_USE_STATIC_RUNTIME OFF) - SET(Boost_NO_BOOST_CMAKE ON) - FIND_PACKAGE(Boost) -ENDIF(MEDCOUPLING_MED_ENABLE_RENUMBER) - -IF(MEDCOUPLING_BUILD_DOC) - FIND_PACKAGE(Doxygen) - FIND_PACKAGE(Graphviz) - FIND_PACKAGE(Sphinx) -ENDIF(MEDCOUPLING_BUILD_DOC) - -IF(MEDCOUPLING_MED_ENABLE_PYTHON) - FIND_PACKAGE(PythonInterp) - GET_FILENAME_COMPONENT(_python_dir "${PYTHON_EXECUTABLE}" PATH) - GET_FILENAME_COMPONENT(CMAKE_INCLUDE_PATH "${_python_dir}/../include/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" ABSOLUTE) - GET_FILENAME_COMPONENT(CMAKE_LIBRARY_PATH "${_python_dir}/../lib" ABSOLUTE) - SET(PythonLibs_FIND_VERSION "${PYTHON_VERSION}") - FIND_PACKAGE(PythonLibs) - - FIND_PACKAGE(SWIG) - # Set the extra flags for SWIG for numpy and scipy - SET(SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY) - IF(NUMPY_FOUND) - SET(SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY "-DWITH_NUMPY") - ENDIF(NUMPY_FOUND) - IF(SCIPY_FOUND) - SET(SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITH_SCIPY") - ENDIF(SCIPY_FOUND) -ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - -# Directories -# -# Directories have to be given after prerequisites (to be able to use -# Python version string for example). -# =========== -SET(MEDCOUPLING_INSTALL_BINS bin CACHE PATH "Install path: MEDCoupling binaries") -SET(MEDCOUPLING_INSTALL_LIBS lib CACHE PATH "Install path: MEDCoupling libs") -SET(MEDCOUPLING_INSTALL_HEADERS include CACHE PATH "Install path: MEDCoupling headers") -SET(MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS ${MEDCOUPLING_INSTALL_BINS} CACHE PATH "Install path: MEDCoupling scripts") -SET(MEDCOUPLING_INSTALL_TESTS tests CACHE PATH "Install path: MEDCoupling tests") -# SET(MEDCOUPLING_INSTALL_SCRIPT_DATA ${MEDCOUPLING_INSTALL_BINS} CACHE PATH "Install path: MEDCoupling script data") -SET(MEDCOUPLING_INSTALL_SCRIPT_PYTHON ${MEDCOUPLING_INSTALL_BINS} CACHE PATH "Install path: MEDCoupling Python scripts") -SET(MEDCOUPLING_INSTALL_CMAKE_LOCAL cmake_files CACHE PATH "Install path: local MEDCoupling CMake files") - -IF(MEDCOUPLING_MED_ENABLE_PYTHON) - SET(_pydir lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) - SET(MEDCOUPLING_INSTALL_PYTHON ${_pydir} CACHE PATH "Install path: MEDCoupling Python stuff") - SET(MEDCOUPLING_INSTALL_PYTHON_SHARED ${MEDCOUPLING_INSTALL_PYTHON}/shared_modules CACHE PATH - "Install path: MEDCoupling Python shared modules") -ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - -SET(MEDCOUPLING_INSTALL_RES share/resources CACHE PATH "Install path: MEDCoupling resources") -SET(MEDCOUPLING_INSTALL_DOC share/doc CACHE PATH "Install path: MEDCoupling documentation") - -# Med specific: - -SET(MEDCOUPLING_INSTALL_RES_DATA "${MEDCOUPLING_INSTALL_RES}/med" CACHE PATH "Install path: MEDCoupling specific data") -#SET(MEDCOUPLING_MED_INSTALL_RES_SCRIPTS "${MEDCOUPLING_INSTALL_RES}/med" CACHE PATH "Install path: MEDCouplng specific scripts") - -MARK_AS_ADVANCED(MEDCOUPLING_INSTALL_BINS MEDCOUPLING_INSTALL_LIBS MEDCOUPLING_INSTALL_IDLS MEDCOUPLING_INSTALL_HEADERS) -MARK_AS_ADVANCED(MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS MEDCOUPLING_INSTALL_SCRIPT_DATA MEDCOUPLING_INSTALL_SCRIPT_PYTHON) -MARK_AS_ADVANCED(MEDCOUPLING_INSTALL_APPLISKEL_SCRIPTS MEDCOUPLING_INSTALL_APPLISKEL_PYTHON MEDCOUPLING_INSTALL_CMAKE MEDCOUPLING_INSTALL_CMAKE_LOCAL MEDCOUPLING_INSTALL_RES) -MARK_AS_ADVANCED(MEDCOUPLING_INSTALL_PYTHON MEDCOUPLING_INSTALL_PYTHON_SHARED MEDCOUPLING_MED_INSTALL_RES_DATA MEDCOUPLING_MED_INSTALL_RES_SCRIPTS MEDCOUPLING_INSTALL_DOC) - -# Header configuration -# ==================== -MEDCOUPLING_XVERSION(${PROJECT_NAME}) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/MEDCoupling_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling_version.h) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling_version.h DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -# Accumulate environment variables for MED module -#SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${MEDCOUPLING_INSTALL_BINS} -# ${CMAKE_INSTALL_PREFIX}/${MEDCOUPLING_INSTALL_PYTHON}) -#SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${MEDCOUPLING_INSTALL_LIBS}) - - -# Sources -# ======== -IF(WIN32) - ADD_DEFINITIONS("-D_USE_MATH_DEFINES") -ENDIF(WIN32) - -ADD_SUBDIRECTORY(src) -ADD_SUBDIRECTORY(cmake_files) - -IF(MEDCOUPLING_BUILD_DOC) - ADD_SUBDIRECTORY(doc) -ENDIF(MEDCOUPLING_BUILD_DOC) - -IF(NOT MEDCOUPLING_MED_MICROMED) - IF(MEDCOUPLING_MED_WITH_FILE_EXAMPLES) - ADD_SUBDIRECTORY(resources) - ENDIF(MEDCOUPLING_MED_WITH_FILE_EXAMPLES) -ENDIF(NOT MEDCOUPLING_MED_MICROMED) - -# Configuration export -# ==================== - -# List of targets in this project we want to make visible to the rest of the world. -# They all have to be INSTALL'd with the option "EXPORT ${PROJECT_NAME}TargetGroup" -SET(_${PROJECT_NAME}_exposed_targets - interpkernel medcoupling medcouplingremapper) - -IF(NOT MEDCOUPLING_MED_MICROMED) - LIST(APPEND _${PROJECT_NAME}_exposed_targets medloader) - IF(MEDCOUPLING_MED_ENABLE_RENUMBER) - LIST(APPEND _${PROJECT_NAME}_exposed_targets renumbercpp) - ENDIF() - IF(MEDCOUPLING_MED_ENABLE_PARTITIONER) - LIST(APPEND _${PROJECT_NAME}_exposed_targets medpartitionercpp) - IF(MEDCOUPLING_BUILD_TESTS) - LIST(APPEND _${PROJECT_NAME}_exposed_targets MEDPARTITIONERTest) - ENDIF() - ENDIF() - IF(MEDCOUPLING_BUILD_TESTS) - LIST(APPEND _${PROJECT_NAME}_exposed_targets InterpKernelTest) - ENDIF() -ENDIF() - -IF(MEDCOUPLING_USE_MPI) - LIST(APPEND _${PROJECT_NAME}_exposed_targets paramedmem) - IF(NOT MEDCOUPLING_MED_MICROMED) - LIST(APPEND _${PROJECT_NAME}_exposed_targets paramedloader) - ENDIF() - IF(MEDCOUPLING_BUILD_TESTS) - IF(NOT MEDCOUPLING_MED_MICROMED) - LIST(APPEND _${PROJECT_NAME}_exposed_targets ParaMEDMEMTest) - ENDIF() - ENDIF() -ENDIF() - -# Add all targets to the build-tree export set - -EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets} - FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake) - -# Create the configuration files: -# - in the build tree: - -# Ensure the variables are always defined for the configure (even if empty): -# SET(KERNEL_ROOT_DIR "${KERNEL_ROOT_DIR}") -# SET(GUI_ROOT_DIR "${GUI_ROOT_DIR}") -# SET(MEDFILE_ROOT_DIR "${MEDFILE_ROOT_DIR}") -# SET(MPI_ROOT_DIR "${MPI_ROOT_DIR}") -# SET(HDF5_ROOT_DIR "${HDF5_ROOT_DIR}") -# SET(OMNIORB_ROOT_DIR "${OMNIORB_ROOT_DIR}") -# SET(PTHREAD_ROOT_DIR "${PTHREAD_ROOT_DIR}") -# SET(BOOST_ROOT_DIR "${BOOST_ROOT_DIR}") -# SET(SWIG_ROOT_DIR "${SWIG_ROOT_DIR}") -# SET(PYTHON_ROOT_DIR "${PYTHON_ROOT_DIR}") -# SET(CPPUNIT_ROOT_DIR "${CPPUNIT_ROOT_DIR}") -# SET(GRAPHVIZ_ROOT_DIR "${GRAPHVIZ_ROOT_DIR}") -# SET(DOXYGEN_ROOT_DIR "${DOXYGEN_ROOT_DIR}") -# SET(SPHINX_ROOT_DIR "${SPHINX_ROOT_DIR}") - -# SET(METIS_ROOT_DIR "${METIS_ROOT_DIR}") -# SET(PARMETIS_ROOT_DIR "${PARMETIS_ROOT_DIR}") -# SET(SCOTCH_ROOT_DIR "${SCOTCH_ROOT_DIR}") -# SET(XDR_ROOT_DIR "${XDR_ROOT_DIR}") - -# - in the install tree: -# Get the relative path of the include directory so -# we can register it in the generated configuration files: -SET(CONF_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}") - -# Build variables that will be expanded when configuring SalomeConfig.cmake: -# SALOME_CONFIGURE_PREPARE(Metis ParMetis Scotch XDR CAS Qt4 CppUnit Graphviz Doxygen Sphinx MPI omniORB -# PThread Boost libXml2 Python HDF5 MEDFile) - -# INCLUDE(CMakePackageConfigHelpers) -# CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in -# ${PROJECT_BINARY_DIR}/to_install/${PROJECT_NAME}Config.cmake -# INSTALL_DESTINATION "${MEDCOUPLING_INSTALL_CMAKE}_LOCAL" -# PATH_VARS CONF_INCLUDE_DIRS MEDCOUPLING_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX -# KERNEL_ROOT_DIR GUI_ROOT_DIR MEDFILE_ROOT_DIR MPI_ROOT_DIR -# HDF5_ROOT_DIR OMNIORB_ROOT_DIR PTHREAD_ROOT_DIR BOOST_ROOT_DIR -# SWIG_ROOT_DIR PYTHON_ROOT_DIR CPPUNIT_ROOT_DIR GRAPHVIZ_ROOT_DIR DOXYGEN_ROOT_DIR -# SPHINX_ROOT_DIR METIS_ROOT_DIR PARMETIS_ROOT_DIR SCOTCH_ROOT_DIR XDR_ROOT_DIR) - -#WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake -# VERSION ${${PROJECT_NAME_UC}_VERSION} -# COMPATIBILITY AnyNewerVersion) - -# Install the CMake configuration files: -# INSTALL(FILES -# "${PROJECT_BINARY_DIR}/to_install/${PROJECT_NAME}Config.cmake" -# "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" -# DESTINATION "${MEDCOUPLING_INSTALL_CMAKE_LOCAL}") - -# Install the export set for use with the install-tree -#INSTALL(EXPORT ${PROJECT_NAME}TargetGroup DESTINATION "${MEDCOUPLING_INSTALL_CMAKE_LOCAL}" -# FILE ${PROJECT_NAME}Targets.cmake) diff --git a/medtool/MEDCoupling_version.h.in b/medtool/MEDCoupling_version.h.in deleted file mode 100644 index e81ace123..000000000 --- a/medtool/MEDCoupling_version.h.in +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#if !defined(__MEDCOUPLING_VERSION_H__) -#define __MEDCOUPLING_VERSION_H__ - -/*! - Specify version of MEDCoupling, as follows - - MEDCOUPLING_VERSION_MAJOR : (integer) number identifying major version - MEDCOUPLING_VERSION_MINOR : (integer) number identifying minor version - MEDCOUPLING_VERSION_MAINTENANCE : (integer) number identifying maintenance version - MEDCOUPLING_VERSION_STR : (string) complete version number "major.minor.maintenance" - MEDCOUPLING_VERSION : (hex) complete version number (major << 16) + (minor << 8) + maintenance - MEDCOUPLING_DEVELOPMENT : (integer) indicates development version when set to 1 -*/ - -#define MEDCOUPLING_VERSION_MAJOR @MEDCOUPLING_MAJOR_VERSION@ -#define MEDCOUPLING_VERSION_MINOR @MEDCOUPLING_MINOR_VERSION@ -#define MEDCOUPLING_VERSION_MAINTENANCE @MEDCOUPLING_PATCH_VERSION@ -#define MEDCOUPLING_VERSION_STR "@MEDCOUPLING_VERSION@" -#define MEDCOUPLING_VERSION @MEDCOUPLING_XVERSION@ -#define MEDCOUPLING_DEVELOPMENT @MEDCOUPLING_VERSION_DEV@ - -#endif // __MEDCOUPLING_VERSION_H__ diff --git a/medtool/cmake_files/CMakeLists.txt b/medtool/cmake_files/CMakeLists.txt deleted file mode 100644 index ecc1dfad1..000000000 --- a/medtool/cmake_files/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -SET(admlocal_cmake_DATA - FindCppUnit.cmake - FindMEDFile.cmake - FindParMetis.cmake - FindSphinx.cmake - MEDCouplingMacros.cmake - FindGraphviz.cmake - FindMetis.cmake - FindScotch.cmake - FindXDR.cmake -) - -INSTALL(FILES ${admlocal_cmake_DATA} DESTINATION ${MEDCOUPLING_INSTALL_CMAKE_LOCAL}) diff --git a/medtool/cmake_files/FindCppUnit.cmake b/medtool/cmake_files/FindCppUnit.cmake deleted file mode 100644 index 7e68e5645..000000000 --- a/medtool/cmake_files/FindCppUnit.cmake +++ /dev/null @@ -1,95 +0,0 @@ -# - Find CppUnit -# Sets the following variables: -# CPPUNIT_INCLUDE_DIRS - path to the CppUnit include directory -# CPPUNIT_LIBRARIES - path to the CppUnit libraries to be linked against -# CPPUNIT_DEFINITIONS - specific CppUnit definitions to be added -# -# The header cppunit/extensions/HelperMacros.h is looked for. -# The following libraries are searched -# cppunit_dll, or cppunitd_dll (Windows) -# cppunit (Linux) -# - -######################################################################### -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -IF(NOT CppUnit_FIND_QUIETLY) - MESSAGE(STATUS "Looking for CppUnit ...") -ENDIF() - -# Headers -SET(CPPUNIT_ROOT_DIR $ENV{CPPUNIT_ROOT_DIR} CACHE PATH "Path to the CPPUNIT.") -IF(CPPUNIT_ROOT_DIR) - LIST(APPEND CMAKE_INCLUDE_PATH "${CPPUNIT_ROOT_DIR}/include") - LIST(APPEND CMAKE_PROGRAM_PATH "${CPPUNIT_ROOT_DIR}/bin") -ENDIF(CPPUNIT_ROOT_DIR) - -SET(CPPUNIT_INCLUDE_TO_FIND cppunit/extensions/HelperMacros.h) -FIND_PATH(CPPUNIT_INCLUDE_DIRS ${CPPUNIT_INCLUDE_TO_FIND}) - -# Libraries -IF(WIN32) - IF(CMAKE_BUILD_TYPE STREQUAL Debug) - FIND_LIBRARY(CPPUNIT_LIBRARIES cppunitd_dll) - ELSE(CMAKE_BUILD_TYPE STREQUAL Debug) - FIND_LIBRARY(CPPUNIT_LIBRARIES cppunit_dll) - ENDIF(CMAKE_BUILD_TYPE STREQUAL Debug) -ELSE(WIN32) - FIND_PROGRAM(CPPUNIT_CONFIG_BIN cppunit-config) - IF(NOT CPPUNIT_CONFIG_BIN) - MESSAGE(FATAL_ERROR "Error in CPPUNIT detection ! cppunit-config executable not found !") - ENDIF(NOT CPPUNIT_CONFIG_BIN) - EXECUTE_PROCESS(COMMAND ${CPPUNIT_CONFIG_BIN} --libs OUTPUT_VARIABLE CPPUNIT_LDFLAGS) - STRING(STRIP ${CPPUNIT_LDFLAGS} CPPUNIT_LDFLAGS) - STRING(REPLACE " " ";" LDFLAGS_LIST ${CPPUNIT_LDFLAGS}) - FOREACH(LDFLAG ${LDFLAGS_LIST}) - STRING(REGEX MATCH "^-L.*" LIBDIR "${LDFLAG}") - STRING(REGEX MATCH "^-l.*" LIB "${LDFLAG}") - IF(LIBDIR) - STRING(REGEX REPLACE "^-L" "" LIBDIR ${LIBDIR}) - LIST(APPEND CMAKE_LIBRARY_PATH ${LIBDIR}) - ELSEIF(LIB) - STRING(REGEX REPLACE "^-l" "" LIB ${LIB}) - LIST(APPEND LIBS ${LIB}) - ELSE() - MESSAGE(FATAL_ERROR "Unrecognized token \"${LDFLAG}\" in the output of cppunit-config --libs") - ENDIF() - ENDFOREACH(LDFLAG ${LDFLAGS_LIST}) - FOREACH(LIB ${LIBS}) - FIND_LIBRARY(CPPUNIT_SUBLIB_${LIB} ${LIB}) - IF(NOT CPPUNIT_SUBLIB_${LIB}) - MESSAGE(FATAL_ERROR "Error in CPPUNIT detection! Fail to locate the needed library ${LIB}!") - ENDIF(NOT CPPUNIT_SUBLIB_${LIB}) - LIST(APPEND CPPUNIT_LIBRARIES ${CPPUNIT_SUBLIB_${LIB}}) - ENDFOREACH(LIB ${LIBS}) -# MESSAGE("**** ${CPPUNIT_LIBRARIES}") -ENDIF(WIN32) - -# Global variables -SET(CPPUNIT_DEFINITIONS) -IF(WIN32) - SET(CPPUNIT_DEFINITIONS -DCPPUNIT_DLL) -ENDIF(WIN32) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(CppUnit REQUIRED_VARS CPPUNIT_INCLUDE_DIRS CPPUNIT_LIBRARIES) diff --git a/medtool/cmake_files/FindGraphviz.cmake b/medtool/cmake_files/FindGraphviz.cmake deleted file mode 100644 index c05a59458..000000000 --- a/medtool/cmake_files/FindGraphviz.cmake +++ /dev/null @@ -1,76 +0,0 @@ -# - Graphviz detection -# -# Output variables: GRAPHVIZ_EXECUTABLE - where is executable 'dot' takes place. -# GRAPHVIZ_INCLUDE_DIRS - where to find headers. -# GRAPHVIZ_LIBRARIES - where to get libraries. -# GRAPHVIZ_VERSION - Graphviz version -# GRAPHVIZ_DEFINITIONS - Graphviz definitions -# GRAPHVIZ_FOUND - True if Graphviz was found. -# -########################################################################### -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -SET(GRAPHVIZ_ROOT_DIR $ENV{GRAPHVIZ_ROOT_DIR} CACHE PATH "Path to the Graphviz.") -IF(GRAPHVIZ_ROOT_DIR) - LIST(APPEND CMAKE_PREFIX_PATH "${GRAPHVIZ_ROOT_DIR}") -ENDIF(GRAPHVIZ_ROOT_DIR) - -FIND_PROGRAM(GRAPHVIZ_EXECUTABLE dot) - -FIND_PATH(GRAPHVIZ_INCLUDE_DIR NAMES graphviz/cgraph.h) -SET(GRAPHVIZ_INCLUDE_DIRS ${GRAPHVIZ_INCLUDE_DIR} ${GRAPHVIZ_INCLUDE_DIR}/graphviz) - -FIND_LIBRARY(GRAPHVIZ_cdt_LIBRARY NAMES cdt PATH_SUFFIXES bin) -FIND_LIBRARY(GRAPHVIZ_graph_LIBRARY NAMES cgraph PATH_SUFFIXES bin) -FIND_LIBRARY(GRAPHVIZ_gvc_LIBRARY NAMES gvc PATH_SUFFIXES bin) -FIND_LIBRARY(GRAPHVIZ_pathplan_LIBRARY NAMES pathplan PATH_SUFFIXES bin) - -SET(GRAPHVIZ_LIBRARIES - ${GRAPHVIZ_cdt_LIBRARY} - ${GRAPHVIZ_graph_LIBRARY} - ${GRAPHVIZ_gvc_LIBRARY} - ${GRAPHVIZ_pathplan_LIBRARY} - ) - -IF(GRAPHVIZ_EXECUTABLE) - EXECUTE_PROCESS(COMMAND ${GRAPHVIZ_EXECUTABLE} "-V" ERROR_VARIABLE GRAPHVIZ_VERSION ERROR_STRIP_TRAILING_WHITESPACE) - STRING(REGEX REPLACE ".* ([0-9.]+) .*" "\\1" GRAPHVIZ_VERSION "${GRAPHVIZ_VERSION}") -ENDIF() - -SET(GRAPHVIZ_DEFINITIONS) -IF("${GRAPHVIZ_VERSION}" VERSION_LESS "2.36.0") - SET(GRAPHVIZ_DEFINITIONS -DWITH_CGRAPH) -ENDIF() - -## Don't detect cgraph on Windows -#IF(NOT WIN32) -# FIND_LIBRARY(GRAPHVIZ_cgraph_LIBRARY NAMES cgraph PATH_SUFFIXES bin) -# SET(GRAPHVIZ_LIBRARIES ${GRAPHVIZ_cgraph_LIBRARY}) -#ENDIF() - -# Handle the standard arguments of the find_package() command: -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Graphviz REQUIRED_VARS - GRAPHVIZ_EXECUTABLE - GRAPHVIZ_LIBRARIES - GRAPHVIZ_INCLUDE_DIRS) diff --git a/medtool/cmake_files/FindMEDFile.cmake b/medtool/cmake_files/FindMEDFile.cmake deleted file mode 100644 index 546969240..000000000 --- a/medtool/cmake_files/FindMEDFile.cmake +++ /dev/null @@ -1,59 +0,0 @@ -# - Find MED file installation -# -# The following variable are set: -# MEDFILE_INCLUDE_DIRS -# MEDFILE_LIBRARIES -# MEDFILE_C_LIBRARIES -# MEDFILE_F_LIBRARIES -# -# The CMake (or environment) variable MEDFILE_ROOT_DIR can be set to -# guide the detection and indicate a root directory to look into. -# -############################################################################ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# ------ - -MESSAGE(STATUS "Check for medfile ...") - -# ------ - -SET(MEDFILE_ROOT_DIR $ENV{MEDFILE_ROOT_DIR} CACHE PATH "Path to the MEDFile.") -IF(MEDFILE_ROOT_DIR) - LIST(APPEND CMAKE_PREFIX_PATH "${MEDFILE_ROOT_DIR}") -ENDIF(MEDFILE_ROOT_DIR) - -FIND_PATH(MEDFILE_INCLUDE_DIRS med.h) -#FIND_PROGRAM(MDUMP mdump) -FIND_LIBRARY(MEDFILE_C_LIBRARIES NAMES medC) -FIND_LIBRARY(MEDFILE_F_LIBRARIES NAMES med) -IF(MEDFILE_F_LIBRARIES) - SET(MEDFILE_LIBRARIES ${MEDFILE_C_LIBRARIES} ${MEDFILE_F_LIBRARIES}) -ELSE(MEDFILE_F_LIBRARIES) - SET(MEDFILE_LIBRARIES ${MEDFILE_C_LIBRARIES}) -ENDIF(MEDFILE_F_LIBRARIES) - -IF(NOT MEDFILE_INCLUDE_DIRS - OR (NOT MEDFILE_C_LIBRARIES AND NOT MEDFILE_F_LIBRARIES)) - MESSAGE(FATAL_ERROR "MEDFile not found; please set MEDFILE_ROOT_DIR and check target directory.") -ENDIF() - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(MEDFile REQUIRED_VARS MEDFILE_INCLUDE_DIRS MEDFILE_LIBRARIES) diff --git a/medtool/cmake_files/FindMetis.cmake b/medtool/cmake_files/FindMetis.cmake deleted file mode 100644 index 23f82e195..000000000 --- a/medtool/cmake_files/FindMetis.cmake +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# ------ - -MESSAGE(STATUS "Check for metis ...") - -SET(METIS_ROOT_DIR $ENV{METIS_ROOT_DIR} CACHE PATH "Path to the METIS.") -IF(METIS_ROOT_DIR) - LIST(APPEND CMAKE_LIBRARY_PATH "${METIS_ROOT_DIR}") - LIST(APPEND CMAKE_LIBRARY_PATH "${METIS_ROOT_DIR}/lib") - LIST(APPEND CMAKE_INCLUDE_PATH "${METIS_ROOT_DIR}/Lib") - LIST(APPEND CMAKE_INCLUDE_PATH "${METIS_ROOT_DIR}/include") -ENDIF(METIS_ROOT_DIR) - -FIND_LIBRARY(METIS_LIBRARIES metis) -FIND_PATH(METIS_INCLUDE_DIRS metis.h) - -IF(NOT METIS_LIBRARIES OR NOT METIS_INCLUDE_DIRS) - MESSAGE(FATAL_ERROR "Metis not found; please set METIS_ROOT_DIR and check target directory.") -ENDIF() - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Metis REQUIRED_VARS METIS_INCLUDE_DIRS METIS_LIBRARIES) -FILE(READ ${METIS_INCLUDE_DIRS}/metis.h metis_h_content) -STRING(REPLACE "\n" ";" list_metis_h_content ${metis_h_content}) -FOREACH(ln ${list_metis_h_content}) - IF("${ln}" MATCHES "^#define METIS_VER_MAJOR") - STRING(REPLACE "#define METIS_VER_MAJOR" "" metis_major_version "${ln}") - STRING(STRIP "${metis_major_version}" metis_major_version) - ENDIF("${ln}" MATCHES "^#define METIS_VER_MAJOR") -ENDFOREACH(ln ${list_metis_h_content}) -IF(metis_major_version STREQUAL 5) - SET(MEDCOUPLING_METIS_V5 1) - MESSAGE(STATUS "Metis maj version 5 detected.") -ELSE(metis_major_version STREQUAL 5) - MESSAGE(STATUS "Metis maj version 4 detected.") -ENDIF(metis_major_version STREQUAL 5) diff --git a/medtool/cmake_files/FindParMetis.cmake b/medtool/cmake_files/FindParMetis.cmake deleted file mode 100644 index 7eb0701a3..000000000 --- a/medtool/cmake_files/FindParMetis.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# ------ - -MESSAGE(STATUS "Check for parmetis ...") - -SET(PARMETIS_ROOT_DIR $ENV{PARMETIS_ROOT_DIR} CACHE PATH "Path to the PARMETIS.") -IF(PARMETIS_ROOT_DIR) - LIST(APPEND CMAKE_PREFIX_PATH "${PARMETIS_ROOT_DIR}") -ENDIF(PARMETIS_ROOT_DIR) - -FIND_LIBRARY(PARMETIS_LIBRARIES parmetis) -FIND_LIBRARY(PARMETIS_SEQ_LIBRARIES metis) -SET(PARMETIS_LIBRARIES ${PARMETIS_LIBRARIES} ${PARMETIS_SEQ_LIBRARIES}) -FIND_PATH(PARMETIS_INCLUDE_DIRS parmetis.h) - -IF(NOT PARMETIS_LIBRARIES OR NOT PARMETIS_INCLUDE_DIRS) - MESSAGE(FATAL_ERROR "Parallel Metis not found; please set PARMETIS_ROOT_DIR and check target directory.") -ENDIF() - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(ParMetis REQUIRED_VARS PARMETIS_INCLUDE_DIRS PARMETIS_LIBRARIES) diff --git a/medtool/cmake_files/FindScotch.cmake b/medtool/cmake_files/FindScotch.cmake deleted file mode 100644 index 351c3e92e..000000000 --- a/medtool/cmake_files/FindScotch.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# ------ - -MESSAGE(STATUS "Check for scotch ...") - -SET(SCOTCH_ROOT_DIR $ENV{SCOTCH_ROOT_DIR} CACHE PATH "Path to the SCOTCH.") -IF(SCOTCH_ROOT_DIR) - LIST(APPEND CMAKE_PREFIX_PATH "${SCOTCH_ROOT_DIR}") -ENDIF(SCOTCH_ROOT_DIR) - -FIND_LIBRARY(SCOTCH_LIBRARIES scotch) -FIND_LIBRARY(SCOTCH_ERR_LIBRARIES scotcherr) -SET(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES} ${SCOTCH_ERR_LIBRARIES}) -FIND_PATH(SCOTCH_INCLUDE_DIRS scotch.h PATH_SUFFIXES "/scotch") - -IF(NOT SCOTCH_LIBRARIES OR NOT SCOTCH_ERR_LIBRARIES OR NOT SCOTCH_INCLUDE_DIRS) - MESSAGE(FATAL_ERROR "Scotch not found; please set SCOTCH_ROOT_DIR and check target directory.") -ENDIF() - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Scotch REQUIRED_VARS SCOTCH_INCLUDE_DIRS SCOTCH_LIBRARIES) diff --git a/medtool/cmake_files/FindSphinx.cmake b/medtool/cmake_files/FindSphinx.cmake deleted file mode 100644 index 94cc2ae05..000000000 --- a/medtool/cmake_files/FindSphinx.cmake +++ /dev/null @@ -1,43 +0,0 @@ -# - Sphinx detection -# -# Output variables: -# SPHINX_EXECUTABLE - path to the Sphinx executable -# SPHINX_PYTHONPATH - path to the Sphinx Python modules -# -########################################################################### -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -FIND_PROGRAM(SPHINX_EXECUTABLE sphinx-build PATH_SUFFIXES Scripts) -FIND_PROGRAM(SPHINX_APIDOC_EXECUTABLE sphinx-apidoc PATH_SUFFIXES Scripts) - -# Get root dir locally, going up two levels from the exec: -GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${SPHINX_EXECUTABLE}" PATH) -GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${_tmp_ROOT_DIR}" PATH) -IF(WIN32) - SET(SPHINX_PYTHONPATH "${_tmp_ROOT_DIR}/lib/site-packages") -ELSE() - SET(SPHINX_PYTHONPATH "${_tmp_ROOT_DIR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages") -ENDIF() -# Handle the standard arguments of the find_package() command: -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sphinx REQUIRED_VARS SPHINX_EXECUTABLE SPHINX_APIDOC_EXECUTABLE) diff --git a/medtool/cmake_files/FindXDR.cmake b/medtool/cmake_files/FindXDR.cmake deleted file mode 100644 index c0eaf86e1..000000000 --- a/medtool/cmake_files/FindXDR.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -MESSAGE(STATUS "Check for XDR ...") - -FIND_PATH(XDR_INCLUDE_DIRS rpc/xdr.h) -SET(XDR_DEFINITIONS "-DHAS_XDR") - -IF(WIN32) - FIND_LIBRARY(XDR_LIBRARIES xdr) # To get the .lib file from XDR - FIND_PATH(XDR_INCLUDE_DIRS2 stdint.h PATH_SUFFIXES src/msvc) # To get the stdint.h from XDR (needed by types.h) - IF(XDR_INCLUDE_DIRS) - IF(XDR_INCLUDE_DIRS2) - LIST(APPEND XDR_INCLUDE_DIRS "${XDR_INCLUDE_DIRS2}") - ELSE() - SET(XDR_INCLUDE_DIRS "${XDR_INCLUDE_DIRS2}") # Make the detection fail - ENDIF() - ENDIF() -ENDIF(WIN32) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(XDR REQUIRED_VARS XDR_INCLUDE_DIRS) diff --git a/medtool/cmake_files/MEDCouplingMacros.cmake b/medtool/cmake_files/MEDCouplingMacros.cmake deleted file mode 100644 index 0dc46e2b8..000000000 --- a/medtool/cmake_files/MEDCouplingMacros.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -#################################################################### -# _TOHEXA() -# Convert a number (smaller than 16) into hexadecimal representation -# with a leading 0. -MACRO(_TOHEXA num result) - SET(_hexa_map a b c d e f) - IF(${num} LESS 10) - SET(${result} "0${num}") - ELSE() - MATH(EXPR _res "${num}-10" ) - LIST(GET _hexa_map ${_res} _out) - SET(${result} "0${_out}") - ENDIF() -ENDMACRO(_TOHEXA) - -#################################################################### -# MEDCOUPLING_XVERSION() -# -# Computes hexadecimal version of MEDCOUPLING package -# -# USAGE: MEDCOUPLING_XVERSION(package) -# -# ARGUMENTS: -# -# package: IN: MEDCOUPLING package name -# -# The macro reads MEDCOUPLING package version from PACKAGE_VERSION variable -# (note package name are uppercase); -# hexadecimal version value in form 0xAABBCC (where AA, BB and CC are -# major, minor and maintenance components of package version in -# hexadecimal form) is put to the PACKAGE_XVERSION variable -MACRO(MEDCOUPLING_XVERSION pkg) - STRING(TOUPPER ${pkg} _pkg_UC) - IF(${_pkg_UC}_VERSION) - SET(_major) - SET(_minor) - SET(_patch) - _TOHEXA(${${_pkg_UC}_MAJOR_VERSION} _major) - _TOHEXA(${${_pkg_UC}_MINOR_VERSION} _minor) - _TOHEXA(${${_pkg_UC}_PATCH_VERSION} _patch) - SET(${_pkg_UC}_XVERSION "0x${_major}${_minor}${_patch}") - ENDIF() -ENDMACRO(MEDCOUPLING_XVERSION) diff --git a/medtool/doc/CMakeLists.txt b/medtool/doc/CMakeLists.txt deleted file mode 100644 index 04f6cc867..000000000 --- a/medtool/doc/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_SUBDIRECTORY(user) -ADD_SUBDIRECTORY(tutorial) diff --git a/medtool/doc/tutorial/CMakeLists.txt b/medtool/doc/tutorial/CMakeLists.txt deleted file mode 100644 index 0f61338a9..000000000 --- a/medtool/doc/tutorial/CMakeLists.txt +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/conf.py) - -MACRO(MEDCOUPLING_EXTEND_ENVIRONMENT_VARIABLE output envvar values) - SET(_env) - FOREACH(_val ${values}) - IF(${envvar} STREQUAL "PATH" OR ${envvar} STREQUAL "LD_LIBRARY_PATH") - IF(NOT IS_DIRECTORY ${_val}) - GET_FILENAME_COMPONENT(_val "${_val}" PATH) - ENDIF() - ENDIF() - IF(WIN32) - IF(${envvar} STREQUAL "LD_LIBRARY_PATH") - SET(envvar PATH) - ENDIF() - STRING(REPLACE "/" "\\" _env "${_env} @SET ${envvar}=${_val};%${envvar}%\n") - ELSE(WIN32) - SET(_env "${_env} export ${envvar}=${_val}:\${${envvar}}\n") - ENDIF(WIN32) - ENDFOREACH(_val) - SET(${output} "${${output}} ${_env}") -ENDMACRO(MEDCOUPLING_EXTEND_ENVIRONMENT_VARIABLE envvar values) - - -SET(SETUPTOOLS_PATH $ENV{SETUPTOOLS_ROOT_DIR}/bin) -SET(SETUPTOOLS_PYTHONPATH $ENV{SETUPTOOLS_ROOT_DIR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) - -SET(DOCUTILS_PATH $ENV{DOCUTILS_ROOT_DIR}/bin) -SET(DOCUTILS_PYTHONPATH $ENV{DOCUTILS_ROOT_DIR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) - -SET(PKGCONFIG_PYTHONPATH $ENV{PKGCONFIG_ROOT_DIR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) - - -SET(build_env) - -#SET(_variables ${SPHINX_EXECUTABLE} ${SPHINX_APIDOC_EXECUTABLE} ${PYTHON_EXECUTABLE} ${GRAPHVIZ_EXECUTABLE} ${SETUPTOOLS_PATH} ${DOCUTILS_PATH}) -#MEDCOUPLING_EXTEND_ENVIRONMENT_VARIABLE(build_env "PATH" "${_variables}") - -#SET(_variables ${SPHINX_PYTHONPATH} ${PYTHON_PYTHONPATH} ${SETUPTOOLS_PYTHONPATH} ${DOCUTILS_PYTHONPATH} ${PKGCONFIG_PYTHONPATH}) -SET(_variables ${SPHINX_PYTHONPATH} ${SETUPTOOLS_PYTHONPATH} ${PKGCONFIG_PYTHONPATH} ${DOCUTILS_PYTHONPATH}) -MEDCOUPLING_EXTEND_ENVIRONMENT_VARIABLE(build_env "PYTHONPATH" "${_variables}") - -#SET(_variables ${PYTHON_LIBRARIES} ${GRAPHVIZ_LIBRARIES}) -SET(_variables ${PYTHON_LIBRARIES}) -MEDCOUPLING_EXTEND_ENVIRONMENT_VARIABLE(build_env "LD_LIBRARY_PATH" "${_variables}") - -IF(WIN32) - SET(_ext "bat") - SET(_call_cmd "call") -ELSE() - SET(_ext "sh") - SET(_call_cmd ".") -ENDIF() - - -SET(_cmd_options -c ${CMAKE_CURRENT_BINARY_DIR} -b html -d doctrees -D latex_paper_size=a4 ${CMAKE_CURRENT_SOURCE_DIR} html) -SET(_cmd ${SPHINX_EXECUTABLE} ${_cmd_options}) - -SET(_script ${CMAKE_CURRENT_BINARY_DIR}/env_script.${_ext}) - -FILE(WRITE ${_script} "${build_env}") -SET(make_doc ${_call_cmd} ${_script} && ${_cmd}) - - -ADD_CUSTOM_TARGET(tutorial_doc COMMAND ${make_doc}) -ADD_DEPENDENCIES(usr_docs tutorial_doc) - -#INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target tutorial_doc)") -INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ DESTINATION ${MEDCOUPLING_INSTALL_DOC}/gui/MED/tutorial) -INSTALL(DIRECTORY images/ DESTINATION ${MEDCOUPLING_INSTALL_DOC}/gui/MED/tutorial/images) -INSTALL(DIRECTORY data/ DESTINATION ${MEDCOUPLING_INSTALL_DOC}/gui/MED/tutorial/data) - -SET(make_clean_files html doctrees) -SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${make_clean_files}") diff --git a/medtool/doc/tutorial/atestMEDCouplingCorba1.rst b/medtool/doc/tutorial/atestMEDCouplingCorba1.rst deleted file mode 100644 index ceeb689e2..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingCorba1.rst +++ /dev/null @@ -1,37 +0,0 @@ - -.. _python_testMEDCouplingcorba1_solution: - -Visualiser une instance de MEDCoupling dans ParaViS à travers CORBA -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDCoupling as mc - from MEDCouplingCorba import MEDCouplingUMeshServant - - # Creating a mesh - arr = mc.DataArrayDouble(11) - arr.iota(0) - m = mc.MEDCouplingCMesh() - m.setCoords(arr,arr) - m = m.buildUnstructured() - - # Making it available on the CORBA bus - ref_m = MEDCouplingUMeshServant._this(m) - import CORBA - orb = CORBA.ORB_init() - ior = orb.object_to_string(ref_m) - print ior - - # Displaying it in ParaVis - import salome - salome.salome_init() - print "About to import module 'pvsimple' ..." - import pvsimple as pvs - print "Module 'pvsimple' was imported!" - - # From here, we use the standard ParaView API: - src1 = pvs.ParaMEDCorbaPluginSource() - src1.IORCorba = ior # This is where we need the CORBA reference of the object created - dr = pvs.Show(src1) - \ No newline at end of file diff --git a/medtool/doc/tutorial/atestMEDCouplingCube.rst b/medtool/doc/tutorial/atestMEDCouplingCube.rst deleted file mode 100644 index 61e4bd404..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingCube.rst +++ /dev/null @@ -1,262 +0,0 @@ - -.. _python_testMEDCouplingcube_solution: - -3D cube meshing -~~~~~~~~~~~~~~~ - -:: - - from MEDCoupling import * - from MEDLoader import * - import MEDLoaderDataForTest - - from math import * - - # Definition of environnement variables - spaceDimension = 3 - N = 4 - nbOfNodes = N*N*N - nbOfCells = (N-1)*(N-1)*(N-1) - nbOfCells2D = (N-1)*(N-1) - - print "1 ********************" - # Initialisation of coordinates - coordinates = [] - for k in range(N): - for j in range(N): - for i in range(N): - coordinates.append(float(i)) - coordinates.append(float(j)) - coordinates.append(float(k)) - - print "2 ********************" - # Creation of meshing : need following initialisations - # => Definition of the mesh dimension - # => Definition of number of cells - # => Definition of name of meshing - mesh=MEDCouplingUMesh.New() - mesh.setMeshDimension(3) - mesh.allocateCells(nbOfCells+nbOfCells2D) - mesh.setName("3Dcube") - - print "3 ********************" - # One remark : only one dimension cells by meshing - # Construction of volumic meshing - # => Definition of connectivity - # => Definition of type of cells - connectivity = [] - for k in range(N-1): - for j in range(N-1): - for i in range(N-1): - inode = N*N*(k+1)+ N*(j+1)+i - connectivity.append(inode) - connectivity.append(inode-N) - connectivity.append(inode-N+1) - connectivity.append(inode+1) - connectivity.append(inode-N*N) - connectivity.append(inode-N*N-N) - connectivity.append(inode-N*N-N+1) - connectivity.append(inode-N*N+1) - print len(connectivity) - print 8*(nbOfCells) - - print "4 ********************" - # Adding cells in meshing - for i in range(nbOfCells): - mesh.insertNextCell(NORM_HEXA8,8,connectivity[8*i:8*(i+1)]) - pass - - print "5 ********************" - # Settings of coordinates and verify if it's OK - myCoords = DataArrayDouble.New() - myCoords.setValues(coordinates,nbOfNodes,3) - mesh.setCoords(myCoords) - mesh.checkCoherency() - - print "6 ********************" - # Extraction of surfacic meshing - pt=[0.,0.,0.] - vec=[0.,0.,1.] - nodes = mesh.findNodesOnPlane(pt,vec,1e-12) - mesh2D = mesh.buildFacePartOfMySelfNode(nodes,True) - #print mesh2D - mesh2D.setName("3Dcube") - mesh2D.checkCoherency() - - print "7 ********************" - # Creation of field : with following definition - # => Definition of the mesh support - # => Definition of field name - # => Definition of field nature - field = MEDCouplingFieldDouble.New(ON_CELLS) - field.setMesh(mesh) - field.setName("field") - field.setNature(Integral) - - # Computing and setting field values - myCoords=DataArrayDouble.New() - sampleTab=[] - bar = mesh.getBarycenterAndOwner() - print bar.getNbOfElems() - for i in range(nbOfCells): - x = bar.getIJ(i+1,1) - y = bar.getIJ(i+1,2) - z = bar.getIJ(i+1,3) - d = sqrt(x*x+y*y+z*z) - sinus = sin(d) - #f.setValueIJ(i+1,1,sin(d)) - sampleTab.append(sinus) - - myCoords.setValues(sampleTab,nbOfCells,1) - field.setArray(myCoords) - - fBF = MEDCouplingFieldDouble.New(ON_CELLS) - fBF.setMesh(mesh2D) - fBF.setName("fieldBottomFace") - fBF.setNature(Integral) - Cval = 10. - myCoords2D=DataArrayDouble.New() - sampleTab=[] - for i in range(nbOfCells2D): - sampleTab.append(Cval) - myCoords2D.setValues(sampleTab,nbOfCells2D,1) - fBF.setArray(myCoords2D) - - medFileName = "MEDCoupling_cube3D.med" - # For note : True / False in Write* functions - # => True : overwriting existing file - # => False : add in existing file - meshes=[mesh2D,mesh] - MEDLoader.WriteUMeshes(medFileName,meshes,True); - MEDLoader.WriteField(medFileName,field,False) - MEDLoader.WriteField(medFileName,fBF,False) - - -:: - - from MEDCoupling import * - from MEDLoader import * - import MEDLoaderDataForTest - - from math import * - - spaceDim3D = 3 - MeshDim2D = 2 - N = 4 - NbCell2D = (N-1)*(N-1) - NbCell3D = NbCell2D*(N-1) - NbNode2D = N*N - NbNode3D = NbNode2D*N - - # Creation of a extruded meshing - # input : a 2D meshing and a 1D meshing - # Creation of 2D meshing - coordinates = [] - for j in range(N): - for i in range(N): - coordinates.append(float(i)) - coordinates.append(float(j)) - Connectivities = [0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5, 5,9,10,6, 6,10,11,7, 8,12,13,9, 9,13,14,10, 10,14,15,11] - myCoords = DataArrayDouble.New() - myCoords.setValues(coordinates,NbNode2D,MeshDim2D) - - m1 = MEDCouplingUMesh.New() - m1.setMeshDimension(MeshDim2D) - m1.allocateCells(NbCell2D) - m1.setCoords(myCoords) - m1.setName("2D_Support") - - for i in range(NbCell2D): - m1.insertNextCell(NORM_QUAD4,4,Connectivities[4*i:4*(i+1)]) - m1.changeSpaceDimension(3) - - # Creation of 1D meshing - coords = [ 0.0, 1.0, 2.0, 3.0 ] - conn = [ 0,1, 1,2, 2,3 ] - m2 = MEDCouplingUMesh.New() - m2.setMeshDimension(1) - m2.allocateCells(3) - m2.insertNextCell(NORM_SEG2,2,conn[0:2]) - m2.insertNextCell(NORM_SEG2,2,conn[2:4]) - m2.insertNextCell(NORM_SEG2,2,conn[4:6]) - myCoords1D=DataArrayDouble.New() - myCoords1D.setValues(coords,4,1) - m2.setCoords(myCoords1D) - m2.changeSpaceDimension(3) - - # Construction of extruded meshing - center = [0.,0.,0.] - vector = [0.,1.,0.] - m2.rotate(center,vector,pi/2.) - m3 = m1.buildExtrudedMesh(m2,0) - m3.setName("Extrusion") - - # Construction of group : old fashion mode - part=[1] - meshGroup=m3.buildPartOfMySelf(part,True); - meshGroup.setName("meshGroup"); - - medFileName = "MEDCoupling_Extrudedcube3D.med" - MEDLoader.WriteUMeshesPartition(medFileName,"Extrusion",[m3,meshGroup],True) - - -:: - - from MEDCoupling import * - from MEDLoader import * - import MEDLoaderDataForTest - - from math import * - - spaceDim3D = 3 - MeshDim2D = 2 - N = 4 - NbCell2D = (N-1)*(N-1) - NbCell3D = NbCell2D*(N-1) - NbNode2D = N*N - NbNode3D = NbNode2D*N - - # Creation of a grid => Structured mesh - # Need directions definition - mesh=MEDCouplingCMesh.New() - coordsX=DataArrayDouble.New() - arrX=[ 0., 1., 2., 3. ] - coordsX.setValues(arrX,4,1) - coordsY=DataArrayDouble.New() - arrY=[ 0., 1., 2., 3. ] - coordsY.setValues(arrY,4,1) - coordsZ=DataArrayDouble.New() - arrZ=[ 0., 1., 2., 3. ] - coordsZ.setValues(arrZ,4,1) - mesh.setCoords(coordsX,coordsY,coordsZ) - # Passing structured meshing to unstructured - # necessary to save meshing - meshU=mesh.buildUnstructured() - meshU.setName("Grid") - - # Creation of group : fashion mode - # if ids cells are known, this step is not to be made - pt=[1] - m2 = meshU.buildPartOfMySelf(pt,True); - ret,tabIdCells = meshU.areCellsIncludedIn(m2,0) - print ret - print tabIdCells - # Definition of the name group - tabIdCells.setName("meshGroup") - - # Passing MEDCoupling to MEDFile - fmeshU = MEDFileUMesh.New() - fmeshU.setName("Grid") - fmeshU.setDescription("IHopeToConvinceLastMEDMEMUsers") - myCoords = meshU.getCoords() - print myCoords - fmeshU.setCoords(myCoords) - print "**************************" - fmeshU.setMeshAtLevel(0,meshU) - print "**************************" - fmeshU.setGroupsAtLevel(0,[tabIdCells],False) - print "**************************" - - medFileName = "MEDCoupling_Gridcube3D.med" - fmeshU.write(medFileName,2) - diff --git a/medtool/doc/tutorial/atestMEDCouplingDataArray1.rst b/medtool/doc/tutorial/atestMEDCouplingDataArray1.rst deleted file mode 100644 index e168e44bc..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingDataArray1.rst +++ /dev/null @@ -1,63 +0,0 @@ - -.. _python_testMEDCouplingdataarray1_solution: - -Playing with regular hexagons using DataArrayDouble -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDCoupling as mc - import math - # Building the coordinates of the initial hexagon, centered at 0,0 - d = mc.DataArrayDouble(6,2) - d[:,0] = 3. - d[:,1] = range(6) - d[:,1] *= math.pi/3. - d = d.fromPolarToCart() - d.setInfoOnComponents(["X [m]","Y [m]"]) - print d.getValues() - print d - print "Uniform array?", d.magnitude().isUniform(3.,1e-12) - # Translating the 7 hexagons with a translation - radius = 3. - translationToPerform = [[0.,0.],[3./2.*radius,-radius*math.sqrt(3.)/2],[3./2.*radius,radius*math.sqrt(3.)/2],[0.,radius*math.sqrt(3.)],[-3./2.*radius,radius*math.sqrt(3.)/2],[-3./2.*radius,-radius*math.sqrt(3.)/2],[0.,-radius*math.sqrt(3.)]] - ds = len(translationToPerform)*[None] - for pos,t in enumerate(translationToPerform): - ds[pos] = d[:] # Perform a deep copy of d and place it at position 'pos' in ds - ds[pos] += t # Adding a vector to a set of coordinates does a translation - pass - # Identifying duplicate tuples - d2 = mc.DataArrayDouble.Aggregate(ds) - oldNbOfTuples = d2.getNumberOfTuples() - c,cI = d2.findCommonTuples(1e-12) - tmp = c[cI[0]:cI[0+1]] - print tmp - a = cI.deltaShiftIndex() - b = a - 1 - myNewNbOfTuples = oldNbOfTuples - sum(b.getValues()) - o2n, newNbOfTuples = mc.DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfTuples,c,cI) - print "Have I got the right number of tuples?" - print "myNewNbOfTuples = %d, newNbOfTuples = %d" % (myNewNbOfTuples, newNbOfTuples) - assert(myNewNbOfTuples == newNbOfTuples) - # Extracting the unique set of tuples - d3 = d2.renumberAndReduce(o2n, newNbOfTuples) - n2o = o2n.invertArrayO2N2N2O(newNbOfTuples) - d3_bis = d2[n2o] - print "Are d3 and d3_bis equal ? %s" % (str(d3.isEqual(d3_bis, 1e-12))) - # Now translate everything - d3 += [3.3,4.4] - # And build an unstructured mesh representing the final pattern - m = mc.MEDCouplingUMesh("My7hexagons",2) - m.setCoords(d3) - print "Mesh dimension is", m.getMeshDimension() - print "Spatial dimension is", m.getCoords().getNumberOfComponents() - m.allocateCells(7) - for i in xrange(7): - cell_connec = o2n[6*i:6*(i+1)] - m.insertNextCell(mc.NORM_POLYGON, cell_connec.getValues()) - pass - # Check that everything is coherent (will throw if not) - m.checkCoherency() - # Write the result into a VTU file that can be read with ParaView - m.writeVTK("My7hexagons.vtu") - diff --git a/medtool/doc/tutorial/atestMEDCouplingFieldDouble1.rst b/medtool/doc/tutorial/atestMEDCouplingFieldDouble1.rst deleted file mode 100644 index 1cf20c922..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingFieldDouble1.rst +++ /dev/null @@ -1,74 +0,0 @@ - -.. _python_testMEDCouplingfielddouble1_solution: - -Playing with fields -~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDCoupling as mc - - # Create an unstructured mesh from a Cartesian one - xarr = mc.DataArrayDouble.New(11,1) - xarr.iota(0.) - cmesh = mc.MEDCouplingCMesh.New() - cmesh.setCoords(xarr,xarr,xarr) - mesh = cmesh.buildUnstructured() - mesh.convertToPolyTypes(mc.DataArrayInt.Range(0,mesh.getNumberOfCells(),2)) - # Create a field - f = mesh.fillFromAnalytic(mc.ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") # 1 means that the field should have one component - f.setName("MyField") - # A variant: - f2 = mc.MEDCouplingFieldDouble(mc.ON_CELLS, mc.ONE_TIME) - f2.setMesh(mesh) - f2.setName("MyField2") - f2.fillFromAnalytic(1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") # 1 means that the field should have one component - print "Are f and f2 equal?", f.isEqualWithoutConsideringStr(f2,1e-12,1e-12) - # - da1 = f.getArray() # a DataArrayDouble, which is a direct reference (not a copy) of the field's values - ids1 = da1.getIdsInRange(0.,5.) - fPart1 = f.buildSubPart(ids1) - fPart1.writeVTK("ExoField_fPart1.vtu") - ids2 = f.getArray().getIdsInRange(50.,1.e300) - fPart2 = f.buildSubPart(ids2) - # Renumbering cells to follow MED file rules - fPart1Cpy = fPart1.deepCpy() - o2n = fPart1Cpy.getMesh().sortCellsInMEDFileFrmt() - fPart1Cpy.getArray().renumberInPlace(o2n) - # Check that fPart1Cpy and fPart1 are the same - fPart1Cpy.substractInPlaceDM(fPart1,12,1e-12) - fPart1Cpy.getArray().abs() - print "Are the fields equal?", (fPart1Cpy.getArray().accumulate()[0]<1e-12) - # Aggregate fields - fPart12 = mc.MEDCouplingFieldDouble.MergeFields([fPart1,fPart2]) - fPart12.writeVTK("ExoField_fPart12.vtu") - # Evaluation on points - bary = fPart12.getMesh().getBarycenterAndOwner() - arr1 = fPart12.getValueOnMulti(bary) - arr2 = f.getValueOnMulti(bary) - delta = arr1-arr2 - delta.abs() - print "Is field evaluation matching?", (delta.accumulate()[0]<1e-12) - # Integral computations - integ1 = fPart12.integral(0,True) - integ1_bis = fPart12.getArray().accumulate()[0] - print "First integral matching ?", ( abs(integ1 - integ1_bis) < 1e-8 ) - fPart12.getMesh().scale([0.,0.,0.], 1.2) - integ2 = fPart12.integral(0,True) - print "Second integral matching ?", ( abs(integ2-integ1_bis*1.2*1.2*1.2) < 1e-8 ) - # Explosion of field - fVec = mesh.fillFromAnalytic(mc.ON_CELLS,3,"(x-5.)*IVec+(y-5.)*JVec+(z-5.)*KVec") - fVecPart1 = fVec.buildSubPart(ids1) - fVecPart1.setName("fVecPart1") - cells = fPart1.getMesh().getNumberOfCells() * [None] - for icell,vec in enumerate(fVecPart1.getArray()): - m = fPart1.getMesh()[[icell]] - m.zipCoords() # Not mandatory but saves memory - m.translate(vec) - cells[icell] = m - pass - meshFVecPart1Exploded = mc.MEDCouplingUMesh.MergeUMeshes(cells) - fPart1.setMesh(meshFVecPart1Exploded) - fPart1.writeVTK("ExoField_fPart1_explo.vtu") - - diff --git a/medtool/doc/tutorial/atestMEDCouplingLoaderEx1.rst b/medtool/doc/tutorial/atestMEDCouplingLoaderEx1.rst deleted file mode 100644 index 2057adcaf..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingLoaderEx1.rst +++ /dev/null @@ -1,124 +0,0 @@ - -.. _python_testmedcouplingloaderex1_solution: - -Agitateur - Swirler -~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDLoader as ml - import numpy as np - - # Get available time steps - data = ml.MEDFileData("agitateur.med") - ts = data.getFields()[0].getTimeSteps() - print ts - # Get position of the swirler - fMts = data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"] - f1ts = fMts[(2,-1)] - fMc = f1ts.getFieldAtLevel(ml.ON_CELLS,0) - arr = fMc.getArray() - arr.getMinMaxPerComponent() # just to see the field variation range per component - ids = arr.getIdsInRange(0.,1.) - f2Mc = fMc[ids] - # Extract pression field on the swirler - pressMts = data.getFields()["PRESSION_ELEM_DOM"] - press1ts = pressMts[(2,-1)] - pressMc = press1ts.getFieldAtLevel(ml.ON_CELLS,0) - pressOnAgitateurMc = pressMc[ids] - # - pressOnAgitateurMc.getMesh().zipCoords() - # Compute pressure on skin - agitateurMesh3DMc = pressOnAgitateurMc.getMesh() - m3DSurf,desc,descI,revDesc,revDescI = agitateurMesh3DMc.buildDescendingConnectivity() - nbOf3DCellSharing = revDescI.deltaShiftIndex() - ids2 = nbOf3DCellSharing.getIdsEqual(1) - agitateurSkinMc = m3DSurf[ids2] - offsetsOfTupleIdsInField = revDescI[ids2] - tupleIdsInField = revDesc[offsetsOfTupleIdsInField] - pressOnSkinAgitateurMc = pressOnAgitateurMc[tupleIdsInField] - pressOnSkinAgitateurMc.setMesh(agitateurSkinMc) - # Force field computation - pressSkin = pressOnSkinAgitateurMc.getArray() - pressSkin *= 1e5 # conversion from bar to Pa - areaSkin = agitateurSkinMc.getMeasureField(True).getArray() - forceSkin = pressSkin*areaSkin - normalSkin = agitateurSkinMc.buildOrthogonalField().getArray() - forceVectSkin = forceSkin*normalSkin - # Torque computation - singlePolyhedron = agitateurMesh3DMc.buildSpreadZonesWithPoly() - singlePolyhedron.orientCorrectlyPolyhedrons() - centerOfMass = singlePolyhedron.getBarycenterAndOwner() - - barySkin=agitateurSkinMc.getBarycenterAndOwner() - posSkin = barySkin-centerOfMass - - torquePerCellOnSkin = ml.DataArrayDouble.CrossProduct(posSkin,forceVectSkin) - - zeTorque = torquePerCellOnSkin.accumulate() - print "couple = %r N.m" % zeTorque[2] - # Power computation - speedMts = data.getFields()["VITESSE_ELEM_DOM"] - speed1ts = speedMts[(2,-1)] - speedMc = speed1ts.getFieldAtLevel(ml.ON_CELLS,0) - speedOnSkin = speedMc.getArray()[tupleIdsInField] - powerSkin = ml.DataArrayDouble.Dot(forceVectSkin,speedOnSkin) - power = powerSkin.accumulate()[0] - print "power = %r W"%(power) - # Eigen vector computation - x2 = posSkin[:,0]*posSkin[:,0] - x2 = x2.accumulate()[0] - y2 = posSkin[:,1]*posSkin[:,1] - y2 = y2.accumulate()[0] - xy = posSkin[:,0]*posSkin[:,1] - xy = xy.accumulate()[0] - inertiaSkin = np.matrix([[x2,xy],[xy,y2]]) - inertiaSkinValues, inertiaSkinVects = np.linalg.eig(inertiaSkin) - pos = max(enumerate(inertiaSkinValues), key=lambda x: x[1])[0] - vect0 = inertiaSkinVects[pos].tolist()[0] - print vect0 - - def computeAngle(locAgitateur1ts): - fMc = locAgitateur1ts.getFieldAtLevel(ml.ON_CELLS,0) - arr = fMc.getArray() - ids = arr.getIdsInRange(0.,1.) - f2Mc = fMc[ids] - m3DSurf,desc,descI,revDesc,revDescI = f2Mc.getMesh().buildDescendingConnectivity() - nbOf3DCellSharing = revDescI.deltaShiftIndex() - ids2 = nbOf3DCellSharing.getIdsEqual(1) - agitateurSkinMc = m3DSurf[ids2] - # - singlePolyhedron = agitateurMesh3DMc.buildSpreadZonesWithPoly() - singlePolyhedron.orientCorrectlyPolyhedrons() - centerOfMass = singlePolyhedron.getBarycenterAndOwner() - bary = agitateurSkinMc.getBarycenterAndOwner() - posSkin = bary-centerOfMass - x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] - y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] - xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] - inertiaSkin = np.matrix([[x2,xy],[xy,y2]]) - inertiaSkinValues,inertiaSkinVects = np.linalg.eig(inertiaSkin) - pos = max(enumerate(inertiaSkinValues), key=lambda x: x[1])[0] - vect0 = inertiaSkinVects[pos].tolist()[0] - return vect0 - - vects = len(ts)*[None] - for itts,locAgitateur1ts in zip(ts,data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"]): - angle = computeAngle(locAgitateur1ts) - vects[itts[0]] = angle - pass - - from math import acos, sqrt - angle2 = len(ts)*[0.] - for pos in xrange(2,len(vects)): - norm1 = sqrt(vects[pos-1][0]*vects[pos-1][0]+vects[pos-1][1]*vects[pos-1][1]) - norm2 = sqrt(vects[pos][0]*vects[pos][0]+vects[pos][1]*vects[pos][1]) - crs = vects[pos-1][0]*vects[pos][0]+vects[pos-1][1]*vects[pos][1] - crs /= norm1 ; crs /= norm2 ; crs = min(crs,1.) - angle2[pos] = acos(crs) #/(ts[pos][2]-ts[pos-1][2]) - pass - - omega=sum(angle2)/(ts[-1][2]-ts[0][2]) - print sum(angle2) - - print "At timestep (%d,%d) (physical time=%r s) the torque is: %r N.m, power/omega=%r N.m " % (ts[2][0],ts[2][1],ts[2][2],zeTorque[2],power/omega) diff --git a/medtool/doc/tutorial/atestMEDCouplingLoaderEx2.rst b/medtool/doc/tutorial/atestMEDCouplingLoaderEx2.rst deleted file mode 100644 index 3ea615ab9..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingLoaderEx2.rst +++ /dev/null @@ -1,115 +0,0 @@ - -.. _python_testmedcouplingloaderex2_solution: - -Intersection géométrique de maillages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDLoader as ml - - def displayVTK(m,fname): - tmp = m.deepCpy() - tmp.tessellate2D(0.1) - tmp.writeVTK(fname) - return - - # Read and clean Fixe.med - fixe = ml.MEDFileMesh.New("Fixe.med") - fixm = fixe.getMeshAtLevel(0) - print "Nb of nodes in the file : %i " % (fixm.getNumberOfNodes()) - fixm.mergeNodes(1e-10) - print "Nb of non duplicated nodes : %i" % (fixm.getNumberOfNodes()) - # Read and clean Mobile.med - mobile = ml.MEDFileMesh.New("Mobile.med") - mobm = mobile.getMeshAtLevel(0) - mobm.mergeNodes(1e-10) - # Visualize fixm and mobm with PARAVIEW - fixm2 = fixm.deepCpy() # tessellate2D() modifies the current mesh - fixm2.tessellate2D(0.1) - fixm2.writeVTK("fixm2.vtu") - mobm2 = mobm.deepCpy() - mobm2.tessellate2D(0.1) - mobm2.writeVTK("mobm2.vtu") - # mobm2 is in several pieces, take the first one - zonesInMobm = mobm.partitionBySpreadZone() - print "Nb of zones in mobm : %i" % (len(zonesInMobm)) - zone1Mobm = mobm[zonesInMobm[0]] - zone1Mobm.zipCoords() - displayVTK(zone1Mobm, "zone1Mobm.vtu") - # Get cell ids from the fix part in the boudning box of zone1Mobm - ids2 = fixm.getCellsInBoundingBox(zone1Mobm.getBoundingBox(),1e-10) - partFixm = fixm[ids2] - partFixm.zipCoords() - displayVTK(partFixm,"partFixm.vtu") - # Intersect partFixm with zone1Mobm - partFixMob, iPart, iMob = ml.MEDCouplingUMesh.Intersect2DMeshes(partFixm,zone1Mobm,1e-10) - partFixMob.mergeNodes(1e-10) - # Get the part of partFixm not included in zone1Mobm using partFixMob - ids3 = iMob.getIdsEqual(-1) - partFixmWithoutZone1Mobm = partFixMob[ids3] - displayVTK(partFixmWithoutZone1Mobm,"partFixmWithoutZone1Mobm.vtu") - # Check that intersection worked properly - # Check #0 - areaPartFixm = partFixm.getMeasureField(ml.ON_CELLS).getArray() - areaPartFixm.abs() - areaPartFixMob = partFixMob.getMeasureField(ml.ON_CELLS).getArray() - areaPartFixMob.abs() - val1=areaPartFixm.accumulate()[0] - val2=areaPartFixMob.accumulate()[0] - print "Check #0 %lf == %lf with precision 1e-8? %s" % (val1,val2,str(abs(val1-val2)<1e-8)) - # Check #1 - areaZone1Mobm = zone1Mobm.getMeasureField(ml.ON_CELLS).getArray() - areaZone1Mobm.abs() - val3 = areaZone1Mobm.accumulate()[0] - ids4 = iMob.getIdsNotEqual(-1) - areaPartFixMob2 = areaPartFixMob[ids4] - val4 = areaPartFixMob2.accumulate()[0] - print "Check #1 %lf == %lf with precision 1e-8 ? %s" % (val3,val4,str(abs(val3-val4)<1e-8)) - # Check #2 - isCheck2OK = True - for icell in xrange(partFixm.getNumberOfCells()): - ids5 = iPart.getIdsEqual(icell) - areaOfCells = areaPartFixMob[ids5] - areaOfCells.abs() - if abs(areaOfCells.accumulate()[0] - areaPartFixm[icell]) > 1e-9: - isCheck2OK = False - pass - pass - print "Check #2? %s" % (str(isCheck2OK)) - # Indicator field creation - f = ml.MEDCouplingFieldDouble(ml.ON_CELLS,ml.ONE_TIME) - m = partFixMob.deepCpy() - m.tessellate2D(0.1) - f.setMesh(m) - arr = ml.DataArrayDouble(partFixMob.getNumberOfCells(),1) - arr[iMob.getIdsEqual(-1)] = 0. - arr[iMob.getIdsNotEqual(-1)] = 1. - f.setArray(arr) - f.checkCoherency() - f.setName("Zone") - ml.MEDCouplingFieldDouble.WriteVTK("Zone.vtu",[f]) - # Other zones - zonesMobm = ml.MEDCouplingUMesh.MergeUMeshesOnSameCoords([mobm[zonesInMobm[0]], mobm[zonesInMobm[1]], mobm[zonesInMobm[5]]]) - zonesMobm.zipCoords() - partFixMob2,iPart2,iMob2 = ml.MEDCouplingUMesh.Intersect2DMeshes(partFixm,zonesMobm,1e-10) - partFixMob2.mergeNodes(1e-10) - f2 = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) - m2 = partFixMob2.deepCpy() - m2.tessellate2D(0.1) - f2.setMesh(m2) - arr = ml.DataArrayDouble(partFixMob2.getNumberOfCells(),1) - arr[iMob2.getIdsEqual(-1)]=0. - st = 0 - end = st + len(zonesInMobm[0]) - arr[iMob2.getIdsInRange(st,end)] = 1. - st += len(zonesInMobm[0]) ; - end = st + len(zonesInMobm[1]) - arr[iMob2.getIdsInRange(st,end)] = 2. - st += len(zonesInMobm[1]) - end = st + len(zonesInMobm[2]) - arr[iMob2.getIdsInRange(st,end)] = 3. - f2.setArray(arr) - f2.checkCoherency() - f2.setName("Zone2") - ml.MEDCouplingFieldDouble.WriteVTK("Zone2.vtu",[f2]) diff --git a/medtool/doc/tutorial/atestMEDCouplingNumPy.rst b/medtool/doc/tutorial/atestMEDCouplingNumPy.rst deleted file mode 100644 index c3641f1a5..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingNumPy.rst +++ /dev/null @@ -1,78 +0,0 @@ - -.. _python_testMEDCouplingNumPy_solution: - -Playing with NumPy and SciPy -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDCoupling as mc - - # - # NumPy - # - import numpy as np - - # Checking NumPy binding - assert(mc.MEDCouplingHasNumPyBindings()) - # Playing with conversion and shared data - arr = mc.DataArrayDouble(12) - arr[:] = 4. - nparr = arr.toNumPyArray() - print nparr.__repr__() - print nparr.tolist() - nparr[::2] = 7. - print nparr.__repr__() - print arr.__repr__() - del arr - import gc; gc.collect() # Make sure the object has been deleted - print nparr.__repr__() - arr2 = mc.DataArrayDouble(nparr) - print arr2.__repr__() - nparr[:] = 5. - print nparr.__repr__() - print arr2.__repr__() - # Writing to file - f = open("toto.data","w+b") - a = np.memmap(f,dtype='float64',mode='w+',offset=0,shape=nparr.shape) - a[:] = nparr[:] - f.flush() - # Re-reading file - f2 = open("toto.data","r+b") - b = np.memmap(f2,dtype='float64',mode='r',offset=0,shape=(12,)) - a[:] = 3.14 - f.flush() - b = np.memmap(f2,dtype='float64',mode='r',offset=0,shape=(12,)) - print b.__repr__() - # - # SciPy - # - assert(mc.MEDCouplingHasSciPyBindings()) - c1 = mc.MEDCouplingCMesh() - arr1 = mc.DataArrayDouble(7) - arr1.iota() - c1.setCoords(arr1,arr1,arr1) - c2 = mc.MEDCouplingCMesh() - arr2 = mc.DataArrayDouble(9) - arr2.iota() - arr2 *= 6./8. - c2.setCoords(arr2,arr2,arr2) - c1 = c1.buildUnstructured() - c2 = c2.buildUnstructured() - c2.translate([6.,0.,0.]) - c = mc.MEDCouplingUMesh.MergeUMeshes([c1,c2]) - c.mergeNodes(1e-12) - skinAndNCFaces = c.computeSkin() - skinAndNCFaces.zipCoords() - # Isolating non conform cells - from MEDCouplingRemapper import MEDCouplingRemapper - rem = MEDCouplingRemapper() - rem.setMaxDistance3DSurfIntersect(1e-12) - rem.setMinDotBtwPlane3DSurfIntersect(0.99) - rem.prepare(skinAndNCFaces,skinAndNCFaces,"P0P0") - mat = rem.getCrudeCSRMatrix() - indptr = mc.DataArrayInt(mat.indptr) - indptr2 = indptr.deltaShiftIndex() - cellIdsOfSkin = indptr2.getIdsEqual(1) - skin = skinAndNCFaces[cellIdsOfSkin] - skin.writeVTK("skin.vtu") diff --git a/medtool/doc/tutorial/atestMEDCouplingPoly.rst b/medtool/doc/tutorial/atestMEDCouplingPoly.rst deleted file mode 100644 index 949fe3091..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingPoly.rst +++ /dev/null @@ -1,97 +0,0 @@ - -.. _python_testMEDCoupling2D_solution: - -2D polygons meshing -~~~~~~~~~~~~~~~~~~~ - -:: - - from MEDCoupling import * - from MEDLoader import * - - from math import * - - numberOfNodes = 25 - numberOfCells = 12 - - print "1 ********************" - spaceDimension = 2 - - # Coordinates of central polygon - X = [1.,0.5,-0.5,-1.,-0.5,0.5] - Y = [0.,sqrt(3.)/2.,sqrt(3.)/2.,0.,-sqrt(3.)/2.,-sqrt(3.)/2.] - - coordinates = [] - # origin - coordinates.append(0.) - coordinates.append(0.) - - # central polygon - for i in range(6): - coordinates.append(X[i]) - coordinates.append(Y[i]) - - # Coordinates of second couron - xc = 1.5 - yc = - sqrt(3.)/2. - d = sqrt(xc*xc+yc*yc) - a30 = pi/6.0 - a60 = pi/3.0 - - for i in range(6): - angle = a30+a60*i - xtmp = d*cos(angle) - ytmp = d*sin(angle) - start = (i-1)%6 - coordinates.append(xtmp+X[(i-1)%6]) - coordinates.append(ytmp+Y[(i-1)%6]) - coordinates.append(xtmp+X[i%6]) - coordinates.append(ytmp+Y[i%6]) - coordinates.append(xtmp+X[(i+1)%6]) - coordinates.append(ytmp+Y[(i+1)%6]) - - print "2 ********************" - # Creation of mesh - mesh=MEDCouplingUMesh.New() - mesh.setMeshDimension(2) - mesh.allocateCells(numberOfCells) - mesh.setName("MaFleur") - - myCoords=DataArrayDouble.New() - myCoords.setValues(coordinates,numberOfNodes,2) - mesh.setCoords(myCoords) - - print "3 ********************" - # Connectivity of triangular meshing - connectivity = [] - for i in range(6): - connectivity.append(0) - connectivity.append(i%6+1) - connectivity.append((i+1)%6+1) - for i in range(6): - mesh.insertNextCell(NORM_TRI3,3,connectivity[3*i:3*(i+1)]) - pass - - print "4 ********************" - # Connectivity of hexagons - connectivity = [] - for i in range(6): - start = i%6+1 - connectivity.append(start) - connectivity.append(start+2*(i+3)) - connectivity.append(start+2*(i+3)+1) - connectivity.append(start+2*(i+3)+2) - if i==5: - connectivity.append(7) - else: - connectivity.append(start+2*(i+3)+3) - connectivity.append((i+1)%6+1) - for i in range(6): - mesh.insertNextCell(NORM_POLYGON,6,connectivity[6*i:6*(i+1)]) - pass - - print "5 ********************" - mesh.checkCoherency() - - medFileName = "MEDCoupling_Fleur.med" - MEDLoader.WriteUMesh(medFileName,mesh,True) diff --git a/medtool/doc/tutorial/atestMEDCouplingRead.rst b/medtool/doc/tutorial/atestMEDCouplingRead.rst deleted file mode 100644 index c0f4c476e..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingRead.rst +++ /dev/null @@ -1,47 +0,0 @@ - -.. _python_testMEDCouplingRead_solution: - -Read med File -~~~~~~~~~~~~~~~~~~~ - -:: - - from MEDCoupling import * - from MEDLoader import * - - - medFileName = "MEDCoupling_cube3D.med" - MeshName = "3Dcube" - FieldName = "field" - Field2DName = "fieldBottomFace" - - # Retrieving meshes - mesh3D = MEDLoader.ReadUMeshFromFile(medFileName,MeshName,0) - mesh2D = MEDLoader.ReadUMeshFromFile(medFileName,MeshName,-1) - - # Retrieving fields - f = MEDLoader.ReadFieldCell(medFileName,mesh3D.getName(),0,FieldName,-1,-1) - f2 = MEDLoader.ReadFieldCell(medFileName,mesh2D.getName(),-1,Field2DName,-1,-1) - - # Retrieving Coords Mesh - Coords3D = mesh3D.getCoords() - Values = Coords3D.getValuesAsTuple() - - # Retrieving field value on 0 tuple - pos= Values[0] - res=f.getValueOn(pos) - - # Verify if value is OK - bar = mesh3D.getBarycenterAndOwner() - x=bar.getIJ(1,1) - y=bar.getIJ(1,2) - z=bar.getIJ(1,3) - - from math import * - d = sqrt(x*x+y*y+z*z) - sinus = sin(d) - - if abs(res[0]-sinus)<1.e-5: - print "OK" - else: - print "KO" diff --git a/medtool/doc/tutorial/atestMEDCouplingRemapper.rst b/medtool/doc/tutorial/atestMEDCouplingRemapper.rst deleted file mode 100644 index 06a3beba2..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingRemapper.rst +++ /dev/null @@ -1,68 +0,0 @@ - -.. _python_testMEDCouplingremapper1_solution: - -Interpoler avec MEDCouplingRemapper -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDCoupling as mc - from MEDCouplingRemapper import MEDCouplingRemapper - # Target mesh - arr = mc.DataArrayDouble(11) - arr.iota(0) - trgMesh = mc.MEDCouplingCMesh() - trgMesh.setCoords(arr,arr) - trgMesh = trgMesh.buildUnstructured() - # Source mesh - arr = mc.DataArrayDouble(21) - arr.iota(0) - arr *= 0.5 - srcMesh = mc.MEDCouplingCMesh() - srcMesh.setCoords(arr,arr) - srcMesh = srcMesh.buildUnstructured() - # Triangularize some cells in source - tmp = srcMesh[:20] # Extract a sub-part of srcMesh - tmp.simplexize(0) - srcMesh = mc.MEDCouplingUMesh.MergeUMeshes([tmp,srcMesh[20:]]) - # Interpolate cells to cells - remap = MEDCouplingRemapper() - remap.prepare(srcMesh,trgMesh,"P0P0") - # Check matrix - myMatrix = remap.getCrudeMatrix() - print myMatrix - sumByRows = mc.DataArrayDouble(len(myMatrix)) - for i,wIt in enumerate(sumByRows): - su = 0. - for it in myMatrix[i]: - su += myMatrix[i][it] - wIt[0] = su - print "Is interpolation well prepared?", sumByRows.isUniform(1.,1e-12) - # Source field construction - srcField = mc.MEDCouplingFieldDouble(mc.ON_CELLS, mc.ONE_TIME) - srcField.setMesh(srcMesh) - srcField.fillFromAnalytic(1,"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))") - srcField.getArray().setInfoOnComponent(0, "powercell [W]") - # Transfer field - #remap.transferField(srcField, 1e300) - srcField.setNature(mc.ConservativeVolumic) - trgFieldCV = remap.transferField(srcField,1e300) - # ConservativeVolumic - integSource = srcField.integral(True)[0] - integTarget = trgFieldCV.integral(True)[0] - print "ConservativeVolumic -- integrals: %lf == %lf" % (integSource, integTarget) - - accSource = srcField.getArray().accumulate()[0] - accTarget = trgFieldCV.getArray().accumulate()[0] - print "ConservativeVolumic -- sums: %lf != %lf" % (accSource, accTarget) - # IntegralGlobConstraint - srcField.setNature(mc.IntegralGlobConstraint) - trgFieldI = remap.transferField(srcField,1e300) - # - integSource = srcField.integral(True)[0] - integTarget = trgFieldI.integral(True)[0] - print "IntegralGlobConstraint -- integrals: %lf != %lf" % (integSource, integTarget) - - accSource = srcField.getArray().accumulate()[0] - accTarget = trgFieldI.getArray().accumulate()[0] - print "IntegralGlobConstraint -- sums: %lf == %lf" % (accSource, accTarget) diff --git a/medtool/doc/tutorial/atestMEDCouplingUMesh1.rst b/medtool/doc/tutorial/atestMEDCouplingUMesh1.rst deleted file mode 100644 index 6734be770..000000000 --- a/medtool/doc/tutorial/atestMEDCouplingUMesh1.rst +++ /dev/null @@ -1,98 +0,0 @@ - -.. _python_testMEDCouplingumesh1_solution: - -Playing with unstructured mesh -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDCoupling as mc - - # Build a 3D mesh from scratch mixing HEXA8 and POLYHED - coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - conn=[0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - mesh3D = mc.MEDCouplingUMesh("mesh3D",3); - mesh3D.allocateCells(18); - mesh3D.insertNextCell(mc.NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[110:118]); - mesh3D.insertNextCell(mc.NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[228:236]); - mesh3D.insertNextCell(mc.NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[346:354]); - myCoords = mc.DataArrayDouble(coords,60,3); - myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) - mesh3D.setCoords(myCoords); - mesh3D.orientCorrectlyPolyhedrons() - mesh3D.sortCellsInMEDFileFrmt() - mesh3D.checkCoherency() - renum = mc.DataArrayInt(60) ; renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) - mesh3D.renumberNodes(renum,60) - # Scale coordinates from meters to centimeters - mesh3D.getCoords()[:] *= 100. - mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) - # Identify unique Z values - zLev = mesh3D.getCoords()[:,2] - zLev = zLev.getDifferentValues(1e-12) - zLev.sort() - # Extract cells from a given Z level - Solution 1 - tmp,cellIdsSol1 = mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2],[0.,0.,1.],1e-12) - # Idem - Solution 2 - bary = mesh3D.getBarycenterAndOwner() - baryZ = bary[:,2] - cellIdsSol2 = baryZ.getIdsInRange(zLev[1],zLev[2]) - # Idem - Solution 3 - nodeIds = mesh3D.findNodesOnPlane([0.,0.,zLev[0]],[0.,0.,1.],1e-10) - mesh2D = mesh3D.buildFacePartOfMySelfNode(nodeIds,True) - extMesh = mc.MEDCouplingExtrudedMesh(mesh3D,mesh2D,0) - n_cells = mesh2D.getNumberOfCells() - cellIdsSol3 = extMesh.getMesh3DIds()[n_cells:2*n_cells] - # Compare the 3 methods - print cellIdsSol1.getValues() - print cellIdsSol2.getValues() - print cellIdsSol3.getValues() - # Extract part of the mesh - mesh3DPart = mesh3D[cellIdsSol2] # equivalent to mesh3DPart = mesh3D.buildPartOfMySelf(cellIdsSol2,True) - mesh3DPart.zipCoords() - # Check geometric type ordering - #print mesh3DPart.advancedRepr() - print mesh3DPart.checkConsecutiveCellTypesAndOrder([mc.NORM_HEXA8,mc.NORM_POLYHED]) - print mesh3DPart.checkConsecutiveCellTypes() - #print mesh3DPart.advancedRepr() - # Extract cells along a line - Solution 1 - baryXY = bary[:,[0,1]] - baryXY -= [250.,150.] - magn = baryXY.magnitude() - cellIds2Sol1 = magn.getIdsInRange(0.,1e-12) - # Extract cells along a line - Solution 2 - bary2 = mesh2D.getBarycenterAndOwner()[:,[0,1]] - bary2 -= [250.,150.] - magn = bary2.magnitude() - ids = magn.getIdsInRange(0.,1e-12) - idStart = int(ids) # ids is assumed to contain only one value, if not an exception is thrown - ze_range = range(idStart,mesh3D.getNumberOfCells(),mesh2D.getNumberOfCells()) - cellIds2Sol2 = extMesh.getMesh3DIds()[ze_range] - # Construct the final sub-part - mesh3DSlice2 = mesh3D[cellIds2Sol1] - mesh3DSlice2.zipCoords() - # Aggregate two meshes, one being the translated version of the original - mesh3DSlice2bis = mesh3DSlice2.deepCpy() - mesh3DSlice2bis.translate([0.,1000.,0.]) - mesh3DSlice2All = mc.MEDCouplingUMesh.MergeUMeshes([mesh3DSlice2,mesh3DSlice2bis]) - mesh3DSlice2All.writeVTK("mesh3DSlice2All.vtu") - # Discover descending connectivity - mesh3DSurf,desc,descIndx,revDesc,revDescIndx = mesh3D.buildDescendingConnectivity() - numberOf3DCellSharing = revDescIndx.deltaShiftIndex() - cellIds = numberOf3DCellSharing.getIdsNotEqual(1) - mesh3DSurfInside = mesh3DSurf[cellIds] - mesh3DSurfInside.writeVTK("mesh3DSurfInside.vtu") - diff --git a/medtool/doc/tutorial/atestMEDLoaderAdvancedAPI1.rst b/medtool/doc/tutorial/atestMEDLoaderAdvancedAPI1.rst deleted file mode 100644 index 788093ccc..000000000 --- a/medtool/doc/tutorial/atestMEDLoaderAdvancedAPI1.rst +++ /dev/null @@ -1,95 +0,0 @@ - -.. _python_testMEDLoaderAdvancedAPI1_solution: - -Reading, Writing a MED file using MEDLoader advanced API -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDLoader as ml - from MEDLoader import MEDLoader - # Mesh creation - targetCoords = [-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn = [0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh = ml.MEDCouplingUMesh("MyMesh",2) - targetMesh.allocateCells(5) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[14:18]) - myCoords = ml.DataArrayDouble(targetCoords,9,2) - myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) - targetMesh.setCoords(myCoords) - # Build the 2D faces from the 3D volumes (descending connectivity) - targetMeshConsti, _, _, _, _ = targetMesh.buildDescendingConnectivity() - targetMesh1 = targetMeshConsti[[3,4,7,8]] - targetMesh1.setName(targetMesh.getName()) - # - # Meshes - # - meshMEDFile = ml.MEDFileUMesh() - meshMEDFile.setMeshAtLevel(0,targetMesh) - meshMEDFile.setMeshAtLevel(-1,targetMesh1) - # Some groups on cells Level 0 - grp0_0 = ml.DataArrayInt([0,1,3]) - grp0_0.setName("grp0_Lev0") - grp1_0 = ml.DataArrayInt([1,2,3,4]) - grp1_0.setName("grp1_Lev0") - meshMEDFile.setGroupsAtLevel(0, [grp0_0,grp1_0]) - # Some groups on cells Level -1 - grp0_M1 = ml.DataArrayInt([0,1]) - grp0_M1.setName("grp0_LevM1") - grp1_M1 = ml.DataArrayInt([0,1,2]) - grp1_M1.setName("grp1_LevM1") - grp2_M1 = ml.DataArrayInt([1,2,3]) - grp2_M1.setName("grp2_LevM1") - meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) - # Write everything - meshMEDFile.write("TargetMesh2.med",2) # 2 stands for write from scratch - # Re-read and test equality - meshMEDFileRead = ml.MEDFileMesh.New("TargetMesh2.med") # a new is needed because it returns a MEDFileUMesh (MEDFileMesh is abstract) - meshRead0 = meshMEDFileRead.getMeshAtLevel(0) - meshRead1 = meshMEDFileRead.getMeshAtLevel(-1) - print "Is level 0 in the file equal to 'targetMesh'?", meshRead0.isEqual(targetMesh,1e-12) - print "Is level 0 in the file equal to 'targetMesh1'?", meshRead1.isEqual(targetMesh1,1e-12) - # Read groups - print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") - grp0_0_read = meshMEDFileRead.getGroupArr(0,"grp0_Lev0") - print "Is group 'grp0_Lev0' equal to what is read in the file?" , grp0_0_read.isEqual(grp0_0) - # - # Fields - # - f = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) - f.setTime(5.6,7,8) - f.setArray(targetMesh.getBarycenterAndOwner()) - f.setMesh(targetMesh) - f.setName("AFieldName") - # Prepare field for writing - fMEDFile = ml.MEDFileField1TS() - fMEDFile.setFieldNoProfileSBT(f) # No profile desired on the field, Sort By Type - # *Append* the field to an existing file - fMEDFile.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it - # Read the field - fMEDFileRead = ml.MEDFileField1TS("TargetMesh2.med",f.getName(),7,8) - fRead1 = fMEDFileRead.getFieldOnMeshAtLevel(ml.ON_CELLS,0,meshMEDFileRead) # Quickest way, not re-reading mesh in the file. - fRead2 = fMEDFileRead.getFieldAtLevel(ml.ON_CELLS,0) # Like above, but this time the mesh is read! - print "Does the field remain OK with the quick method?", fRead1.isEqual(f,1e-12,1e-12) - print "Does the field remain OK with the slow method?", fRead2.isEqual(f,1e-12,1e-12) - # - # Writing and Reading fields on profile using MEDLoader advanced API - # - pfl = ml.DataArrayInt([1,2,3]) - pfl.setName("My1stPfl") - fPart = f.buildSubPart(pfl) - fPart.setName("fPart") - # - fMEDFile2 = ml.MEDFileField1TS() - fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) # 0 is the relative level (here 0 means 3D) - fMEDFile2.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file - # - fMEDFileRead2 = ml.MEDFileField1TS("TargetMesh2.med",fPart.getName(),7,8) - fPartRead, pflRead = fMEDFileRead2.getFieldWithProfile(ml.ON_CELLS,0,meshMEDFileRead) - print "Is the partial field correclty read?", fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) - print "Is the list of cell identifiers matching?", pflRead.isEqualWithoutConsideringStr(pfl) - diff --git a/medtool/doc/tutorial/atestMEDLoaderBasicAPI1.rst b/medtool/doc/tutorial/atestMEDLoaderBasicAPI1.rst deleted file mode 100644 index c610ae616..000000000 --- a/medtool/doc/tutorial/atestMEDLoaderBasicAPI1.rst +++ /dev/null @@ -1,52 +0,0 @@ - -.. _python_testMEDLoaderBasicAPI1_solution: - -Reading, Writing a MED file using MEDLoader basic API -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDLoader as ml - from MEDLoader import MEDLoader - # Mesh creation - targetCoords = [-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn = [0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh = ml.MEDCouplingUMesh("MyMesh",2) - targetMesh.allocateCells(5) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[14:18]) - myCoords = ml.DataArrayDouble(targetCoords,9,2) - myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) - targetMesh.setCoords(myCoords) - # Writing mesh only - MEDLoader.WriteUMesh("TargetMesh.med",targetMesh,True) # True means 'from scratch' - # Re-read it and test equality - meshRead = MEDLoader.ReadUMeshFromFile("TargetMesh.med",targetMesh.getName(),0) - print "Is the read mesh equal to 'targetMesh' ?", meshRead.isEqual(targetMesh,1e-12) - # Writing a field and its support mesh in one go - f = ml.MEDCouplingFieldDouble.New(ml.ON_CELLS, ml.ONE_TIME) - f.setTime(5.6,7,8) # Declare the timestep associated to the field - f.setArray(targetMesh.getBarycenterAndOwner()) - f.setMesh(targetMesh) - f.setName("AFieldName") - MEDLoader.WriteField("MyFirstField.med",f,True) - # Re-read it ans test equality - f2 = MEDLoader.ReadFieldCell("MyFirstField.med", f.getMesh().getName(), 0, f.getName(), 7, 8) - print "Is the read field identical to 'f' ?", f2.isEqual(f,1e-12,1e-12) - # Writing in several steps - MEDLoader.WriteUMesh("MySecondField.med",f.getMesh(),True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f) - # A second field to write - f2 = f.clone(True) # 'True' means that we need a deep copy - f2.getArray()[:] = 2.0 - f2.setTime(7.8,9,10) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f2) - # Re-read and test this two-timestep field - f3 = MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),7,8) - print "Is the field read in file equals to 'f' ?", f.isEqual(f3,1e-12,1e-12) - f4 = MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),9,10) - print "Is the field read in file equals to 'f2' ?", f2.isEqual(f4,1e-12,1e-12) - diff --git a/medtool/doc/tutorial/atestMEDLoaderSplitAndMerge1.rst b/medtool/doc/tutorial/atestMEDLoaderSplitAndMerge1.rst deleted file mode 100644 index aa498a873..000000000 --- a/medtool/doc/tutorial/atestMEDLoaderSplitAndMerge1.rst +++ /dev/null @@ -1,124 +0,0 @@ - -.. _python_testMEDLoaderSplitAndMerge1_solution: - -Splitting and Merging a MED file using MEDLoader -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - import MEDLoader as ml - from MEDLoader import MEDLoader - - m0 = ml.MEDCouplingCMesh() - arr = ml.DataArrayDouble(31,1) ; arr.iota(0.) - m0.setCoords(arr,arr) - m0 = m0.buildUnstructured() - m00 = m0[::2] # Extract even cells - m00.simplexize(0) - m01 = m0[1::2] - m0 = ml.MEDCouplingUMesh.MergeUMeshes([m00,m01]) - m0.getCoords()[:] *= 1/15. - m0.setName("mesh") - # Cell field - cellField = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) - cellField.setTime(5.6,5,6) - cellField.setMesh(m0) - cellField.setName("CellField") - cellField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") - cellField.getArray().setInfoOnComponent(0,"powercell [W]") - # Node field - nodeField = ml.MEDCouplingFieldDouble(ml.ON_NODES,ml.ONE_TIME) - nodeField.setTime(5.6,5,6) - nodeField.setMesh(m0) - nodeField.setName("NodeField") - nodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") - nodeField.getArray().setInfoOnComponent(0,"powernode [W]") - # Splitting - proc0 = m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) - proc1 = proc0.buildComplement(m0.getNumberOfCells()) - # - nodeField0 = nodeField[proc0] ; cellField0 = cellField[proc0] ; cellField0.setMesh(nodeField0.getMesh()) - nodeField1 = nodeField[proc1] ; cellField1 = cellField[proc1] ; cellField1.setMesh(nodeField1.getMesh()) - - proc0_fname = "proc0.med" - MEDLoader.WriteField(proc0_fname, nodeField0, True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc0_fname, cellField0) - - proc1_fname = "proc1.med" - MEDLoader.WriteField(proc1_fname,nodeField1,True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc1_fname,cellField1) - # - # Merging - Sub-optimal method - # - cellField0_read = MEDLoader.ReadFieldCell("proc0.med","mesh",0,"CellField",5,6) - cellField1_read = MEDLoader.ReadFieldCell("proc1.med","mesh",0,"CellField",5,6) - cellField_read = ml.MEDCouplingFieldDouble.MergeFields([cellField0_read,cellField1_read]) - cellFieldCpy = cellField.deepCpy() - cellFieldCpy.substractInPlaceDM(cellField_read,10,1e-12) - cellFieldCpy.getArray().abs() - print cellFieldCpy.getArray().isUniform(0.,1e-12) - # - nodeField0_read = MEDLoader.ReadFieldNode("proc0.med","mesh",0,"NodeField",5,6) - nodeField1_read = MEDLoader.ReadFieldNode("proc1.med","mesh",0,"NodeField",5,6) - nodeField_read = ml.MEDCouplingFieldDouble.MergeFields([nodeField0_read, nodeField1_read]) - nodeField_read.mergeNodes(1e-10) - nodeFieldCpy = nodeField.deepCpy() - nodeFieldCpy.mergeNodes(1e-10) - nodeFieldCpy.substractInPlaceDM(nodeField_read,10,1e-12) - print nodeFieldCpy.getArray().isUniform(0.,1e-12) - # - # Merging - Optimal method - # - fileNames = ["proc0.med","proc1.med"] - msML = [ml.MEDFileMesh.New(fname) for fname in fileNames] - fsML = [ml.MEDFileFields.New(fname) for fname in fileNames] - mergeMLMesh = ml.MEDFileUMesh() - mergeMLFields = ml.MEDFileFields() - for lev in msML[0].getNonEmptyLevels(): - o2nML = len(msML[0].getNonEmptyLevels())*[None] - cs = [mML.getCoords() for mML in msML] - mergeMLMesh.setCoords(ml.DataArrayDouble.Aggregate(cs)) - ms = [mML.getMeshAtLevel(lev) for mML in msML] - m = ml.MEDCouplingUMesh.MergeUMeshes(ms) ; m.setCoords(mergeMLMesh.getCoords()) - o2nML[lev] = m.sortCellsInMEDFileFrmt() - mergeMLMesh.setMeshAtLevel(lev,m) - pass - - for fieldName in fsML[0].getFieldsNames(): - fmts = [fML[fieldName] for fML in fsML] - mergeField = ml.MEDFileFieldMultiTS() - for dt,it,tim in fmts[0].getTimeSteps(): - fts = [fmt[dt,it] for fmt in fmts] - arrs = len(fts)*[None] - for typp in fts[0].getTypesOfFieldAvailable(): - arr1s = [] - if typp == ml.ON_CELLS: - for ft in fts: - for geoTyp,smth in ft.getFieldSplitedByType(): - if geoTyp != ml.NORM_ERROR: - smth1 = filter(lambda x:x[0] == ml.ON_CELLS,smth) - arr2s = [ft.getUndergroundDataArray()[elt[1][0]:elt[1][1]] for elt in smth1] - arr1s.append(ml.DataArrayDouble.Aggregate(arr2s)) - pass - pass - pass - pass - else: - for ft in fts: - smth = filter(lambda x:x[0] == ml.NORM_ERROR,ft.getFieldSplitedByType()) - arr2 = ml.DataArrayDouble.Aggregate([ft.getUndergroundDataArray()[elt[1][0][1][0]:elt[1][0][1][1]] for elt in smth]) - arr1s.append(arr2) - pass - pass - arr = ml.DataArrayDouble.Aggregate(arr1s) - if typp == ml.ON_CELLS: - arr.renumberInPlace(o2nML[lev]) - mcf = ml.MEDCouplingFieldDouble(typp,ml.ONE_TIME) ; mcf.setName(fieldName) ; mcf.setTime(tim,dt,it) ; mcf.setArray(arr) - mcf.setMesh(mergeMLMesh.getMeshAtLevel(lev)) ; mcf.checkCoherency() - mergeField.appendFieldNoProfileSBT(mcf) - pass - pass - mergeMLFields.pushField(mergeField) - pass - mergeMLMesh.write("merge.med",2) - mergeMLFields.write("merge.med",0) diff --git a/medtool/doc/tutorial/conf.py.in b/medtool/doc/tutorial/conf.py.in deleted file mode 100644 index 0622ad520..000000000 --- a/medtool/doc/tutorial/conf.py.in +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Code Coupling and Code Integration documentation build configuration file, created by -# sphinx-quickstart on Tue Apr 28 15:28:57 2009. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# The contents of this file are pickled, so don't put values in the namespace -# that aren't pickleable (module imports are okay, they're removed automatically). -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If your extensions are in another directory, add it here. If the directory -# is relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# General configuration -# --------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.pngmath'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'MEDCoupling tutorial' -copyright = u'2015, Geay, Bruneton' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '@MEDCOUPLING_VERSION@' -# The full version, including alpha/beta/rc tags. -release = '@MEDCOUPLING_VERSION@' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - - -# Options for HTML output -# ----------------------- - -html_theme = 'classic' - -# The style sheet to use for HTML and HTML Help pages. A file of that name -# must exist either in Sphinx' static/ path, or in one of the custom paths -# given in html_static_path. -#html_style = 'default.css' - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = '' - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, the reST sources are included in the HTML build as _sources/. -#html_copy_source = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'MEDCouplingTutorial' - - -# Options for LaTeX output -# ------------------------ - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, document class [howto/manual]). -latex_documents = [ - ('index', 'MEDCouplingTutorial.tex', ur'MEDCoupling tutorial', - ur'A. Geay, A. Bruneton', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = '' - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True diff --git a/medtool/doc/tutorial/data/Fixe.med b/medtool/doc/tutorial/data/Fixe.med deleted file mode 100644 index e8955de01..000000000 Binary files a/medtool/doc/tutorial/data/Fixe.med and /dev/null differ diff --git a/medtool/doc/tutorial/data/Mobile.med b/medtool/doc/tutorial/data/Mobile.med deleted file mode 100644 index f357d2d2e..000000000 Binary files a/medtool/doc/tutorial/data/Mobile.med and /dev/null differ diff --git a/medtool/doc/tutorial/data/agitateur.med b/medtool/doc/tutorial/data/agitateur.med deleted file mode 100644 index 10529512c..000000000 Binary files a/medtool/doc/tutorial/data/agitateur.med and /dev/null differ diff --git a/medtool/doc/tutorial/images/DataArrayDouble_1.jpg b/medtool/doc/tutorial/images/DataArrayDouble_1.jpg deleted file mode 100644 index e5f1d4754..000000000 Binary files a/medtool/doc/tutorial/images/DataArrayDouble_1.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/FieldDouble1_1.png b/medtool/doc/tutorial/images/FieldDouble1_1.png deleted file mode 100644 index bf5f082a5..000000000 Binary files a/medtool/doc/tutorial/images/FieldDouble1_1.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/FieldDouble1_1_exploded.png b/medtool/doc/tutorial/images/FieldDouble1_1_exploded.png deleted file mode 100644 index 33bf6c695..000000000 Binary files a/medtool/doc/tutorial/images/FieldDouble1_1_exploded.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/FieldDouble1_2.png b/medtool/doc/tutorial/images/FieldDouble1_2.png deleted file mode 100644 index 6c5fbac59..000000000 Binary files a/medtool/doc/tutorial/images/FieldDouble1_2.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/Field_Cube3D.jpg b/medtool/doc/tutorial/images/Field_Cube3D.jpg deleted file mode 100644 index 90e68015e..000000000 Binary files a/medtool/doc/tutorial/images/Field_Cube3D.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/IndirectIndex.jpg b/medtool/doc/tutorial/images/IndirectIndex.jpg deleted file mode 100644 index 3f5ccf5d6..000000000 Binary files a/medtool/doc/tutorial/images/IndirectIndex.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/LocationEx2.jpg b/medtool/doc/tutorial/images/LocationEx2.jpg deleted file mode 100644 index f7d109e33..000000000 Binary files a/medtool/doc/tutorial/images/LocationEx2.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/Mesh_cube3D.jpg b/medtool/doc/tutorial/images/Mesh_cube3D.jpg deleted file mode 100644 index aaefb731d..000000000 Binary files a/medtool/doc/tutorial/images/Mesh_cube3D.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/Mesh_polygons2D.jpg b/medtool/doc/tutorial/images/Mesh_polygons2D.jpg deleted file mode 100644 index 37330742c..000000000 Binary files a/medtool/doc/tutorial/images/Mesh_polygons2D.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/Remapper1.png b/medtool/doc/tutorial/images/Remapper1.png deleted file mode 100644 index b410ab6e4..000000000 Binary files a/medtool/doc/tutorial/images/Remapper1.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/SplitAndMerge2.jpg b/medtool/doc/tutorial/images/SplitAndMerge2.jpg deleted file mode 100644 index a67d0fa6b..000000000 Binary files a/medtool/doc/tutorial/images/SplitAndMerge2.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/SplitAndMergeCell1.jpg b/medtool/doc/tutorial/images/SplitAndMergeCell1.jpg deleted file mode 100644 index 88a27c102..000000000 Binary files a/medtool/doc/tutorial/images/SplitAndMergeCell1.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/SurjectionDataArray.png b/medtool/doc/tutorial/images/SurjectionDataArray.png deleted file mode 100644 index 229b02e78..000000000 Binary files a/medtool/doc/tutorial/images/SurjectionDataArray.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/UMesh1.png b/medtool/doc/tutorial/images/UMesh1.png deleted file mode 100644 index 3ffb6590c..000000000 Binary files a/medtool/doc/tutorial/images/UMesh1.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/agitateur.jpg b/medtool/doc/tutorial/images/agitateur.jpg deleted file mode 100644 index e4ab2eeba..000000000 Binary files a/medtool/doc/tutorial/images/agitateur.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/blade.jpg b/medtool/doc/tutorial/images/blade.jpg deleted file mode 100644 index 72791e523..000000000 Binary files a/medtool/doc/tutorial/images/blade.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/captureCoarseMesh.png b/medtool/doc/tutorial/images/captureCoarseMesh.png deleted file mode 100644 index a5394bec5..000000000 Binary files a/medtool/doc/tutorial/images/captureCoarseMesh.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/captureFineMesh.png b/medtool/doc/tutorial/images/captureFineMesh.png deleted file mode 100644 index 0b60d1cc9..000000000 Binary files a/medtool/doc/tutorial/images/captureFineMesh.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/cube.jpg b/medtool/doc/tutorial/images/cube.jpg deleted file mode 100644 index 735ecbce3..000000000 Binary files a/medtool/doc/tutorial/images/cube.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/face.jpg b/medtool/doc/tutorial/images/face.jpg deleted file mode 100644 index 1a35b2eae..000000000 Binary files a/medtool/doc/tutorial/images/face.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/fixm.jpg b/medtool/doc/tutorial/images/fixm.jpg deleted file mode 100644 index 475f248bb..000000000 Binary files a/medtool/doc/tutorial/images/fixm.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/mesh3DSurfInside.jpg b/medtool/doc/tutorial/images/mesh3DSurfInside.jpg deleted file mode 100644 index 17534de80..000000000 Binary files a/medtool/doc/tutorial/images/mesh3DSurfInside.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/mobm.jpg b/medtool/doc/tutorial/images/mobm.jpg deleted file mode 100644 index ba1e0c918..000000000 Binary files a/medtool/doc/tutorial/images/mobm.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/partFixmAndzone1Mobm.jpg b/medtool/doc/tutorial/images/partFixmAndzone1Mobm.jpg deleted file mode 100644 index fb9ca78c9..000000000 Binary files a/medtool/doc/tutorial/images/partFixmAndzone1Mobm.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/partFixmWithoutZone1Mobm.jpg b/medtool/doc/tutorial/images/partFixmWithoutZone1Mobm.jpg deleted file mode 100644 index b47e79d05..000000000 Binary files a/medtool/doc/tutorial/images/partFixmWithoutZone1Mobm.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/skinandnccells_numpy.png b/medtool/doc/tutorial/images/skinandnccells_numpy.png deleted file mode 100644 index e7cb7e7c7..000000000 Binary files a/medtool/doc/tutorial/images/skinandnccells_numpy.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/skinonly_numpy.png b/medtool/doc/tutorial/images/skinonly_numpy.png deleted file mode 100644 index 1b16286a6..000000000 Binary files a/medtool/doc/tutorial/images/skinonly_numpy.png and /dev/null differ diff --git a/medtool/doc/tutorial/images/zone1Mobm.jpg b/medtool/doc/tutorial/images/zone1Mobm.jpg deleted file mode 100644 index 3aa07f60c..000000000 Binary files a/medtool/doc/tutorial/images/zone1Mobm.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/images/zonesMobm.jpg b/medtool/doc/tutorial/images/zonesMobm.jpg deleted file mode 100644 index 7de18b3f9..000000000 Binary files a/medtool/doc/tutorial/images/zonesMobm.jpg and /dev/null differ diff --git a/medtool/doc/tutorial/index.rst b/medtool/doc/tutorial/index.rst deleted file mode 100644 index d93c54950..000000000 --- a/medtool/doc/tutorial/index.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. Code Integration and Code Coupling documentation master file, created by sphinx-quickstart on Tue Apr 28 14:31:38 2009. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -MEDCoupling/MEDLoader Tutorial -============================== - -MEDCoupling is a powerful library to manipulate meshes and fields. - -This tutorial presents the most wanted functionalities of the MEDCoupling/MEDLoader -library through a series of small exercises in Python. -Both the French and English versions are provided, but the French version -is better maintained ... - -(Jump to the English version below :ref:`english-toc`) - -Version française ------------------ - -Table des matières: - -.. toctree:: - :maxdepth: 2 - - medcoupling_fr - medloader_fr - medcouplingremapper_fr - medcouplingnumpy_fr - medcouplingcorba_fr - medcouplingloaderex1_fr - medcouplingloaderex2_fr - -.. _english-toc: - -English version ---------------- - -Table of contents: - -.. toctree:: - :maxdepth: 2 - - medcoupling_en - medloader_en - medcouplingremapper_en - medcouplingnumpy_en - medcouplingcorba_en - medcouplingloaderex1_en - medcouplingloaderex2_en - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/medtool/doc/tutorial/medcoupling_2Dpolygon.rst b/medtool/doc/tutorial/medcoupling_2Dpolygon.rst deleted file mode 100644 index 3f0764385..000000000 --- a/medtool/doc/tutorial/medcoupling_2Dpolygon.rst +++ /dev/null @@ -1,117 +0,0 @@ - -Meshing a 2D geometry with polygons ------------------------------------ - -Objective -~~~~~~~~~ - -In this example we propose to build a mesh on a 2D geometry. We first create triangles in the center of the geometry and then hexagons around them. The result will be saved in a med file, and then visualized with the SMESH module of Salome. - -.. image:: images/Mesh_polygons2D.jpg - - -Beginning of implementation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To implement this exercice we use the python language script and import the MEDCoupling and MEDLoader parts of the MED module:: - - from MEDCoupling import * - from MEDLoader import * - - from math import * - -Then we must instanciate a meshing object:: - - mesh=MEDCouplingUMesh.New() - mesh.setMeshDimension(2) - mesh.allocateCells(numberOfCells) - mesh.setName("MaFleur") - - -You must define 2 variables for space dimension and total number of nodes:: - - numberOfNodes = 25 - numberOfCells = 12 - spaceDimension = 2 - - -You must define the coordinates of the nodes of the central hexagon:: - - X = [1.,0.5,-0.5,-1.,-0.5,0.5] - Y = [0.,sqrt(3.)/2.,sqrt(3.)/2.,0.,-sqrt(3.)/2.,-sqrt(3.)/2.] - -Definition of nodes coordinates -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Define the coordinates of the origin and the nodes of the 2D central polygon:: - - coordinates = [] - # origin - coordinates.append(0.) - coordinates.append(0.) - - # central polygon - for i in range(6): - coordinates.append(X[i]) - coordinates.append(Y[i]) - -Define the coordinates of the extra nodes of the hexagons around the central hexagon:: - - # second couron - xc = 1.5 - yc = - sqrt(3.)/2. - - for i in range(6): - ... - - myCoords=DataArrayDouble.New() - myCoords.setValues(coordinates,numberOfNodes,2) - mesh.setCoords(myCoords) - - -Definition of triangles connectivity -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -For each triangle of the mesh, you have to give its connectivity: the list of the nodes which belong to the triangles:: - - connectivity = [] - for i in range(6): - connectivity.append(0) - connectivity.append(...) - connectivity.append(...) - for i in range(6): - mesh.insertNextCell(NORM_TRI3,3,connectivity[3*i:3*(i+1)]) - pass - - -Definition of hexagons connectivity -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -For each hexagon of the mesh, you have to give its connectivity: the list of the nodes which belong to the hexagons:: - - connectivity = [] - for i in range(6): - start = i%6+1 - connectivity.append(...) - for i in range(6): - mesh.insertNextCell(NORM_POLYGON,6,connectivity[6*i:6*(i+1)]) - pass - mesh.checkCoherency() - -Saving the mesh in a med file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You have to create a med file with the MED driver:: - - medFileName = "MEDCoupling_Fleur.med" - MEDLoader.WriteUMesh(medFileName,mesh,True) - -Visualize the mesh with SMESH module of Salome -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Launch Salome platform, then select SMESH module and import your MED file. First You can see the number of elements of your mesh. For that, select your mesh in the object browser, set select Mesh menu and "Advanced Mesh Info" option. Verify the number of triangles and the number of hexagons. To visualize your mesh: click right bottom on your mesh and select "Show" option. - -Solution -~~~~~~~~ - -:ref:`python_testMEDCoupling2D_solution` diff --git a/medtool/doc/tutorial/medcoupling_3Dcube.rst b/medtool/doc/tutorial/medcoupling_3Dcube.rst deleted file mode 100644 index 2564f7863..000000000 --- a/medtool/doc/tutorial/medcoupling_3Dcube.rst +++ /dev/null @@ -1,345 +0,0 @@ - -Meshing a 3D cube ------------------ - -Objective -~~~~~~~~~ - -The meshing class of the SALOME MED module allows user to create a mesh from scratch. -In this example we propose to build a mesh on a 3D cube by three methods (classical method, method by extrusion and grid method). Each cell of the mesh must be a hexaedron. -We see also how creating a group. -Then we create a field on all the 3D cube. -Each result will be saved in a med file, and then visualized with the SMESH module of Salome. - -In spite of a mesh in MEDCoupling has only one dimension, it's possible to save some meshes with different dimension in one med file. We will see this method. - -.. image:: images/Mesh_cube3D.jpg - - -Beginning of implementation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To implement this exercice we use the python language script and import the MEDCoupling and MEDLoader parts of the MED module. We need also mathematical functions, so we import the python math module:: - - from MEDCoupling import * - from MEDLoader import * - from math import * - -You must define 3 variables for space dimension, number of nodes on each dimension and total number of nodes:: - - MeshDim3D = 3 - MeshDim2D = 2 - N = ... - NbCell2D = (N-1)*(N-1) - NbCell3D = NbCell2D*(N-1) - NbNode2D = N*N - NbNode3D = NbNode2D*N - - -Classical method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -First instanciate a meshing object. Therefore, we need to define : - - * its name - * its dimension - * its number of cells - -.. note:: All this initialisation are necessary. If one lacks, you will have a segmentation fault!. - -:: - - mesh=MEDCouplingUMesh.New() - mesh.setMeshDimension(3) - mesh.allocateCells(...) - mesh.setName("3Dcube") - -Definition of nodes coordinates -``````````````````````````````` - -Define the coordinates of the nodes of the 3D cube mesh, and then use the setCoords function to set it:: - - # Initialisation of coordinates - coordinates = [] - for k in range(N): - for j in range(N): - for i in range(N): - coordinates.append(...) - - myCoords = DataArrayDouble.New() - myCoords.setValues(coordinates,nbOfNodes,3) - mesh.setCoords(myCoords) - - -Definition of hexahedrons connectivity -`````````````````````````````````````` -For each hexahedron of the mesh, you have to give its connectivity: the list of the nodes which belong to the hexahedron. The order of the nodes in the connectivity array must respect the MEDCoupling format (see the following figure). - -.. image:: images/cube.jpg - -.. warning:: Connectivity elements begin to 0 from (n-1) elements - -:: - - connectivity = [] - for k in range(N-1): - for j in range(N-1): - for i in range(N-1): - inode = ... - connectivity.append(inode) - connectivity.append(...) - - # Adding cells in meshing - for i in range(nbOfCells): - mesh.insertNextCell(NORM_HEXA8,8,connectivity[8*i:8*(i+1)]) - pass - - # Check mesh consistency: - mesh.checkCoherency() - -Method by extrusion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In order to create a extruded mesh, we need one 2D mesh and one 1D mesh which define the vector of extrusion and the number of steps. - -Definition of 2D mesh -`````````````````````````````````````` -:: - - coordinates = [] - for j in range(N): - for i in range(N): - coordinates.append(...) - ... - Connectivities = [...] - myCoords = DataArrayDouble.New() - myCoords.setValues(coordinates,NbNode2D,MeshDim2D) - - m1 = MEDCouplingUMesh.New() - m1.setMeshDimension(MeshDim2D) - m1.allocateCells(NbCell2D) - m1.setCoords(myCoords) - m1.setName("2D_Support") - - for i in range(NbCell2D): - m1.insertNextCell(NORM_QUAD4,4,Connectivities[4*i:4*(i+1)]) - m1.changeSpaceDimension(3) - -Definition of 1D mesh -`````````````````````````````````````` -:: - - coords = [ ... ] - conn = [ ... ] - m2 = MEDCouplingUMesh.New() - m2.setMeshDimension(1) - m2.allocateCells(3) - m2.insertNextCell(NORM_SEG2,2,conn[0:2]) - m2.insertNextCell(NORM_SEG2,2,conn[2:4]) - m2.insertNextCell(NORM_SEG2,2,conn[4:6]) - myCoords1D=DataArrayDouble.New() - myCoords1D.setValues(coords,4,1) - m2.setCoords(myCoords1D) - m2.changeSpaceDimension(3) - -Definition of extruded mesh -`````````````````````````````````````` - -Since 1D meshing isn't well oriented (along 0x vector), we need to imply a transformation on it. -Then, we can extrude 2D meshing. - -:: - - center = [...] - vector = [...] - m2.rotate(...) - m3 = m1.buildExtrudedMesh(m2,0) - m3.setName("Extrusion") - -Grid method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -it's the easiest way to create a grid since you have no connectivity to set. They will be automatically setting. Incrementation of ids will be made first along Ox axis, then along Oy axis and finally along Oz axis. - -:: - - mesh=MEDCouplingCMesh.New() - coordsX=DataArrayDouble.New() - arrX=[ ... ] - coordsX.setValues(arrX,4,1) - coordsY=DataArrayDouble.New() - arrY=[ ... ] - coordsY.setValues(arrY,4,1) - coordsZ=DataArrayDouble.New() - arrZ=[ ... ] - coordsZ.setValues(arrZ,4,1) - mesh.setCoords(coordsX,coordsY,coordsZ) - -Really in order to save this mesh, you need to transform this structured mesh to an unstructerd mesh. -:: - - meshU=mesh.buildUnstructured() - meshU.setName("Grid") - -Creation of groups -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A group is a set of cells defining by their id. This set must the input for creating a group. -Generally ids cells using in group are known. So you just need put these ids in a DataArray. -:: - - tabIdCells = DataArrayInt.New() - IdCells = [ ... ] - tabIdCells.setValues(IdCells,...) - - -.. note:: It's also possible to retrieve ids cells from a submesh of the principal mesh. - -:: - - ret,tabIdCells = mesh.areCellsIncludedIn(subMesh,0) - - -Once the DataArray is created, some initializations have to be done. -:: - - # Definition of the name group - tabIdCells.setName("meshGroup") - - -In order to add a group on a mesh, you need to transform your unstructured mesh in a file unstructured mesh. -Moreover, we need to define: - - * its name - * its description - * its coordinates - * its dimension - * its number of cells - - -:: - - # Passing MEDCoupling to MEDFile - fmeshU = MEDFileUMesh.New() - fmeshU.setName("Grid") - fmeshU.setDescription("IHopeToConvinceLastMEDMEMUsers") - myCoords = meshU.getCoords() - fmeshU.setCoords(myCoords) - fmeshU.setMeshAtLevel(0,meshU) - -Then, you can -Therefore, you need to define the level (ie. the dimension) of the group. -This information is given by a number : 0,-1 or -2. - - * 0 means the same level at mesh - -:: - - fmeshU.setGroupsAtLevel(0,[tabIdCells],False) - -Create field on 3D cube -~~~~~~~~~~~~~~~~~~~~~~~ - -First you need to create a CouplingField and initialize some data: - - * its name - * its support (ie mesh) - * its nature - * its values - - -The field will be a sin function dependant of distance of the barycenter of each cell from origin. So we need to create a barycenter field on the 3D mesh:: - - # Creation of field : with following definition - # => Definition of the mesh support - # => Definition of field name - # => Definition of field nature - field = MEDCouplingFieldDouble.New(ON_CELLS) - field.setMesh(mesh) - field.setName("field") - field.setNature(Integral) - - # Computing and setting field values - myCoords=DataArrayDouble.New() - sampleTab=[] - bar = mesh.getBarycenterAndOwner() - print bar.getNbOfElems() - for i in range(nbOfCells): - x = bar.getIJ(...) - y = bar.getIJ(...) - z = bar.getIJ(...) - d = sqrt(x*x+y*y+z*z) - sinus = sin(d) - . sampleTab.append(sinus) - - myCoords.setValues(sampleTab,nbOfCells,1) - field.setArray(myCoords) - - -Saving the mesh in a med file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -General Case -```````````` -:: - - medFileName = "MEDCoupling_Extrudedcube3D.med" - MEDLoader.WriteUMesh(medFileName,meshU,True) - -.. note:: True / False in Write* functions : True for overwriting existing file and False for adding in existing file - -Multi mesh Case -```````````````` - -In spite of a MEDCoupling mesh has only one dimension, it's possible to genrate a file with multi dimension. -Therefore, you need to create as meshes as necessary dimensions. - -You have to give the connectivity of the faces on the bottom face of the 3D cube: the list of the nodes which belong to the face. -The connectivity must respect following figure: - -.. image:: images/face.jpg - -:: - - # Extraction of surfacic meshing - pt=[0.,0.,0.] - vec=[0.,0.,1.] - nodes = mesh.findNodesOnPlane(pt,vec,1e-12) - mesh2D = mesh.buildFacePartOfMySelfNode(nodes,True) - #print mesh2D - mesh2D.setName("3Dcube") - mesh2D.checkCoherency() - - medFileName = "MEDCoupling_cube3D.med" - meshes=[mesh2D,mesh] - MEDLoader.WriteUMeshes(medFileName,meshes,True) - -Group Case -```````````` -:: - - medFileName = "MEDCoupling_Gridcube3D.med" - fmeshU.write(medFileName,2) - -Saving the fields in the med file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - MEDLoader.WriteField(medFileName,field,False) - -Visualize the mesh with the SMESH module of Salome -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Launch Salome platform, then select SMESH module and import your MED file. First You can see the number of elements of your mesh. For that, select your mesh in the object browser, set select Mesh menu and "Advanced Mesh Info" option. Verify the number of faces and the number of hexahedrons. To visualize your mesh: click right bottom on your mesh and select "Show" option. You can also visualize your groups. Select one group, click right bottom on your group and select "Show only" option. - -Visualize the fields with the VISU module of Salome -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Launch Salome platform, then select VISU module and import your MED file. You can see in the object browser the 2 fields you have created. Then you have to create a scalar map on each field to visualize them. - -.. image:: images/Field_Cube3D.jpg - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingcube_solution` diff --git a/medtool/doc/tutorial/medcoupling_Read.rst b/medtool/doc/tutorial/medcoupling_Read.rst deleted file mode 100644 index d954bfdab..000000000 --- a/medtool/doc/tutorial/medcoupling_Read.rst +++ /dev/null @@ -1,88 +0,0 @@ - -Reading a med file -------------------- - -Objective -~~~~~~~~~ - -The MEDLoader class also allows to read a med file. - -We will use the case of the 3D cube in order to retrieve all meshes and fields along with value on one node. - -Beginning of implementation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To implement this exercice we use the python language script and import the MEDCoupling and MEDLoader parts of the MED module. We need also mathematical functions, so we import the python math module:: - - from MEDCoupling import * - from MEDLoader import * - from math import * - - -Then define some variables:: - - medFileName = "MEDCoupling_cube3D.med" - MeshName = "3Dcube" - FieldName = "field" - Field2DName = "fieldBottomFace" - -Retrieving 3D mesh and associated field -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You need to use MEDLoader API in order to read med file. Read functions need to give the real dimension of the mesh to max. -This information is given by a number : 0,-1 or -2. - - * 0 means the high dimension of the mesh - * -1 means the second high dimension of the mesh - -and the iteration and order of the field. In our case, since there is no iteration, it's -1 for these 2 arguments:: - - mesh3D = MEDLoader.ReadUMeshFromFile(medFileName,MeshName,0) - f = MEDLoader.ReadFieldCell(medFileName,mesh3D.getName(),0,FieldName,-1,-1) - - -Retrieving 2D mesh and associated field -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Do the same thing for the 2D mesh and the associated field:: - - mesh2D = MEDLoader.ReadUMeshFromFile(...) - f2 = MEDLoader.ReadFieldCell(...) - -Retrieving mesh coords -~~~~~~~~~~~~~~~~~~~~~~ - -:: - - # Retrieving Coords Mesh - Coords3D = mesh3D.getCoords() - Values = Coords3D.getValuesAsTuple() - -Retrieving field values -~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - # Retrieving field value on 0 tuple - pos= Values[...] - res=f.getValueOn(pos) - - # Verify if value is OK - bar = mesh3D.getBarycenterAndOwner() - x=bar.getIJ(...) - y=bar.getIJ(...) - z=bar.getIJ(...) - - from math import * - d = sqrt(x*x+y*y+z*z) - sinus = sin(d) - - if abs(res[0]-sinus)<1.e-5: - print "OK" - else: - print "KO" - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingRead_solution` diff --git a/medtool/doc/tutorial/medcoupling_dataarray1_en.rst b/medtool/doc/tutorial/medcoupling_dataarray1_en.rst deleted file mode 100644 index eeb8d6d69..000000000 --- a/medtool/doc/tutorial/medcoupling_dataarray1_en.rst +++ /dev/null @@ -1,257 +0,0 @@ - -Manipulate DataArray objects ----------------------------- - -DataArrays (DataArrayInt and DataArrayDouble) are used in MEDCoupling to store contiguous arrays in memory. Each array entry is a tuple of data. -They form the base of many data processing performed by MEDCoupling. It is thus useful to be able to manipulate them with ease. - -DataArrayDouble are often used to manipulate fields in an optimized fashion, as will be shown later on. - -Objective -~~~~~~~~~ - -In this exercise the aim is to create a set of 2D Cartesian coordinates. The first component will be called X (with unit "m") and the second Y (same unit). The coordinates represent 7 regular hexagons (all inscribed in a 3cm radius circle). -The 7 hexagons are built from a centered reference hexagon (3.4; 4.4). - -Around this reference, 6 translated copies are created and each copy shares exactly one edge with the reference. -The common nodes (tuples) are then merged. This shows how to use indirections, concept widely used in unstructured meshes. - -.. image:: images/DataArrayDouble_1.jpg - -Concepts at hand: - -* Create an instance of DataArrayDouble -* Display a DataArrayDouble instance and invoke the getValue() method to convert it to a list -* Use convenient notations da[...] -* Learn about renumbering (old2new convention) -* Invoke services from findCommonTuples - -Starting the implementation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To start with, import the whole python module MEDCoupling and the standard math module. :: - - from MEDCoupling import * - import math - -This makes the following available: - -* all MEDCoupling classes -* all enum (ON_CELLS, ON_NODES, ONE_TIME...) -* all static methods - -Create a DataArrayDouble instance containing 6 tuples -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The target here is to create one DataArrayDouble containing the complete set of coordinates for one regular hexagon. :: - - d=DataArrayDouble(6,2) - -Which is equivalent to :: - - d=DataArrayDouble() - d.alloc(6,2) - -or to :: - - d=DataArrayDouble(12) - d.rearrange(2) - -.. note:: d contains 12 values grouped in 6 tuples containing each 2 components. - The values in d are still un-initialized. - -Initialize an instance of DataArrayDouble -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Assign the value 3.0 (radius) to the first component of all tuples. :: - - d[:,0]=3. - -Initialize the 2nd component of each tuple i with the index value i. :: - - d[:,1]=range(6) - -Multiply the 2nd component by pi/3. :: - - d[:,1]*=math.pi/3. - -.. note:: d now contains the polar coordinates of our regular hexagon centered at 0,0. - -Convert from polar to Cartesian by invoking fromPolarToCart(), and assign the result to d. :: - - d=d.fromPolarToCart() - -.. note:: fromPolarToCart() generates a new instance and d now points to it. - -Assign the correct component information of d.:: - - d.setInfoOnComponents(["X [m]","Y [m]"]) - -Display the values only in form of a Python list. :: - - print d.getValues() - -Display d. :: - - print d - -Verify that for each tuple of d its norm (returned by the magnitude() method) is indeed 3 (with an error less than 1.e-12): -:: - - print d.magnitude().isUniform(3.,1e-12) - - -Duplication and aggregation of DataArrayDouble -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -translationToPerform contains a list of vectors of size 2. This list has length 7 (7 hexagons) Cette liste de taille 7 (7 hexagones) and describes the appropriate translation for each copy of d. - -Execute directly the following lines :: - - radius=3. - translationToPerform=[[0.,0.],[3./2.*radius,-radius*math.sqrt(3.)/2],[3./2.*radius,radius*math.sqrt(3.)/2],[0.,radius*math.sqrt(3.)],[-3./2.*radius,radius*math.sqrt(3.)/2],[-3./2.*radius,-radius*math.sqrt(3.)/2],[0.,-radius*math.sqrt(3.)]] - - -Create the len(translationToPerform) copies of d and apply the corresponding translation. :: - - ds=len(translationToPerform)*[None] - for pos,t in enumerate(translationToPerform): - ds[pos]=d[:] - ds[pos]+=t - pass - -An alternative (and more compact) way to do it : :: - - ds=[d.deepCpy() for i in xrange(len(translationToPerform))] - for (elt,t) in zip(ds,translationToPerform) : elt+=t - -Aggregating DataArrayDouble -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -From the list of DataArrayDouble instances 'ds', construct the aggregation 'd2' (a new instance of DataArrayDouble). -:: - - d2=DataArrayDouble.Aggregate(ds) - -.. note:: d2 now contains the full tuple set (6*7=42 tuples of 2 components each) which was in ds with the same order. This might sound obvious but the aggregation of meshes and fields is based on the exact same principle thus facilitating data access and indexing. This is a key difference to the MED file model, as will be seen later on. - -Find identical tuples in d2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -d2 contains 42 tuples but some of them are duplicated. To identify those (with a 1e-12 precision) invoke DataArrayDouble.findCommonTuples(). -Use help(DataArrayDouble.findCommonTuples) to show the prototype of the method and store the result in c and cI:: - - oldNbOfTuples=d2.getNumberOfTuples() - c,cI=d2.findCommonTuples(1e-12) - -c is an array containing all the common nodes grouped sequentially. cI contains the pointers to c allowing to identify all the nodes in a group 'i' (with 'i' in [0, 12) ). Thus the tuple ids of group 'i' start at index cI[i] in the list c, and finish at index cI[i+1]. - -.. note:: DataArrayDouble.findCommonTuples() thus returns 2 values: an array containing a list of common tuples, and an index array which is used to navigate in the first list. This is a very classical return signature in MEDCoupling and often appears when manipulating unstructured meshes. - -Manipulate DataArrayInt couple representing a pair (Data,IndexData) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The number of common tuples is len(cI)-1, i.e. 12 in our case. -Get the list of tuple ids forming the first group of common nodes and store the result in tmp. :: - - tmp=c[cI[0]:cI[0+1]] - print tmp - -Check the result: all the tuples stored in tmp point to identical coordinates in d2.:: - - print d2[tmp] - -.. note:: we see the tuple (3.,0.) repeated 3 times (with an error margin below 1e-12). - -Now we will deduce from the 3 variables oldNbOfTuples, c and cI the number of truly different tuples in d2. -To this end we compute the number of repetitions in d2 and we subtract this from oldNbOfTuples. - -To get the repetition count invoke the method DataArrayInt.deltaShiftIndex(). It returns the size of each group. -Store the result in a. :: - - a=cI.deltaShiftIndex() - -The number of repetitions in d2 for each group can now be stored in b. :: - - b=a-1 - -Finally the new count of tuples can be computed as follows. :: - - myNewNbOfTuples=oldNbOfTuples-sum(b.getValues()) - -Build old to new array from c and cI -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -c and cI define a surjective function from a starting set X containing 42 tuples (oldNbOfTuples) to a set Y containing 24 tuples (myNewNbOfTuples). - -.. image:: images/SurjectionDataArray.png - -This surjective function may also be represented thanks to an "old-2-new" array. -This storage method takes the form of a DataArrayInt 'o2n' made of Card(X) tuples (in our case 42) with one component each. For each tuple (element) indexed by i in o2n, o2n[i] contains the new tuple id in Y. - -The format 'old-2-new' is systematically used for all renumbering operations (one-to-one correspondence). - -The static method DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2() performs the conversion from one storage mode to the other (c, cI to o2n). -We get for free the number of elements in Y, i.e. the variable newNbOfTuples. :: - - o2n,newNbOfTuples=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfTuples,c,cI) - print "Have I got the right result? %s"%(str(myNewNbOfTuples==newNbOfTuples)) - -Using o2n and newNbOfTuples invoke DataArrayDouble.renumberAndReduce() on d2. :: - - d3=d2.renumberAndReduce(o2n,newNbOfTuples) - -This method has one drawback: we don't know for each group of common tuples in d2 what id was finally retained. -For example: in the group 0 we know that tuples 0, 8 and 16 are identical (tmp.getValues()), but we don't know which of the three has been retained in d3. - -To make this choice explicit we use the new-2-old format. This storage mode is represented by a DataArrayInt n2o containing Card(Y) tuples (in our case 24) with one component each. -For each tuple (element) with id 'i' in n2o, n2o[i] contains the tuple id which was chosen in X. - -The method DataArrayInt.invertArrayO2N2N2O() allows to switch between the two representations. -Try it on the variable o2n. :: - - n2o=o2n.invertArrayO2N2N2O(newNbOfTuples) - -Using n2o we can deduce d3_bis from d2. :: - - d3_bis=d2[n2o] - print "Have I got the right result (2)? %s"%(str(d3.isEqual(d3_bis,1e-12))) - -Translate all tuples at once -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -All tuples (or nodes) are to be translated by the vector [3.3,4.4]. :: - - d3+=[3.3,4.4] - -Build an unstructured mesh using d3 (coordinates) and o2n -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Create an unstructured mesh m with coordinates d3. m has a mesh dimension of 2 :: - - m=MEDCouplingUMesh("My7hexagons",2) - m.setCoords(d3) - -Now allocate the number of cells with an upper bound of the actual number of cells. :: - - m.allocateCells(7) - -Finally thanks to o2n we know the connectivity of all 7 hexagons using the coordinates stored in d3. - - for i in xrange(7): - m.insertNextCell(NORM_POLYGON,o2n[6*i:6*(i+1)].getValues()) - pass - -Check that m is coherent. :: - - m.checkCoherency() - -To visually check m, write it in a VTU file ("My7hexagons.vtu") and display it in ParaVis. :: - - m.writeVTK("My7hexagons.vtu") - -.. note:: We write the data in VTU file, not in a MED file, because MEDCoupling doesn't use the MED file pre-requisite. Also note that although we output VTK data, MEDCoupling in itself doesn't depend on the VTK libraries. - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingdataarray1_solution` diff --git a/medtool/doc/tutorial/medcoupling_dataarray1_fr.rst b/medtool/doc/tutorial/medcoupling_dataarray1_fr.rst deleted file mode 100644 index 5dae2410e..000000000 --- a/medtool/doc/tutorial/medcoupling_dataarray1_fr.rst +++ /dev/null @@ -1,333 +0,0 @@ - -Manipuler les DataArray ------------------------ - -Les DataArrays (``DataArrayInt`` et ``DataArrayDouble``) sont utilisés dans MEDCoupling pour stocker des valeurs sous -forme de tableaux contigus en mémoire. Les valeurs sont groupées par tuples, et chaque tuple a le même nombre de composantes. -Ils sont à la base de beaucoup de traitements réalisés dans MEDCoupling. Il est ainsi important de bien savoir les manipuler. - -Les ``DataArrayDouble`` sont souvent utilisés pour la manipulation directe des valeurs d'un champ comme on le verra plus tard. -Les ``DataArrayInt`` eux sont utilisés pour toutes les fonctionnalités travaillant avec des identifiants de -cellules et/ou de points. - -Le but de l'exercice -~~~~~~~~~~~~~~~~~~~~ - -Le but ici est de créer les coordonnées de 7 hexagones réguliers (tous inscrits dans des cercles de rayon 3m) en dimension 2. -La première composante du tableau de coordonnées s'appelera X avec l'unité "m" (mètre) et la 2ème composante s'appelera "Y" avec la même unité. - -On pourrait directement calculer les coordonnées de l'ensemble des points requis avec un peu de trigonométrie, mais afin de travailler un peu avec l'API, on fait le choix de construire les 7 hexagones à partir d'un seul hexagone régulier centré en [3.4; 4.4]. -Autour de cet hexagone régulier central, on crée 6 copies translatées et chaque copie partagera exactement un bord (edge) avec le motif initial. Ensuite on fusionne les noeuds (tuples) communs. Ceci nous permettra de manipuler les indirections et les méthodes d'indexing très usitées dans les maillages non structurés. - -.. image:: images/DataArrayDouble_1.jpg - :scale: 50 - -Les points traités ici : - -* Créer une instance de ``DataArrayDouble`` -* Afficher une instance de ``DataArrayDouble`` et invoquer la méthode ``getValue()`` pour la convertir en liste -* Utiliser les notations pratiques ``da[:,:]`` ... -* Apprendre la renumérotation (convention "old-2-new") -* Invoquer des services tels que ``findCommonTuples()`` - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer le module Python ``MEDCoupling`` et l'aliaser avec ``mc`` (ca nous évitera des noms trop longs). Importer aussi le module ``math``. :: - - import MEDCoupling as mc - import math - -On rappelle que toutes les méthodes statiques du module commencent par une majuscule. -Avec ces imports sont disponibles : - -* toutes les classes de MEDCoupling -* tous les énumérations (par exemple, les types de cellules standard: ``mc.ON_CELLS``, ``mc.ON_NODES``, ``mc.ONE_TIME``...) -* toutes les méthodes statiques - -Créer une instance de DataArrayDouble contenant 6 tuples -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Le but ici est de créer un ``DataArrayDouble`` contenant les coordonnées d'un seul hexagone régulier. :: - - d = mc.DataArrayDouble(6,2) - -Ceci est équivalent à :: - - d = mc.DataArrayDouble() - d.alloc(6,2) - -Ceci est aussi équivalent à :: - - d = mc.DataArrayDouble(12) - d.rearrange(2) - -Notons enfin que l'on peut aussi directement construire un ``DataArray`` à partir d'une liste Python. Par défaut le tableau -n'a qu'une seule composante. :: - - d_example = mc.DataArrayDouble([0.0,1.0,2.5]) - print d_example - -.. note:: Le tableau ``d`` contient maintenant 12 valeurs groupées en 6 tuples contenant chacun 2 composantes. - Les valeurs dans ``d`` ne sont pas encore assignées. - -Initialiser une instance de DataArrayDouble -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Assigner la valeur 3.0 (le rayon) à la première composante de chacun des tuples. La syntaxe ressemble fortement -à celle de NumPy. On peut par exemple assigner d'un coup les tuples 1 à 3 (inclus), sur la première composante avec la valeur -3.0 :: - - d[1:4,0] = 3. - -ou directement l'intégralité de la première composante :: - - d[:,0] = 3. - -Initialiser la 2ème composante de chaque tuple i avec la valeur i. :: - - d[:,1] = range(6) - -Multiplier la seconde composante de chacun des tuples par pi/3. :: - - d[:,1] *= math.pi/3. - -.. note:: ``d`` contient désormais les coordonnées polaires des noeuds de notre hexagone régulier centré en 0,0 pour le moment. - -Convertir ``d`` de polaire à cartésien en invoquant la méthode ``fromPolarToCart()`` et re-mettre le résultat dans ``d``. :: - - d = d.fromPolarToCart() - -.. note:: ``fromPolarToCart()`` génère une nouvelle instance, nous avons donc perdu le ``d`` initial - -Assigner les informations textuelles correctes sur les 2 composantes de ``d`` : :: - - d.setInfoOnComponents(["X [m]","Y [m]"]) - -.. note:: Cela n'est pas indispensable pour cet exercise, mais d'autres fonctions plus avancées nécessitent cette information. - -Afficher ``d`` tel quel. :: - - print d - - -Afficher juste les valeurs sous forme d'une liste python. :: - - print d.getValues() - - -Vérifier que pour chaque tuple désormais dans ``d``, sa norme (méthode ``magnitude()``) est bien égale à 3.0, à 1.e-12 près (méthode ``isUniform()``) :: - - print "Uniform array?", d.magnitude().isUniform(3.,1e-12) - - -Duplication et agrégation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -On construit maintenant la liste ``translationToPerform``, qui contient une liste de vecteurs chacun de taille 2. Cette liste de taille 7 (7 hexagones) contient la translation à opérer pour produire chacun des hexagones. - -Faites nous confiance sur la trigonométrie, vous pouvez copier directement les deux lignes suivantes :: - - radius = 3. - translationToPerform = [[0.,0.],[3./2.*radius,-radius*math.sqrt(3.)/2],[3./2.*radius,radius*math.sqrt(3.)/2],[0.,radius*math.sqrt(3.)],[-3./2.*radius,radius*math.sqrt(3.)/2],[-3./2.*radius,-radius*math.sqrt(3.)/2],[0.,-radius*math.sqrt(3.)]] - - -Créer les 7 copies de ``d`` et opérer la "translation" correspondante. :: - - ds = len(translationToPerform)*[None] - for pos,t in enumerate(translationToPerform): - ds[pos] = d[:] # Perform a deep copy of d and place it at position 'pos' in ds - ds[pos] += t # Adding a vector to a set of coordinates does a translation. t could have been a DataArrayDouble too. - pass - -.. note:: Le ``pass`` à la fin de la boucle ``for`` n'est pas indispensable mais aide certains éditeurs à indenter le code. - -Une autre façon de faire un peu plus compacte (pour les amoureux des *one-liner*) : :: - - ds = [d + translationToPerform[i] for i in xrange(len(translationToPerform))] - -Agrégation de tableaux -~~~~~~~~~~~~~~~~~~~~~~ - -A partir de la liste d'instances de DataArrayDouble ``ds`` construire le DataArrayDouble ``d2`` résultat de l'*agrégation* des instances les unes à la suite des autres. :: - - d2 = mc.DataArrayDouble.Aggregate(ds) - -``d2`` contient désormais l'ensemble des tuples (6*7 de 2 composantes chacun) des -instances contenues dans ``ds``, en respectant l'ordre dans ``ds``. Cela parait évident, mais -l'agrégation de maillages et de champs respecte exactement le même principe pour -faciliter l'accès et le repérage des données. C'est par exemple une différence essentielle avec le -modèle MED fichier comme on le verra plus tard. - -.. note:: La méthode permettant d'agréger par composante (c'est-à-dire de concaténer des tableaux - colonne par colonne, plutôt que par tuples) s'appelle ``Meld()``. - -Trouver les tuples égaux -~~~~~~~~~~~~~~~~~~~~~~~~ - -La variable ``d2`` contient 42 tuples mais certains tuples apparaissent plusieurs fois. -Pour trouver les tuples égaux à 1e-12 près (précision absolue) invoquer ``findCommonTuples()``. -Utiliser ``help(mc.DataArrayDouble.findCommonTuples)`` pour en connaitre l'interface. Stocker le retour de la fonction dans -``c`` et ``cI`` :: - - oldNbOfTuples = d2.getNumberOfTuples() - c,cI = d2.findCommonTuples(1e-12) - -On a ainsi récupéré dans ``c`` l'ensemble des m=12 groupes de noeuds communs accollés. ``cI`` contient les index pour repérer les identifiants de points dans ``c`` pour tout groupe -``i`` dans [0,12). Ainsi les identifiants de tuples du groupe ``i`` commencent à l'index ``cI[i]`` et finissent à l'index ``cI[i+1]``. - -La méthode ``findCommonTuples()`` retourne ainsi 2 paramètres: un tableau contenant la liste des tuples communs -et un tableau d'index qui permet de naviguer dans le premier tableau. -Il s'agit d'une forme de retour très classique dans MEDCoupling, appelée *indirect indexing*. Cela apparaît souvent dans la manipulation des -maillages non structurés. Cette représentation est rappelée sur l'image ci-dessous, où le premier tableau et en haut, -et le deuxième tableau permettant de la parcourir en bas: - -.. image:: images/IndirectIndex.jpg - :scale: 50 - - -.. note:: Le dernier élément de ``cI`` pointe en dehors du tableau ``c``. Ce dernier index est toujours présent - et permet de s'assurer que des traitements tels que les *slices* présentés juste après, sont toujours valables, - sans avoir besoin de particulariser le dernier groupe. - - -.. _indirect-index-exo: - -Manipuler le format "indirect index" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Le nombre de tuples communs à 1e-12 près est donc égal à ``len(cI)-1``, c'est-à-dire 12 dans notre cas. -Récupérer la liste des identifiants de tuples du groupe 0 et mettre le résultat dans la variable ``tmp``. -Afficher ``tmp``. :: - - tmp = c[cI[0]:cI[0+1]] - print tmp - -Vérifier, en l'affichant, que pour tous les identifiants de tuples dans ``tmp``, leurs tuples sont bien égaux dans ``d2``. :: - - print d2[tmp] - -.. note:: On voit que le tuple (3.,0.) à 1e-12 près est répété 3 fois et ``tmp`` donne les positions respectives de - ces 3 répétitions. - -Maintenant on va déduire des variables ``oldNbOfTuples``, ``c`` et ``cI`` le nombre de tuples effectivement différents dans d2. -Pour ce faire, nous allons trouver le nombre de tuples doublons dans ``d2`` et soustraire le résultat de ``oldNbOfTuples``. - -Pour connaître le nombre de doublons, invoquer ``DataArrayInt.deltaShiftIndex`` qui retourne pour chaque groupe sa taille. -Mettre le résultat dans ``a``. :: - - a = cI.deltaShiftIndex() - -Déduire de ``a`` le nombre de tuples doublons dans ``d2`` par groupe et mettre le résultat dans ``b``. :: - - b = a-1 - -Enfin on peut trouver le nouveau nombre de tuples grâce à ``b`` et à ``oldNbOfTuples``. Mettre le résultat dans ``myNewNbOfTuples``. :: - - myNewNbOfTuples = oldNbOfTuples - sum(b.getValues()) - -Construire un tableau "old-2-new" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nous allons maintenant exploiter cette information pour extraire un seul -représentant dans chaque groupe de points dupliqués. - -Les deux tableaux ``c`` et ``cI`` définissent une surjection d'un espace de départ à 42 (``oldNbOfTuples``) tuples X -vers un espace à 24 (``myNewNbOfTuples``) tuples Y. - -.. image:: images/SurjectionDataArray.png - -L'autre manière de définir cette surjection (sans perte d'information) est de la représenter par un tableau "old-2-new". -Ce mode de stockage prend la forme d'un DataArrayInt ``o2n`` composé de Card(X) tuples (i.e. 42) à une composante. -Pour chaque tuple (élément) d'index ``i`` de ``o2n``, la case ``o2n[i]`` contient le nouvel identifiant de tuple dans Y. -On va donc d'un ancien identifiant (old) vers un nouveau (new). - -Nous allons construire ce tableau pour extraire un sous-ensemble des coordonnées de départ, et ne garder que les -tuples uniques (non doublons) dans l'ensemble de départ. - -.. note:: Pour toutes les opérations de renumérotation en MEDCoupling (bijection), - le format "old-2-new" est systématiquement utilisé. - -La méthode statique ``DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2()`` (nom un peu barbare, on vous l'accorde) -permet de passer du mode de stockage de cette surjection ``c``, ``cI`` au format ``o2n``. -On récupère au passage card(Y) c'est-à-dire le ``newNbOfTuples``. :: - - o2n, newNbOfTuples = mc.DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfTuples,c,cI) - print "Have I got the right number of tuples?" - print "myNewNbOfTuples = %d, newNbOfTuples = %d" % (myNewNbOfTuples, newNbOfTuples) - assert(myNewNbOfTuples == newNbOfTuples) - -Nous pouvons maintenant constuire le tableau de points uniques ``d3``. A l'aide de ``o2n`` -et ``newNbOfTuples``, invoquer ``DataArrayDouble.renumberAndReduce()`` sur ``d2``. :: - - d3 = d2.renumberAndReduce(o2n, newNbOfTuples) - -L'inconvénient de cette méthode c'est que finalement on ne connait pas pour chaque groupe de tuple communs dans -d2 quel identifiant a été utilisé. -Par exemple pour le groupe 0 on sait que les tuples 0, 8 et 16 (tmp.getValues()) sont tous égaux, et on ne sait -pas si 0, 8 ou 16 a été utilisé pour remplir ``d3``. - -Si l'on souhaite expliciter ce choix, on peut passer en format "new-2-old". Ce mode de stockage prend la forme d'un -``DataArrayInt`` ``n2o`` composé de Card(Y) -tuples (24) à 1 composante. Pour chaque tuple (élément) d'index i de ``n2o``, la case ``n2o[i]`` contient l'index du tuple qui a été choisi dans X. - -Pour passer d'une description "old-2-new" vers "new-2-old", la méthode est ``DataArrayInt.invertArrayO2N2N2O()``. -Effectuer ce traitement sur la variable ``o2n``. :: - - n2o = o2n.invertArrayO2N2N2O(newNbOfTuples) - -A l'aide de ``n2o`` on peut construire un ``d3_bis`` à partir de ``d2``, et qui contient la même chose que le ``d3`` précédent. :: - - d3_bis = d2[n2o] - print "Are d3 and d3_bis equal ? %s" % (str(d3.isEqual(d3_bis, 1e-12))) - -Translater tous les tuples -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Tous les tuples (ou nodes) sont à translater du vecteur [3.3,4.4] afin de recentrer toute la figure en ce point. :: - - d3 += [3.3,4.4] - -Constuire un maillage non strucuturé -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -On chercher maintenant à créer le maillage final montré dans la figure. Nous avons déjà construit le tableau -de coordonnées, il nous reste les cellules à créer. - -Créer un maillage non structuré ``m`` avec les coordonnées ``d3``. Le maillage``m`` a une mesh-dimension 2 :: - - m = mc.MEDCouplingUMesh("My7hexagons",2) - m.setCoords(d3) - print "Mesh dimension is", m.getMeshDimension() - print "Spatial dimension is", m.getCoords().getNumberOfComponents() - -Maintenant, allouer le nombre de cellules avec (un majorant du) nombre attendu de cellules. :: - - m.allocateCells(7) - -Enfin grâce à ``o2n`` on a la *connectivité* (i.e. la liste des points formant un hexagone) -des 7 hexagones utilisant les coordonnées ``d3``. :: - - for i in xrange(7): - cell_connec = o2n[6*i:6*(i+1)] - m.insertNextCell(mc.NORM_POLYGON, cell_connec.getValues()) - pass - -Vérifier que ``m`` est correct et ne contient pas d'anomalie. :: - - m.checkCoherency() - -.. note:: Il est toujours une bonne idée d'appeler cette méthode après la construction "from scratch" d'un maillage. - Cela assure qu'il n'y a pas de gros "couacs" dans la connectivité, etc ... - -Pour vérifier *visuellment* que ``m`` est correct, l'écrire dans un fichier "My7hexagons.vtu" et le visualiser dans ParaViS. :: - - m.writeVTK("My7hexagons.vtu") - -.. note:: On a écrit ici dans un fichier VTU et non MED, car MEDCoupling n'inclut pas par défaut les services de MED fichier. - Bien que l'on écrive au format VTK (\*.vtu), MEDCoupling ne dépend pas de VTK. - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingdataarray1_solution` diff --git a/medtool/doc/tutorial/medcoupling_en.rst b/medtool/doc/tutorial/medcoupling_en.rst deleted file mode 100644 index f46e42780..000000000 --- a/medtool/doc/tutorial/medcoupling_en.rst +++ /dev/null @@ -1,19 +0,0 @@ - - -Creating, Playing with DataArrays, Meshes and Fields with the MEDCoupling library -================================================================================== - -The objective of these exercises is to learn to manipulate MEDCoupling objects in Python. - - * the first exercise shows how to manipulate DataArrayDouble objects, - * the second shows how to manipulate MEDCouplingUMesh objects, - * and the third shows how to manipulate MEDCouplingFieldDouble objects. - - -.. toctree:: - :maxdepth: 2 - - medcoupling_dataarray1_en - medcoupling_umesh1_en - medcoupling_fielddouble1_en - diff --git a/medtool/doc/tutorial/medcoupling_fielddouble1_en.rst b/medtool/doc/tutorial/medcoupling_fielddouble1_en.rst deleted file mode 100644 index 7f3bca89c..000000000 --- a/medtool/doc/tutorial/medcoupling_fielddouble1_en.rst +++ /dev/null @@ -1,181 +0,0 @@ - -Playing with fields -------------------- - -In MEDCoupling fields are directly supported by a mesh. That is a major difference -with the field notion in MED file. - -Fields instances are well suited: - * for high level services where an interaction with the mesh is requested as in getValueOn(), getValueOnMulti(), integral(), normL1(), normL2(), fillFromAnalytic(), changeUnderlyingMesh(), ... - * to precisely transmit information between components when coupling codes. - -For information, the MEDCouplingFieldDouble implementation is tiny since -it delegates most of its work to MEDCouplingMesh, DataArrayDouble, MEDCouplingSpatialDiscretization classes. -MEDCouplingFieldDouble insure the coherency in this model. -It is often possible and even advised to manipulate the array and mesh of a MEDCouplingFieldDouble directly. - -Objective -~~~~~~~~~ - -This exercise focuses on the relationship between a mesh and the values of a field. - -* Create a field -* Aggregate fields -* Build parts of a field -* Renumbering a field -* Compare two fields coming from 2 sources -* Evaluation of a field on a point set -* Explode a field - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -Import the MEDCoupling Python module. :: - - from MEDCoupling import * - -We are going to create a MEDCouplingUMesh from a 3D cartesian mesh. Each direction will contain 10 cells and 11 nodes. The generated MEDCouplingUMesh -will contain 1000 cells. :: - - xarr=DataArrayDouble.New(11,1) - xarr.iota(0.) - cmesh=MEDCouplingCMesh.New() - cmesh.setCoords(xarr,xarr,xarr) - mesh=cmesh.buildUnstructured() - -In order to put the focus on mixed types, cells with an even id will be converted to polyhedrons :: - - mesh.convertToPolyTypes(DataArrayInt.Range(0,mesh.getNumberOfCells(),2)) - -Creation of a field -~~~~~~~~~~~~~~~~~~~ - -Create a field called "MyField" by application of an analytic function "(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)". -Two possibilities : - -* Directly by calling fillFromAnalytic on a mesh :: - - f=mesh.fillFromAnalytic(ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") - f.setName("MyField") - -* Or by building a new instance :: - - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - f2.setMesh(mesh) - f2.setName("MyField2") - f2.fillFromAnalytic(1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") - -Compare the two fields: -Compare f and f2 with a precision of 1e-12 on coordinates and 1e-12 on values. :: - - print "f and f2 are equal: %s"%(f.isEqualWithoutConsideringStr(f2,1e-12,1e-12)) - -Builing of a subpart of a field -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Store in ids1 the list of tuple ids whose value is within [0.0,5.0] (DataArrayDouble.getIdsInRange) . From ids1 build the sub-part fPart1 of the field "f". :: - - ids1=f.getArray().getIdsInRange(0.,5.) - fPart1=f.buildSubPart(ids1) - -.. image:: images/FieldDouble1_1.png - -Select the part "fPart2" of the field "f" whose values are in [50.,infinity). :: - - ids2=f.getArray().getIdsInRange(50.,1.e300) - fPart2=f.buildSubPart(ids2) - -Renumbering cells -~~~~~~~~~~~~~~~~~ - -The generated file "fPart1" is valid for MEDCoupling, but its cells are not sorted by geometric type: it is not valid from a MED file point of view. By using MEDCouplingUMesh.sortCellsInMEDFileFrmt and DataArrayDouble.renumberInPlace -renumber manually fPart1 starting from a deep copy of fPart1. :: - - fPart1Cpy=fPart1.deepCpy() - o2n=fPart1Cpy.getMesh().sortCellsInMEDFileFrmt() - fPart1Cpy.getArray().renumberInPlace(o2n) - -"fPart1Cpy" is now normalized to be stored in a MED file (we will tackle this later). -Check that fPart1Cpy and fPart1 are the same (discarding any permutation): :: - - fPart1Cpy.substractInPlaceDM(fPart1,12,1e-12) - fPart1Cpy.getArray().abs() - print "Fields are the same? %s"%(fPart1Cpy.getArray().accumulate()[0]<1e-12) - -.. note:: This is in fact a very special case of interpolation. Except that here - we assume that the supports of "fPart1" and "fPart1Cpy" are equal, discarding any - cell and/or node permutation. - -Aggregate Fields -~~~~~~~~~~~~~~~~ - -Aggregate fields "fPart1" and "fPart2". The result is stored in "fPart12". :: - - fPart12=MEDCouplingFieldDouble.MergeFields([fPart1,fPart2]) - -.. image:: images/FieldDouble1_2.png - -.. note:: Apologies for the name MEDCouplingFieldDouble.MergeFields instead of - AggregateFields. - -Evaluation of a MEDCouplingFieldDouble on given space points -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Evaluate the values of the computed field "fPart12" on the barycenters of its mesh. -Evaluate the field "f" on the same barycenters. The method used is MEDCouplingFieldDouble.getValueOnMulti(). :: - - bary=fPart12.getMesh().getBarycenterAndOwner() - arr1=fPart12.getValueOnMulti(bary) - arr2=f.getValueOnMulti(bary) - delta=arr1-arr2 - delta.abs() - print "Check OK: %s"%(delta.accumulate()[0]<1e-12) - -.. note:: In this context and for example for a field on cells, "evaluate" at a point means returning the value of the cell containing the point. -.. note:: This technique can be used to quickly assess the quality of an interpolation. - -Operations on a field -~~~~~~~~~~~~~~~~~~~~~ - -Compute the integral of the field "fPart12" and compute it a second time by using -DataArrayDouble.accumulate on the underlying DataArrayDouble of this "fPart12" (remember that the cell volumes are all 1.0). -To show the link with the underlying mesh, scale the underlying mesh (fPart12.getMesh()) by 1.2 and centered at [0.,0.,0.]. -Recompute the integral. -:: - - fPart12.integral(0,True) - fPart12.getArray().accumulate() - fPart12.getMesh().scale([0.,0.,0.],1.2) - abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 - -Exploding a field -~~~~~~~~~~~~~~~~~ - -Starting from "mesh", create a vector field on cells "fVec" with 3 components representing the displacement between each cell's barycenter and the point [5.,5.,5.]. Use MEDCouplingMesh.fillFromAnalytic(). :: - - fVec=mesh.fillFromAnalytic(ON_CELLS,3,"(x-5.)*IVec+(y-5.)*JVec+(z-5.)*KVec") - -Create the reduction of "fVec" ("fVecPart1") on cell IDs "ids1" (previously obtained). :: - - fVecPart1=fVec.buildSubPart(ids1) - fVecPart1.setName("fVecPart1") - -Build the scalar field fPart1Exploded having the same values as "fPart1" but supported by an exploded mesh (in comparison to fPart1.getMesh()). -To explode the underlying mesh fPart1.getMesh(), use the vectorial displacement field "fVecPart1" in order to apply to each cell the proper translation. :: - - cells=fPart1.getMesh().getNumberOfCells()*[None] - for icell,vec in enumerate(fVecPart1.getArray()): - m=fPart1.getMesh()[[icell]] - m.zipCoords() # pas absolument nécessaire mais permet d'être économe en mémoire - m.translate(vec) - cells[icell]=m - pass - meshFVecPart1Exploded=MEDCouplingUMesh.MergeUMeshes(cells) - fPart1.setMesh(meshFVecPart1Exploded) - -.. image:: images/FieldDouble1_1_exploded.png - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingfielddouble1_solution` diff --git a/medtool/doc/tutorial/medcoupling_fielddouble1_fr.rst b/medtool/doc/tutorial/medcoupling_fielddouble1_fr.rst deleted file mode 100644 index d6bf354e1..000000000 --- a/medtool/doc/tutorial/medcoupling_fielddouble1_fr.rst +++ /dev/null @@ -1,246 +0,0 @@ - -Manipuler des champs de double ------------------------------- - -Les champs dans MEDCoupling ont comme support un unique maillage, de dimension fixée, et bien défini. -Cela semble trivial mais c'est en fait une différence majeure avec la notion de champ dans MED fichier, qui elle est beaucoup -plus permissive. - -Les champs sont utiles pour : - -* stocker des valeurs d'une grandeur physique relative au problème traité, mais aussi -* des services de haut niveau où l'interaction avec les maillages - est requise comme par exemple ``getValueOn()``, ``getValueOnMulti()``, ``integral()``, ``getMeasureField`` - ``normL1()``, ``normL2()``, ``fillFromAnalytic()``, ... qui calculent toutes des valeurs en lien avec le maillage - (par exemple le *volume* des cellules) -* expliciter précisément les informations échangées entre les différents codes - lors de couplage. - -Pour information, l'implémentation de ``MEDCouplingFieldDouble`` est relativement petite car cette classe -délègue la très large majorité de ses traitements à des instances de classes aggrégées -comme ``MEDCouplingMesh``, ``DataArrayDouble``, et ``MEDCouplingSpatialDiscretization``. -La classe ``MEDCouplingFieldDouble`` permet d'assurer la cohérence entre tous ces éléments. - - -Il est souvent possible et même parfois recommandé de manipuler les tableaux (un ``DataArrayDouble``) -et/ou le maillage d'une instance de ``MEDCouplingFieldDouble`` directement. - -Objectifs -~~~~~~~~~ - -Cet exercice met l'accent sur la relation entre le maillage et les valeurs d'un champ. - -* Créer un champ -* Agréger des champs -* Construire une sous-partie d'un champ -* Renuméroter les entités d'un champ -* Comparer 2 champs venant de 2 sources différentes -* Evaluation d'un champ sur un ensemble de points -* Exploser un champ - -Début de l'implementation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Importer le module Python ``MEDCoupling``. :: - - import MEDCoupling as mc - -Créer un ``MEDCouplingUMesh`` à partir d'un maillage 3D cartésien. Chaque direction contiendra 10 cells -et 11 nodes. Le ``MEDCouplingUMesh`` résultant contiendra ainsi 1000 cells. :: - - xarr = mc.DataArrayDouble.New(11,1) - xarr.iota(0.) # Generate s, s+1, s+2, ... with a given start value s - cmesh = mc.MEDCouplingCMesh.New() - cmesh.setCoords(xarr,xarr,xarr) - mesh = cmesh.buildUnstructured() - -.. note:: La méthode ``MEDCouplingMesh.buildUnstructured()`` est très utile pour construire rapidement un maillage - non structuré afin de tester quelque chose. - -Afin de mettre en évidence le problème des types géométriques multiples, convertir en polyhèdres -les cellules d'identifiant pair :: - - mesh.convertToPolyTypes(mc.DataArrayInt.Range(0,mesh.getNumberOfCells(),2)) - - -Création d'un champ -~~~~~~~~~~~~~~~~~~~ - -Créer un champ scalaire (une seule composante) aux cellules (P0) appelé "MyField" en appliquant la fonction analytique -suivante ``(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)``, où ``(x, y, z)`` représente implicitement les coordonnées du barycentre -d'une cellule. -Pour cela, deux possiblités : - -* Directement en appelant ``fillFromAnalytic()`` sur un maillage :: - - f = mesh.fillFromAnalytic(mc.ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") # 1 means that the field should have one component - f.setName("MyField") - -* Ou en créant au préalable un champ non initialisé, et en appliquant ``fillFromAnalytic()`` sur cette - instance de ``MEDCouplingFieldDouble`` :: - - f2 = mc.MEDCouplingFieldDouble(mc.ON_CELLS, mc.ONE_TIME) - f2.setMesh(mesh) - f2.setName("MyField2") - f2.fillFromAnalytic(1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") # 1 means that the field should have one component - -Comparer les deux champs : comparer ``f`` et ``f2`` avec une précision de 1e-12 sur les coordonnées et -de 1e-13 sur les valeurs. :: - - print "Are f and f2 equal?", f.isEqualWithoutConsideringStr(f2,1e-12,1e-13) - - -.. note:: Le ``WithoutConsideringStr`` dans le nom de la méthode précédente indique que les noms des champs ne seront - pas comparés. On retrouve ce suffixe dans d'autres méthodes MEDCoupling. - - -Construire une sous-partie d'un champ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Récupérer dans une variable ``ids1`` la liste des identifiants de cellules pour lesquelles la valeur du champ est dans le -range [0.0,5.0]. Utiliser pour cela la méthode ``DataArrayDouble.getIdsInRange()``. Avec ce résultat, construire la -sous-partie ``fPart1`` du champ ``f``. :: - - da1 = f.getArray() # a DataArrayDouble, which is a direct reference (not a copy) of the field's values - ids1 = da1.getIdsInRange(0., 5.) - fPart1 = f.buildSubPart(ids1) - fPart1.writeVTK("ExoField_fPart1.vtu") - -.. image:: images/FieldDouble1_1.png - -Sélectionner la partie ``fPart2`` du champ ``f`` dont toutes les valeurs de tuples -sont dans ``[50.,+infinity)``. :: - - ids2 = f.getArray().getIdsInRange(50., 1.e300) - fPart2 = f.buildSubPart(ids2) - -Ce genre de technique permet d'extraire facilement les parties d'un champ relatives à un groupe de mailles par exemple. - -Renuméroter les entités d'un champ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -La partie ``fPart1`` générée est valide d'un point de vue de MEDCoupling. Mais elle -n'est pas valide d'un point de vue de MED *fichier*. -Une renumérotation s'impose dans l'hypothèse de stocker ce champs dans un fichier MED afin d'ordonner les cellules -par type géométrique. - -L'idée est d'utiliser les deux méthodes ``MEDCouplingUMesh.sortCellsInMEDFileFrmt()`` et -``DataArrayDouble.renumberInPlace()`` pour renuméroter manuellement une *copie* de ``fPart1``: :: - - fPart1Cpy = fPart1.deepCpy() - o2n = fPart1Cpy.getMesh().sortCellsInMEDFileFrmt() - fPart1Cpy.getArray().renumberInPlace(o2n) - -``fPart1Cpy`` est désormais normalisé pour être stocké dans un fichier MED (ce que nous verrons plus loin) - -Vérifier que ``fPart1Cpy`` et ``fPart1`` sont les mêmes à une permutation près (``MEDCouplingFieldDouble.substractInPlaceDM()``) :: - - fPart1Cpy.substractInPlaceDM(fPart1,12,1e-12) - fPart1Cpy.getArray().abs() - print "Equal field ? %s" % (fPart1Cpy.getArray().accumulate()[0]<1e-12) - -.. note:: La renumérotation effectuée ici représente en fait d'un cas très particulier - d'interpolation. Effectivement l'hypothèse est faite que les supports - de ``fPart1`` et ``fPart1Cpy`` sont égaux à une permutation de cellule - et/ou noeuds. - -Agréger des champs -~~~~~~~~~~~~~~~~~~ - -Agréger ``fPart1`` et ``fPart2`` (utiliser ``MEDCouplingFieldDouble.MergeFields()``). Et mettre le résultat de l'agrégation -dans ``fPart12``. :: - - fPart12 = mc.MEDCouplingFieldDouble.MergeFields([fPart1,fPart2]) - fPart12.writeVTK("ExoField_fPart12.vtu") - -.. note:: La méthode ``MEDCouplingFieldDouble.MergeFields()`` devrait vraiment se - nommer ``MEDCouplingFieldDouble.AggregateFields()`` ... - -.. image:: images/FieldDouble1_2.png - -Evaluation d'un champ en des points donnés de l'espace -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Evaluer la valeur du champ ``fPart12`` calculé précédemment sur les barycentres des cellules de son -maillage (variable ``bary``) et mettre le résultat dans ``arr1``. -Utiliser pour cela les méthodes ``MEDCouplingFieldDouble.getValueOnMulti()`` et ``MEDCouplingMesh.getBarycenterAndOwner()``. - -De manière similaire, évaluer ensuite directement le champ ``f`` en utilisant la même liste de points -que précédemment (``bary``) et mettre le résultat dans ``arr2``. - -Vérifier ensuite que ``arr1`` et ``arr2`` sont bien égaux: :: - - bary = fPart12.getMesh().getBarycenterAndOwner() - arr1 = fPart12.getValueOnMulti(bary) - arr2 = f.getValueOnMulti(bary) - delta = arr1-arr2 - delta.abs() - print "Is field evaluation matching?", (delta.accumulate()[0]<1e-12) - -.. note:: Dans ce contexte, et pour un champ aux cellules (P0) par exemple, "évaluer" en un point signifie retourner la valeur - de la cellule contenant le point donné. - Pour les champs aux noeuds (P1), les cellules doivent être de types simples (triangles, tétraèdres) et une interpolation - linéaire est alors utilisée. - -.. note:: Cette technique peut être utilisée pour juger rapidement de la qualité d'une interpolation. - -Opérations sur les champs -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Calculer l'intégrale du champ ``fPart12`` sur le maillage, et la retrouver d'une autre manière en utilisant -la méthode ``DataArrayDouble.accumulate()`` sur le tableau de valeurs de ce champ. -On rappelle que, vu le maillage simplifié en jeu, les cellules ont toutes un volume unité. :: - - integ1 = fPart12.integral(0,True) - integ1_bis = fPart12.getArray().accumulate()[0] - print "First integral matching ?", ( abs(integ1 - integ1_bis) < 1e-8 ) - -Ensuite appliquer une homotétie de facteur 1.2 centrée en [0.,0.,0.] sur le support de ``fPart12`` (c'est-à-dire son maillage). -Quelle est alors la nouvelle valeur de l'intégrale ? :: - - fPart12.getMesh().scale([0.,0.,0.], 1.2) - integ2 = fPart12.integral(0,True) - print "Second integral matching ?", ( abs(integ2-integ1_bis*1.2*1.2*1.2) < 1e-8 ) - -Exploser un champ - Vecteurs de déplacement -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nous allons maintenant créer un nouveau maillage représentant l'*éclaté* du maillage initial. - -Partant du maillage ``mesh`` créer un champ vectoriel aux cellules ``fVec`` ayant 3 composantes représentant -le vecteur déplacement entre le point [5.,5.,5.] et le barycentre de chaque cellule du maillage. -Utiliser la méthode ``MEDCouplingMesh.fillFromAnalytic()`` : :: - - fVec = mesh.fillFromAnalytic(mc.ON_CELLS,3,"(x-5.)*IVec+(y-5.)*JVec+(z-5.)*KVec") - -.. note:: Les identifiants spéciaux ``IVec``, ``JVec`` et ``KVec`` représentent les vecteurs unitaires du repère. - -Créer ensuite une réduction de ``fVec`` (nommée ``fVecPart1``) sur les cellules ``ids1`` précédemment obtenues : :: - - fVecPart1 = fVec.buildSubPart(ids1) - fVecPart1.setName("fVecPart1") - -Construire le champ scalaire ``fPart1Exploded`` ayant les mêmes valeurs que ``fPart1`` mais reposant sur un maillage *eclaté* -par rapport à celui de ``fPart1.getMesh()``. Pour exploser ``fPart1.getMesh()`` utiliser le champ de déplacement vectoriel -``fVecPart1`` afin d'appliquer à chaque cellule la translation associée. :: - - cells = fPart1.getMesh().getNumberOfCells() * [None] - for icell,vec in enumerate(fVecPart1.getArray()): - m = fPart1.getMesh()[[icell]] - m.zipCoords() # Not mandatory but saves memory - m.translate(vec) - cells[icell] = m - pass - meshFVecPart1Exploded = mc.MEDCouplingUMesh.MergeUMeshes(cells) - fPart1.setMesh(meshFVecPart1Exploded) - fPart1.writeVTK("ExoField_fPart1_explo.vtu") - -Et voilà ce que vous devriez obtenir: - -.. image:: images/FieldDouble1_1_exploded.png - :scale: 120 - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingfielddouble1_solution` diff --git a/medtool/doc/tutorial/medcoupling_fr.rst b/medtool/doc/tutorial/medcoupling_fr.rst deleted file mode 100644 index 6b2f89b83..000000000 --- a/medtool/doc/tutorial/medcoupling_fr.rst +++ /dev/null @@ -1,19 +0,0 @@ - - -MEDCoupling : créer et manipuler des DataArrays, des Meshes et des Fields -========================================================================= - -L'objectif de ces exercices est d'apprendre à manipuler les objets MEDCoupling en Python. - - * La première série d'exercices montre comment manipuler des tableaux ``DataArrayDouble`` et ``DataArrayInt``. - * La deuxième série d'exercices montre comment manipuler des maillages ``MEDCouplingUMesh``. - * La troisième série d'exercices montre comment manipuler des champs ``MEDCouplingFieldDouble``. - - -.. toctree:: - :maxdepth: 2 - - medcoupling_dataarray1_fr - medcoupling_umesh1_fr - medcoupling_fielddouble1_fr - diff --git a/medtool/doc/tutorial/medcoupling_umesh1_en.rst b/medtool/doc/tutorial/medcoupling_umesh1_en.rst deleted file mode 100644 index c7c319f39..000000000 --- a/medtool/doc/tutorial/medcoupling_umesh1_en.rst +++ /dev/null @@ -1,215 +0,0 @@ - -Playing with unstructured mesh ------------------------------- - -Unstructured meshes are the most used mesh type. MEDCouplingUMesh is the name of the class representing unstuctured meshes in MEDCoupling. MEDCouplingUMesh inherits from the MEDCouplingPointSet class that deals with all methods handling coordinates only. -MEDCouplingUMesh adds two more attributes : -* nodal connectivity -* nodal connectivity index - -Objective -~~~~~~~~~ - -The aim here is to manipulate unstructured mesh instances to extract part of an unstructured mesh. -Several points will be covered in this exercise : - -* coordinates modification of an unstructured mesh -* extraction of a slice -* build a part of a mesh given cell ids -* playing with data, index arrays - -.. image:: images/UMesh1.png - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -Import the MEDCoupling Python module. :: - - from MEDCoupling import * - -We now build a mesh containing artificially two types of cell (NORM_HEXA8 and NORM_POLYHED) to highlight the possibility to work with non-homogeneous cell types. -mesh3D is an extruded mesh containing 18 cells composed into 3 levels along Z of 6 cells. -Copy paste the following lines. :: - - coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - conn=[0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - mesh3D=MEDCouplingUMesh.New("mesh3D",3) - mesh3D.allocateCells(18) - mesh3D.insertNextCell(NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(NORM_HEXA8,conn[110:118]); - mesh3D.insertNextCell(NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(NORM_HEXA8,conn[228:236]); - mesh3D.insertNextCell(NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(NORM_HEXA8,conn[346:354]); - myCoords=DataArrayDouble.New(coords,60,3) - myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) - mesh3D.setCoords(myCoords) - mesh3D.orientCorrectlyPolyhedrons() - mesh3D.sortCellsInMEDFileFrmt() - mesh3D.checkCoherency() - renum=DataArrayInt.New(60) ; renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) - mesh3D.renumberNodes(renum,60) - -Convert coordinate unit from meters to centimeters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It might seem stupid, but this comes up regularly when coupling... :: - - mesh3D.getCoords()[:]*=100. - mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) - -.. note:: It is important to keep the DataArrayDouble instance up-to-date about the physical units to avoid ambiguity. The INTERP_KERNEL library includes a physical unit processor. - -Find the different Z levels in mesh3D and sort in increasing order -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -DataArrayDouble.getDifferentValues and DataArrayDouble.sort can help you! :: - - zLev=mesh3D.getCoords()[:,2] - zLev=zLev.getDifferentValues(1e-12) - zLev.sort() - -Extract the 6 cells of the second row along Oz -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are 3 possibilities to do that. We will see them from the simplest to the most complicated. - -* Using buildSlice3D: - -Simple method but a little costly. To do that simply define a plane having direction vector equal to [0.,0.,1.] and -going through point [0.,0.,(zLev[1]+zLev[2])/2]. This method retrieves 2 things : the slicemesh containing the result slicing mesh3D -and foreach 2D cell in slicemesh, the corresponding cell id into mesh3D. :: - - tmp,cellIdsSol1=mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2],[0.,0.,1.],1e-12) - -* Using Barycenter of cells of mesh3D : - -Firstly, compute the barycenters of the 3D cells. Then select the 2nd component of the barycenter of the cells. -Finally select the tuple ids (corresponding to cell ids) falling in the range [zLev[1],zLev[2]]. :: - - bary=mesh3D.getBarycenterAndOwner() - baryZ=bary[:,2] - cellIdsSol2=baryZ.getIdsInRange(zLev[1],zLev[2]) - -* Using MEDCouplingExtrudedMesh : - -This is the safest method since it only uses the nodal connectivity to compute the extrusion. The coordinates are ignored. -Two things are needed to build a MEDCouplingExtrudedMesh. The 3D mesh you expect to be an extruded mesh, and a 2D mesh -lying on the same coordinates, from which the extrusion will be computed. -Let's begin with the build of the 2D mesh. We build it from all the nodes on a plane going through point [0.,0.,zLev[0]] and with normal vector [0.,0.,1.] (MEDCouplingUMesh.findNodesOnPlane()). -Then invoke MEDCouplingUMesh.buildFacePartOfMySelfNode to build mesh2D (read the documentation of buildFacePartOfMySelfNode()). :: - - nodeIds=mesh3D.findNodesOnPlane([0.,0.,zLev[0]],[0.,0.,1.],1e-10) - mesh2D=mesh3D.buildFacePartOfMySelfNode(nodeIds,True) - -Then it is possible to compute an extrusion from mesh3D and mesh2D. :: - - extMesh=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,0) - -Then simply request the 2nd row. :: - - cellIdsSol3=extMesh.getMesh3DIds()[mesh2D.getNumberOfCells():2*mesh2D.getNumberOfCells()] - -It is now possible to check that the 3 solutions are the same : :: - - for i in xrange(3): - exec("print cellIdsSol%s.getValues()"%(i+1)) - -Extract a sub-part of mesh3D -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the previously retrieved cell ids in cellIdsSol2 to compute a sub-part of mesh3D. :: - - mesh3DPart=mesh3D[cellIdsSol2] # equivalent to mesh3DPart=mesh3D.buildPartOfMySelf(cellIdsSol2,True) - -.. note:: The geometrical type doesn't play any role here. "mesh3DPart" now contains len(cellIdsSol2) cells. The cell #0 in "mesh3DPart" corresponds to the cell #cellIdsSol2[0] in "mesh3D" and so on ... "cellIdsSol2" can thus be seen as an array "new-to-old". - -At this point, "mesh3DPart" lies on the same coordinates, so mesh3DPart has 60 nodes whereas only 30 are necessary. To zip the orphan nodes in "mesh3DPart", simply invoke zipCoords(): :: - - mesh3DPart.zipCoords() - -At this point mesh3DPart only contains 30 nodes and 6 cells. To prepare to MED file I/O we have to check if mesh3DPart is ready to be written safely into a MED file (i.e. if the cells are indeed ordered by type). :: - - print mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) - -Or: :: - - print mesh3DPart.checkConsecutiveCellTypes() - -You can also print the content of the mesh "mesh3Dpart": :: - - print mesh3DPart.advancedRepr() - -We see that mesh3DPart contains 6 cells, 4 HEXA8 then 2 POLYHED. Everything's OK: the cells are grouped by geometrical type. - -Extract the 3 cells in mesh3D whose barycenters are along the line (pt=[250.,150.,0.],v=[0.,0.,1.]) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are 2 solutions to do that. - -* using the barycenters of mesh3D again: same principle than above. :: - - baryXY=bary[:,[0,1]] - baryXY-=[250.,150.] - magn=baryXY.magnitude() - cellIds2Sol1=magn.getIdsInRange(0.,1e-12) - -* using extrusion extMesh: starting from the unique cell in mesh2D whose center is at [250.,150.,0.] MEDCouplingExtrudedMesh.getMesh3DIds retrieves the cell IDs sorted by slice. :: - - bary2=mesh2D.getBarycenterAndOwner()[:,[0,1]] - bary2-=[250.,150.] - magn=bary2.magnitude() - ids=magn.getIdsInRange(0.,1e-12) - idStart=int(ids) # ids is assumed to contain only one value, if not an exception is thrown - cellIds2Sol2=extMesh.getMesh3DIds()[range(idStart,mesh3D.getNumberOfCells(),mesh2D.getNumberOfCells())] - -Now, build the sub-part of mesh3D using cell IDs in cellIds2Sol1. :: - - mesh3DSlice2=mesh3D[cellIds2Sol1] - mesh3DSlice2.zipCoords() - -Duplicate "mesh3DSlice2" and translate it -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This part of the exercise shows how to perform copy and aggregation. This can be useful to build complex meshes, or to get in a single object several mesh parts coming from several processors. - -Perform a deep copy of mesh3DSlice2. On this copy perform a translation v=[0.,1000.,0.]. -Then aggregate mesh3DSlice2 with its translated copy, using MEDCouplingUMesh.MergeUMeshes. :: - - mesh3DSlice2bis=mesh3DSlice2.deepCpy() - mesh3DSlice2bis.translate([0.,1000.,0.]) - mesh3DSlice2All=MEDCouplingUMesh.MergeUMeshes([mesh3DSlice2,mesh3DSlice2bis]) - -.. note:: My apologies for the name of the method MEDCouplingUMesh.MergeUMeshes. In future version it will be called AggregateUMeshes. For information, to merge two (or more) unstructured meshes, one has to invoke MergeUMeshes(), then mergeNodes() on the result, and finally zipConnectivity(). - - -Descending connectivity -~~~~~~~~~~~~~~~~~~~~~~~ - -The aim here is to retrieve the internal faces of mesh3D. -To this purpose, we build the "descending" mesh from "mesh3D" ("mesh3Dsurf"), i.e. the mesh with mesh dimension (mesh3D.getMeshDimension()-1) made of the faces of each cell in "mesh3D". -The method MEDCoupling.buildDescendingConnectivity builds this mesh and also returns the correspondences "mesh3D" <-> "mesh3DSurf". - -A face from "mesh3DSurf" is said to be internal if and only if it is shared by more than one 3D cell in "mesh3D" (see reverse descending connectivity (out parameter 3 et 4)). :: - - mesh3DSurf,desc,descIndx,revDesc,revDescIndx=mesh3D.buildDescendingConnectivity() - numberOf3DCellSharing=revDescIndx.deltaShiftIndex() - cellIds=numberOf3DCellSharing.getIdsNotEqual(1) - mesh3DSurfInside=mesh3DSurf[cellIds] - mesh3DSurfInside.writeVTK("mesh3DSurfInside.vtu") - -.. image:: images/mesh3DSurfInside.jpg - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingumesh1_solution` diff --git a/medtool/doc/tutorial/medcoupling_umesh1_fr.rst b/medtool/doc/tutorial/medcoupling_umesh1_fr.rst deleted file mode 100644 index 74993cdc6..000000000 --- a/medtool/doc/tutorial/medcoupling_umesh1_fr.rst +++ /dev/null @@ -1,292 +0,0 @@ - -Manipuler les maillages non structurés --------------------------------------- - -Les meshes non-structurées sont le type de maillage le plus utilisé. ``MEDCouplingUMesh`` est le nom de la classe en charge -de représenter ces maillages dans MEDCoupling. ``MEDCouplingUMesh`` hérite de la classe ``MEDCouplingPointSet``. -``MEDCouplingPointSet`` gère toutes les méthodes relatives au coordonnées. ``MEDCouplingUMesh`` a deux attributs en plus de -ceux de ``MEDCouplingPointSet`` permettant de décrire la liste des noeuds contribuants à une cellule (i.e. la *connectivité*). - -Objectifs -~~~~~~~~~ - -Le but ici est de manipuler des maillages non structurés (en extraire une partie, etc...). -Plusieurs points seront traités dans cet exercice : - -* modification des coordonnées d'un maillage -* extraction d'une coupe d'un maillage -* extraire une partie de maillage à partir d'identifiants de cellules -* manipuler les indices, etc ... -* manipulation de la connectivité descendante - -.. image:: images/UMesh1.png - :scale: 80 - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Importer le module Python ``MEDCoupling``. :: - - import MEDCoupling as mc - -Construire un maillage. Ce maillage ``mesh3D`` contient artificiellement 2 types de cellules (``mc.NORM_HEXA8`` et ``mc.NORM_POLYHED``) -pour appréhender le mélange de types geometriques. -``mesh3D`` est un *maillage extrudé* contenant 18 cellules composées de 3 niveaux selon Z, chaque niveau ayant 6 cellules. -Faire un bon gros copier-coller des lignes suivantes pour construire la mesh (l'intérêt de l'exercise vient après) : :: - - coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - conn=[0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - mesh3D = mc.MEDCouplingUMesh("mesh3D",3) - mesh3D.allocateCells(18) - mesh3D.insertNextCell(mc.NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[110:118]); - mesh3D.insertNextCell(mc.NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[228:236]); - mesh3D.insertNextCell(mc.NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[346:354]); - myCoords = mc.DataArrayDouble(coords,60,3) - myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) - mesh3D.setCoords(myCoords) - mesh3D.orientCorrectlyPolyhedrons() - mesh3D.sortCellsInMEDFileFrmt() - mesh3D.checkCoherency() - renum = mc.DataArrayInt(60); renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) - mesh3D.renumberNodes(renum,60) - -Convertir les unités -~~~~~~~~~~~~~~~~~~~~ - -On convertit ici les coordonnées de mètres en centimètres. -Cela paraît idiot mais c'est un très grand classique du couplage ... :: - - mesh3D.getCoords()[:] *= 100. - mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) - -.. note:: Il est important de mettre à jour les informations sur les composantes des coordonnées (les unités) pour éviter toute ambiguïté. - INTERP_KERNEL library inclut un évaluateur d'unité. - -.. note:: Noter l'astuce sur la première ligne ``[:]`` afin de récupérer la version inscriptible des coordonnées - (et non une copie temporaire) - -Trouver les différents niveaux -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Le maillage est extrudé, il est donc très régulier, et aligné sur les axes Ox, Oy et Oz (cf figure). -On veut connaître quelles -sont les côtes Z des différentes couches de cubes. -Extraire les différents niveaux en Z dans ``mesh3D``, rangés de manière croissante. -Utiliser la méthode ``DataArrayDouble.getDifferentValues()`` and ``DataArrayDouble.sort()``. :: - - zLev = mesh3D.getCoords()[:,2] - zLev = zLev.getDifferentValues(1e-12) - zLev.sort() # In-place sort - -Extraire des identifiants de cellules -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Extraire les 6 identifiants des cellules de la seconde rangée suivant Oz. -Il y a 3 possibilités pour faire cela. Nous allons les voir du plus simple au plus complexe. - -* En utilisant ``buildSlice3D()`` : - Méthode très simple mais gourmande en CPU. Pour trouver la solution il suffit de définir un plan dont le vecteur normal est ``[0.,0.,1.]`` - et passant par le point ``[0., 0., (zLev[1]+zLev[2])/2]``. - La méthode retourne deux choses : le maillage de coupe ``tmp`` (un maillage de mesh-dimension 2, mais de dimension spatiale - 3) et pour chaque cellule 3D surfacique de ``tmp``, l'identifiant de la cellule 3D (=un volume) coupée dans le - maillage de départ :: - - tmp, cellIdsSol1 = mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2], [0.,0.,1.], 1e-12) - -* En utilisant les barycentres des cellules de ``mesh3D`` : - L'utilisation des barycentres est une technique classique pour identifier un ensemble de cellules répondant à certains - critères géométriques. - Il s'agit d'abord de calculer les barycentres des cellules 3D de ``mesh3D`` (méthode - ``MEDCouplingUMesh.getBarycenterAndOwner()``). - (*Note*: le nom -- un peu trop long -- de cette méthode hérite du passé. Le "AndOwner" indique le fait qu'en C++ - l'appelant est responsable de la désallocation de l'objet retourné : il prend l'*ownership* du résultat). - - Ensuite sélectionner la composante #2 des barycentres des cellules et mettre le résultat dans ``baryZ``. - Ensuite il suffit de selectionner dans ``baryZ`` les tuples qui sont dans l'intervalle ``[zLev[1], zLev[2]]``. - Les identifiants de ces tuples (i.e. leur index dans ``baryZ``) est directement un identifiant de cellule - car ``getBarycenterAndOwner()`` retourne un tableau indéxé par les numéros de cellule.:: - - bary = mesh3D.getBarycenterAndOwner() - baryZ = bary[:,2] - cellIdsSol2 = baryZ.getIdsInRange(zLev[1], zLev[2]) - -* En utilisant ``MEDCouplingExtrudedMesh`` : - C'est la méthode exclusivement basée sur la connectivité nodale pour déduire l'extrusion. Les coordonnées sont ici ignorées. - Pour construire un ``MEDCouplingExtrudedMesh`` deux objets sont requis. Le maillage non-structuré 3D - représentant en fait un maillage *extrudé*, et un maillage non structuré 3D surfacique (mesh-dim 2) - reposant sur les mêmes coordonnéees, à partir duquel l'extrusion sera calculée. - Commencer par construire le maillage 3D surfacique. Pour ce faire il suffit de repérer les noeuds appartenant - à 1e-10 près de plan de vecteur normal ``[0.,0.,1.]`` et passant - par ``[0.,0.,zLev[0]]`` (``MEDCouplingUMesh.findNodesOnPlane()``). Ensuite appeler ``MEDCouplingUMesh.buildFacePartOfMySelfNode()`` - pour construire ``mesh2D`` (lire la doc de la fonction). :: - - nodeIds = mesh3D.findNodesOnPlane([0., 0., zLev[0]], [0.,0.,1.], 1e-10) - mesh2D = mesh3D.buildFacePartOfMySelfNode(nodeIds, True) - - - Il est alors possible de construire un maillage extrudé ``extMesh`` à partir de ``mesh3D`` et de ``mesh2D``. - Un maillage extrudé se construit en *reconnaissant* un maillage non structuré comme étant l'extrusion d'un maillage - de dimension ``n-1`` (avec ``n`` la dimension initiale de ``mesh3D``, ici 3). Si cela n'est pas le cas, la construction - plante. Le maillage 2D est forcément en haut ou en bas du 3D volumique, et le dernier entier spécifie la cellule à partir - de laquelle le fil de fer 1D guidant l'extrusion sera construit : :: - - extMesh = mc.MEDCouplingExtrudedMesh(mesh3D, mesh2D, 0) - - On a alors la garantie que, dans ``extMesh``, les cellules sont ordonnées par niveau Z croissant. - Il suffit de récupérer le 2ème niveau (``MEDCouplingExtrudedMesh.getMesh3DIds()``). :: - - n_cells = mesh2D.getNumberOfCells() - cellIdsSol3 = extMesh.getMesh3DIds()[n_cells:2*n_cells] - -On vérifie alors que les 3 solutions sont les mêmes : :: - - print cellIdsSol1.getValues() - print cellIdsSol2.getValues() - print cellIdsSol3.getValues() - - -Extraire une sous partie d'un maillage 3D -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Utiliser les identifiants de cellules ``cellIdsSol2`` obtenus précédemment pour extraire une sous-partie de ``mesh3D``, -c'est-à-dire un maillage avec un sous-ensemble des cellules de ``mesh3D``. :: - - mesh3DPart = mesh3D[cellIdsSol2] - -.. note:: En C++ la méthode sous-jacente invoquée (et par ailleurs aussi disponible en Python) s'appelle - ``mesh3DPart = mesh3D.buildPartOfMySelf(cellIdsSol2,True)`` - -.. note:: Le type géométrique ne rentre pas du tout en compte ici. L'instruction précédente prend les cellules - dans l'ordre où elles sont disponibles dans le maillage initial. - -L'objet ``mesh3DPart`` contient ``len(cellIdsSol2)`` cellules désormais. La cellule #0 de ``mesh3DPart`` correspond à la cellule avec l'identifiant ``cellIdsSol2[0]`` de ``mesh3D``, et ainsi de suite. Ainsi ``cellIdsSol2`` peut être vu comme un -tableau new-2-old. - -A ce point, ``mesh3DPart`` repose sur une copie du tableau de coordonnées de ``mesh3D``, c'est-à-dire 60 nodes. -Seuls 30 sont effectivement utilisés. -Pour retirer les noeuds orphelins de ``mesh3DPart`` invoquer simplement ``MEDCouplingUMesh.zipCoords()``. :: - - mesh3DPart.zipCoords() - -Maintenant, ``mesh3DPart`` repose sur 30 nodes et possède 6 cellules. Pour être prêt aux I/O MED-fichier, il est -alors important de voir si ``mesh3DPart`` est bien ordonné, c'est-à-dire si ses cellules sont bien rangées par type géométrique. -On commence par inspecter l'état actuel : :: - - print mesh3DPart.advancedRepr() - -La fonction suivante fait le même travail : :: - - print mesh3DPart.checkConsecutiveCellTypesAndOrder([mc.NORM_HEXA8, mc.NORM_POLYHED]) - -Ou bien : :: - - print mesh3DPart.checkConsecutiveCellTypes() - -On voit que ``mesh3DPart`` contient 6 cellules, quatre HEXA8 puis deux POLYHED. Les cellules sont bien -groupées par type géométrique. Si ce n'était pas le cas, on aurait pu invoquer ``MEDCouplingUMesh.sortCellsInMEDFileFrmt()``. - - -Extraire des cellules alignées sur une ligne 3D -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -On souhaite extraire de ``mesh3D`` les 3 cellules dont les barycentres sont le long de la ligne portée par -``v = [0.,0.,1.]`` et passant par ``pt = [250.,150.,0.]``. -Il y a deux solutions. - -* les barycentres de ``mesh3D`` : même principe qu'au-dessus. :: - - baryXY = bary[:,[0,1]] - baryXY -= [250.,150.] - magn = baryXY.magnitude() - cellIds2Sol1 = magn.getIdsInRange(0.,1e-12) - -* utiliser le maillage extrudé ``extMesh`` : partant de l'unique cellule dans ``mesh2D`` dont le centre est - en ``[250.,150.,0.]``, la méthdode ``MEDCouplingExtrudedMesh.getMesh3DIds()`` retourne les identifiants de - cellules rangée par rangée. :: - - bary2 = mesh2D.getBarycenterAndOwner()[:,[0,1]] - bary2 -= [250.,150.] - magn = bary2.magnitude() - ids = magn.getIdsInRange(0.,1e-12) - idStart = int(ids) # ids is assumed to contain only one value, if not an exception is thrown - ze_range = range(idStart,mesh3D.getNumberOfCells(),mesh2D.getNumberOfCells()) - cellIds2Sol2 = extMesh.getMesh3DIds()[ze_range] - -Maintenant on construit cette sous partie de ``mesh3D`` en utilisant ``cellIds2Sol1`` ou ``cellIds2Sol2``: :: - - mesh3DSlice2 = mesh3D[cellIds2Sol1] - mesh3DSlice2.zipCoords() - -Duplication, translation et aggrégation de maillages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Cette partie de l'exercice est intéressante pour construire des maillages complexes, ou pour aggréger des parties -de maillages venant de différents processeurs. - -On cherche ici à dupliquer ``mesh3DSlice2``, le translater et l'aggréger avec l'original. - -Effectuer une copie complète de ``mesh3DSlice2`` (aussi appelée *deep copy*) sous le nom ``mesh3DSlice2bis``. -Sur cette copie effectuer une translation de ``v=[0.,1000.,0.]``. -Puis aggréger ``mesh3DSlice2`` avec sa copie translatée ``mesh3DSlice2bis``, en utilisant ``MEDCouplingUMesh.MergeUMeshes()``. :: - - mesh3DSlice2bis = mesh3DSlice2.deepCpy() - mesh3DSlice2bis.translate([0.,1000.,0.]) - mesh3DSlice2All = mc.MEDCouplingUMesh.MergeUMeshes([mesh3DSlice2,mesh3DSlice2bis]) - mesh3DSlice2All.writeVTK("mesh3DSlice2All.vtu") - -.. note:: Pour information pour merger deux (ou plus) maillages non structurés, il faut invoquer ``MEDCouplingUMesh.MergeUMeshes()`` - puis ``MEDCouplingUMesh.mergeNodes()`` sur le résultat, et enfin ``MEDCouplingUMesh.zipConnectivity()``. - -.. _exo-umesh-desc-connec: - -Connectivité descendante -~~~~~~~~~~~~~~~~~~~~~~~~ - -Le but ici est de présenter la notion de *connectivité descendante* (*descending connectivity*). - -La connectivité descendante représente les éléments de dimension ``n-1`` -constituant chacune des cellules de dimension ``n`` (avec donc ``n`` la dimension du maillage, *mesh-dim*). Par exemple, pour un -maillage de dimension 3 (les cellules sont des *volumes* 3D), cela donne l'ensemble des faces (des *surfaces* 2D) bordant -ces volumes. - -A titre d'exemple, on se propose dans notre cas de récupérer les faces *internes* du maillage ``mesh3D``. -Pour cela il est nécessaire de construire le maillage -descendant de ``mesh3D`` (stocké dans ``mesh3DSurf``) c'est-à-dire -le maillage de mesh-dimension 2 (soit ``mesh3D.getMeshDimension()-1``) constitué -des *faces* bordant chacune des cellules (ici des *volumes* 3D) de ``mesh3D``. -La méthode ``MEDCoupling.buildDescendingConnectivity()`` calcule ce maillage, et retourne en même temps des tableaux -de correspondance. Ces tableaux font le lien entre les identifiants des cellules de ``mesh3D`` -vers les identifiants de cellules de ``mesh3DSurf``, et vice-et-versa. - -Une face de ``mesh3DSurf`` est dite interne, si et seulement si, elle est partagée par plus d'une cellule 3D de ``mesh3D``. -Les 3ème et 4ème paramètres de sortie de la fonction donnent le lien -entre une face et ses cellules *parentes* (i.e. le ou les volumes qu'elle délimite). -Ce lien est exprimé au format *indirect index* vu dans le premier exercice :ref:`indirect-index-exo`. :: - - mesh3DSurf, desc, descIndx, revDesc, revDescIndx = mesh3D.buildDescendingConnectivity() - numberOf3DCellSharing = revDescIndx.deltaShiftIndex() - cellIds = numberOf3DCellSharing.getIdsNotEqual(1) - mesh3DSurfInside = mesh3DSurf[cellIds] - mesh3DSurfInside.writeVTK("mesh3DSurfInside.vtu") - -Ce genre de manipulation est très utile pour accéder au voisinage d'une ou plusieurs cellules d'un maillage non-structuré. - -.. image:: images/mesh3DSurfInside.jpg - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingumesh1_solution` diff --git a/medtool/doc/tutorial/medcouplingcorba_en.rst b/medtool/doc/tutorial/medcouplingcorba_en.rst deleted file mode 100644 index 4e3e7472d..000000000 --- a/medtool/doc/tutorial/medcouplingcorba_en.rst +++ /dev/null @@ -1,94 +0,0 @@ - -Visualize a MEDCoupling instance in ParaViS through CORBA ---------------------------------------------------------- - -ParaViS can be used to directly visualize a mesh or a field stored in memory in a Python -process. For information, this technique will become the preferred choice for the MED -Calculator in a future Salome release. -The following use cases can also be mentioned: - -* YACS, to create visualization nodes -* create a Python mock-up script and use the standard Python interpreter whilst benefiting - from the ParaViS graphical interface - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -Import the whole Python module MEDCouplingCorba. :: - - from MEDCouplingCorba import * - - -Create a 2D MEDCouplingUMesh instance -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Create a trivial unstructured mesh "m" which will be sent through CORBA to ParaViS. -:: - - arr=DataArrayDouble(11) - arr.iota(0) - m=MEDCouplingCMesh() - m.setCoords(arr,arr) - m=m.buildUnstructured() - -.. note:: "m" is unstructured but a Cartesian mesh would also work perfectly fine. - -Create a CORBA servant from "m", and turn the Python process into a CORBA server -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Invoke MEDCouplingUMeshServant._this() on "m" to turn it into a CORBA reference ("ref_m"). -:: - - ref_m=MEDCouplingUMeshServant._this(m) - -.. note:: This command doesn't only create a CORBA servant but also makes the current - Python process a full CORBA server. - -Read the identifiers that are passed to ParaViS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -What follows holds for any omniORBpy code. Display the IOR "ior" of "ref_m". -This character string is given to the ParaViS plugin (ParaMEDCorbaPlugin) to create -a new ParaViS source. -:: - - import CORBA - orb=CORBA.ORB_init() - ior=orb.object_to_string(ref_m) - print ior - -A simple copy/paste in the ParaViS GUI allows to create the source and to have our -mesh rendered on screen. - -Use ParaViS interactively -~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section simply highlights what can be done in principle. It should be regarded -as a starting point towards the creation of more advanced scripts. -With ParaViS still up, retrieve a remote handle on ParaViS: -:: - - import PARAVIS_Gen_idl - import salome - salome.salome_init() - paravis=salome.lcc.FindOrLoadComponent("FactoryServer","PARAVIS") - -Then send a script to ParaViS so that it displays "m": -:: - - script=""" - src1 = ParaMEDCorbaPluginSource() - src1.IORCorba = '%s' - asc=GetAnimationScene() - rw=GetRenderView() - dr=Show()\ndr.Visibility = 1 - Render() - """ - content=script%(ior) - paravis.ExecuteScript(content) - - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingcorba1_solution` diff --git a/medtool/doc/tutorial/medcouplingcorba_fr.rst b/medtool/doc/tutorial/medcouplingcorba_fr.rst deleted file mode 100644 index 394ff44d5..000000000 --- a/medtool/doc/tutorial/medcouplingcorba_fr.rst +++ /dev/null @@ -1,100 +0,0 @@ - -Visualiser une instance de MEDCoupling dans ParaViS à travers CORBA -------------------------------------------------------------------- - -Il peut être intéressant de visualiser directement un maillage ou un champ en mémoire dans -un process Python avec une session de ParaViS. Cela évite d'avoir à écrire le maillage (ou le champ) sur disque. -Cette technique peut également être utilisée pour : - -* faire des noeuds de visualisation dans le module YACS -* maquetter un script Python, et profiter de l'interpreteur interactif Python tout en - bénéficiant de l'interface graphique de ParaViS. - -Nous allons pour ce faire bénéficier des mécanismes de distribution mis en oeuvre dans SALOME sur -la base du standard `CORBA `_. -SALOME utilise l'implémentation `omniORB `_ et -`omniORBPy `_ du standard. - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer le module ``MEDCoupling`` -et la classe ``MEDCouplingUMeshServant`` du module Python ``MEDCouplingCorba``. :: - - import MEDCoupling as mc - from MEDCouplingCorba import MEDCouplingUMeshServant - -Créer un maillage -~~~~~~~~~~~~~~~~~ - -Le but ici est de créer un maillage ``m`` non structuré trivial qui sera envoyé par CORBA à ParaViS. :: - - arr = mc.DataArrayDouble(11) - arr.iota(0) - m = mc.MEDCouplingCMesh() - m.setCoords(arr,arr) - m = m.buildUnstructured() - -.. note:: Le maillage ``m`` est non struturé, mais s'il est cartésien ça marche aussi ! - -Créer un servant CORBA -~~~~~~~~~~~~~~~~~~~~~~ - -Nous allons maintenant créer un *servant* CORBA à partir de ``m``, et faire du process Python courant -un *serveur* CORBA. L'objet ``m`` devient ainsi disponible sur le bus CORBA et pourra être interrogé pour -la visualisation par un service distant, typiquement dans notre cas, le module ParaVis. - -Invoquer ``MEDCouplingUMeshServant._this()`` sur ``m`` pour en faire une reférence CORBA (``ref_m``).:: - - ref_m = MEDCouplingUMeshServant._this(m) - -.. note:: Cette ligne ne se contente pas de faire un servant CORBA mais fait du processus courant Python un serveur CORBA. - -Récupérer les identifiants pour ParaViS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Ce qui suit est général à tout code omniORBpy. Afficher l'IOR ``ior`` de ``ref_m`` (c'est à dire l'identifiant -unique de l'objet sur le bus CORBA) pour pouvoir passer cette chaîne de caractères au plugin ParaMEDCorbaPlugin -de ParaViS, et ainsi créer une nouvelle source dans ParaViS. :: - - import CORBA - orb = CORBA.ORB_init() - ior = orb.object_to_string(ref_m) - print ior - -Puis, via un copier/coller dans l'IHM ParaViS (Menu "Source -> Para MED Corba Plugin Source"), passer l'IOR. -On voit s'afficher notre maillage. - -Utiliser ParaViS en interactif -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Le but ici est juste de voir le principe. Il s'agit d'un point d'entrée pour réaliser des scripts ParaViS plus évolués. -*Tout en laissant actif ParaViS*, importer le module ``pvsimple`` qui fournit l'interface haut niveau de visualisation : :: - - import salome - salome.salome_init() - import pvsimple as pvs - -.. note:: Le module ``pvsimple`` est, à peu de choses prêt, identique au module ``paraview.simple``. - Il est juste adapté à une utilisation au sein de SALOME. Voir la formation PARAVIS à ce sujet. - -Une fois cet import réalisé, le script est automatiquement connecté au même serveur de visualisation que -l'interface graphique de SALOME (si le module PARAVIS est bien actif !). Nous pouvons donc envoyer des commandes -au serveur de visualisation pour demander l'affichage de notre objet CORBA. :: - - # We now talk to the PVServer directly - import pvsimple as pvs - pvs.Connect(url) - src1 = pvs.ParaMEDCorbaPluginSource() - src1.IORCorba = ior # This is where we need the CORBA reference of the object created - dr = pvs.Show(src1) - -.. note:: Cela correspond exactement à la manipulation précédente faite via l'interface graphique (ajout d'une nouvelle - source, saisie de l'IOR, etc ...). - -Solution -~~~~~~~~ - -Le script complet doit être exécuté avec le module PARAVIS (ou une fenêtre ParaView) actif dans l'IHM SALOME! - -:ref:`python_testMEDCouplingcorba1_solution` diff --git a/medtool/doc/tutorial/medcouplingloaderex1_en.rst b/medtool/doc/tutorial/medcouplingloaderex1_en.rst deleted file mode 100644 index 23c825193..000000000 --- a/medtool/doc/tutorial/medcouplingloaderex1_en.rst +++ /dev/null @@ -1,162 +0,0 @@ - - -Full example 1 - Agitator -------------------------- - -The MED file :download:`agitateur.med ` is used and has the following content:ant : - -.. image:: images/agitateur.jpg - -This is the result of a simple 2-phase computation. -The agitator in green (represented by a cell field) turn on itself from one time-step -to the other. -The purpose of the exercise is to compute the torque applied on this piece.agitateur. - -Objective -~~~~~~~~~ - -The aim of this exercise is to give a full example of non-trivial post-treatment -from a MED file. - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -Import the whole Python module MEDLoader (which includes MEDCoupling). -Also import NumPy and acos() from the math module. :: - - from MEDLoader import * - from numpy import * - from math import acos - -Mesh and field extraction using advanced API -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Using the advanced API read the whole file "agitateur.med" and display all time-steps of -the first field. :: - - data=MEDFileData("agitateur.med") - ts=data.getFields()[0].getTimeSteps() - print ts - -Get the agitator's mesh (in green) at the time-step (2,-1) (see ts). -To this end use the cell field "DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM" and select -only the field part having a value within [0.0, 1.0] (variable "ids"). :: - - fMts=data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"] - f1ts=fMts[(2,-1)] - fMc=f1ts.getFieldAtLevel(ON_CELLS,0) - arr=fMc.getArray() - arr.getMinMaxPerComponent() # just to see the variation range of the field per component - ids=arr.getIdsInRange(0.,1.) - f2Mc=fMc[ids] - -Using the field "PRESSION_ELEM_DOM" find the 3D pression field applied on the agitator. -Store the result in pressOnAgitateur. :: - - pressMts=data.getFields()["PRESSION_ELEM_DOM"] - press1ts=pressMts[(2,-1)] - pressMc=press1ts.getFieldAtLevel(ON_CELLS,0) - pressOnAgitateurMc=pressMc[ids] - -Delete unused nodes in pressOnAgitateurMc.getMesh(). :: - - pressOnAgitateurMc.getMesh().zipCoords() - -Create a 3D surface field from the 3D cell field -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Deduce the 3D field on the skin of the agitator. -To achieve this use the constituting mesh MEDCouplingUMesh.buildDescendingConnectivity(). -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - - agitateurMesh3DMc=pressOnAgitateurMc.getMesh() - m3DSurf,desc,descI,revDesc,revDescI=agitateurMesh3DMc.buildDescendingConnectivity() - nbOf3DCellSharing=revDescI.deltaShiftIndex() - ids2=nbOf3DCellSharing.getIdsEqual(1) - agitateurSkinMc=m3DSurf[ids2] - OffsetsOfTupleIdsInField=revDescI[ids2] - tupleIdsInField=revDesc[OffsetsOfTupleIdsInField] - pressOnSkinAgitateurMc=pressOnAgitateurMc[tupleIdsInField] - pressOnSkinAgitateurMc.setMesh(agitateurSkinMc) - -Manipulate fields -~~~~~~~~~~~~~~~~~ - -Compute the force vector field on the agitator's skin by multiplying at each cell -the pressure by the surface, and then the normal vector. -Pression is expressed in bar, convert it first to Pa. :: - - pressSkin=pressOnSkinAgitateurMc.getArray() - pressSkin*=1e5 - areaSkin=agitateurSkinMc.getMeasureField(True).getArray() - forceSkin=pressSkin*areaSkin - normalSkin=agitateurSkinMc.buildOrthogonalField().getArray() - forceVectSkin=forceSkin*normalSkin - -First computation of the torque at the center of mass of the agitator: - -Let's compute first the position of the center of mass. -Compute the polyhedron representing the 3D mesh hull of the agitator "agitateurMesh3DMc" -(use MEDCouplingUMesh.buildSpreadZonesWithPoly()). :: - - singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() - singlePolyhedron.orientCorrectlyPolyhedrons() - centerOfMass=singlePolyhedron.getBarycenterAndOwner() - -.. note:: The call to MEDCouplingUMesh.orientCorrectlyPolyhedrons() is not mandatory - but is recommended: if the polyhedron happens to be mis-oriented, its center of mass will - be incorrect! - -Compute for each skin cell the torque with respect to the center of mass "centerOfMass". -To this end compute "posSkin", a DataArrayDouble giving for each skin cell the vector -centerOfMass -> G, where G represents the center of mass of the current cell. :: - - barySkin=agitateurSkinMc.getBarycenterAndOwner() - posSkin=barySkin-centerOfMass - -Compute the cross product for each cell of "posSkin" using "forceVectSkin" -(method DataArrayDouble.CrossProduct()). :: - - torquePerCellOnSkin=DataArrayDouble.CrossProduct(posSkin,forceVectSkin) - -Sum "torqueOnSkin" using DataArrayDouble.accumulate(). :: - - zeTorque=torquePerCellOnSkin.accumulate() - print "couple = %r N.m"%(zeTorque[2]) - -Check the previously computed torque by dividing the power by the angular speed. -Compute the power per skin cell and sum it. :: - - speedMts=data.getFields()["VITESSE_ELEM_DOM"] - speed1ts=speedMts[(2,-1)] - speedMc=speed1ts.getFieldAtLevel(ON_CELLS,0) - speedOnSkin=speedMc.getArray()[tupleIdsInField] - powerSkin=DataArrayDouble.Dot(forceVectSkin,speedOnSkin) - power=powerSkin.accumulate()[0] - print "power = %r W"%(power) - -Compute the angular speed: compute the sum of x^2, y^2 and xz of "posSkin" and build -with NumPy the 2x2 matrix -inertiaSkin=[[x2,xy], [xy,z2]] -Retrieve the eigen vector associated to the maximal eigen value with linalg.eig(inertiaSkin). :: - - x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] - y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] - xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] - inertiaSkin=matrix([[x2,xy],[xy,y2]]) - inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) - pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] - vect0=inertiaSkinVects[pos].tolist()[0] - print vect0 - -Thanks to the previous computation we can see that the agitator had a rotation of -1.1183827931 radian (see solution). -Compute and compare the torque on the agitator. :: - - omega=1.1183827931/(ts[-1][2]-ts[0][2]) - print "At time-step (%d,%d) at %r s the torque is: %r N.m, power/omega=%r N.m"%(ts[2][0],ts[2][1],ts[2][2],zeTorque[2],power/omega) - -Solution -~~~~~~~~ - -:ref:`python_testmedcouplingloaderex1_solution` diff --git a/medtool/doc/tutorial/medcouplingloaderex1_fr.rst b/medtool/doc/tutorial/medcouplingloaderex1_fr.rst deleted file mode 100644 index 9f13cc24a..000000000 --- a/medtool/doc/tutorial/medcouplingloaderex1_fr.rst +++ /dev/null @@ -1,168 +0,0 @@ - -MEDCoupling / MEDLoader - Exemple complet 1 - Agitateur -------------------------------------------------------- - -Nous partons ici d'un fichier :download:`agitateur.med ` ayant le contenu suivant : - -.. image:: images/agitateur.jpg - -Il s'agit du résultat d'un petit calcul diphasique : l'agitateur magnétique en vert (repéré seulement par un champ -aux cellules, et n'ayant *pas* de maillage propre) tourne d'un pas de temps à l'autre au -sein d'une phase liquide. Deux gouttes de liquide chutent pendant ce temps vers l'interface air/eau (en gris). - -Le but de l'exercice est de calculer le couple appliqué sur cet agitateur, qui est la pièce mécanique entraînant la -partie basse du fluide. - -Objectif -~~~~~~~~ - -L'objectif est de donner un exemple complet de post-traitement non trivial à partir d'un fichier MED. - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer tout le module python ``MEDLoader`` (qui inclut ``MEDCoupling``). -Importer aussi ``numpy``. :: - - import MEDLoader as ml - import numpy as np - -Extraction des maillages et champs avec l'API avancée -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Avec l'API avancée lire tout le fichier "agitateur.med" et afficher tous les pas de temps du 1er champ. :: - - data = ml.MEDFileData("agitateur.med") - ts = data.getFields()[0].getTimeSteps() - print ts - -Récupérer le maillage de l'agitateur (en vert) au pas de temps (2,-1) (cf. ts). -La position de l'agitateur est définie par un champ sur le maillage global du système et n'a pas de maillage propre. -Il faut donc utiliser le champ aux cellules "DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM" -et ne sélectionner que la partie du champ ayant une valeur entre dans ``[0.,1.]``. Mettre les identifiants -de cellules correspondant dans ``ids`` : :: - - fMts = data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"] - f1ts = fMts[(2,-1)] - fMc = f1ts.getFieldAtLevel(ml.ON_CELLS,0) - arr = fMc.getArray() - arr.getMinMaxPerComponent() # just to see the field variation range per component - ids = arr.getIdsInRange(0.,1.) - f2Mc = fMc[ids] - -A l'aide du champ "PRESSION_ELEM_DOM" trouver le champ de pression 3D qu'applique l'agitateur. Mettre le résultat dans -``pressOnAgitateur``. :: - - pressMts = data.getFields()["PRESSION_ELEM_DOM"] - press1ts = pressMts[(2,-1)] - pressMc = press1ts.getFieldAtLevel(ml.ON_CELLS,0) - pressOnAgitateurMc = pressMc[ids] - -Supprimer les noeuds inutiles de ``pressOnAgitateurMc.getMesh()`` : :: - - pressOnAgitateurMc.getMesh().zipCoords() - -Passer d'un champ aux cellules 3D à un champ surfacique 3D -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Deduire le champ 3D de pression sur la *peau* de l'agitateur. -Pour ce faire passer par le maillage descendant ``MEDCouplingUMesh.buildDescendingConnectivity()``. :: - - agitateurMesh3DMc = pressOnAgitateurMc.getMesh() - m3DSurf,desc,descI,revDesc,revDescI = agitateurMesh3DMc.buildDescendingConnectivity() - nbOf3DCellSharing = revDescI.deltaShiftIndex() - ids2 = nbOf3DCellSharing.getIdsEqual(1) # Cells with only one neighbor are on the boundary, i.e. on the skin - agitateurSkinMc = m3DSurf[ids2] - offsetsOfTupleIdsInField = revDescI[ids2] - tupleIdsInField = revDesc[offsetsOfTupleIdsInField] - pressOnSkinAgitateurMc = pressOnAgitateurMc[tupleIdsInField] - pressOnSkinAgitateurMc.setMesh(agitateurSkinMc) - -Manipuler les champs -~~~~~~~~~~~~~~~~~~~~ - -Calculer le champ vectoriel de force sur la peau de l'agitateur en multipliant pour chaque cellule -la pression par la surface et ensuite par le vecteur normal. -La pression est en bar, la convertir au préalable en pascal (Pa). :: - - pressSkin = pressOnSkinAgitateurMc.getArray() - pressSkin *= 1e5 # conversion from bar to Pa - areaSkin = agitateurSkinMc.getMeasureField(True).getArray() - forceSkin = pressSkin*areaSkin - normalSkin = agitateurSkinMc.buildOrthogonalField().getArray() - forceVectSkin = forceSkin*normalSkin - -Voici maintenant le premier calcul du moment au centre de masse de l'agitateur : - -Pour faire ce 1er calcul de couple exercé sur l'agitateur, calculons la position du centre de masse de l'agitateur. -Calculer le polyèdre représentant l'enveloppe du maillage 3D de l'agitateur ``agitateurMesh3DMc`` -(utiliser ``MEDCouplingUMesh.buildSpreadZonesWithPoly()``). :: - - singlePolyhedron = agitateurMesh3DMc.buildSpreadZonesWithPoly() - singlePolyhedron.orientCorrectlyPolyhedrons() - centerOfMass = singlePolyhedron.getBarycenterAndOwner() - -.. note:: L'appel à ``MEDCouplingUMesh.orientCorrectlyPolyhedrons()`` n'est pas obligatoire mais conseillé car - si par malheur le polyhèdre est mal orienté, son barycentre sera incorrect ! - -Calculer pour chaque cellule de la peau de l'agitateur le moment par rapport au centre de masse ``centerOfMass`` -de l'agitateur. -Pour ce faire calculer ``posSkin`` le ``DataArrayDouble`` donnant pour chaque cellule de la peau de l'agitateur -le vecteur ``centerOfMass`` -> ``G``, avec ``G`` le barycentre de la cellule courante. :: - - barySkin=agitateurSkinMc.getBarycenterAndOwner() - posSkin = barySkin-centerOfMass - -Appliquer maintenant la formule classique de calcul du moment : calculer le produit -vectoriel par cellule de ``posSkin`` avec ``forceVectSkin`` (méthode ``DataArrayDouble.CrossProduct()``). :: - - torquePerCellOnSkin = ml.DataArrayDouble.CrossProduct(posSkin,forceVectSkin) - -Sommer ``torqueOnSkin`` en utilisant la méthode ``DataArrayDouble.accumulate()``. :: - - zeTorque = torquePerCellOnSkin.accumulate() - print "couple = %r N.m" % zeTorque[2] - -Vérifions le couple calculé précédemment en divisant la puissance par la vitesse *angulaire*. -La vitesse *linéaire* est stockée dans le champ "VITESSE_ELEM_DOM". - -Calculer la puissance par cellule de la peau de l'agitateur et la sommer. :: - - speedMts = data.getFields()["VITESSE_ELEM_DOM"] - speed1ts = speedMts[(2,-1)] - speedMc = speed1ts.getFieldAtLevel(ml.ON_CELLS,0) - speedOnSkin = speedMc.getArray()[tupleIdsInField] - powerSkin = ml.DataArrayDouble.Dot(forceVectSkin,speedOnSkin) - power = powerSkin.accumulate()[0] - print "power = %r W"%(power) - -Calculer la vitesse *angulaire*. Pour ce faire, calculer la somme de ``x^2``, ``y^2`` et ``xz`` de ``posSkin`` et -construire (avec NumPy) la matrice 2x2 d'inertie ``inertiaSkin=[[x2,xy], [xy,z2]]``. - -Récupérer le vecteur propre associé à la valeur propre maximale -avec ``linalg.eig(inertiaSkin)``. :: - - x2 = posSkin[:,0]*posSkin[:,0] - x2 = x2.accumulate()[0] - y2 = posSkin[:,1]*posSkin[:,1] - y2 = y2.accumulate()[0] - xy = posSkin[:,0]*posSkin[:,1] - xy = xy.accumulate()[0] - inertiaSkin = np.matrix([[x2,xy],[xy,y2]]) - inertiaSkinValues, inertiaSkinVects = np.linalg.eig(inertiaSkin) - pos = max(enumerate(inertiaSkinValues), key=lambda x: x[1])[0] - vect0 = inertiaSkinVects[pos].tolist()[0] - print vect0 - -Grâce au calcul précédent on peut déduire que l'agitateur a tourné de 1.1183827931 radian (cf. solution complète pour le -détail - on remet les étapes précédentes dans une fonction que l'on applique sur plusieurs pas de temps). - -Calculer et comparer le couple sur l'agitateur. :: - - omega = 1.1183827931 / (ts[-1][2]-ts[0][2]) - print "At timestep (%d,%d) (physical time=%r s) the torque is: %r N.m, power/omega=%r N.m " % (ts[2][0],ts[2][1],ts[2][2],zeTorque[2],power/omega) - -Solution -~~~~~~~~ - -:ref:`python_testmedcouplingloaderex1_solution` diff --git a/medtool/doc/tutorial/medcouplingloaderex2_en.rst b/medtool/doc/tutorial/medcouplingloaderex2_en.rst deleted file mode 100644 index cfb29bf12..000000000 --- a/medtool/doc/tutorial/medcouplingloaderex2_en.rst +++ /dev/null @@ -1,240 +0,0 @@ - -Full example 2 - RJH --------------------- - -Two MED files are used in this case, which are (very freely) inspired by the RJH experimental reactor. - -The first file "Fixe.med" represents the 2D geometry of the static RJH without the installations. - -.. image:: images/fixm.jpg - -The 2nd file "Mobile.med" represent the mobile part. - -.. image:: images/mobm.jpg - - -Objective -~~~~~~~~~ - -The aim of this exercise is to use MEDCoupling to intersect those two meshes, assign a field to it and thus localize the zones. - - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -Import the whole Python module MEDLoader (which includes MEDCoupling). :: - - from MEDLoader import * - -Read and repare the static mesh "Fixe.med" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -With the advanced API read the whole file "Fixe.med" and call "fixm" the MEDCouplingUMEsh instance -representing the static mesh. :: - - fixe=MEDFileMesh.New("Fixe.med") - fixm=fixe.getMeshAtLevel(0) - -In what follows, it is required that any two cells touching each other share the same edges. -As we are in nodal connectivity mode it means that common nodes have to merged. This is not the case here. -Merge the nodes closer than 1e-10 and assess the impact on the node count of "fixm". :: - - print "nb of nodes in file : %i"%(fixm.getNumberOfNodes()) - fixm.mergeNodes(1e-10) - print "nb of non duplicated nodes : %i"%(fixm.getNumberOfNodes()) - -Same thing for "Mobile.med" (called "mobm"). Repair it by deleting duplicated nodes. :: - - mobile=MEDFileMesh.New("Mobile.med") - mobm=mobile.getMeshAtLevel(0) - mobm.mergeNodes(1e-10) - - -Repair the "mobm" mesh converting from POLYGON to QPOLYG (temporary solution) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section will disappear in the future. -The RJH mesh being more generic than TRI6 and QUAD8 we need to store cells with an intermediate type QPOLYG -(Quadratic Polygon) which is the polygonal extension to the 2D cells with a dynamic edge count. -For now this geometrical type QPOLYG is in MEDCoupling but there is no equivalent yet in MED file (work in progress -at EDF). -The trick for now is to store QPOLYG in standard linear polygons and to convert them after reading. -Only "mobm" is concerned. Convert all polygonal cells in "mobm" into QPOLYG. :: - - ids=mobm.giveCellsWithType(NORM_POLYGON) - mobm.getNodalConnectivity()[mobm.getNodalConnectivityIndex()[ids]]=NORM_QPOLYG - mobm.computeTypes() - -Visualize "fixm" and "mobm" using ParaView. Tesselation is needed: OpenGL doesn't handle properly circle arcs -and those have to be split into smaller linear segments to be able to represent them. The method MEDCouplingUMesh.tessellate2D() achieves this but modifies the mesh (non const method in C++). -It only take a cut fineness parameter (0.1 will suffice (angle expressed in rd)). Remember not to modify -neither "fixm" nor "mobm"! :: - - fixm2=fixm.deepCpy() # tessellate2D is non const - a mesh copy is required - fixm2.tessellate2D(0.1) - fixm2.writeVTK("fixm2.vtu") - mobm2=mobm.deepCpy() - mobm2.tessellate2D(0.1) - mobm2.writeVTK("mobm2.vtu") - -Define a small method displayVTK() which we will use later on. :: - - def displayVTK(m,fname): - tmp=m.deepCpy() - tmp.tessellate2D(0.1) - tmp.writeVTK(fname) - return - -Perform reductions and identifying zones -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -"mobm" is made of 6 distinct parts (see image above). We only want the first part. -Use MEDCouplingUMesh.partitionBySpreadZone() to partition "mobm" in zones and only -extract the first zone. -Name this new instance "zone1Mobm", remove all orphan nodes and display. :: - - zonesInMobm=mobm.partitionBySpreadZone() - print "number of zones in mobm : %i"%(len(zonesInMobm)) - zone1Mobm=mobm[zonesInMobm[0]] - zone1Mobm.zipCoords() - displayVTK(zone1Mobm,"zone1Mobm.vtu") - -.. image:: images/zone1Mobm.jpg - -From now on we work on "zone1Mobm". We will reduce the working area of "fixm" around "zone1Mobm". -To achive this: reduce "fixm" taking only "fixm" cells located in the bounding box of "zone1Mobm" (MEDCouplingUMesh.getBoundingBox() and MEDCouplingUMesh.getCellsInBoundingBox()). -Name this object "partFixm", remove its orphan nodes and display it. :: - - ids2=fixm.getCellsInBoundingBox(zone1Mobm.getBoundingBox(),1e-10) - partFixm=fixm[ids2] - partFixm.zipCoords() - displayVTK(partFixm,"partFixm.vtu") - -.. image:: images/partFixmAndzone1Mobm.jpg - -Geometrical intersection of the two meshes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This is the core of the exercise. - -We intersect geometrically "partFixm" and "zone1Mobm". -This boils down to partition in a minimal fashion "partFixm" into cells belonging either fully to -"partFixm", or to "partFixm" and "zone1Mobm". Invoke the static method -MEDCouplingUMesh.Intersect2DMeshes(), with "partFixm" and "zone1Mobm", and use a precision -of 1e-10 (merge detection threshold). -This method returns 3 parameters (see API documentation) which will be called partFixMob, iPart and iMob. - -In partFixMob merge common nodes with a threshold of 1e-10. :: - - partFixMob,iPart,iMob=MEDCouplingUMesh.Intersect2DMeshes(partFixm,zone1Mobm,1e-10) - partFixMob.mergeNodes(1e-10) - -Get and display partFixm part which is not in zone1Mobm. Call this mesh partFixmWithoutZone1Mobm. :: - - ids3=iMob.getIdsEqual(-1) - partFixmWithoutZone1Mobm=partFixMob[ids3] - displayVTK(partFixmWithoutZone1Mobm,"partFixmWithoutZone1Mobm.vtu") - -.. image:: images/partFixmWithoutZone1Mobm.jpg - - -Let's now check the result quality given by MEDCouplingUMesh.Intersect2DMeshes. -Three tests will be passed: - - * (check#0) the cell area sum in partFixm equals the one in partFixMob - * (check#1) the cell area sum in zone1Mobm equals the same sum on the cells in partFixMob whose cell ID different of -1 - * (check#2) for each cell in partFixm, its area equals the cell area sum in partFixMob - -Area is a algebraic value. The check can be performed only if all cells are correctly oriented or at least -all oriented consistently. -To check this let's inspect the areas of the 38 cells of partFixm (variable name "areaPartFixm"). :: - - areaPartFixm=partFixm.getMeasureField(ON_CELLS).getArray() - print areaPartFixm.getValues() - -All values are negative: this MED file doesn't respect the MED file convention. -"partFixm" being mis-oriented and the method MEDCouplingUMesh.Intersect2DMeshes() conserving the orientation, "partFixMob" is also mis-oriented. -To cut long story short, we perform comparison on absolute arrays. -Check then that the first test check#0 is successful - - areaPartFixm=partFixm.getMeasureField(ON_CELLS).getArray() - areaPartFixm.abs() - areaPartFixMob=partFixMob.getMeasureField(ON_CELLS).getArray() - areaPartFixMob.abs() - val1=areaPartFixm.accumulate()[0] - val2=areaPartFixMob.accumulate()[0] - print "Check #0 %lf == %lf a 1e-8 ? %s"%(val1,val2,str(abs(val1-val2)<1e-8)) - -Now check#1. Same spirit as in check#0. :: - - areaZone1Mobm=zone1Mobm.getMeasureField(ON_CELLS).getArray() - areaZone1Mobm.abs() - val3=areaZone1Mobm.accumulate()[0] - ids4=iMob.getIdsNotEqual(-1) - areaPartFixMob2=areaPartFixMob[ids4] - val4=areaPartFixMob2.accumulate()[0] - print "Check #1 %lf == %lf a 1e-8 ? %s"%(val3,val4,str(abs(val3-val4)<1e-8)) - -Finally check#2. :: - - isCheck2OK=True - for icell in xrange(partFixm.getNumberOfCells()): - ids5=iPart.getIdsEqual(icell) - areaOfCells=areaPartFixMob[ids5] - areaOfCells.abs() - if abs(areaOfCells.accumulate()[0]-areaPartFixm[icell])>1e-9: - isCheck2OK=False - pass - pass - print "Check #2? %s"%(str(isCheck2OK)) - -Use intersection information to create fields -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We are done with partFixMob. -Now create a cell field on partFixMob by setting it to 0 on the part covering only partFixm and 1 on the overlapped -part. Visualize it in a VTK file. :: - - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - m=partFixMob.deepCpy() ; m.tessellate2D(0.1) - f.setMesh(m) - arr=DataArrayDouble(partFixMob.getNumberOfCells(),1) - arr[iMob.getIdsEqual(-1)]=0. - arr[iMob.getIdsNotEqual(-1)]=1. - f.setArray(arr) - f.checkCoherency() - f.setName("Zone") - MEDCouplingFieldDouble.WriteVTK("Zone.vtu",[f]) - -.. image:: images/LocationEx2.jpg - -More generally take zones 0, 1 and 5. -Create a cell field whose value is 0 in the zone being exclusively part of fixm, -1 in the zone #0, 2 in the zone #1 and 3 in the zone #5. :: - - zonesMobm=MEDCouplingUMesh.MergeUMeshesOnSameCoords([mobm[zonesInMobm[0]], mobm[zonesInMobm[1]], mobm[zonesInMobm[5]]]) - zonesMobm.zipCoords() - partFixMob2,iPart2,iMob2=MEDCouplingUMesh.Intersect2DMeshes(partFixm,zonesMobm,1e-10) - partFixMob2.mergeNodes(1e-10) - f2=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - m2=partFixMob2.deepCpy() ; m2.tessellate2D(0.1) - f2.setMesh(m2) - arr=DataArrayDouble(partFixMob2.getNumberOfCells(),1) - arr[iMob2.getIdsEqual(-1)]=0. - st=0 ; end=st+len(zonesInMobm[0]) - arr[iMob2.getIdsInRange(st,end)]=1. - st+=len(zonesInMobm[0]) ; end=st+len(zonesInMobm[1]) - arr[iMob2.getIdsInRange(st,end)]=2. - st+=len(zonesInMobm[1]) ; end=st+len(zonesInMobm[2]) - arr[iMob2.getIdsInRange(st,end)]=3. - f2.setArray(arr) - f2.checkCoherency() - f2.setName("Zone2") - MEDCouplingFieldDouble.WriteVTK("Zone2.vtu",[f2]) - -.. image:: images/zonesMobm.jpg - -Solution -~~~~~~~~ - -:ref:`python_testmedcouplingloaderex2_solution` diff --git a/medtool/doc/tutorial/medcouplingloaderex2_fr.rst b/medtool/doc/tutorial/medcouplingloaderex2_fr.rst deleted file mode 100644 index 9c24d45ed..000000000 --- a/medtool/doc/tutorial/medcouplingloaderex2_fr.rst +++ /dev/null @@ -1,253 +0,0 @@ - -MEDCoupling / MEDLoader - Exemple complet 2 - RJH -------------------------------------------------- - -Ici nous partons de deux fichiers MED très librement inspirés du réacteur expérimental -RJH (Réacteur Jules Horowitz). - -Le premier, :download:`Fixe.med `, représente la partie statique du réacteur -sans dispositif expérimental. - -.. image:: images/fixm.jpg - :scale: 70 - -Le deuxième, :download:`Mobile.med `, représente la partie mobile. - -.. image:: images/mobm.jpg - :scale: 70 - - -Objectif -~~~~~~~~ - -Le but ici est d'utiliser MEDCoupling pour: - -* intersecter ces deux maillages, -* y mettre un champ, -* et ainsi localiser les zones de recouvrement - - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer tout le module python MEDLoader (qui inclus MEDCoupling). :: - - import MEDLoader as ml - -Lire et réparer le maillage statique "Fixe.med" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Avec l'API avancée lire tout le fichier "Fixe.med" et appeler ``fixm`` -l'objet de type ``MEDCouplingUMesh`` représentant le maillage statique. :: - - fixe = ml.MEDFileMesh.New("Fixe.med") - fixm = fixe.getMeshAtLevel(0) - -Pour ce qui suit il faut absolument que deux cellules se touchant partagent les mêmes edges. Pour ce faire, comme on est -en connectivité nodale, il faut absolument que les noeuds soient les mêmes. Il s'avère que cela n'est pas le cas ici. -Fusionner le noeuds distants de moins de 1e-10 et regarder l'impact sur le nombre de noeuds de ``fixm``. :: - - print "Nb of nodes in the file : %i " % (fixm.getNumberOfNodes()) - fixm.mergeNodes(1e-10) - print "Nb of non duplicated nodes : %i" % (fixm.getNumberOfNodes()) - -Même traitement pour ``Mobile.med``, le lire avec l'API avancée de MEDLoader (appeler ``mobm`` l'instance du maillage) -et le réparer en supprimant les noeuds dupliqués. :: - - mobile = ml.MEDFileMesh.New("Mobile.med") - mobm = mobile.getMeshAtLevel(0) - mobm.mergeNodes(1e-10) - -Le maillage du RJH étant plus général que des ``TRI6`` et des ``QUAD8``, on a besoin -de stocker ces cellules avec un type géométrique à ``QPOLYG`` (Quadratic Polygon) qui représente un polygone *quadratique* -(le terme n'est pas très heureux, encore des raisons historiques, ...), c'est-à-dire un polygone avec un nombre arbitraire -de côtés, et potentiellement des côtés en forme d'arcs de cercles plutôt que de segments de droites. -Ce type géométrique ``NORM_QPOLYG`` est dans MEDCoupling/MEDLoader et aussi dans MED fichier. - -Nous voudrions visualiser ces deux maillages dans PARAVIS/ParaView, mais nous rencontrons ici deux soucis: - -* les polygones non-convexes sont, par défaut, mal représentés par VTK en mode *Surface*. - Il faut sélectionner l'option avancée "Triangulate" dans le panneau Display de PARAVIS/ParaView pour avoir un rendu correct. -* les arcs de cercles ne sont pas correctement supportés par ParaView. Il faut les *tesséliser*, c'est-à-dire les transformer - en plusieurs petits segments de droite. La méthode ``MEDCouplingUMesh.tessellate2D()`` fait ce travail, mais modifie - le maillage. Nous faisons donc une copie préalable. Nous passons en paramètre la finesse de découpage (0.1 est suffisant - -- angle en radian). Attention donc à ne pas modifer ni ``fixm`` ni ``mobm`` ! :: - - fixm2 = fixm.deepCpy() # tessellate2D() modifies the current mesh - fixm2.tessellate2D(0.1) - fixm2.writeVTK("fixm2.vtu") - mobm2 = mobm.deepCpy() - mobm2.tessellate2D(0.1) - mobm2.writeVTK("mobm2.vtu") - -Faire une petite méthode ``displayVTK()``, faisant le travail qui nous servira souvent après. :: - - def displayVTK(m,fname): - tmp = m.deepCpy() - tmp.tessellate2D(0.1) - tmp.writeVTK(fname) - return - -Faire des réductions et des repérages de zones -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Le maillage ``mobm`` est en 6 parties distinctes (voir l'image au dessus). On ne veut récupérer que la première partie. -Utiliser ``MEDCouplingUMesh.partitionBySpreadZone()`` pour partitionner en zones ``mobm`` et ne prendre que la première zone. -Appeler cette nouvelle instance ``zone1Mobm`` et lui retirer tous les noeuds orphelins (``MEDCouplingUMesh.zipCoords()``) -Enfin l'afficher : :: - - zonesInMobm = mobm.partitionBySpreadZone() - print "Nb of zones in mobm : %i" % (len(zonesInMobm)) - zone1Mobm = mobm[zonesInMobm[0]] - zone1Mobm.zipCoords() - displayVTK(zone1Mobm, "zone1Mobm.vtu") - -.. image:: images/zone1Mobm.jpg - :scale: 70 - -Nous allons désormais travailler autour de ``zone1Mobm``. Nous allons réduire la zone de travail de ``fixm`` autour de ``zone1Mobm``. -Pour ce faire, réduire ``fixm`` en ne prenant que les cellules dans la boîte englobante -de ``zone1Mobm`` (``MEDCouplingUMesh.getBoundingBox()`` et ``MEDCouplingUMesh.getCellsInBoundingBox()``). -Appeler ce nouvel objet ``partFixm``, lui retirer ses noeuds orphelins et l'afficher. :: - - ids2 = fixm.getCellsInBoundingBox(zone1Mobm.getBoundingBox(),1e-10) - partFixm = fixm[ids2] - partFixm.zipCoords() - displayVTK(partFixm,"partFixm.vtu") - -.. image:: images/partFixmAndzone1Mobm.jpg - -Intersecter géométriquement deux maillages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -C'est le coeur de l'exercice. Nous allons intersecter géométriquement ``partFixm`` et ``zone1Mobm``. Cela revient à -partitionner à minima ``partFixm`` en cellules appartenant -soit complètement à ``partFixm`` soit à ``partFixm`` et ``zone1Mobm``. Invoquer la méthode statique -``MEDCouplingUMesh.Intersect2DMeshes()``, avec ``partFixm`` et ``zone1Mobm`` et mettre une précision -de 1e-10 (seuil de détection de fusion). Cette méthode retourne 3 paramètres (voir API dans la doc) que l'on appellera -ici ``partFixMob``, ``iPart`` et ``iMob`` dans cet ordre. - -Sur ``partFixMob`` merger les noeuds à 1e-10 près. :: - - partFixMob, iPart, iMob = ml.MEDCouplingUMesh.Intersect2DMeshes(partFixm,zone1Mobm,1e-10) - partFixMob.mergeNodes(1e-10) - -Récupérer et afficher la partie de ``partFixm`` qui n'est pas dans ``zone1Mobm``. Appeler ce maillage ``partFixmWithoutZone1Mobm``. :: - - ids3 = iMob.getIdsEqual(-1) - partFixmWithoutZone1Mobm = partFixMob[ids3] - displayVTK(partFixmWithoutZone1Mobm,"partFixmWithoutZone1Mobm.vtu") - -.. image:: images/partFixmWithoutZone1Mobm.jpg - :scale: 70 - -Maintenant, on va vérifier la qualité du résultat retourné par ``MEDCouplingUMesh.Intersect2DMeshes()``. -Pour ce faire on va passer 3 tests: - - * **Check #0** la somme des aires des cellules de ``partFixm`` et égale à celle de ``partFixMob`` - * **Check #1** la somme des aires des cellules de ``zone1Mobm`` et égale à la somme des cells de ``partFixMob`` - dont l'id dans ``iMob`` est different de -1 - * **Check #2** pour chaque cellule de ``partFixm``, son aire est égale à la somme des aires des cellules de ``partFixMob`` - -L'aire est une valeur algébrique. Donc attention cette verification ne peut se faire que si les cellules -sont toutes bien orientées ou à minima toutes orientées de la même manière. -Pour ce faire, regardons les aires des 38 cellules de ``partFixm`` (nom de variable : ``areaPartFixm``). :: - - areaPartFixm = partFixm.getMeasureField(ml.ON_CELLS).getArray() - print areaPartFixm.getValues() - -On voit que toutes les valeurs sont négatives. *Bilan*: ce fichier MED ne respecte pas la convention MED fichier ! -``partFixm`` étant mal orienté, et ``MEDCouplingUMesh.Intersect2DMeshes()`` conservant l'orientation, -``partFixMob`` est lui aussi mal orienté. -Bref, on va faire les comparaisons sur des tableaux de valeurs absolues. Vérifier alors **Check #0**. :: - - areaPartFixm = partFixm.getMeasureField(ml.ON_CELLS).getArray() - areaPartFixm.abs() - areaPartFixMob = partFixMob.getMeasureField(ml.ON_CELLS).getArray() - areaPartFixMob.abs() - val1=areaPartFixm.accumulate()[0] - val2=areaPartFixMob.accumulate()[0] - print "Check #0 %lf == %lf with precision 1e-8? %s" % (val1,val2,str(abs(val1-val2)<1e-8)) - -On peut passer au **Check #1**. L'esprit est le même que le **Check #0**. :: - - areaZone1Mobm = zone1Mobm.getMeasureField(ml.ON_CELLS).getArray() - areaZone1Mobm.abs() - val3 = areaZone1Mobm.accumulate()[0] - ids4 = iMob.getIdsNotEqual(-1) - areaPartFixMob2 = areaPartFixMob[ids4] - val4 = areaPartFixMob2.accumulate()[0] - print "Check #1 %lf == %lf with precision 1e-8 ? %s" % (val3,val4,str(abs(val3-val4)<1e-8)) - -Puis le **Check #2**. :: - - isCheck2OK = True - for icell in xrange(partFixm.getNumberOfCells()): - ids5 = iPart.getIdsEqual(icell) - areaOfCells = areaPartFixMob[ids5] - areaOfCells.abs() - if abs(areaOfCells.accumulate()[0] - areaPartFixm[icell]) > 1e-9: - isCheck2OK = False - pass - pass - print "Check #2? %s" % (str(isCheck2OK)) - -Utiliser les informations de l'intersection pour en faire des champs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -OK pour ``partFixMob``. Nous souhaitons maintenant créer un champ représentant une fonction indicatrice de la zone - -Maintenant créer un champ aux cellules sur ``partFixMob`` en mettant 0 sur la partie -exclusive ``partFixm`` et 1 sur la partie couverte. Nous créons donc un champ représentant une fonction indicatrice. -Le visualiser en utilisant un fichier VTK (ne pas oublier l'option *Triangulate* de ParaView). :: - - f = ml.MEDCouplingFieldDouble(ml.ON_CELLS,ml.ONE_TIME) - m = partFixMob.deepCpy() - m.tessellate2D(0.1) - f.setMesh(m) - arr = ml.DataArrayDouble(partFixMob.getNumberOfCells(),1) - arr[iMob.getIdsEqual(-1)] = 0. - arr[iMob.getIdsNotEqual(-1)] = 1. - f.setArray(arr) - f.checkCoherency() - f.setName("Zone") - ml.MEDCouplingFieldDouble.WriteVTK("Zone.vtu",[f]) - -.. image:: images/LocationEx2.jpg - :scale: 100 - -Plus généralement prendre les zones 0, 1 et 5. Faire un champ aux cellules qui vaut 0 dans la zone exclusivement de ``fixm``, -1 dans zone #0, 2 dans la zone #1 et finalement 3 dans la zone #5. :: - - zonesMobm = ml.MEDCouplingUMesh.MergeUMeshesOnSameCoords([mobm[zonesInMobm[0]], mobm[zonesInMobm[1]], mobm[zonesInMobm[5]]]) - zonesMobm.zipCoords() - partFixMob2,iPart2,iMob2 = ml.MEDCouplingUMesh.Intersect2DMeshes(partFixm,zonesMobm,1e-10) - partFixMob2.mergeNodes(1e-10) - f2 = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) - m2 = partFixMob2.deepCpy() - m2.tessellate2D(0.1) - f2.setMesh(m2) - arr = ml.DataArrayDouble(partFixMob2.getNumberOfCells(),1) - arr[iMob2.getIdsEqual(-1)]=0. - st = 0 - end = st + len(zonesInMobm[0]) - arr[iMob2.getIdsInRange(st,end)] = 1. - st += len(zonesInMobm[0]) ; - end = st + len(zonesInMobm[1]) - arr[iMob2.getIdsInRange(st,end)] = 2. - st += len(zonesInMobm[1]) - end = st + len(zonesInMobm[2]) - arr[iMob2.getIdsInRange(st,end)] = 3. - f2.setArray(arr) - f2.checkCoherency() - f2.setName("Zone2") - ml.MEDCouplingFieldDouble.WriteVTK("Zone2.vtu",[f2]) - -Ne pas oublier l'option *Triangulate* de ParaView dans le panneau Display pour bien voir les champs: - -.. image:: images/zonesMobm.jpg - -Solution -~~~~~~~~ - -:ref:`python_testmedcouplingloaderex2_solution` diff --git a/medtool/doc/tutorial/medcouplingnumpy_en.rst b/medtool/doc/tutorial/medcouplingnumpy_en.rst deleted file mode 100644 index a6dc90e50..000000000 --- a/medtool/doc/tutorial/medcouplingnumpy_en.rst +++ /dev/null @@ -1,190 +0,0 @@ - -MEDCoupling, NumPy et SciPy ----------------------------- - -NumPy est un package additionnel de python qui permet de manipuler des tableaux de manière optimisée. -Il s'agit d'un prérequis optionnel de MEDCoupling. - -NumPy est une passerelle vers le HPC Python (multiprocessing, pyCUDA, SciPy...) et offre de puissantes -fonctions de calcul vectoriel. C'est pourquoi MEDCoupling offre des liens avec NumPy. -Un bon point de départ pour la découverte de NumPy est le `Tutorial NumPy `_ - -SciPy est aussi un package de python nécessitant NumPy. Il s'agit également d'un prérequis optionnel de MEDCoupling. -SciPy offre des services d'algèbre linéaire, Fast Fourrier Transform, etc ... - -Nous allons ici faire quelques petites manipulations pour voir ce lien entre MEDCoupling et NumPy / SciPy. - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer le module Python ``MEDCoupling``: :: - - import MEDCoupling as mc - -NumPy est un prérequis optionnel, vérifions que nous en bénéficions bien : :: - - assert(mc.MEDCouplingHasNumPyBindings()) - -Nous pouvons alors importer NumPy sans problème: :: - - import numpy as np - -Convertir un DataArray en tableau NumPy et vice versa -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Créer une instance de ``DataArrayDouble`` ayant une composante et 12 tuples. -Et assigner 4. à tous les tuples. :: - - arr = mc.DataArrayDouble(12) - arr[:] = 4. - -Créons maintenant un tableau NumPy reposant sur les mêmes données que ``arr``. :: - - nparr = arr.toNumPyArray() - -Et afficher ``nparr``. :: - - print nparr.__repr__() - print nparr.tolist() - -Mais est ce qu'on ne nous a pas mystifié ? ``arr`` et ``nparr`` partagent-ils le même bloc mémoire ? -Pour le vérifier assignons 7.0 un tuple sur 2 avec ``nparr`` et vérifions que ``arr`` et ``nparr`` sont simultanément modifiés. :: - - nparr[::2] = 7. - print nparr.__repr__() - print arr.__repr__() - -C'est rigolo ! Mais si je détruis ``arr`` (le premier à avoir alloué la mémoire) est-ce que ``nparr`` est tué aussi ? -Ne risque-t-on pas le SIGSEGV ? -Testons : :: - - del arr - import gc; gc.collect() # Make sure the object has been deleted - print nparr.__repr__() - -OK super. Mais inversement puis je faire une instance de ``DataArrayDouble`` avec ``nparr`` ? Oui, en utilisant le constructeur -qui prend un ``nparray`` en entrée. -Et afficher le contenu.:: - - arr2 = mc.DataArrayDouble(nparr) - print arr2.__repr__() - -Modifions ``nparr`` en assignant 5.0 pour tous les tuples et vérifier que les 2 représentations ont bien été modifiées simultanément.:: - - nparr[:] = 5. - print nparr.__repr__() - print arr2.__repr__() - -Nous en profitons pour montrer un petit service pratique avec NumPy, à savoir, l'écriture optimisée. -Ecrivons le contenu binaire de ``nparr`` dans un fichier. :: - - f = open("toto.data","w+b") - a = np.memmap(f, dtype='float64', mode='w+', offset=0, shape=nparr.shape) - a[:] = nparr[:] - f.flush() - -Relisons "toto.data". :: - - f2 = open("toto.data","r+b") - b = np.memmap(f2,dtype='float64',mode='r',offset=0,shape=(12,)) - -Pour rigoler, assignons 3.14 à ``a``, flushons et relisons. :: - - a[:] = 3.14 - f.flush() - b = np.memmap(f2,dtype='float64',mode='r',offset=0,shape=(12,)) - print b.__repr__() - -On voit donc que le passage de MEDCoupling à NumPy se fait directement et de manière optimisée. Donc ca peut valoir le coup ! -Tout ce qui vient d'être montré marche aussi avec des ``DataArrayInt``. -Regardons la suite. - -Jouons avec SciPy -~~~~~~~~~~~~~~~~~ - -Nous allons créer un maillage non conforme. Le but sera de trouver la peau de ce maillage *sans* les surfaces non conformes. - -Nous allons faire cela en jouant avec les matrices creuses de SciPy (*sparse matrix*). Nous interpolons ce maillage non conforme -sur lui même, ce qui devrait donner une matrice diagonale si le maillage était conforme. - -Avant nous vérifions que l'on peut jouer avec SciPy ! :: - - assert(mc.MEDCouplingHasSciPyBindings()) - -Pour le moment créons un maillage non conforme. Nous collons simplement deux maillages structurés avec des -discrétisations spatiales différentes.:: - - c1 = mc.MEDCouplingCMesh() - arr1 = mc.DataArrayDouble(7) - arr1.iota() - c1.setCoords(arr1,arr1,arr1) - c2 = mc.MEDCouplingCMesh() - arr2 = mc.DataArrayDouble(9) - arr2.iota() - arr2 *= 6./8. - c2.setCoords(arr2,arr2,arr2) - -Dégénérons ``c1`` et ``c2`` en non-structuré, une translation de ``[6.,0.,0.]`` de ``c2``, et en faisant -l'agrégation des deux, c'est dans la poche. :: - - c1 = c1.buildUnstructured() - c2 = c2.buildUnstructured() - c2.translate([6.,0.,0.]) - c = mc.MEDCouplingUMesh.MergeUMeshes([c1,c2]) - -Attention des noeuds sont dupliqués, il faut invoquer ``mergeNodes()``. :: - - c.mergeNodes(1e-12) - -Récupérons la peau et les faces non conformes. Ca nous savons faire, car nous avons fait les exercices avant :-) :: - - skinAndNCFaces = c.computeSkin() - -Retirons les noeuds non utilisés. Cette étape n'est pas obligatoire. :: - - skinAndNCFaces.zipCoords() - -Voici à quoi cela ressemble: - -.. image:: images/skinandnccells_numpy.png - -OK maintenant on va séparer les cellules de bord des cellules non conformes grâce au ``MEDCouplingRemapper``. -Interpolons ``skinAndNCFaces`` sur lui-même. On acceptera un écart entre face de 1e-12 et un warping max de 0.01. :: - - from MEDCouplingRemapper import MEDCouplingRemapper - rem = MEDCouplingRemapper() - rem.setMaxDistance3DSurfIntersect(1e-12) - rem.setMinDotBtwPlane3DSurfIntersect(0.99) - rem.prepare(skinAndNCFaces,skinAndNCFaces,"P0P0") - -Récupérer la matrice creuse au format CSR du remapper. :: - - mat = rem.getCrudeCSRMatrix() - -.. note:: Le format CSR est un format de stockage efficace des matrices - creuses : `Sparse matrix CSR `_ - -Comme nous avons bien suivi les exos sur NumPy, grâce au NumPy array ``mat.indptr`` on peut récupérer -l'ensemble des lignes de la matrice ``mat`` ayant exactement un élément non nul. :: - - indptr = mc.DataArrayInt(mat.indptr) - indptr2 = indptr.deltaShiftIndex() - cellIdsOfSkin = indptr2.getIdsEqual(1) - -C'est presque fini. Créer le sous maillage contenant uniquement la peau et l'écrire dans -un fichier VTK ou MED pour le visualiser avec ParaView. :: - - skin = skinAndNCFaces[cellIdsOfSkin] - skin.writeVTK("skin.vtu") - -.. note:: ``skin`` contient des noeuds orphelins, on peut les retirer avec ``skin.zipCoords()``. - -Et voilà ce que cela donne : - -.. image:: images/skinonly_numpy.png - -Script complet -~~~~~~~~~~~~~~ - -:ref:`python_testMEDCouplingNumPy_solution` - diff --git a/medtool/doc/tutorial/medcouplingnumpy_fr.rst b/medtool/doc/tutorial/medcouplingnumpy_fr.rst deleted file mode 100644 index a6dc90e50..000000000 --- a/medtool/doc/tutorial/medcouplingnumpy_fr.rst +++ /dev/null @@ -1,190 +0,0 @@ - -MEDCoupling, NumPy et SciPy ----------------------------- - -NumPy est un package additionnel de python qui permet de manipuler des tableaux de manière optimisée. -Il s'agit d'un prérequis optionnel de MEDCoupling. - -NumPy est une passerelle vers le HPC Python (multiprocessing, pyCUDA, SciPy...) et offre de puissantes -fonctions de calcul vectoriel. C'est pourquoi MEDCoupling offre des liens avec NumPy. -Un bon point de départ pour la découverte de NumPy est le `Tutorial NumPy `_ - -SciPy est aussi un package de python nécessitant NumPy. Il s'agit également d'un prérequis optionnel de MEDCoupling. -SciPy offre des services d'algèbre linéaire, Fast Fourrier Transform, etc ... - -Nous allons ici faire quelques petites manipulations pour voir ce lien entre MEDCoupling et NumPy / SciPy. - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer le module Python ``MEDCoupling``: :: - - import MEDCoupling as mc - -NumPy est un prérequis optionnel, vérifions que nous en bénéficions bien : :: - - assert(mc.MEDCouplingHasNumPyBindings()) - -Nous pouvons alors importer NumPy sans problème: :: - - import numpy as np - -Convertir un DataArray en tableau NumPy et vice versa -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Créer une instance de ``DataArrayDouble`` ayant une composante et 12 tuples. -Et assigner 4. à tous les tuples. :: - - arr = mc.DataArrayDouble(12) - arr[:] = 4. - -Créons maintenant un tableau NumPy reposant sur les mêmes données que ``arr``. :: - - nparr = arr.toNumPyArray() - -Et afficher ``nparr``. :: - - print nparr.__repr__() - print nparr.tolist() - -Mais est ce qu'on ne nous a pas mystifié ? ``arr`` et ``nparr`` partagent-ils le même bloc mémoire ? -Pour le vérifier assignons 7.0 un tuple sur 2 avec ``nparr`` et vérifions que ``arr`` et ``nparr`` sont simultanément modifiés. :: - - nparr[::2] = 7. - print nparr.__repr__() - print arr.__repr__() - -C'est rigolo ! Mais si je détruis ``arr`` (le premier à avoir alloué la mémoire) est-ce que ``nparr`` est tué aussi ? -Ne risque-t-on pas le SIGSEGV ? -Testons : :: - - del arr - import gc; gc.collect() # Make sure the object has been deleted - print nparr.__repr__() - -OK super. Mais inversement puis je faire une instance de ``DataArrayDouble`` avec ``nparr`` ? Oui, en utilisant le constructeur -qui prend un ``nparray`` en entrée. -Et afficher le contenu.:: - - arr2 = mc.DataArrayDouble(nparr) - print arr2.__repr__() - -Modifions ``nparr`` en assignant 5.0 pour tous les tuples et vérifier que les 2 représentations ont bien été modifiées simultanément.:: - - nparr[:] = 5. - print nparr.__repr__() - print arr2.__repr__() - -Nous en profitons pour montrer un petit service pratique avec NumPy, à savoir, l'écriture optimisée. -Ecrivons le contenu binaire de ``nparr`` dans un fichier. :: - - f = open("toto.data","w+b") - a = np.memmap(f, dtype='float64', mode='w+', offset=0, shape=nparr.shape) - a[:] = nparr[:] - f.flush() - -Relisons "toto.data". :: - - f2 = open("toto.data","r+b") - b = np.memmap(f2,dtype='float64',mode='r',offset=0,shape=(12,)) - -Pour rigoler, assignons 3.14 à ``a``, flushons et relisons. :: - - a[:] = 3.14 - f.flush() - b = np.memmap(f2,dtype='float64',mode='r',offset=0,shape=(12,)) - print b.__repr__() - -On voit donc que le passage de MEDCoupling à NumPy se fait directement et de manière optimisée. Donc ca peut valoir le coup ! -Tout ce qui vient d'être montré marche aussi avec des ``DataArrayInt``. -Regardons la suite. - -Jouons avec SciPy -~~~~~~~~~~~~~~~~~ - -Nous allons créer un maillage non conforme. Le but sera de trouver la peau de ce maillage *sans* les surfaces non conformes. - -Nous allons faire cela en jouant avec les matrices creuses de SciPy (*sparse matrix*). Nous interpolons ce maillage non conforme -sur lui même, ce qui devrait donner une matrice diagonale si le maillage était conforme. - -Avant nous vérifions que l'on peut jouer avec SciPy ! :: - - assert(mc.MEDCouplingHasSciPyBindings()) - -Pour le moment créons un maillage non conforme. Nous collons simplement deux maillages structurés avec des -discrétisations spatiales différentes.:: - - c1 = mc.MEDCouplingCMesh() - arr1 = mc.DataArrayDouble(7) - arr1.iota() - c1.setCoords(arr1,arr1,arr1) - c2 = mc.MEDCouplingCMesh() - arr2 = mc.DataArrayDouble(9) - arr2.iota() - arr2 *= 6./8. - c2.setCoords(arr2,arr2,arr2) - -Dégénérons ``c1`` et ``c2`` en non-structuré, une translation de ``[6.,0.,0.]`` de ``c2``, et en faisant -l'agrégation des deux, c'est dans la poche. :: - - c1 = c1.buildUnstructured() - c2 = c2.buildUnstructured() - c2.translate([6.,0.,0.]) - c = mc.MEDCouplingUMesh.MergeUMeshes([c1,c2]) - -Attention des noeuds sont dupliqués, il faut invoquer ``mergeNodes()``. :: - - c.mergeNodes(1e-12) - -Récupérons la peau et les faces non conformes. Ca nous savons faire, car nous avons fait les exercices avant :-) :: - - skinAndNCFaces = c.computeSkin() - -Retirons les noeuds non utilisés. Cette étape n'est pas obligatoire. :: - - skinAndNCFaces.zipCoords() - -Voici à quoi cela ressemble: - -.. image:: images/skinandnccells_numpy.png - -OK maintenant on va séparer les cellules de bord des cellules non conformes grâce au ``MEDCouplingRemapper``. -Interpolons ``skinAndNCFaces`` sur lui-même. On acceptera un écart entre face de 1e-12 et un warping max de 0.01. :: - - from MEDCouplingRemapper import MEDCouplingRemapper - rem = MEDCouplingRemapper() - rem.setMaxDistance3DSurfIntersect(1e-12) - rem.setMinDotBtwPlane3DSurfIntersect(0.99) - rem.prepare(skinAndNCFaces,skinAndNCFaces,"P0P0") - -Récupérer la matrice creuse au format CSR du remapper. :: - - mat = rem.getCrudeCSRMatrix() - -.. note:: Le format CSR est un format de stockage efficace des matrices - creuses : `Sparse matrix CSR `_ - -Comme nous avons bien suivi les exos sur NumPy, grâce au NumPy array ``mat.indptr`` on peut récupérer -l'ensemble des lignes de la matrice ``mat`` ayant exactement un élément non nul. :: - - indptr = mc.DataArrayInt(mat.indptr) - indptr2 = indptr.deltaShiftIndex() - cellIdsOfSkin = indptr2.getIdsEqual(1) - -C'est presque fini. Créer le sous maillage contenant uniquement la peau et l'écrire dans -un fichier VTK ou MED pour le visualiser avec ParaView. :: - - skin = skinAndNCFaces[cellIdsOfSkin] - skin.writeVTK("skin.vtu") - -.. note:: ``skin`` contient des noeuds orphelins, on peut les retirer avec ``skin.zipCoords()``. - -Et voilà ce que cela donne : - -.. image:: images/skinonly_numpy.png - -Script complet -~~~~~~~~~~~~~~ - -:ref:`python_testMEDCouplingNumPy_solution` - diff --git a/medtool/doc/tutorial/medcouplingremapper_en.rst b/medtool/doc/tutorial/medcouplingremapper_en.rst deleted file mode 100644 index 42e16e305..000000000 --- a/medtool/doc/tutorial/medcouplingremapper_en.rst +++ /dev/null @@ -1,125 +0,0 @@ - -Interpolate with MEDCouplingRemapper ------------------------------------- - -The purpose of this exercise is to interpolate between two meshes "srcMesh" and "trgMesh". -To make the reader aware of some subtleties about interpolation, a special case -is considered: "srcMesh" is a refinement of "trgMesh". - - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -To start the exercise import the whole Python module MEDCouplingRemapper. :: - - from MEDCouplingRemapper import * - - -Create a MEDCouplingUMesh 2D instance, built from a Cartesian mesh -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Build the unstructured mesh "trgMesh" from a 2D Cartesian mesh with 10x10 cells, -starting at point [0.,0.] and having a step of 1.0 along the X and Y directions. -:: - - arr=DataArrayDouble(11) ; arr.iota(0) - trgMesh=MEDCouplingCMesh() ; trgMesh.setCoords(arr,arr) ; trgMesh=trgMesh.buildUnstructured() - -Create the source mesh "srcMesh" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Create a mesh "srcMesh" from a 2D Cartesian mesh having 20x20 cells and starting -at point [0.,0.] with a step of 0.5 along the X and Y directions. -:: - - arr=DataArrayDouble(21) ; arr.iota(0) ; arr*=0.5 - srcMesh=MEDCouplingCMesh() ; srcMesh.setCoords(arr,arr) ; srcMesh=srcMesh.buildUnstructured() - -Triangulate the 20 first cells of source mesh (using MEDCouplingUMesh.simplexize()). -Store the result in "srcMesh". -:: - - tmp=srcMesh[:20] ; tmp.simplexize(0) - srcMesh=MEDCouplingUMesh.MergeUMeshes([tmp,srcMesh[20:]]) - -Interpolate using MEDCouplingRemapper -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Compute the first part of the interpolation matrix with the following considerations: -"srcMesh" is regarded as a discretization at cell points, and so is "trgMesh". -To this end invoke prepare() on an instance of the MEDCouplingRemapper class ("remap"). -:: - - remap=MEDCouplingRemapper() - remap.prepare(srcMesh,trgMesh,"P0P0") - -Check that the computed matrix is correct in this trivial case: get the internal -interpolation matrix by calling MEDCouplingRemapper.getCrudeMatrix() and save it in -"myMatrix". This matrix gives for each cell in "trgMesh" the cell IDs of "srcMesh" -which are intersecting the target and the area of intersection. Check that for each -cell in "trgMesh" the sum of the areas is always equal to 1.0. -:: - - myMatrix=remap.getCrudeMatrix() - print myMatrix # to see what it looks like - sumByRows=DataArrayDouble(len(myMatrix)) - for i,wIt in enumerate(sumByRows): - su=0. - for it in myMatrix[i]: - su+=myMatrix[i][it] - wIt[0]=su - print "Does interpolation look OK? %s"%(str(sumByRows.isUniform(1.,1e-12))) - -.. note:: Some triangles were added into "srcMesh" to make "myMatrix" less boring. "myMatrix". - -Create a field at cell points "srcField" built from the following analytical formula: -"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))" where x and y represent the usual space coordinates. -:: - - srcField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; srcField.setMesh(srcMesh) - srcField.fillFromAnalytic(1,"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))") ; srcField.getArray().setInfoOnComponent(0,"powercell [W]") - -.. image:: images/Remapper1.png - -Apply the interpolation using MEDCouplingRemapper.transferField(): :: - - remap.transferField(srcField,1e300) - -.. note:: 1e300 is a default value. It will be systematically assigned to all cells - in "trgField" which do not intersect any cell in "srcMesh". The common usage is to assign - a huge value to identify what is often considered as a bug. But some other use cases - indicate using 0 here, e.g. when considering a parallel interpolation merged ultimately - with an addition. - -.. note:: An exception is raised since "srcField" hasn't got an explicitly defined nature. - In what follows the impact of this attribute on the final result will be explained. - -Set the nature of "srcField" to ConservativeVolumic (intensive field, e.g. a temperature). :: - - srcField.setNature(ConservativeVolumic) - trgFieldCV=remap.transferField(srcField,1e300) - -Check that with this nature the field integral is conserved. On the other side -the sum on cells (accumulation) is NOT conserved. :: - - print "ConservativeVolumic %lf == %lf"%(srcField.integral(True)[0],trgFieldCV.integral(True)[0]) - print "ConservativeVolumic %lf != %lf"%(srcField.getArray().accumulate()[0],trgFieldCV.getArray().accumulate()[0]) - -Set the nature of "srcField" to IntegralGlobConstraint (extensive field, e.g. a power). :: - - srcField.setNature(IntegralGlobConstraint) - trgFieldI=remap.transferField(srcField,1e300) - -Check that given this nature the field integral is NOT conserved. On the other side the -cumulative sum on cells is conserved. :: -:: - - print "IntegralGlobConstraint %lf != %lf"%(srcField.integral(True)[0],trgFieldI.integral(True)[0]) - print "IntegralGlobConstraint %lf == %lf"%(srcField.getArray().accumulate()[0],trgFieldI.getArray().accumulate()[0]) - -Visualize the fields using ParaViS. - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingremapper1_solution` diff --git a/medtool/doc/tutorial/medcouplingremapper_fr.rst b/medtool/doc/tutorial/medcouplingremapper_fr.rst deleted file mode 100644 index 8ea9dfa2f..000000000 --- a/medtool/doc/tutorial/medcouplingremapper_fr.rst +++ /dev/null @@ -1,150 +0,0 @@ - -MEDCouplingRemapper : interpolation de champs ---------------------------------------------- - -Nous allons ici effectuer une interpolation entre deux maillages ``srcMesh`` et ``trgMesh``. -Pour mettre l'accent sur certaines petites subtilités de l'interpolation, nous prenons un cas particulier où ``srcMesh`` est -un maillage raffiné de ``trgMesh`` (avec certaines cellules découpées plus finement). - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pour commencer l'exercice importer le module Python ``MEDCoupling`` et la -classe ``MEDCouplingRemapper`` du module ``MEDCouplingRemapper``. :: - - import MEDCoupling as mc - from MEDCouplingRemapper import MEDCouplingRemapper - - -Créer le maillage target -~~~~~~~~~~~~~~~~~~~~~~~~ - -Construire le maillage non structuré ``trgMesh`` issu d'un maillage cartésien 2D 10x10 commençant au -point ``[0.,0.]`` et ayant un pas de 1. selon X et selon Y : :: - - arr = mc.DataArrayDouble(11) - arr.iota(0) - trgMesh = mc.MEDCouplingCMesh() - trgMesh.setCoords(arr,arr) - trgMesh = trgMesh.buildUnstructured() - -Créer le maillage source -~~~~~~~~~~~~~~~~~~~~~~~~ - -Créer un maillage ``srcMesh`` issu d'un maillage cartésien 2D 20x20 cellules commençant -aussi au point ``[0.,0.]`` et ayant un pas de 0.5 selon X et selon Y : :: - - arr = mc.DataArrayDouble(21) - arr.iota(0) - arr *= 0.5 - srcMesh = mc.MEDCouplingCMesh() - srcMesh.setCoords(arr,arr) - srcMesh = srcMesh.buildUnstructured() - -Afin de rendre l'exercise plus intéressant, triangulariser à l'aide de ``MEDCouplingUMesh.simplexize()`` -les 20 premières cellules de ``srcMesh`` -(les simplexes 2D sont les triangles). Mettre le résultat dans ``srcMesh``. :: - - tmp = srcMesh[:20] # Extract a sub-part of srcMesh - tmp.simplexize(0) - srcMesh = mc.MEDCouplingUMesh.MergeUMeshes([tmp,srcMesh[20:]]) - -Interpoler avec MEDCouplingRemapper -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nous rappelons que pour projeter un champ d'un maillage vers un autre, il faut d'abord préparer la matrice d'interpolation -qui contient les ratios de projection. - -Calculer la première partie de la matrice d'interpolation de ``srcMesh`` (discrétisée aux cellules - *P0*) -vers ``trgMesh`` (discrétisée aux cellules également). -Pour ce faire, invoquer ``MEDCouplingRemapper.prepare()`` sur une instance (``remap``) de ``MEDCouplingRemapper``. :: - - remap = MEDCouplingRemapper() - remap.prepare(srcMesh,trgMesh,"P0P0") - -Vérifier que la matrice calculée par la méthode est correcte dans notre cas trivial. -Pour ce faire, récupérer dans ``myMatrix`` la matrice interne retournée par ``MEDCouplingRemapper.getCrudeMatrix()``. -Celle-ci donne pour chaque cellule de ``trgMesh`` les identifiants de cellules de ``srcMesh`` avec -lesquelles elle s'intersecte, et l'aire d'intersection correspondante. - -Vérifier notamment que pour chaque cellule de ``trgMesh`` la somme des aires fait toujours 1. :: - - myMatrix = remap.getCrudeMatrix() - print myMatrix - sumByRows = mc.DataArrayDouble(len(myMatrix)) - for i,wIt in enumerate(sumByRows): - su = 0. - for it in myMatrix[i]: - su += myMatrix[i][it] - wIt[0] = su - print "Is interpolation well prepared?", sumByRows.isUniform(1.,1e-12) - -.. note:: Les triangles dans ``srcMesh`` ont été rajoutés pour casser la monotonie de la matrice ``myMatrix``. - -.. note:: Comme on le voit, la préparation ne nécessite que les deux maillages, et rien d'autre. - -Construire un champ aux cellules "srcField" construit à partir de la formule analytique -suivante ``7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))`` : :: - - srcField = mc.MEDCouplingFieldDouble(mc.ON_CELLS, mc.ONE_TIME) - srcField.setMesh(srcMesh) - srcField.fillFromAnalytic(1,"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))") - srcField.getArray().setInfoOnComponent(0, "powercell [W]") - -Voici à quoi ressemble ce champ : - -.. image:: images/Remapper1.png - -Appliquer l'interpolation avec ``MEDCouplingRemapper.transferField()`` : :: - - remap.transferField(srcField, 1e300) - -.. note:: 1e300 est une valeur par défaut. Cette valeur sera systématiquement assignée à toute cellule - de ``trgField`` n'interceptant aucune cellule de ``srcMesh``. En général, les utilisateurs mettent une - valeur énorme pour repérer ce qui est souvent un bug. Mais d'autres utilisateurs, dans la perspective - d'une interpolation parallèle par exemple, mettent 0. - -.. note:: Une exception est envoyée car ``srcField`` n'a pas de *nature* définie. - Nous allons voir dans la suite l'impact de cet attribut sur le résultat final. - -Mettre la nature de ``srcField`` à ``ConservativeVolumic``. Cela signifie que le champ doit être interprété commé étant -intensif (une température par exemple). :: - - srcField.setNature(mc.ConservativeVolumic) - trgFieldCV = remap.transferField(srcField,1e300) - -Vérifier qu'avec la nature ``ConservativeVolumic``, l'intégrale du champ est conservée. Par contre, -la somme sur les cellules (accumulation) n'est **pas** conservée ! :: - - integSource = srcField.integral(True)[0] - integTarget = trgFieldCV.integral(True)[0] - print "ConservativeVolumic -- integrals: %lf == %lf" % (integSource, integTarget) - - accSource = srcField.getArray().accumulate()[0] - accTarget = trgFieldCV.getArray().accumulate()[0] - print "ConservativeVolumic -- sums: %lf != %lf" % (accSource, accTarget) - - -Maintenant mettre la nature de ``srcField`` à ``IntegralGlobConstraint``. Le champ doit être interprété commé étant -extensif (par exemple une puissance ou un volume). :: - - srcField.setNature(mc.IntegralGlobConstraint) - trgFieldI = remap.transferField(srcField,1e300) - -Vérifier qu'avec la nature ``IntegralGlobConstraint``, l'intégrale du champ n'est **pas** conservée. -Par contre, la somme sur les cellules est conservée. :: - - integSource = srcField.integral(True)[0] - integTarget = trgFieldI.integral(True)[0] - print "IntegralGlobConstraint -- integrals: %lf != %lf" % (integSource, integTarget) - - accSource = srcField.getArray().accumulate()[0] - accTarget = trgFieldI.getArray().accumulate()[0] - print "IntegralGlobConstraint -- sums: %lf == %lf" % (accSource, accTarget) - -Visualiser les champs avec ParaViS, ou en les écrivant dans un fichier. - -Solution -~~~~~~~~ - -:ref:`python_testMEDCouplingremapper1_solution` diff --git a/medtool/doc/tutorial/medloader_SplitAndMerge1_en.rst b/medtool/doc/tutorial/medloader_SplitAndMerge1_en.rst deleted file mode 100644 index 8a2f4d0b3..000000000 --- a/medtool/doc/tutorial/medloader_SplitAndMerge1_en.rst +++ /dev/null @@ -1,186 +0,0 @@ - -Splitting and merging a MED file using MEDLoader's advanced API ---------------------------------------------------------------- - -Objective -~~~~~~~~~ - -The aim of this exercise is to create a mesh with mixed geometrical type from scratch, and to associate two fields to it: - -* a field on cells "CellField" -* a field on nodes "NodeField" - - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -Create an unstructured mesh "m0" built from a 30x30 structured mesh (meshDim=2, spaceDim=2). -Each of the even cell of "m0" is "simplexized" (cut in triangles - method MEDCouplingUMesh.simplexize(0)) :: - - from MEDLoader import * - m0=MEDCouplingCMesh() - arr=DataArrayDouble(31,1) ; arr.iota(0.) - m0.setCoords(arr,arr) - m0=m0.buildUnstructured() - m00=m0[::2] # Extract even cells - m00.simplexize(0) - m01=m0[1::2] - m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) - m0.getCoords()[:]*=1/15. # Illustrate how to quickly rescale a mesh - m0.setName("mesh") - -.. note:: The call to setName() on "m0" is mandatory. Don't forget that the correct naming of the meshes is paramount in the MED file context. - -Create the fields "CellField" and "NodeField" at the time-stamp (5,6) corresponding to 5.6s. -:: - - CellField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; CellField.setTime(5.6,5,6) ; CellField.setMesh(m0) - CellField.setName("CellField") - CellField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") - NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) - NodeField.setName("NodeField") - NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") - -"CellField" looks like this: - -.. image:: images/SplitAndMergeCell1.jpg - - -Mesh partitionning -~~~~~~~~~~~~~~~~~~ - -Cut "m0" into two distinct parts called "proc0" and "proc1". "proc0" will be contained in the bounding box [(0.,0.4),(0.,0.4)] (with a precision of 1e-10). Use the method MEDCouplingUMesh.getCellsInBoundingBox(). "proc1" is simply the complementary part of "proc0" (method DataArrayInt.buildComplement()). :: - - proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) - proc1=proc0.buildComplement(m0.getNumberOfCells()) - -.. image:: images/SplitAndMerge2.jpg - -Writing into two different MED files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Starting with the partition above ("proc0" and "proc1") create two MED files called "proc0.med" et "proc1.med". :: - - NodeField0=NodeField[proc0] ; CellField0=CellField[proc0] ; CellField0.setMesh(NodeField0.getMesh()) - NodeField1=NodeField[proc1] ; CellField1=CellField[proc1] ; CellField1.setMesh(NodeField1.getMesh()) - - proc0_fname="proc0.med" - MEDLoader.WriteField(proc0_fname,NodeField0,True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc0_fname,CellField0) - - proc1_fname="proc1.med" - MEDLoader.WriteField(proc1_fname,NodeField1,True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc1_fname,CellField1) - -Reading and merging 2 MED files - Easy (but non optimal) version -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In the two files "proc0.med" and "proc1.med" read the respective "CellField" with the basic API. Aggregate the two and store the result in "CellField_read". :: - - CellField0_read=MEDLoader.ReadFieldCell("proc0.med","mesh",0,"CellField",5,6) - CellField1_read=MEDLoader.ReadFieldCell("proc1.med","mesh",0,"CellField",5,6) - CellField_read=MEDCouplingFieldDouble.MergeFields([CellField0_read,CellField1_read]) - -.. note:: It might seem to the reader that the cell type information is repeated uselessly, but don't forget that the MED file norm doesn't forbid a field to be defined simultaneously on nodes and on Gauss points for example ... - -Compare "CellField_read" and "CellField0". Problem: because of the constraint on the MED file numbering, the initial numbering has been lost. Or more exactly there is no standard way to retrieve it. This means that a call to MEDCouplingFieldDouble.isEqual() won't succeed. Let's use the method MEDCouplingFieldDouble.substractInPlaceDM() which operates a renumbering based on a given policy (see HTML doc). -To this end, create a deep copy of "CellField" into "CellFieldCpy" and invoke substractInPlaceDM() on it (DM stands for "Different Meshes", contrarily to substract() which only succeeds if the fields share the same mesh). :: - - CellFieldCpy=CellField.deepCpy() - CellFieldCpy.substractInPlaceDM(CellField_read,10,1e-12) - CellFieldCpy.getArray().abs() - print CellFieldCpy.getArray().isUniform(0.,1e-12) - -Let's do the same on "NodeField". The main difference here is that redundant information is created at the boundary. :: - - NodeField0_read=MEDLoader.ReadFieldNode("proc0.med","mesh",0,"NodeField",5,6) - NodeField1_read=MEDLoader.ReadFieldNode("proc1.med","mesh",0,"NodeField",5,6) - NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0_read,NodeField1_read]) - -.. note:: The mesh is read a second time here, which can be damaging in terms of performance. - -Invoke MEDCouplingUMesh.mergeNodes() on "NodeField_read" to remove duplicate nodes. -Make a deep copy called "NodeFieldCpy" from "NodeField" and call MEDCouplingUMesh.mergeNodes(). :: - - NodeField_read.mergeNodes(1e-10) - NodeFieldCpy=NodeField.deepCpy() - NodeFieldCpy.mergeNodes(1e-10) - -.. note:: mergeNodes() takes two epsilons: the first classical one on the absolute distance between nodes, and the second expressing a tolerance on the values. If the field value of two nodes to be merged is bigger than this an exception is raised. - -Compare "NodeFieldCpy" and "NodeField_read" still using MEDCouplingFieldDouble.substractInPlaceDM(). :: - - NodeFieldCpy.substractInPlaceDM(NodeField_read,10,1e-12) - print NodeFieldCpy.getArray().isUniform(0.,1e-12) - - -Read/write of two separated MED files - More complex but more efficient version -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We show a more systematic and more general method to merge files. -This is the preferred route when dealing with big files . -This method adds performance but also allows to add extra information. - -Using the advanced API read the meshes of two files "proc0.med" and "proc1.med" and aggregate the result in an MEDFileUMesh instance "mergeMLMesh". -Handle all the levels (even if there is only one in the present case) using the method -MEDFileUMesh.getNonEmptyLevels() on the instance coming from "proc0.med". :: - - fileNames=["proc0.med","proc1.med"] - msML=[MEDFileMesh.New(fname) for fname in fileNames] - fsML=[MEDFileFields.New(fname) for fname in fileNames] - mergeMLMesh=MEDFileUMesh() - mergeMLFields=MEDFileFields() - for lev in msML[0].getNonEmptyLevels(): - o2nML=len(msML[0].getNonEmptyLevels())*[None] - cs=[mML.getCoords() for mML in msML] - mergeMLMesh.setCoords(DataArrayDouble.Aggregate(cs)) - ms=[mML.getMeshAtLevel(lev) for mML in msML] - m=MEDCouplingUMesh.MergeUMeshes(ms) ; m.setCoords(mergeMLMesh.getCoords()) - o2nML[lev]=m.sortCellsInMEDFileFrmt() - mergeMLMesh.setMeshAtLevel(lev,m) - pass - - for fieldName in fsML[0].getFieldsNames(): - fmts=[fML[fieldName] for fML in fsML] - mergeField=MEDFileFieldMultiTS() - for dt,it,tim in fmts[0].getTimeSteps(): - fts=[fmt[dt,it] for fmt in fmts] - arrs=len(fts)*[None] - for typp in fts[0].getTypesOfFieldAvailable(): - arr1s=[] - if typp==ON_CELLS: - for ft in fts: - for geoTyp,smth in ft.getFieldSplitedByType(): - if geoTyp!=NORM_ERROR: - smth1=filter(lambda x:x[0]==ON_CELLS,smth) - arr2s=[ft.getUndergroundDataArray()[elt[1][0]:elt[1][1]] for elt in smth1] - arr1s.append(DataArrayDouble.Aggregate(arr2s)) - pass - pass - pass - pass - else: - for ft in fts: - smth=filter(lambda x:x[0]==NORM_ERROR,ft.getFieldSplitedByType()) - arr2=DataArrayDouble.Aggregate([ft.getUndergroundDataArray()[elt[1][0][1][0]:elt[1][0][1][1]] for elt in smth]) - arr1s.append(arr2) - pass - pass - arr=DataArrayDouble.Aggregate(arr1s) - if typp==ON_CELLS: - arr.renumberInPlace(o2nML[lev]) - mcf=MEDCouplingFieldDouble(typp,ONE_TIME) ; mcf.setName(fieldName) ; mcf.setTime(tim,dt,it) ; mcf.setArray(arr) - mcf.setMesh(mergeMLMesh.getMeshAtLevel(lev)) ; mcf.checkCoherency() - mergeField.appendFieldNoProfileSBT(mcf) - pass - pass - mergeMLFields.pushField(mergeField) - pass - mergeMLMesh.write("merge.med",2) - mergeMLFields.write("merge.med",0) - - -Solution -~~~~~~~~ - -:ref:`python_testMEDLoaderSplitAndMerge1_solution` diff --git a/medtool/doc/tutorial/medloader_SplitAndMerge1_fr.rst b/medtool/doc/tutorial/medloader_SplitAndMerge1_fr.rst deleted file mode 100644 index 181505051..000000000 --- a/medtool/doc/tutorial/medloader_SplitAndMerge1_fr.rst +++ /dev/null @@ -1,220 +0,0 @@ - -Spliter et fusionner un fichier MED grâce à l'API avancée de MEDLoader ----------------------------------------------------------------------- - -Objectif -~~~~~~~~ - -Cet exercise présente un cas complet et avancé d'utilisation de l'API avancée de MEDLoader. -Le but est de créer un maillage multi-type à partir de rien avec 2 champs : - -* un champ aux cellules "CellField" -* un champ aux noeuds "NodeField" - -Nous allons ensuite couper ces champs en deux parties (dans le but d'un traitement en parallèle par un code par exemple) -et aussi montrer comment re-fusionner deux champs à partir de morceaux disjoints. - -Début de l'implémentation -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Créer un unstructured mesh ``m0`` issu d'un maillage structuré (meshDim=2, spaceDim=2) de 30*30. -Chacune des cellules paires du maillage sera *simplexisée* (i.e. coupée en triangle - méthode ``MEDCouplingUMesh.simplexize(0)``) :: - - import MEDLoader as ml - from MEDLoader import MEDLoader - - m0 = ml.MEDCouplingCMesh() - arr = ml.DataArrayDouble(31,1) ; arr.iota(0.) - m0.setCoords(arr,arr) - m0 = m0.buildUnstructured() - m00 = m0[::2] # Extract even cells - m00.simplexize(0) - m01 = m0[1::2] - m0 = ml.MEDCouplingUMesh.MergeUMeshes([m00,m01]) - m0.getCoords()[:] *= 1/15. # Illustrate how to quickly rescale a mesh - m0.setName("mesh") - -.. note:: Le ``setName()`` sur "m0" est obligatoire. Ne pas oublier que dans le contexte MED fichier - le nommage correct des maillages est fondamental. - -Créer les champs ``cellField`` et ``nodeField`` au pas de temps identifié à (5,6) et au pas de temps 5.6 s. :: - - # Cell field - cellField = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) - cellField.setTime(5.6,5,6) - cellField.setMesh(m0) - cellField.setName("CellField") - cellField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") - cellField.getArray().setInfoOnComponent(0,"powercell [W]") - # Node field - nodeField = ml.MEDCouplingFieldDouble(ml.ON_NODES,ml.ONE_TIME) - nodeField.setTime(5.6,5,6) - nodeField.setMesh(m0) - nodeField.setName("NodeField") - nodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") - nodeField.getArray().setInfoOnComponent(0,"powernode [W]") - -On obtient par exemple pour "CellField" ceci : - -.. image:: images/SplitAndMergeCell1.jpg - - -Partitionnement de maillage -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Couper ``m0`` en deux parties distinctes. Les deux parties seront nommées ``proc0`` et ``proc1``. -``proc0`` sera la partie dans la boîte englobante (``MEDCouplingUMesh.getCellsInBoundingBox()``) ``[(0.,0.4),(0.,0.4)]`` -à 1e-10 près. ``proc1`` sera le complémentaire (``DataArrayInt.buildComplement()``). :: - - proc0 = m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) - proc1 = proc0.buildComplement(m0.getNumberOfCells()) - -.. image:: images/SplitAndMerge2.jpg - -Ecriture dans 2 fichiers MED séparés -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -En partant du partitionnement ``proc0`` et ``proc1`` créer 2 fichiers MED appelés "proc0.med" et "proc1.med" : :: - - nodeField0 = nodeField[proc0] ; cellField0 = cellField[proc0] ; cellField0.setMesh(nodeField0.getMesh()) - nodeField1 = nodeField[proc1] ; cellField1 = cellField[proc1] ; cellField1.setMesh(nodeField1.getMesh()) - - proc0_fname = "proc0.med" - MEDLoader.WriteField(proc0_fname, nodeField0, True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc0_fname, cellField0) - - proc1_fname = "proc1.med" - MEDLoader.WriteField(proc1_fname,nodeField1,True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc1_fname,cellField1) - -Lecture et fusion des 2 fichiers MED séparés (non optimal) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Partant de "proc0.med" et de "proc1.med" lire leur "CellField" respectif avec l'API basique, -agréger les deux et mettre le résultat dans ``cellField_read`` : :: - - cellField0_read = MEDLoader.ReadFieldCell("proc0.med","mesh",0,"CellField",5,6) - cellField1_read = MEDLoader.ReadFieldCell("proc1.med","mesh",0,"CellField",5,6) - cellField_read = ml.MEDCouplingFieldDouble.MergeFields([cellField0_read,cellField1_read]) - -.. note:: On peut avoir l'impression que l'information Cell (méthode ``ReadFieldCell``) est répétée de manière abusive - (effectivement le champ "CellField" a été créé aux cellules), - mais ne pas oublier que dans la norme MED fichier rien n'interdit qu'un champ repose sur des cellules mais - aussi simultanément sur des noeuds, ou des points de Gauss ... - -Comparer ``cellField_read`` et ``cellField0``. Problème, à cause de la contrainte sur la numérotation MED fichier, -on a perdu la numérotation initiale. Ou plus exactement il n'y a pas -de moyen standard de retrouver la numérotation originale. Donc un ``MEDCouplingFieldDouble.isEqual()`` -n'est pas suffisant. Utilisons un ``MEDCouplingFieldDouble.substractInPlaceDM()`` -qui opère pour nous une renumérotation suivant une politique particulière (*policy*, voir doc html). -Pour ce faire une copie profonde (*deep copy*) de ``cellField`` vers ``cellFieldCpy`` et opérer sur cette copie -un ``substractInPlaceDM`` (DM pour "Different Meshes", contrairement à ``substract`` qui ne marche que -s'ils partagent le même maillage): :: - - cellFieldCpy = cellField.deepCpy() - cellFieldCpy.substractInPlaceDM(cellField_read,10,1e-12) - cellFieldCpy.getArray().abs() - print cellFieldCpy.getArray().isUniform(0.,1e-12) - -Opérons le même travail sur "NodeField" que celui réalisé plus haut sur "CellField". -La différence ici c'est qu'il va y avoir duplication de l'information à la frontière, car les noeuds limites sont partagés -des deux côtés : :: - - nodeField0_read = MEDLoader.ReadFieldNode("proc0.med","mesh",0,"NodeField",5,6) - nodeField1_read = MEDLoader.ReadFieldNode("proc1.med","mesh",0,"NodeField",5,6) - nodeField_read = ml.MEDCouplingFieldDouble.MergeFields([nodeField0_read, nodeField1_read]) - -.. note:: Dans cette partie, on a donc relu le maillage une deuxième fois ce qui peut être pénalisant ... - -Invoquer ``MEDCouplingUMesh.mergeNodes()`` sur ``nodeField_read`` pour lui retirer les noeuds dupliqués. -Faire une deep copy appelée ``nodeFieldCpy`` de ``nodeField`` -et supprimer encore les doublons : :: - - nodeField_read.mergeNodes(1e-10) - nodeFieldCpy = nodeField.deepCpy() - nodeFieldCpy.mergeNodes(1e-10) - -.. note:: A noter que ``mergeNodes()`` possède deux paramètres de précisions (*epsilons*), le premier, - classique, sur la distance absolue entre les noeuds, et l'autre sur la tolérance acceptée sur les valeurs du champ. - Si la valeur du champ de deux noeuds à fusionner dépasse ce deuxième epsilon, une exception est levée. - -Comparer ``nodeFieldCpy`` et ``nodeField_read`` toujours en utilisant ``MEDCouplingFieldDouble.substractInPlaceDM()`` : :: - - nodeFieldCpy.substractInPlaceDM(nodeField_read,10,1e-12) - print nodeFieldCpy.getArray().isUniform(0.,1e-12) - - -Lecture et merge des 2 fichiers MED séparés (moins facile, mais plus optimal) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Il s'agit ici de faire une méthode plus systématique et potentiellement plus générale de fusion de fichiers. -Pour de gros fichiers cette approche est à préférer. -Outre la performance, cette approche a l'avantage de pouvoir rajouter des infos. - -Avec l'API avancée lire les maillages des deux fichiers "proc0.med" et "proc1.med" et agréger le résultat -dans une instance ``mergeMLMesh`` de ``MEDFileUMesh``. -Traiter tous les niveaux de dimension (même si ici il n'y en a qu'un seul) en utilisant la méthode ``MEDFileUMesh.getNonEmptyLevels()`` -sur l'instance venant de "proc0.med". - -La solution donnée ci-dessous est la plus générique possible, car elle traite aussi les différents pas de temps et les -différents types géométriques : :: - - fileNames = ["proc0.med","proc1.med"] - msML = [ml.MEDFileMesh.New(fname) for fname in fileNames] - fsML = [ml.MEDFileFields.New(fname) for fname in fileNames] - mergeMLMesh = ml.MEDFileUMesh() - mergeMLFields = ml.MEDFileFields() - for lev in msML[0].getNonEmptyLevels(): - o2nML = len(msML[0].getNonEmptyLevels())*[None] - cs = [mML.getCoords() for mML in msML] - mergeMLMesh.setCoords(ml.DataArrayDouble.Aggregate(cs)) - ms = [mML.getMeshAtLevel(lev) for mML in msML] - m = ml.MEDCouplingUMesh.MergeUMeshes(ms) ; m.setCoords(mergeMLMesh.getCoords()) - o2nML[lev] = m.sortCellsInMEDFileFrmt() - mergeMLMesh.setMeshAtLevel(lev,m) - pass - - for fieldName in fsML[0].getFieldsNames(): - fmts = [fML[fieldName] for fML in fsML] - mergeField = ml.MEDFileFieldMultiTS() - for dt,it,tim in fmts[0].getTimeSteps(): - fts = [fmt[dt,it] for fmt in fmts] - arrs = len(fts)*[None] - for typp in fts[0].getTypesOfFieldAvailable(): - arr1s = [] - if typp == ml.ON_CELLS: - for ft in fts: - for geoTyp,smth in ft.getFieldSplitedByType(): - if geoTyp != ml.NORM_ERROR: - smth1 = filter(lambda x:x[0] == ml.ON_CELLS,smth) - arr2s = [ft.getUndergroundDataArray()[elt[1][0]:elt[1][1]] for elt in smth1] - arr1s.append(ml.DataArrayDouble.Aggregate(arr2s)) - pass - pass - pass - pass - else: - for ft in fts: - smth = filter(lambda x:x[0] == ml.NORM_ERROR,ft.getFieldSplitedByType()) - arr2 = ml.DataArrayDouble.Aggregate([ft.getUndergroundDataArray()[elt[1][0][1][0]:elt[1][0][1][1]] for elt in smth]) - arr1s.append(arr2) - pass - pass - arr = ml.DataArrayDouble.Aggregate(arr1s) - if typp == ml.ON_CELLS: - arr.renumberInPlace(o2nML[lev]) - mcf = ml.MEDCouplingFieldDouble(typp,ml.ONE_TIME) ; mcf.setName(fieldName) ; mcf.setTime(tim,dt,it) ; mcf.setArray(arr) - mcf.setMesh(mergeMLMesh.getMeshAtLevel(lev)) ; mcf.checkCoherency() - mergeField.appendFieldNoProfileSBT(mcf) - pass - pass - mergeMLFields.pushField(mergeField) - pass - mergeMLMesh.write("merge.med",2) - mergeMLFields.write("merge.med",0) - - -Solution -~~~~~~~~ - -:ref:`python_testMEDLoaderSplitAndMerge1_solution` diff --git a/medtool/doc/tutorial/medloader_advancedAPI1_en.rst b/medtool/doc/tutorial/medloader_advancedAPI1_en.rst deleted file mode 100644 index 5be2a6e8c..000000000 --- a/medtool/doc/tutorial/medloader_advancedAPI1_en.rst +++ /dev/null @@ -1,151 +0,0 @@ - -Reading, Writing a MED file using MEDLoader's advanced API ----------------------------------------------------------- - -The advanced API is incarnated by the MEDFile* classes in the MEDLoader library. - -* MEDFileMesh, MEDFileUMesh, MEDFileCMesh -* MEDFileMeshes, MEDFileMeshMultiTS -* MEDFileField1TS, MEDFileFieldMultiTS -* MEDFileFields, MEDFileFieldGlobs -* MEDFileData - -Objective -~~~~~~~~~ - -Write a mesh and a field from scratch, re-read them and compare the result. - -Topics covered: - -* Read/Write Mesh using MEDLoader's advanced API -* Read/Write Field using MEDLoader's advanced API - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -To implement this exercise we use the Python scripting language and import the MEDLoader Python module. -The whole MEDCoupling module is fully included in MEDLoader. No need to import MEDCoupling when MEDLoader has been loaded. :: - - from MEDLoader import * - -Writing and Reading meshes using MEDLoader's advanced API -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -First of all, creation of a mesh "targetMesh". :: - - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New("MyMesh",2) - targetMesh.allocateCells(5) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - myCoords=DataArrayDouble.New(targetCoords,9,2) - targetMesh.setCoords(myCoords) - - -.. note:: targetMesh is grouped by geometric type. - -Build "targetMesh1" representing the sub-constituents (faces) of "targetMesh" reduced to cell ids [3,4,7,8]. -:: - - targetMeshConsti=targetMesh.buildDescendingConnectivity()[0] - targetMesh1=targetMeshConsti[[3,4,7,8]] - targetMesh1.setName(targetMesh.getName()) - -.. note:: "targetMesh1" will be recorded as a part of the same global mesh in the MED file, so it must have the same name! - -Then we are ready to write targetMesh and targetMesh1 into TargetMesh2.med. :: - - meshMEDFile=MEDFileUMesh.New() - meshMEDFile.setMeshAtLevel(0,targetMesh) - meshMEDFile.setMeshAtLevel(-1,targetMesh1) - meshMEDFile.write("TargetMesh2.med",2) # 2 stands for write from scratch - -Create 2 groups on level 0. The first called "grp0_Lev0" on cells [0,1,3] and the second called "grp1_Lev0" on cells [1,2,3,4] :: - - grp0_0=DataArrayInt.New([0,1,3]) ; grp0_0.setName("grp0_Lev0") - grp1_0=DataArrayInt.New([1,2,3,4]) ; grp1_0.setName("grp1_Lev0") - meshMEDFile.setGroupsAtLevel(0,[grp0_0,grp1_0]) - -Create 3 groups on level -1. The 1st called "grp0_LevM1" on cells [0,1], the 2nd called "grp1_LevM1" on cells [0,1,2], and the 3rd called "grp2_LevM1" on cells [1,2,3] :: - - grp0_M1=DataArrayInt.New([0,1]) ; grp0_M1.setName("grp0_LevM1") - grp1_M1=DataArrayInt.New([0,1,2]) ; grp1_M1.setName("grp1_LevM1") - grp2_M1=DataArrayInt.New([1,2,3]) ; grp2_M1.setName("grp2_LevM1") - meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) - - -Then trying to read it. :: - - meshMEDFileRead=MEDFileMesh.New("TargetMesh2.med") - meshRead0=meshMEDFileRead.getMeshAtLevel(0) - meshRead1=meshMEDFileRead.getMeshAtLevel(-1) - print "Is the mesh at level 0 read in file equals targetMesh ? %s"%(meshRead0.isEqual(targetMesh,1e-12)) - print "Is the mesh at level -1 read in file equals targetMesh ? %s"%(meshRead1.isEqual(targetMesh1,1e-12)) - -Print available levels for group "grp0_Lev0" :: - - print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") - -Request for cell ids of group "grp0_Lev0" :: - - grp0_0_read=meshMEDFileRead.getGroupArr(0,"grp0_Lev0") - print "Is group \"grp0_Lev0\" are the same ? %s"%(grp0_0_read.isEqual(grp0_0)) - -Writing and Reading fields -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Creation of a simple vector field on cells called f. :: - - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - f.setTime(5.6,7,8) - f.setArray(targetMesh.getBarycenterAndOwner()) - f.setMesh(targetMesh) - f.setName("AFieldName") - -Put f into a MEDFileField1TS for preparation of MED writing :: - - fMEDFile=MEDFileField1TS.New() - fMEDFile.setFieldNoProfileSBT(f) - -Append field to "TargetMesh2.med" :: - - fMEDFile.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to overwrite it - -Read it : :: - - fMEDFileRead=MEDFileField1TS.New("TargetMesh2.med",f.getName(),7,8) - fRead1=fMEDFileRead.getFieldOnMeshAtLevel(ON_CELLS,0,meshMEDFileRead) # fastest method. No reading of the supporting mesh. - fRead2=fMEDFileRead.getFieldAtLevel(ON_CELLS,0) # like above but mesh is re-read from file... - print "Does the field f remain the same using fast method ? %s"%(fRead1.isEqual(f,1e-12,1e-12)) - print "Does the field f remain the same using slow method ? %s"%(fRead2.isEqual(f,1e-12,1e-12)) - -Writing and Reading fields on a "profile" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Build a reduction on cells [1,2,3] of f and call it fPart. :: - - pfl=DataArrayInt.New([1,2,3]) ; pfl.setName("My1stPfl") - fPart=f.buildSubPart(pfl) - fPart.setName("fPart") - -Put it into MEDFileField1TS data structure. :: - - fMEDFile2=MEDFileField1TS.New() - fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) - fMEDFile2.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it - -Read "fPart" field from File "TargetMesh2.med". :: - - fMEDFileRead2=MEDFileField1TS.New("TargetMesh2.med",fPart.getName(),7,8) - fPartRead,pflRead=fMEDFileRead2.getFieldWithProfile(ON_CELLS,0,meshMEDFileRead) - print fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) - print pflRead.isEqualWithoutConsideringStr(pfl) - -Solution -~~~~~~~~ - -:ref:`python_testMEDLoaderAdvancedAPI1_solution` diff --git a/medtool/doc/tutorial/medloader_advancedAPI1_fr.rst b/medtool/doc/tutorial/medloader_advancedAPI1_fr.rst deleted file mode 100644 index cad6678a5..000000000 --- a/medtool/doc/tutorial/medloader_advancedAPI1_fr.rst +++ /dev/null @@ -1,191 +0,0 @@ - -Lecture, écriture d'un fichier MED grâce à l'API avancée de MEDLoader ---------------------------------------------------------------------- - -L'API avancée de MEDLoader est représentée par les classes ``MEDFile*`` de la bibliothèque MEDLoader. - -* Au plus haut niveau, pour l'ensemble du fichier: ``MEDFileData``, -* Pour l'ensemble des maillages du fichier : ``MEDFileMeshes``, -* Pour chacun des maillages : ``MEDFileMeshMultiTS``, ``MEDFileMesh``, ``MEDFileUMesh``, ``MEDFileCMesh``, -* Pour l'ensemble des champs du fichier : ``MEDFileFields``, ``MEDFileFieldGlobs``, -* Et enfin pour chacun des champs : ``MEDFileField1TS``, ``MEDFileFieldMultiTS`` - - -Objectif -~~~~~~~~ - -Ecrire un maillage et un champ à partir de rien, les relire et comparer les résultats. - -Points abordés : en utilisant l'API avancée de MEDLoader, - -* Ecrire un fichier -* Lire un fichier - -Début d'implémentation -~~~~~~~~~~~~~~~~~~~~~~ - -Cet exercice repose comme tous les autres sur le language de script Python. On charge -le module Python ``MEDLoader``. - -Pour information, le module ``MEDCoupling`` complet est inclus dans ``MEDLoader``. Pas besoin de l'importer -si ``MEDLoader`` a été chargé. :: - - import MEDLoader as ml - from MEDLoader import MEDLoader - -Lecture, écriture d'un maillage -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nous créons tout d'abord le même maillage ``targetMesh`` que pour l'API simple. :: - - targetCoords = [-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn = [0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh = ml.MEDCouplingUMesh("MyMesh",2) - targetMesh.allocateCells(5) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[14:18]) - myCoords = ml.DataArrayDouble(targetCoords,9,2) - myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) - targetMesh.setCoords(myCoords) - -.. note:: Le maillage ``targetMesh`` est ordonné par type géométrique. - -Nous construisons ensuite ``targetMesh1`` représentant les sous-constituants (*faces*) du maillage -``targetMesh``, et nous en extrayons seulement les cellules (donc ici des surfaces) [3,4,7,8]. -Pour plus de détails sur la connectivité descendante, -consulter la section :ref:`exo-umesh-desc-connec` du deuxième exercise. -Cet ensemble peut par exemple représenter un ensemble d'intérêt pour un calcul : :: - - targetMeshConsti, _, _, _, _ = targetMesh.buildDescendingConnectivity() - targetMesh1 = targetMeshConsti[[3,4,7,8]] - targetMesh1.setName(targetMesh.getName()) - -.. note:: En Python, le underscore ``_`` signifie que l'on attend une valeur de retour, mais qu'on n'en aura pas l'usage - (on ne la *bind* pas). -.. note:: ``targetMesh1`` sera sauvé comme étant une partie du même maillage global dans le fichier MED. - Il doit donc avoir le même nom. C'est là qu'on voit qu'un maillage au sens MED fichier peut mélanger les dimensions. - -On peut alors écrire les deux maillages dans le fichier "TargetMesh2.med". :: - - meshMEDFile = ml.MEDFileUMesh() - meshMEDFile.setMeshAtLevel(0,targetMesh) - meshMEDFile.setMeshAtLevel(-1,targetMesh1) - meshMEDFile.write("TargetMesh2.med",2) # 2 stands for 'write from scratch' - -Lecture, écriture de groupes de mailles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Créons deux groupes de cellules sur le maillage 2D, c'est à dire au niveau relatif 0 (ici, le niveau relatif 0 correspond -à la 2D, le niveau -1 -correspond à la 1D, etc ...). Le premier groupe ``grp0_Lev0`` contient les cellules [0,1,3] -le second ``grp1_Lev0`` les cellules [1,2,3,4] : :: - - grp0_0 = ml.DataArrayInt([0,1,3]) - grp0_0.setName("grp0_Lev0") - grp1_0 = ml.DataArrayInt([1,2,3,4]) - grp1_0.setName("grp1_Lev0") - meshMEDFile.setGroupsAtLevel(0, [grp0_0,grp1_0]) - -.. note:: On voit évidemment ici l'importance de nommer les tableaux : c'est le nom qui sera utilisé pour le groupe. - -Créons trois groupes de niveau -1, c'est à dire des groupes de faces. Le premier appelé -``grp0_LevM1`` aux cellules [0,1], le second appelé ``grp1_LevM1`` aux cellules [0,1,2], et le 3ème ``grp2_LevM1`` -aux cellules [1,2,3] : :: - - grp0_M1 = ml.DataArrayInt([0,1]) - grp0_M1.setName("grp0_LevM1") - grp1_M1 = ml.DataArrayInt([0,1,2]) - grp1_M1.setName("grp1_LevM1") - grp2_M1 = ml.DataArrayInt([1,2,3]) - grp2_M1.setName("grp2_LevM1") - meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) - -Ecrivons le tout : :: - - meshMEDFile.write("TargetMesh2.med",2) # 2 stands for 'write from scratch' - -Nous pouvons ensuite re-lire le fichier MED : :: - - meshMEDFileRead = ml.MEDFileMesh.New("TargetMesh2.med") # a new is needed because it returns a MEDFileUMesh (MEDFileMesh is abstract) - meshRead0 = meshMEDFileRead.getMeshAtLevel(0) - meshRead1 = meshMEDFileRead.getMeshAtLevel(-1) - print "Is level 0 in the file equal to 'targetMesh'?", meshRead0.isEqual(targetMesh,1e-12) - print "Is level 0 in the file equal to 'targetMesh1'?", meshRead1.isEqual(targetMesh1,1e-12) - -Affichons les niveaux disponibles pour le groupe ``grp0_Lev0`` : :: - - print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") - -Et récupérons enfin les identifiants de cellules contenus dans le groupe ``grp0_Lev0`` : :: - - grp0_0_read = meshMEDFileRead.getGroupArr(0,"grp0_Lev0") - print "Is group 'grp0_Lev0' equal to what is read in the file?" , grp0_0_read.isEqual(grp0_0) - -Lire/écrire des champs avec l'API avancée -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Créons un champ de vecteurs simple, aux cellules (P0), avec un seul pas de temps, appelé ``f``. :: - - f = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) - f.setTime(5.6,7,8) - f.setArray(targetMesh.getBarycenterAndOwner()) - f.setMesh(targetMesh) - f.setName("AFieldName") - -Stocker ``f`` dans un object ``MEDFileField1TS`` (un champ avec un seul pas de temps -- *one time-step, 1TS*) -pour préparer l'écriture MED :: - - fMEDFile = ml.MEDFileField1TS() - fMEDFile.setFieldNoProfileSBT(f) # No profile desired on the field, Sort By Type - -Ajouter le champ au fichier "TargetMesh2.med" :: - - fMEDFile.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file - -.. note:: Noter l'utilisation du 0 pour indiquer que nous désirons ajouter au fichier existant. - -Lire le champ : :: - - fMEDFileRead = ml.MEDFileField1TS("TargetMesh2.med",f.getName(),7,8) - fRead1 = fMEDFileRead.getFieldOnMeshAtLevel(ml.ON_CELLS,0,meshMEDFileRead) # Quickest way, not re-reading mesh in the file. - fRead2 = fMEDFileRead.getFieldAtLevel(ml.ON_CELLS,0) # Like above, but this time the mesh is read! - print "Does the field remain OK with the quick method?", fRead1.isEqual(f,1e-12,1e-12) - print "Does the field remain OK with the slow method?", fRead2.isEqual(f,1e-12,1e-12) - -Lire/écrire un champ sur un "profil" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nous allons maintenant voir un concept avancé des fichiers MED, à savoir la possibilité d'écrire un champ sur seulement -une *partie* du maillage. La technique habituellement utilisée est plutôt de mettre des valeurs particulières (e.g. +infinity -soit 1e+300) sur les zones où le champ n'a pas de sens, permettant ainsi de repérer en plus des bugs éventuels lors du calcul. - -Le mode de fonctionnement avec les profils reste donc peu courant. - -Construisons une réduction aux cellules [1,2,3] de ``f`` et appelons la ``fPart`` : :: - - pfl = ml.DataArrayInt([1,2,3]) - pfl.setName("My1stPfl") - fPart = f.buildSubPart(pfl) - fPart.setName("fPart") - -La stocker dans la structure ``MEDFileField1TS`` et invoquer ``setFieldProfile()``. :: - - fMEDFile2 = ml.MEDFileField1TS() - fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) # 0 is the relative level (here 0 means 2D) - fMEDFile2.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file - -Lire le champ ``fPart`` du fichier "TargetMesh2.med" et les identifiants de cellules correspondant. :: - - fMEDFileRead2 = ml.MEDFileField1TS("TargetMesh2.med",fPart.getName(),7,8) - fPartRead, pflRead = fMEDFileRead2.getFieldWithProfile(ml.ON_CELLS,0,meshMEDFileRead) - print "Is the partial field correclty read?", fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) - print "Is the list of cell identifiers matching?", pflRead.isEqualWithoutConsideringStr(pfl) - -Solution -~~~~~~~~ - -:ref:`python_testMEDLoaderAdvancedAPI1_solution` - diff --git a/medtool/doc/tutorial/medloader_basicAPI1_en.rst b/medtool/doc/tutorial/medloader_basicAPI1_en.rst deleted file mode 100644 index e20241881..000000000 --- a/medtool/doc/tutorial/medloader_basicAPI1_en.rst +++ /dev/null @@ -1,97 +0,0 @@ - -Reading, Writing a MED file using MEDLoader's basic API -------------------------------------------------------- - -The basic API is incarnated by the MEDLoader class. -All methods in that class are static. -The sessions of read/write are done on each call of a method. - -Objective -~~~~~~~~~ - -Write a mesh and a field from scratch, re-read them and compare the result. - -Topics covered: -* Write using MEDLoader's basic API -* Read using MEDLoader's basic API - -Implementation start -~~~~~~~~~~~~~~~~~~~~ - -To implement this exercise we use the Python scripting language and import the MEDLoader Python module. -The whole MEDCoupling module is fully included in MEDLoader. No need to import MEDCoupling when MEDLoader has been loaded. :: - - from MEDLoader import * - -Writing/Reading a mesh -~~~~~~~~~~~~~~~~~~~~~~ - -First of all, creation of a mesh "targetMesh". :: - - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New("MyMesh",2) - targetMesh.allocateCells(5) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - myCoords=DataArrayDouble.New(targetCoords,9,2) - myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) - targetMesh.setCoords(myCoords) - -.. note:: targetMesh is ordered by geometric type. - -We are then ready to write it. :: - - MEDLoader.WriteUMesh("TargetMesh.med",targetMesh,True) - -Then trying to read it. :: - - meshRead=MEDLoader.ReadUMeshFromFile("TargetMesh.med",targetMesh.getName(),0) - print "Is the mesh read in file equals targetMesh? %s"%(meshRead.isEqual(targetMesh,1e-12)) - -Writing/Reading a field on one time step at once -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Creation of a vector field "f" on cell supported by "targetMesh". :: - - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - f.setTime(5.6,7,8) - f.setArray(targetMesh.getBarycenterAndOwner()) - f.setMesh(targetMesh) - f.setName("AFieldName") - MEDLoader.WriteField("MyFirstField.med",f,True) - -.. note:: Mesh AND Field is written at once into MyFirstField. - -Reading into MyFirstField.med :: - - f2=MEDLoader.ReadFieldCell("MyFirstField.med",f.getMesh().getName(),0,f.getName(),7,8) - print "Is the field read in file equals f ? %s"%(f2.isEqual(f,1e-12,1e-12)) - -Writing/Reading a field on one or many times steps in "multi-session mode" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Here contrary to the previous steps, we are going to write in a multi-session mode on the same MED file. -First dealing with the mesh. :: - - MEDLoader.WriteUMesh("MySecondField.med",f.getMesh(),True) - -Then writing only array part of field. :: - - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f) - -Then put a another time step. :: - - f2=f.clone(True) - f2.getArray()[:]=2.0 - f2.setTime(7.8,9,10) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f2) - -Now "MySecondField.med" file contains 2 time steps. - -Solution -~~~~~~~~ - -:ref:`python_testMEDLoaderBasicAPI1_solution` diff --git a/medtool/doc/tutorial/medloader_basicAPI1_fr.rst b/medtool/doc/tutorial/medloader_basicAPI1_fr.rst deleted file mode 100644 index d542c0dc3..000000000 --- a/medtool/doc/tutorial/medloader_basicAPI1_fr.rst +++ /dev/null @@ -1,128 +0,0 @@ - -Lecture, écriture d'un fichier MED grâce à l'API basique de MEDLoader ---------------------------------------------------------------------- - -L'API basique de MEDLoader est contenue dans la classe ``MEDLoader``. -Toutes les méthodes de cette classe sont *statiques* (elles ne dépendent pas d'une instance particulière de la -classe), leurs noms commencent par une majuscule. -L'ensemble des lectures/écritures sont exécutées à chaque appel de méthode et aucun état interne à la classe n'est -enregistré. - -Objectif -~~~~~~~~ - -Ecrire un maillage et un champ à partir de rien, les relire et comparer les résultats. - -Points abordés: en utilisant l'API basique de ``MEDLoader`` - -* Ecrire un fichier -* Lire un fichier - -Début d'implémentation -~~~~~~~~~~~~~~~~~~~~~~ - -Cet exercice repose comme tous les autres sur le language de script Python. On charge -le module Python ``MEDLoader``. - -Pour information, le module ``MEDCoupling`` complet est inclus dans ``MEDLoader``. Pas besoin de l'importer -si ``MEDLoader`` a été chargé. :: - - import MEDLoader as ml - from MEDLoader import MEDLoader - -Lecture, écriture d'un maillage -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Tout d'abord créons un maillage ``targetMesh`` composé de plusieurs types géométriques. :: - - targetCoords = [-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn = [0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh = ml.MEDCouplingUMesh("MyMesh",2) - targetMesh.allocateCells(5) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[14:18]) - myCoords = ml.DataArrayDouble(targetCoords,9,2) - myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) - targetMesh.setCoords(myCoords) - -.. note:: Le maillage ``targetMesh`` est ordonné par type géométrique. - -Le maillage peut alors directement être écrit ... :: - - MEDLoader.WriteUMesh("TargetMesh.med",targetMesh,True) # True means 'from scratch' - -... et relu. :: - - meshRead = MEDLoader.ReadUMeshFromFile("TargetMesh.med",targetMesh.getName(),0) - print "Is the read mesh equal to 'targetMesh' ?", meshRead.isEqual(targetMesh,1e-12) - -Lire/Ecrire un champ sur un pas de temps -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nous créons maintenant un champ de vecteurs ``f`` aux cellules (P0) avec ``targetMesh`` comme support. -Ce champ correspond par exemple au temps physique 5.6, repéré par l'itération 7 et la sous-itération 8. -Nous en profitons pour rappeler -que dans les champs MEDCoupling, le temps physique est donné pour information seulement, le stockage et la plupart des -fonctions de l'API se basent sur les deux derniers entiers. :: - - f = ml.MEDCouplingFieldDouble.New(ml.ON_CELLS, ml.ONE_TIME) - f.setTime(5.6,7,8) # Declare the timestep associated to the field - f.setArray(targetMesh.getBarycenterAndOwner()) - f.setMesh(targetMesh) - f.setName("AFieldName") - MEDLoader.WriteField("MyFirstField.med",f,True) - -Question subsidiaire : à quoi correspond le champ ainsi créé ? - -.. note:: Le maillage **et** le champ sont écrits d'un seul coup dans le fichier "MyFirstField.med". - -Nous relisons ensuite MyFirstField.med : :: - - f2 = MEDLoader.ReadFieldCell("MyFirstField.med", f.getMesh().getName(), 0, f.getName(), 7, 8) - print "Is the read field identical to 'f' ?", f2.isEqual(f,1e-12,1e-12) - -.. note:: Lors de la lecture du champ, on doit donc connaître: son nom, le nom de sa mesh de support - et le pas de temps voulu. Des fonctions du type ``MEDFileFields.getFieldsNames()`` ou encore - ``MEDFileMeshes.getMeshesNames()`` aident à cela. - -.. note:: Le nom ``ReadFieldCell()`` rappelle que le champ doit être lu aux cellules. Souvenez-vous que suivant la - norme MED fichier, un même champ peut avoir une partie de ses données stockées aux cellules, mais aussi - simultanément aux noeuds, aux points de Gauss, etc ... même si ce genre de mélange exotique n'est généralement - pas conseillé. - -Lire/Ecrire un champ sur plusieurs pas de temps -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Ici contrairement au cas précédent, nous écrivons en plusieurs fois dans le *même* fichier MED. -Ecrivons tout d'abord le maillage. :: - - MEDLoader.WriteUMesh("MySecondField.med",f.getMesh(),True) - -Ensuite, nous écrivons seulement les informations relatives au champ (principalement son tableau de valeurs en fait -). :: - - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f) # mesh is not re-written - -Nous rajoutons ensuite un second pas de temps sur le *même* maillage. :: - - f2 = f.clone(True) # 'True' means that we need a deep copy - f2.getArray()[:] = 2.0 - f2.setTime(7.8,9,10) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f2) - -Maintenant le fichier "MySecondField.med" contient le maillage et un champ à deux pas de temps porté par ce maillage. - -Nous pouvons relire tout cela avec des méthodes similaires à ce qui a été vu précédemment : :: - - f3 = MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),7,8) - print "Is the field read in file equals to 'f' ?", f.isEqual(f3,1e-12,1e-12) - f4 = MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),9,10) - print "Is the field read in file equals to 'f2' ?", f2.isEqual(f4,1e-12,1e-12) - -Solution -~~~~~~~~ - -:ref:`python_testMEDLoaderBasicAPI1_solution` diff --git a/medtool/doc/tutorial/medloader_en.rst b/medtool/doc/tutorial/medloader_en.rst deleted file mode 100644 index 19c328ba2..000000000 --- a/medtool/doc/tutorial/medloader_en.rst +++ /dev/null @@ -1,23 +0,0 @@ - -Reading, Writing a MED file using the MEDLoader library -======================================================= - -The objective of these exercises is to see how to read and write a MED file. - * Usage of MEDLoader's basic API - - * Meshes - * Fields - - * Usage of MEDLoader's advanced API - - * Meshes - * Fields - - * An Example of classical manipulation of MED files: splitting a MED file / merge a MED file - -.. toctree:: - :maxdepth: 2 - - medloader_basicAPI1_en - medloader_advancedAPI1_en - medloader_SplitAndMerge1_en diff --git a/medtool/doc/tutorial/medloader_fr.rst b/medtool/doc/tutorial/medloader_fr.rst deleted file mode 100644 index af19266d1..000000000 --- a/medtool/doc/tutorial/medloader_fr.rst +++ /dev/null @@ -1,23 +0,0 @@ - -MEDLoader : lecture, écriture d'un fichier MED -============================================== - -L'objectif de ces exercices est de comprendre comment lire et écrire un fichier MED. - * Utilisation basique de l'API MEDLoader - - * Maillages - * Champs - - * Utilisation avancée de l'API MEDLoader - - * Maillages - * Champs - - * Exemple de manipulation classique de fichiers MED : splitter / fusionner un fichier MED suivant plusieurs sous-domaines - -.. toctree:: - :maxdepth: 2 - - medloader_basicAPI1_fr - medloader_advancedAPI1_fr - medloader_SplitAndMerge1_fr diff --git a/medtool/doc/user/CMakeLists.txt b/medtool/doc/user/CMakeLists.txt deleted file mode 100644 index 951bc1bdd..000000000 --- a/medtool/doc/user/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_SUBDIRECTORY(doxygen) diff --git a/medtool/doc/user/doxygen/BuildPyExamplesFromCPP.py b/medtool/doc/user/doxygen/BuildPyExamplesFromCPP.py deleted file mode 100644 index a7fd08c53..000000000 --- a/medtool/doc/user/doxygen/BuildPyExamplesFromCPP.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -import sys -import re -import os - -# :TRICKY: -# In input file, contents delimited by two lines containing BEGIN_CPP_ONLY and -# END_CPP_ONLY strings respectively, will only appear in C++ documentation. -# The same rule applies for Python-specific contents. - -def Cpp2Python(contents): - cpp_only = False - output = [] - for st in contents: - if "BEGIN_CPP_ONLY" in st: - cpp_only = True - elif "END_CPP_ONLY" in st: - cpp_only = False - elif not cpp_only: - st=st.replace("C++","Python") - st=st.replace("Cxx","Py") - st=st.replace("Cpp","Py") - st=st.replace("cxx","py") - st=st.replace("cpp","py") - output.append(st) - pass - pass - - return output -# -def discardPythonFrom(contents): - python_only = False - output = [] - for st in contents: - if "BEGIN_PYTHON_ONLY" in st: - python_only = True - elif "END_PYTHON_ONLY" in st: - python_only = False - elif not python_only: - output.append(st) - pass - pass - - return output - # -# - -# Usage: BuildPyExamplesFromCPP.py - -fCpp=file(sys.argv[1],"r") -cppCont=fCpp.readlines() ; del fCpp -pyCont=cppCont[:] -pyCont=[elt.replace("medcouplingcppexamples","medcouplingpyexamples") for elt in pyCont] -pyCont=Cpp2Python(pyCont) - -s= "Be sure to take a look at the page \\ref python-api before proceeding." -pyCont.insert(2, s) -cppCont=discardPythonFrom(cppCont) # remove Python-only contents from Cpp - -# Save CPP and PY examples in two separate dox files -outFileName=os.path.join(sys.argv[2],os.path.basename(sys.argv[1])) - -f=file(os.path.splitext(outFileName)[0]+"CPP.dox","w") -f.writelines(cppCont) ; del f - -f=file(os.path.splitext(outFileName)[0]+"PY.dox","w") -f.writelines(pyCont) ; del f diff --git a/medtool/doc/user/doxygen/CMakeLists.txt b/medtool/doc/user/doxygen/CMakeLists.txt deleted file mode 100644 index 39e6aecb5..000000000 --- a/medtool/doc/user/doxygen/CMakeLists.txt +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_med_user.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_med_user) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/static/header.html.in ${CMAKE_CURRENT_BINARY_DIR}/static/header.html) - -IF(MEDCOUPLING_MED_ENABLE_PYTHON) - INCLUDE(doxy2swig/doxy2swig.cmake) - - FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/tmp/medcouplingexamples.in" input) - FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/BuildPyExamplesFromCPP.py" pythondocexamplesgenerator) - FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" output) - - # :TRICKY: For ease of maintenance, documentation for code examples is - # splitted in several files. We here splice to a single file before running - # Doxygen. - - SET(EXAMPLE_FILES # files to concatenate: order is important! - doxfiles/examples/medcouplingexamplesheader.doxy - doxfiles/examples/medcouplingexamplesfields.doxy - doxfiles/examples/medcouplingexamplesmeshes.doxy - doxfiles/examples/medcouplingexamplesarrays.doxy - doxfiles/examples/medcouplingexamplesother.doxy - doxfiles/examples/medcouplingexamplesfooter.doxy - ) - - # This function adds IN_FILE contents to the end of OUT_FILE - FUNCTION(concat IN_FILE OUT_FILE) - FILE(READ ${IN_FILE} CONTENTS) - FILE(APPEND ${OUT_FILE} ${CONTENTS}) - ENDFUNCTION() - - # Prepare a temporary file to "concat" to: - FILE(WRITE ${input} "") - # Call the "concat" function for each example file - FOREACH(EXAMPLE_FILE ${EXAMPLE_FILES}) - concat(${EXAMPLE_FILE} ${input}) - ENDFOREACH() - # Note: The reason for writing to a temporary is so the real target file only - # gets updated if its content has changed. - - # Here is the "standard" procedure, as if ${input} was hand-written. - ADD_CUSTOM_TARGET(usr_docs ALL - COMMAND ${PYTHON_EXECUTABLE} ${pythondocexamplesgenerator} ${input} ${output} - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile_med_user - VERBATIM - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - - # Create dummy target gathering the generation of all .i files: - ADD_CUSTOM_TARGET(swig_ready) - ADD_DEPENDENCIES(swig_ready usr_docs) - - MEDCOUPLING_MED_SWIG_DOCSTRING_CONFIGURE(usr_docs swig_ready MEDCoupling) - MEDCOUPLING_MED_SWIG_DOCSTRING_CONFIGURE(usr_docs swig_ready MEDLoader) - - SET(doxyfile_med_user ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_med_user) - FILE(STRINGS ${doxyfile_med_user} enabled_sections REGEX "ENABLED_SECTIONS") - IF(enabled_sections) - FILE(READ ${doxyfile_med_user} doxy_file) - STRING(REPLACE ${enabled_sections} "${enabled_sections} ENABLE_EXAMPLES" new_doxy_file ${doxy_file}) - FILE(WRITE ${doxyfile_med_user} ${new_doxy_file}) - ELSE() - FILE(APPEND ${doxyfile_med_user} - "#Temporary variable to enable python documentation sections\nENABLED_SECTIONS = ENABLE_EXAMPLES") - ENDIF() - - # Swig generation to have docstrings correctly populated: - INCLUDE(doxy2swig/doxy2swig.cmake) - -ELSE() - ADD_CUSTOM_TARGET(usr_docs ALL - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile_med_user - VERBATIM - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) -ENDIF() - -#INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_docs)") -INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc_ref_user/html/ DESTINATION ${MEDCOUPLING_INSTALL_DOC}/gui/MED) -INSTALL(FILES images/head.png DESTINATION ${MEDCOUPLING_INSTALL_DOC}/gui/MED) - -SET(MAKE_CLEAN_FILES doc_ref_user tmp) -SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MAKE_CLEAN_FILES}") diff --git a/medtool/doc/user/doxygen/Doxyfile_med_user.in b/medtool/doc/user/doxygen/Doxyfile_med_user.in deleted file mode 100644 index 4d56fe163..000000000 --- a/medtool/doc/user/doxygen/Doxyfile_med_user.in +++ /dev/null @@ -1,286 +0,0 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# Doxyfile 0.1 -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- -# -PROJECT_NAME = "MEDCoupling Users' Guide" -PROJECT_NUMBER = -OUTPUT_DIRECTORY = doc_ref_user -OUTPUT_LANGUAGE = English -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -HIDE_UNDOC_MEMBERS = YES -HIDE_UNDOC_CLASSES = YES -BRIEF_MEMBER_DESC = NO -REPEAT_BRIEF = YES -ALWAYS_DETAILED_SEC = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -INTERNAL_DOCS = NO -STRIP_CODE_COMMENTS = YES -CASE_SENSE_NAMES = YES -SHORT_NAMES = NO -HIDE_SCOPE_NAMES = NO -VERBATIM_HEADERS = NO -SHOW_INCLUDE_FILES = NO -JAVADOC_AUTOBRIEF = NO -INHERIT_DOCS = YES -MARKDOWN_SUPPORT = YES -INLINE_INFO = NO -SORT_MEMBER_DOCS = NO -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 8 -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -ALIASES = -ENABLED_SECTIONS = user MEDCOUPLING_ug -MAX_INITIALIZER_LINES = 30 -OPTIMIZE_OUTPUT_FOR_C = NO -SHOW_USED_FILES = NO -SORT_BRIEF_DOCS = YES -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = log_user -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/index.dox \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/faq.dox \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/start \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/tutorial.dox \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/gui.dox \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/arrays \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/meshes \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/fields \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/medloader \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/interpolation \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/cpp \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/distrib \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/reference/misc \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/examples/examples.dox \ - @CMAKE_CURRENT_BINARY_DIR@/medcouplingexamplesPY.dox \ - @CMAKE_CURRENT_BINARY_DIR@/medcouplingexamplesCPP.dox \ - @CMAKE_CURRENT_SOURCE_DIR@/doxfiles/appendix \ - @CMAKE_CURRENT_SOURCE_DIR@/fakesources \ - @PROJECT_SOURCE_DIR@/src/ParaMEDMEM \ - @PROJECT_SOURCE_DIR@/src/INTERP_KERNEL \ - @PROJECT_SOURCE_DIR@/src/INTERP_KERNEL/Bases \ - @PROJECT_SOURCE_DIR@/src/INTERP_KERNEL/Geometric2D \ - @PROJECT_SOURCE_DIR@/src/MEDCoupling \ - @PROJECT_SOURCE_DIR@/src/MEDLoader \ - @PROJECT_SOURCE_DIR@/src/MEDCouplingCorba - -FILE_PATTERNS = InterpKernelDEC.* \ - OverlapDEC.* \ - DEC.* \ - DECOptions.* \ - DisjointDEC.* \ - *Topology.* \ - MPIProcessorGroup.* \ - ProcessorGroup.* \ - MPIAccess.* \ - StructuredCoincidentDEC.* \ - ExplicitCoincidentDEC.* \ - NonCoincidentDEC.* \ - CommInterface.* \ - ICoCo*.* \ - NormalizedGeometricTypes \ - NormalizedUnstructuredMesh.* \ - Interpolation2D.* \ - Interpolation3D.* \ - Interpolation3DSurf.* \ - InterpolationMatrix.* \ - PlanarIntersector.* \ - TargetIntersector.* \ - Interpolation.* \ - InterpolationOptions.* \ - InterpKernelGeo2DAbstractEdge.* \ - InterpKernelGeo2DEdge.* \ - InterpKernelGeo2DEdgeArcCircle.* \ - InterpKernelGeo2DEdgeLin.* \ - InterpKernelGeo2DComposedEdge.* \ - InterpKernelGeo2DElementaryEdge.* \ - InterpKernelGeo2DNode.* \ - InterpKernelGeo2DQuadraticPolygon.* \ - ParaFIELD.* \ - ParaMESH.* \ - MEDCouplingMesh.* \ - MEDCouplingUMesh.* \ - MEDCoupling1GTUMesh.* \ - MEDCouplingPointSet.* \ - MEDCouplingCMesh.* \ - MEDCouplingIMesh.* \ - MEDCouplingStructuredMesh.* \ - MEDCouplingCurveLinearMesh.* \ - MEDCouplingExtrudedMesh.* \ - MEDCouplingFieldDouble.* \ - MEDCouplingField.* \ - MEDCouplingNatureOfFieldEnum \ - MEDCouplingNatureOfField.hxx \ - MEDCouplingFieldTemplate.* \ - MEDCouplingFieldDiscretization.* \ - MEDCouplingTimeDiscretization.* \ - MEDCouplingAMRAttribute.* \ - MEDCouplingCartesianAMRMesh.* \ - MEDCouplingTimeLabel.* \ - MEDCouplingRefCountObject.* \ - MEDCouplingAutoRefCountObjectPtr.* \ - MEDCouplingMemArray.* \ - MEDCouplingGaussLocalization.* \ - MEDCouplingRemapper.* \ - MEDLoader.* \ - MEDFileData.* \ - MEDFileParameter.* \ - MEDFileMesh.* \ - MEDFileField.* \ - *Servant.* \ - *.dox -RECURSIVE = YES -EXCLUDE = CVS -EXCLUDE_PATTERNS = *~ -EXAMPLE_PATH = @PROJECT_SOURCE_DIR@/src/ParaMEDMEM \ - @PROJECT_SOURCE_DIR@/src/MEDCoupling/Test \ - @PROJECT_SOURCE_DIR@/src/MEDCoupling_Swig \ - @PROJECT_SOURCE_DIR@/src/MEDLoader/Swig -EXAMPLE_PATTERNS = *.cxx *.py -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/figures -INPUT_FILTER = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_HEADER = @CMAKE_CURRENT_BINARY_DIR@/static/header.html -HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/static/footer.html -HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/static/medcoupling_extra.css -GENERATE_HTMLHELP = NO -GENERATE_CHI = YES -BINARY_TOC = NO -TOC_EXPAND = YES -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -#SORT related options -#--------------------------------------------------------------------------- -SORT_GROUP_NAMES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = YES -LATEX_OUTPUT = latex -COMPACT_LATEX = YES -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = YES -XML_OUTPUT = xml -XML_PROGRAMLISTING = NO -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = YES -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = MEDCOUPLING_EXPORT MEDCOUPLINGREMAPPER_EXPORT MEDLOADER_EXPORT -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -TEMPLATE_RELATIONS = YES -HIDE_UNDOC_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DOT_PATH = -DOT_FONTNAME = Arial -DOTFILE_DIRS = -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/medtool/doc/user/doxygen/doxfiles/appendix/appendix.dox b/medtool/doc/user/doxygen/doxfiles/appendix/appendix.dox deleted file mode 100644 index b00011ba4..000000000 --- a/medtool/doc/user/doxygen/doxfiles/appendix/appendix.dox +++ /dev/null @@ -1,17 +0,0 @@ -/*! - -\page appendix Appendix - -Some useful complementary resources: - -- \subpage glossary -- \subpage med-file -- \subpage install -- \subpage references - -Implementation details: - -- \subpage interpkernel -- \ref MPIAccess-det - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/appendix/glossary.dox b/medtool/doc/user/doxygen/doxfiles/appendix/glossary.dox deleted file mode 100644 index a4b844b25..000000000 --- a/medtool/doc/user/doxygen/doxfiles/appendix/glossary.dox +++ /dev/null @@ -1,35 +0,0 @@ -/*! -\page glossary Glossary, concepts and definitions - -- \b Mesh: representation of a domain by a set of \b cells and \b nodes. Cells and nodes are named \b entities. There is no notion of edges or faces. -- The \b dimension \b of \b a \b mesh is characterized by two parameters: the size of the space wherein the mesh is immersed, and the (maximum) size of the mesh cells. -Examples: 3D surface mesh (3D space, 2D cells), 3D mesh (3D space, 3D cells), curved 2D mesh (2D space, 1D cells)... - -- \b Field: physical quantity whose value varies in space and time. Represented by a result vector V obtained from one or more tables of values ​​A, at any point of space covered by a mesh and in time defined by its temporal resolution. The size of V is called the number of \b components (equal to the number of components of A). -A P1 field is a field where values are stored at node level, a P0 field is a field where values are stored -at cell level. -- \b Intensive \b field: represents intensive physical data (i.e. which do not depend on the amount of material). -Examples: density, power density, temperature, pressure. -- \b Extensive \b field: represents extensive physical data (i.e. proportional to the size of the physical system represented). -Examples: mass, volume, time, power. -- The \b mesh \b support identifies both the mesh and the entity on which it is defined. - -- \b Family: partition of a mesh (nodes and cells with the same identifier). Every node or cell can only belong to one family, i.e. the intersection of two families is zero. -- \b Group: a set of families; two groups may share elements. -- \b Profile: subset of the entities of a mesh. -- \b Field \b profile: indicates on which mesh entities field values are located (a field being defined on a part of a mesh). - -- The \b connectivity of a mesh represents the kind of connections between its vertices. -- The \b nodal \b connectivity is the description of a mesh entity by the ordered list of its nodes. -- The \b descending \b connectivity is the description of N-dimensional mesh entities by the ordered list of (N-1)-dimensional geometrical entities. - -- \b Intersector: algorithm that calculates the intersection of two cells from their position and geometry. -- \b Maximum \b principle: a property of solutions to certain partial differential equations, of the elliptic and parabolic types; it says that the maximum of a function in a domain is to be found on the boundary of that domain. -- \b Conservativity: preservation of conservation laws governing physical quantities during their discretization or their interpolation. -- \b Projection: modification (by interpolation) of the entity on which a field is defined. The projection is called \b conservative if the interpolation uses intersection detection. The projection is said \b not \b conservative if the interpolation localizes a cloud of points in a mesh. -- The \b Gauss \b integration \b points are the geometrical points where the numerical integration of a given quantity is performed. Precise location of these nodes and a sufficient number (related to the approximation order of the integration term) allow for an exact integration in the case of polynomial functions integration. -- \b Kriging: a linear estimation method guaranteeing minimum variance. The estimate at a given point P is obtained locally from the point values ​​on a neighbourhood of P. -- \b Code \b coupling: run of two numerical codes (or two instances of the same code) in such a way that information -is passed from one instance to the other. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/appendix/install.dox b/medtool/doc/user/doxygen/doxfiles/appendix/install.dox deleted file mode 100644 index eb89c9646..000000000 --- a/medtool/doc/user/doxygen/doxfiles/appendix/install.dox +++ /dev/null @@ -1,42 +0,0 @@ -/*! -\page install Configuring and Installing MED from sources - -The install procedure of %MEDCoupling can handle a variety of configurations -to suit the needs of its user. Instructions for configuring and -installing the module can be found here. -Partitioning and parallel functionalities are optional. - -Assume that the library sources are located in \a MEDCOUPLING_SRC directory. Build and install directories are MEDCOUPLING_BUILD and MEDCOUPLING_INSTALL, respectively. -The first step consists in preparing the CMake build precedure : -\verbatim -mkdir -cd -cmake -DCMAKE_BUILD_TYPE= -DCMAKE_INSTALL_PREFIX= -\endverbatim - -, where is build mode (Release or Debug). - -This will configure the library without splitting functionalities. The \ref parallel "parallel functionalities" will be compiled if an MPI version has been found. - -The following options can be useful to configure MEDCoupling : -- \a -DMEDCOUPLING_MED_PARTITIONER_METIS=ON enables metis graph library in MEDPartitioner, -- \a -DMEDCOUPLING_MED_PARTITIONER_PARMETIS=ON enables parmetis graph library in MEDPartitioner, -- \a -DMEDCOUPLING_MED_PARTITIONER_SCOTCH=ON enables scotch graph library in MEDPartitioner, -- \a -DMEDCOUPLING_MED_MICROMED=ON build MED with MED file dependancy, -- \a -DMEDCOUPLING_MED_ENABLE_PYTHON=ON builds PYTHON bindings, -- \a -DMEDCOUPLING_MED_ENABLE_PARTITIONER builds MEDPartitioner, -- \a -DMEDCOUPLING_MED_ENABLE_RENUMBER builds Renumber, -- \a -DMEDCOUPLING_USE_MPI=ON uses MPI containers. - -According to set options and compilation environment, user may need to define some _ROOT_DIR variables. For example if in SALOME environment: -\verbatim -export MEDFILE_ROOT_DIR=${MED3HOME} -export METIS_ROOT_DIR=$METISDIR -export SCOTCH_ROOT_DIR=$SCOTCHDIR -export BOOST_ROOT_DIR=$BOOST_ROOT -export GRAPHVIZ_ROOT_DIR=$GRAPHVIZHOME -export CPPUNIT_ROOT_DIR=$CPPUNIT_ROOT -\endverbatim - -If using MPI, the PARMETIS_ROOT_DIR variable should be set. -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/appendix/interpkernel.dox b/medtool/doc/user/doxygen/doxfiles/appendix/interpkernel.dox deleted file mode 100644 index aacff18f5..000000000 --- a/medtool/doc/user/doxygen/doxfiles/appendix/interpkernel.dox +++ /dev/null @@ -1,85 +0,0 @@ -/*! -\page interpkernel Interpolation kernel - Implementation notes - -\section InterpKerIntro Introduction - -The main purpose of this module is to propose a set of algorithms for -mesh interpolation \b fully \b independent \b of \b the \b mesh \b data structure to -support several type of format. This component is parametrized as -much as possible using C++ templates. -For the moment only interpolators for unstructured meshes are present in -the %interpolation kernel. - -\section InterpKerMainArchitecture Main architecture of interpolation kernel. - -In the %interpolation kernel, algorithms that computes the intersection \f$ T_i\cap S_j\f$ given the locations and geometries of source cell \f$ S_j \f$ -and target cell \f$ T_i \f$ are called \ref InterpKerIntersectors. - -As can be seen in \ref InterpKerRemapGlobal "the theory of interpolation", all the proposed interpolators aim at -filling the interpolation matrix W (which is generally sparse). For each pair (i,j), \f$ W_{ij} \f$ is obtained -by calling the desired intersector. The problem is that each call to this algorithm -is CPU-expensive. -To reduce the computational time, a first filtering is done to detect -pairs (i,j) \f$ W_{ij} \f$ is obviously equal to 0. It is typically the case when a cell in the source mesh -is too far from an another cell in the target mesh each. - -So for a given type of interpolation, the computation of W is -performed in two steps : - --# A filtering process reduces the number of pairs of elements for which the calculation -must be carried out by eliminating the pairs whose bounding boxes do not intersect. --# For all remaining pairs, call the appropriate \ref InterpKerIntersectors "cell intersector" - -Whatever its dimension and type, each interpolator inherits from INTERP_KERNEL::Interpolation which is a -template (CRTP) class than enable an easy access to the main API without useless CPU cost. - -\subsection InterpKerMeshType class MeshType - -Each Interpolators and Intersectors are parametrized (templated in -C++ language) with \c class \c MeshType . This type of generalization -has been chosen to reduce at maximum overhead. \n -Thanks to this principle intersectors and interpolators are usable -with \b several \b mesh \b formats such as \c MED or \c VTK, \b without \b performance \b loss. -\c MeshType is a concept that should strictly fulfilled the following -rules : - -- Const values / Types - - MyConnType : represents type of connectivity index. This is typically \c int or \c long \c int . - - MY_SPACEDIM : space dimension. Dimension relative to coordinates. - - MY_MESHDIM : the dimension of all cells in meshes. - - My_numPol : policy of numbering. C Format ( \f$ [0,n-1] \f$ ) or FORTRAN ( \f$ [1,n] \f$ ). -- Methods - -# \code void getBoundingBox(double *boundingBox) const \endcode - -# \code INTERP_KERNEL::NormalizedCellType getTypeOfElement(MyConnType eltId) const \endcode - -# \code unsigned char getNumberOfNodesOfElement(MyConnType eltId) const \endcode - -# \code unsigned long getNumberOfNodes() const \endcode - -# \code unsigned long getNumberOfElements() const \endcode - -# \code const MyConnType *getConnectivityPtr() const \endcode - -# \code const double *getCoordinatesPtr() const \endcode - -# \code const MyConnType *getConnectivityIndexPtr() const \endcode - -# \code void releaseTempArrays() \endcode -- Formats of arrays - - the array returned by \c getCoordinatesPtr must be a \b full \b interlace array. - - the arrays returned by \c getConnectivityPtr and \c getConnectivityIndexPtr must be with the same principle as it is \ref MEDCouplingUMeshNodalConnectivity "implemented in MEDCouplingUMesh". Of course the numbering format may change according to \a My_numPol policy. - -Note that the array format for connectivity is kept close to MED. It is -close to VTK format too but slightly different. So it may require for the VTK side a copy -on wrap. To avoid this copy of a part of the connectivity structure, an iterator should be used. - -\subsection InterpKerMatrixType class MatrixType - -As already said, the matrix returned by interpolator is typically a sparse matrix. Instances of -\c class \c MatrixType are used to store the resulting interpolation matrix. To be able to be filled by the interpolator the \c MatrixType class has to match the following concept : - -- Methods - -# \code void resize(uint nbrows) \endcode - -# \code Row &operator [] (uint irow) \endcode - -\c class \c Row has to match at least the following concept : - -- Methods - - \code void insert(const std::pair& myPair) \endcode - -Note that \c std::vector\c < \c std::map > is a candidate for \c MatrixType. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/appendix/med-file.dox b/medtool/doc/user/doxygen/doxfiles/appendix/med-file.dox deleted file mode 100644 index 684015da8..000000000 --- a/medtool/doc/user/doxygen/doxfiles/appendix/med-file.dox +++ /dev/null @@ -1,33 +0,0 @@ -/*! - -\page med-file Notes on the MED file format - -\section med-file-intro Introduction - -The MED file format is a specialization of the HDF5 standard, and existed well before -MEDCoupling. Take a look at the -HDF5 Group website for more details on HDF5 itself. -It focuses on (potentially) big amount of data, and the design philosophy was to facilitate a -parallel usage. - -The official documentation of the MED-file format is available on-line (in French) in -your SALOME installation at: - -\code{.sh} -${MEDFILE_ROOT_DIR}/share/doc/html/index.html -\endcode - -Remember that the term "MED-file" denotes both: -- a file format on disk (I/O) -- a comprehensive low level C library to read/write MED files (now with a Python wrapping) -and authored by Eric FAYOLLE (EdF R&D). - -\section med-file-struct What does it look like? - -The picture below shows an UML-like diagram of the MED file format. -We see for example that the mesh name is the unique key linking a \ref fields "field" -to its supporting \ref meshes "mesh". - -\image html med-file-uml.png "Functional diagram of the MED file format" - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/appendix/references.dox b/medtool/doc/user/doxygen/doxfiles/appendix/references.dox deleted file mode 100644 index 312ec046e..000000000 --- a/medtool/doc/user/doxygen/doxfiles/appendix/references.dox +++ /dev/null @@ -1,13 +0,0 @@ -/*! - -\page references References - -Here follows a list of useful references : - --# \anchor RefManualMedFile Reference Manual for Med File, V. Lefebvre, E. Fayolle, Projet PAL: Définition du modèle d'échange de données MED V2.2, Note technique EDF/SINETICS, HI-26-03-012/A, https://hammi.extra.cea.fr/static/MED/web_med/index.html --# VTK home page: \c http://public.kitware.com/VTK --# Med File Data Model : V. Lefebvre, E. Fayolle, Définition du modèle d'échange de données MED v2.2, https://hammi.extra.cea.fr/static/MED/web_med/pdf/NOTE_HI_26_03_012_A.pdf --# Jeffrey Grandy, Conservative remapping and region overlays by intersecting arbitrary polyhedra, Journal of Computational Physics, vol 148, 433-466 (1999) --# F. Preparata and M. Shamos Computational Geometry. Springer-Verlag, New York, 1985 - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/examples/examples.dox b/medtool/doc/user/doxygen/doxfiles/examples/examples.dox deleted file mode 100644 index 29f9fa9a3..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/examples.dox +++ /dev/null @@ -1,11 +0,0 @@ -/*! - -\page examples Code examples - -Several code examples are provided with the library. -Be sure to take a look at the page \ref python-api before proceeding with the Python examples. - -- \subpage medcouplingpyexamples -- \subpage medcouplingcppexamples - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesarrays.doxy b/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesarrays.doxy deleted file mode 100644 index bf96a4e50..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesarrays.doxy +++ /dev/null @@ -1,820 +0,0 @@ - -\section ExamplesArrays Arrays - -\subsection ExamplesArraysCreate Create - -\anchor BEGIN_PYTHON_ONLY -\subsubsection MEDCouplingArraySteps0 Building an array from scratch in Python -\anchor MEDCouplingArraySteps0Double -

Building a double array from scratch in Python

- -Let's consider a list of floats \c dataDouble. - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayBuild1_0 - -The easiest way to build the \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instance" called \c arrayDouble simply call : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayBuild1_1bis - -An another way is to do that : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayBuild1_1 - -\anchor MEDCouplingArraySteps0Int -

Building an int array from scratch in Python

- -Let's consider a list of ints \c dataInt. - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayBuild1_2 - -The easiest way to build the \ref ParaMEDMEM::DataArrayInt "DataArrayInt instance" called \c arrayInt simply call : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayBuild1_3bis - -An another way is to do that : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayBuild1_3 -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_CPP_ONLY -\subsubsection MEDCouplingArraySteps1 Building an array from scratch in C++ - -In this example we will create arrays with 12 tuples constituted each -of 3 components. These arrays will be created using different ways.\n - -The following code is only based using \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" -but the use of \ref ParaMEDMEM::DataArrayInt "DataArrayInt" is strictly equivalent. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_0 - -\anchor MEDCouplingArraySteps1NCNO -

Building an array from scratch in C++, no copy no ownership

- -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_1 - -\anchor MEDCouplingArraySteps1NCWCPPO -

Building an array from scratch in C++, no copy with C++ ownership

- -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_2 - -\anchor MEDCouplingArraySteps1NCWCO -

Building an array from scratch in C++, no copy with C ownership

- -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_3 - -\anchor MEDCouplingArraySteps1WC -

Building an array from scratch in C++, with copy

- -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_4 -\anchor END_CPP_ONLY - -\anchor BEGIN_CPP_ONLY -\subsubsection cpp_mcdataarray_copy Copy DataArrays - -\anchor cpp_mcdataarray_deepcopy -

Deep copy

- -To perform a deep copy of a DataArray instance simply invoke : - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_5 - -or : - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_5bis - -\c coordsArrCpy is the deep copy of \c coordsArr so they are independent and their *raw data* has been deeply copied. - -So it leads to the following behaviour : -\anchor MEDCouplingArrayBasicsCopyDeepTestEqual - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_6 - -As \c coordsArrCpy is a copy object it needs to be deallocated in C++ like \c coordsArr. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_7 - -\anchor cpp_mcdataarray_shallowcopy -

Shallow copy

- -To perform a shallow copy of a DataArray instance simply invoke : - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_8 - -\c coordsArrCpy is the shallow copy of \c coordsArr so they share the same *raw data*. In reality they are the same object. -So it leads to the following behaviour to compare with the deep copy : - -\anchor MEDCouplingArrayBasicsCopyShallowTestEqual - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_9 - -So here the content of \c coordsArr and \c coordsArrCpy are linked, contrary to the deep copy case. - -As \c coordsArrCpy is a copy object, in C++, it needs to be deallocated. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_10 - -\anchor MEDCouplingArrayBasicsCopyDeepAssign -

Assignation by deep copy of DataArray

- -We start by building a instance of ParaMEDMEM::DataArrayDouble allocated or not. Here, instance is not allocated, only built empty. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_11 - -Then, \c coordsArrCpy is assigned with the content of \c coordsArr. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_12 - -Then \c coordsArrCpy is a deep copy of \c coordsArr except that the instance of ParaMEDMEM::DataArrayDouble is those specified. -But the behaviour is the same than those seen for \ref MEDCouplingArrayBasicsCopyDeepTestEqual "deep copy". - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_13 - -As always, in C++, \c coordsArrCpy is an object whose life cycle is fully independent from \c coordsArr so decrement is needed. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetDataArrayBuild1_14 - -\anchor END_CPP_ONLY - - -\subsubsection cpp_mcdataarrayint_buildpermutationarr Building a permutation array - -Here we create two arrays containing same values but in different order and then we use -\ref ParaMEDMEM::DataArrayInt::buildPermutationArr "DataArrayInt::buildPermutationArr()" to get -an array showing in what places the values of \b b array are located in \b a array. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_buildPermutationArr_1 -The result array \b c contains [1,0,4,2,3]. - - -\subsection ExamplesArraysModify Modify - -\subsubsection cpp_mcdataarrayint_invertarray Inverting renumbering maps - -\anchor cpp_mcdataarrayint_invertarrayo2n2n2o -

invertArrayO2N2N2O()

- -In this example we create a DataArrayInt containing a renumbering map in -"Old to New" mode, convert it into the renumbering map in "New to Old" mode and check the -result. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_invertArrayO2N2N2O_1 - -\anchor cpp_mcdataarrayint_invertarrayn2o2o2n -

invertArrayN2O2O2N()

- -In this example we create a DataArrayInt containing a renumbering map in -"New to Old" mode, convert it into the renumbering map in "Old to New" mode and check the -result. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_invertArrayN2O2O2N_1 - - -\subsubsection py_mcdataarraydouble_setpartofvalues Set part of values of DataArrayDouble - -\anchor py_mcdataarraydouble_setselectedcomponents -

setSelectedComponents()

-First, we create a 'source' array. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents1 -Now we create a larger zero array and assign the array \b da into it. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents2 -As result contents of the array \b dv are as follows. -
-Info of components : "a2"   "a1"   "v3"   "v4"
-    Tuple #0 : 2 1 0 0
-    Tuple #1 : 4 3 0 0
-    Tuple #2 : 6 5 0 0
-    Tuple #3 : 0 0 0 0
-
-The same result can be achieved other way (except that component info -is not copied): -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents3 - -\anchor py_mcdataarraydouble_setpartofvalues1 -

setPartOfValues1()

-We create two arrays: -- a "large" (4x4) zero array \b da to assign to and -- a smaller (2x2) array \b dv filled with values [7.,8.,9.,10]. - -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_1 -Now we copy \b dv to the middle of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_2 -As result contents of the array \b da are as follows. -
-    Info of components :"v1"   "v2"   "v3"   "v4"
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 8 0
-    Tuple #2 : 0 9 10 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and copy \b dv into a component of \b da. - -Note that the last parameter \b strictCompoCompare should be \c False -in this case, else \ref ParaMEDMEM::DataArrayDouble::setPartOfValues1() -throws an exception because \b da has 2 components but only one target -component is specified. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 8 0 0
-    Tuple #2 : 0 9 0 0
-    Tuple #3 : 0 10 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 8 9 10
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_5 -
-    Tuple #0 : 0 7 0 8
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 9 0 10
-    Tuple #3 : 0 0 0 0
-
-The same result can be achieved other way: -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_6 - - -\anchor py_mcdataarraydouble_setpartofvaluessimple1 -

setPartOfValuesSimple1()

-We create an array (4x4) \b da to assign to and define a value \b dv to assign. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_1 -Now we assign \b dv to the middle of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 7 0
-    Tuple #2 : 0 7 7 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and assign \b dv to a component of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 7 0 0
-    Tuple #2 : 0 7 0 0
-    Tuple #3 : 0 7 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 7 7 7
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_5 -
-    Tuple #0 : 0 7 0 7
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 7 0 7
-    Tuple #3 : 0 0 0 0
-
-The same result can be achieved other way: -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_6 - - -\anchor py_mcdataarraydouble_setpartofvaluessimple2 -

setPartOfValuesSimple2()

-We create an array (4x4) \b da to assign to and define a value \b dv to assign. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_1 -Now we assign \b dv to the middle of \b da. -We explicitly specify tuples and component to assign to by a list [1,2]. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 7 0
-    Tuple #2 : 0 7 7 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and assign \b dv to a component of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 7 0 0
-    Tuple #2 : 0 7 0 0
-    Tuple #3 : 0 7 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 7 7 7
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_5 -
-    Tuple #0 : 0 7 0 7
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 7 0 7
-    Tuple #3 : 0 0 0 0
-
-\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValuesSimple2() can't -be explicitly called in Python. - - -\anchor py_mcdataarraydouble_setpartofvaluessimple3 -

setPartOfValuesSimple3()

-We create an array (4x4) \b da to assign to and define a value \b dv to assign. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_1 -Now we assign \b dv to the middle of \b da. -We explicitly specify tuples to assign to by a list [1,2]. And we specify -components to assign to using slicing: 1:3. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 7 0
-    Tuple #2 : 0 7 7 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and assign \b dv to a component of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 7 0 0
-    Tuple #2 : 0 7 0 0
-    Tuple #3 : 0 7 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 7 7 7
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_5 -
-    Tuple #0 : 0 7 0 7
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 7 0 7
-    Tuple #3 : 0 0 0 0
-
-\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValuesSimple3() can't -be explicitly called in Python. - - -\anchor py_mcdataarraydouble_setpartofvalues2 -

setPartOfValues2()

-We create two arrays: -- a "large" (4x7) zero array \b da to assign to, -- a smaller (3x2) array \b dv filled with values [7.,8.,9.,10.,11.,12.]. - -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_1 -Now we assign the two components of \b dv to the components of \b da -with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with - indices [0,1,2]. This is the first mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0  7  0  8  0  0  0
-    Tuple #1 : 0  9  0 10  0  0  0
-    Tuple #2 : 0 11  0 12  0  0  0
-    Tuple #3 : 0  0  0  0  0  0  0
-
-Every value of \b dv has been assigned to its own location within \b da. - -Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. -And we assign \b dv to the tuples of \b da with indices [0,2,3] . -This is the second mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_3 -The contents of \b dv have been assigned to each of specified tuples of \b da. -Every value of \b dv is repeated in the 3 specified tuples within \b da. -
-    Tuple #0 : 7  0  8  9 10 11 12
-    Tuple #1 : 0  0  0  0  0  0  0
-    Tuple #2 : 7  0  8  9 10 11 12
-    Tuple #3 : 7  0  8  9 10 11 12
-
-\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValues2() can't -be explicitly called in Python. - - -\anchor py_mcdataarraydouble_setpartofvalues3 -

setPartOfValues3()

-We create two arrays: -- a "large" (4x7) zero array \b da to assign to, -- a smaller (3x2) array \b dv filled with values [7.,8.,9.,10.,11.,12.]. - -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_1 -Now we assign the two components of \b dv to the components of \b da -with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with -indices [0,1,2] which are specified using slicing: "0:3". -This is the first mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0  7  0  8  0  0  0
-    Tuple #1 : 0  9  0 10  0  0  0
-    Tuple #2 : 0 11  0 12  0  0  0
-    Tuple #3 : 0  0  0  0  0  0  0
-
-Every value of \b dv has been assigned to its own location within \b da. - -Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. -And we assign \b dv to the tuples of \b da with indices [0,2] using \a -slice notation "0:4:2". This is the second mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_3 -The contents of \b dv have been assigned to each of specified tuples of \b da. -Every value of \b dv is repeated in the 3 specified tuples within \b da. -
-    Tuple #0 : 7  0  8  9 10 11 12
-    Tuple #1 : 0  0  0  0  0  0  0
-    Tuple #2 : 7  0  8  9 10 11 12
-    Tuple #3 : 0  0  0  0  0  0  0
-
-\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValues3() can't -be explicitly called in Python. - - -\subsubsection py_mcdataarrayint_setpartofvalues Set part of values of DataArrayInt - -\anchor py_mcdataarrayint_setselectedcomponents -

setSelectedComponents()

-First, we create a 'source' array. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents1 -Now we create a larger zero array and assign the array \b da to it. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents2 -As result contents of the array \b dv are as follows. -
-Info of components : "a2"   "a1"   "v3"   "v4"
-    Tuple #0 : 2 1 0 0
-    Tuple #1 : 4 3 0 0
-    Tuple #2 : 6 5 0 0
-    Tuple #3 : 0 0 0 0
-
-The same result can be achieved other way (except that component info -is not copied): -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents3 - -\anchor py_mcdataarrayint_setpartofvalues1 -

setPartOfValues1()

-We create two arrays: -- a "large" (4x4) zero array \b da to assign to, and -- a smaller (2x2) array \b dv filled with values [7,8,9,10]. - -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_1 -Now we copy \b dv to the middle of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_2 -As result contents of the array \b da are as follows. -
-    Info of components :"v1"   "v2"   "v3"   "v4"
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 8 0
-    Tuple #2 : 0 9 10 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and copy \b dv into a component of \b da. - -Note that the last parameter \b strictCompoCompare should be \c False -in this case, else \ref ParaMEDMEM::DataArrayInt::setPartOfValues1() -throws an exception because \b da has 2 components but only one target -component is specified. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 8 0 0
-    Tuple #2 : 0 9 0 0
-    Tuple #3 : 0 10 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 8 9 10
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_5 -
-    Tuple #0 : 0 7 0 8
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 9 0 10
-    Tuple #3 : 0 0 0 0
-
-The same result can be achieved other way: -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_6 - - - -\anchor py_mcdataarrayint_setpartofvaluessimple1 -

setPartOfValuesSimple1()

-We create an array (4x4) \b da to assign to and define a value \b dv to assign. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_1 -Now we assign \b dv to the middle of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 7 0
-    Tuple #2 : 0 7 7 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and assign \b dv to a component of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 7 0 0
-    Tuple #2 : 0 7 0 0
-    Tuple #3 : 0 7 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 7 7 7
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_5 -
-    Tuple #0 : 0 7 0 7
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 7 0 7
-    Tuple #3 : 0 0 0 0
-
-The same result can be achieved other way: -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_6 - - -\anchor py_mcdataarrayint_setpartofvaluessimple2 -

setPartOfValuesSimple2()

-We create an array (4x4) \b da to assign to and define a value \b dv to assign. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_1 -Now we assign \b dv to the middle of \b da. -We explicitly specify tuples and component to assign to by a list [1,2]. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 7 0
-    Tuple #2 : 0 7 7 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and assign \b dv to a component of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 7 0 0
-    Tuple #2 : 0 7 0 0
-    Tuple #3 : 0 7 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 7 7 7
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_5 -
-    Tuple #0 : 0 7 0 7
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 7 0 7
-    Tuple #3 : 0 0 0 0
-
-\note \ref ParaMEDMEM::DataArrayInt::setPartOfValuesSimple2() can't -be explicitly called in Python. - - -\anchor py_mcdataarrayint_setpartofvaluessimple3 -

setPartOfValuesSimple3()

-We create an array (4x4) \b da to assign to and define a value \b dv to assign. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_1 -Now we assign \b dv to the middle of \b da. -We explicitly specify tuples to assign to by a list [1,2]. And we specify -components to assign to using slicing: 1:3. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 0 7 7 0
-    Tuple #2 : 0 7 7 0
-    Tuple #3 : 0 0 0 0
-
- -Here we re-fill \b da with zeros and assign \b dv to a component of \b da. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_3 -
-    Tuple #0 : 0 7 0 0
-    Tuple #1 : 0 7 0 0
-    Tuple #2 : 0 7 0 0
-    Tuple #3 : 0 7 0 0
-
-Below more two variants of location of target values are shown. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_4 -
-    Tuple #0 : 0 0 0 0
-    Tuple #1 : 7 7 7 7
-    Tuple #2 : 0 0 0 0
-    Tuple #3 : 0 0 0 0
-
- -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_5 -
-    Tuple #0 : 0 7 0 7
-    Tuple #1 : 0 0 0 0
-    Tuple #2 : 0 7 0 7
-    Tuple #3 : 0 0 0 0
-
-\note \ref ParaMEDMEM::DataArrayInt::setPartOfValuesSimple3() can't -be explicitly called in Python. - - -\anchor py_mcdataarrayint_setpartofvalues2 -

setPartOfValues2()

-We create two arrays: -- a "large" (4x7) zero array \b da to assign to, -- a smaller (3x2) array \b dv filled with values [7,8,9,10,11,12]. - -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_1 -Now we assign the two components of \b dv to the components of \b da -with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with - indices [0,1,2]. This is the first mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0  7  0  8  0  0  0
-    Tuple #1 : 0  9  0 10  0  0  0
-    Tuple #2 : 0 11  0 12  0  0  0
-    Tuple #3 : 0  0  0  0  0  0  0
-
-Every value of \b dv has been assigned to its own location within \b da. - -Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. -And we assign \b dv to the tuples of \b da with indices [0,2,3] . -This is the second mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_3 -The contents of \b dv have been assigned to each of specified tuples of \b da. -Every value of \b dv is repeated in the 3 specified tuples within \b da. -
-    Tuple #0 : 7  0  8  9 10 11 12
-    Tuple #1 : 0  0  0  0  0  0  0
-    Tuple #2 : 7  0  8  9 10 11 12
-    Tuple #3 : 7  0  8  9 10 11 12
-
-\note \ref ParaMEDMEM::DataArrayInt::setPartOfValues2() can't -be explicitly called in Python. - - -\anchor py_mcdataarrayint_setpartofvalues3 -

setPartOfValues3()

-We create two arrays: -- a "large" (4x7) zero array \b da to assign to, -- a smaller (3x2) array \b dv filled with values [7,8,9,10,11,12]. - -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_1 -Now we assign the two components of \b dv to the components of \b da -with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with -indices [0,1,2] which are specified using slicing: "0:3". -This is the first mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_2 -As result contents of the array \b da are as follows. -
-    Tuple #0 : 0  7  0  8  0  0  0
-    Tuple #1 : 0  9  0 10  0  0  0
-    Tuple #2 : 0 11  0 12  0  0  0
-    Tuple #3 : 0  0  0  0  0  0  0
-
-Every value of \b dv has been assigned to its own location within \b da. - -Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. -And we assign \b dv to the tuples of \b da with indices [0,2] using \a -slice notation "0:4:2". This is the second mode of usage. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_3 -The contents of \b dv have been assigned to each of specified tuples of \b da. -Every value of \b dv is repeated in the 3 specified tuples within \b da. -
-    Tuple #0 : 7  0  8  9 10 11 12
-    Tuple #1 : 0  0  0  0  0  0  0
-    Tuple #2 : 7  0  8  9 10 11 12
-    Tuple #3 : 0  0  0  0  0  0  0
-
-\note \ref ParaMEDMEM::DataArrayInt::setPartOfValues3() can't -be explicitly called in Python. - - -\subsubsection py_mcdataarraydouble_getdifferentvalues Excluding coincident tuples from DataArrayDouble - -The code below creates an array of real values and than an array of - unique values, not closer one to another than 0.2, is retrieved from it. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_getDifferentValues1 - - -\subsubsection cpp_mcdataarraydouble_meldwith Concatenating DataArrayDouble's by appending components - -In this example we create two data arrays including \b same number of -tuples and then we concatenate them using \ref -ParaMEDMEM::DataArrayDouble::meldWith "meldWith()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_Meld1_1 -Now the array \b da1 includes 7 tuples (as before) of 3 components -each. Its components are: "c0da1","c1da1","c0da2". - - -\subsubsection cpp_mcdataarrayint_meldwith Concatenating DataArrayInt's by appending components - -In this example we create two data arrays including \b same number of -tuples and then we concatenate them using \ref -ParaMEDMEM::DataArrayInt::meldWith "meldWith()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_Meld1_1 -Now the array \b da1 includes 7 tuples (as before) of 3 components -each. Its components are: "c0da1","c1da1","c0da2". - - -\subsection ExamplesArraysAccess Access - -\subsubsection cpp_mcdataarrayint_getTuple Getting a tuple of DataArrayInt - -In this simple example we create an array of integers arranged into 3 -tuples per 2 components, and finally print the second tuple. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_getTuple_1 -The output is -
 [9, 10] 
-Note that we can traverse all tuples in the array by simply iterating -over it as the code below does. -\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_getTuple_2 -Its output follows. -
-(7, 8)
-(9, 10)
-(11, 12)
-
- - -\subsubsection cpp_mcdataarraydouble_getidsinrange Finding values in range in DataArrayDouble - -In this example we create an array \b da containing same values as ones returned by -\c range( \c 10 ). Then we get an array of indices of values of \b da being in -range [ 2.5, 6 ]. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_getIdsInRange_1 -As result contents of the array \b da2 are as follows. -
-    Tuple #0 : 3
-    Tuple #1 : 4
-    Tuple #2 : 5
-    Tuple #3 : 6
-
- - -\subsubsection cpp_mcdataarraydouble_findcommontuples Finding coincident tuples in DataArrayDouble - -Let's create an array of 6 tuples and 2 components that can be - considered as coordinates of 6 points in 2D space. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_findCommonTuples1 -Now we find points that are not far each from other than 1e-1. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_findCommonTuples2 -As we can realize from the above code, a hardcoded array \b expected3 is equal - to the raw data of a DataArrayInt \b c and a hardcoded array \b expected4 is equal - to the raw data of the DataArrayInt \b cI. - -The array \b c contains indices of 5 coincident points. The array \b - cI shows us boundaries of (cI->getNumberOfTuples()-1) = 2 groups of coincident points: -- The first group starts at index 0 and includes (3 - 0) = 3 points: 0,3,4. -- The second group starts at index 3 and includes (5 - 3) = 2 points: 1,2. - - -\subsubsection py_mcdataarraydouble_KeepSelectedComponents Creation of a sub-part of the DataArrayDouble by selecting components - -\snippet MEDCouplingExamplesTest.py SnippeDataArrayDoubleKeepSelectedComponents1_1 -We created an array \b a1 containing 5 tuples of 4 components each (20 -values). Now we are going to create an array \b a2 containing some -components of \b a1. -\snippet MEDCouplingExamplesTest.py SnippeDataArrayDoubleKeepSelectedComponents1_2 -Now each tuple of \b a2 includes components named "b","c","b","c","a","a". Thus -the result array \b a2 includes 30 elements (5 tuples per 6 components). - - -\subsubsection py_mcdataarrayint_keepselectedcomponents Creation of a sub-part of the DataArrayInt by selecting components - -\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_1 -We created an array \b a1 containing 5 tuples of 4 components each (20 -values). Now we are going to create an array \b a2 containing some -components of \b a1. -\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_2 -Now each tuple of \b a2 includes components named "b","c","b","c","a","a". Thus -the result array \b a2 includes 30 elements (5 tuples per 6 components). - -Note that -\ref ParaMEDMEM::DataArrayInt::keepSelectedComponents() "DataArrayInt::keepSelectedComponents()" -is called, providing the same result, by the following python code: -\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_3 diff --git a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesfields.doxy b/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesfields.doxy deleted file mode 100644 index cf430d383..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesfields.doxy +++ /dev/null @@ -1,651 +0,0 @@ - -\section ExamplesFields Fields - -\subsection ExamplesFieldsCreate Create - -\subsubsection medcouplingcppexamplesFieldDoubleBuild1 Standard build of a tensor field on cells with no time attached - -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuild1_1 - - -\subsubsection medcouplingcppexamplesFieldDoubleBuild2 Standard build of a scalar field on nodes with no time attached - -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuild2_1 - - -\subsubsection medcouplingcppexamplesFieldDoubleBuild3 Standard build of a vector field on cells with one time attached and no time interval - -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuild3_1 - - -\subsubsection medcouplingcppexamplesFieldDoubleBuild4 Standard build of a vector field on nodes defined on a time interval with a constant value during this interval - -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuild4_1 - - -\subsubsection cpp_mcfielddouble_MaxFields Getting maximal and minimal fields - -In this example we -- create two fields with two tuples per two components, -- use -\ref ParaMEDMEM::MEDCouplingFieldDouble::MaxFields "MaxFields()" -to get a field holding maximal values of the two fields. -- use -\ref ParaMEDMEM::MEDCouplingFieldDouble::MinFields "MinFields()" -to get a field holding minimal values of the two fields. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_MaxFields_1 - - -\subsubsection cpp_mcfielddouble_MergeFields Concatenating fields - -In this example we -- create an 1D mesh and a field on it, -- make a deep copy of the mesh and the field, -- translate the mesh and the field, -- use two variants of -\ref ParaMEDMEM::MEDCouplingFieldDouble::MergeFields "MergeFields()" -to create one field from the two by concatenating them and their meshes. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_MergeFields_1 -The result field is twice "longer" than \b field1. - - -\subsubsection cpp_mcfielddouble_buildNewTimeReprFromThis Getting a field copy with different time discretization - -First, we create a supporting 2D mesh and a field on it got using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". -\ref MEDCouplingTemporalDisc "Time discretization" of this field is -\ref ParaMEDMEM::ONE_TIME "ONE_TIME". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1 -Now we use -\ref ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis "buildNewTimeReprFromThis()" -to get a copy of \b field1 whose time discretization is -\ref ParaMEDMEM::NO_TIME "NO_TIME". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2 - - -\subsubsection cpp_mcmesh_fillFromAnalytic3 Creating a field using an expression - -First, we create a 2D Cartesian mesh constituted by 2 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1 -Now we use -\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic3 "fillFromAnalytic3()" -to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled -with values computed using an expression \b func. This expression is applied to coordinates of -each point (barycenter) for which the field value is computed. We want to get the -field on cells, with 3 components computed as follows. (In \b func, we refer to the -first component of a point using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. -- Component #1 = the first coordinate of the point; hence "JVec * a". -- Component #2 = distance between the point and SC origin (0.,0.); hence -"KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2 -Now we ascertain that the result field is as we expect. We check the second tuple of -the \b field. We get barycenter of the cell #1 and checks that values of the second -tuple are computed as we want. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3 - - -\subsubsection cpp_mcmesh_fillFromAnalytic2 Creating a field using an expression - -First, we create a 2D Cartesian mesh constituted by 2 cells. -Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to -corresponding coordinates within a function. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1 -Now we use -\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic2 "fillFromAnalytic2()" -to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled -with values computed using an expression \b func. This expression is applied to coordinates of -each point (barycenter) for which the field value is computed. We want to get the -field on cells, with 3 components computed as follows. (In \b func, we refer to the -first component of a point using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. -- Component #1 = the first coordinate of the point; hence "JVec * a". -- Component #2 = distance between the point and SC origin (0.,0.); hence -"KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2 -Now we ascertain that the result field is as we expect. We check the second tuple of -the \b field. We get barycenter of the cell #1 and checks that values of the second -tuple are computed as we want. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3 - - -\subsubsection cpp_mcmesh_fillFromAnalytic Creating a field using an expression - -First, we create a 2D Cartesian mesh constituted by 2 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_1 -Now we use -\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic "fillFromAnalytic()" -to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled -with values computed using an expression \b func. This expression is applied to coordinates of -each point (barycenter) for which the field value is computed. We want to get the -field on cells, with 3 components computed as follows. (In \b func, we refer to the -first component of a point using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. -- Component #1 = the first coordinate of the point; hence "JVec * a". -- Component #2 = distance between the point and SC origin (0.,0.); hence -"KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_2 -Now we ascertain that the result field is as we expect. We check the second tuple of -the \b field. We get barycenter of the cell #1 and checks that values of the second -tuple are computed as we want. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_3 - - -\subsubsection cpp_mcfielddouble_subpart1 Creation of a sub part of a field - -

Creation of a sub part of a field on cells

-\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_1 -The field on cells \b f1 lies on a mesh containing 5 cells and 9 nodes. -So this field \b f1 contains 5 tuples of 2 components each (10 values). -Now let's create a subfield on cells \b f2 from \b f1. -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_2 - -\b f1 is a field on cells, \ref ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart "buildSubPart" method performs an extraction on cells too. - -So the array \b part1 lists ids on cells. - -- cell #0 of \b f2 is the same cell of cell #2 of \b f1 -- cell #1 of \b f2 is the same cell of cell #1 of \b f1 -- cell #2 of \b f2 is the same cell of cell #4 of \b f1 - -So \b f2 contains 3 tuples with 2 components. - -The underlying mesh of \b f2 contains a newly created mesh with 3 cells (not as \b mesh1 in \b f1) and 9 nodes (as \b mesh1 in \b f1). -\n For fields on cells the number of tuples of the returned field is always equal to the number of ids given in input (here \b part1). -\n -Only fields on cells have this particular behaviour. - -

Creation of a sub part of a field on nodes

-\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_3 -The field on nodes \b f1 lies on a mesh containing 5 cells and 9 nodes. -So this field \b f1 contains 9 tuples of 2 components each (18 values). -Now let's create a subfield on nodes \b f2 from \b f1. -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_4 - -\b f1 is a field on nodes, but \ref ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart "buildSubPart" method performs an extraction on \b cells. - -After the call of \ref ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart "buildSubPart" on node field \b f1, \b f1 will be reduced on a -submesh of \b mesh1 containing cells whose ids are in \b part2. So here the number of cells of \b f2 is 2 and the number of nodes is 4. -\n -So contrary to fields on cells, it is normal for fields on nodes that number of tuples of the returned field of \ref ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart "buildSubPart" -method does not match the size of the input array (here \b part2). - - -\subsection ExamplesFieldsModify Modify - -\subsubsection cpp_mcfielddouble_substractInPlaceDM Subtracting field on different meshes - -We make two meshes in 1D space with no cells and 4 nodes. Nodes #0 and #2 are swapped -in the two meshes.
-And we make two fields on these meshes, so that fields values to equal to node -coordinates of the underlying meshes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1 -We are going to subtract \b field2 from \b field1, though they are on -different meshes. -\ref ParaMEDMEM::MEDCouplingFieldDouble::substractInPlaceDM "substractInPlaceDM()" -allows us doing this. We use a mesh comparison level \b levOfCheck = 10 that allows -subtracting fields on meshes with different node arrays.
-\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2 -After applying -\ref ParaMEDMEM::MEDCouplingFieldDouble::substractInPlaceDM "substractInPlaceDM()" -the both fields lie on \b mesh2. As -\ref ParaMEDMEM::MEDCouplingFieldDouble::substractInPlaceDM "substractInPlaceDM()" -permutes values of \b field1 before value subtraction, and thus \b field1 becomes -equal to \b field2, hence their subtraction results in a zero field. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3 - - -\subsubsection cpp_mcfielddouble_changeUnderlyingMesh Changing the underlying mesh - -We make two meshes in 1D space with no cells and 4 nodes. Nodes #0 and #2 are swapped -in the two meshes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1 -We are going to use -\ref ParaMEDMEM::MEDCouplingFieldDouble::changeUnderlyingMesh "changeUnderlyingMesh()" -to set \b mesh2 instead of \b mesh1 as a support of a field.
-We use -\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic "fillFromAnalytic()" -to make a field on nodes of \b mesh1, so that its values to equal to node coordinates. -Then we use -\ref ParaMEDMEM::MEDCouplingFieldDouble::changeUnderlyingMesh "changeUnderlyingMesh()" -to change the underlying mesh of the \b field. -(We use a mesh comparison level \b levOfCheck = 10 that allows substituting meshes with -different node arrays.) As a result, we expect that values of the \b field are also -permuted same as nodes of the two meshes, and thus its values become equal to the -array \b coords2. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2 - - -\subsubsection cpp_mcfielddouble_applyFunc_same_nb_comp Changing a field using an expression - -We create a 2D vector field with 2 tuples and we want to transform this -field using an expression using -\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int, const std::string&) "applyFunc()". -The expression \b func is applied to each atomic value of the \b field. We want to change -the \b field as follows. (In \b func, we use the variable "v" to refer to an atomic field value). -- Component #0 = component #0 (remains the same); hence "IVec * v" in \b func. -- Component #1 = component #1 ^ 2; hence "JVec * v*v". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1 -Now we ascertain that the result field is as we expect. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2 - - -\subsubsection cpp_mcfielddouble_applyFunc3 Changing a field using an expression - -We create a 2D vector field with 2 values (vectors) and then we transform this -field into a 3D vector field by applying an expression to values of the 2D field -using -\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc3() "applyFunc3()". -The expression \b func is applied to components of each vector of the \b field. We want -the \b field to have 3 components computed as follows. (In \b func, we refer to the -first component of a field value using the variable "a", and to the second component, using -the variable "b", as we define it by \b varNamesVec). -- Component #0 = the second vector component; hence "IVec * b" in \b func. -- Component #1 = the first vector component; hence "JVec * a". -- Component #2 = a vector magnitude; hence "KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc3_1 -Now we ascertain that the result field is as we expect. We check the second vector of -the \b field. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc3_2 - - -\subsubsection cpp_mcfielddouble_applyFunc2 Changing a field using an expression - -We create a 2D vector field with 2 values (vectors) and then we transform this -field into a 3D vector field by applying an expression to values of the 2D field -using -\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string&) "applyFunc2()". -Note that we set component info the \b array ("a" and "b" ) which will be used to refer to -corresponding components within a function. -The expression \b func is applied to components of each vector of the \b field. We want -the \b field to have 3 components computed as follows. (In \b func, we refer to the -first component of a field value using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second vector component; hence "IVec * b" in \b func. -- Component #1 = the first vector component; hence "JVec * a". -- Component #2 = a vector magnitude; hence "KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc2_1 -Now we ascertain that the result field is as we expect. We check the second vector of -the \b field. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc2_2 - - -\subsubsection cpp_mcfielddouble_applyFunc Changing a field using an expression - -We create a 2D vector field with 2 values (vectors) and then we transform this -field into a 3D vector field by applying an expression to values of the 2D field -using -\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()". -The expression \b func is applied to components of each vector of the \b field. We want -the \b field to have 3 components computed as follows. (In \b func, we refer to the -first component of a field value using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second vector component; hence "IVec * b" in \b func. -- Component #1 = the first vector component; hence "JVec * a". -- Component #2 = a vector magnitude; hence "KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_1 -Now we ascertain that the result field is as we expect. We check the second vector of -the \b field. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_2 - - -\subsubsection cpp_mcfielddouble_applyFunc_val Filling a field with a value - -We want to transform a 2D vector field to a 3D vector field so that all values to be -equal to a certain value. First, we create the 2D mesh and the vector field on it. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_val_1 -Finally we use -\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) "applyFunc()" -to change the number of components and all field values. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_val_2 -As a result, number of tuples in the field equals to the number of cells in the mesh, -and number of components becomes equal to 3 as required. - - -\subsubsection cpp_mcfielddouble_fillFromAnalytic3 Filling a field using an expression - -First, we create a 2D Cartesian mesh constituted by 2 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1 -Now we create a field on cells and use -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic2 "fillFromAnalytic2()" -to fill it -with values computed using an expression \b func. This expression is applied to coordinates of -each point (barycenter) for which the field value is computed. We want the \b field -to have 3 components computed as follows. (In \b func, we refer to the -first component of a point using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. -- Component #1 = the first coordinate of the point; hence "JVec * a". -- Component #2 = distance between the point and SC origin (0.,0.); hence -"KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2 -Now we ascertain that the result field is as we expect. We check the second tuple of -the \b field. We get barycenter of the cell #1 and checks that values of the second -tuple are computed as we want. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3 - - -\subsubsection cpp_mcfielddouble_fillFromAnalytic2 Filling a field using an expression - -First, we create a 2D Cartesian mesh constituted by 2 cells. -Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to -corresponding coordinates within a function. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1 -Now we create a field on cells and use -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic2 "fillFromAnalytic2()" -to fill it -with values computed using an expression \b func. This expression is applied to coordinates of -each point (barycenter) for which the field value is computed. We want the \b field -to have 3 components computed as follows. (In \b func, we refer to the -first component of a point using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. -- Component #1 = the first coordinate of the point; hence "JVec * a". -- Component #2 = distance between the point and SC origin (0.,0.); hence -"KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2 -Now we ascertain that the result field is as we expect. We check the second tuple of -the \b field. We get barycenter of the cell #1 and checks that values of the second -tuple are computed as we want. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3 - - -\subsubsection cpp_mcfielddouble_fillFromAnalytic Filling a field using an expression - -First, we create a 2D Cartesian mesh constituted by 2 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1 -Now we create a field on cells and use -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" -to fill it -with values computed using an expression \b func. This expression is applied to coordinates of -each point (barycenter) for which the field value is computed. We want the \b field to have - 3 components computed as follows. (In \b func, we refer to the -first component of a point using the variable "a", and to the second component, using -the variable "b"). -- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. -- Component #1 = the first coordinate of the point; hence "JVec * a". -- Component #2 = distance between the point and SC origin (0.,0.); hence -"KVec * sqrt( a*a + b*b )". - -In addition we want to add 10.0 to each component computed as described above, hence -"10" in \b func. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2 -Now we ascertain that the result field is as we expect. We check the second tuple of -the \b field. We get barycenter of the cell #1 to check that values of the second -tuple (#1) are computed as we want. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3 - - -\subsubsection medcouplingcppexamplesFieldDoubleBuild5 Some operations that can be carried out on fields on cells - -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuild1_2 - -\anchor BEGIN_CPP_ONLY -The decrementation of ref counter should be carried out in CPlusPlus only ... - -\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuild1_3 -\anchor END_CPP_ONLY - - -\subsubsection cpp_mcfielddouble_renumberNodes Permuting a field on nodes - -First, we create a supporting 2D mesh constituted by 4 cells. We create a 2x2 -Cartesian mesh and then convert it to an unstructured one, since the Cartesian mesh -is not suitable for -\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberNodes "renumberNodes()" as its - nature does not imply node renumbering. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberNodes_1 -Then we create a field on nodes using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()", -such that its values to coincide with coordinates of field location points that are - nodes in our case (as our field is \ref ParaMEDMEM::ON_NODES "ON_NODES"). -At last we ascertain that field values are equal to node coordinates. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberNodes_2 -Now, we are going to reverse order of nodes using -\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberNodes "renumberNodes()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberNodes_3 -As a result, the underlying mesh of \b field is changed and its nodes are also - renumbered. -And the field values are still equal to node coordinates of the renumbered \b mesh2. - - -\subsubsection cpp_mcfielddouble_renumberCells Permuting a field on cells - -First, we create a supporting 2D mesh constituted by 4 cells. We create a 2x2 -Cartesian mesh and then convert it to an unstructured one, since the Cartesian mesh -is not suitable for -\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberCells "renumberCells()" as its - nature does not imply cell renumbering. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberCells_1 -Then we create a field on cells using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()", -such that its values to coincide with coordinates of field location points that are - cell barycenters in our case (as our field is \ref ParaMEDMEM::ON_CELLS "ON_CELLS"). -At last we ascertain that field values are equal to cell barycenters. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberCells_2 -Now, we are going to reverse order of cells using -\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberCells "renumberCells()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberCells_3 -As a result, the underlying mesh of \b field is changed and its cells are also - renumbered. -And the field values are still equal to cell barycenters of the renumbered \b mesh2. - - -\anchor BEGIN_CPP_ONLY -\subsubsection cpp_mcfielddouble_fillFromAnalytic_c_func Filling a field using a C function - -We want to create a 3D vector field lying on a 2D mesh using a C function as a value -generator. For that, first, we define the function that computes 3 values basing on 2 -coordinates of a 2D point. -\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0 -Then we create the 2D mesh and the field on it, and finally we use -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) "fillFromAnalytic()" -to fill the field with values each composed of 3 components. -\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1 -As a result, number of tuples in the field equals to the number of cells in the mesh, -and number of components equals to 3 as required. -\anchor END_CPP_ONLY - - -\anchor BEGIN_CPP_ONLY -\subsubsection cpp_mcfielddouble_applyFunc_c_func Changing a field by applying a C function - -We want to transform a 2D vector field to a 3D vector field by -applying a C function to each vector value. For that, first, we define the function -that computes 3 values basing on 2 components of a 2D vector. -\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0 -Then we create the 2D mesh and the vector field on it. -\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1 -Finally we use -\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) "applyFunc()" -to change the field values. -\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2 -As a result, number of tuples in the field equals to the number of cells in the mesh, -and number of components becomes equal to 3 as required. -\anchor END_CPP_ONLY - - -\anchor BEGIN_CPP_ONLY - -\subsubsection cpp_mcfield_remapper_highlevel Using interpolation tools - High level usage - -\code -... -const char sourceFileName[]="source.med"; -MEDCouplingFieldDouble *sourceField=MEDLoader::ReadFieldCell(sourceFileName,"Source_Mesh",0,"Density",/*iteration*/0,/*order*/0); -const char targetFileName[]="target.med"; -MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile(targetFileName,"Target_Mesh",0); -// -sourceField->setNature(ConservativeVolumic);//Specify which formula to use in case of non overlapping meshes -MEDCouplingRemapper remapper; -remapper.setPrecision(1e-12); -remapper.setIntersectionType(INTERP_KERNEL::Triangulation); -remapper.prepare(sourceField->getMesh(),med_target_mesh,"P0P0"); -MEDCouplingFieldDouble *targetField=remapper.transferField(sourceField,/*default_value*/4.57);//Any target cell not intercepted by any source cell will have value set to 4.57. -... -// clean-up -targetField->decrRef(); -sourceField->decrRef(); -med_target_mesh->decrRef(); -\endcode - -\anchor END_CPP_ONLY - - -\anchor BEGIN_CPP_ONLY - -\subsubsection cpp_mcfield_remapper_middlelevel Using interpolation tools - Middle level usage - -- The simplest way to use the interpolator with \ref medcoupling "MEDCoupling data struture" is illustrated in the following example. - -\code -... -MEDCouplingUMesh *med_source_mesh=MEDLoader::ReadUMeshFromFile("source.med","Source_mesh",0); -MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile("target.med","Target_mesh",0); -MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_source_mesh(med_source_mesh); -MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_target_mesh(med_target_mesh); -// Go for interpolation... -INTERP_KERNEL::Interpolation2D myInterpolator; -myInterpolator.setPrecision(1e-7); -myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); -std::vector > resultMatrix; -INTERP_KERNEL::Matrix resultMatrix2; -// here the interpolation is performed twice for this code to illustrate the possibility of storing data the interpolation matrix in 2 different data structures. -myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix,"P0P0"); -myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix2,"P0P0"); -//Ok resultMatrix and resultMatrix2 contain matrix now -... -\endcode - - -- Same with VTK data structure : - -\code -... -vtkXMLUnstructuredGridReader *readerSource=vtkXMLUnstructuredGridReader::New(); -readerSource->SetFileName("source.vtu"); -vtkUnstructuredGrid *vtk_source_mesh=readerSource->GetOutput(); -readerSource->Update(); -vtkXMLUnstructuredGridReader *readerTarget=vtkXMLUnstructuredGridReader::New(); -readerTarget->SetFileName("target.vtu"); -vtkUnstructuredGrid *vtk_target_mesh=readerTarget->GetOutput(); -readerTarget->Update(); -// Ok at this point we have our mesh in VTK format. -// Go to wrap vtk_source_mesh and vtk_target_mesh. -VTKNormalizedUnstructuredMesh<2> wrap_source_mesh(vtk_source_mesh); -VTKNormalizedUnstructuredMesh<2> wrap_target_mesh(vtk_target_mesh); -// Go for interpolation... -INTERP_KERNEL::Interpolation2D myInterpolator; -//optional call to parametrize your interpolation. First precision, tracelevel, intersector wanted. -myInterpolator.setOptions(1e-7,0,Geometric2D); -INTERP_KERNEL::Matrix resultMatrix; -myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix,"P0P0"); -//Ok let's multiply resultMatrix by source field to interpolate to target field. -resultMatrix.multiply(...) -//clean-up -readerSource->Delete(); -readerTarget->Delete(); -... -\endcode - -\anchor END_CPP_ONLY - - -\subsection ExamplesFieldsAccess Access - -\subsubsection cpp_mcfielddouble_getValueOn_time Getting a field value at some point at certain time - -First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh -constituted by 4 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1 -Then we create a scalar field on cells, whose values vary linearly in time. -We set all field values at a start time to be equal 10.0 using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". -And we set all field values at an end time to be equal 20.0 by doubling the start -time array. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2 -Now, we want to get a field value at a point [0,0] at a middle time between the start -and end times. We expect the returned value to be equal to an average of 10. and 20. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3 - - -\subsubsection cpp_mcfielddouble_getValueOnMulti Getting field values at some points - -First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh -constituted by 4 cells. Then we create a scalar field on cells using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1 -Now, we want to retrieve all field values using -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti "getValueOnMulti()". -The field values relate to cells, hence we will use cell barycenters as a parameter of -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti "getValueOnMulti()". -We expect that the double array returned -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti "getValueOnMulti()" -is equal to that stored by \b field. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2 - - -\subsubsection cpp_mcfielddouble_getValueOn Getting a field value at a point - -First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh -constituted by 4 cells. Then we create a scalar field on cells using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_1 -Now, we want to retrieve all field values using -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn()". -The field values relate to cells, hence we will use cell barycenters to get a field -value at each cell. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_2 -We collected all values returned by -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn()" in an array, so -that we can ascertain that the array of returned values is same as that stored by \b -field. - - -\subsubsection cpp_mcfielddouble_getValueOnPos Getting a value of field lying on a structured mesh - -First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh -constituted by 4 cells. Then we create a scalar field on cells using -\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1 -Now, we retrieve a field value relating to the cell #3 (this cell has a structured indexed -(1,1)). For that we use -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnPos "getValueOnPos()" where we -pass the structured indexed of the cell: 1,1,-1 (the last index is meaningless as the -mesh is 2D). -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2 -After all we ascertain that the returned value corresponds to the expression used for -the field creation. Namely that the value equals to the sum of components of -barycenter of cell #3. diff --git a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesfooter.doxy b/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesfooter.doxy deleted file mode 100644 index d7365df16..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesfooter.doxy +++ /dev/null @@ -1,2 +0,0 @@ - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesheader.doxy b/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesheader.doxy deleted file mode 100644 index cd385bcd1..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesheader.doxy +++ /dev/null @@ -1,2 +0,0 @@ -/*! -\page medcouplingcppexamples MEDCoupling C++ examples diff --git a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesmeshes.doxy b/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesmeshes.doxy deleted file mode 100644 index 166b7a209..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesmeshes.doxy +++ /dev/null @@ -1,676 +0,0 @@ - -\section ExamplesMeshes Meshes - -\subsection ExamplesMeshesCreate Create - -\subsubsection medcouplingcppexamplesUmeshStdBuild1 Standard build of an unstructured mesh from scratch - -Firstly retrieve basic data in full interlace mode for coordinates, and nodal connectivity cell per cell. -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_1 - -Then create ParaMEDMEM::MEDCouplingUMesh instance giving its mesh dimension (2 here) and a name. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_2 - -Gives an upper bound of the number of cells to be inserted into the unstructured mesh. -\n Then enter nodal connectivity of all cells, cell per cell using ParaMEDMEM::MEDCouplingUMesh::insertNextCell method. -\n When the nodal connectivity cell per cell has been finished, call ParaMEDMEM::MEDCouplingUMesh::finishInsertingCells method in order to restore \b mesh instance. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_3 - -At this level the connectivity part of the mesh \b mesh as been defined. Now let's set the coordinates using array \b coords defined above. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_4 - -At this level mesh is usable. When this mesh is no more needed simply call decrRef to decrement its reference counter. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshStdBuild1_5 - - -\subsubsection medcouplingcppexamplesUmeshAdvBuild1 Advanced build of an unstructured mesh from scratch - -Firstly retrieve basic data in full interlace mode for coordinates, and nodal connectivity cell per cell, cell type \b included (3 for INTERP_KERNEL::NORM_TRI3 and 4 for INTERP_KERNEL::QUAD4). -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_1 - -Then create ParaMEDMEM::MEDCouplingUMesh instance giving its mesh dimension (2 here) and a name. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_2 - -Then enter nodal connectivity at once. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_3 - -At this level the connectivity part of the mesh \b mesh as been defined. Now let's set the coordinates using array \b coords defined above. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_4 - -At this level mesh is usable. When this mesh is no more needed simply call decrRef() to decrement its reference counter. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_5 - - -\subsubsection medcouplingcppexamplesCmeshStdBuild1 Standard build of an cartesian mesh from scratch - -We are going to build a 2D cartesian mesh, constituted from 9 nodes along X axis, and 7 nodes along Y axis. - -Firstly retrieve for each direction the discretization and build a \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instance" on the corresponding direction. - -\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_1 - -Then create ParaMEDMEM::MEDCouplingCMesh instance giving the 2 instances of \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" obtained above. - -There are 2 techniques to get it. - -Either : - -\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_2 - -Or : - -\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_2bis - -\c mesh is now available for use : - -\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_3 - -When this mesh is no more needed simply call decrRef to decrement its reference counter (nothing -to be done in Python). - -\snippet MEDCouplingExamplesTest.cxx CppSnippetCMeshStdBuild1_4 - - -\subsubsection cpp_mcumesh_buildBoundaryMesh Getting a bounding mesh - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::buildBoundaryMesh "buildBoundaryMesh()" to get a mesh -of lower dimension bounding \b mesh. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2 -Depending on the value of a parameter, -\ref ParaMEDMEM::MEDCouplingUMesh::buildBoundaryMesh "buildBoundaryMesh()" -creates the mesh sharing the node coordinates array with \b mesh or not. - - -\subsubsection cpp_mcumesh_buildFacePartOfMySelfNode Retrieving a lower dimension mesh based on given nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1 -In the following code we retrieve nodes of the cell #0 an then we call -\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" -twice with these nodes and with varying last parameter \b allNodes as input. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2 -
If the last parameter is \c true -\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" looks -for segements whose all nodes are given to it, hence it finds segments bounding the cell #0 only. -
If the last parameter is \c false -\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" looks -for any segment whose nodes are given to it, hence it adds more segments to \b mesh2. - - -\subsubsection cpp_mcumesh_buildPartOfMySelfNode Copying cells selected by nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1 -In the following code we retrieve nodes of the cell #0 an then we call -\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" -twice with these nodes and with varying last parameter \b allNodes as input. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2 -
If the last parameter is \c true -\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" looks -for cells whose all nodes are given to it, hence it finds the cell #0 only. -
If the last parameter is \c false -\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" looks -for any cell whose nodes are given to it, hence it finds all cells of \b mesh because all -cells share the node #4. - - -\subsubsection cpp_mcumesh_buildPartOfMySelf Getting a part of mesh - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelf "buildPartOfMySelf()" to get a mesh -containing only two cells of \b mesh. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2 - - -\subsection ExamplesMeshesModify Modify - -\subsubsection cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells Fixing orientation of "extruded" volumes - -First, we create a mesh with 2 incorrectly oriented "extruded" volumes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1 -Now we check that -\ref ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells "findAndCorrectBadOriented3DExtrudedCells()" -finds and fixes the reversed cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2 - - -\subsubsection cpp_mcumesh_arePolyhedronsNotCorrectlyOriented Fixing orientation of polyhedra - -First, we create a mesh with 2 polyhedra, one of which is incorrectly oriented. We create -two "extruded" polyhedra and then convert them to correctly defined polyhedra. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1 -Now we check that -\ref ParaMEDMEM::MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented "arePolyhedronsNotCorrectlyOriented()" -finds one reversed cell. After that we fix it using -\ref ParaMEDMEM::MEDCouplingUMesh::orientCorrectlyPolyhedrons "orientCorrectlyPolyhedrons()" and -re-check the orientation of polyhedra. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2 - - -\subsubsection cpp_mcumesh_are2DCellsNotCorrectlyOriented Fixing orientation of faces - -First, we create a 2D mesh in 3D space with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is -reversed comparing with others. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1 -Now we check that -\ref ParaMEDMEM::MEDCouplingUMesh::are2DCellsNotCorrectlyOriented "are2DCellsNotCorrectlyOriented()" -finds one reversed face. After that we fix the incorrectly oriented cell using -\ref ParaMEDMEM::MEDCouplingUMesh::orientCorrectly2DCells "orientCorrectly2DCells()" and -re-check the orientation of cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2 - - -\subsubsection cpp_mcumesh_renumberNodesInConn Renumbering nodes in the connectivity array - -First, we create a 2D mesh with 1 QUAD4 cell and with undefined coordinates of nodes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn()" -to get the following nodal connectivity of a sole cell: 0,1,2,3. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2 -\b old2newIds array defines how node ids are changed: -- new id of node #0 is -1, -- new id of node #1 is 3, -- new id of node #2 is 4, -- new id of node #3 is 1, -- new id of node #4 is 0. - - -\subsubsection cpp_mcumesh_renumberNodes Renumbering nodes - -First, we create a 2D mesh with 4 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_1 -Next, we use -\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()" -to permute nodes so that -- old node #0 becomes #2, -- old node #1 remains #1, -- old node #2 becomes #0, -- old node #3 is removed. - -Number of nodes becomes 3. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_2 - -Next we compare behavior of -\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()" and that of -\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes2 "renumberNodes2()" which, in contrast to -\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()", -moves merged nodes to their barycenter.
-We set #2 as new id of old node #3 and expect that -\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes2 "renumberNodes2()" moves old nodes #0 -and #3 to their barycenter (-0.3,0.0) which becomes position of node #2.
-\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_3 - - -\subsubsection cpp_mcumesh_mergeNodes Merging equal nodes - -First, we create a 2D mesh with 1 QUAD4 and 2 TRI3 cells. The cells are based on 6 nodes -of which 2 nodes fully coincide (#3 and #4) and 3 nodes are equal with precision 0.003. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_1 -Now we merge node duplicates using -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" and check values it returns. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_2 -Contents of \b arr shows ids of old nodes after the merging. The nodes considered equal -one to the other have the same id in \b arr. - -Next we compare behavior of -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" and that of -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes2 "mergeNodes2()" which, in contrast to -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()", -moves merged nodes to their barycenter.
We expect that -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes2 "mergeNodes2()" moves old nodes #0, #2 -and #5 to their barycenter equal to position of node #2.
-First we check that -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" does not move nodes -coincident with the node #2 to the position of node #2, and then we check that -\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes2()" does move. -(We check only the second (Y) component of node coordinates since the first component of -these nodes is exactly same.) -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_3 - - -\subsubsection cpp_mcumesh_zipConnectivityTraducer Removing cell duplicates - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells, so that -- the cell #2 has the same nodal connectivity as the cell #1 does, -- the cell #3 has the same nodal connectivity as the cell #0 does, -- the cell #4 is based on the same nodes as the cell #0 but nodes order is different. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer "zipConnectivityTraducer()" -to remove duplicate cells. Then we check that two cells, having exactly same nodal -connectivity with other cells, have been removed. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2 -Contents of \b arr shows ids of cells after duplicates removal. If a value (cell id) -equals to its index in \b arr, this means that the cell is not a duplicate of any cell -with lower id. Else, the value gives a cell id to which this cell is equal.
-Thus, the cells #0 and #1 have no preceding equal cell since \b arr[i] == i.
-The cell #2 equals to the cell #1 (== \b arr[2] ).
-The cell #3 equals to the cell #0 (== \b arr[3] ).
-The cell #4 has no equal cell. This is because the cell comparison technique specified -when we called -\ref ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer "zipConnectivityTraducer()" -was 0 ("exact"), if we had used the technique 2 ("nodal"), \b arr[4] would be 0. - - -\subsubsection cpp_mcumesh_zipCoordsTraducer Removing unused nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1 -Now we create \b mesh2 including all nodes but only two cells of \b mesh, and we use \ref -ParaMEDMEM::MEDCouplingUMesh::zipCoordsTraducer "zipCoordsTraducer()" to remove unused -nodes from \b mesh2. -\ref ParaMEDMEM::MEDCouplingUMesh::zipCoordsTraducer "zipCoordsTraducer()" returns an array -with -1 for unused nodes and new ids for used ones. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2 - - -\subsubsection cpp_mcumesh_getNodeIdsInUse Retrieving unused nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1 -Now we create \b mesh2 including all nodes but only two cells of \b mesh, and we use \ref -ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" to get nodes of \b mesh2 -used in its two cells. -\ref ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" returns an array -with -1 for unused nodes and new ids for used ones. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2 -Now we use \b newNbOfNodes returned by -\ref ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" to convert \b arr -to "New to Old" mode. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3 - - -\subsubsection cpp_mcumesh_convertToPolyTypes Conversion of cells to "poly" types - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1 -Now we convert cells #1 and #3 to type POLYGON and check the result -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2 - - -\subsubsection cpp_mcpointset_scale Scaling the mesh - -First, we create a 2D mesh with 4 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_1 -Then we scale it by a factor of 2 with a center (0.,0.). -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_2 -Finally we check that all node coordinates have changed by more than 0.9. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_3 - - -\subsubsection cpp_mcpointset_translate Translating the mesh - -First, we create a 2D mesh with 4 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_1 -Then we translate it by a vector (1.,1.). -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_2 -Finally we check that all node coordinates have changed by more than 0.9. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_3 - - -\subsubsection cpp_mcpointset_rotate Rotating the mesh - -First, we create a 2D mesh with 4 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_1 -Then we rotate it around a point (0.,0.) by 90 degrees clockwise. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_2 -Next, we make a 3D mesh from the 2D one and rotate it around the Z axis by 90 degrees -counter-clockwise. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_3 -Finally we transform the mesh back to 2D space and check that all nodes get back to the -initial location. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_4 - - -\subsection ExamplesMeshesAccess Access - -\subsubsection cpp_mccmesh_getCoordsAt Getting node coordinates along an axis - -We create an 1D Cartesian mesh and retrieves node coordinates using -\ref ParaMEDMEM::MEDCouplingCMesh::getCoordsAt "getCoordsAt()". -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingCMesh_getCoordsAt_1 - - -\subsubsection cpp_mcpointset_getcoordinatesofnode Getting coordinates of a node - -The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh -"MEDCouplingUMesh" with 3 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1 -Here we get coordinates of the second node and check its two coordinates. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2 - - -\subsubsection cpp_mcumesh_areCellsIncludedIn Cells correspondence in two meshes - -First, we create a 2D \b mesh1 with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1 -Then we create a \b mesh2 which includes cells #4, #2 and #0 of \b mesh1. The two meshes -share the same node coordinates array. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2 -Now we ascertain that -- \ref ParaMEDMEM::MEDCouplingUMesh::areCellsIncludedIn "areCellsIncludedIn()" -detects that all cells of \b mesh2 are present in \b mesh1, -- the correspondence array \b corr2to1, which gives cell ids of \b mesh2 within -\b mesh1, is equal to the array \b cells2 which selected cells from \b mesh1 for creation -of \b mesh2. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3 -Now we apply -\ref ParaMEDMEM::MEDCouplingUMesh::areCellsIncludedIn "areCellsIncludedIn()" -in a reverse direction and ascertain that it returns \c false. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4 -The contents of the correspondence -array \b corr1to2 [2, 3, 1, 4, 0] means the following. -- The cell #0 of \b mesh1 is equal to the cell #2 (== \b corr1to2[ 0 ]) of \b mesh2. -- The cell #1 of \b mesh1 is missing from \b mesh2 (as \b corr1to2[ 1 ] >= \b mesh2->getNumberOfCells()). -- The cell #2 of \b mesh1 is equal to the cell #1 (== \b corr1to2[ 2 ]) of \b mesh2. -- The cell #3 of \b mesh1 is missing from \b mesh2 (as \b corr1to2[ 3 ] >= \b mesh2->getNumberOfCells()). -- The cell #4 of \b mesh1 is equal to the cell #0 (== \b corr1to2[ 4 ]) of \b mesh2. - - -\subsubsection cpp_mcumesh_checkDeepEquivalWith Deep comparison of meshes - -First, we create two 2D meshes with two triangles, so that -- their nodes are almost same but permuted, -- the first triangle is based exactly on the same nodes (taking the permutation into account), -- an order of nodes in the second triangle is changed. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1 -Then we check that -- \ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalWith "checkDeepEquivalWith()" -considers the meshes equal (i.e. it does not throw any exception) if it is called with a cell -comparison policy \b cellCompPol == 1 -- mapping from \b mesh1 to \b mesh2 for both nodes and cells is as expected. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2 -Next we ascertain that -\ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith "checkDeepEquivalOnSameNodesWith()" -consider \b mesh1 and \b mesh2 different as they do not share the same nodal connectivity -array.
-After that we make the meshes share the node coordinates array and insert new -triangles based on the same nodes but in different order. This is to ascertain that -\ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith "checkDeepEquivalOnSameNodesWith()" -called with the weakest cell comparison policy considers the meshes equal. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3 - - -\subsubsection cpp_mcumesh_getPartBarycenterAndOwner Getting barycenters of cells - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::getPartBarycenterAndOwner "getPartBarycenterAndOwner()" to get -barycenters of all but the first cell. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_3 -The returned array contains 4 tuples per 2 components. - - -\subsubsection cpp_mcumesh_getCellsContainingPoints Finding cells containing a point (multi-point case) - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1 -Then we use -\ref ParaMEDMEM::MEDCouplingUMesh::getCellsContainingPoints "getCellsContainingPoints()" to -get cells in contact with tree points. Two of them are in contact with some cells and one is not. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2 -The contents of the result arrays \b cells ([4, 0, 1]) and \b cellsIndex ([0, 0, 1, 3]) -mean the following. -- Point #0 is in contact with none (== \b cellsIndx[1] - \b cellsIndx[0]) cell. -- Point #1 is in contact with 1 (== \b cellsIndx[2] - \b cellsIndx[1]) cell whose id is #4 - (== \b cells[ \b cellsIndx[ 1 ]]). -- Point #2 is in contact with 2 (== \b cellsIndx[3] - \b cellsIndx[2]) cells whose ids are #0 - (== \b cells[ \b cellsIndx[ 2 ]]) and #1 (== \b cells[ \b cellsIndx[ 2 ] + 1 ]). - - -\subsubsection cpp_mcumesh_getCellsContainingPoint Finding cells containing a point - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1 -Then we use -\ref ParaMEDMEM::MEDCouplingUMesh::getCellsContainingPoint "getCellsContainingPoint()" to -get cells in contact with a small ball (point with precision) located near the node #4 and -shifted from this node by its radius \b eps. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2 -Since the node #4 is shared by all cells, size of the vector \b cellIds must be equal to -the number of cells in \b mesh. - - -\subsubsection cpp_mcumesh_buildPartOrthogonalField Getting normals of cells - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is -reversed. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField "buildPartOrthogonalField()" to get -normal vectors to the cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2 - - -\subsubsection cpp_mcumesh_getPartMeasureField Getting volumes of cells - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is -reversed. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField "getPartMeasureField()" to get -volumes of all but the first cell. If we call -\ref ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField "getPartMeasureField()" with \b -isAbs == \c true, the area of the cell #1 is returned positive, else, negative that -reflects its inverse orientation. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_2 - - -\subsubsection cpp_mcumesh_getCellsInBoundingBox Getting cells using the bounding box - -First, we create a 2D mesh with 1 TRI3 cell. Bounding box of this cell is [0.,0., 1.,1]. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1 -Now we check how -\ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" -searches for cells using the bounding box. We use a bounding box touching the bounding box -of the sole cell at one point (1.,1.). -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2 -If \ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" is -called with parameter \b eps == 0.0, the cell is not found because the two bounding boxes -(one of the cell and the one passed as parameter) do not overlap.
-If \ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" is -called with parameter \b eps == 0.1, the cell is found because \b eps is used to increase -the bounding box of the cell and thus the two bounding boxes intersect each other.
- - -\subsubsection cpp_mcumesh_findBoundaryNodes Getting boundary nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1 -Now we use -\ref ParaMEDMEM::MEDCouplingUMesh::findBoundaryNodes "findBoundaryNodes()" to get ids -of boundary nodes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2 -\ref ParaMEDMEM::MEDCouplingUMesh::findBoundaryNodes "findBoundaryNodes()" returns all -node ids except the node #4 which is in the middle of \b mesh. - - -\subsubsection cpp_mcumesh_getCellIdsLyingOnNodes Getting cells by nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1 -In the following code we retrieve nodes of the cell #0 an then we call -\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" -twice with these nodes and with varying last parameter \b allNodes as input. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2 -
If the last parameter is \c true -\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" looks -for cells whose all nodes are given to it, hence it finds the cell #0 only. -
If the last parameter is \c false -\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" looks -for any cell whose nodes are given to it, hence it finds all cells of \b mesh because all -cells share the node #4. - - -\subsubsection cpp_mcumesh_getCellIdsFullyIncludedInNodeIds Getting cells by nodes - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1 -In the following code we retrieve nodes of two cells an then we use -\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds -"getCellIdsFullyIncludedInNodeIds()" to find these cells by their nodes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2 - - -\subsubsection cpp_mcumesh_buildDescendingConnectivity2 Retrieving the descending connectivity with orientation - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1 -Now we get and check the descending connectivity. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2 -Here we get connectivity of the cell #2 (#3 in FORTRAN mode) of \b mesh2 to see how -mutual orientation of cells in \b mesh and \b mesh2 is defined. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3 -The contents of the result arrays \b desc and \b descIndx mean the following. -- The cell #0 of \b mesh (QUAD4) is bound by 4 (== \b descIndx[1] - \b descIndx[0]) - segments (SEG2) of \b mesh2 whose ids in FORTRAN mode are - - #1 (== \b desc[ \b descIndx[ 0 ]]), - - #2 (== \b desc[ \b descIndx[ 0 ] + 1 ]), - - #3 (== \b desc[ \b descIndx[ 0 ] + 2 ]) and - - #4 (== \b desc[ \b descIndx[ 0 ] + 3 ]). -
Ids are positive since order of nodes in the corresponding cells of \b mesh and \b mesh2 - are same. For example nodes of SEG2 #3 are [4,1] and nodes of QUAD4 #0 are [0,3,\b 4,\b 1]. -- The cell #1 of \b mesh (TRI3) is bound by 3 (== \b descIndx[2] - \b descIndx[1]) segements of - \b mesh2 whose ids in FORTRAN mode are: - - #-3 (== \b desc[ \b descIndx[ 1 ]]), - - #5 (== \b desc[ \b descIndx[ 1 ] + 1 ]) and - - #6 (== \b desc[ \b descIndx[ 1 ] + 2 ]). -
The id -3 means that order of nodes in SEG2 #3 ([4,1]) is different from the order of - these nodes in TRI3 #1: [\b 1,\b 4,2]. -- etc. - -The contents of the result arrays \b revDesc and \b revDescIndx mean the following. -- The cell #0 of \b mesh2 (SEG2) bounds 1 (== \b revDescIndx[1] - \b revDescIndx[0]) cell of \b - mesh whose id is: - - # 0 (== \b revDesc[ \b revDescIndx[ 0 ]]). -- The cell #1 of \b mesh2 bounds 2 (== \b revDescIndx[2] - \b revDescIndx[1]) cells of \b - mesh whose ids are: - - # 0 (== \b revDesc[ \b revDescIndx[ 1 ]]) and - - # 1 (== \b revDesc[ \b revDescIndx[ 1 ] + 1 ]). -- etc. - - -\subsubsection cpp_mcumesh_buildDescendingConnectivity Retrieving the descending connectivity - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1 -Now we get and check the descending connectivity. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2 -The contents of the result arrays \b desc and \b descIndx mean the following. -- The cell #0 of \b mesh (QUAD4) is bound by 4 (== \b descIndx[1] - \b descIndx[0]) - segments (SEG2) of \b mesh2 whose ids are - - #0 (== \b desc[ \b descIndx[ 0 ]]), - - #1 (== \b desc[ \b descIndx[ 0 ] + 1 ]), - - #2 (== \b desc[ \b descIndx[ 0 ] + 2 ]) and - - #3 (== \b desc[ \b descIndx[ 0 ] + 3 ]). -- The cell #1 of \b mesh (TRI3) is bound by 3 (== \b descIndx[2] - \b descIndx[1]) segements of - \b mesh2 whose ids are: - - #2 (== \b desc[ \b descIndx[ 1 ]]), - - #4 (== \b desc[ \b descIndx[ 1 ] + 1 ]) and - - #5 (== \b desc[ \b descIndx[ 1 ] + 2 ]). -- etc. - -The contents of the result arrays \b revDesc and \b revDescIndx mean the following. -- The cell #0 of \b mesh2 (SEG2) bounds 1 (== \b revDescIndx[1] - \b revDescIndx[0]) cell of \b - mesh whose id is: - - # 0 (== \b revDesc[ \b revDescIndx[ 0 ]]). -- The cell #1 of \b mesh2 bounds 2 (== \b revDescIndx[2] - \b revDescIndx[1]) cells of \b - mesh whose ids are: - - # 0 (== \b revDesc[ \b revDescIndx[ 1 ]]) and - - # 1 (== \b revDesc[ \b revDescIndx[ 1 ] + 1 ]). -- etc. - - -\subsubsection cpp_mcumesh_getReverseNodalConnectivity Getting the reverse nodal connectivity - -First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1 -Now we get and check its reverse nodal connectivity. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2 -The contents of the result arrays mean the following. -- Node #0 is shared by 1 (== \b revNodalIndx[1] - \b revNodalIndx[0]) cell whose id is #0 - (== \b revNodal[ \b revNodalIndx[ 0 ]]). -- Node #1 is shared by 2 (== \b revNodalIndx[2] - \b revNodalIndx[1]) cells whose ids are #0 - (== \b revNodal[ \b revNodalIndx[ 1 ]]) and #1 (== \b revNodal[ \b revNodalIndx[ 1 ] + 1 ]). -- etc. - - -\subsubsection cpp_mcpointset_getBoundingBox Getting a minimum box bounding nodes - -First, we create a 3D mesh with 2 nodes, so that the first one has minimal coordinates and -the second one has maximal coordinates. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getBoundingBox_1 -Now we get a bounding box enclosing these nodes. This bounding box should contain -coordinates of our two nodes (but in "no interlace" mode), as the nodes coincide with -points returned by the bounding box. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getBoundingBox_2 - - -\subsubsection cpp_mcpointset_getnodeidsnearpoint Getting nodes close to a point - -The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh -"MEDCouplingUMesh" with 5 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1 -Now we define an array of coordinates of a point close to nodes #0, #2 and #4. - -Thus we expect that -\ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoint "getNodeIdsNearPoint()" that -we are going to use, -if called with \b eps = 0.003, would return ids of nodes #0, #2 and #4. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2 - - -\subsubsection cpp_mcpointset_getnodeidsnearpoints Getting nodes close to some points - -The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh -"MEDCouplingUMesh" with 7 nodes and no cells. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1 -Now we define an array of coordinates of 3 points near which we want to find nodes of the mesh. -- Point #0 is at distance 0.001 from the node #1. -- Point #1 is rather far from all nodes. -- Point #2 is close to nodes #3, #4 and #5. - -Thus we expect that -\ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoints "getNodeIdsNearPoints()" that -we are going to use, -if called with \b eps = 0.003, would return ids of close nodes #1, #3, #4 and #5. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2 -\b idsIndex returns [0, 1, 1, 4] which means that: -- Point #0 is close to 1 (== \b idsIndex[1] - \b idsIndex[0]) node whose id is -\b ids[ \b idsIndex[ 0 ]]. -- Point #1 is close to 0 (== \b idsIndex[2] - \b idsIndex[1]) nodes. -- Point #2 is close to 3 (== \b idsIndex[3] - \b idsIndex[2]) nodes whose ids are -\b ids[ \b idsIndex[ 2 ]], \b ids[ \b idsIndex[ 2 ] + 1 ] and \b ids[ \b idsIndex[ 2 ] + 2 ]. - - -\subsubsection cpp_mcpointset_findcommonnodes Finding coincident nodes - -First, we create a mesh with 6 nodes, of which two nodes (#3 and #4) are fully coincident -and 3 nodes (#0, #2 and #5) have distance less than 0.004 between them. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_findCommonNodes_1 -Then, we use \ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes()" to find -coincident nodes, and check that (1) calling -\ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes()" with \b prec -== 1e-13 finds the two fully coincident nodes only and (2) -\ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes"(0.004) finds 5 -equal nodes. -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_findCommonNodes_2 diff --git a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesother.doxy b/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesother.doxy deleted file mode 100644 index 551ca72e5..000000000 --- a/medtool/doc/user/doxygen/doxfiles/examples/medcouplingexamplesother.doxy +++ /dev/null @@ -1,260 +0,0 @@ - -\section ExamplesOther Other - -\subsection ExamplesOtherInputOutput Input/Output - -\subsubsection cpp_mcfielddouble_WriteVTK Writing fields in a VTK file - -In this example we -- create an 2D mesh and 3 fields on it, -- use -\ref ParaMEDMEM::MEDCouplingFieldDouble::WriteVTK "WriteVTK()" -to write all the fields and the mesh to a VTK file. - -\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_WriteVTK_1 - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection MEDLoaderExample2 Loading a mesh using basic API - -Consider a mesh called "Example2" in file "file2.med" -containing MED_POLYHEDRA, MED_TETRA4, MED_QUAD8, MED_TRI6, MED_SEG2 -and MED_POINT1. In this case you will have : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_8 - -To get 3D cells (MED_POLYHEDRA and MED_TETRA4) you should type : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_7 - -To get 2D cells (MED_TRI6 and MED_QUAD8) you should type : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_4 - -To get 1D cells (MED_SEG2) you should type : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_5 - -And finally for 0D cells (MED_POINT1) you will write : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_6 - -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcumesh_writefile_onemesh_basic Writing one mesh using basic API - -To write one mesh \b myMesh with name \b "myMeshName" in a MED file \b "wfile1.med" the following code should be typed : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_1 - -With the previous code, if "wFile1.med" file exists the file is -crashed and will contain after the call only the contents of myMesh -instance. - -If you want to append a mesh in "wFile1.med" you should type : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_2 - -With the previous code, if the "wFile1.med" has already a mesh called "myMeshName" an -INTERP_KERNEL::Exception will be thrown. -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_CPP_ONLY -\subsubsection cpp_mcumesh_loadfile Loading a mesh using advanced API - -\code - -const char fileName[]=...; -const char meshName[]=...; -MEDFileUMesh *medmesh=MEDFileUMesh::New(fileName,meshName); -std::vector nel=medmesh->getNonEmptyLevels(); -if(nel.size()<1) - throw INTERP_KERNEL::Exception("The test is not good for my file ! Expecting a multi level mesh to play with !"); -MEDCouplingUMesh *m0=medmesh->getMeshAtLevel(nel[1],false); -MEDCouplingUMesh *g1=medmesh->getGroup(nel[1],"mesh2",false); -DataArrayInt *dag1=medmesh->getGroupArr(nel[1],"mesh2",false); -MEDCouplingUMesh *g1bis=m0->buildPartOfMySelf(dag1->getConstPointer(),dag1->getConstPointer()+dag1->getNbOfElems()); -g1bis->setName(dag1->getName()); -if(!g1->isEqual(g1bis,1e-12)) - throw INTERP_KERNEL::Exception("hmmmm :g1 and g1bis should be equal..."); -// -dag1->decrRef(); -g1->decrRef(); -m0->decrRef(); -medmesh->decrRef(); - -\endcode -\anchor END_CPP_ONLY - -\anchor BEGIN_CPP_ONLY -\subsubsection cpp_mcumesh_writefile Writing a mesh using advanced API - -\code - -MEDCouplingUMesh *m=...; //m is a mesh with meshDim=2 spaceDim=2 -MEDCouplingUMesh *m1=...; //m1 is a mesh with meshDim=1 spaceDim=2 same coords than m -MEDCouplingUMesh *m2=...; //m2 is a mesh with meshDim=0 spaceDim=2 same coords than m -MEDFileUMesh *mm=MEDFileUMesh::New(); -mm->setName("mm");//name needed to be non empty -mm->setDescription("Description mm"); -mm->setCoords(m1->getCoords()); -mm->setMeshAtLevel(-1,m1,false); -mm->setMeshAtLevel(0,m,false); -mm->setMeshAtLevel(-2,m2,false); -DataArrayInt *g1=DataArrayInt::New(); -g1->alloc(2,1); -g1->setName("G1"); -const int val1[2]={1,3}; -std::copy(val1,val1+2,g1->getPointer()); -DataArrayInt *g2=DataArrayInt::New(); -g2->alloc(3,1); -g2->setName("G2"); -const int val2[3]={1,2,3}; -std::copy(val2,val2+3,g2->getPointer()); -// -std::vector grps(2); -grps[0]=g1; grps[1]=g2; -mm->setGroupsAtLevel(0,grps,false); -// -g2->decrRef(); -g1->decrRef(); -// -mm->write(2); - -\endcode -\anchor END_CPP_ONLY - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_loadfile_onetimestep_basic Reading a field at one time step using basic API -So to retrieve a field on 3D cell called "F1Cell" in example file -"file2.med" on a mesh "Example2" (\ref MEDLoaderExample2 "as defined here") on time -step defined by iteration number 2 and iteration 3 the request will be : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_12 - -To retrieve the same field (same iteration) on 2D cells only the call will be : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_13 -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_loadfile_alltimesteps_basic Reading a field at all time steps using basic API - -It is typically recommended to use the following -code when you want to load all time steps of a field on cell "myField" lying on -same mesh "mesh1" in one shot : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_11 - -\anchor END_PYTHON_ONLY - - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_loadfile_allentities Reading a field on all entities using advanced API - -Let's read a field on all entity called \a fieldName lying on a mesh called \a meshName in a MED file called \a fname at a iteration defined on time step defined -by \a iteration and \a order. - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_1 - -To read it there are 3 main approaches : - -- Use ParaMEDMEM::MEDFileField1TS class : - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_3 - -- Use ParaMEDMEM::MEDFileFieldMultiTS class : - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_4 - -- Use iteration ParaMEDMEM::MEDFileFieldMultiTS class : - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_5 - -\anchor END_PYTHON_ONLY - - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_loadfile_partial Reading a partial field using advanced API - -Let's read a partial field called \a fieldName lying on a mesh called \a meshName in a MED file called \a fname at a iteration defined on time step defined -by \a iteration and \a order. - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_1 - -Fields defined partially on a meshes can been read using 2 main approaches : - -- Either the user wants to retrieve it's field in %MEDCoupling sense, that is to say for interpolation, to evaluate such field on different points... -\n In this mode the link with the whole mesh is not useful for the user - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_3 - -- Or the user wants to retrieve the binding (cell ids or node ids) with the whole mesh on which the partial field lies partially on. - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_4 - -\ref medcoupling "MEDCoupling" allows to make bridges between the approaches. For example \a pfl \ref ParaMEDMEM::DataArrayInt "DataArrayInt instance" retrieved directly -from the file in the second approach can be retrieved starting from first approach. - -Starting from mesh \a firstApproachMesh of read field in first approach \a fread, whith the whole mesh \a wholeMesh the profile \a pflComputed can be computed : - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_5 - -Inversely, it is possible to rebuild field obtained in first approach starting from second approach : - -\snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_6 - -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_writefile_severaltimesteps_basic Writing several time steps of a field using basic API - -To write a serie of time steps in a "file3.med" file lying on the same -unstructured mesh the typical code -to write is the following : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_3 - -In the above code, it is important to note that the values of pairs -(iteration,order) should be different between two calls to avoid that -a call to MEDLoader::WriteFieldUsingAlreadyWrittenMesh overwrites a -previous call. -Another important thing is the fact that \c f.getMesh() is not modified. -This write method presents the big advantage to be fast, because -neither check nor read is performed. That's why the parameter of \b writeFromScratch -is not needed here, contrary -to other MEDLoader::Write* methods. - -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_writefile_allentities Writing a field defined on all entities using advanced API - -Let's write a cell field on all entities called \a fieldName lying on a mesh called \a meshName in a MED file called \a fname at a iteration defined on time step defined -by \a iteration and \a order. - -\snippet MEDLoaderExamplesTest.py PySnippetWriteFieldOnAllEntity1_2 - -We can see here that the necessity to deal with both mesh and field to write a field is exposed by the API. The mesh write mode is 2 to tell to MED file that is file already exists to scratch it. -The mode of write is 0 to simply add to the file the field specific part. - -\anchor END_PYTHON_ONLY - - -\anchor BEGIN_PYTHON_ONLY -\subsubsection py_mcfield_writefile_partial Writing a partial field using advanced API - -\snippet MEDLoaderExamplesTest.py PySnippetWriteFieldPartial1_2 - -To write a partial field \a f can have a **null mesh**, because the link with mesh is made given the entry of \a mm MEDFileField1TS::setFieldProfile method. - -\anchor END_PYTHON_ONLY diff --git a/medtool/doc/user/doxygen/doxfiles/faq.dox b/medtool/doc/user/doxygen/doxfiles/faq.dox deleted file mode 100644 index 0d0937423..000000000 --- a/medtool/doc/user/doxygen/doxfiles/faq.dox +++ /dev/null @@ -1,174 +0,0 @@ -/*! - -\page faq FAQ - Frequently asked questions - -Many points covered in this FAQ are illustrated via Python scripts. Remember that the -Python API is almost 100% identical to the C++ one, with the \ref python-api "rules listed here". - -\section Questions - -\ref faq-general - -# \ref f-newbie - -# \ref f-mehsf - -# \ref f-constel - -# \ref f-visu - -# \ref f-p0p1 - -# \ref f-number - -\ref faq-python - -# \ref f-hellow - -# \ref f-pyimport - -# \ref f-meshscratch - -# \ref f-fieldscratch - -# \ref f-io - -# \ref f-coher - -# \ref f-groups - -# \ref f-unstruc - -\ref faq-interp - -# \ref f-proj - -# \ref f-proj-formula - -\ref faq-cpp - -# \ref f-cpp-guide - -# \ref f-cpp-segfault - -\section Answers -\subsection faq-general General questions -\subsubsection f-newbie "I am a complete newbie, where should I start?" -Take a look at the \ref start "getting started" section and the \ref tutorial. - -\subsubsection f-mehsf "What is a mesh, what is a field?" -Take a look at \ref terminology - -\subsubsection f-constel "What is a the difference between MED file, MEDCoupling and the SALOME MED module?" -Take a look at \ref library - -\subsubsection f-visu "How can I visualize a mesh and/or a field?" -Use the PARAVIS module of SALOME to visualize your MED file. The following dedicated fitlers have been -written specifically for MED files: Extract group, Extract cell types, ELNO Mesh, ELNO Points, ELNO Surface. - -\subsubsection f-p0p1 "What does a P0- (or P1-) field mean?" -Take a look at \ref terminology - -\subsubsection f-number "What does surjective/old-2-new/new-2-old format mean?" -Take a look at \ref numbering - -\subsection faq-python MEDCoupling scripts in Python -\subsubsection f-hellow "Can you show me a simple example to get me started" -TODO - - -\subsubsection f-pyimport "When trying to execute my Python script I have 'ImportError: No module named MEDCoupling'" -Check that the environment variables PYTHONPATH and LD_LIBRARY_PATH (PATH under Windows) are correctly set. -If you have a full SALOME installation, use the 'shell' command that will automatically set up everything as it -should be: -\code{.sh} -cd -salome shell -\endcode - -With a custom installation you may want to set the variable manually: -\code{.sh} -export PYTHONPATH=/lib/python2.7/site-packages/salome -export LD_LIBRARY_PATH=/lib/salome -\endcode - -\subsubsection f-meshscratch "How to build a mesh from scratch" -Take a look at this example: \ref medcouplingpyexamplesUmeshStdBuild1 - -\subsubsection f-fieldscratch "How to build a field from scratch" -Take a look at this example: \ref medcouplingpyexamplesFieldDoubleBuild1 - -\subsubsection f-io "How to write/read a mesh to/from a file" -For starter, take a look at the \ref MEDLoaderBasicAPIPage "basic MEDLoader API". - -\subsubsection f-coher "How to control the validity of my mesh" -Use the methods \ref ParaMEDMEM::MEDCouplingUMesh::checkCoherency() "MEDCouplingUMesh::checkCoherency()" or -\ref ParaMEDMEM::MEDCouplingUMesh::checkCoherency1() "MEDCouplingUMesh::checkCoherency1()" - -\subsubsection f-groups "How can I read/write groups on a mesh" -Take a look at \ref AdvMEDLoaderAPIMeshReading and \ref AdvMEDLoaderAPIMeshWriting. - -\subsubsection f-unstruc "How can I transform a structured mesh into an unstructured one" -Use the method \ref ParaMEDMEM::MEDCouplingCMesh::buildUnstructured() "MEDCouplingCMesh::buildUnstructured()" - -\subsection faq-interp Projection, interpolation, remapping -\subsubsection f-proj How to project a field from one mesh to the other -This the job of the interpolation algorithms in the MED library. For starters, take a look at the -\ref interpolation "general introduction on interpolation". Also -\ref cpp_mcfield_remapper_highlevel "this simple example" gives a good first illustration. -Finally, if you are intereseted in parallel projection (C++ only!), you should take a -look at the \ref para-dec "DEC". - -\subsubsection f-proj-formula Which formula are used in the field projection algorithms -The documentation for non \ref glossary "P0 field" (i.e. non \ref glossary "cell-based fields") is still an -on-going work, but for the P0->P0 case, \ref InterpKerRemapGlobal "this page" gives a good overview. - -\subsection faq-cpp C++ specific questions -\subsubsection f-cpp-guide Is there some coding guidelines that I should follow -Yes. Please: -- document your code (this is true for Python too!) -- write some tests (this is true for Python too!) -- and finally, take a look at the page \ref cpp - -\subsubsection f-cpp-segfault My C++ program produces a SIGSEGV, what should I do -Re-compile in debug mode (with \c CMAKE_BUILD_TYPE=Debug), and use either valgrind or gdb -to spot the place where the segfault happens. -The most common source of mistake is some memory mis-allocation and/or deallocation. -With this respect using the auto pointer class -\ref ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr "MEDCouplingAutoRefCountObjectPtr" -can be of great help. - -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n - -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n - - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/gui.dox b/medtool/doc/user/doxygen/doxfiles/gui.dox deleted file mode 100644 index fe63dd880..000000000 --- a/medtool/doc/user/doxygen/doxfiles/gui.dox +++ /dev/null @@ -1,23 +0,0 @@ -/*! -\page gui Graphical user interface - -

A graphical interface for standard use cases

- -The MED module in SALOME comes with a graphical interface that helps -you deal with the most standard use cases of field manipulation. The -user guide can be found here: - -- User guide of the MED Graphical Interface - -You could also be interested to read the software specifications and -requirements for this graphical module, and even the technical -considerations for development: - -- Software - specifications and requirements of the MED Graphical Interface (in french) -- Developer guide of the MED Graphical Interface (in french) - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/index.dox b/medtool/doc/user/doxygen/doxfiles/index.dox deleted file mode 100644 index fd9b49a8e..000000000 --- a/medtool/doc/user/doxygen/doxfiles/index.dox +++ /dev/null @@ -1,59 +0,0 @@ -/*! - -\mainpage Welcome to MEDCoupling! - -The MED module gathers several powerful functionalities around the input and output data of -simulation codes (meshes and fields mainly). - -\image html projectionHQ_600.png "Example of a field interpolation between two 3D surfacic meshes" - -The most common usage is to write dedicated code (C++ or Python) linking to the library, -however a \ref gui "graphical user interface" is also available. - -- If you don't know where to start, reading the \ref start "getting started" section and then -taking a look at the tutorial is probably a good way to go. -- If you are looking for a very specific point (how can I build a mesh from scratch, - how do I write my data to a file, etc ...), taking a look at the \ref faq "FAQ" or at the numerous - \ref examples "code examples" might help. -- Finally people looking for the reference documentation of a given function (in C++ or Python) should -take a look at the \ref ParaMEDMEM "API documentation". Only the C++ functions are documented, but -the Python API has been designed to be used in a very similar fashion, provided you are aware of the -\ref python-api "conventions used". - -\section contents Contents -This documentation is organized as follows: -- \ref index (this page!) -- \ref faq -- \ref start - - \ref intro-start - - \ref terminology - - \ref library - - \ref functionalities - - \ref python-api -- Tutorial - MEDCoupling/MEDLoader in Python -- \ref gui -- \ref reference - - \ref medcoupling - - \ref medloader - - \ref interpolation - - \ref cpp - - \ref distrib - - \ref misc - \if ENABLE_EXAMPLES -- \ref examples - - \ref medcouplingpyexamples - - \ref medcouplingcppexamples - \endif - -- \ref appendix - - \ref glossary - - \ref med-file - - \ref install - -- \ref ParaMEDMEM "MEDCoupling (and other parallel classes) API documentation" -- \ref MEDLoader "MEDLoader API documentation" - -*/ - - - diff --git a/medtool/doc/user/doxygen/doxfiles/reference/arrays/arrays.dox b/medtool/doc/user/doxygen/doxfiles/reference/arrays/arrays.dox deleted file mode 100644 index 24eea3654..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/arrays/arrays.dox +++ /dev/null @@ -1,298 +0,0 @@ - -/*! - -\page arrays Arrays of data - -[TOC] - -\section MEDCouplingArrayIntro Introduction - -One of the most basic concept mainly used all over MEDCoupling is the -MEDCoupling array. - -This concept is used all over the -MEDCoupling, \ref parallel "ParaMEDMEM", and \ref medloader "MEDLoader" modules so it should be correctly -understood to efficiently deal with \ref meshes "Meshes" and \ref fields "Fields". - -\ref ParaMEDMEM::DataArray "DataArrays" are the atomic element of potentially heavy-memory objects in -the 3 modules mentionned above. - -There are for the moment two types of arrays : - - double precision float (64 bits) array incarnated by \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble class". - - signed integer (32 bits) array incarnated by \ref ParaMEDMEM::DataArrayInt "DataArrayInt class". - -\ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" and \ref ParaMEDMEM::DataArrayInt "DataArrayInt" classes inherits from -\ref ParaMEDMEM::DataArray "DataArray" \b non \b instantiable \b class that factorizes some common methods of inherited instantiable classes. - -In the rest of the documentation \b DataArray will be used for both \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" and \ref ParaMEDMEM::DataArrayInt "DataArrayInt". - -\section MEDCouplingArrayBasics Basics concepts of the DataArrays. - -It will be presented in this section common concept shared by the two classes to \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" and \ref ParaMEDMEM::DataArrayInt "DataArrayInt". - -\subsection MEDCouplingArrayBasicsName Name - -A \ref ParaMEDMEM::DataArray "DataArray" instance has an attribute **name**. - -**name** is particularly useful for \ref ParaMEDMEM::DataArray "DataArray" representing profiles, families, groups, fields in MEDLoader. -But excepted these useful usecases, **name** attribute is often ignored when \ref ParaMEDMEM::DataArray "DataArrays" are aggregated (field array, connectivity, coordinates) in a bigger object. -Whatever the usage of the **name** attribute of \ref ParaMEDMEM::DataArray "DataArrays", all methods in ParaMEDMEM::DataArrayDouble and ParaMEDMEM::DataArrayInt class deal with **name** as they do for components names. - -\subsection MEDCouplingArrayBasicsTuplesAndCompo Raw data, tuples and components of DataArrays. - -The main goal of \ref ParaMEDMEM::DataArray "DataArray" is to store contiguous vector of atomical elements with same basic datatype (signed integers, double precision...). This vector of atomical elements is called **raw data** of \ref ParaMEDMEM::DataArray "DataArray". - -The size of this vector of data is called "number of elements". So the number of bytes stored by a \ref ParaMEDMEM::DataArray "DataArray" instance, is equal to -the product of the __number of elements__ * __constant size of DataType__ . - -As \ref ParaMEDMEM::DataArray "DataArray" instances are designed to store vector fields, tensor fields, coordinate of nodes, the notion of _components_ has been added. - -So, \ref ParaMEDMEM::DataArray "DataArrays" have an additional attribute that is number of components that represent the size of a contiguous set of atomical elements. -The vector of atomical elements stored into \ref ParaMEDMEM::DataArray "DataArrays" are grouped in contiguous memory set of atomical elements having each same size. - -The contiguous set of atomical elements is called **tuple**. And each **tuple** stored in raw data, has a length exactly equal to the number of components of -\ref ParaMEDMEM::DataArray "DataArray" storing it. - -Thus : - -\f[ - N_{elements}=N_{tuples}*N_{components}. -\f] - -\f[ - N_{bytes}=N_{elements}*sizeof(DataType)=N_{tuples}*N_{components}*sizeof(DataType). -\f] - -In other words, **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" can be seen as a dense matrix, whose number of components would be the row size and number of tuples -would be the column size. In this point of view of \ref ParaMEDMEM::DataArray "DataArrays" a **tuple** is represented by the corresponding row in the dense matrix. - -Typically in the **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" **number of tuples** is highly bigger than **number of components** ! - -To finish, raw data is stored tuples by tuples, in another words, in **full interlace mode**, which is the natural storage strategy in C/C++ world. - -For example, let's consider a DataArray having 3 components (called *x* for the first component, *y* for the second, and *z* for the third) and composed by 5 tuples. -\n The *raw data* of the DataAarray instance will be organized in memory like that : \f$ x_0,y_0,z_0,x_1,y_1,z_1,x_2,y_2,z_2,x_3,y_3,z_3,x_4,y_4,z_4 \f$. - - -\subsection MEDCouplingArrayBasicsCompoName Information on components name. - -As seen in the sub section above, a \ref ParaMEDMEM::DataArray "DataArray" instance has a defined number of components. - -There is an information attached to each of these components constituting the \ref ParaMEDMEM::DataArray "DataArray". - -This information is concretely a string of characters that allows, if needed, to give information about the corresponding component. - -The format chosen in **MEDCoupling** for information on is "MY_COMPO_INFO [MYUNIT]". If needed, the unit attached to the component -should be put between "[" and "]" after the information of the components after one space character. - -\subsection MEDCouplingArrayBasicsTimeLabel DataArrays and TimeLabel. - -\ref ParaMEDMEM::DataArray "DataArrays instances" can consume big amount of data in memory so they inherit from \ref MEDCouplingTimeLabelPage "TimeLabel". -So in C++ it is a good practice to use : -- \c getConstPointer method in readonly access. -- \c getPointer method only if write is needed. - -If the user in C++ or Python wants to modify intensively its **big** \ref ParaMEDMEM::DataArray "DataArray" instance **not** using raw data pointer it is better to invoke -\c setIJSilent just after invocation of \c declareAsNew instead of calling \c setIJ method that will increment time label of \ref ParaMEDMEM::DataArray "DataArray" instance -on each call. - -\c setIJ method usage should be reduced to little modification sessions. - -\section MEDCouplingArrayBuildFromScratch Building an array from scratch - -Here is a description of typical usages of \ref ParaMEDMEM::DataArrayDouble "MEDCoupling arrays". - -\if ENABLE_EXAMPLES -\ref MEDCouplingArraySteps1 "Here is a C++ example."
-\ref MEDCouplingArraySteps0 "Here is a Python example."
-\endif - -\section MEDCouplingArrayBasicsCopy Copy DataArrays - -As \ref ParaMEDMEM::DataArray "DataArrays" are the atomic entity of potentially big memory objects into \ref medcoupling "MEDCoupling" -, \ref ParaMEDMEM::DataArray "DataArrays" introduces concepts of copy and comparison that will be used by aggregating classes. - -For more complex objects (that aggregate themselves big objects) -like ParaMEDMEM::MEDCouplingFieldDouble the concept of copy (shallow or deep) is less straight forward because which aggregated subobjects are copied or not. - -\subsection MEDCouplingArrayBasicsCopyDeep Deep copy of DataArray - -As for all potentially heavy memory consumer objects in \ref medcoupling "MEDCoupling", \ref ParaMEDMEM::DataArray "DataArrays" implement - method \c deepCpy. This method deeply copies an instance. The life cycle of the returned object is *fully* independent from the instance on which the method -\c deepCpy has been invoked. - -\if ENABLE_EXAMPLES -\ref cpp_mcdataarray_deepcopy "Here is a C++ example."
-\endif - -\subsection MEDCouplingArrayBasicsCopyShallow Shallow copy of DataArray - -As \ref ParaMEDMEM::DataArray "DataArrays" are the atomic entity of potentially big memory objects into \ref medcoupling "MEDCoupling", the shallow copy -simply returns the same object with the reference counter incremented. - -\if ENABLE_EXAMPLES -\ref cpp_mcdataarray_shallowcopy "Here is a C++ example."
-\endif - -\section MEDCouplingArrayBasicsCompare Compare DataArrays - -Comparison is \ref medcoupling "MEDCoupling" is a concept highly sensitive because big amount of tests uses this to state about the success or the fail of these tests. -There are two types of comparison : - -- strict, that compares strictly all the non mutable attributes (state sensitive). Methods to perform this strict comparison are : - - ParaMEDMEM::DataArrayInt::isEqual - - ParaMEDMEM::DataArrayDouble::isEqual. - -- less strict, that focus only on non string attributes. Methods to perform less strict comparison are : - - ParaMEDMEM::DataArrayInt::isEqualWithoutConsideringStr - - ParaMEDMEM::DataArrayDouble::isEqualWithoutConsideringStr - -\section MEDCouplingArrayFill Filling DataArray with values - -Both DataArrayDouble and DataArrayInt provide comfort methods that -fill the array with some values. These methods are: -- ParaMEDMEM::DataArrayInt::fillWithZero and - ParaMEDMEM::DataArrayDouble::fillWithZero which assigns zero to all - values in array. -- ParaMEDMEM::DataArrayInt::fillWithValue and - ParaMEDMEM::DataArrayDouble::fillWithValue which assigns a certain value to all - values in array. -- ParaMEDMEM::DataArrayInt::iota() and - ParaMEDMEM::DataArrayDouble::iota() which assigns incrementing values to all - values in array. - -\section MEDCouplingArrayApplyFunc Application of a function on DataArrayDouble instances. - -This section is only dedicated for \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instances". - -It is possible to apply to \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instance" a function given by a string. - -There are different API for applyFunc* methods of \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble class". - -\subsection MEDCouplingArrayApplyFuncExpr Expressions supported - -In order to reduce as much as possible dependencies, a little dynamic formula interpreter has been developed into INTERP_KERNEL. -This dynamic expression evaluator can deal the following exhaustive list : - -- +,-,*,^ (^ for exponent 3^2==9) -- sin,cos,tan,sqrt,abs,exp,max,min,ln (neper logarithm), log (neper logarithm), log10 (decimal logarithm), -- >,< -- if - -The expression evaluator is also sensitive to the following var pattern : IVec, JVec, KVec, LVec,... ,ZVec - -- IVec stands for unitary vector [1,0,0,0,...] -- JVec stands for unitary vector [0,1,0,0,...] -- KVec stands for unitary vector [0,0,1,0,...] -- ... - -The dynamic expression evaluator works tuple by tuple through the *raw data* of DataArrayDouble instance. - -The principle of the dynamic expression evaluator is the following : - -- Given the input string a compilation tree is built whose leaves are either constants or variables. - At this phase only syntax errors are thrown. -\anchor MEDCouplingArrayApplyFuncExprA1 -- Then given the computed tree, a link phase is performed to accelerate evaluation. At this phase the incoherence between the number of - components and the number of variables are detected. - -- The given the preprocessed tree given an input tuple a preallocated tuple is fed with the result of the evaluation. - At this last phase only mathematical errors are thrown (division by 0, log(0), sqrt of a negative number ...) - -\subsection MEDCouplingArrayApplyFunc0 applyFunc method with only one parameter - -This method produces a newly allocated DataArrayDouble instance having exactly the same number of components **and** number of tuples than the instance on which the -\ref ParaMEDMEM::DataArrayDouble::applyFunc(const std::string &, bool) const applyFunc method is applied. - -**This method is useful when the evaluation expression do not need to consider the components of each tuple separately**. - -That's why this method of \ref ParaMEDMEM::DataArrayDouble::applyFunc(const std::string &, bool) const applyFunc method with one parameter accepts at most only one variable. - -If it is not the case an exception is thrown as seen here : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_1 - -Let's take a very simple example on a DataArrayDouble instance \c d having 4 tuples and 2 components. - -In the next example the expression contains only one variable : \c smth. -So \c smth represent a tuple of size 2. - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_2 - -As the example shows, the output \c d1 has 2 components as \c d. - -Whereas all the components of the input of \c d be not considered separately, it is also, possible with \ref ParaMEDMEM::DataArrayDouble::applyFunc(const std::string &, bool) const applyFunc method with one parameter -to build an output having same number of components than input but where components in input are treated separately. - -Let's build an example using DataArrayDouble instance \c d defined just above. - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_3 - -In this example using IVec and JVec it is possible to differentiate output in component #0 and output in component #1 for DataArrayDouble instance \c d2. - -\subsection MEDCouplingArrayApplyFunc1 applyFunc method with only two parameters - -This method also returns a newly allocated DataArrayDouble instance having the same number of tuples than the DataArrayDouble instance on which \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const std::string &, bool) const applyFunc method is called, but the contrary to previous \ref MEDCouplingArrayApplyFunc0 "applyFunc with one parameter version" here the number of components is set by the user. - -The big difference with \ref MEDCouplingArrayApplyFunc0 "applyFunc method with one parameter" seen above is that here components of tuples are treated separately. - -The method that implements it is \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const std::string &, bool) const here. - -Here the number of variables appearing in the expression should be equal at most to the number of component of the DataArrayDouble instance on which \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const std::string &, bool) const applyFunc method is called. - -Let's consider the following DataArrayDouble having 4 tuples with 3 components called dd. - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_4 - -If you intend to create a new DataArrayDouble instance called \c dd1 having only one component that is the result of the sum of first component and the square root of the second component and the third component -the invocation should be something like this : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_5 - -\warning In the expression \c "f+sqrt(g)+h", there are 3 variables \c {"g","h","f"}. As seen \ref MEDCouplingArrayApplyFuncExprA1 "in link phase in expression evaluator" it is needed to match a variable to -the component id. The strategy of expression evaluator is the following. Sort ascendingly variables using their names and affect component id following this sorted list. It leads to : -- \c f will be attached to component #0 of \c dd -- \c g will be attached to component #1 of \c dd -- \c h will be attached to component #2 of \c dd - -Considering the previous warning, let's try to perform an application of function to compute in a DataArrayDouble instance called \c dd2 starting by adding component #0 and component #2 -of \c dd. -\n -The expression \c "a+c" will add component #0 to component #1 as seen in warning section !!!! It can appear silly, but this strategy has been chosen in order to support different set of variables. -\n \ref ParaMEDMEM::DataArrayDouble::applyFunc2 "applyFunc2" and \ref ParaMEDMEM::DataArrayDouble::applyFunc3 "applyFunc3" methods have been developed to remedy to that feature that can be surprising. -\n These two methods are explained respectively \ref MEDCouplingArrayApplyFunc2 "here for applyFunc2" and \ref MEDCouplingArrayApplyFunc3 "here for applyFunc3". - -Whatever it is possible to find a workaround using \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const std::string &, bool) const applyFunc with 2 parameters. -\n Here is a solution to compute \c dd2 : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_6 - -\subsection MEDCouplingArrayApplyFunc2 applyFunc2 method - -The method that implements it is \ref ParaMEDMEM::DataArrayDouble::applyFunc2 here. - -This method is very close to \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters". - -The only difference is the mapping between variables found in expression and tuple id. Rather than using rank in string sorting as \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters uses" here the component information are considered. - -Let's consider DataArrayDouble instance \c ddd constituted with 4 tuples containing each 3 components. The components are named respectively \c {"Y","AA","GG"} with following different units attached on them. - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_7 - -To compute the sum of the first component (component #0) and the third component (component #2) simply do that : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_8 - -\subsection MEDCouplingArrayApplyFunc3 applyFunc3 method - -The method that implements it is \ref ParaMEDMEM::DataArrayDouble::applyFunc3 here. - -This method is very close to \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters" and \ref MEDCouplingArrayApplyFunc2 "applyFunc2". - -The only difference is the mapping between variables found in expression and tuple id. Rather than using rank in string sorting as in \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters uses" or the component information as in \ref MEDCouplingArrayApplyFunc2 "applyFunc2", here an explicit vector is given in input. - -Let's consider DataArrayDouble instance \c ddd constituted with 4 tuples containing each 3 components. To add first component (component #0) and the third component (component #2) simply do that : - -\snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_9 - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/arrays/numbering.dox b/medtool/doc/user/doxygen/doxfiles/reference/arrays/numbering.dox deleted file mode 100644 index 0bb506765..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/arrays/numbering.dox +++ /dev/null @@ -1,113 +0,0 @@ -/*! -\page numbering Array indexing and numbering - -The MED library make constant use of arrays of integer or double to represent the various -data it needs. The arrays of integer (\ref ParaMEDMEM::DataArrayInt "DataArrayInt") are of special importance as they -often constitutes the return value of the functions provided by the API. This can be -a list of nodes, a list of cells, a way to rearrange the cell in a mesh (a permutation), a part of the -domain when doing parallel computation, etc ... - -This page tries to cover all the form such a data can take and points to the most important -functions available to convert from one format to the other. - -Formally a "renumbering" is a mathematical application that can be surjective, injective or bijective. -This application is defined using an instance of -\ref ParaMEDMEM::DataArrayInt "DataArrayInt". There are different ways to define this application. - -\section MEDCouplingArrayRenumberingO2N Old-to-new mode - -The old to new mode is particularly recommanded for surjective and bijective applications. This -is typically the case of \ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "MEDCouplingUMesh::mergeNodes" method. -Let's consider a call to \ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes" that reduces the -number of nodes from 5 nodes to 3 nodes.\n -In old to new mode the array \b MySurjection that specifies this surjection will have 5 tuples -and 1 component. The content of the 5*1 values will be in {0,1,2}.\n - -If \b MySujection equals [2,1,0,1,2], it means that : - -- old id #0 will have new id equal to 2 -- old id #1 will have new id equal to 1 -- old id #2 will have new id equal to 0 -- old id #3 will have new id equal to 1 like old id #1 -- old id #4 will have new id equal to 2 like old id #0 - -This is the most common mode of renumbering in MEDCoupling because there is more methods -implying renumbering that reduce the number of entities than method that increase number of entities. - -Method in old to new mode that works on bijective applications : - -- \ref ParaMEDMEM::DataArrayDouble::renumber "DataArrayDouble::renumber" -- \ref ParaMEDMEM::DataArrayDouble::renumberInPlace "DataArrayDouble::renumberInPlace" - -Method in old to new mode that works on surjective applications : - -- \ref ParaMEDMEM::DataArrayDouble::renumberAndReduce "DataArrayDouble::renumberAndReduce" - -Sometimes the format old to new for surjections can be replaced by another format with 2 arrays. -Less compact in memory. The \ref ParaMEDMEM::DataArrayInt::changeSurjectiveFormat "DataArrayInt::changeSurjectiveFormat" method performs that. - -\section MEDCouplingArrayRenumberingN2O New-to-old mode - -The new-to-old mode is particularly recommended for strictly injective and bijective permutations. -This is particularly useful for methods that increase the number of entities like for example -\ref ParaMEDMEM::MEDCouplingUMesh::simplexize "MEDCouplingUMesh::simplexize".\n -All non static methods in \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" -or \ref ParaMEDMEM::DataArrayInt "DataArrayInt" having as last letter \b R (meaning Reversed) in -capital works with the mode new to old. -Let's consider a call to \ref ParaMEDMEM::MEDCouplingUMesh::simplexize "simplexize" that increases -the number of cell from 4 cells to 6 cells.\n -In new-to-old mode the array \b MyInjection that specifies this injection will have 6 tuples -and 1 component. The content of the 5*1 values will be in {0,1,2,3}.\n -If \b MyInjection equals [2,0,1,1,3,0] it means that : - -- new id #0 comes from old id 2 -- new id #1 comes from old id 0 -- new id #2 comes from old id 1 -- new id #3 comes from old id 1 -- new id #4 comes from old id 3 -- new id #5 comes from old id 0 - -Method in new-to-old mode that works on bijective applications : - -- \ref ParaMEDMEM::DataArrayDouble::renumberR "DataArrayDouble::renumberR" -- \ref ParaMEDMEM::DataArrayDouble::renumberInPlace "DataArrayDouble::renumberInPlaceR" - -Method in new-to-old mode that works on surjective applications : - -- \ref ParaMEDMEM::DataArrayDouble::selectByTupleId "DataArrayDouble::selectByTupleId" -- \ref ParaMEDMEM::DataArrayDouble::selectByTupleIdSafe "DataArrayDouble::selectByTupleIdSafe" -- \ref ParaMEDMEM::DataArrayDouble::selectByTupleId2 "DataArrayDouble::selectByTupleId2" -- \ref ParaMEDMEM::DataArrayDouble::selectByTupleRanges "DataArrayDouble::selectByTupleRanges" - -\section numbering-indirect Indirect indexing - -The indirect indexing format is made of two \ref arrays "arrays of int (DataArrayInt)" and -is used to describe a set of groups (a group being here understood as a simple pack of int identifiers). -Each group of identifier can for example represent a set of coincident nodes, or a set of nodes belonging -to the same cell, etc ... - -\image html IndirectIndex.jpg "Indirect indexing principle" - -Denoting \c tab and \c tabI the two arrays of the indirect indexing format, -we see at the top in the picture above the \c tab array, which contains n packs of identifiers -(first pack is 3,1,4,6, second pack is 4,3,2,6,5, etc ...), and below the array \c tabI -which provides the necessary offsets to extract a given pack from \c tab. - -This format is widely used internally (this is how the connectivity of -\ref MEDCouplingUMeshPage "unstructured cells" is stored for example), and is also returned by -many functions, e.g.: -- \ref ParaMEDMEM::MEDCouplingPointSet::findCommonCells "MEDCouplingPointSet::findCommonCells" -- \ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes "MEDCouplingPointSet::findCommonNodes" -- \ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoints "MEDCouplingPointSet::getNodeIdsNearPoints" -- \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity "MEDCouplingUMesh::buildDescendingConnectivity" -- \ref ParaMEDMEM::MEDCouplingUMesh::computeNeighborsOfNodes "MEDCouplingUMesh::computeNeighborsOfNodes" -- \ref ParaMEDMEM::MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh "MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh" -- \ref ParaMEDMEM::MEDCouplingUMesh::setConnectivity "MEDCouplingUMesh::setConnectivity" -- \ref ParaMEDMEM::MEDCouplingUMesh::split2DCells "MEDCouplingUMesh::split2DCells" - -Some functions in the API to manipulate this format: -- \ref ParaMEDMEM::DataArrayInt::changeSurjectiveFormat "DataArrayInt::changeSurjectiveFormat" -- \ref ParaMEDMEM::MEDCouplingUMesh::ExtractFromIndexedArrays "(static) MEDCouplingUMesh::ExtractFromIndexedArrays" -- \ref ParaMEDMEM::MEDCouplingUMesh::ExtractFromIndexedArrays2 "(static) MEDCouplingUMesh::ExtractFromIndexedArrays2" - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/cpp/MEDCouplingTimeLabel.dox b/medtool/doc/user/doxygen/doxfiles/reference/cpp/MEDCouplingTimeLabel.dox deleted file mode 100644 index 4b6ec8c84..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/cpp/MEDCouplingTimeLabel.dox +++ /dev/null @@ -1,25 +0,0 @@ - -/*! - \page MEDCouplingTimeLabelPage Time label in MEDCoupling - -Time label is a **non instantiable** class whose each object consuming potentially big amount of memory inherits from. -The class that incarnates this concept is ParaMEDMEM::TimeLabel. - -Here are some of examples of classes that inherit from \ref ParaMEDMEM::TimeLabel "TimeLabel" class : - -- ParaMEDMEM::DataArrayInt, ParaMEDMEM::DataArrayDouble -- ParaMEDMEM::MEDCouplingMesh -- ParaMEDMEM::MEDCouplingFieldDouble -- ... - -This class is in charge of storing a 32 bits unsigned integer called the time label, that allows the user to know easily, if an heavy object in memory has been modified or not. - -The usage is simple : - -- Call ParaMEDMEM::TimeLabel::getTimeOfThis a first time to retrieve a reference. Store the returned unsigned integer. -- When you need to know if the instance inheriting from ParaMEDMEM::TimeLabel has changed or not simply invoke ParaMEDMEM::TimeLabel::getTimeOfThis again and compare with the stored value. - If the value is different, the instance has changed, if not the instance has **not** changed. - -The virtual call to ParaMEDMEM::TimeLabel::updateTime changes the behaviour of ParaMEDMEM::TimeLabel::getTimeOfThis ; it is a bug, so please notify the bug on the SALOME forum. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/cpp/cpp.dox b/medtool/doc/user/doxygen/doxfiles/reference/cpp/cpp.dox deleted file mode 100644 index 2b553bce5..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/cpp/cpp.dox +++ /dev/null @@ -1,25 +0,0 @@ -/*! - \page cpp Note for C++ developpers - -Using the C++ API provided by MED requires you to be familiar with some specificities which are not -visible to the Python user. - -- \ref ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr "MEDCouplingAutoRefCountObjectPtr" -- \subpage MEDCouplingTimeLabelPage - -\b Note: all the standard (sequential) MEDCoupling API lies in the \ref ParaMEDMEM "ParaMEDMEM namespace". -This is quite unfortunate but due to historical reasons. The true parallel functionalities -of the \ref library "MED library" are detailed here: \ref parallel - -The memory management of the various strucutres is eased by the class -\ref ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr "MEDCouplingAutoRefCountObjectPtr". It acts as an auto pointer and takes care of deleting the -memory automatically when going out of scope. See an example usage in \ref cpp_mcfielddouble_WriteVTK . -Beware however that not all functions return a pointer that should be deleted when going out of scope. -Some methods only return an observer to the data, see for example \ref ParaMEDMEM::MEDCouplingPointSet::getCoords() "getCoords()". The API documentation of each method indicates whether the caller is responsible of the returned -data or not. - -For advanced usage, one has to be aware of the stamping mechanism used internally to know -whether an instance has been modified or not. This is described in the second page above: - \ref MEDCouplingTimeLabelPage - - */ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/distrib/corba-distrib.dox b/medtool/doc/user/doxygen/doxfiles/reference/distrib/corba-distrib.dox deleted file mode 100644 index 59ed64c2e..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/distrib/corba-distrib.dox +++ /dev/null @@ -1,16 +0,0 @@ -/*! -\page corba-distrib Distribution in MEDCoupling using CORBA - -The following classes allow to publish \ref medcoupling "MEDCoupling objects" on the CORBA bus. They are -directly related to the equivalent class in MEDCoupling, without the string \c Servant at the end of the -name: - -- \ref ParaMEDMEM::DataArrayDoubleServant "DataArrayDoubleServant" -- \ref ParaMEDMEM::DataArrayIntServant "DataArrayIntServant" -- \ref ParaMEDMEM::MEDCouplingUMeshServant "MEDCouplingUMeshServant" -- \ref ParaMEDMEM::MEDCouplingCMeshServant "MEDCouplingCMeshServant" -- \ref ParaMEDMEM::MEDCouplingFieldDoubleServant "MEDCouplingFieldDoubleServant" - - TODO: complete the list. - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/distrib/distrib.dox b/medtool/doc/user/doxygen/doxfiles/reference/distrib/distrib.dox deleted file mode 100644 index 7f9f37d8d..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/distrib/distrib.dox +++ /dev/null @@ -1,10 +0,0 @@ -/*! -\page distrib Distribution and parallelism in MEDCoupling - -The MEDCoupling library features several functionalities to allow its efficient usage -in a parallel and/or distributed setup: -- \subpage parallel -- \subpage corba-distrib - - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/distrib/parallel.dox b/medtool/doc/user/doxygen/doxfiles/reference/distrib/parallel.dox deleted file mode 100644 index 0c197817a..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/distrib/parallel.dox +++ /dev/null @@ -1,81 +0,0 @@ -/*! -\page parallel Parallelism - -\section para-over Building blocks - -Several classes and methods are available in the MED library to ease the exchange of information -in a parallel context. The DECs (\ref para-dec "detailed further down") then use those classes to enable -the parallel remapping (projection) of a field. -For historical reasons, all those items are in the same namespace as the non-parallel MEDCoupling functionalities, -%ParaMEDMEM. - -The core elements of the API are: -- \ref CommInterface-det "CommInterface", this is the wrapper around the MPI library, and an instance -of this object is required in many constructors of the following objects. -- \ref ParaMESH-det "ParaMESH", the parallel instanciation of a \ref meshes "MEDCoupling mesh" -- \ref ParaFIELD-det "ParaFIELD", the parallel instanciation of a \ref fields "MEDCoupling field" -- \ref MPIProcessorGroup-det "MPIProcessorGroup" (which inherits from the abstract -\ref ParaMEDMEM::ProcessorGroup "ProcessorGroup"), a group of processors (typically MPI nodes) - -In an advanced usage, the topology of the nodes in the computation is accessed through the following elements: -- \ref BlockTopology-det "BlockTopology", specification of a topology based on the (structured) mesh. -The mesh is divided in block (typically a split along the first axis) which are allocated on the various -processors. -- %ExplicitTopology (not fully supported yet and only used internally), specification of user-defined -topology, still based on the mesh. -- \ref ComponentTopology-det "ComponentTopology", specification of a topology allowing the split of -several field *components* among different processors. The mesh is not the support of the topology anymore. - -\section para-dec Data Exchange Channel - DEC - -A Data Exchange Channel (%DEC) allows the transfer and/or the interpolation (remapping) of field data between several -processors in a parallel (MPI) context. -Some DECs perform a simple renumbering and copy of the data, and some are capable of functionalities similar to the -\ref remapper "sequential remapper". - -We list here the main characteristics of the DECs, the list being structured in the same -way as the class hierarchy: - -- \ref DisjointDEC-det "DisjointDEC", works with two disjoint groups of processors. This is an abstract class. - - \ref InterpKernelDEC-det "InterpKernelDEC", inherits the properties of the \c %DisjointDEC. The projection - methodology is based on the algorithms of %INTERP_KERNEL, that is to say, they work in a similar fashion than - what the \ref remapper "sequential remapper" does. The following \ref discretization "projection methods" - are supported: P0->P0 (the most common case), P1->P0, P0->P1. - - \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC", also inherits the properties - of the \c %DisjointDEC, but this one is \b not based on the %INTERP_KERNEL algorithms. - This DEC does a simple data transfer between two fields having a common (coincident) structured support, - but different topologies (i.e. the structured domain is split differently among the processors for the - two fields). Only the cell identifiers are handled, and no kind of interpolation (in the sense of the - computation of a weight matrix) is performed. It is a "mere" reallocation of data from one domain - partitioning to another. - - \b ExplicitCoincidentDEC : as above, but based on an explicit topology. This DEC is used internally but - rarely directly in the public API. -- \ref OverlapDEC-det "OverlapDEC", works with a single processor group, but each processor detains -both (part of) the source and target fields. This %DEC can really be seen as the true parallelisation of the -\ref remapper "sequential remapper". Similarly to the \ref InterpKernelDEC-det "InterpKernelDEC" -the projection methodology is based on the algorithms of %INTERP_KERNEL, that is to say, -it works in a similar fashion than what the \ref remapper "sequential remapper" does. -- \b NonCoincidentDEC (deprecated for now) - -Besides, all the DECs inherit from the class \ref ParaMEDMEM::DECOptions "DECOptions" which provides -the necessary methods to adjust the parameters used in the transfer/remapping. - -The most commonly used %DEC is the \c %InterpKernelDEC, and here is a simple example to of its usage: - - \code -... -InterpKernelDEC dec(groupA, groupB); // groupA and groupB are two MPIProcessorGroup -dec.attachLocalField(field); // field is a ParaFIELD, a MEDCouplingField or an ICoCo::MEDField -dec.synchronize(); // compute the distributed interpolation matrix -if (groupA.containsMyRank()) -dec.recvData(); // effectively transfer the field (receiving side) -else if (groupB.containsMyRank()) -dec.sendData(); // effectively transfer the field (sending side) -... -\endcode - -\n -\n -\n - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/fields/MEDCouplingFields.dox b/medtool/doc/user/doxygen/doxfiles/reference/fields/MEDCouplingFields.dox deleted file mode 100644 index 48860dc41..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/fields/MEDCouplingFields.dox +++ /dev/null @@ -1,118 +0,0 @@ -/*! -\page MEDCouplingFieldsPage Fields - -[TOC] - -\section MEDCouplingFields Field concept - -A field in MEDCoupling point of view, is a structure that allows to -store a discretization of a physical value on a defined discretized spatial and -possibly temporal support. - -The spatial support is a \ref meshes "mesh". -A field is lying on an entity that will be specified by the spatial -discretization of the field. For example a field on node will lie on -all nodes of its mesh. - -A field on cell will lie on all cells of its mesh. - -Fields in MEDCoupling follow the two following rules : - -- A field will lie on \b ALL entities of its spatial support (\ref meshes "mesh"). -- A field has \b only \b one spatial support (\ref meshes "mesh") on its temporal support. - -The main properties of a field are : - -- name -- spatial support which is a \ref meshes "mesh" -- a \ref MEDCouplingSpatialDisc "spatial discretization" -- a description of intrinsic nature of the values of field (see \ref NatureOfField). This is important for conservative interpolation (see \ref TableNatureOfField). -- a temporal discretization that specifies, if it exists, the time interval on which the field is covering, and how. -- number of components - -This definition of field in MEDCoupling allows an instance of field to -know at any point inside its spatial-temporal support the value. - -The class that incarnates the concept described above is : \ref ParaMEDMEM::MEDCouplingFieldDouble. - -Some of most important implemented methods are : - -- \ref ParaMEDMEM::MEDCouplingFieldDouble::getNumberOfComponents "getNumberOfComponents" -- \ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn" -- \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc "applyFunc" -- \ref ParaMEDMEM::MEDCouplingFieldDouble::AddFields "cross instances operations" -\section MEDCouplingSpatialDisc Spatial discretization concept - -This is the concept that makes the link, independently from temporal -discretization, between the field and its spatial support (\ref meshes "mesh"). This -concept allows the field to make a check and interpretation of an -array of values given a spatial support (\ref meshes "mesh"). - -The abstract class that incarnates the concept is : \ref ParaMEDMEM::MEDCouplingFieldDiscretization. - -The most important pure virtual methods are : - -- \ref ParaMEDMEM::MEDCouplingFieldDiscretization::getNumberOfTuples "getnumberOfTuples" -- \ref ParaMEDMEM::MEDCouplingFieldDiscretization::getValueOn "getValueOn" -- \ref ParaMEDMEM::MEDCouplingFieldDiscretization::getMeasureField "getMeasureField" - -\section MEDCouplingTemporalDisc Temporal discretization concept - -This information allows, independently from spatial discretization, to -associate a time interval, if it exists, on which the field will be -defined. This concept is able to give the value at any time of -the definition interval (if any). - -The abstract class \ref ParaMEDMEM::MEDCouplingTimeDiscretization -incarnates this described concept. - -This classes and its subclasses are responsible in storing the arrays -of the aggregating field. - -The most important methods are : - -- \ref ParaMEDMEM::MEDCouplingTimeDiscretization::setTime "setTime" and \ref ParaMEDMEM::MEDCouplingTimeDiscretization::getTime "getTime" -- \ref ParaMEDMEM::MEDCouplingTimeDiscretization::getArray "getArray" and \ref ParaMEDMEM::MEDCouplingTimeDiscretization::setArray "setArray" -- \ref ParaMEDMEM::MEDCouplingTimeDiscretization::getArraysForTime "getArraysForTime" -- \ref ParaMEDMEM::MEDCouplingTimeDiscretization::getValueForTime "getValueForTime" - -\section MEDCouplingFirstSteps3 Building a field from scratch - -Here we will make the assumption that an instance of \c MEDCouplingMesh called \c mesh has been created ( to know more about mesh creation \ref MEDCouplingUMeshStdBuild "click here" ). - -\subsection MEDCouplingFirstSteps3OnCellsNoTS Create a tensor field with 9 components on cells with no time step - -\ref medcouplingcppexamplesFieldDoubleBuild1 "Here the C++ implementation." - -\ref medcouplingpyexamplesFieldDoubleBuild1 "Here the Python implementation." - -\subsection MEDCouplingFirstSteps3OnNodesNoTS Create a scalar field on nodes with no time step - -\ref medcouplingcppexamplesFieldDoubleBuild2 "Here the C++ implementation." - -\ref medcouplingpyexamplesFieldDoubleBuild2 "Here the Python implementation." - -\subsection MEDCouplingFirstSteps3OnCellsWTS Create a 2 components-vector field on cells with one time step and no interval - -\ref medcouplingcppexamplesFieldDoubleBuild3 "Here the C++ implementation." - -\ref medcouplingpyexamplesFieldDoubleBuild3 "Here the Python implementation." - -\subsection MEDCouplingFirstSteps3OnCellsCTI Create a 3 components-vector field on nodes with a time interval where field remains constant on this time interval - -\ref medcouplingcppexamplesFieldDoubleBuild4 "Here the C++ implementation." - -\ref medcouplingpyexamplesFieldDoubleBuild4 "Here the Python implementation." - -\section MEDCouplingSecondStep0 Operations on Fields - -Here we will make the assumption that an instance of \ref ParaMEDMEM::MEDCouplingMesh "MEDCouplingMesh" -called \c mesh has been created with spaceDim==2. - -\ref medcouplingcppexamplesFieldDoubleBuild5 "Here a C++ example of more advanced use of MEDCouplingFieldDouble instances". - -\ref medcouplingpyexamplesFieldDoubleBuild5 "Here a Python example of more advanced use of MEDCouplingFieldDouble instances". - -*/ - - LocalWords: discretization diff --git a/medtool/doc/user/doxygen/doxfiles/reference/fields/discretization.dox b/medtool/doc/user/doxygen/doxfiles/reference/fields/discretization.dox deleted file mode 100644 index 6789241ce..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/fields/discretization.dox +++ /dev/null @@ -1,56 +0,0 @@ -/*! -\page discretization Spatial and temporal discretizations - -When defining a field in MEDCoupling, the notions of spatial and temporal discretizations play -a crucial role. - -The spatial discretization details the relationship between the field and its support mesh -and the temporal discretization gives an indication of the time coverage represented -by the field. - -\section field-space Spatial discretization -A field can be supported by: -- the nodes (vertices) of the mesh: this is built with the -\ref ParaMEDMEM::TypeOfField "ON_NODES" keyword in the -\ref ParaMEDMEM::MEDCouplingFieldDouble::New(TypeOfField , TypeOfTimeDiscretization) "constructor of a field". - -- the cells (or "elements") of the mesh: built with the -\ref ParaMEDMEM::TypeOfField "ON_CELLS" keyword in the -\ref ParaMEDMEM::MEDCouplingFieldDouble::New(TypeOfField , TypeOfTimeDiscretization) "constructor of a field". -- or more complex items: - - Gauss points: built with \ref ParaMEDMEM::TypeOfField "ON_GAUSS_PT" - - Gauss points on nodes per element: built with \ref ParaMEDMEM::TypeOfField "ON_GAUSS_NE" - - Kriging points: built with \ref ParaMEDMEM::TypeOfField "ON_NODES_KR" - -The spatial discretization is at the center of the \ref interpolation "interpolation" mechanisms, -since one of the main interpolation paramter is indeed specifying from which source discretization -to which target discretization one wants to go. For example: -- a P0->P0 interpolation means that a field on cells will be transfered to another cell-based field; -- a P1->P0 interpolation means that a field on nodes this time will be transfered to a cell-based field. -- etc ... - -Finally, in the code itself, the class \ref ParaMEDMEM::MEDCouplingFieldDiscretization "MEDCouplingFieldDiscretization" -is the concrete representation of this concept. - -\section field-time Temporal discretization - -Similarly to the spatial discretization, a field object in MEDCoupling has a time discretization -representing the time range that is covered by the data. It is also specified in the -\ref ParaMEDMEM::MEDCouplingFieldDouble::New(TypeOfField , TypeOfTimeDiscretization) "constructor of a field". - -It can be one of: -- \ref ParaMEDMEM::TypeOfTimeDiscretization "NO_TIME", in this case no time is attached to the field, and no -time-related operation is permitted (for example unable to call -\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn()") -- \ref ParaMEDMEM::TypeOfTimeDiscretization "ONE_TIME", the field data represent a single time step. -- \ref ParaMEDMEM::TypeOfTimeDiscretization "LINEAR_TIME", the field data contains \b two arrays, stamped with two -different time points. A linear interpolation of the field values between those two time steps is then possible. -- \ref ParaMEDMEM::TypeOfTimeDiscretization "CONST_ON_TIME_INTERVAL", the field data contains a single array -of data, but a start- and end-time can be specified, thus declaring that the field represent a constant -set of data during this time interval. All time evaluation function then just check that the given time -fits in the interval. - -Finally, in the code itself, the class \ref ParaMEDMEM::MEDCouplingTimeDiscretization "MEDCouplingTimeDiscretization" -is the concrete representation of this concept. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/fields/fields.dox b/medtool/doc/user/doxygen/doxfiles/reference/fields/fields.dox deleted file mode 100644 index 28ff75f49..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/fields/fields.dox +++ /dev/null @@ -1,21 +0,0 @@ -/*! - -\page fields Fields - -A field in MEDCoupli,g represents some physical quantity associated with the spatial domain. -This is not a continuous description of the physical quantity over the domain, and hence a field has -a finite set of values, associated to some constituents of the mesh (nodes, cells, or more complicated). - -At a low level, a field is a \ref arrays DataArray associated to a given mesh. A field can have more than one -component (vector or tensor field), for example the 3 components v_x, v_y, vz of a velocity field. - -- \subpage discretization -- \subpage MEDCouplingFieldsPage - -Finally, and for interpolation purposes only, one needs to define the nature of a field (is it an extensive -field, like mass, or an intensive field, like temperature, etc ...). This is covered thoroughly in the -interpolation pages: - -- \ref NatureOfField - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/Geometric2D.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/Geometric2D.dox deleted file mode 100644 index a00934f61..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/Geometric2D.dox +++ /dev/null @@ -1,237 +0,0 @@ -/*! -\page interpkernelGeo2D Geometric2D Intersector - -Like other intersectors the aim of this intersector is to compute intersection between 2 -polygons.\n -The specificity of this intersector is to deal with \b any \b type of -polygons even those with \b quadratic \b edges. -Its quite generic architecture allows him to deal with some other -potentially useful functions.\n -This page described Geometric2D intersector basic principles and -specific usage. - -\section interpkernelGeo2DIntro Introduction - -The principle used in this intersector to perform boolean operation on geometry is geometric-modeler like. -The data structure used to describe polygons is boundary description. That is to say the internal -representation of a polygon is its edges composing it. - -\subsection interpkernelGeo2DNamingConv Naming conventions - - - An \ref INTERP_KERNEL::Edge "edge" is defined by a start - node, a end node and a curve equation (linear or arc of - circle). \b WARNING : start node and end node \b HAVE \b TO \b BE - different and distant at least equal to precision set. - - An \ref INTERP_KERNEL::ElementaryEdge "elementary edge" is an edge \b NOT \b splittable \b without \b applying - \b mathematical \b intersection \b computation. - - A \ref INTERP_KERNEL::ComposedEdge "composed edge" is a collection of consecutive edges hierarchically \b splittable - \b without \b any \b mathematical \b intersection \b computation. - -Consecutive means that in a composed edge if edge \a e2 follows edge -\a e1, the end node of \a e1 is geometrically equal to start node of -\a e2. - -\subsection interpkernelGeo2DBasicConcepts Basic concepts - -A \ref INTERP_KERNEL::QuadraticPolygon "quadratic polygon" is a -specialization of a -\ref INTERP_KERNEL::ComposedEdge "composed edge" in that it is -closed. Closed means that the start node of first edge is equal to end -node of last edge.\n -A \ref INTERP_KERNEL::ComposedEdge "composed edge" is considered as a -collection of \ref INTERP_KERNEL::Edge "abstract edges". An -\ref INTERP_KERNEL::Edge "abstract edge" is either an \ref -INTERP_KERNEL::ElementaryEdge "elementary edge" or itself a \ref -INTERP_KERNEL::ComposedEdge "composed edge".\n A composite pattern has -been used here. - -Each \ref INTERP_KERNEL::ElementaryEdge " elementary edge" and each -\ref INTERP_KERNEL::Node "nodes" have a flag that states if during -the split process if it is \b out, \b on, \b in or \b unknown. - -\section interpkernelGeo2DBoolOp Boolean operation algorithm - -\subsection interpkernelGeo2DBoolOpPrinc Basics - -The boolean operation (intersection) between two polygons is used in P0 P0 interpolation. - -The process of boolean operations between two polygons P1 and P2 is done in three steps : - - -# \ref interpkernelGeo2DBoolOpStep1 "splitting". - -# \ref interpkernelGeo2DBoolOpStep2 "edges localization". - -# \ref interpkernelGeo2DBoolOpStep3 "result polygons building". - -\subsection interpkernelGeo2DBoolOpStep1 Step1 : splitting. - -The principle used to do boolean operations between 2 polygons P1 and -P2 is to intersect each edge of P1 with each edge of P2. \n After this -edge-splitting, polygon P1 is splitted, so that each -\ref INTERP_KERNEL::ElementaryEdge "elementary edge" constituting P1 -is either \b in, \b out or \b on polygon P2. And inversely, polygon P2 is splitted so that each -\ref INTERP_KERNEL::ElementaryEdge "elementary edge" constituting P2 -is either \b in, \b out or \b on polygon P1. - -During split process, when, without any CPU overhead, the location can be -deduced, the nodes and edges are localized. - -This step of splitting is common to all boolean operations.\n -The method in charge of that is INTERP_KERNEL::QuadraticPolygon::splitPolygonsEachOther. - -\subsection interpkernelGeo2DBoolOpStep2 Step2 : Edges localization. - -Perform localization of each splitted edge. As \ref interpkernelGeo2DBoolOpStep1 "split process" it - is common to all boolean operations. - -When the location of edges has \b not been -already deduced in previous computation and there is no predecessor, the -\ref interpkernelGeo2DAlgLoc "localization is done in absolute". -After it deduces the localization relatively to the previous edge -thanks to node localization.\n The relative localization is done -following these rules : - - * - * - * - * - * - * - * - * - * - * - *
Previous Edge LocCurrent start node Loc Current edge Loc
UNKNOWN ANY UNKNOWN -> \ref interpkernelGeo2DAlgLoc "Absolute search"
OUT ON IN
OUT ON_TANGENT OUT
IN ON OUT
IN ON_TANGENT IN
OUT OUT OUT
IN IN IN
ON ANY UNKNOWN -> \ref interpkernelGeo2DAlgLoc "Absolute search"
- -The method in charge of that is INTERP_KERNEL::QuadraticPolygon::performLocatingOperation. - -\subsection interpkernelGeo2DBoolOpStep3 Step3 : Result polygon building. - -This stage links each edge with wanted loc. \b Contrary to last 2 steps it is obviously boolean -operation dependant. Let's take the case of the intersection that is used in -P0->P0 interpolation. \n The principle of result polygon building is to build polygon by taking -edges localized as \b in or \b on. - -Generally, the principle is to take an edge in \a P1 with wanted loc and linking -direct neighbour-edges (with correct loc) until closing a polygon. If -not, using \a P2 edges to try to close polygon. The process is -repeated until all edges with correct loc have been consumed. - -The method in charge of that is INTERP_KERNEL::QuadraticPolygon::buildIntersectionPolygons. - -\section interpkernelGeo2DAlg Underlying algorithms - -\subsection interpkernelGeo2DAlgLoc Absolute localization algorithm - -This algorithm is called when splitting process has been done, and -that we are sure that the edge is either \b fully \b in ,or \b fully \b on or \b fully -\b out. - -The principle chosen to know if an edge \a E is completely included in an -any polygon \a P is to see if its barycenter \a B is inside this any -polygon \a P. -After, for each nodes \f$ P_i \f$ of polygon \a P we store angle in \f$ [-\pi/2,\pi/2 ] \f$ -that represents the slope of line \f$ (BP_i) \f$.\n -Then a line \a L going through \a B with a slope being as far as -possible from all slopes found above. Then the algorithm goes along \a L -and number of times \a N it intersects \b non-tangentially the any polygon \a P. - -If \a N is odd \a B (and then \a E) is IN. -If \a N is even \a B (and then \a E) is OUT. - -This computation is \b very \b expensive, that why some tricks as described in -\ref interpkernelGeo2DBoolOpStep2 "localization techniques" are used to call as few as possible -during intersecting process. - -\subsection interpkernelGeo2DAlgIntsect Intersection algorithms - -The only mathematical intersections performed are edges intersections. -The algorithms used are : - - -# Lin-Lin intersection : http://mathworld.wolfram.com/Line-LineIntersection.html - -# Lin-Arc intersection : http://mathworld.wolfram.com/Circle-LineIntersection.html - -# Arc-Arc intersection : http://mathworld.wolfram.com/Circle-CircleIntersection.html - -\subsection interpkernelGeo2DAlgOthers Other algorithms - -As internal architecture is quite general, it is possible to have more than classical intersection on any polygons : - - - \ref INTERP_KERNEL::ComposedEdge::getArea "area" computation is available. - - \ref INTERP_KERNEL::ComposedEdge::getPerimeter "perimeter" computation. - - \ref INTERP_KERNEL::ComposedEdge::getHydraulicDiameter "Hydraulic diameter" computation. - -\section interpkernelGeo2DUsage Usage - -This intersector is usable standalone. To use a set of user friendly methods have been implemented. - - - INTERP_KERNEL::QuadraticPolygon::buildArcCirclePolygon method builds from a \c std::vector of INTERP_KERNEL::Node* \a V, an instance of QuadraticPolygon \a P. - \a P will have \f$ N_{edges} = V.size()/2 \f$ edges. Quadratic edge \f$ Edge_i i \in [0,N_{edges}-1] \f$ starts with node V[i], ends with node V[i+1] and has a middle in - \f$ V[i+N_{edge}] \f$. \n If start, end and middle nodes of edge \f$ Edge_i \f$ are aligned by a precision specified by INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision. - - INTERP_KERNEL::QuadraticPolygon::buildLinearPolygon method builds from a \c std::vector of INTERP_KERNEL::Node* \a V, an instance of QuadraticPolygon \a - P. \a P will have \f$ N_edges = V.size() \f$ edges. Linear edge \f$ Edge_i i \in [0,N_{edges}-1] \f$ starts with node V[i] and ends with node V[i+1]. - -The orientation of polygons (clockwise, inverse clockwise) impact computation only on the sign of areas. During intersection of 2 polygons their orientation can be different. - -The usage is simple : - -\code -... -// defining a precision -INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-5); -INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); -// -INTERP_KERNEL::QuadraticPolygon *polygon1=...; -bool isQuadratic=...//Depends on the nature of your cell. If your cell is MED_QUAD8 or MED_TRIA6 for example isQuadratic=true. -const double *externalTabXCoords=...; -const double *externalTabYCoords=...; -std::vector nodes; -INTERP_KERNEL::QuadraticPolygon *polygon2=0; -for(int i=0;iintersectWith(*polygon2); -double dhydPol1=polygon1->getHydraulicDiameter(); -double areaPol1=polygon1->getAreaOfZone(); -//clean-up -delete polygon1; -delete polygon2; -... -\endcode - -\section interpkernelGeo2DExample Example of result - -Here an example of 2 polygons. The left one \a P1 has 4 edges and the -right one \a P2 has 4 edges too. - -\anchor interpkernelGeo2DEx1 -\image html SampGeo2D1.png "An example of intersection of 2 polygons." -\image latex SampGeo2D1.eps "An example of intersection of 2 polygons." - -After \ref interpkernelGeo2DBoolOpStep1 "spliting process" \a P1 has 6 edges and \a P2 has 6 edges too. - -\anchor interpkernelGeo2DEx2 -\image html SampGeo2D2.png "After spliting process two edges of P1 have been located has out." -\image latex SampGeo2D2.eps "After spliting process two edges of P1 have been located has out." - -\note BLUE is for OUT, GREEN for IN and RED for ON. - -For each 6 edges \ref interpkernelGeo2DBoolOpStep2 "locate" them. - -\anchor interpkernelGeo2DEx3 -\image html SampGeo2D3.png "Result after locating phase." -\image latex SampGeo2D3.eps "Result after locating phase." - -Too finish \ref interpkernelGeo2DBoolOpStep3 "closing" polygons. - -\anchor interpkernelGeo2DEx4 -\image html SampGeo2D4.png "Close-up of final result after close polygons phase." -\image latex SampGeo2D4.eps "Close-up of final result after close polygons phase." - -\note The result polygon is constituted of 2 sub-edges coming from \a P1 -and 1 sub-edge from \a P2 closing the polygon. For the 2 edges of \a P1 -they are green because they are fully included in \a P2. Inversely, -the only sub-edge coming from \a P2 is fully included in \a P1. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/NatureOfField.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/NatureOfField.dox deleted file mode 100644 index b005a9cc5..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/NatureOfField.dox +++ /dev/null @@ -1,62 +0,0 @@ - -/*! -\page NatureOfField Nature of a field - -\section IntExtFields Overview: intensive and extensive field - -\c NatureOfField is an enum which helps in determining some physical significance of the field and affects the choice of the interpolation formula (see \ref TableNatureOfField). -It has five possible values: -- "NoNature", the default value, does not allow the use of any interpolation tools - -For intensive fields: -- \ref TableNatureOfFieldExampleConservVol "ConservativeVolumic", for intensive field with the maximum principle favored over conservativity. Relevant for temperature, pressure fields. - -- \ref TableNatureOfFieldExampleRevIntegral "RevIntegral", for intensive field with the conservativity favored over maximum principle. Relevant for power density fields. - -For extensive fields: -- \ref TableNatureOfFieldExampleIntegral "Integral", for extensive field with the maximum principle favored over conservativity. Relevant for power fields. - -- \ref TableNatureOfFieldExampleIntegralGlobConstraint "IntegralGlobConstraint", for extensive fields with conservativity favored over the maximum principle. Relevant for power fields. - -\n - -By intensive field we mean a field that represents an intensive physical variable such as density (\f$kg.m^{-3}\f$), power density (\f$W.m^{-3}\f$), temperature (\f$K\f$) or pressure (\f$Pa\f$). Typically the physical value doesn't scale with the size of the underlying geometry.
-By extensive (or integral) field we mean a field that represents an extensive physical quantity such as mass (\f$kg\f$), volume (\f$m^3\f$), a momentum (\f$kg.m.s^{-1}\f$) or power \f$(W\f$). -Typically the field value scales linearly with respect to the underlying geometry size. -For fields with a P0 representation (cell based), conservativity formulas are different depending on whether the field is extensive or intensive (see \ref InterpKerP0P0Int and \ref InterpKerP0P0Ext).
-These two notions are themselves split into two sub-categories. -Indeed in some cases (e.g. non \ref MeshOverlap "overlapping meshes"), it is impossible to fulfill both the conservation principle and the maximum principle during the interpolation. The nature of the fields determines the formula to be used for non overlapping cells and thus the property that we will be satisfied. - -Finally we consider that fields with P1 or P2 representations are necessarily intensive. - -\section Usage - -In order to use the various \ref intro-interp "interpolations", you have to specify the nature of your field. -When the source and target meshes do not overlap, different treatments will be employed depending on the nature of the source and target fields. -You can specify the nature of the field when you create a \ref fields "MEDCoupling field" -with the following constructor: -\code -MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); -\endcode - -If you read or copy an already existing field, or later after its creation, you may want to change/set its nature. -In order to do so, you can use the function - -\code -void setNature(NatureOfField nat); -\endcode - -Here is an example - -\code -... -const char sourceFileName[]="source.med"; -MEDCouplingFieldDouble *sourceField=MEDLoader::ReadFieldCell(sourceFileName,"Source_Mesh",0,"Density",/*iteration*/0,/*order*/0); -const char targetFileName[]="target.med"; -MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile(targetFileName,"Target_Mesh",0); -// -sourceField->setNature(ConservativeVolumic); -... -\endcode - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/barycoords.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/barycoords.dox deleted file mode 100644 index b45c2a60d..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/barycoords.dox +++ /dev/null @@ -1,39 +0,0 @@ -/*! -\page barycoords Barycentric coordinates algorithm - -Computation of barycentric coordinates is used to fill interpolation -matrix in case of P1 and P1d types of interpolation. Computation of -barycentric coordinates consists in finding weights of vertices -bearing values within the cell. The cell is triangular in 2D space and -tetrahedral in 3D space. - -Input of the algorithm include: -- coordinates of cell vertices (p1...pn), -- coordinates of a barycentre of cells intersection (b), -
where n is number of vertices which is either 3 or 4. - -Purpose is to find coefficients a1...an so that -- (a1*p1+...+an*pn)=b and -- (a1+...+an)=1.0 - -Combining the last two expressions we get an equation in matrix form -a * T = ( b - pn ) -where -- a is a vector of coefficients a1...an -- b is a vector of cartesian coordinates of barycentre -- T is a matrix expressed via cartesian coordinates of vertices as -
in 2D case
-| x1-x3 x2-x3 |
-| y1-y3 y2-y3 |
-in 3D case
-| x1-x4 x2-x4 x3-x4 |
-| y1-y4 y2-y4 y3-y4 |
-| z1-z4 z2-z4 z3-z4 |
- -In 2D case solution is found by inverting T which is trivial: a = T^(-1) * ( b - pn ) - -In 3D case we use Gaussian elimination algorithm. First we use elementary -row operations to transform T into upper triangular form and -then perform back substitution to find coefficients a. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/interpolation.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/interpolation.dox deleted file mode 100644 index e8319c70d..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/interpolation.dox +++ /dev/null @@ -1,27 +0,0 @@ -/*! - -\page interpolation Interpolation - -Interpolation (or projection) methods are a key feature of the MEDCoupling library. -It allows to "transfer" the values of a field on a given source mesh to another, newly created field -on a target mesh. - -The two meshes/fields need not to have the same \ref MEDCouplingMeshes "mesh/spatial dimension", nor do they need to have the same \ref discretization "discretization". - - - -- \subpage intro-interp -- \subpage InterpKerRemapGlobal -- \subpage NatureOfField -- \subpage remapper -- \subpage InterpKerIntersectors - -If you are looking for a parallel utilisation of the above, take a look at: - -- \ref parallel - -Some implementation details of the C++ code can be found in appendix: - -- \ref interpkernel - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/interptheory.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/interptheory.dox deleted file mode 100644 index 6ac5a2014..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/interptheory.dox +++ /dev/null @@ -1,271 +0,0 @@ -/*! -\page InterpKerRemapGlobal Detailed explanations for cell-based (P0) fields - -For fields with polynomial representation on each cell, the components of the discretized field \f$ \phi_s \f$ on the source side can be expressed as linear combinations of the components of the discretized field \f$ \phi_t \f$ on the target side, in terms of a matrix-vector product: - -\f[ - \phi_t=W.\phi_s. -\f] - -\f$W\f$ is called the \anchor interpolationmatrix interpolation matrix. -The objective of interpolators is to compute the matrix W depending on their physical -properties (\ref IntExtFields) and their mesh discretization (on cells P0, on nodes P1,...). - -\section ConsInterp Conservative interpolation - -At the basis of many CFD numerical schemes is the fact that physical -quantities such as density, momentum per unit volume or energy per -unit volume obey some balance laws that should be preserved at the -discrete level on every cell. - -It is therefore often desired that the process interpolation preserve the -integral of \f$ \phi \f$ on any domain. At the discrete level, for any -target cell \f$ T_i \f$, the following \b general \b interpolation \b -formula has to be satisfied : -\anchor InterpKerGenralEq -\f[ -\int_{T_i} \phi_t = \sum_{S_j\cap T_i \neq \emptyset} \int_{T_i\cap S_j} \phi_s. -\f] - -This equation is used to compute \f$ W_{ij} \f$, based on the fields representation ( P0, P1, P1d etc..) and the -geometry of source and target mesh cells. - -\section MeshOverlap Mesh overlapping - -Another important property of the interpolation process is the maximum principle: the field values resulting from the interpolation should remain between the upper and lower bounds of the original field. -When interpolation is performed between a source mesh S and a target -mesh T the aspect of overlapping is important. In fact if any cell of -of S is fully overlapped by cells of T and inversely any cell of T is -fully overlapped by cells of S that is -\f[ -\sum_{S_j} Vol(T_i\cap S_j) = Vol(T_i),\hspace{1cm} and \hspace{1cm} \sum_{T_i} Vol(S_j\cap T_i) = Vol(S_j) -\f] -then the meshes S and T are said to be \b -overlapping. In this case the two formulas in a given column in the table below give the same -result. All intensive formulas result in the same output, and all the extensive formulas give also the same output. - -The ideal interpolation algorithm should be conservative and respect the maximum principle. However such an algorithm can be impossible to design if the two meshes do not overlap. When the meshes do not overlap, using either \f$Vol(T_i)\f$ or \f$\sum_{S_j} Vol(T_i\cap S_j)\f$ one obtains an algorithm that respects either the conservativity or the maximum principle (see the nature of field \ref TableNatureOfField "summary table"). - - -\section InterpKerRemapInt Linear conservative remapping of P0 (cell based) fields - -We assume that the field is represented by a vector with a discrete value on each cell. -This value can represent either -- an average value of the field in the cell (average density, velocity or temperature in the cell) in which case the representation is said to be \b intensive, -- an integrated value over the cell (total mass, power of the cell) in which case the representation is said to be \b extensive - -\section InterpKerP0P0Int cell-cell (P0->P0) conservative remapping of intensive fields - -For intensive fields such as mass density or power density, the -left hand side in the \ref InterpKerGenralEq "general interpolation equation" becomes : - -\f[ -\int_{T_i} \phi = Vol(T_i).\phi_{T_i}. -\f] - -Here Vol represents the volume when the mesh dimension is equal to 3, the -area when mesh dimension is equal to 2, and length when mesh dimension is equal to 1. - -In the \ref InterpKerGenralEq "general interpolation equation" the -right hand side becomes : - -\f[ -\sum_{S_j\cap T_i \neq \emptyset} \int_{T_i\cap S_j} \phi = \sum_{S_j\cap T_i \neq \emptyset} {Vol(T_i\cap S_j)}.\phi_{S_j}. -\f] - -As the field values are constant on each -cell, the coefficients of the linear remapping matrix \f$ W \f$ are -given by the formula : - -\f[ - W_{ij}=\frac{Vol(T_i\cap S_j)}{ Vol(T_i) }. -\f] - - -\section InterpKerP0P0Ext cell-cell (P0->P0) conservative remapping of extensive fields - -In code coupling from neutronics to hydraulics, \b extensive field -of power is exchanged and the total power should remain the same. -The discrete values of the field represent the total power contained in the cell. -Hence in the \ref InterpKerGenralEq "general interpolation equation" the -left hand side becomes : - -\f[ -\int_{T_i} \phi = P_{T_i}, -\f] - -while the right hand side is now : - -\f[ -\sum_{S_j\cap T_i \neq \emptyset} \int_{T_i\cap S_j} \phi = -\sum_{S_j\cap T_i \neq \emptyset} \frac{Vol(T_i\cap S_j)}{ Vol(S_j)}.P_{S_j}. -\f] - -The coefficients of the linear remapping matrix \f$ W \f$ are then -given by the formula : - -\f[ - W_{ij}=\frac{Vol(T_i\cap S_j)}{ Vol(S_j) }. -\f] - -\section TableNatureOfField Summary -In the case of fields with a P0 representation (cell based) and when the meshes do not overlap, the scheme is either conservative or maximum preserving (not both). Depending on the \ref NatureOfField the interpolation coefficients take the following value: - - * - * - * - * - *
Intensive extensive
Conservation \f[\frac{Vol(T_i\cap S_j)}{ Vol(T_i)}\f]
\ref TableNatureOfFieldExampleRevIntegral "RevIntegral"
\f[ \frac{Vol(T_i\cap S_j)}{ \sum_{T_i} Vol(S_j\cap T_i) }\f]
\ref TableNatureOfFieldExampleIntegralGlobConstraint "IntegralGlobConstraint"
Maximum principle \f[\frac{Vol(T_i\cap S_j)}{ \sum_{S_j} Vol(T_i\cap S_j)}\f]
\ref TableNatureOfFieldExampleConservVol "ConservativeVolumic"
\f[\frac{Vol(T_i\cap S_j)}{ Vol(S_j) }\f]
\ref TableNatureOfFieldExampleIntegral "Integral"
- -\section TableNatureOfFieldExample Illustration of a non overlapping P0P0 interpolation - -Let's consider the following case with a source mesh containing two cells and a target mesh containing one cell. -Let's consider a field FS on cells on the source mesh that we want to interpolate on the target mesh. - -The value of FS on the cell#0 is 4 and the value on the cell#1 is 100. - -The aim here is to compute the interpolated field FT on the target mesh of field FS depending on the \ref NatureOfField "nature of the field". - -\anchor TableNatureOfFieldEx1 -\image html NonOverlapping.png "An example of non overlapping intersection of two meshes." - -The first step of the interpolation leads to the following M1 matrix : - -\f[ - M1=\left[\begin{tabular}{cc} - 0.125 & 0.75 \\ - \end{tabular}\right] - \f] - -\subsection TableNatureOfFieldExampleConservVol Conservative volumic case - -If we apply the formula \ref TableNatureOfField "above" it leads to the following \f$ M_{Conservative Volumic} \f$ matrix : - -\f[ - M_{Conservative Volumic}=\left[\begin{tabular}{cc} - $\displaystyle{\frac{0.125}{0.125+0.75}}$ & - $\displaystyle{\frac{0.75}{0.125+0.75}}$ \\ - \end{tabular}\right]=\left[\begin{tabular}{cc} - 0.14286 & 0.85714 \\ - \end{tabular}\right] -\f] -\f[ - FT=\left[\begin{tabular}{cc} - $\displaystyle\frac{0.125}{0.875}$ & $\displaystyle\frac{0.75}{0.875}$ \\ - \end{tabular}\right].\left[\begin{tabular}{c} - 4 \\ - 100 \\ - \end{tabular}\right] - =\left[\begin{tabular}{c} - 86.28571\\ - \end{tabular}\right] -\f] - -As we can see here the maximum principle is respected.This nature of field is particularly recommended to interpolate an intensive -field such as \b temperature or \b pressure. - -\subsection TableNatureOfFieldExampleIntegral Integral case - -If we apply the formula \ref TableNatureOfField "above" it leads to the following \f$ M_{Integral} \f$ matrix : - -\f[ - M_{Integral}=\left[\begin{tabular}{cc} - $\displaystyle{\frac{0.125}{9}}$ & $\displaystyle{\frac{0.75}{3}}$ \\ - \end{tabular}\right]=\left[\begin{tabular}{cc} - 0.013888 & 0.25 \\ - \end{tabular}\right] -\f] -\f[ - FT=\left[\begin{tabular}{cc} - $\displaystyle{\frac{0.125}{9}}$ & $\displaystyle{\frac{0.75}{3}}$ \\ - \end{tabular}\right].\left[\begin{tabular}{c} - 4 \\ - 100 \\ - \end{tabular}\right] - =\left[\begin{tabular}{c} - 25.055\\ - \end{tabular}\right] -\f] - -This type of interpolation is typically recommended for the interpolation of \b power (\b NOT \b power \b density !) for -a user who wants to conserve the quantity \b only on the intersecting part of the source mesh (the green part on the \ref TableNatureOfFieldEx1 "example") - -This type of interpolation is equivalent to the computation of \f$ FS_{vol} \f$ followed by a multiplication by \f$ M1 \f$ where \f$ FS_{vol} \f$ is given by : - -\f[ - FS_{vol}=\left[\begin{tabular}{c} - $\displaystyle{\frac{4}{9}}$ \\ - $\displaystyle{\frac{100}{3}}$ \\ - \end{tabular}\right] -\f] - -In the particular case treated \ref TableNatureOfFieldEx1 "here", it means that only a power of 25.055 W is intercepted by the target cell ! - -So from the 104 W of the source field \f$ FS \f$, only 25.055 W are transmitted in the target field using this nature of field. -In order to treat differently a power field, another policy, \ref TableNatureOfFieldExampleIntegralGlobConstraint "integral global constraint nature" is available. - -\subsection TableNatureOfFieldExampleIntegralGlobConstraint Integral with global constraints case - -If we apply the formula \ref TableNatureOfField "above" it leads to the following \f$ M_{IntegralGlobConstraint} \f$ matrix : - -\f[ - M_{IntegralGlobConstraint}=\left[\begin{tabular}{cc} - $\displaystyle{\frac{0.125}{0.125}}$ & ${\displaystyle\frac{0.75}{0.75}}$ \\ - \end{tabular}\right]=\left[\begin{tabular}{cc} - 1 & 1 \\ - \end{tabular}\right] -\f] -\f[ - FT=\left[\begin{tabular}{cc} - 1 & 1 \\ - \end{tabular}\right].\left[\begin{tabular}{c} - 4 \\ - 100 \\ - \end{tabular}\right] - =\left[\begin{tabular}{c} - 104\\ - \end{tabular}\right] -\f] - -This type of interpolation is typically recommended for the interpolation of \b power (\b NOT \b power \b density !) for -a user who wants to \b conserve \b all \b the \b power in its source field. Here we have 104 W in source field, we have 104 W too, -in the output target interpolated field. - -\b BUT, As we can see here, the maximum principle is \b not respected here, because the target cell #0 has a value higher than the two -intercepted source cells. - -\subsection TableNatureOfFieldExampleRevIntegral Reverse integral case - -If we apply the formula \ref TableNatureOfField "above" it leads to the following \f$ M_{RevIntegral} \f$ matrix : - -\f[ - M_{RevIntegral}=\left[\begin{tabular}{cc} - $\displaystyle{\frac{0.125}{1.5}}$ & $\displaystyle{\frac{0.75}{1.5}}$ \\ - \end{tabular}\right]=\left[\begin{tabular}{cc} - 0.083333 & 0.5 \\ - \end{tabular}\right] -\f] -\f[ - FT=\left[\begin{tabular}{cc} - $\displaystyle{\frac{0.125}{1.5}}$ & $\displaystyle{\frac{0.75}{1.5}}$ \\ - \end{tabular}\right].\left[\begin{tabular}{c} - 4 \\ - 100 \\ - \end{tabular}\right] - =\left[\begin{tabular}{c} - 50.333\\ - \end{tabular}\right] -\f] - -This type of nature is particulary recommended to interpolate an intensive \b density -field (moderator density, power density). -The difference with \ref TableNatureOfFieldExampleConservVol "conservative volumic" seen above is that here the -target field is homogenized to the \b whole target cell. It explains why this nature of field does not follow the maximum principle. - -To illustrate the case, let's consider that \f$ FS \f$ is a power density field in \f$ W/m^2 \f$. -With this nature of field the target cell #0 accumulates 0.125*4=0.5 W of power from the source cell #0 and 0.75*100=75 W of power from the source cell #1. -It leads to 75.5 W of power on the \b whole target cell #0. So, the final power density is equal to 75.5/1.5=50.333 W/m^2. - -*/ - - diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersec-specifics.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersec-specifics.dox deleted file mode 100644 index 041d57feb..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersec-specifics.dox +++ /dev/null @@ -1,140 +0,0 @@ -/*! -\page intersec-specifics Specificities of 2D and 3D intersectors - -All the options described here can be set using the -\ref ParaMEDMEM::MEDCouplingRemapper::setOptionInt "MEDCouplingRemapper::setOptionInt", -\ref ParaMEDMEM::MEDCouplingRemapper::setOptionDouble "MEDCouplingRemapper::setOptionDouble", -and \ref ParaMEDMEM::MEDCouplingRemapper::setOptionString "MEDCouplingRemapper::setOptionString" -methods. - -\section interpolation2D Special features of 2D intersectors - -\subsection InterpKerPlanarIntGenP0P0 P0->P0 : PlanarIntersector. - -All the 2D intersectors inherits from INTERP_KERNEL::PlanarIntersector class. - -The main task offered by this class is to give the -evaluation of the interpolation of one cell in source mesh with an another -cell in the target mesh. - -\subsection InterpKerPlanarIntFeatureP0P0 P0->P0 intersectors features. - -When remapping two dimensional fields, areas of intersection between polygonal cells are to be computed. Three algorithms are available: -- Triangle: decompose each cells into triangles and computes triangle-triangle intersection by determining segment crossings and node inclusions. This algorithm is the fastest if both meshes are made of triangular cells. -- Convex: presume that both meshes are made of convex cells, and performs a direct computation of the intersection nodes between two cells through a sweep line algorithm (see F. Preparata and M. Shamos, 1985 in \ref references). -For the moment, it is only possible to remap two dimensional fields on -meshes with mixed triangular and quadrangular elements. -- Geometric2D: Any type of 2D cells (linear, quadratic, convex-polygons, -non-convex polygons) is supported by this algorithm. Due to its -flexibility this algorithm is slower than the other. -- \anchor pointlocator PointLocator: This is a \b non \b conservative interpolator. For P0P0, it -locates the barycenter of target cell in the source cells. For P1P0, it -locates barycenter of target cell and compute \ref barycoords "barycentric coordinates" -in source cell (Works only with Triangle). For P0P1 locate target nodes -in source cells. For P1P1 compute for each target node its barycentric coordinates in source cell. - -The following options are available for the 2D intersection computations: - * - * - * - * - * - *
OptionDescription Admitted valuesDefault
Intersection_typeSpecifies the algorithm to be - * used in the computation of the cell-cell intersections - * Triangle, Convex, \ref interpkernelGeo2D "Geometric2D", PointLocator Triangle
Precision Accuracy of the computations is precision times the characteristic size of the meshes positive real numbers 1.0E-12
PrintLevel Level of verboseness during the computations 0, 1, 2, 3 0
- -\section interpolation3Dsurf Special features of 3D surface intersectors - -When remapping a three dimensional surfaces, one should give a meaning to the area of intersection between two three-dimensional non coplanar polygons. A projection phase is thus necessary to have both polygons on the same plane. Care must be taken when defining this projection to avoid non conservative remappings. After the projection step, the source and target cells lie in the same plane and the same algorithms as for 2D remapping can be employed. -For the moment, it is only possible to remap fields on three dimension surface meshes with mixed triangular and quadrangular elements. -Similar options as for the 2D remapping are available, plus some additional options specific to 3D surface remapping: - - * - * - * - * - * - * - * - * - * - *
OptionDescription Admitted valuesDefault
MedianPlane Position of the median plane where both cells will be projected real numbers between 0 and 1 0.5
Precision Accuracy of the computations is - * precision times the characteristic size of the meshes - * positive real numbers 1.E-12
Orientation Specifies orientation to take into account. If -1 only negative intersection area are taken into account. If 1 only positive intersection - * area are taken into account. If 0 intersection area are always taken into account. If 2 intersection area are always taken into account (as 0) difference is that absolute value -1,0,1,2 0
DoRotate Performs a rotation of the coordinate - system such that the median plane is the Oxy plane - boolean true or false true
BoundingBoxAdjustmentWhen detecting an intersection between bounding boxes, the bounding are expanded by a factor (1+BoundingBoxAdjustment). It is particularly useful when detecting intersections for 3D surfaces for which the bounding boxes might not actually intersect. positive real numbers 1.e-4
BoundingBoxAdjustmentAbsWhen detecting an intersection between bounding boxes, the bounding are expanded uniformly in the 3 dimension of space with the absolute value BoundingBoxAdjustmentAbs. It is particularly useful when detecting intersections for 3D surfaces for which the bounding boxes might not actually intersect. positive real numbers 0.
MaxDistance3DSurfIntersectBefore attempting an intersection in 3D surf test the distance D between fast barycenter of target cell and medium source plane P. If option < 0. no interpretation of D is done. If option > 0. then if D real numbers -1.
- -Note that choosing the Triangle Intersection_type necessarily set the DoRotate option to true. - -\section interpolation3D Special features of 3D volumes intersectors - -\subsection InterpKer3DIntGenP0P0 P0->P0 : TargetIntersector - -Unlike \ref InterpKerPlanarIntGenP0P0 "PlanarIntersector phylosophy" -this intersector is slightly different. Here for the moment -there is one instance per pair of meshes \b and target element. See INTERP_KERNEL::TargetIntersector for more details. - -\subsection InterpKer3DIntFeatureP0P0 P0->P0 intersectors features. - -When remapping three dimensional fields, volumes of intersection -between polyhedral cells are to be computed. -Two methods are available : -- Triangle : the method of Jeffrey Grandy, 1999 (see \ref references) -to intersect arbitrary polyhedra. The basic algorithm computes the -intersection of a tetrahedron with an arbitrary (possibly non convex) -polyhedron. Using splitting techniques, it is possible to transform -the problem of computing the intersection between two general -polyhedra into several tetrahedron-polyhedron intersection -calculations. For the moment it is only possible to remap fields on -meshes having mixed tetrahedral and hexahedral cells. When using a -mesh with hexahedral cells, several splitting techniques may be -employed depending mainly on whether the faces are planar or not. The -following options are available for the splitting: -- PointLocator : \b non \b conservative intersector based on the same -principle than described in 2D. - - * - * - * - * - * - *
OptionDescription Admitted valuesDefault
Intersection_typeSpecifies the algorithm to be - * used in the computation of the cell-cell intersections - * Triangle, PointLocator Triangle
SplittingPolicy Way in which the hexahedra are - * split into tetrahedra (only if Intersection_type==Triangle) PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48 GENERAL_48
PrintLevel Level of verboseness during the computations 1, 2, 3, 4, 5 0
- -Note that a SplittingPolicy values starting with the word "PLANAR" presume that each face is to be considered planar, while the SplittingPolicy values starting with the word GENERAL does not. The integer at the end gives the number of tetrahedra that result from the split. - Consider an hexahedron with planar faces and nodes numbered according to the following picture: -\verbatim - - 7 ------ 6 - /| /| - / | / | - 3 ------ 2 | - | | | | - | | | | - | 4-----|- 5 - | / | / - 0 ------ 1 -\endverbatim -The use of the SPLIT_NODES_5 splitting policy would lead to a 5 tetrahedra decomposition as follows : -\verbatim - 0, 1, 5, 2 - 0, 4, 5, 7 - 0, 3, 7, 2 - 5, 6, 7, 2 - 0, 2, 5, 7 -\endverbatim -The use of the SPLIT_NODES_6 splitting policy would lead to a 6 tetrahedra decomposition as follows : -\verbatim - 0, 1, 5, 6 - 0, 2, 1, 6 - 0, 5, 4, 6 - 0, 4, 7, 6 - 0, 3, 2, 6 - 0, 7, 3, 6 -\endverbatim - - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersectors.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersectors.dox deleted file mode 100644 index 1729060bd..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intersectors.dox +++ /dev/null @@ -1,18 +0,0 @@ -/*! - -\page InterpKerIntersectors Intersectors and point locators - -The various interpolation methods often require the computation of the intersection between -a cell of the source mesh and a cell of the target mesh, or the localization of a point -inside another mesh. The intersectors implemented in the -library take care of this job. - -Before reading on, remember the definition of a \ref glossary "P0 and P1 field". - -- \subpage intersec-specifics -- \subpage interpkernelGeo2D -- \subpage barycoords (used in some P1 intersectors/locators) - -Some implementation details of the C++ code can also be found here: \ref interpkernel - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intro-interp.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intro-interp.dox deleted file mode 100644 index 17a8ea446..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/intro-interp.dox +++ /dev/null @@ -1,52 +0,0 @@ -/*! -\page intro-interp Interpolation presentation - -\section interp-over Overview - -The InterpKernel algorithms are part of the MED tool suite. They -answer to the following basic problem : given a source mesh \f$M_s\f$, a -source field \f$F_s\f$ and a target mesh \f$M_t\f$, reconstruct a field \f$F_t\f$ -that uses \f$M_t\f$ as a support. The InterpKernel suite gives a number of -possibilities to compute the target field, depending on a variety of -user constraints. - -\image html interpolationimage.png "General interpolation scheme" width=10cm - -Two different APIs are available depending on whether you run sequentially or in parallel: -- the \ref remapper "remapper class" (based on the underlying \ref interpkernel "InterpKernel" library) -for sequential codes, which uses MEDCoupling \ref fields "fields" and other core data structures. -- the \ref parallel "ParaMEDMEM API" for parallel MPI based codes using \c %ParaMEDMEM distributed fields -(\ref ParaMEDMEM::ParaFIELD "ParaFIELD"), which is also based on the algorithms of the -\ref interpkernel "InterpKernel" library. - -The following space/mesh dimensions are covered: -- 1D, 2D lines, 2D surfaces (\ref interpolation2D), -- 3D surfaces (\ref interpolation3Dsurf) -- and 3D volumes (\ref interpolation3D) - -The interpolation is performed either by: -- node localization (\ref pointlocator "PointLocator"), when for example a node field is projected to a cell field -- or via cell intersection (\ref ConsInterp), when for example a cell field is projected to another cell field. -For any given type of interpolation involving cell intersection computation, the computation of -interpolation matrix W is performed in two steps : - -# A filtering process reduces the number of pairs of elements for which the calculation -must be carried out by eliminating the pairs whose bounding boxes do not intersect. - -# For all remaining pairs, call the appropriate \ref InterpKerIntersectors "cell intersector" - -More complex treatments are also available: -- treatment of extended polygons (where edges can be arcs or segments) -for 2D intersection computations, via the \ref interpkernelGeo2D "Geometric2D intersector", - -Finally the following types of \ref discretization "spatial discretization" combinations are supported: -- management of fields with P0,P1 or P2 representations -- P0<->P0, P1<->P0, P1<->P1 and P2->P0 (non conservative) interpolators are available. - -Remember that whatever the situation you face, you must always specify whether the field -represents an extensive or intensive physical quantity through -the \ref NatureOfField "nature" attribute of the \ref fields "field". - -\section interp-api Key elements of the API - -TODO, list setOption, setIntersectionType, etc ... - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/remapper.dox b/medtool/doc/user/doxygen/doxfiles/reference/interpolation/remapper.dox deleted file mode 100644 index c03c0bad9..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/interpolation/remapper.dox +++ /dev/null @@ -1,28 +0,0 @@ - -/*! -\page remapper The remapper class. - -\section InterpKerHighLevUsage High-level usage - -The simplest way of using the \ref intro-interp "interpolations" in sequential mode is to use the class \c ParaMEDMEM::MEDCouplingRemapper . This class fulfills \c HXX2SALOME rules and may be used in YACS coupling graphs. - -If you intend to use \ref medcoupling "MEDCoupling data structures", the ParaMEDMEM::MEDCouplingRemapper class should be used. - -\if ENABLE_EXAMPLES -Here is a \ref cpp_mcfield_remapper_highlevel "C++ example". -\endif - -\section InterpKerMidLevUsage Middle-level usage - -This mode is the mode that needs the minimum of prerequisites -(algorithms and the data structure you intend to use). On the other -hand it is needed to specify precisely nature of interpolator. - -As a consequence of the genericity of the interpolators, they are usable only by -instantiating an underlying \ref InterpKerMeshType "mesh" and \ref InterpKerMatrixType "matrix" data structure fulfilling some requirements. - -\if ENABLE_EXAMPLES -Here is a \ref cpp_mcfield_remapper_middlelevel "C++ example". -\endif - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/medcoupling.dox b/medtool/doc/user/doxygen/doxfiles/reference/medcoupling.dox deleted file mode 100644 index 271204fb6..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/medcoupling.dox +++ /dev/null @@ -1,39 +0,0 @@ -/*! -\page medcoupling Core data structures (MEDCoupling) - -

Overview

- -The MEDCoupling library gather the core structures used everywhere in the MED world. - -- \subpage arrays -- \subpage numbering -- \subpage meshes -- \subpage fields - -

Design philosophy

- -The structures described above (arrays, meshes and fields), with the algorithms associated to it -form the core of the MEDCoupling library (\b libmedcoupling.so or \b medcoupling.dll). -It is fully written in C++ and wrapped in Python. - -The MEDCoupling C++ library implements a data structure which is the result of the following tradeoff: -- compliant with \ref glossary "code coupling": - - fields data structure containing enough information to perform a well defined interpolation - - data structure exchangeable through processes, as well in \ref parallel "parallel" (SPMD paradigm - - \ref library "sometimes called ParaMEDMEM"), as in a \ref corba-distrib "distributed paradigm" (using CORBA). -- minimize as much as possible the number of external software prerequisites needed to use it (the core of the -library, MEDCoupling, can be built as a standalone tool). -- light and agile enough to: - - maximize the amount of possible algorithms being applied on it - - ease the implementation of other projects using MEDCoupling as a prerequisite. -- large enough to be used for MED file I/O (thanks to the \ref medloader "MEDLoader" part). -- compliant with VTK visualization data structures -- integrate HPC constraints (compact structures, limitation of copies and launching of CPU consuming algorithms only when absolutely needed ). -- compliant with the \ref icoco "ICoCo API" - -The MEDCoupling also implements a set of algorithms linked to this data structure. The -\ref functionalities "functionalities" section gives an insight of the avalaible algorithm. - - - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/medloader/MEDLoaderAdvancedAPI.dox b/medtool/doc/user/doxygen/doxfiles/reference/medloader/MEDLoaderAdvancedAPI.dox deleted file mode 100644 index 60ae211f4..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/medloader/MEDLoaderAdvancedAPI.dox +++ /dev/null @@ -1,294 +0,0 @@ - -/*! -\page MEDLoaderAdvancedAPIPage Advanced MEDLoader API - -[TOC] - -This method is much closer to MED file organization than the \ref -MEDLoaderBasicAPIPage "basic MEDLoader API". All MED file -concepts are exposed to the user. As a consequence, this advanced -API is meant to evolve with MED file data model enhancement. - -In reading mode, the user can scan entirely and directly the contents of -its MED file directly as it is organized on the disk. -Inversely, in writing mode, the user can describe its data in the same -way that MED file does on the disk. - -When looking for a specific point in the API, the diagram provided at the -end of this section might help: - -\section AdvMEDLoaderBasics Some of basics of advanced API - -- Like basic %MEDLoader API there is a notion of \c meshDimRelToMax. -Each time this parameter appears in API, it will have the semantic -explained here. -The value of the parameter \c meshDimRelToMax is at most in {0,-1,-2,-3}. This relative value specifies a level -relative to the value returned by ParaMEDMEM::MEDFileMesh::getMeshDimension(). - -A mesh containing MED_TETRA4, MED_TRI3, MED_QUAD4 and MED_POINT1 has a meshDimension -equal to 3. For \c meshDimRelToMax equal to 0 the user will -deal with cells whose type has a dimension equal to 3+0, that is to -say here MED_TETRA4. For \c meshDimRelToMax equal to -1 the user will -deal with cells which dimension equals 3-1 that is to say MED_TRI3 -and MED_QUAD4. - -An important method is ParaMEDMEM::MEDFileUMesh::getNonEmptyLevels(). It returns all -non empty levels available. In the previous example, this method will -return {0,-1,-3}. -2 does not appear because no cells with dimension -equal to 1 (3-2) appear in MED file mesh (no MED_SEG2, no MED_SEG3). - -- Besides notion of \c meshDimRelToMax there is notion of \c meshDimRelToMaxExt. -\c meshDimRelToMaxExt is simply an extension of \c meshDimRelToMax for -nodes. - -The parameter of \c meshDimRelToMaxExt appears in -\ref ParaMEDMEM::MEDFileUMesh "umesh advanced API" of %MEDLoader with the following semantics. - -Some of MED file concepts are available both for cells and -nodes (for example families, groups, numbering) ; that's why for a simpler API this -concept has been introduced. \c meshDimRelToMaxExt parameter can take a value in at -most {1,0,-1,-2,-3}. -1 stands for node and 0,-1,-2,-3 has exactly the -same semantic than those described in \c meshDimRelToMax -before. - -- A parameter that also often appears in advanced %MEDLoader API is \c renum. -This parameter is set to \c -true by default. -This parameter indicates if the user intends to take into account -the renumbering array of cells of the current MED file mesh. -If no renumbering array is defined, this parameter is ignored by -%MEDLoader. - -If such renumbering exists and the \c renum parameter is -set to \c true, then the renumbering is taken into account. This is -exactly the behaviour of \ref MEDLoader::ReadUMeshFromFile "basic MEDLoader API". -If the user expects to ignore this renumbering even in case of -presence of renumbering array, false should be passed to \c renum -parameter. \b The \b parameter \b renum \b should \b be \b set \b with -\b caution \b for \b users \b concerned \b by \b cells \b orders. - -- A last important parameter is the \c mode during writing. The - available values for the parameter \c mode are : - - 2 : for a write from scratch. If file already exists, file will be - erased and replace by the content of the instance on which \c write - method has been called. - - 1 : If the file does not exists equivalent to 2. If file already - exists, the write is done on APPEND mode. That is to say that no - data loss will occur. But in case that an element with same ids than - current instance already exists, the content is not written and an - exception is thrown. - - 0 : If the file does not exists equivalent to 2. If file already - exists write without any question. If an element with same ids - existed previously the content is overwritten by the content of the - current instance, that can lead to a file corruption. - -\section AdvMEDLoaderAPIMeshesRW Dealing with Meshes with advanced API. - -Contrary to the basic %MEDLoader API, here after reading process, the user -has to deal with a new instance of class that fits the MED file model. -To access a MEDCoupling mesh user should request this class -instance. - -\subsection AdvMEDLoaderAPIMeshReading Reading a mesh. - -The class that incarnates Read/Write mesh in MED file is ParaMEDMEM::MEDFileUMesh. - -First of all, like basic %MEDLoader API, only MEDfile files whose version >= 2.2 are able -to be read with advanced API. - -To read a mesh having the name \c meshName in file \c fileName the -following simple code has to be written : - -\code - -MEDFileUMesh *myMedMesh=MEDFileUMesh::New(fileName,meshName); - -\endcode - -If the user do not know the name of the mesh inside MED file -'fileName' the following code should be written : - -\code - -MEDFileUMesh *myMedMesh=MEDFileUMesh::New(fileName); - -\endcode - -In this case the first mesh (in MED file sense) found in \c fileName -file will be loaded. - -Now the user can ask for mesh dimension of of \c myMedMesh instance by -calling \c myMedMesh->getMeshDimension(). This method returns the -highest level of present cell in MED file mesh \c myMedMesh. -This returned integer is computed and \b not those contained in MED file -that can be invalid. - -\n - -- Retrieving a mesh at a specified relative level \c meshDimRelToMax=mdrm : simply call - - \c myMedMesh->getMeshAtLevel(mdrm) - - or \c myMedMesh->getLevel0Mesh() or \c - myMedMesh->getLevelM1Mesh(), or \c myMedMesh->getLevelM2Mesh() - depending on the value of mdrm - - -- Retrieving a family at a specified level : - - Either an array of node/cell id - - \c getFamilyArr method or \c getFamiliesArr - - Or on \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" form by calling - - \c getFamily method or \c getFamilies - -- Retrieving a group at a specified level : - - Either an array of node/cell id - - \c getGroupArr method or \c getGroupsArr - - Or on \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" form by calling - - \c getGroup method or \c getGroups - -- Retrieving family field array : -Method \c getFamilyFieldAtLevel retrieves for a specified extended level the -family id of each cell or node. - -- Retrieving renumbering array : -Method \c getNumberFieldAtLevel returns, if it exists for a specified extended level, the -family id of each cell or node. If it does not exist an exception will -be thrown. - -An important point is that families and groups are \b not sorted in -MED file. No sort is stored in MED file explicitly for Groups and -Families. Advanced %MEDLoader API, uses the same order than underlying -mesh at specified level. - -\anchor AdvMEDLoaderAPIMeshReadingSampl - -\if ENABLE_EXAMPLES -Here is a \ref cpp_mcumesh_loadfile "C++ example" illustrating a typical use of \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" instance. -\endif - -\subsection AdvMEDLoaderAPIMeshWriting Writing a mesh. - -The use is very symmetric to reading part. It is possible to either -build a \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance from -scratch, or to work with an existing instance coming from a loading -from a file. - -One important point is that coordinates of a mesh are shared by all -cells whatever their level. That's why the -\ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" instance -should be shared by all \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" used in input parameter of -set* methods. If the user intends to build a \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance from -scratch, a call to \c setCoords should be done first. - - -Generally speaking traduce get* methods with set* methods have corresponding write semantic. - -Some differences still exist : - -- \c setMeshAtLevel, \c setMeshAtLevelOld simply call \c setMeshAtLevelGen with repectively \c newOrOld parameter -set to true and false. These methods specify if a renumbering computation is needed or not. \c setMeshAtLevelOld is faster -than \c setMeshAtLevel because no renumbering computation is done. If the user is not warranty about the order of its meshes to enter -it is better to use \c setMeshAtLevel method. - -- Groups definition : Groups constitution is time consuming because of the store mode chosen by MED file. Groups definition -leads to a partition computation which is time/memory consuming ; that is why groups should be defined at once and not with addGroup one by one that will lead to -compute a partition for each appended group. One important point to note is that DataArrayInt instance given in input to define groups should have its name -set to the desired group name. If not an exception will be thrown, because MED file does not support groups with no name. - -\anchor AdvMEDLoaderAPIMeshWritingSampl - -\if ENABLE_EXAMPLES -Here is a \ref cpp_mcumesh_writefile "C++ example". -\endif - -\section AdvMEDLoaderAPIFieldRW Dealing with Fields with advanced API. - -In advanced API fields have been developed using divide and conquer pattern to reproduce with the maximal fidelity the MED file field concept \ref BasicMEDLoaderAPIGen "seen here". - -Here the list of classes in %MEDLoader advanced API top down sorted : - -- Level 0 : ParaMEDMEM::MEDFileFields -- Level -1 : ParaMEDMEM::MEDFileFieldMultiTSWithoutSDA -- Level -2 : ParaMEDMEM::MEDFileField1TSWithoutSDA -- Level -3 : ParaMEDMEM::MEDFileFieldPerMesh (present only for backward compatibility MED file 2.2) -- Level -4 : ParaMEDMEM::MEDFileFieldPerMeshPerType -- Level -5 : ParaMEDMEM::MEDFileFieldPerMeshPerTypePerDisc - - -Each level in the tree representing a field (cyan box) is represented by a class. The only difference is that values are grouped in a single big array located -in level -2 (ParaMEDMEM::MEDFileField1TSWithoutSDA) in which each leaf (level -5) of MED file field -points to range [\a start, \a end). - -As different time steps of a same field and different fields inside a MED file can share or not profiles (yellow box) and localization (red box) a manipulable field classes instance -(ParaMEDMEM::MEDFileField1TS and ParaMEDMEM::MEDFileFieldMultiTS) in advanced API is the result of a subclass of a data class -(respectively ParaMEDMEM::MEDFileField1TSWithoutSDA, ParaMEDMEM::MEDFileFieldMultiTSWithoutSDA) and an instance of ParaMEDMEM::MEDFileFieldGlobsReal representing the shared data arrays (SDA) -at a specified scope inside the MED file. - -\subsection AdvMEDLoaderAPIFieldR Reading a field - -\subsubsection AdvMEDLoaderAPIFieldRC Reading a field defined on all entities - -Fields defined on all entities are the most used and common fields in MED file world. - -In this mode the user does **not** want to retrieve the entity ids of the constituting subsupport of the whole mesh because it has no sense. - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_loadfile_allentities "Python example". -\endif - -\subsubsection AdvMEDLoaderAPIFieldRP Reading a partial field - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_loadfile_partial "Python example". -\endif - -\subsection AdvMEDLoaderAPIFieldW Writing a field - -\subsubsection AdvMEDLoaderAPIFieldWC Writing a field defined on all entities - -Fields defined on all entities are the most used and common fields in MED file world. - -In this mode the user do **not** want to retrieve the entity ids of the constituting subsupport of the whole mesh because it has no sense. - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_writefile_allentities "Python example". -\endif - -\subsubsection AdvMEDLoaderAPIFieldWP Writing a partial field - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_writefile_partial "Python example". -\endif - -\section AdvMEDLoaderDiagram Simplified class diagram of the advanced API - -\image html med-loader-adv-classes.png "Class diagram of the advanced MEDLoader API" - -The blue rectangles show the links to the MEDCoupling objects. Note that in MEDCoupling there is no -representation of a field of integer. Those are extracted directly as \ref ParaMEDMEM::DataArrayInt "DataArrayInt". - -The classes shown on this diagram (all part of the \ref cpp "unfortunately named ParaMEDMEM namespace"): -- \ref ParaMEDMEM::MEDFileData "MEDFileData", the encapsulation of a complete MED file - -and also: -- \ref ParaMEDMEM::MEDFileMeshes "MEDFileMeshes", the set of meshes in the file -- \ref ParaMEDMEM::MEDFileMeshMultiTS "MEDFileMeshMultiTS", a single mesh with muliple time steps -- \ref ParaMEDMEM::MEDFileMesh "MEDFileMesh", a single mesh on a single timestep -- \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh", a single unstructured mesh - -and also: -- \ref ParaMEDMEM::MEDFileFields "MEDFileFields", the set of fields in a MED file -- \ref ParaMEDMEM::MEDFileAnyTypeFieldMultiTS "MEDFileAnyTypeFieldMultiTS", a single field with multiple -time steps (can be an integer field or a double field) -- \ref ParaMEDMEM::MEDFileFieldMultiTS "MEDFileFieldMultiTS", a single field of doubles with multiple time steps -- \ref ParaMEDMEM::MEDFileIntFieldMultiTS "MEDFileIntFieldMultiTS", a single field of int with multiple time steps -- \ref ParaMEDMEM::MEDFileFieldMultiTS "MEDFileAnyTypeField1TS", a single field with a single time step -(integer or double) -- \ref ParaMEDMEM::MEDFileField1TS "MEDFileField1TS", a single field of doubles with a single time step -- \ref ParaMEDMEM::MEDFileIntField1TS "MEDFileIntField1TS", a single field of ints with a single time step - -and finally: -- \ref ParaMEDMEM::MEDFileParameters "MEDFileParameters", numerical parameters stored in a MED file - - - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/medloader/MEDLoaderBasicAPI.dox b/medtool/doc/user/doxygen/doxfiles/reference/medloader/MEDLoaderBasicAPI.dox deleted file mode 100644 index c4eb56848..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/medloader/MEDLoaderBasicAPI.dox +++ /dev/null @@ -1,236 +0,0 @@ - -/*! -\page MEDLoaderBasicAPIPage Basic MEDLoader API - -[TOC] - -The aim of this page is to present MEDLoader basic API. The goal of -this basic API is to perform a read or a write in one shot without any -internal state. That's why the basic API of MEDLoader offers \b only \b static methods whose names have the first -character in capital. You are intended to use these methods. The following -chapters will try to describe in details some of important ones. - -The basic idea of MEDLoader is to exploit as much as possible MED - file capabilities to store MEDCoupling data file in a MED file and -reversely to load from a MED file into a MEDCoupling data structure. -Basically, the info on components of ParaMEDMEM::DataArrayDouble instances are stored into components and units into MED files. The -name of meshes and fields are used by MEDLoader as is into -MED file. From a field f with \ref ParaMEDMEM::MEDCouplingTimeDiscretization -"time discretization" set to ONE_TIME, calls to -\c f->getTime(time,iteration,order) are used by MEDLoader to store the field into MED file. All strings used by MEDLoader should fulfill the rules of MED file where string length -is limited. -That's why the user should be aware of these constraints when trying to read/write a MED file using MEDLoader. -MEDLoader tries to manage that by protecting the user by throwing exceptions when the rules are not followed. - -\section BasicMEDLoaderBasicAPIGlobalInfo Retrieving tiny global information from MED files using basic API - -The MEDLoader::CheckFileForRead method will perform such a check before any attempt of read. -A field is also discriminated by its name. The methods MEDLoader::GetCellFieldNamesOnMesh and MEDLoader::GetNodeFieldNamesOnMesh are available to know all fields -respectively on cells and on nodes lying on a specified mesh. - - A field is defined by several time steps discriminated by a pair of ints -(iteration,order). It is \b not possible to store 2 time steps of a same -field having the same iteration and order -numbers. The floating point value attached to this couple of ids (iteration,order) is only present for information. -Static methods MEDLoader::GetCellFieldIterations and -MEDLoader::GetNodeFieldIterations return a vector of pairs (iteration, order). - -A field time step lies on one \b or \b more mesh(es) specified by its \b or \b their name(s). A field time step in -MED file could be defined on point \b and on cell \b and, \b or on Gauss points \b and, \b or on point per element. - -This recalled specificities of MED file explain that it is necessary to specify each time, at field-read time, the type of field, the iteration and order number the mesh you are interested in. - -Let's recall basic principles that explains some of the aspect of MEDLoade API. -\anchor MEDLoaderMeshNameConstraint MED file can contain several meshes. These meshes are -discriminated by their names (two meshes could not have the same -name). In the same way a MED file can contain several fields. -So MEDLoader offers the MEDLoader::GetMeshNames method to -discover all the mesh names contained in your file. - -\section BasicMEDLoaderBasicAPIMesh Reading and writing meshes in MED files using basic API - -In MED file meshes could combine in one unstructured mesh cells that -have different dimension. For example it is possible to mix -MED_TETRA4, MED_TRIA6, MED_SEG2, MED_POINT1, MED_POLYGON, -MED_POLYHEDRA in a same mesh. In MEDCouplingUMesh such a mix is not -allowed as described \ref MEDCouplingMeshes "here". So to \b read such mesh it -is important to know which mesh dimension you are interested in. The parameter \b meshDimRelToMax of method MEDLoader::ReadUMeshFromFile corresponds to the mesh dimension you are -interested in, expressed relatively to the maximal dimension of cells contained -in the mesh in file. - -Let's take 2 examples : - -- If you have a mesh called "MyMesh" in file "file1.med" with -MED_POLYGON, MED_TRI3, MED_SEG2 and MED_SEG3 : The max dimension of -cells is 2 (for MED_POLYGON and MED_TRI3). So if you want exclusively -cells with type MED_POLYGON and MED_TRI3 you should use : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_9 - -If you are interested in MED_SEG2 and MED_SEG3 you should use : - -\snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_10 - -The method MEDLoader::ReadUMeshDimFromFile could -help you to have this mesh dimension. - -Here is a \ref MEDLoaderExample2 "Python example".
- -To finish this subsection, it is important to know that MEDLoader -takes into account the cell numbers stored in a mesh of a med -file. This renumbering allows MEDLoader to conserve the order of -MEDCoupling cells into the file. So if the renumbering of cells in MED -file is not correct an exception will be thrown. - -\subsection BasicMEDLoaderAPIPoMesh Part of meshes in MED files - -A mesh contains one or more families on nodes and/or on cells. A family is a partition -(mathematical sense) of the mesh it lies on. A family can be described -by an integer value on \b all nodes and on \b all cells of a same mesh. -All cells and nodes having the same id define this family. This id -is called the familyId. A family is discriminated by its id. MED file -attaches a name to its id to be more user friendly. So by construction, 2 different -families could not share anything. The user can retrieve all the -families names available on a mesh with the static method MEDLoader::GetMeshFamiliesNames. - -A group is a set of families. So groups can overlap each other, -contrary to families. Groups are also discriminated by a name. As for -families the static method to retrieve the groups of a specified mesh is MEDLoader::GetMeshGroupsNames. - -MEDLoader allows you to retrieve the -corresponding "part of meshes" thanks to static methods -MEDLoader::ReadUMeshFromFamilies and MEDLoader::ReadUMeshFromGroups. -These methods allow you to combine several families and groups in the -same returned mesh. - -\subsection BasicMEDLoaderAPIField Reading a field at one time step in MED files - -A field at one time step on one mesh, with one entity (cell, node) -lies on all mesh on a part of it. In this last case a definition of -a profile is needed. Even if the notions of profile on mesh and group -on mesh could appear close, these two concepts are totally -disconnected in MED file. -The aspect of profile is managed by MEDLoader, that is why this -aspect does not appear in the MEDLoader API. - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_loadfile_onetimestep_basic "Python example". -\endif - -\subsection MEDLoaderMEDFieldsRead Reading several field time steps at a time in MED files - -It is possible with MEDLoader to read several time steps of a field at once. -The advantage with this approach is to avoid reading and loading the same mesh several -times. - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_loadfile_alltimesteps_basic "Python example". -\endif - -\section MEDLoaderWriteMain Writing a MED file with MEDLoader - -As MED file does, MEDLoader write process clearly separates -meshes from fields. The reason is that a common use case in write mode -is to write in a first time a mesh and then to write several time steps -of a same field in appended mode. - -The fact that the write process is rarely in a one shot puts a -constraint on API to precise to MEDLoader if you intend -to append data to an existing file, or if you want to create a new -file from scratch. This explains the presence of boolean parameter \b -writeFromScratch in API of MEDLoader starting with \b -MEDLoader::Write* . - -If \b writeFromScratch parameter is set to \b true and if the file -already exists the file will be crashed and replaced by the new -corresponding data. If \b writeFromScratch parameter is set to \b false and if the -file does \b not \b exist the new file is created, but if the file -exists MEDLoader will enter in appended mode. - -Two classes of MEDLoader write methods exist when \b writeFromScratch -is set to \b false : - -- Methods \b MEDLoader::Write*Dep : The write operation is performed without any question in file. The - responsibility is let to the user because the MED file could be - corrupted. The advantage of this method is that it is faster - because no check is done. -- Methods \b MEDLoader::Write* : MEDLoader will not corrupt your file - by always trying to append data. The consequence is that a - read of part (and data processing) of MED file could be needed before any attempt of - writing. So these methods could be in some cases much time and memory consuming. - -The behaviour of MEDLoader when \b writeFromScratch is set to false will be precised -for each \b MEDLoader::Write* methods is the next subsections. - -\subsection MEDLoaderWriteMesh Writing one mesh in a MED file with MEDLoader - -The first think to know is that MEDLoader is using the \b meshName in -ParaMEDMEM::MEDCouplingMesh instance to put it in MED file. - -As explained in previous section \ref MEDLoaderMeshNameConstraint "here", -a mesh in MED file is discriminated by a name, so the \b meshName -\b should \b be \b non \b empty. If it is the case an -INTERP_KERNEL::Exception will be thrown. - -\if ENABLE_EXAMPLES -Here is a \ref py_mcumesh_writefile_onemesh_basic "Python example". -\endif - -\subsection MEDLoaderWriteMeshes Writing several meshes in a MED file with MEDLoader - -It could be interesting to write several meshes in one shot. Two -possibilities: - -- Write several instances of ParaMEDMEM::MEDCouplingUMesh - lying \b on \b same \b coords \b with \b different \b mesh \b dimensions. In this case MEDLoader::WriteUMeshes is the method you should - use. Typically this method should be used to write files such as - defined \ref MEDLoaderExample2 "here". - This method first checks that all instances share the same - ParaMEDMEM::DataArrayDouble instance as coords. If not an - INTERP_KERNEL::Exception will be thrown and an invocation on - ParaMEDMEM::MEDCouplingPointSet::tryToShareSameCoords will be necessary. - -- Write a partition of meshes having \b same \b mesh \b dimension, that is to say a set of - groups and families from given meshes. As in the previous case the - check of same coords will be done (if not an INTERP_KERNEL::Exception is - thrown). After this step this method will - merge input (preserving order) and will simplify the - merged mesh. After this operation, the groups will be constituted by - assigning the group names with the corresponding names of - instance. That's why all meshes must have a not empty name which is different from one mesh to the other. The method to use in this case is - MEDLoader::WriteUMeshesPartition. - -For these 2 described methods the semantic of \b writeFromScratch when -\b false is the same, that is to say : no writing -(INTERP_KERNEL::Exception thrown) will be done if the -file already exists and contains a mesh with name 'meshName' -for MEDLoader::WriteUMeshesPartition method and the name of first element -of unstructured mesh vector passed as first parameter of -MEDLoader::WriteUMeshes. - -\subsection MEDLoaderWriteField Writing one time step of a field in a MED file with MEDLoader - -To write \b one \b time \b step of a field from scratch with MEDLoader -use MEDLoader::WriteField method. The behaviour of this method depends -on the value of the \b writeFromScratch parameter : - -- When \b writeFromScratch equals to \b true, this method performs two things, it -writes the underlying mesh and writes the specified time step on it. - -- When \b writeFromScatch equals to \b false, this method checks that - the underlying mesh exists (by looking to the contents of \c field->getMesh()->getName()) in file. If not, the behaviour is the - same that previous case with \b writeFromScratch parameter set to - \b true. If the mesh already exists, MEDLoader reads the field and - tries to apply field on it. This operation could be rather time - consuming because a read operation is performed and a reorder - operation too. If the file already contains the same field at the - same time step (iteration and order ids) the corresponding time step - will be replaced by the field passed in parameter. - -\subsection MEDLoaderWriteFields Writing several time steps of a field in a MED file with MEDLoader - -\if ENABLE_EXAMPLES -Here is a \ref py_mcfield_writefile_severaltimesteps_basic "Python example". -\endif - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/medloader/intro-medloader.dox b/medtool/doc/user/doxygen/doxfiles/reference/medloader/intro-medloader.dox deleted file mode 100644 index e7aed8163..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/medloader/intro-medloader.dox +++ /dev/null @@ -1,184 +0,0 @@ -/*! -\page intro-medloader Overview - -[TOC] - -\section MEDLoaderIntro Introduction - -\ref medloader "MEDLoader" is a package in charge of loading from a file or write to a file -in MED format a \ref medcoupling "MEDCoupling data structure". The fact that these -functionalities are not merged in the \ref library "MEDCoupling library" is explained by a -willingness of reducing as much as possible the dependencies of this library. - -As a MED file can combine several \ref medcoupling "MEDCoupling" aspects in one (for example meshes in -MED file on more than one dimensions with families and groups) the API -of \ref medloader "MEDLoader" is much more rich than simply read and write. - -\ref meshes "MEDCoupling mesh" is \b not as rich as a MED file mesh, and a \ref MEDCouplingFieldsPage "MEDCoupling field" is \b not as rich as a MED file field. -But it is possible to emulate with a very good fidelity a MED file mesh and a MED file field with a collection of MEDCoupling instances for each. - -\section MEDLoader2Approaches Two approaches - -\ref medloader "MEDLoader" module offers two different approaches to perform Read/Write from/to MED file. - -- \ref MEDLoaderBasicApproach "basic API approach" -- \ref MEDLoaderAdvApproach "advanced API approach" - -Whatever the approach(es) you choose, it is advisable to know main concepts of MED files \ref MEDLoaderMainC "that are quickly reminded here." - -\subsection MEDLoaderBasicApproach Basic API approach - -\ref MEDLoaderBasicAPIPage "A specific page dedicated to the basic API is available here". - -This approach is less close to MED file concepts, but closer to \ref medcoupling "MEDCoupling concepts". - -So, basic API is simpler, as shown by method MEDLoader::WriteUMesh that needs no special knowledge about MED file concepts to interact with MED files. - -This API is in the form of a list of public static methods in a class ParaMEDMEM::MEDLoader. - -This simplicity has a cost, the I/O are not (cannot be) optimized. - -As MED file concepts are more complex than MEDCoupling concepts, this approach is not the most relevant for specific MED file objects read/write. - -- Manipulation of multi level MED file mesh is not easy with basic approach - -- Manipulation of partial fields is not easy with basic approach - -\subsection MEDLoaderAdvApproach Advanced API approach - -\ref MEDLoaderAdvancedAPIPage "A specific page dedicated to the advanced API is available here". - -This approach is the closest to MED file. By using this advanced API approach the user will manipulate classes that represent MED file concepts. - -It implies that the user should be informed about the \ref MEDLoaderMainC "MED file concepts", that do not exist in \ref medcoupling "MEDCoupling". For example : - -- group/family in meshes -- profiles in fields - -This is typically the case for a user that wants to precisely set/get mesh/group/family groups set on different level. - -*This is why a set of classes corresponding to memory representation of MED file concepts is proposed by advanced API approach.* - -*So All information contained in file is represented by advanced API class instances.* - -The level of coherency check is variable across methods, to let to the user the maximal capacity of modification of its MED file data in memory. - -This API is particularly recommended : - -1. For users that want to repair a MED file (invalid family ids, invalid mesh dimension, mismatch of family ids, numbering cells/nodes array modification) -2. For users that want to operate directly on complex MED file objects (split of MED files for example, duplication of nodes). - - -\subsection MEDLoaderCohabitationApproach Cohabitation of the two approaches - -The two approaches are \b NOT opposed, they are compatible each other so it is possible to mix them. - -Typically it is possible to read rich information of a complex MED file using advanced API in read mode, postprocess this input then get a simpler MED file model, and write it to a simple output MED file using basic API. - -\section MEDLoaderMainC Main concepts of MED files - -Here we will describe some of the basic concepts of MED files in order to -use the best methods proposed by \ref medloader "MEDLoader API". - -\subsection BasicMEDLoaderAPIGen Basics in MED files - -First of all **MEDLoader will not read MED files whose version is strictly lower than 2.2.** - -For new comers in MED file world some of basics principles are recalled in the following graphic : - -\image html MEDFileConcepts.png "Resumed MED file concepts" - -Inside the parenthesis, there is multiplicity : - -- + stands for [1,inf) -- * stands for [0,inf) -- ? stands for 0 or 1 - -Each box is **independent in MED file format during read/write session.** - -**Boxes instances are linked each other only by red arrows using string as discriminating key.** It implies that empty names in basic concepts objects of MED file are forbidden. - -There can be as many instance of boxes as wanted in a MED file. - -**As it can be seen in MED file world, fields and meshes are sorted by geometric type**. - -This specificity leads to a constraint during writing phase because some mesh operations may significantly modify the organization of geometric types during mesh/field operations. -\n Here are some of operations that can alter the geometric type order of cells: - -- aggregation of meshes -- aggregation of fields -- extraction of a part of meshes -- extraction of a part of fields -- partial polyhedrization of meshes -- unpolyhedronization of meshes - -\section MEDLoaderCommonVoc Vocabulary used in MEDLoader - -\subsection MEDLoaderCommonVocRelMeshDimMesh Relative mesh dimension in meshes - -As it has been seen \ref BasicMEDLoaderAPIGen "above", all big arrays in fields and meshes (except coordinates) are sorted by geometric type, without any awareness of the dimension. - -For example an unstructured mesh in MED file world can lie simultaneously on MED_TRI3, MED_POINT1, MED_POLYHED, MED_TETRA4..., \ref MEDCouplingMeshes "which is impossible in MEDCoupling" for manipulation reasons. - -To connect the MED file world to the MEDLoader/MEDCoupling world the notion of **relative mesh dimension** has been introduced in \ref medloader "MEDLoader". - -This concept of **relative mesh dimension** is used frequently in the \ref medloader "MEDLoader APIs" (\ref MEDLoaderBasicAPIPage "basic" and \ref MEDLoaderAdvancedAPIPage "advanced"). - -To explain the semantic of **relative mesh dimension** let's take the example of a mesh called \a myMesh in a MED file, containing MED_TRI3, MED_POINT1, MED_POLYHED, MED_TETRA4. - -For each geometric type on which \a myMesh is defined the mesh dimensions are : - -- MED_TRI3 -> mesh dimension=2 -- MED_POINT1 -> mesh dimension=0 -- MED_POLYHED -> mesh dimension=3 -- MED_TETRA4 -> mesh dimension=3 - -The mesh dimension of \a myMesh is equal to 3 ( \c max(2,0,3,3) ). The **relative mesh dimension** is equal to the difference between mesh dimension of geometric type and the mesh dimension -of the whole MED file dimension. It leads to the following **relative mesh dimension** : - -- MED_TRI3 -> **relative mesh dimension** = -1 -- MED_POINT1 -> **relative mesh dimension** = -3 -- MED_POLYHED -> **relative mesh dimension** = 0 -- MED_TETRA4 -> **relative mesh dimension** = 0 - -In \ref medloader "MEDLoader" all geometric information are then grouped relative dimension per relative dimension. It leads to the following geometric sorting of -MED file data structure of \a myMesh : - -- Level 0 - - MED_TETRA4 - - MED_POLYHED -- Level -1 - - MED_TRI3 -- Level -2 - - nothing -> level **not** available for \a myMesh -- Level -3 - - MED_POINT1 - -The mesh dimension of \a myMesh is 3. The relative mesh dimensions available are 0, -1 and -3. - -\subsection MEDLoaderCommonVocRelMeshDimField Relative mesh dimension in fields - -As it has been seen previously in \ref MEDLoaderCommonVocRelMeshDimMesh "for meshes", the values of fields are sorted by levels too. - -The principle is the same than those explained for meshes. The only difference is in the fact that it is possible for fields on cell and fields on Gauss points that mesh dimension of underlying mesh of a field is not always (but very often) equal to the dimension of geometric types on which this field is defined. - -So it is advised, to compare the non empty level of a field **and** of its underlying mesh before trying to request heavy data from a MED file. - -\subsection MEDLoaderCommonVocIterationOrder Iteration and order in MED file - -As seen \ref BasicMEDLoaderAPIGen "above", fields in MED file can be defined on different time steps. - -But there is a **major difference** with \ref medcoupling "MEDCoupling" concept in time steps. \ref medcoupling "MEDCoupling" focuses on the float value of time for interpolation reason. - -\ref medloader MEDLoader and MED file focus on pair of integers to precise a specific time steps. - -This difference of point of view can be seen in the API where the order of returned parameters in python differs from MEDCouplingFieldDouble::getTime to MEDFileField1TS::getTime. - -In MED file and so in \ref medloader "MEDLoader" the time steps are identified by a pair of integers called : - -- iteration -- order - -Order refers to sub iteration id, that is by default set to -1 in case of non use. A physical time with float type is attached to this pair of integer. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/medloader/medloader.dox b/medtool/doc/user/doxygen/doxfiles/reference/medloader/medloader.dox deleted file mode 100644 index 641af911a..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/medloader/medloader.dox +++ /dev/null @@ -1,16 +0,0 @@ -/*! -\page medloader MEDLoader: Writing, reading MED files - -MEDLoader is built on top of the **MEDCoupling** library and uses its core structure -(\ref arrays DataArray, \ref meshes Meshes, \ref fields Fields). -It is an extension dedicated to the writing and reading of mesh and fields to MED files (files with a .med -extension). - -- \subpage intro-medloader -- \subpage MEDLoaderBasicAPIPage -- \subpage MEDLoaderAdvancedAPIPage - -More information on the MED file format itself can be found at: -- \ref med-file - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingCMesh.dox b/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingCMesh.dox deleted file mode 100644 index 6f75f2cd2..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingCMesh.dox +++ /dev/null @@ -1,23 +0,0 @@ - -/*! - \page MEDCouplingCMeshPage Cartesian mesh - -A cartesian mesh is a mesh that represents structured mesh whose nodes are arranged along axes of trihedron. - -To instantiate an object of this type, only n arrays are needed. - -In this type of mesh space dimension \b and mesh dimension are equals and the value is n ( with n in [1,2,3] ). - -The n arrays will have only one component and the values contained in these arrays will be ascendently sorted. - -The class that incarnates the described concept is : ParaMEDMEM::MEDCouplingCMesh. - -\section MEDCouplingCMeshStdBuild Standard building of a cartesian mesh from scratch - -Let's present an example of a 2D cartesian mesh. - -\ref medcouplingcppexamplesCmeshStdBuild1 "Here the C++ implementation." - -\ref medcouplingpyexamplesCmeshStdBuild1 "Here the Python implementation." - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingExtruded.dox b/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingExtruded.dox deleted file mode 100644 index f684fb6f1..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingExtruded.dox +++ /dev/null @@ -1,17 +0,0 @@ - -/*! - \page MEDCouplingExtrudedPage 3D extruded mesh - -An extruded mesh is sometimes also called a 2.5D mesh. - -It is a convolution of a 2D unstructured mesh with a 1D unstructured mesh. - -The problem is that this type of mesh is not managed by any file format that's why to build an instance of this mesh you need a 3D unstructured mesh and a 2D -unstructured mesh lying on the same coordinates. - -The advantage of this structure is that the interpolation time is highly improved. - -This class is also useful for users that want to map the 3D unstructured mesh cell ids level by level along an axis. - -The class that incarnates this concept in MEDCoupling is : \ref ParaMEDMEM::MEDCouplingExtrudedMesh. -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingPointSet.dox b/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingPointSet.dox deleted file mode 100644 index fd679e684..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingPointSet.dox +++ /dev/null @@ -1,21 +0,0 @@ - -/*! - \page MEDCouplingPointSetPage Point set mesh - -This is a \b non \b instantiable class that implements many algorithm working only on a set of points without any connectivity aspect. -The presence of this class is only for factorization reasons. - -The class that incarnates this concept in \ref medcoupling "MEDCoupling" is : \ref ParaMEDMEM::MEDCouplingPointSet. -Instantiable class ParaMEDMEM::MEDCouplingUMesh inherits from ParaMEDMEM::MEDCouplingPointSet. - -Some of most important implemented methods by \ref ParaMEDMEM::MEDCouplingPointSet "MEDCouplingPointSet" class are : - -- \ref ParaMEDMEM::MEDCouplingPointSet::getSpaceDimension "getSpaceDimension" -- \ref ParaMEDMEM::MEDCouplingPointSet::getNumberOfNodes "getNumberOfNodes" -- \ref ParaMEDMEM::MEDCouplingPointSet::rotate "rotate" -- \ref ParaMEDMEM::MEDCouplingPointSet::translate "translate" -- \ref ParaMEDMEM::MEDCouplingPointSet::scale "scale" -- \ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes "findCommonNodes" -- \ref ParaMEDMEM::MEDCouplingPointSet::renumberNodes "renumberNodes" -- \ref ParaMEDMEM::MEDCouplingPointSet::getBoundingBox "getBoundingBox" -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingUMesh.dox b/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingUMesh.dox deleted file mode 100644 index 0aa7f23b6..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/meshes/MEDCouplingUMesh.dox +++ /dev/null @@ -1,66 +0,0 @@ - -/*! - \page MEDCouplingUMeshPage Unstructured mesh - -An unstructured mesh in \ref medcoupling MEDCoupling is defined by : - - - a point cloud where the explicit coordinates of each point must be specified (inherited from \ref MEDCouplingPointSetPage "MEDCouplingPointSet class"). - - nodal connectivity that specifies for each cell, the points in the previous point cloud that constitutes the cell. - -As unstructured mesh is dynamically defined enough, this class is also used by MEDCoupling to instantiate degenerated meshes as : - -- point cloud only meshes. This type of mesh will have mesh dimension 0. -- abstract meshes containing only one cell that covers a potentially - infinite space. This abstract mesh is used as support of fields - containing only one integrated value. This is typically used to - represent fields used by system code. This type of mesh will have - mesh dimension equal to -1. - -The norm used for cells connectivity of different types, is the same as specified in MED file except -that connectivities are represented in \b C \b format and \b not \b in \b FORTRAN \b format ! - -The class that incarnates the described concept is : ParaMEDMEM::MEDCouplingUMesh. -\n This class inherits from ParaMEDMEM::MEDCouplingPointSet abstract class. -\n So \ref MEDCouplingUMeshPage "MEDCouplingUMesh" inherits from all \ref MEDCouplingPointSetPage "point set features". - -\section MEDCouplingUMeshStdBuild Standard building of an unstructured mesh from scratch - -The described method here is called standard, because no special knowledge of underneath nodal connectivity is needed here. -This method of building unstructured mesh is easiest but not the most CPU/memory efficient one. - -All of examples given here make the assumption that the \ref ParaMEDMEM "ParaMEDMEM namespace" is visible ( by calling for example \c using \c namespace \c ParaMEDMEM; ). - -Here we will create a mesh with spacedim==3 and meshdim==2. \b mesh contains 5 cells (with geometric type INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4) -and 9 nodes. - -You can notice that it is possible to mix cell types as long as the dimension of the cell is exactly -equal to meshDim to respect \ref MEDCouplingMeshes "this rule". - -\ref medcouplingcppexamplesUmeshStdBuild1 "Here is the C++ implementation." - -\ref medcouplingpyexamplesUmeshStdBuild1 "Here is the Python implementation." - -\section MEDCouplingUMeshNodalConnectivity How MEDCouplingUMesh stores its nodal connectivity - -\ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh class" stores its nodal connectivity into 2 arrays. - -- The first one, the biggest is ParaMEDMEM::MEDCouplingUMesh::_nodal_connectivity. -- The second one, the less big is ParaMEDMEM::MEDCouplingUMesh::_nodal_connectivity_index. - -\image html MEDCouplingUMeshConn.png "Nodal connectivity storage into MEDCouplingUMesh class" -\image latex MEDCouplingUMeshConn.eps "Nodal connectivity storage into MEDCouplingUMesh class" - -\note The last value of the nodal connectivity index points to an invalid memory place. It is not an error, simply as for standard C++, all ranges -are given in format [\b begin,\b end) where \b begin is included and \b end excluded. - -\section MEDCouplingUMeshAdvBuild Advanced building of an unstructured mesh from scratch - -Here we are going to build the mesh in a more advanced manner. This method expects that the user knows the storage format underlying ParaMEDMEM::MEDCouplingUMesh. - -The same mesh than \ref MEDCouplingUMeshStdBuild "in the standard section above" is going to be implemented using advanced method. - -\ref medcouplingcppexamplesUmeshAdvBuild1 "Here the C++ implementation." - -\ref medcouplingpyexamplesUmeshAdvBuild1 "Here the Python implementation." - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/meshes/meshes.dox b/medtool/doc/user/doxygen/doxfiles/reference/meshes/meshes.dox deleted file mode 100644 index 76e952402..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/meshes/meshes.dox +++ /dev/null @@ -1,47 +0,0 @@ - -/*! - \page meshes Meshes - -

Overview

- -Several types of meshes are available in MEDCoupling: - -- \subpage MEDCouplingPointSetPage "Point set mesh" (abstract, can not be instanciated) -- \subpage MEDCouplingUMeshPage "Unstructured meshes" -- \subpage MEDCouplingCMeshPage "Cartesian meshes" -- \subpage MEDCouplingExtrudedPage "3D Extruded meshes" - -\anchor MEDCouplingMeshes -

Common concept shared by all type of Meshes in MEDCoupling

- -A mesh has the following properties : -- a name (a string) -- **a dimension (called mesh dimension) and only one** (it implies that \b all cells constituting -mesh have the same dimension, e.g. no mix between a volumic cube and a flat triangle in the same mesh). This -point matters as it differs from what the MED file format authorizes. -- a space dimension (the space where the coordinates of the points are defined) -- a set of nodes -- a set of cells (whose vertices are in the node set above) - -In MEDCoupling library there is no explicit notion of faces nor edges. All cells, be it in 3D, 2D or 1D is -described by a set of point, or by a set of coordinates. - -As said above, a mesh has only one dimension, which is often called the "mesh dimension". This notion is different -from the "space dimension", corresponding to the dimension of the space where the nodes are defined. - -For example a mesh with a mesh dimension equal to 1 can have \b cells of type -NORM_SEG2 (simple segments). This mesh can however have a space dimension of 3, meaning that we -describe a 3D polygonal line. -Another example: a mesh with a mesh dimension equal -to 2, can have \b cells of type NORM_TRI3 (triangles) and NORM_POLYGON (arbitrary 2D polygons) for example. -It can still have a space dimension of 3, meaning that we describe a planar surface embedded in a 3D space. - -The (abstract) class that covers the concept described above is \ref ParaMEDMEM::MEDCouplingMesh. - -

Available (non abstract) mesh types in MEDCoupling

- -- \ref MEDCouplingUMeshPage -- \ref MEDCouplingCMeshPage -- \ref MEDCouplingExtrudedPage - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/misc/MEDCouplingFieldTemplates.dox b/medtool/doc/user/doxygen/doxfiles/reference/misc/MEDCouplingFieldTemplates.dox deleted file mode 100644 index 52092d93a..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/misc/MEDCouplingFieldTemplates.dox +++ /dev/null @@ -1,18 +0,0 @@ - -/*! - \page MEDCouplingFieldTemplatesPage Field templates in MEDCoupling - -This concept appears in ICOCO API. -A field template is the adequate data structure to perform costly interpolation matrix computation as \ref remapper "Remapper class" does. -A field template can be seen as field without its double values. The double values are only used for light matrix vector multiplication. - -Concretely a field template is a pair containing : - -- a \ref meshes "mesh" -- a spatial discretization (on cells, on nodes, on Gauss points (including localizations, reference elements), ) - -TODO enhance here - -*/ - - LocalWords: discretization diff --git a/medtool/doc/user/doxygen/doxfiles/reference/misc/icoco.dox b/medtool/doc/user/doxygen/doxfiles/reference/misc/icoco.dox deleted file mode 100644 index b48ec73a9..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/misc/icoco.dox +++ /dev/null @@ -1,11 +0,0 @@ -/*! - -\page icoco The ICoCo API - -ICoCo stands for Interface for COde COupling. - -It is a pure abstract API defining a standard way for two physical codes to exchange information between them. - -TODO: complete this section. - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/misc/misc.dox b/medtool/doc/user/doxygen/doxfiles/reference/misc/misc.dox deleted file mode 100644 index 111192a7a..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/misc/misc.dox +++ /dev/null @@ -1,12 +0,0 @@ -/*! -\page misc Miscellaneous - Specialized interfaces and tools - -This page references miscellaneous tools available in MEDCoupling that do not fit -anywhere else in the documentation. - -- \subpage tools -- \subpage icoco -- \subpage MEDCouplingFieldTemplatesPage - - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/reference/misc/tools.dox b/medtool/doc/user/doxygen/doxfiles/reference/misc/tools.dox deleted file mode 100644 index 8bcba7cd2..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/misc/tools.dox +++ /dev/null @@ -1,100 +0,0 @@ -/*! -\page tools Tools on MED file - -\section Introduction - -There are few executables based on the MEDCoupling and MEDLoader libraries that - help the user to perform -common operations on MED files : -- conversion to other formats, -- splitting of a %MED file to a parallel %MED file distributed over a -number of subdomains. - -\section medpartitioner MEDPartitioner tool - -The purpose of MEDPARTITIONER is to split MED files into -a series of other MED files forming a partition of the original MED -files. It can either work with serial meshes (1 to n) or distributed -meshes (p to n). For serial meshes, it accepts MED files from the 2.1 -version onwards. For distributed MED files, it accepts MED files from -the 2.3 version onwards. - -There exists a parallel version of MEDPARTITIONER, which accepts -distributed MED files only. In contrast to the ordinary MEDPARTITIONER -the parallel one distributes several usual MED files composing the -whole model among available processors. After the -partitioning, each processor writes only it's own part of the -distributed MED file. The parallel MEDPARTITIONER processes meshes only, -not fields. - -It can be used either as an executable, \a medpartitioner (or \a -medpartitioner_para) or as a library. The partitioning is made thanks to -one of the following library : -- METIS (http://glaros.dtc.umn.edu/gkhome/views/metis/index.html) -- SCOTCH (http://www.labri.fr/perso/pelegrin/scotch/scotch_en.html) - -The arguments to the medpartitioner tool can be retrieved by calling : -\code -medpartitioner --help -\endcode -or -\code -medpartitioner_para --help -\endcode - -For Salome V7.2.0, one gets the following arguments (some of them are -unavailable in parallel version): - -\code -Available options: - --help : produces this help message - --mesh-only : do not create the fields contained in the original file(s) - --distributed : specifies that the input file is distributed - --input-file= : name of the input MED file - --output-file= : name of the resulting file - --meshname= : name of the input mesh (not used with --distributed option) - --ndomains= : number of subdomains in the output file, default is 1 - --plain-master : creates a plain masterfile instead of an XML file - --creates-boundary-faces: creates the necessary faces so that faces joints are created in the output files - --family-splitting : preserves the family names instead of focusing on the groups -\endcode - -\section renumber RENUMBER tool - -The purpose of RENUMBER is to renumber the cell of a mesh in order to -make numerical computation easier. This tool works with meshes -which contain only one cell type and can renumber it according to two -different methods: -- Reverse Cuthill McKee (with the Boost Graph Library http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/table_of_contents.html) -- Nested Dissection (with the METIS library -http://glaros.dtc.umn.edu/gkhome/views/metis/index.html) - -It can be used in this way : -\code -renumber MEDFile_in MeshName Method[BOOST/METIS] MEDFile_out -\endcode - -\section sauv2med sauv2med tool - -The sauv2med tool enable conversion from a Cast3m \a sauv file into a -MED file. It is a python script that encapsulates the read/write -drivers provided by the MEDLoader library. - -Calling -\code -sauv2med myfile.sauv -\endcode -generates a \a med file named \a myfile.sauv.med - -\section med2sauv med2sauv tool - -med2sauv operator is the operator that is inverse of sauv2med. Its -behaviour is symmetrical. - -Calling -\code -med2sauv myfile.med -\endcode -generates a \a sauv file named \a myfile.med.sauv - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/reference/reference.dox b/medtool/doc/user/doxygen/doxfiles/reference/reference.dox deleted file mode 100644 index d6419583d..000000000 --- a/medtool/doc/user/doxygen/doxfiles/reference/reference.dox +++ /dev/null @@ -1,23 +0,0 @@ -/*! -\page reference Reference manual - -The following pages constitutes the reference manual of the \ref library "MEDCoupling and MEDLoader libraries". -If you are looking for a more informal overview, you should go to the \ref start "getting started" section. - -The basic \ref medcoupling "core structures" are first covered (this is what constitutes the MEDCoupling library), -and the manual then moves onto more advanced concepts and methods. - -You can also take a look at the numerous \ref examples "code examples" provided with this documentation. - -- \subpage medcoupling - - \ref arrays - - \ref numbering - - \ref meshes - - \ref fields -- \subpage medloader -- \subpage interpolation -- \subpage cpp -- \subpage distrib -- \subpage misc - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/start/functionalities.dox b/medtool/doc/user/doxygen/doxfiles/start/functionalities.dox deleted file mode 100644 index 10869924c..000000000 --- a/medtool/doc/user/doxygen/doxfiles/start/functionalities.dox +++ /dev/null @@ -1,120 +0,0 @@ -/*! -\page functionalities Available functionalities - -This page tries to list most of the available functionalities of the %MEDCoupling library. -It is by no mean exhaustive, but gives an overview of the capabilities of the core library. - -\section directOperations Direct operations on fields -\subsection directOperations_creation Field creation -- From scratch: \b New - -- Copy: \b clone*, \b deepCpy - -\subsection directOperations_modification Partial modifications -- Creation: \b New, \b setMesh, \b setArray* \n - \if ENABLE_EXAMPLES - Example 1: \ref medcouplingpyexamplesFieldDoubleBuild1 \n - Example 2: \ref medcouplingpyexamplesFieldDoubleBuild2 \n - Example 3: \ref medcouplingpyexamplesFieldDoubleBuild3 \n - Example 4: \ref medcouplingpyexamplesFieldDoubleBuild4 \n - \endif -- Copy - - \b buildNewTimeReprFromThis - \if ENABLE_EXAMPLES - . - Example: \ref py_mcfielddouble_buildNewTimeReprFromThis - \endif -- Subparts - - \b buildSubPart* - \if ENABLE_EXAMPLES - . - Example: \ref py_mcfielddouble_subpart1 - \endif - - \b keepSelectedComponents, \b setSelectedComponents - -And also: - -- Description: \b setName - -- I/O: cf. MEDLoader - - -\section arithmeticOperations Local arithmetic -\subsection arithmeticOperations_scalar Operations on scalars -- Affectation - - From a constant: \b = - - From an expression: \b applyFunc* \b applyLin \b fillFromAnalytic* \n - \if ENABLE_EXAMPLES - Example 1: \ref py_mcfielddouble_applyFunc_same_nb_comp \n - Example 2: \ref py_mcfielddouble_applyFunc3 \n - Example 3: \ref py_mcfielddouble_applyFunc2 \n - Example 4: \ref py_mcfielddouble_applyFunc \n - Example 5: \ref py_mcmesh_fillFromAnalytic3 \n - Example 6: \ref py_mcmesh_fillFromAnalytic2 \n - Example 7: \ref py_mcmesh_fillFromAnalytic \n - Example 8: \ref cpp_mcfielddouble_fillFromAnalytic_c_func \n - Example 9: \ref cpp_mcfielddouble_applyFunc_c_func - \endif -- Addition - - \b + \b += \b AddFields - \if ENABLE_EXAMPLES - . - Example: \ref medcouplingpyexamplesFieldDoubleBuild5 - \endif -- Subtraction - - \b \- \b \-= \b SubstractFields - - \b substractInPlaceDM - \if ENABLE_EXAMPLES - . - Example: \ref py_mcfielddouble_substractInPlaceDM - \endif -- Multiplication - - \b * \b *= \b MultiplyFields - \if ENABLE_EXAMPLES - . - Example: \ref medcouplingpyexamplesFieldDoubleBuild5 - \endif -- Division: - - \b / \b /= \b DivideFields - \if ENABLE_EXAMPLES - . - Example: \ref medcouplingpyexamplesFieldDoubleBuild5 - \endif -- Power: \b ^ \b ^= \b PowFields - -\subsection arithmeticOperations_vector Operations on vectors or second order tensors -- Contracted product: \b doublyContractedProduct -- Determinant: \b determinant -- Eigenvalues and eigenvectors: \b eigenValues, \b eigenVectors -- Tensor inversion: \b inverse -- Trace: \b trace -- Deviator: \b deviator -- Norms: \b norm* - - -\section interpolationOperations Interpolation -A full section is dedicated to interpolation, as this is far from being a trivial matter. See: \ref interpolation - -\section globalOperations Global operations -- Spatial extrema: \b MaxFields, \b MinFields \n - \if ENABLE_EXAMPLES - Example: \ref py_mcfielddouble_MaxFields - \endif -- Spatial mean: \b getAverageValue - -- Temporal extrema - - \b getMaxValue* - - \b getMinValue* - - -\section otherOperations Others -- Renumbering a mesh: \b renumber* \n - \if ENABLE_EXAMPLES - Example 1: \ref py_mcfielddouble_renumberNodes \n - Example 2: \ref py_mcfielddouble_renumberCells - \endif -- Merge non overlapping fields: \b MergeFields \n - \if ENABLE_EXAMPLES - Example: \ref py_mcfielddouble_MergeFields - \endif -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/start/intro-start.dox b/medtool/doc/user/doxygen/doxfiles/start/intro-start.dox deleted file mode 100644 index 51c6ca63f..000000000 --- a/medtool/doc/user/doxygen/doxfiles/start/intro-start.dox +++ /dev/null @@ -1,42 +0,0 @@ -/*! - -\page intro-start What can I do with MED? - -Simulation studies require the manipulation of \ref meshes "meshes" and \ref fields "fields" for data -pre-processing, in calculation schemes (including chaining and coupling -of codes), or even for results post-processing. - -Corresponding computer codes can be viewed as software components accessing -input \ref meshes "meshes" and \ref fields "fields" (with specific constraints) along with parameters -(datasets), and producing output \ref meshes "meshes" and \ref fields "fields". Each code presents by -construction the specificities of its discipline. - -The \ref library "MED module" aims at pooling operations on those items, facilitating -their use by various codes involved in a simulation process. This includes -making codes communicate while preserving as much as possible the integrity of -their content. - -To fulfill its objective, the \ref library "MED module" includes: -- Handling \ref meshes "meshes" and \ref fields "fields" to satisfy code input requirements. -- Extraction of field information to post-process computation results of -a code. -- \ref interpolation "Projections" and serialization to \ref para-dec "exchange meshes and fields" between codes. - -In addition, the \ref library "MED module" offers several interfacing levels; users can thus -benefit from an interaction level adapted to their codes. - -The main services offered by \ref library "MEDCoupling" are: -- Manipulation of \ref fields "fields" and their support \ref meshes "mesh", serialized with the -\ref medloader "MED format". -- Operations on scalars, vectors, and second order tensors. -- 1D/2D/3D \ref interpolation "interpolation" on nodes, cells, Gauss points and nodes by element. - -MEDCoupling thus considers: -- the \ref MEDCouplingMeshes "data dimension". -- the \ref NatureOfField "physical nature" of the information stored in a field, as well as conservation laws. -- the field profiles and the mesh connectivity. - -\image html projectionHQ_600.png -
- -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/start/library.dox b/medtool/doc/user/doxygen/doxfiles/start/library.dox deleted file mode 100644 index 921338504..000000000 --- a/medtool/doc/user/doxygen/doxfiles/start/library.dox +++ /dev/null @@ -1,50 +0,0 @@ -/*! -\page library The MED constellation: MEDCoupling, MEDLoader, MED file, etc ... - -\section lib-termino Who's who? -The library and the module have evolved over the years, raising -some confusion between all the names used to label the various pieces. This page tries to clarify -this situation. - -"MED" can (unfortunately) refer to: -- \ref med-file "MED file format": the file format used to save a mesh (".med" extension) -- \ref med-file "MED-file library": the C++ library developped by EdF R&D (and provided - with SALOME) to read/write MED file (warning: for advanced users only!) -- \ref medcoupling "MEDCoupling": the (relatively) high level API to deal with mesh and fields in memory -- \ref medloader MEDLoader: part of the library dedicated to file I/O = a more user-friendly API than the MED-file library API -- \ref remapper "Remapper": part of the library dedicated to -\ref interpolation "interpolation/projection methods" -- \ref gui "SALOME’s MED module" (GUI point of view): a graphical client in the SALOME main application, providing a graphical interaction with part of the library -- and finally \ref parallel "ParaMEDMEM", for the projection operations and field transfers in parallel - -The most common confusion is between the MED library (what you are reading at present) and -the MED-file library ("MED fichier"). -The MED-file library is part of the prerequisites of the MED libary, and its only purpose is to read and write -MED files. This is a low level API written in C, and giving a fine-grain access to the structure -of the MED files (.med). The architecture diagramm below details those points further. - -Another source of common confusion is that all the standard (sequential) MEDCoupling/MEDLoader API lies in -the \b %ParaMEDMEM namespace. -This is quite unfortunate but due to historical reasons. The true parallel functionalities -of the MED library are detailed here: \ref parallel, but are still often called -the %ParaMEDMEM part of the library. - -\section lib-archi Architecture -The figure below represents the layer structure of the packages of the -library. -- each element depends on the blocks it covers (fully or partially). -- White blocks represent system or external dependencies. -- the MEDCalc block, with gray background color, is the \ref gui "Graphical User Interface". -- red-colored text identifies code with Swig interfaces (API available in \ref python-api "Python") -- blue-colored text identifies code with both \ref python-api "Swig interfaces" and \ref corba-distrib "CORBA layer". - -\image html MedCoupling_Architecture.png - -The fundamental set (blue background) consists in three atomic libraries: - -- \ref medcoupling "MEDCoupling" that describes data structures used for cross process exchange of \ref meshes "meshes" and \ref fields "fields". -- \ref medloader "MEDLoader" and ParaMEDLoader that provides I/O functions to the MED file format with sequential and parallel processing, respectively. Those are built on top of the MED-file library. -- \ref intro-interp "interpolation tools" that provides mathematical structures and algorithms for interpolation and - localization. It is implemented in three blocks: \ref INTERP_KERNEL "InterpKernel", \ref ParaMEDMEM::MEDCouplingRemapper "Remapper" and \ref parallel "ParaMEDMEM" (Remapper with parallel processing). - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/start/python-api.dox b/medtool/doc/user/doxygen/doxfiles/start/python-api.dox deleted file mode 100644 index 5af75272d..000000000 --- a/medtool/doc/user/doxygen/doxfiles/start/python-api.dox +++ /dev/null @@ -1,35 +0,0 @@ -/*! - -\page python-api A word on the Python API - -The Python API is highly similar to the C++ one. The main modules to import are: -- %MEDCoupling -- %MEDLoader (with mainly the static \ref MEDLoader "MEDLoader class" within this module) - -The following intuitive rules have been used to map the C++ objects to the Python ones: -- std::vector become standard Python lists, see for example \ref py_mcdataarrayint_setpartofvalues where the function -ParaMEDMEM::DataArray::setInfoOnComponents() is used. -- the return values of C++ functions (usually passed as last arguments in the C++ prototype) are -returned directly as a tuple, see for example the Python usage of ParaMEDMEM::MEDCouplingUMesh::getReverseNodalConnectivity() in \ref cpp_mcumesh_getReverseNodalConnectivity. The -initial prototype where the return values are passed as argument can however still be used, provided you instantiate -the returned objects first. -- the indexing mechanism is greatly simplified in Python, and offers similar functionalities to what NumPy -provides thanks to the ':' (column) operator. Once can for example refer to part of an array with something like - -\code{.py} -import MEDCoupling as mc -d = mc.DataArrayInt([(1,2), (3,4), (5,6)], 3, 2) # an array of 3 tuples with 2 components -print d[:,1] # show only second component of the array: 2,4,6 -\endcode - - -Finally for the most common objects (DataArray, MEDCouplingUMesh, etc ...) one can direclty access the -Doxygen documentation in the interactive Python interpreter using the built-in help function from Python: - -\code{.py} -import MEDCoupling as mc -help(mc.DataArrayDouble.getNumberOfTuples) -\endcode - - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxfiles/start/start.dox b/medtool/doc/user/doxygen/doxfiles/start/start.dox deleted file mode 100644 index 9780907b8..000000000 --- a/medtool/doc/user/doxygen/doxfiles/start/start.dox +++ /dev/null @@ -1,18 +0,0 @@ -/*! -\page start Getting started - -If you are completly new to MED, this page will help you grasp the main concepts -used overall in the \ref library "MED world", and have an idea of what you can achieve with MED. - -The tutorial is also a good way to start. - -Once you are familiar with those concepts, more detailed explanations are available -in the \ref reference "reference manual". - -- \subpage intro-start -- \subpage terminology -- \subpage library -- \subpage functionalities -- \subpage python-api - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/start/terminology.dox b/medtool/doc/user/doxygen/doxfiles/start/terminology.dox deleted file mode 100644 index 8d05a9f23..000000000 --- a/medtool/doc/user/doxygen/doxfiles/start/terminology.dox +++ /dev/null @@ -1,57 +0,0 @@ -/*! -\page terminology Terminology - Meshes, fields, interpolation - -\section start-meshfield Meshes and fields - -This section covers at a very high level the concepts used overall in the MED world. -More precise definitions can be found in the \ref glossary, or in the dedicated pages for the -\ref meshes "meshes" and the \ref fields "fields". - -Many physical simulation codes (try to) solve a given set of equations on a given geometrical domain. -This domain can be anything from the representation of a building to the description of the -molecular network found in a small piece of concrete. - -The geometrical domain is provided to the machine as a CAO modelisation (what you can build with the -GEOM module of SALOME for example). - -\image html geom.png "Example geometry (CAO) of a cylinder" - -The numerical codes (e.g. FEM-based codes) -are usually unable to work directly with such a format, and a spatial discretization of the domain has -to be performed: the **meshing**. A **mesh** can hence roughly be seen as a discrete version of a continuous input geometry. -The module SMESH in SALOME is typically dedicated to performing this task. - -\image html fine_mesh.png "Example meshing of the above geometry" - -A mesh is made of **cells** (the elementary spatial unit), which are typically simple polygons or polyhedrons. - -On this support, the code can read/store values in form of a **field**. A **field** is hence an -array of data, where each cell (or node, or ... etc) has -one (or more) values associated to it. A code simulating the heat equation will for example produce a temperature -field assigning a single temperature value to each cell of the mesh. - -Taking the vocabulary of the finite-element world, a field with values stored at the cell level is often -called a **P0 field**, and a field where values are stored at node level a **P1 field**. - -More on this subject: -- \ref meshes -- \ref fields - -\section start-interp Interpolation - -When working with different codes, or when coupling codes, it is often the case that the initial problem -has been modelised in two different ways. For example a thermic code might use a mesh made of tetrahedron -and a CFD code might use a mesh made of hexaedrons. The interpolation mechanisms provided in the MED library -allow the user to easily \b transfer field data from one representation to the other. - -In all its generality it is a complex task, covering many different use cases (do the two meshes overlap? do -we want to conserve the total amount represented by the field?, etc...), justifying a dedicated section in -the documentation: \ref interpolation - -In this documentation you will sometime read the words "projection", or "transfer" or "interpolation" for this -process. - -More on this subject: -- \ref interpolation - -*/ diff --git a/medtool/doc/user/doxygen/doxfiles/tutorial.dox b/medtool/doc/user/doxygen/doxfiles/tutorial.dox deleted file mode 100644 index edf6943f9..000000000 --- a/medtool/doc/user/doxygen/doxfiles/tutorial.dox +++ /dev/null @@ -1,8 +0,0 @@ -/*! - -\page tutorial Tutorial - MEDCoupling/MEDLoader in Python - -The %MEDCoupling/%MEDLoader Python tutorial is accessible here: -- MEDCoupling tutorial - -*/ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxy2swig/MEDCoupling_doc.i.in b/medtool/doc/user/doxygen/doxy2swig/MEDCoupling_doc.i.in deleted file mode 100644 index 0ca88d7ee..000000000 --- a/medtool/doc/user/doxygen/doxy2swig/MEDCoupling_doc.i.in +++ /dev/null @@ -1 +0,0 @@ -@_swig_include_set@ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxy2swig/MEDLoader_doc.i.in b/medtool/doc/user/doxygen/doxy2swig/MEDLoader_doc.i.in deleted file mode 100644 index 0ca88d7ee..000000000 --- a/medtool/doc/user/doxygen/doxy2swig/MEDLoader_doc.i.in +++ /dev/null @@ -1 +0,0 @@ -@_swig_include_set@ \ No newline at end of file diff --git a/medtool/doc/user/doxygen/doxy2swig/doxy2swig.cmake b/medtool/doc/user/doxygen/doxy2swig/doxy2swig.cmake deleted file mode 100644 index ff7577c1c..000000000 --- a/medtool/doc/user/doxygen/doxy2swig/doxy2swig.cmake +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -## -## This module is dedicated to the generation of specific SWIG files (".i") containing -## the docstrings built from the C++ doxygen documentation. -## - -SET(_DOXY2SWIG ${PROJECT_SOURCE_DIR}/doc/user/doxygen/doxy2swig/doxy2swig.py) -SET(_SWIG_DOC_SUFFIX "doc_class_") - -# -# MEDCoupling classes to include -# -SET(_classes_MEDCoupling -# ParaMEDMEM_1_1MEDCouplingPointSet -# ParaMEDMEM_1_1MEDCouplingUMesh -# ParaMEDMEM_1_1MEDCouplingCMesh -# ParaMEDMEM_1_1MEDCouplingRemapper -# ParaMEDMEM_1_1DataArray -# ParaMEDMEM_1_1DataArrayInt - ParaMEDMEM_1_1DataArrayDouble - ) - -# -# MEDLoader classes to include -# -SET(_classes_MEDLoader -# MEDLoader -# ParaMEDMEM_1_1MEDFileMeshes -# ParaMEDMEM_1_1MEDFileMesh -# ParaMEDMEM_1_1MEDFileUMesh - ParaMEDMEM_1_1MEDFileCMesh - ) - -## -## Generates the ".i" files from a list of C++ classes. -## -## \param[in] target_doc main target for the stantard doxygen generation -## \param[in] target_swig dummy target encompassing the final build of all SWIG files -## \param[in] cls_list list of classes for which to generate SWIG files -## \param[in] swig_main_file main SWIG file including the other generated SWIG files -## \param[out] swig_files list of generated SWIG files -## -MACRO(MEDCOUPLING_MED_SWIG_DOCSTRING_GENERATE target_doc target_swig cls_list swig_main_file swig_files) - # List of generated SWIG files (.i) for doc purposes only: - SET(${swig_files}) - FOREACH(_cls IN LISTS ${cls_list}) - SET(_xml_file "${CMAKE_CURRENT_BINARY_DIR}/../doxygen/doc_ref_user/xml/class${_cls}.xml") - SET(_swig_file_base "${_SWIG_DOC_SUFFIX}${_cls}.i") - SET(_swig_file "${PROJECT_BINARY_DIR}/doc/${_swig_file_base}" ) - - # SWIG doc files will always be generated *after* Doxygen is run: - ### WARNING: ADD_CUSTOM_COMMAND(TARGET xxx POST_BUILD ...) command - ### must be in exactly the same subdir as the initial target construction command. - ### That's why this file is included with an INCLUDE() rather than using ADD_SUBDIRECTORY - # Note: we touch the main .i file to be sure to retrigger swig when the doc in a included - # class changes. - ADD_CUSTOM_COMMAND(OUTPUT ${_swig_file} - COMMAND ${PYTHON_EXECUTABLE} ${_DOXY2SWIG} "-n" ${_xml_file} ${_swig_file} - COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${swig_main_file} - DEPENDS ${_xml_file} - COMMENT "Generating docstring SWIG file (from Doxygen's XML): ${_swig_file_base}" - VERBATIM - ) - ADD_CUSTOM_TARGET(${_swig_file_base} DEPENDS ${_swig_file}) - # The doxy2swig script is executed once the doxygen documentation has been generated ... - ADD_DEPENDENCIES(${_swig_file_base} ${target_doc}) - # ... and the meta target 'swig_ready' (here ${target_swig}) is ready when all .i files - # have been generated: - ADD_DEPENDENCIES(${target_swig} ${_swig_file_base}) - - LIST(APPEND ${swig_files} ${_swig_file_base}) - ENDFOREACH() -ENDMACRO(MEDCOUPLING_MED_SWIG_DOCSTRING_GENERATE) - - -## -## Configures the MEDCoupling_doc.i or MEDLoader_doc.i file so that they include -## the list of SWIG files generated by the macro above. -## -## \param[in] target_doc main target for the stantard doxygen generation -## \param[in] target_swig dummy target encompassing the final build of all SWIG files -## \param[in] root_name either 'MEDCoupling' or 'MEDLoader' -## -MACRO(MEDCOUPLING_MED_SWIG_DOCSTRING_CONFIGURE target_doc target_swig root_name) - SET(_all_swig_docs) - SET(_swig_include_set) - SET(_in_file doxy2swig/${root_name}_doc.i.in) - SET(_out_file ${PROJECT_BINARY_DIR}/doc/${root_name}_doc.i) - MEDCOUPLING_MED_SWIG_DOCSTRING_GENERATE(${target_doc} ${target_swig} _classes_${root_name} ${_out_file} _all_swig_docs) - FOREACH(f IN LISTS _all_swig_docs) - SET(_swig_include_set "${_swig_include_set}\n%include \"${f}\"") - ENDFOREACH() - CONFIGURE_FILE(${_in_file} ${_out_file} @ONLY) -ENDMACRO(MEDCOUPLING_MED_SWIG_DOCSTRING_CONFIGURE) diff --git a/medtool/doc/user/doxygen/doxy2swig/doxy2swig.py b/medtool/doc/user/doxygen/doxy2swig/doxy2swig.py deleted file mode 100755 index 7a3b3ea8f..000000000 --- a/medtool/doc/user/doxygen/doxy2swig/doxy2swig.py +++ /dev/null @@ -1,455 +0,0 @@ -#!/usr/bin/env python -"""Doxygen XML to SWIG docstring converter. - -Usage: - - doxy2swig.py [options] input.xml output.i - -Converts Doxygen generated XML files into a file containing docstrings -that can be used by SWIG-1.3.x. Note that you need to get SWIG -version > 1.3.23 or use Robin Dunn's docstring patch to be able to use -the resulting output. - -input.xml is your doxygen generated XML file and output.i is where the -output will be written (the file will be clobbered). - -""" -###################################################################### -# -# This code is implemented using Mark Pilgrim's code as a guideline: -# http://www.faqs.org/docs/diveintopython/kgp_divein.html -# -# Author: Prabhu Ramachandran -# License: BSD style -# -# Thanks: -# Johan Hake: the include_function_definition feature -# Bill Spotz: bug reports and testing. -# Sebastian Henschel: Misc. enhancements. -# -###################################################################### - -from xml.dom import minidom -import re -import textwrap -import sys -import types -import os.path -import optparse - - -def my_open_read(source): - if hasattr(source, "read"): - return source - else: - return open(source) - -def my_open_write(dest): - if hasattr(dest, "write"): - return dest - else: - return open(dest, 'w') - - -class Doxy2SWIG: - """Converts Doxygen generated XML files into a file containing - docstrings that can be used by SWIG-1.3.x that have support for - feature("docstring"). Once the data is parsed it is stored in - self.pieces. - - """ - - def __init__(self, src, include_function_definition=True, quiet=False): - """Initialize the instance given a source object. `src` can - be a file or filename. If you do not want to include function - definitions from doxygen then set - `include_function_definition` to `False`. This is handy since - this allows you to use the swig generated function definition - using %feature("autodoc", [0,1]). - - """ - f = my_open_read(src) - self.my_dir = os.path.dirname(f.name) - self.xmldoc = minidom.parse(f).documentElement - f.close() - - self.pieces = [] - self.pieces.append('\n// File: %s\n'%\ - os.path.basename(f.name)) - - self.space_re = re.compile(r'\s+') - self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)') - self.multi = 0 - self.ignores = ['inheritancegraph', 'param', 'listofallmembers', - 'innerclass', 'name', 'declname', 'incdepgraph', - 'invincdepgraph', 'programlisting', 'type', - 'references', 'referencedby', 'location', - 'collaborationgraph', 'reimplements', - 'reimplementedby', 'derivedcompoundref', - 'basecompoundref'] - #self.generics = [] - self.include_function_definition = include_function_definition - if not include_function_definition: - self.ignores.append('argsstring') - - self.quiet = quiet - - - def generate(self): - """Parses the file set in the initialization. The resulting - data is stored in `self.pieces`. - - """ - self.parse(self.xmldoc) - - def parse(self, node): - """Parse a given node. This function in turn calls the - `parse_` functions which handle the respective - nodes. - - """ - pm = getattr(self, "parse_%s"%node.__class__.__name__) - pm(node) - - def parse_Document(self, node): - self.parse(node.documentElement) - - def parse_Text(self, node): - txt = node.data - txt = txt.replace('\\', r'\\\\') - txt = txt.replace('"', r'\"') - # ignore pure whitespace - m = self.space_re.match(txt) - if m and len(m.group()) == len(txt): - pass - else: - self.add_text(textwrap.fill(txt, break_long_words=False)) - - def parse_Element(self, node): - """Parse an `ELEMENT_NODE`. This calls specific - `do_` handers for different elements. If no handler - is available the `generic_parse` method is called. All - tagNames specified in `self.ignores` are simply ignored. - - """ - name = node.tagName - ignores = self.ignores - if name in ignores: - return - attr = "do_%s" % name - if hasattr(self, attr): - handlerMethod = getattr(self, attr) - handlerMethod(node) - else: - self.generic_parse(node) - #if name not in self.generics: self.generics.append(name) - - def parse_Comment(self, node): - """Parse a `COMMENT_NODE`. This does nothing for now.""" - return - - def add_text(self, value): - """Adds text corresponding to `value` into `self.pieces`.""" - if type(value) in (types.ListType, types.TupleType): - self.pieces.extend(value) - else: - self.pieces.append(value) - - def get_specific_nodes(self, node, names): - """Given a node and a sequence of strings in `names`, return a - dictionary containing the names as keys and child - `ELEMENT_NODEs`, that have a `tagName` equal to the name. - - """ - nodes = [(x.tagName, x) for x in node.childNodes \ - if x.nodeType == x.ELEMENT_NODE and \ - x.tagName in names] - return dict(nodes) - - def generic_parse(self, node, pad=0): - """A Generic parser for arbitrary tags in a node. - - Parameters: - - - node: A node in the DOM. - - pad: `int` (default: 0) - - If 0 the node data is not padded with newlines. If 1 it - appends a newline after parsing the childNodes. If 2 it - pads before and after the nodes are processed. Defaults to - 0. - - """ - npiece = 0 - if pad: - npiece = len(self.pieces) - if pad == 2: - self.add_text('\n') - for n in node.childNodes: - self.parse(n) - if pad: - if len(self.pieces) > npiece: - self.add_text('\n') - - def space_parse(self, node): - self.add_text(' ') - self.generic_parse(node) - - do_ref = space_parse - do_emphasis = space_parse - do_bold = space_parse - do_computeroutput = space_parse - do_formula = space_parse - - def do_compoundname(self, node): - self.add_text('\n\n') - data = node.firstChild.data - self.add_text('%%feature("docstring") %s "\n'%data) - - def do_compounddef(self, node): - kind = node.attributes['kind'].value - if kind in ('class', 'struct'): - prot = node.attributes['prot'].value - if prot <> 'public': - return - names = ('compoundname', 'briefdescription', - 'detaileddescription', 'includes') - first = self.get_specific_nodes(node, names) - for n in names: - if first.has_key(n): - self.parse(first[n]) - self.add_text(['";','\n']) - for n in node.childNodes: - if n not in first.values(): - self.parse(n) - elif kind in ('file', 'namespace'): - nodes = node.getElementsByTagName('sectiondef') - for n in nodes: - self.parse(n) - - def do_includes(self, node): - self.add_text('C++ includes: ') - self.generic_parse(node, pad=1) - - def do_parameterlist(self, node): - text='unknown' - for key, val in node.attributes.items(): - if key == 'kind': - if val == 'param': text = 'Parameters' - elif val == 'exception': text = 'Exceptions' - else: text = val - break - self.add_text(['\n', '\n', text, ':', '\n']) - self.generic_parse(node, pad=1) - - def do_para(self, node): - self.add_text('\n') - self.generic_parse(node, pad=1) - - def do_parametername(self, node): - self.add_text('\n') - try: - data=node.firstChild.data - except AttributeError: # perhaps a tag in it - data=node.firstChild.firstChild.data - if data.find('Exception') != -1: - self.add_text(data) - else: - self.add_text("%s: "%data) - - def do_parameterdefinition(self, node): - self.generic_parse(node, pad=1) - - def do_detaileddescription(self, node): - self.generic_parse(node, pad=1) - - def do_briefdescription(self, node): - self.generic_parse(node, pad=1) - - def do_memberdef(self, node): - prot = node.attributes['prot'].value - id = node.attributes['id'].value - kind = node.attributes['kind'].value - tmp = node.parentNode.parentNode.parentNode - compdef = tmp.getElementsByTagName('compounddef')[0] - cdef_kind = compdef.attributes['kind'].value - - if prot == 'public': - first = self.get_specific_nodes(node, ('definition', 'name')) - name = first['name'].firstChild.data - if name[:8] == 'operator': # Don't handle operators yet. - return - - if not first.has_key('definition') or \ - kind in ['variable', 'typedef']: - return - - if self.include_function_definition: - defn = first['definition'].firstChild.data - else: - defn = "" - self.add_text('\n') - self.add_text('%feature("docstring") ') - - anc = node.parentNode.parentNode - if cdef_kind in ('file', 'namespace'): - ns_node = anc.getElementsByTagName('innernamespace') - if not ns_node and cdef_kind == 'namespace': - ns_node = anc.getElementsByTagName('compoundname') - if ns_node: - ns = ns_node[0].firstChild.data - self.add_text(' %s::%s "\n%s'%(ns, name, defn)) - else: - self.add_text(' %s "\n%s'%(name, defn)) - elif cdef_kind in ('class', 'struct'): - # Get the full function name. - anc_node = anc.getElementsByTagName('compoundname') - cname = anc_node[0].firstChild.data - self.add_text(' %s::%s "\n%s'%(cname, name, defn)) - - for n in node.childNodes: - if n not in first.values(): - self.parse(n) - self.add_text(['";', '\n']) - - def do_definition(self, node): - data = node.firstChild.data - self.add_text('%s "\n%s'%(data, data)) - - def do_sectiondef(self, node): - kind = node.attributes['kind'].value - if kind in ('public-func', 'func', 'user-defined', ''): - self.generic_parse(node) - - def do_header(self, node): - """For a user defined section def a header field is present - which should not be printed as such, so we comment it in the - output.""" - data = node.firstChild.data - self.add_text('\n/*\n %s \n*/\n'%data) - # If our immediate sibling is a 'description' node then we - # should comment that out also and remove it from the parent - # node's children. - parent = node.parentNode - idx = parent.childNodes.index(node) - if len(parent.childNodes) >= idx + 2: - nd = parent.childNodes[idx+2] - if nd.nodeName == 'description': - nd = parent.removeChild(nd) - self.add_text('\n/*') - self.generic_parse(nd) - self.add_text('\n*/\n') - - def do_simplesect(self, node): - kind = node.attributes['kind'].value - if kind in ('date', 'rcs', 'version'): - pass - elif kind == 'warning': - self.add_text(['\n', 'WARNING: ']) - self.generic_parse(node) - elif kind == 'see': - self.add_text('\n') - self.add_text('See: ') - self.generic_parse(node) - elif kind == 'return': - self.add_text(['\n', '===> Returns: ']) - self.generic_parse(node) - else: - self.generic_parse(node) - - def do_argsstring(self, node): - self.generic_parse(node, pad=1) - - def do_member(self, node): - kind = node.attributes['kind'].value - refid = node.attributes['refid'].value - if kind == 'function' and refid[:9] == 'namespace': - self.generic_parse(node) - - def do_doxygenindex(self, node): - self.multi = 1 - comps = node.getElementsByTagName('compound') - for c in comps: - refid = c.attributes['refid'].value - fname = refid + '.xml' - if not os.path.exists(fname): - fname = os.path.join(self.my_dir, fname) - if not self.quiet: - print "parsing file: %s"%fname - p = Doxy2SWIG(fname, self.include_function_definition, self.quiet) - p.generate() - self.pieces.extend(self.clean_pieces(p.pieces)) - - def write(self, fname): - o = my_open_write(fname) - if self.multi: - o.write("".join(self.pieces)) - else: - o.write("".join(self.clean_pieces(self.pieces))) - o.close() - - def clean_pieces(self, pieces): - """Cleans the list of strings given as `pieces`. It replaces - multiple newlines by a maximum of 2 and returns a new list. - It also wraps the paragraphs nicely. - - """ - ret = [] - count = 0 - for i in pieces: - if i == '\n': - count = count + 1 - else: - if i == '";': - if count: - ret.append('\n') - elif count > 2: - ret.append('\n\n') - elif count: - ret.append('\n'*count) - count = 0 - ret.append(i) - - _data = "".join(ret) - ret = [] - for i in _data.split('\n\n'): - if i == 'Parameters:' or i == 'Exceptions:': - ret.extend([i, '\n-----------', '\n\n']) - elif i.find('// File:') > -1: # leave comments alone. - ret.extend([i, '\n']) - else: - _tmp = textwrap.fill(i.strip(), break_long_words=False) - _tmp = self.lead_spc.sub(r'\1"\2', _tmp) - ret.extend([_tmp, '\n\n']) - return ret - - -def convert(input, output, include_function_definition=True, quiet=False): - p = Doxy2SWIG(input, include_function_definition, quiet) - p.generate() - p.write(output) - -def main(): - usage = __doc__ - parser = optparse.OptionParser(usage) - parser.add_option("-n", '--no-function-definition', - action='store_true', - default=False, - dest='func_def', - help='do not include doxygen function definitions') - parser.add_option("-q", '--quiet', - action='store_true', - default=False, - dest='quiet', - help='be quiet and minimize output') - - options, args = parser.parse_args() - if len(args) != 2: - parser.error("error: no input and output specified") - - convert(args[0], args[1], not options.func_def, options.quiet) - - -if __name__ == '__main__': - main() - diff --git a/medtool/doc/user/doxygen/fakesources/MEDCouplingField.C b/medtool/doc/user/doxygen/fakesources/MEDCouplingField.C deleted file mode 100644 index 8f748fd76..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDCouplingField.C +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// generation of documentation for inline methods. - - -namespace ParaMEDMEM -{ - /*! - * Checks if \a this field is correctly defined, else an exception is thrown. - * \throw If the mesh is not set. - * \throw If the data array is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a this->getTimeTolerance() < 0. - * \throw If the temporal discretization data is incorrect. - * \throw If mesh data does not correspond to field data. - */ - void MEDCouplingField::checkCoherency() const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns the underlying mesh of \a this field. - * \return const ParaMEDMEM::MEDCouplingMesh * - a const pointer to the underlying mesh. - */ - const ParaMEDMEM::MEDCouplingMesh *MEDCouplingField::getMesh() const {} - /*! - * Returns the description of \a this field. - * \return const char * - a string containing the field description. - */ - const char *MEDCouplingField::getDescription() const {} - /*! - * Sets the description of \a this field. - * \param [in] desc - a string containing the field description. - */ - void MEDCouplingField::setDescription(const char *desc) {} - /*! - * Returns the name of \a this field. - * \return const char * - a string containing the field name. - */ - const char *MEDCouplingField::getName() const {} -} diff --git a/medtool/doc/user/doxygen/fakesources/MEDCouplingFieldDouble.C b/medtool/doc/user/doxygen/fakesources/MEDCouplingFieldDouble.C deleted file mode 100644 index 69e14afcd..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDCouplingFieldDouble.C +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// * generation of documentation for inline methods, -// * groupping methods into "Basic API", "Advanced" and "Others..." sections - - -namespace ParaMEDMEM -{ - /*! - * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of - * \a this and a given field ( _f_ [ i, j ] = _this_ [ i, j ] + _other_ [ i, j ] ). - * Number of tuples and components in the two fields must be the same. - * \param [in] other - the input field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of - * \a this and a given field ( _f_ [ i, j ] = _this_ [ i, j ] - _other_ [ i, j ] ). - * Number of tuples and components in the two fields must be the same. - * \param [in] other - the field to subtract from \a this one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing product values of \a this and a - * given field. There are 2 valid cases. - * 1. The fields have same number of tuples and components. Then each value of - * the result field (_f_) is a product of the corresponding values of _this_ and - * _other_, i.e. _f_ [ i, j ] = _this_ [ i, j ] * _other_ [ i, j ]. - * 2. The fields have same number of tuples and one field, say _other_, has one - * component. Then - * _f_ [ i, j ] = _this_ [ i, j ] * _other_ [ i, 0 ]. - * - * The two fields must have same number of tuples and same underlying mesh. - * \param [in] other - a factor field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not compatible for production (areCompatibleForMul()), - * i.e. they differ not only in values and possibly number of components. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing division of \a this and a given - * field. There are 2 valid cases. - * 1. The fields have same number of tuples and components. Then each value of - * the result field (_f_) is a division of the corresponding values of \a this and - * \a other, i.e. _f_ [ i, j ] = _this_ [ i, j ] / _other_ [ i, j ]. - * 2. The fields have same number of tuples and _other_ has one component. Then - * _f_ [ i, j ] = _this_ [ i, j ] / _other_ [ i, 0 ]. - * - * \param [in] other - a denominator field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not compatible for division (areCompatibleForDiv()), - * i.e. they differ not only in values and possibly in number of components. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing a dot product of \a this and a given field, - * so that the i-th tuple of the result field (_f_) is a sum of products of j-th components of - * i-th tuples of two fields (\f$ f_i = \sum_ {}^n f1_j * f2_j \f$). - * Number of tuples and components in the two fields must be the same. - * \param [in] other - the input field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing a cross product of \a this and - * a given field, so that the i-th tuple of the result field is a 3D vector which - * is a cross product of two vectors defined by the i-th tuples of the two fields. - * Number of tuples in the fields must be the same. - * Number of components in the fields must be 3. - * \param [in] other - the input field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If \a this->getNumberOfComponents() != 3 - * \throw If \a other->getNumberOfComponents() != 3 - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing maximal values of \a this and a - * given field. Number of tuples and components in the two fields must be the same. - * \param [in] other - the field to compare values with \a this one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a new MEDCouplingFieldDouble containing minimal values of \a this and a - * given field. Number of tuples and components in the two fields must be the same. - * \param [in] other - the field to compare values with \a this one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ - MEDCouplingFieldDouble *MEDCouplingFieldDouble::min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns the data array of \a this field. - * \return const DataArrayDouble * - a const pointer to the data array of \a this field. - */ - const DataArrayDouble *MEDCouplingFieldDouble::getArray() const {} - /*! - * Returns the data array of \a this field apt for modification. - * \return DataArrayDouble * - a non-const pointer to the data array of \a this field. - */ - DataArrayDouble *MEDCouplingFieldDouble::getArray() {} - /*! - * Sets a precision used to compare time values. - * \param [in] val - the precision value. - */ - void MEDCouplingFieldDouble::setTimeTolerance(double val) {} - /*! - * Returns a precision used to compare time values. - * \return double - the precision value. - */ - double MEDCouplingFieldDouble::getTimeTolerance() const {} - /*! - * Sets the number of iteration where the data array of \a this field has been calculated. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [in] it - the iteration number. - */ - void MEDCouplingFieldDouble::setIteration(int it) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets the number of iteration where the second data array of \a this field has been calculated. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [in] it - the iteration number. - */ - void MEDCouplingFieldDouble::setEndIteration(int it) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets the order number of iteration where the data array of \a this field has been calculated. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [in] order - the order number. - */ - void MEDCouplingFieldDouble::setOrder(int order) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets the order number of iteration where the second data array of \a this field has - * been calculated. - * \param [in] order - the order number. - */ - void MEDCouplingFieldDouble::setEndOrder(int order) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets the time when the data array of \a this field has been calculated. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [in] val - the time value. - */ - void MEDCouplingFieldDouble::setTimeValue(double val) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets the time when the second data array of \a this field has been calculated. - * \param [in] val - the time value. - */ - void MEDCouplingFieldDouble::setEndTimeValue(double val) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets time, number of iteration and order number of iteration when the data array - * of \a this field has been calculated. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [in] val - the time value. - * \param [in] iteration - the iteration number. - * \param [in] order - the order number. - */ - void MEDCouplingFieldDouble::setTime(double val, int iteration, int order) {} - /*! - * Returns time, number of iteration and order number of iteration when the data array - * of \a this field has been calculated. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [out] iteration - the iteration number. - * \param [out] order - the order number. - * \return double - the time value. - */ - double MEDCouplingFieldDouble::getTime(int& iteration, int& order) const {} - /*! - * Returns a value indexed by a tuple id and a component id. - * \param [in] tupleId - the id of the tuple of interest. - * \param [in] compoId - the id of the component of interest. - * \return double - the field value. - */ - double MEDCouplingFieldDouble::getIJ(int tupleId, int compoId) const {} -} - -namespace ParaMEDMEM -{ -/*! \name Basic API */ -///@{ -MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::MergeFields(const std::vector& a); -MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); -MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); -MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector& fs); -MEDCouplingFieldDouble::accumulate(double *res) const; -MEDCouplingFieldDouble::accumulate(int compId) const; -MEDCouplingFieldDouble::advancedRepr() const; -MEDCouplingFieldDouble::applyFunc(const std::string &func); -MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func); -MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string &func); -MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val); -MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string &func); -MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string &func); -MEDCouplingFieldDouble::applyLin(double a, double b, int compoId); -MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; -MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const; -MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const; -MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue=0.); -MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15); -MEDCouplingFieldDouble::checkCoherency() const; -MEDCouplingFieldDouble::clone(bool recDeepCpy) const; -MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const; -MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other); -MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other); -MEDCouplingFieldDouble::crossProduct(const MEDCouplingFieldDouble& other) const; -MEDCouplingFieldDouble::deepCpy() const; -MEDCouplingFieldDouble::determinant() const; -MEDCouplingFieldDouble::deviator() const; -MEDCouplingFieldDouble::dot(const MEDCouplingFieldDouble& other) const; -MEDCouplingFieldDouble::doublyContractedProduct() const; -MEDCouplingFieldDouble::eigenValues() const; -MEDCouplingFieldDouble::eigenVectors() const; -MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func); -MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string &func); -MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string &func); -MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string &func); -MEDCouplingFieldDouble::getArray() const; -MEDCouplingFieldDouble::getArray(); -MEDCouplingFieldDouble::getAverageValue() const; -MEDCouplingFieldDouble::getIJ(int tupleId, int compoId) const; -MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const; -MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const; -MEDCouplingFieldDouble::getMaxValue() const; -MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const; -MEDCouplingFieldDouble::getMinValue() const; -MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const; -MEDCouplingFieldDouble::getNumberOfComponents() const; -MEDCouplingFieldDouble::getNumberOfTuples() const; -MEDCouplingFieldDouble::getNumberOfValues() const; -MEDCouplingFieldDouble::getTime(int& iteration, int& order) const; -MEDCouplingFieldDouble::getTimeDiscretization() const; -MEDCouplingFieldDouble::getTimeTolerance() const; -MEDCouplingFieldDouble::getTimeUnit() const; -MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const; -MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const; -MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const; -MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const; -MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs=true) const; -MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs=true) const; -MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const; -MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const; -MEDCouplingFieldDouble::inverse() const; -MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; -MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const; -MEDCouplingFieldDouble::magnitude() const; -MEDCouplingFieldDouble::max(const MEDCouplingFieldDouble& other) const; -MEDCouplingFieldDouble::maxPerTuple() const; -MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals=1e-15); -MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals=1e-15); -MEDCouplingFieldDouble::min(const MEDCouplingFieldDouble& other) const; -MEDCouplingFieldDouble::norm2() const; -MEDCouplingFieldDouble::normL1(double *res) const; -MEDCouplingFieldDouble::normL1(int compId) const; -MEDCouplingFieldDouble::normL2(double *res) const; -MEDCouplingFieldDouble::normL2(int compId) const; -MEDCouplingFieldDouble::normMax() const; -MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check=true); -MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps=1e-15); -MEDCouplingFieldDouble::setArray(DataArrayDouble *array); -MEDCouplingFieldDouble::setArrays(const std::vector& arrs); -MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array); -MEDCouplingFieldDouble::setEndIteration(int it); -MEDCouplingFieldDouble::setIteration(int it); -MEDCouplingFieldDouble::setNature(NatureOfField nat); -MEDCouplingFieldDouble::setOrder(int order); -MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds); -MEDCouplingFieldDouble::setTime(double val, int iteration, int order); -MEDCouplingFieldDouble::setTimeTolerance(double val); -MEDCouplingFieldDouble::setTimeUnit(const char *unit); -MEDCouplingFieldDouble::setTimeValue(double val); -MEDCouplingFieldDouble::simpleRepr() const; -MEDCouplingFieldDouble::simplexize(int policy); -MEDCouplingFieldDouble::sortPerTuple(bool asc); -MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15); -MEDCouplingFieldDouble::trace() const; -MEDCouplingFieldDouble::updateTime() const; -MEDCouplingFieldDouble::writeVTK(const char *fileName) const; -MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals=1e-15); -MEDCouplingFieldDouble::zipCoords(double epsOnVals=1e-15); - MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator=(double value); - MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator*(const MEDCouplingFieldDouble& other) const; - MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator+(const MEDCouplingFieldDouble& other) const; - MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator-(const MEDCouplingFieldDouble& other) const; - MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator/(const MEDCouplingFieldDouble& other) const; - const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other); - const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other); - const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other); - const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other); -///@} -/*! \name Advanced API */ -///@{ -MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check=true); -MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15); -///@} - -/*! \name Others... */ -///@{ - MEDCouplingFieldDouble::negate() const; - MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const; - MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other); - MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); -MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const; -MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); -MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); -MEDCouplingFieldDouble::applyFuncFast32(const std::string &func); -MEDCouplingFieldDouble::applyFuncFast64(const std::string &func); -MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const; -MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; -MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const; -MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const; -MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const; -MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other); -MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const; -MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); -MEDCouplingFieldDouble::getArrays() const; -MEDCouplingFieldDouble::getEndArray() const; -MEDCouplingFieldDouble::getEndArray(); -MEDCouplingFieldDouble::getEndTime(int& iteration, int& order) const; -MEDCouplingFieldDouble::getStartTime(int& iteration, int& order) const; -MEDCouplingFieldDouble::getTimeDiscretizationUnderGround() const; -MEDCouplingFieldDouble::getTimeDiscretizationUnderGround(); -MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector& tinyInfo) const; -MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const; -MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const; -MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; -MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const; -MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays); -MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector& arrays) const; -MEDCouplingFieldDouble::setEndOrder(int order); -MEDCouplingFieldDouble::setEndTime(double val, int iteration, int order); -MEDCouplingFieldDouble::setEndTimeValue(double val); -MEDCouplingFieldDouble::setStartTime(double val, int iteration, int order); -MEDCouplingFieldDouble::synchronizeTimeWithMesh(); -MEDCouplingFieldDouble::synchronizeTimeWithSupport(); -MEDCouplingFieldDouble::~MEDCouplingFieldDouble(); -MEDCouplingFieldDouble::_time_discr; -///@} -} diff --git a/medtool/doc/user/doxygen/fakesources/MEDCouplingMemArray.C b/medtool/doc/user/doxygen/fakesources/MEDCouplingMemArray.C deleted file mode 100644 index 26f45eab2..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDCouplingMemArray.C +++ /dev/null @@ -1,611 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// * generation of documentation for inline methods of DataArray* classes -// * groupping methods into "Basic API", "Advanced" and "Others..." sections - - -namespace ParaMEDMEM -{ -/*! - * Returns the attribute \a _name of \a this array. - * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. - * \return std::string - array name - */ -std::string DataArray::getName() const {} - -/*! - * Returns number of components of \a this array. - * See \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. - * \return int - number of components - */ -int DataArray::getNumberOfComponents() const {} - -/*! - * Returns number of tuples of \a this array. - * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. - * \return int - number of tuples - */ -int DataArray::getNumberOfTuples() const {} - -/*! - * Returns number of elements of \a this array. - * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. - * \return int - number of elements == this->getNumberOfTuples() * - * this->getNumberOfComponents() - */ -int DataArray::getNbOfElems() const {} - -/*! - * Throws an exception if number of elements in \a this array differs from a given one. - * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. - * \param [in] nbOfElems - expected array size. - * \param [in] msg - message to return within the thrown exception. - * \throw if this->getNbOfElems() != nbOfElems. - */ -void DataArray::checkNbOfElems(int nbOfElems, const char *msg) const {} - -/*! - * Returns values of a specified tuple. - * \param [in] tupleId - index of the tuple of interest. - * \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res - * must be allocated by the caller and be of size not less than \a - * this->getNumberOfComponents(). - */ -void DataArrayDouble::getTuple(int tupleId, double *res) const {} - -/*! - * Returns a value of a specified element of \a this array. - * \param [in] tupleId - index of the tuple of interest. - * \param [in] compoId - index of the component of interest. - * \return double - the value of \a compoId-th component of \a tupleId-th tuple. - */ -double DataArrayDouble::getIJ(int tupleId, int compoId) const {} - -/*! - * Returns a pointer to the first element of the raw data of \a this array. - * \return double* - the pointer to the value of 0-th tuple and 0-th component. - */ -double * DataArrayDouble::getPointer() {} - -/*! - * Returns a const pointer to the first element of the raw data of \a this array. - * \return const double* - the pointer to the value of 0-th tuple and 0-th component. - */ -const double * DataArrayDouble::getConstPointer() const {} - -/*! - * Assigns a given value to a specified element of \a this array. - * \param [in] tupleId - index of the tuple to modify. - * \param [in] compoId - index of the component to modify. - * \param [in] newVal - the value to assign to the value at \a compoId-th component - * of \a tupleId-th tuple. - */ -void DataArrayDouble::setIJ(int tupleId, int compoId, double newVal) {} - -/*! - * Assigns a given value to a specified element of \a this array which is not marked - * as changed. - * \param [in] tupleId - index of the tuple to modify. - * \param [in] compoId - index of the component to modify. - * \param [in] newVal - the value to assign to the value at \a compoId-th component - * of \a tupleId-th tuple. - */ -void DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal) {} - -/*! - * Copies values from another array starting from a specified element of \a this. - * \param [in] id - index of element to assign the value \a element0 to. - * \param [in] element0 - value to assign to the \a id-th element of \a this. - * \param [in] others - values to assign to elements following the \a id-th - * element of \a this. - * \param [in] sizeOfOthers - number of values to copy from \a others. - */ -void DataArrayDouble::writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) {} - -/*! - * Does nothing because this class does not aggregate any TimeLabel instance. - */ -void DataArrayDouble::updateTime() const {} - -/*! - * Returns values of a specified tuple. - * \param [in] tupleId - index of the tuple of interest. - * \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res - * must be allocated by the caller and be of size not less than \a - * this->getNumberOfComponents(). - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_getTuple "Here is a Python example". - * \endif - */ -void DataArrayInt::getTuple(int tupleId, int *res) const {} - -/*! - * Returns a value of a specified element of \a this array. - * \param [in] tupleId - index of the tuple of interest. - * \param [in] compoId - index of the component of interest. - * \return int - the value of \a compoId-th component of \a tupleId-th tuple. - */ -int DataArrayInt::getIJ(int tupleId, int compoId) const {} - - -/*! - * Assigns a given value to a specified element of \a this array. - * \param [in] tupleId - index of the tuple to modify. - * \param [in] compoId - index of the component to modify. - * \param [in] newVal - the value to assign to the value at \a compoId-th component - * of \a tupleId-th tuple. - * \warning As this method declares \a this array as modified, it is more optimal to use - * setIJSilent() for modification of muliple values of array and to call - * declareAsNew() after the modification is done. - */ -void DataArrayInt::setIJ(int tupleId, int compoId, int newVal) {} - - -/*! - * Assigns a given value to a specified element of \a this array which is \b not marked - * as changed. - * \param [in] tupleId - index of the tuple to modify. - * \param [in] compoId - index of the component to modify. - * \param [in] newVal - the value to assign to the value at \a compoId-th component - * of \a tupleId-th tuple. - */ -void DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal) {} - -/*! - * Returns a pointer to the first element of the raw data of \a this array. - * \return int* - the pointer to the value of 0-th tuple and 0-th component. - */ -int * DataArrayInt::getPointer() {} - -/*! - * Returns a const pointer to the first element of the raw data of \a this array. - * \return const int* - the pointer to the value of 0-th tuple and 0-th component. - */ -const int * DataArrayInt::getConstPointer() const {} - -/*! - * Copies values from another array starting from a given element of \a this. - * \param [in] id - index of element to assign the value \a element0 to. - * \param [in] element0 - value to assign to the \a id-th element of \a this. - * \param [in] others - values to assign to elements following the \a id-th - * element of \a this. - * \param [in] sizeOfOthers - number of values to copy from \a others. - */ -void DataArrayInt::writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) {} - -} - -namespace ParaMEDMEM -{ -//================================================================================ -/////////////////////// DataArray GROUPPING ////////////////////////////////////// -//================================================================================ - -/*! \name Basic API */ -///@{ -DataArray::setName(const char *name); -DataArray::copyStringInfoFrom(const DataArray& other); -DataArray::areInfoEquals(const DataArray& other) const; -DataArray::getName() const; -DataArray::setInfoOnComponents(const std::vector& info); -DataArray::getVarOnComponent(int i) const; -DataArray::getUnitOnComponent(int i) const; -DataArray::setInfoOnComponent(int i, const char *info); -DataArray::getNumberOfComponents() const; -DataArray::getNumberOfTuples() const; -DataArray::getNbOfElems() const; -DataArray::checkNbOfElems(int nbOfElems, const char *msg) const; -DataArray::GetVarNameFromInfo(const std::string& info); -DataArray::GetUnitFromInfo(const std::string& info); -///@} - -/*! \name Others... */ -///@{ -DataArray::getHeapMemorySizeWithoutChildren() const; -DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds); -DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other); -DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; -DataArray::reprWithoutNameStream(std::ostream& stream) const; -DataArray::cppRepr(const char *varName) const; -DataArray::getInfoOnComponents() const; -DataArray::getInfoOnComponents(); -DataArray::getVarsOnComponent() const; -DataArray::getUnitsOnComponent() const; -DataArray::getInfoOnComponent(int i) const; -DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const; -DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const; -//DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception); -//DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception); -DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg); -DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg); -DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step); -DataArray::reprCppStream(const char *varName, std::ostream& stream) const; -DataArray::DataArray(); -DataArray::CheckValueInRange(int ref, int value, const char *msg); -DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg); -DataArray::CheckClosingParInRange(int ref, int value, const char *msg); -std::string DataArray::_name; -std::vector DataArray::_info_on_compo; -///@} - -//================================================================================ -/////////////////////// DataArrayDouble GROUPPING //////////////////////////////// -//================================================================================ - -/*! \name Basic API */ -///@{ -DataArrayDouble::isAllocated() const; -//DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& info); -DataArrayDouble::doubleValue() const; -DataArrayDouble::empty() const; -DataArrayDouble::deepCpy() const; -DataArrayDouble::performCpy(bool deepCpy) const; -DataArrayDouble::cpyFrom(const DataArrayDouble& other); -DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo); -DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo); -DataArrayDouble::fillWithZero(); -DataArrayDouble::fillWithValue(double val); -DataArrayDouble::iota(double init=0.); -DataArrayDouble::isUniform(double val, double eps) const; -DataArrayDouble::sort(bool asc=true); -DataArrayDouble::reverse(); -DataArrayDouble::checkMonotonic(bool increasing, double eps) const; -DataArrayDouble::isMonotonic(bool increasing, double eps) const; -DataArrayDouble::repr() const; -DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const; -DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; -DataArrayDouble::reAlloc(int nbOfTuples); -DataArrayDouble::convertToIntArr() const; -DataArrayDouble::fromNoInterlace() const; -DataArrayDouble::toNoInterlace() const; -DataArrayDouble::renumberInPlace(const int* old2New); -DataArrayDouble::renumberInPlaceR(const int* new2Old); -DataArrayDouble::renumber(const int* old2New) const; -DataArrayDouble::renumberR(const int* new2Old) const; -DataArrayDouble::renumberAndReduce(const int* old2New, int newNbOfTuple) const; -DataArrayDouble::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const; -DataArrayDouble::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const; -DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const; -DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const; -DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd=-1) const; -DataArrayDouble::rearrange(int newNbOfCompo); -DataArrayDouble::transpose(); -DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const; -DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const; -DataArrayDouble::meldWith(const DataArrayDouble* other); -DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; -DataArrayDouble::getDifferentValues(double prec, int limitTupleId=-1) const; -DataArrayDouble::setSelectedComponents(const DataArrayDouble* a, const std::vector& compoIds); -DataArrayDouble::setPartOfValues1(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); -DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); -DataArrayDouble::setPartOfValues2(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); -DataArrayDouble::setPartOfValuesSimple2(double a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp); -DataArrayDouble::setPartOfValues3(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); -DataArrayDouble::setPartOfValuesSimple3(double a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp); -DataArrayDouble::getTuple(int tupleId, double* res) const; -DataArrayDouble::getIJ(int tupleId, int compoId) const; -DataArrayDouble::back() const; -DataArrayDouble::getIJSafe(int tupleId, int compoId) const; -DataArrayDouble::setIJ(int tupleId, int compoId, double newVal); -DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal); -DataArrayDouble::writeOnPlace(int id, double element0, const double* others, int sizeOfOthers); -DataArrayDouble::checkNoNullValues() const; -DataArrayDouble::getMinMaxPerComponent(double* bounds) const; -DataArrayDouble::getMaxValue(int& tupleId) const; -DataArrayDouble::getMaxValueInArray() const; -DataArrayDouble::getMinValue(int& tupleId) const; -DataArrayDouble::getMinValueInArray() const; -DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const; -DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const; -DataArrayDouble::getAverageValue() const; -DataArrayDouble::norm2() const; -DataArrayDouble::normMax() const; -DataArrayDouble::accumulate(double* res) const; -DataArrayDouble::accumulate(int compId) const; -DataArrayDouble::fromPolarToCart() const; -DataArrayDouble::fromCylToCart() const; -DataArrayDouble::fromSpherToCart() const; -DataArrayDouble::doublyContractedProduct() const; -DataArrayDouble::determinant() const; -DataArrayDouble::eigenValues() const; -DataArrayDouble::eigenVectors() const; -DataArrayDouble::inverse() const; -DataArrayDouble::trace() const; -DataArrayDouble::deviator() const; -DataArrayDouble::magnitude() const; -DataArrayDouble::maxPerTuple() const; -DataArrayDouble::sortPerTuple(bool asc); -DataArrayDouble::abs(); -DataArrayDouble::applyLin(double a, double b, int compoId); -DataArrayDouble::applyLin(double a, double b); -DataArrayDouble::applyInv(double numerator); -DataArrayDouble::negate() const; -DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const; -DataArrayDouble::applyFunc(const std::string& func, bool isSafe=true) const; -DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const; -DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe=true) const; -DataArrayDouble::getIdsInRange(double vmin, double vmax) const; -DataArrayDouble::addEqual(const DataArrayDouble* other); -DataArrayDouble::substractEqual(const DataArrayDouble* other); -DataArrayDouble::multiplyEqual(const DataArrayDouble* other); -DataArrayDouble::divideEqual(const DataArrayDouble* other); -DataArrayDouble::updateTime() const; -DataArrayDouble::New(); -DataArrayDouble::Aggregate(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Aggregate(const std::vector& arr); -DataArrayDouble::Meld(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Meld(const std::vector& arr); -DataArrayDouble::Dot(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::CrossProduct(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Max(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Min(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Add(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Substract(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Multiply(const DataArrayDouble* a1, const DataArrayDouble* a2); -DataArrayDouble::Divide(const DataArrayDouble* a1, const DataArrayDouble* a2); -///@} - -/*! \name Advanced API */ -///@{ -DataArrayDouble::checkAllocated() const; -DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble* a, const DataArrayInt* tuplesSelec); -DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble* a, const DataArrayInt* tuplesSelec); -DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble* a, int bg, int end2, int step); -DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const; -///@} - -/*! \name Others... */ -///@{ -DataArrayDouble::getNumberOfTuples() const; -DataArrayDouble::getNbOfElems() const; -//DataArrayDouble::getHeapMemorySize() const; -DataArrayDouble::reserve(int nbOfElems); -DataArrayDouble::pushBackSilent(double val); -DataArrayDouble::popBackSilent(); -DataArrayDouble::pack() const; -DataArrayDouble::getNbOfElemAllocated() const; -DataArrayDouble::reprZip() const; -DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char* nameInFile) const; -DataArrayDouble::reprStream(std::ostream& stream) const; -DataArrayDouble::reprZipStream(std::ostream& stream) const; -DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const; -DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const; -DataArrayDouble::reprCppStream(const char* varName, std::ostream& stream) const; -DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; -DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const; -DataArrayDouble::setPartOfValues4(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); -DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp); -DataArrayDouble::getPointer(); -DataArrayDouble::SetArrayIn(DataArrayDouble* newArray, DataArrayDouble* &arrayToSet); -DataArrayDouble::iterator(); -DataArrayDouble::getConstPointer() const; -DataArrayDouble::begin() const; -DataArrayDouble::end() const; -DataArrayDouble::useArray(const double* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); -DataArrayDouble::useExternalArrayWithRWAccess(const double* array, int nbOfTuple, int nbOfCompo); -DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last); -DataArrayDouble::computeBBoxPerTuple(double epsilon=0.0) const; -DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble* other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; -DataArrayDouble::recenterForMaxPrecision(double eps); -DataArrayDouble::distanceToTuple(const double* tupleBg, const double* tupleEnd, int& tupleId) const; -DataArrayDouble::buildEuclidianDistanceDenseMatrix() const; -DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble* other) const; -DataArrayDouble::applyFuncFast32(const std::string& func); -DataArrayDouble::applyFuncFast64(const std::string& func); -DataArrayDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const; -DataArrayDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const; -DataArrayDouble::resizeForUnserialization(const std::vector& tinyInfoI); -DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); - -DataArrayDouble::findCommonTuplesAlg(const double* bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt* c, DataArrayInt* cI) const; - -DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double* pos, int nbOfTuples, double eps, DataArrayInt* c, DataArrayInt* cI); -DataArrayDouble::DataArrayDouble(); -MemArray DataArrayDouble::_mem; -///@} - -//================================================================================ -/////////////////////// DataArrayInt GROUPPING /////////////////////////////////// -//================================================================================ - -/*! \name Advanced API */ -///@{ -DataArrayInt::checkAllocated() const; -DataArrayInt::getHashCode() const; -DataArrayInt::buildPermutationArr(const DataArrayInt& other) const; -DataArrayInt::transformWithIndArr(const int* indArrBg, const int* indArrEnd); -DataArrayInt::transformWithIndArrR(const int* indArrBg, const int* indArrEnd) const; -DataArrayInt::splitByValueRange(const int* arrBg, const int* arrEnd,DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const; -DataArrayInt::setPartOfValuesAdv(const DataArrayInt* a, const DataArrayInt* tuplesSelec); -DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt* tuplesSelec); -DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt* a, int bg, int end2, int step); -DataArrayInt::SetArrayIn(DataArrayInt* newArray, DataArrayInt* &arrayToSet); -///@} - -/*! \name Basic API */ -///@{ -DataArrayInt::isAllocated() const; -//DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& info); -DataArrayInt::intValue() const; -DataArrayInt::empty() const; -DataArrayInt::deepCpy() const; -DataArrayInt::performCpy(bool deepCpy) const; -DataArrayInt::cpyFrom(const DataArrayInt& other); -DataArrayInt::alloc(int nbOfTuple, int nbOfCompo); -DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo); -DataArrayInt::isEqual(const DataArrayInt& other) const; -DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const; -DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const; -DataArrayInt::sort(bool asc=true); -DataArrayInt::reverse(); -DataArrayInt::fillWithZero(); -DataArrayInt::fillWithValue(int val); -DataArrayInt::iota(int init=0); -DataArrayInt::repr() const; -DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const; -DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const; -DataArrayInt::reAlloc(int nbOfTuples); -DataArrayInt::convertToDblArr() const; -DataArrayInt::fromNoInterlace() const; -DataArrayInt::toNoInterlace() const; -DataArrayInt::renumberInPlace(const int* old2New); -DataArrayInt::renumberInPlaceR(const int* new2Old); -DataArrayInt::renumber(const int* old2New) const; -DataArrayInt::renumberR(const int* new2Old) const; -DataArrayInt::renumberAndReduce(const int* old2NewBg, int newNbOfTuple) const; -DataArrayInt::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const; -DataArrayInt::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const; -DataArrayInt::selectByTupleId2(int bg, int end, int step) const; -DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const; -DataArrayInt::checkAndPreparePermutation() const; -DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const; -DataArrayInt::buildPermArrPerLevel() const; -DataArrayInt::isIdentity() const; -DataArrayInt::isUniform(int val) const; -DataArrayInt::substr(int tupleIdBg, int tupleIdEnd=-1) const; -DataArrayInt::rearrange(int newNbOfCompo); -DataArrayInt::transpose(); -DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const; -DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const; -DataArrayInt::meldWith(const DataArrayInt* other); -DataArrayInt::setSelectedComponents(const DataArrayInt* a, const std::vector& compoIds); -DataArrayInt::setPartOfValues1(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); -DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); -DataArrayInt::setPartOfValues2(const DataArrayInt* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); -DataArrayInt::setPartOfValuesSimple2(int a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp); -DataArrayInt::setPartOfValues3(const DataArrayInt* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); -DataArrayInt::setPartOfValuesSimple3(int a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp); -DataArrayInt::getTuple(int tupleId, int* res) const; -DataArrayInt::getIJ(int tupleId, int compoId) const; -DataArrayInt::getIJSafe(int tupleId, int compoId) const; -DataArrayInt::back() const; -DataArrayInt::setIJ(int tupleId, int compoId, int newVal); -DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal); -DataArrayInt::getPointer(); -DataArrayInt::getConstPointer() const; -DataArrayInt::getIdsEqual(int val) const; -DataArrayInt::getIdsNotEqual(int val) const; -DataArrayInt::getIdsEqualList(const int* valsBg, const int* valsEnd) const; -DataArrayInt::getIdsNotEqualList(const int* valsBg, const int* valsEnd) const; -DataArrayInt::changeValue(int oldValue, int newValue); -DataArrayInt::presenceOfValue(int value) const; -DataArrayInt::presenceOfValue(const std::vector& vals) const; -DataArrayInt::getMaxValue(int& tupleId) const; -DataArrayInt::getMaxValueInArray() const; -DataArrayInt::getMinValue(int& tupleId) const; -DataArrayInt::getMinValueInArray() const; -DataArrayInt::abs(); -DataArrayInt::applyLin(int a, int b, int compoId); -DataArrayInt::applyLin(int a, int b); -DataArrayInt::applyInv(int numerator); -DataArrayInt::negate() const; -DataArrayInt::applyDivideBy(int val); -DataArrayInt::applyModulus(int val); -DataArrayInt::applyRModulus(int val); -DataArrayInt::buildComplement(int nbOfElement) const; -DataArrayInt::buildSubstraction(const DataArrayInt* other) const; -DataArrayInt::buildUnion(const DataArrayInt* other) const; -DataArrayInt::buildIntersection(const DataArrayInt* other) const; -DataArrayInt::deltaShiftIndex() const; -DataArrayInt::computeOffsets(); -DataArrayInt::computeOffsets2(); -DataArrayInt::buildExplicitArrByRanges(const DataArrayInt* offsets) const; -DataArrayInt::useArray(const int* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); -DataArrayInt::writeOnPlace(int id, int element0, const int* others, int sizeOfOthers); -DataArrayInt::addEqual(const DataArrayInt* other); -DataArrayInt::substractEqual(const DataArrayInt* other); -DataArrayInt::multiplyEqual(const DataArrayInt* other); -DataArrayInt::divideEqual(const DataArrayInt* other); -DataArrayInt::modulusEqual(const DataArrayInt* other); -DataArrayInt::updateTime() const; -DataArrayInt::New(); -DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int* arr, const int* arrIBg, const int* arrIEnd, int &newNbOfTuples); -DataArrayInt::Aggregate(const DataArrayInt* a1, const DataArrayInt* a2, int offsetA2); -DataArrayInt::Aggregate(const std::vector& arr); -DataArrayInt::Meld(const DataArrayInt* a1, const DataArrayInt* a2); -DataArrayInt::Meld(const std::vector& arr); -DataArrayInt::MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); -DataArrayInt::BuildUnion(const std::vector& arr); -DataArrayInt::BuildIntersection(const std::vector& arr); -DataArrayInt::Add(const DataArrayInt* a1, const DataArrayInt* a2); -DataArrayInt::Substract(const DataArrayInt* a1, const DataArrayInt* a2); -DataArrayInt::Multiply(const DataArrayInt* a1, const DataArrayInt* a2); -DataArrayInt::Divide(const DataArrayInt* a1, const DataArrayInt* a2); -DataArrayInt::Modulus(const DataArrayInt* a1, const DataArrayInt* a2); -DataArrayInt::CheckAndPreparePermutation(const int* start, const int* end); -DataArrayInt::Range(int begin, int end, int step); -///@} - -/*! \name Others... */ -///@{ -DataArrayInt::getNumberOfTuples() const; -DataArrayInt::getNbOfElems() const; -//DataArrayInt::getHeapMemorySize() const; -DataArrayInt::reserve(int nbOfElems); -DataArrayInt::pushBackSilent(int val); -DataArrayInt::popBackSilent(); -DataArrayInt::pack() const; -DataArrayInt::getNbOfElemAllocated() const; -DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const; -DataArrayInt::checkMonotonic(bool increasing) const; -DataArrayInt::isMonotonic(bool increasing) const; -DataArrayInt::checkStrictlyMonotonic(bool increasing) const; -DataArrayInt::isStrictlyMonotonic(bool increasing) const; -DataArrayInt::reprZip() const; -DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char* type, const char* nameInFile) const; -DataArrayInt::reprStream(std::ostream& stream) const; -DataArrayInt::reprZipStream(std::ostream& stream) const; -DataArrayInt::reprWithoutNameStream(std::ostream& stream) const; -DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const; -DataArrayInt::reprCppStream(const char* varName, std::ostream& stream) const; -DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const; -DataArrayInt::setPartOfValues4(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); -DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp); -DataArrayInt::iterator(); -DataArrayInt::begin() const; -DataArrayInt::end() const; -DataArrayInt::locateTuple(const std::vector& tupl) const; -DataArrayInt::locateValue(int value) const; -DataArrayInt::locateValue(const std::vector& vals) const; -DataArrayInt::search(const std::vector& vals) const; -DataArrayInt::presenceOfTuple(const std::vector& tupl) const; -DataArrayInt::accumulate(int* res) const; -DataArrayInt::accumulate(int compId) const; -DataArrayInt::getIdsInRange(int vmin, int vmax) const; -DataArrayInt::buildSubstractionOptimized(const DataArrayInt* other) const; -DataArrayInt::buildUnique() const; -DataArrayInt::findRangeIdForEachTuple(const DataArrayInt* ranges) const; -DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt* ranges) const; -DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const; -DataArrayInt::getDifferentValues() const; -> DataArrayInt::partitionByDifferentValues(std::vector& differentIds) const; -DataArrayInt::useExternalArrayWithRWAccess(const int* array, int nbOfTuple, int nbOfCompo); -tor> -DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last); -DataArrayInt::getTinySerializationIntInformation(std::vector& tinyInfo) const; -DataArrayInt::getTinySerializationStrInformation(std::vector& tinyInfo) const; -DataArrayInt::resizeForUnserialization(const std::vector& tinyInfoI); -DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); -DataArrayInt::DataArrayInt(); -MemArray DataArrayInt::_mem; -///@} - -} diff --git a/medtool/doc/user/doxygen/fakesources/MEDCouplingMesh.C b/medtool/doc/user/doxygen/fakesources/MEDCouplingMesh.C deleted file mode 100644 index 4809eec6b..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDCouplingMesh.C +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// * generation of documentation for inline methods of DataArray* classes -// * groupping methods into "Basic API", "Advanced" and "Others..." sections - - -namespace ParaMEDMEM -{ - //================================================================================ - /*! - * Checks if \a this and another MEDCouplingMesh are equal without considering - * textual data like mesh name, names of spatial components etc. - * \param [in] other - an instance of MEDCouplingMesh to compare with \a this one. - * \param [in] prec - precision value used to compare node coordinates. - * \return bool - \c true if the two meshes are equal, \c false else. - */ - //================================================================================ - - bool MEDCouplingMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const {} - - /*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are - * considered equivalent if (1) \a this mesh contains the same nodes as the \a other - * mesh (with a specified precision) and (2) \a this mesh contains the same cells as - * the \a other mesh (with use of a specified cell comparison technique). The mapping - * from \a other to \a this for nodes and cells is returned via out parameters. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of - * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - */ - void MEDCouplingMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) {} - - /*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are considered equivalent if (1) they share the same - * node coordinates array(s) and (2) they contain the same cells (with use of a specified - * cell comparison technique). The mapping from cells of the \a other to ones of \a this - * is returned via an out parameter. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of - * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). - * \param [in] prec - a not used parameter. - * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - */ - void MEDCouplingMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) {} -} - -namespace ParaMEDMEM -{ -//================================================================================ -/////////////////////// GROUPPING members of MEDCouplingMesh ///////////////////// -//================================================================================ -/*! \name Basic API */ -///@{ - MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); - MEDCouplingMesh::MergeMeshes(std::vector& meshes); - MEDCouplingMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const; - MEDCouplingMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const; - MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const; - MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const; - MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const; - MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; - MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; - MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const; - MEDCouplingMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; - MEDCouplingMesh::writeVTK(const char *fileName) const; -///@} - -/*! \name Advanced API */ -///@{ - MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; -///@} - -/*! \name Others... */ -///@{ - MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCouplingMesh::MEDCouplingMesh(); - MEDCouplingMesh::~MEDCouplingMesh(); - MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other); - MEDCouplingMesh::advancedRepr() const = 0; - MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const; - MEDCouplingMesh::buildOrthogonalField() const = 0; - MEDCouplingMesh::buildPart(const int *start, const int *end) const = 0; - MEDCouplingMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; - MEDCouplingMesh::buildUnstructured() const; - MEDCouplingMesh::checkCoherency() const; - MEDCouplingMesh::checkCoherency1(double eps=1e-12) const; - MEDCouplingMesh::checkCoherency2(double eps=1e-12) const; - MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCouplingMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCouplingMesh::computeIsoBarycenterOfNodesPerCell() const; - MEDCouplingMesh::computeNbOfNodesPerCell() const; - MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other); - MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCouplingMesh::deepCpy() const = 0; - MEDCouplingMesh::getAllGeoTypes() const = 0; - MEDCouplingMesh::getBarycenterAndOwner() const = 0; - MEDCouplingMesh::getBoundingBox(double *bbox) const = 0; - MEDCouplingMesh::getCellContainingPoint(const double *pos, double eps) const = 0; - MEDCouplingMesh::getCoordinatesAndOwner() const = 0; - MEDCouplingMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCouplingMesh::getDescription() const; - MEDCouplingMesh::getDistributionOfTypes() const; -// MEDCouplingMesh::getHeapMemorySize() const; - MEDCouplingMesh::getMeasureField(bool isAbs) const = 0; - MEDCouplingMesh::getMeasureFieldOnNode(bool isAbs) const = 0; - MEDCouplingMesh::getMeshDimension() const = 0; - MEDCouplingMesh::getName() const; - MEDCouplingMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const = 0; - MEDCouplingMesh::getNumberOfCells() const = 0; - MEDCouplingMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; - MEDCouplingMesh::getNumberOfNodes() const = 0; - MEDCouplingMesh::getSpaceDimension() const = 0; - MEDCouplingMesh::getTime(int& iteration, int& order) const; - MEDCouplingMesh::getTimeUnit() const; - MEDCouplingMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const = 0; - MEDCouplingMesh::getType() const = 0; - MEDCouplingMesh::getTypeOfCell(int cellId) const = 0; - MEDCouplingMesh::getVTKDataSetType() const; - MEDCouplingMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCouplingMesh::isStructured() const; - MEDCouplingMesh::mergeMyselfWith(const MEDCouplingMesh *other) const = 0; - MEDCouplingMesh::renumberCells(const int *old2NewBg, bool check=true); - MEDCouplingMesh::reprQuickOverview(std::ostream& stream) const; - MEDCouplingMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const = 0; - MEDCouplingMesh::rotate(const double *center, const double *vector, double angle) = 0; - MEDCouplingMesh::scale(const double *point, double factor) = 0; - MEDCouplingMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0; - MEDCouplingMesh::setDescription(const char *descr); - MEDCouplingMesh::setName(const char *name); - MEDCouplingMesh::setTime(double val, int iteration, int order); - MEDCouplingMesh::setTimeUnit(const char *unit); - MEDCouplingMesh::simpleRepr() const = 0; - MEDCouplingMesh::simplexize(int policy); - MEDCouplingMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCouplingMesh::translate(const double *vector) = 0; - MEDCouplingMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,const std::vector& littleStrings) = 0; - //MEDCouplingMesh::writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda) const; - MEDCouplingMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const; - MEDCouplingMesh::_description; - MEDCouplingMesh::_iteration; - MEDCouplingMesh::_name; - MEDCouplingMesh::_order; - MEDCouplingMesh::_time; - MEDCouplingMesh::_time_unit; -///@} -} diff --git a/medtool/doc/user/doxygen/fakesources/MEDCouplingPointSet.C b/medtool/doc/user/doxygen/fakesources/MEDCouplingPointSet.C deleted file mode 100644 index b637a7c75..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDCouplingPointSet.C +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// * generation of documentation for inline methods of MEDCouplingPointSet - -namespace ParaMEDMEM -{ - - /*! - * Tries to use a coordinates array of \a other mesh for \a this one. If all nodes - * of \a this mesh coincide, within a specified precision, with some nodes of \a - * other mesh, then \a this mesh refers to the coordinates array of the \a other mesh, - * i.e. \a this->_coords = \a other._coords. Otherwise an exception is thrown and \a - * this remains unchanged. - * \param [in] other - the other mesh. - * \param [in] epsilon - the precision to compare node coordinates of the two meshes. - * \throw If the coordinates array of \a this is not set. - * \throw If the coordinates array of \a other is not set. - * \throw If not all nodes of \a this mesh are present in the \a other mesh. - */ - void MEDCouplingPointSet::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) {} - - /*! - * Returns a const pointer to the node coordinates array of \a this mesh \b without - * incrementing its reference counter, thus there is no need to decrRef() it by the caller. - */ - const DataArrayDouble *MEDCouplingPointSet::getCoords() const { return _coords; } - - /*! - * Returns a pointer to the node coordinates array of \a this mesh \b without - * incrementing its reference counter, thus there is no need to decrRef() it by the caller. - */ - DataArrayDouble *MEDCouplingPointSet::getCoords() { return _coords; } - - - //! size of returned tinyInfo must be always the same. - void MEDCouplingPointSet::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const {} -} diff --git a/medtool/doc/user/doxygen/fakesources/MEDCouplingUMesh.C b/medtool/doc/user/doxygen/fakesources/MEDCouplingUMesh.C deleted file mode 100644 index 443b632c7..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDCouplingUMesh.C +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// * generation of documentation for inline methods of MEDCouplingUMesh class, -// * groupping methods into "Basic API", "Advanced" and "Others..." sections - -namespace ParaMEDMEM -{ - /*! - * Returns the nodal connectivity array. For more info on how data in stored in - * this array, see \ref MEDCouplingUMeshAdvBuild. - * \return const DataArrayInt * - a pointer to the nodal connectivity array - * referred by \a this mesh. - */ - const DataArrayInt * MEDCouplingUMesh::getNodalConnectivity() const {} - /*! - * Returns the nodal connectivity index array. For more info on how data in stored in - * this array, see \ref MEDCouplingUMeshAdvBuild. - * \return const DataArrayInt * - a pointer to the nodal connectivity index array - * referred by \a this mesh. - */ - const DataArrayInt * MEDCouplingUMesh::getNodalConnectivityIndex() const {} - /*! - * Returns the nodal connectivity array. For more info on how data in stored in - * this array, see \ref MEDCouplingUMeshAdvBuild. - * \return const DataArrayInt * - a pointer to the nodal connectivity array - * referred by \a this mesh. - */ - DataArrayInt * MEDCouplingUMesh::getNodalConnectivity() {} - /*! - * Returns the nodal connectivity index array. For more info on how data in stored in - * this array, see \ref MEDCouplingUMeshAdvBuild. - * \return const DataArrayInt * - a pointer to the nodal connectivity index array - * referred by \a this mesh. - */ - DataArrayInt * MEDCouplingUMesh::getNodalConnectivityIndex() {} -} - -namespace ParaMEDMEM -{ -//================================================================================ -/////////////////////// MEDCouplingUMesh GROUPPING /////////////////////////////// -//================================================================================ - -/*! \name Basic API */ -///@{ -MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); -MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2); -MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps); -MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); -MEDCouplingUMesh::MergeUMeshes(std::vector& a); -MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); -MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector& meshes); -MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector& meshes); -MEDCouplingUMesh::allocateCells(int nbOfCells); -MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const; -MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const; -MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cells) const; -MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const; -MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; -MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; -MEDCouplingUMesh::buildDirectionVectorField() const; -MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; -MEDCouplingUMesh::buildOrthogonalField() const; -MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; -//MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; -MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const; -MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; -MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; -MEDCouplingUMesh::checkCoherency() const; -MEDCouplingUMesh::checkCoherency1(double eps=1e-12) const; -MEDCouplingUMesh::checkCoherency2(double eps=1e-12) const; -//MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const; -//MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; -MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; -MEDCouplingUMesh::clone(bool recDeepCpy) const; -MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const; -MEDCouplingUMesh::convertAllToPoly(); -MEDCouplingUMesh::convertQuadraticCellsToLinear(); -MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd); -MEDCouplingUMesh::deepCpy() const; -MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells(); -MEDCouplingUMesh::findBoundaryNodes() const; -MEDCouplingUMesh::finishInsertingCells(); -MEDCouplingUMesh::getAllGeoTypes() const; -MEDCouplingUMesh::getAspectRatioField() const; -MEDCouplingUMesh::getBarycenterAndOwner() const; -MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const; -MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const; -//MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; -//MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const; -MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; -MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; -MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); -MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const; -MEDCouplingUMesh::getEdgeRatioField() const; -MEDCouplingUMesh::getMeasureField(bool isAbs) const; -MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const; -MEDCouplingUMesh::getMeshDimension() const; -MEDCouplingUMesh::getNodalConnectivity() const; -MEDCouplingUMesh::getNodalConnectivity(); -MEDCouplingUMesh::getNodalConnectivityIndex() const; -MEDCouplingUMesh::getNodalConnectivityIndex(); -MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const; -MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const; -MEDCouplingUMesh::getNumberOfCells() const; -MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const; -MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const; -MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; -MEDCouplingUMesh::getSkewField() const; -MEDCouplingUMesh::getTypeOfCell(int cellId) const; -MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const; -MEDCouplingUMesh::getWarpField() const; -MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell); -MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; -//MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); -//MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); -MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly); -MEDCouplingUMesh::orientCorrectlyPolyhedrons(); -//MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes); -//MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); -MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N); -MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const; -MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); -MEDCouplingUMesh::setMeshDimension(int meshDim); -MEDCouplingUMesh::sortCellsInMEDFileFrmt(); -//MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon); -MEDCouplingUMesh::unPolyze(); -//MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId=0); -MEDCouplingUMesh::zipCoordsTraducer(); - ///@} - - /*! \name Advanced API */ -///@{ -MEDCouplingUMesh::areOnlySimplexCells() const; -MEDCouplingUMesh::checkButterflyCells(std::vector& cells, double eps=1e-12) const; -MEDCouplingUMesh::computeTypes(); -MEDCouplingUMesh::convertDegeneratedCells(); -MEDCouplingUMesh::convertExtrudedPolyhedra(); -MEDCouplingUMesh::getMeshLength() const; -MEDCouplingUMesh::isFullyQuadratic() const; -MEDCouplingUMesh::isPresenceOfQuadratic() const; -MEDCouplingUMesh::simplexize(int policy); -MEDCouplingUMesh::tessellate2D(double eps); -MEDCouplingUMesh::tessellate2DCurve(double eps); - ///@ - -/*! \name Others... */ -///@{ -MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms,DataArrayInt *&szOfCellGrpOfSameType,DataArrayInt *&idInMsOfCellGrpOfSameType); -//MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); -MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType); -MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2); -MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2); -MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2); -MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2); -MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2); -MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; -//MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector& cut3DCurve, std::vector& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,const int *nodal3DCurve, const int *nodalIndx3DCurve,const int *desc, const int *descIndx, std::vector< std::pair >& cut3DSurf); -MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da); -MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut); -//MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector& addCoo, const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge); -//MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector >& intesctEdges1, const std::vector< std::vector >& colinear2,const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector >& intesctEdges2,const std::vector& addCoords,std::vector& addCoordsQuadratic, std::vector& cr, std::vector& crI, std::vector& cNb1, std::vector& cNb2); -MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI,DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); -//MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector& code); -MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn); -MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); -//MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); -MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p); -//MEDCouplingUMesh::CorrectExtrudedCell(int *begin, int *end); -MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end); -MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); -//MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt); -MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI,DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr); -//MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2,MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,std::vector& addCoo); -//MEDCouplingUMesh::Is3DExtrudedCellWellOriented(const int *begin, const int *end, const double *coords); -MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords); -MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords); -MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); -MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, const double *coords); -MEDCouplingUMesh::IsTetra4WellOriented(const int *begin, const int *end, const double *coords); -MEDCouplingUMesh::MEDCouplingUMesh(); -MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); -//MEDCouplingUMesh::MergeUMeshesLL(std::vector& a); -MEDCouplingUMesh::New(); -MEDCouplingUMesh::New(const std::string& meshName, int meshDim); -MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0); -MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); -MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); -MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); -MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); -MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res); -MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords); -MEDCouplingUMesh::advancedRepr() const; -//MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const; -MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const; -//MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf,const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const; -MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); -MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; -MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; -MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; -MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const; -MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const; -MEDCouplingUMesh::buildSpreadZonesWithPoly() const; -MEDCouplingUMesh::buildUnionOf2DMesh() const; -MEDCouplingUMesh::buildUnionOf3DMesh() const; -MEDCouplingUMesh::buildUnstructured() const; -MEDCouplingUMesh::cellIterator(); -MEDCouplingUMesh::cellsByType(); -MEDCouplingUMesh::checkConnectivityFullyDefined() const; -MEDCouplingUMesh::checkConsecutiveCellTypes() const; -MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; -MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const; -MEDCouplingUMesh::checkFullyDefined() const; -MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; -MEDCouplingUMesh::computeFetchedNodeIds() const; -MEDCouplingUMesh::computeNbOfNodesPerCell() const; -MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; -MEDCouplingUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const; -MEDCouplingUMesh::computeSkin() const; -MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const; -MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType=0); -MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; -MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; -MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; -MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; -MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; -MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; -MEDCouplingUMesh::convexEnvelop2D(); -MEDCouplingUMesh::cppRepr() const; -MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const; -//MEDCouplingUMesh::distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const; -//MEDCouplingUMesh::distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const; -MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); -MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset); -MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const; -MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; -MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; -MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; -MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; -MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; -MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; -MEDCouplingUMesh::findAndCorrectBadOriented3DCells(); -MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const; -MEDCouplingUMesh::findCellIdsOnBoundary() const; -MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; -MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate,DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const; -//MEDCouplingUMesh::getAllTypes() const; -MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector& bbox) const; -MEDCouplingUMesh::getDistributionOfTypes() const; -MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const; -//MEDCouplingUMesh::getHeapMemorySize() const; -MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const; -MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; -MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const; -MEDCouplingUMesh::getQuadraticStatus() const; -MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; -MEDCouplingUMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; -MEDCouplingUMesh::getType() const { return UNSTRUCTURED; } -MEDCouplingUMesh::getVTKDataSetType() const; -MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; -MEDCouplingUMesh::isContiguous1D() const; -MEDCouplingUMesh::isEmptyMesh(const std::vector& tinyInfo) const; -MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; -MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const; -MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; -MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const; -MEDCouplingUMesh::partitionBySpreadZone() const; -MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const; -MEDCouplingUMesh::rearrange2ConsecutiveCellTypes(); -MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check=true); -MEDCouplingUMesh::reprConnectivityOfThis() const; -MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const; -MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; -MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; -MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis); -MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis); -MEDCouplingUMesh::shiftNodeNumbersInConn(int delta); -MEDCouplingUMesh::simpleRepr() const; -MEDCouplingUMesh::simplexizePlanarFace5(); -MEDCouplingUMesh::simplexizePlanarFace6(); -MEDCouplingUMesh::simplexizePol0(); -MEDCouplingUMesh::simplexizePol1(); -MEDCouplingUMesh::simplifyPolyhedra(double eps); -MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve); -MEDCouplingUMesh::splitByType() const; -MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; -MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex); -MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); -MEDCouplingUMesh::updateTime() const; -MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const; -MEDCouplingUMesh::~MEDCouplingUMesh(); -//template MEDCouplingUMesh * MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const; -template void MEDCouplingUMesh::getCellsContainingPointsAlg -(const double *coords, const double *pos, int nbOfPoints,double eps, std::vector& elts, - std::vector& eltsIndex) const; - -//const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER]; -//const int MEDCouplingUMesh::N_MEDMEM_ORDER=24; -double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION; -int MEDCouplingUMesh::_mesh_dim; -std::set MEDCouplingUMesh::_types; -DataArrayInt * MEDCouplingUMesh::_nodal_connec; -DataArrayInt * MEDCouplingUMesh::_nodal_connec_index; - ///@} -} - diff --git a/medtool/doc/user/doxygen/fakesources/MEDFileField.C b/medtool/doc/user/doxygen/fakesources/MEDFileField.C deleted file mode 100644 index 9e9365db6..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDFileField.C +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// generation of documentation for inline methods. - - -namespace ParaMEDMEM // inline methods of MEDFileField1TSWithoutSDA -{ - /*! - * Returns the number of iteration where \a this field has been calculated. - * \return int - the iteration number. - */ -// int MEDFileField1TSWithoutSDA::getIteration() const {} - /*! - * Returns the order number of iteration where \a this field has been calculated. - * \return int - the order number. - */ -// int MEDFileField1TSWithoutSDA::getOrder() const {} - /*! - * Returns time, number of iteration and order number of iteration when - * \a this field has been calculated. - * \param [out] iteration - the iteration number. - * \param [out] order - the order number. - * \return double - the time value. - */ -// double MEDFileField1TSWithoutSDA::getTime(int& iteration, int& order) const {} - /*! - * Sets time, number of iteration and order number of iteration when - * \a this field has been calculated. - * \param [in] val - the time value. - * \param [in] iteration - the iteration number. - * \param [in] order - the order number. - */ -// void MEDFileField1TSWithoutSDA::setTime(int iteration, int order, double val) {} - /*! - * Returns units in which the time is measured. - * \return const char * - the time unit name. - */ -// const std::string& MEDFileField1TSWithoutSDA::getDtUnit() const {} -} - -namespace ParaMEDMEM // inline methods of MEDFileFieldGlobsReal -{ - /*! - * Returns non empty names of all used profiles. To get all profiles call getPfls(). - * \warning If a profile is used several times, its name is returned **only once**. - * To have a profile name in the result each time it is used, call - * getPflsReallyUsedMulti(). - * \return std::vector - a sequence of names of used profiles. - */ - std::vector MEDFileFieldGlobsReal::getPflsReallyUsed() const {} - /*! - * Returns non empty names of all used localizations. To get all localizations call getLocs(). - * \warning If a localization is used several times, its name is returned **only once**. - * To have a localization name in the result each time it is used, call - * getLocsReallyUsedMulti(). - * \return std::vector - a sequence of names of used localizations. - */ - std::vector MEDFileFieldGlobsReal::getLocsReallyUsed() const {} - /*! - * Returns non empty names of all used profiles as many times as they are used. - * \return std::vector - a sequence of names of used profiles. - */ - std::vector MEDFileFieldGlobsReal::getPflsReallyUsedMulti() const {} - /*! - * Returns non empty names of all used localizations as many times as they are used. - * \return std::vector - a sequence of names of used localizations. - */ - std::vector MEDFileFieldGlobsReal::getLocsReallyUsedMulti() const {} - /*! - * Replaces references to some profiles (a reference is a profile name) by references - * to other profiles. - * \param [in] mapOfModif - a sequence describing required replacements. Each element of - * this sequence is a pair whose - * - the first item is a vector of profile names to replace by the second item, - * - the second item is a profile name to replace every profile of the first item. - */ - void MEDFileFieldGlobsReal::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) {} - /*! - * Replaces references to some localizations (a reference is a localization name) by references - * to other localizations. - * \param [in] mapOfModif - a sequence describing required replacements. Each element of - * this sequence is a pair whose - * - the first item is a vector of localization names to replace by the second item, - * - the second item is a localization name to replace every localization of the first - * item. - */ - void MEDFileFieldGlobsReal::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) {} -} diff --git a/medtool/doc/user/doxygen/fakesources/MEDFileMesh.C b/medtool/doc/user/doxygen/fakesources/MEDFileMesh.C deleted file mode 100644 index 10565363b..000000000 --- a/medtool/doc/user/doxygen/fakesources/MEDFileMesh.C +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains some code used only for -// * generation of documentation for inline methods, -// * groupping methods into "Basic API", "Advanced" and "Others..." sections - - -namespace ParaMEDMEM -{ - /*! - * Sets the name of \a this mesh. - * \param [in] name - the new mesh name. - */ - void MEDFileMesh::setName(const std::string& name) {} - /*! - * Returns the name of \a this mesh. - * \return const char* name - the mesh name. - */ - const std::string& MEDFileMesh::getName() const {} - /*! - * Sets the universal name of \a this mesh. The universal name uniquely identifies the mesh. - * \param [in] name - the new universal mesh name. - */ - void MEDFileMesh::setUnivName(const std::string& name) {} - /*! - * Returns the universal name of \a this mesh. The universal name uniquely identifies the mesh. - * \return const std::string& - the universal mesh name. - */ - const std::string& MEDFileMesh::getUnivName() const {} - /*! - * Sets the description of \a this mesh. - * \param [in] name - the new mesh description. - */ - void MEDFileMesh::setDescription(const std::string& name) {} - /*! - * Returns the description of \a this mesh. - * \return const char* - the mesh description. - */ - const std::string& MEDFileMesh::getDescription() const {} - /*! - * Sets the order number of iteration of \a this mesh state. - * \param [in] order - the order number. - */ - void MEDFileMesh::setOrder(int order) {} - /*! - * Returns the order number of iteration of \a this mesh state. - * \return int - the order number. - */ - int MEDFileMesh::getOrder() const {} - /*! - * Sets the number of iteration of \a this mesh state. - * \param [in] it - the iteration number. - */ - void MEDFileMesh::setIteration(int it) {} - /*! - * Returns the number of iteration of \a this mesh state. - * \return int - the iteration number. - */ - int MEDFileMesh::getIteration() const {} - /*! - * Sets the time of \a this mesh state. - * \param [in] val - the time value. - */ - void MEDFileMesh::setTimeValue(double time) {} - /*! - * Sets time, the number of iteration and the order number of iteration - * of \a this mesh state. - * \param [in] val - the time value. - * \param [in] iteration - the iteration number. - * \param [in] order - the order number. - */ - void MEDFileMesh::setTime(int dt, int it, double time) {} - /*! - * Returns time, the number of iteration and the order number of iteration - * of \a this mesh state. - * \param [out] iteration - the iteration number. - * \param [out] order - the order number. - * \return double - the time value. - */ - double MEDFileMesh::getTime(int& dt, int& it) {} - /*! - * Returns the time of \a this mesh state. - * \return double - the time value. - */ - double MEDFileMesh::getTimeValue() const {} - /*! - * Sets units in which the time is measured. - * \param [in] unit - the time unit name. - */ - void MEDFileMesh::setTimeUnit(const std::string& unit) {} - /*! - * Returns units in which the time is measured. - * \return const std::string& - the time unit name. - */ - const std::string& MEDFileMesh::getTimeUnit() const {} - /*! - * Returns names and ids of all families in \a this mesh. - * \return const std::map& - a map of a family name to a family id. - */ - const std::map& MEDFileMesh::getFamilyInfo() const {} - /*! - * Returns names of all groups and families constituting them in \a this mesh. - * \return const std::map >& - - * a map of a group name to a vector of names of families constituting the group. - */ - const std::map >& MEDFileMesh::getGroupInfo() const {} - /*! - * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions. - */ - std::vector MEDFileMesh::getNonEmptyLevels() const {} - /*! - * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions. - */ - std::vector MEDFileMesh::getNonEmptyLevelsExt() const {} - /*! - * Returns number of mesh entities of a given relative dimension in \a this mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \return int - the number of entities. - * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. - */ - int MEDFileMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a MEDCouplingMesh of a given relative dimension. - * \param [in] meshDimRelToMax - the relative dimension of interest. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a renum == \c true but permutation is impossible. - */ - MEDCouplingMesh *MEDFileMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns the dimension on cells in \a this mesh. - * \return int - the mesh dimension. - * \throw If there are no cells in this mesh. - */ - int MEDFileMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns a full textual description of \a this mesh. - * \return std::string - the string holding the mesh description. - */ - std::string MEDFileMesh::advancedRepr() const {} - /*! - * Sets the family field of a given relative dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which - * the family field is set. - * \param [in] famArr - the array of the family field. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a famArr has an invalid size. - */ - void MEDFileMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) {} - /*! - * Sets the optional numbers of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] renumArr - the array of the numbers. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a renumArr has an invalid size. - */ - void MEDFileMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) {} - /*! - * Returns the family field for mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families - * each mesh entity belongs to. It can be NULL. - */ - const DataArrayInt *MEDFileMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns the optional numbers of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ - const DataArrayInt *MEDFileMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns the optional numbers of mesh entities of a given dimension transformed using - * DataArrayInt::invertArrayN2O2O2N(). - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers transformed using - * DataArrayInt::invertArrayN2O2O2N(). - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ - const DataArrayInt *MEDFileMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} - /*! - * Returns ids of mesh entities contained in given families of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] fams - the names of the families of interest. - * \param [in] renum - if \c true, the optional numbers of entities, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of mesh entities of the families. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ - DataArrayInt *MEDFileMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception) {} -} - - -namespace ParaMEDMEM -{ - /*! \name Basic API */ - ///@{ - MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created); -//MEDFileMesh::New(const std::string& fileName); -//MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1); -MEDFileMesh::addFamily(const std::string& familyName, int id); -MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName); -MEDFileMesh::advancedRepr() const = 0; -MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const; -MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const; -MEDFileMesh::assignFamilyNameWithGroupName(); -MEDFileMesh::changeFamilyId(int oldId, int newId); -MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName); -MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName); -MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other); -MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName); -MEDFileMesh::existsFamily(const std::string& familyName) const; -MEDFileMesh::existsFamily(int famId) const; -MEDFileMesh::existsGroup(const std::string& groupName) const; -MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created); -MEDFileMesh::getDescription() const; -MEDFileMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; -MEDFileMesh::getFamiliesIds(const std::vector& famNames) const; -MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const; -MEDFileMesh::getFamiliesNames() const; -MEDFileMesh::getFamiliesOnGroup(const std::string& name) const; -MEDFileMesh::getFamiliesOnGroups(const std::vector& grps) const; -MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; -MEDFileMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; -MEDFileMesh::getFamilyId(const std::string& name) const; -MEDFileMesh::getFamilyInfo() const; -MEDFileMesh::getFamilyNameGivenId(int id) const; -MEDFileMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; -MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; -MEDFileMesh::getGroupInfo() const; -MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const; -MEDFileMesh::getGroupsNames() const; -MEDFileMesh::getGroupsOnFamily(const std::string& name) const; -MEDFileMesh::getIteration() const; -MEDFileMesh::getMaxFamilyId() const; -MEDFileMesh::getMeshDimension() const; -MEDFileMesh::getName() const; -MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum=false) const; -MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum=false) const; -MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum=false) const; -MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum=false) const; -MEDFileMesh::getNonEmptyLevels() const = 0; -MEDFileMesh::getNonEmptyLevelsExt() const = 0; -MEDFileMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const; -MEDFileMesh::getOrder() const; -MEDFileMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; -MEDFileMesh::getSizeAtLevel(int meshDimRelToMaxExt) const; -MEDFileMesh::getTime(int& dt, int& it); -MEDFileMesh::getTimeUnit() const; -MEDFileMesh::getTimeValue() const; -MEDFileMesh::getUnivName() const; -MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const; -MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& levs); -MEDFileMesh::removeFamily(const std::string& name); -MEDFileMesh::removeGroup(const std::string& name); -MEDFileMesh::setDescription(const std::string& name); -MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds); -MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector& fams); -MEDFileMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); -MEDFileMesh::setFamilyId(const std::string& familyName, int id); -MEDFileMesh::setFamilyInfo(const std::map& info); -MEDFileMesh::setGroupInfo(const std::map >&info); -MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false); -MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector& grps); -MEDFileMesh::setIteration(int it); -MEDFileMesh::setName(const std::string& name); -MEDFileMesh::setOrder(int order); -MEDFileMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); -MEDFileMesh::setTime(int dt, int it, double time); -MEDFileMesh::setTimeUnit(const std::string& unit); -MEDFileMesh::setTimeValue(double time); -MEDFileMesh::setUnivName(const std::string& name); -MEDFileMesh::simpleRepr() const; -MEDFileMesh::write(const std::string& fileName, int mode) const; -MEDFileMesh::write(med_idt fid) const; -///@} - -/*! \name Advanced API */ -///@{ -MEDFileMesh::clearNonDiscrAttributes() const; -///@} - -/*! \name Others... */ -///@{ -MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const std::string& familyNameToChange, const std::vector& newFamiliesNames); -MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid); -MEDFileMesh::MEDFileMesh(); -MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector& code, int strt); -MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); -MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName); -MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); -MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames); -MEDFileMesh::changeFamilyIdArr(int oldId, int newId); -MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab); -MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m); -MEDFileMesh::deepCpy() const; -MEDFileMesh::ensureDifferentFamIdsPerLevel(); -MEDFileMesh::getAllFamiliesIdsReferenced() const; -MEDFileMesh::getFamilyRepr(std::ostream& oss) const; -//MEDFileMesh::getHeapMemorySize() const; -MEDFileMesh::getMaxFamilyIdInArrays() const; -MEDFileMesh::getMinFamilyId() const; -MEDFileMesh::getMinFamilyIdInArrays() const; -MEDFileMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const; -MEDFileMesh::getNumberOfNodes() const; -MEDFileMesh::getTheMaxFamilyId() const; -MEDFileMesh::getTheMinFamilyId() const; -MEDFileMesh::normalizeFamIdsMEDFile(); -MEDFileMesh::normalizeFamIdsTrio(); -MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id); -MEDFileMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); -MEDFileMesh::shallowCpy() const; -MEDFileMesh::synchronizeTinyInfoOnLeaves() const = 0; -MEDFileMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); -MEDFileMesh::writeLL(med_idt fid) const; -int MEDFileMesh::_order; -int MEDFileMesh::_iteration; -double MEDFileMesh::_time; -std::string MEDFileMesh::_dt_unit; -std::string MEDFileMesh::_name; -std::string MEDFileMesh::_univ_name; -std::string MEDFileMesh::_desc_name; -std::map > MEDFileMesh::_groups; -std::map MEDFileMesh::_families; -static const char MEDFileMesh::DFT_FAM_NAME[]; -///@} -} - diff --git a/medtool/doc/user/doxygen/fakesources/namespaces.C b/medtool/doc/user/doxygen/fakesources/namespaces.C deleted file mode 100644 index d14e85718..000000000 --- a/medtool/doc/user/doxygen/fakesources/namespaces.C +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This file contains code used only for -// generation of documentation. Not working? - -/*! - * \namespace INTERP_KERNEL - * \brief Low level structures and algorithms used in MEDCoupling. Not considered as part of the public API. - */ - -/*! - * \namespace ParaMEDMEM - * \brief Namespace gathering the core MEDCoupling functionalities, the advanced MEDLoader classes and the parallel classes. - */ - -/*! - * \namespace ICoCo - * \brief Interface for COde COupling. See the page \ref icoco. - */ - diff --git a/medtool/doc/user/doxygen/figures/IndirectIndex.jpg b/medtool/doc/user/doxygen/figures/IndirectIndex.jpg deleted file mode 100644 index dd4aceff9..000000000 Binary files a/medtool/doc/user/doxygen/figures/IndirectIndex.jpg and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/MED.png b/medtool/doc/user/doxygen/figures/MED.png deleted file mode 100644 index 6ba6047e0..000000000 Binary files a/medtool/doc/user/doxygen/figures/MED.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.eps b/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.eps deleted file mode 100644 index 5a8694c83..000000000 --- a/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.eps +++ /dev/null @@ -1,577 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Title: MEDCouplingUMeshConn.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5d -%%CreationDate: Wed Jul 4 16:48:48 2012 -%%For: geay@is210377 (Anthony GEAY - SFME/LGLS) -%%BoundingBox: 0 0 866 380 -%Magnification: 1.0000 -%%EndComments -%%BeginProlog -/MyAppDict 100 dict dup begin def -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end - -% crosshatch45 -<< - /PatternType 1 - /PaintType 2 - /TilingType 2 - /BBox [-1 -1 9 9] - /XStep 8 - /YStep 8 - /PaintProc - { - pop - newpath - 1 setlinewidth - -1 9 moveto - 9 -1 lineto - stroke - -1 -1 moveto - 9 9 lineto - stroke - } bind - ->> - -matrix -makepattern -/P6 exch def - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/reencdict 12 dict def /ReEncode { reencdict begin -/newcodesandnames exch def /newfontname exch def /basefontname exch def -/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def -basefontdict { exch dup /FID ne { dup /Encoding eq -{ exch dup length array copy newfont 3 1 roll put } -{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall -newfont /FontName newfontname put newcodesandnames aload pop -128 1 255 { newfont /Encoding get exch /.notdef put } for -newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat -newfontname newfont definefont pop end } def -/isovec [ -8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde -8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis -8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron -8#220 /dotlessi 8#230 /oe 8#231 /OE -8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling -8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis -8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot -8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus -8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph -8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine -8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf -8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute -8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring -8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute -8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute -8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve -8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply -8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex -8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave -8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring -8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute -8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute -8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve -8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide -8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex -8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def -/Times-Roman /Times-Roman-iso isovec ReEncode -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -/pageheader { -save -newpath 0 380 moveto 0 0 lineto 866 0 lineto 866 380 lineto closepath clip newpath --26.1 467.2 translate -1 -1 scale -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06000 0.06000 sc -} bind def -/pagefooter { -$F2psEnd -restore -} bind def -%%EndProlog -pageheader -% -% Fig objects follow -% -% -% here starts figure with depth 50 -% Polyline -2 slj -0 slc -7.500 slw -n 751 3483 m 751 3482 l 751 3479 l 751 3475 l 752 3468 l 753 3460 l - 755 3450 l 758 3438 l 762 3426 l 767 3413 l 774 3401 l - 783 3388 l 795 3375 l 811 3363 l 830 3350 l 854 3338 l - 884 3327 l 919 3317 l 950 3310 l 982 3305 l 1012 3302 l - 1040 3300 l 1064 3299 l 1085 3300 l 1104 3303 l 1119 3305 l - 1132 3309 l 1145 3313 l 1156 3317 l 1168 3321 l 1180 3325 l - 1194 3329 l 1210 3332 l 1230 3334 l 1253 3335 l 1280 3335 l - 1311 3333 l 1345 3329 l 1383 3324 l 1421 3317 l 1466 3307 l - 1507 3295 l 1544 3283 l 1575 3271 l 1603 3258 l 1628 3245 l - 1650 3232 l 1670 3220 l 1689 3207 l 1705 3194 l 1719 3183 l - 1731 3173 l 1741 3164 l 1748 3157 l 1753 3153 l 1756 3150 l - - 1757 3149 l gs col0 s gr -% Polyline -n 2759 3483 m 2759 3482 l 2759 3479 l 2759 3475 l 2758 3468 l 2757 3460 l - 2755 3450 l 2753 3438 l 2749 3426 l 2744 3413 l 2737 3401 l - 2728 3388 l 2716 3375 l 2701 3363 l 2682 3350 l 2657 3338 l - 2628 3327 l 2593 3317 l 2562 3310 l 2530 3305 l 2500 3302 l - 2472 3300 l 2448 3299 l 2426 3300 l 2408 3303 l 2393 3305 l - 2379 3309 l 2367 3313 l 2355 3317 l 2344 3321 l 2331 3325 l - 2317 3329 l 2301 3332 l 2281 3334 l 2258 3335 l 2231 3335 l - 2200 3333 l 2166 3329 l 2128 3324 l 2090 3317 l 2045 3307 l - 2004 3295 l 1968 3283 l 1936 3271 l 1909 3258 l 1884 3245 l - 1862 3232 l 1842 3220 l 1824 3207 l 1808 3194 l 1794 3183 l - 1782 3173 l 1773 3164 l 1766 3157 l 1761 3153 l 1758 3150 l - - 1757 3149 l gs col0 s gr -% Polyline -n 2759 3483 m 2759 3482 l 2759 3481 l 2759 3479 l 2760 3475 l 2760 3470 l - 2761 3464 l 2763 3457 l 2765 3449 l 2768 3440 l 2772 3431 l - 2778 3422 l 2784 3413 l 2793 3403 l 2803 3394 l 2816 3384 l - 2832 3375 l 2851 3366 l 2874 3357 l 2901 3349 l 2933 3340 l - 2969 3333 l 3005 3327 l 3041 3323 l 3076 3320 l 3109 3318 l - 3138 3317 l 3164 3317 l 3187 3319 l 3206 3321 l 3223 3323 l - 3238 3326 l 3252 3330 l 3265 3333 l 3278 3337 l 3292 3340 l - 3308 3343 l 3326 3346 l 3347 3348 l 3371 3349 l 3399 3349 l - 3432 3348 l 3469 3347 l 3509 3343 l 3552 3339 l 3596 3333 l - 3647 3325 l 3694 3316 l 3736 3306 l 3774 3296 l 3807 3286 l - 3837 3275 l 3864 3265 l 3888 3254 l 3910 3244 l 3930 3233 l - 3949 3223 l 3965 3214 l 3979 3205 l 3991 3197 l 4001 3191 l - 4008 3187 l 4012 3184 l 4015 3182 l - 4016 3181 l gs col0 s gr -% Polyline -n 5269 3483 m 5269 3482 l 5269 3480 l 5269 3477 l 5268 3473 l 5268 3467 l - 5266 3459 l 5264 3451 l 5261 3441 l 5257 3431 l 5251 3421 l - 5244 3411 l 5234 3400 l 5222 3390 l 5207 3380 l 5188 3370 l - 5164 3360 l 5136 3350 l 5101 3341 l 5062 3333 l 5026 3327 l - 4990 3323 l 4954 3320 l 4922 3318 l 4892 3317 l 4866 3317 l - 4844 3319 l 4824 3321 l 4807 3323 l 4792 3326 l 4778 3330 l - 4764 3333 l 4751 3337 l 4737 3340 l 4721 3343 l 4703 3346 l - 4682 3348 l 4657 3349 l 4629 3349 l 4596 3348 l 4559 3347 l - 4519 3343 l 4476 3339 l 4432 3333 l 4381 3325 l 4334 3316 l - 4292 3306 l 4255 3296 l 4222 3286 l 4192 3275 l 4166 3265 l - 4142 3254 l 4120 3244 l 4100 3233 l 4082 3223 l 4066 3214 l - 4052 3205 l 4040 3197 l 4031 3191 l 4024 3187 l 4020 3184 l - 4017 3182 l - 4016 3181 l gs col0 s gr -% Polyline -n 8281 3483 m 8281 3482 l 8281 3481 l 8281 3479 l 8282 3475 l 8283 3470 l - 8284 3464 l 8286 3457 l 8288 3449 l 8292 3440 l 8297 3431 l - 8303 3422 l 8312 3413 l 8322 3403 l 8334 3394 l 8350 3384 l - 8368 3375 l 8391 3366 l 8419 3357 l 8452 3349 l 8490 3340 l - 8533 3333 l 8573 3328 l 8613 3323 l 8652 3320 l 8689 3318 l - 8723 3317 l 8753 3317 l 8780 3318 l 8803 3319 l 8824 3321 l - 8842 3324 l 8858 3327 l 8873 3330 l 8888 3333 l 8902 3336 l - 8918 3339 l 8935 3342 l 8954 3345 l 8976 3347 l 9001 3348 l - 9030 3349 l 9063 3349 l 9101 3348 l 9143 3346 l 9188 3343 l - 9236 3338 l 9285 3333 l 9341 3326 l 9393 3317 l 9440 3309 l - 9483 3299 l 9521 3290 l 9555 3281 l 9586 3271 l 9615 3262 l - 9641 3252 l 9665 3243 l 9687 3233 l 9707 3224 l 9725 3215 l - 9742 3207 l 9755 3200 l 9767 3194 l 9776 3189 l 9782 3185 l - 9787 3183 l 9789 3182 l - 9790 3181 l gs col0 s gr -% Polyline -n 11293 3483 m 11293 3482 l 11293 3481 l 11293 3479 l 11292 3475 l 11292 3470 l - 11291 3464 l 11289 3457 l 11286 3449 l 11283 3440 l 11278 3431 l - 11272 3422 l 11264 3413 l 11254 3403 l 11242 3394 l 11227 3384 l - 11208 3375 l 11185 3366 l 11158 3357 l 11125 3349 l 11087 3340 l - 11044 3333 l 11004 3328 l 10964 3323 l 10925 3320 l 10888 3318 l - 10854 3317 l 10823 3317 l 10796 3318 l 10773 3319 l 10752 3321 l - 10734 3324 l 10717 3327 l 10702 3330 l 10687 3333 l 10673 3336 l - 10657 3339 l 10640 3342 l 10621 3345 l 10599 3347 l 10573 3348 l - 10544 3349 l 10511 3349 l 10473 3348 l 10431 3346 l 10385 3343 l - 10338 3338 l 10289 3333 l 10233 3326 l 10182 3317 l 10135 3309 l - 10092 3299 l 10055 3290 l 10020 3281 l 9990 3271 l 9962 3262 l - 9936 3252 l 9912 3243 l 9891 3233 l 9871 3224 l 9853 3215 l - 9837 3207 l 9824 3200 l 9812 3194 l 9804 3189 l 9797 3185 l - 9793 3183 l 9791 3182 l - 9790 3181 l gs col0 s gr -/Times-Roman-iso ff 266.67 scf sf -4868 1675 m -gs 1 -1 sc (and) col0 sh gr -/Times-Roman-iso ff 266.67 scf sf -5370 1675 m -gs 1 -1 sc (nodal connectivity per cell) col2 sh gr -/Times-Roman-iso ff 266.67 scf sf -4265 1675 m -gs 1 -1 sc (Type) col3 sh gr -% Polyline -n 5269 3483 m 5269 3482 l 5269 3480 l 5269 3477 l 5270 3473 l 5271 3467 l - 5272 3459 l 5274 3451 l 5277 3441 l 5281 3431 l 5286 3421 l - 5292 3411 l 5300 3400 l 5311 3390 l 5324 3380 l 5340 3370 l - 5360 3360 l 5384 3350 l 5413 3341 l 5446 3333 l 5479 3327 l - 5512 3322 l 5544 3319 l 5573 3317 l 5598 3317 l 5620 3318 l - 5639 3320 l 5656 3323 l 5670 3326 l 5682 3329 l 5694 3333 l - 5706 3337 l 5719 3341 l 5734 3344 l 5751 3346 l 5772 3348 l - 5796 3349 l 5824 3349 l 5856 3347 l 5893 3344 l 5932 3339 l - 5972 3333 l 6019 3324 l 6062 3313 l 6101 3302 l 6134 3291 l - 6163 3280 l 6190 3268 l 6213 3257 l 6234 3245 l 6253 3233 l - 6270 3222 l 6285 3212 l 6298 3202 l 6308 3195 l 6316 3189 l - 6321 3184 l 6324 3182 l - 6325 3181 l gs col0 s gr -% Polyline -n 7378 3483 m 7378 3482 l 7378 3480 l 7378 3477 l 7377 3473 l 7377 3467 l - 7375 3459 l 7374 3451 l 7371 3441 l 7367 3431 l 7363 3421 l - 7356 3411 l 7348 3400 l 7338 3390 l 7325 3380 l 7309 3370 l - 7289 3360 l 7265 3350 l 7236 3341 l 7203 3333 l 7170 3327 l - 7137 3322 l 7105 3319 l 7076 3317 l 7050 3317 l 7028 3318 l - 7009 3320 l 6993 3323 l 6978 3326 l 6966 3329 l 6954 3333 l - 6941 3337 l 6928 3341 l 6913 3344 l 6896 3346 l 6876 3348 l - 6852 3349 l 6823 3349 l 6791 3347 l 6754 3344 l 6715 3339 l - 6675 3333 l 6628 3324 l 6585 3313 l 6547 3302 l 6514 3291 l - 6484 3280 l 6458 3268 l 6435 3257 l 6415 3245 l 6396 3233 l - 6379 3222 l 6364 3212 l 6352 3202 l 6342 3195 l 6334 3189 l - 6329 3184 l 6326 3182 l - 6325 3181 l gs col0 s gr -% Polyline -0 slj -15.000 slw -n 751 3583 m 1253 3583 l 1253 4085 l 751 4085 l - cp gs col3 1.00 shd ef gr gs col0 s gr -% Polyline -n 1253 3583 m 1755 3583 l 1755 4085 l 1253 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 1755 3583 m 2257 3583 l 2257 4085 l 1755 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 2257 3583 m 2759 3583 l 2759 4085 l 2257 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 2759 3583 m 3261 3583 l 3261 4085 l 2759 4085 l - cp gs col3 1.00 shd ef gr gs col0 s gr -% Polyline -n 3261 3583 m 3763 3583 l 3763 4085 l 3261 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 3763 3583 m 4265 3583 l 4265 4085 l 3763 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 4265 3583 m 4767 3583 l 4767 4085 l 4265 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 4767 3583 m 5269 3583 l 5269 4085 l 4767 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 5269 3583 m 5771 3583 l 5771 4085 l 5269 4085 l - cp gs col3 1.00 shd ef gr gs col0 s gr -% Polyline -n 5771 3583 m 6273 3583 l 6273 4085 l 5771 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 6273 3583 m 6775 3583 l 6775 4085 l 6273 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline - [45] 0 sd -n 6775 3583 m - 8281 3583 l gs col0 s gr [] 0 sd -% Polyline - [45] 0 sd -n 6775 4085 m - 8281 4085 l gs col0 s gr [] 0 sd -% Polyline -n 8281 3583 m 8783 3583 l 8783 4085 l 8281 4085 l - cp gs col3 1.00 shd ef gr gs col0 s gr -% Polyline -n 8783 3583 m 9285 3583 l 9285 4085 l 8783 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 9285 3583 m 9787 3583 l 9787 4085 l 9285 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 9787 3583 m 10289 3583 l 10289 4085 l 9787 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 10289 3583 m 10791 3583 l 10791 4085 l 10289 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 10791 3583 m 11293 3583 l 11293 4085 l 10791 4085 l - cp gs col2 1.00 shd ef gr gs col0 s gr -% Polyline -n 751 6495 m 1253 6495 l 1253 6997 l 751 6997 l - cp gs col0 s gr -% Polyline -gs clippath -1012 4356 m 1012 4170 l 891 4170 l 891 4356 l 891 4356 l 952 4196 l 1012 4356 l cp -eoclip -n 952 6394 m - 952 4185 l gs col5 s gr gr - -% arrowhead -7.500 slw -n 1012 4356 m 952 4196 l 891 4356 l 1012 4356 l cp gs col5 1.00 shd ef gr col5 s -% Polyline -15.000 slw -n 1253 6495 m 1755 6495 l 1755 6997 l 1253 6997 l - cp gs col0 s gr -% Polyline -n 1755 6495 m 2257 6495 l 2257 6997 l 1755 6997 l - cp gs col0 s gr -% Polyline -n 2257 6495 m 2759 6495 l 2759 6997 l 2257 6997 l - cp gs col0 s gr -% Polyline - [45] 0 sd -n 2759 6495 m - 4265 6495 l gs col0 s gr [] 0 sd -% Polyline - [45] 0 sd -n 2759 6997 m - 4265 6997 l gs col0 s gr [] 0 sd -% Polyline -n 4265 6495 m 4767 6495 l 4767 6997 l 4265 6997 l - cp gs col0 s gr -% Polyline -n 4767 6495 m 5269 6495 l 5269 6997 l 4767 6997 l - cp gs col0 s gr -% Polyline -gs clippath -3013 4360 m 3118 4206 l 3018 4138 l 2913 4292 l 2913 4292 l 3054 4194 l 3013 4360 l cp -eoclip -n 1554 6394 m - 3060 4185 l gs col5 s gr gr - -% arrowhead -7.500 slw -n 3013 4360 m 3054 4194 l 2913 4292 l 3013 4360 l cp gs col5 1.00 shd ef gr col5 s -% Polyline -15.000 slw -gs clippath -5457 4327 m 5614 4227 l 5550 4126 l 5393 4226 l 5393 4226 l 5561 4191 l 5457 4327 l cp -eoclip -n 2068 6402 m - 5570 4185 l gs col5 s gr gr - -% arrowhead -7.500 slw -n 5457 4327 m 5561 4191 l 5393 4226 l 5457 4327 l cp gs col5 1.00 shd ef gr col5 s -% Polyline -15.000 slw -gs clippath -8362 4322 m 8524 4229 l 8465 4125 l 8302 4217 l 8302 4217 l 8472 4191 l 8362 4322 l cp -eoclip -n 4577 6401 m - 8482 4185 l gs col5 s gr gr - -% arrowhead -7.500 slw -n 8362 4322 m 8472 4191 l 8302 4217 l 8362 4322 l cp gs col5 1.00 shd ef gr col5 s -% Polyline -15.000 slw -gs clippath -11450 4298 m 11627 4237 l 11588 4123 l 11411 4184 l 11411 4184 l 11583 4189 l 11450 4298 l cp -eoclip -n 5173 6389 m - 11594 4185 l gs col5 s gr gr - -% arrowhead -7.500 slw -n 11450 4298 m 11583 4189 l 11411 4184 l 11450 4298 l cp gs col5 1.00 shd ef gr col5 s -% Polyline -15.000 slw -gs clippath -922 7237 m 736 7237 l 736 7358 l 922 7358 l 922 7358 l 762 7298 l 922 7237 l cp -5097 7358 m 5284 7358 l 5284 7237 l 5097 7237 l 5097 7237 l 5258 7298 l 5097 7358 l cp -eoclip -n 5269 7298 m - 751 7298 l gs col5 s gr gr - -% arrowhead -7.500 slw -n 5097 7358 m 5258 7298 l 5097 7237 l 5097 7358 l cp gs col5 1.00 shd ef gr col5 s -% arrowhead -n 922 7237 m 762 7298 l 922 7358 l 922 7237 l cp gs col5 1.00 shd ef gr col5 s -% Polyline -15.000 slw -gs clippath -922 2618 m 736 2618 l 736 2739 l 922 2739 l 922 2739 l 762 2679 l 922 2618 l cp -11121 2739 m 11308 2739 l 11308 2618 l 11121 2618 l 11121 2618 l 11282 2679 l 11121 2739 l cp -eoclip -n 11293 2679 m - 751 2679 l gs col0 s gr gr - -% arrowhead -7.500 slw -n 11121 2739 m 11282 2679 l 11121 2618 l 11121 2739 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 922 2618 m 762 2679 l 922 2739 l 922 2618 l cp gs 0.00 setgray ef gr col0 s -% Polyline -n 11293 3583 m 11795 3583 l 11795 4085 l 11293 4085 l - cp -% Fill with pattern background color -gs /DeviceRGB setcolorspace 1.00 1.00 1.00 setcolor fill gr - -% Fill with pattern pen color -gs /DeviceRGB setcolorspace 0.00 0.00 0.00 P6 setpattern fill gr - -gs col0 s gr -% Polyline -gs clippath -1021 3391 m 1021 3498 l 1082 3498 l 1082 3391 l 1082 3391 l 1052 3472 l 1021 3391 l cp -eoclip -n 1052 2177 m - 1052 3483 l gs col3 s gr gr - -% arrowhead -n 1021 3391 m 1052 3472 l 1082 3391 l 1021 3391 l cp gs col3 1.00 shd ef gr col3 s -% Polyline -gs clippath -3029 3391 m 3029 3498 l 3090 3498 l 3090 3391 l 3090 3391 l 3060 3472 l 3029 3391 l cp -eoclip -n 3060 2177 m - 3060 3483 l gs col3 s gr gr - -% arrowhead -n 3029 3391 m 3060 3472 l 3090 3391 l 3029 3391 l cp gs col3 1.00 shd ef gr col3 s -% Polyline -gs clippath -5539 3391 m 5539 3498 l 5600 3498 l 5600 3391 l 5600 3391 l 5570 3472 l 5539 3391 l cp -eoclip -n 5570 2177 m - 5570 3483 l gs col3 s gr gr - -% arrowhead -n 5539 3391 m 5570 3472 l 5600 3391 l 5539 3391 l cp gs col3 1.00 shd ef gr col3 s -% Polyline -gs clippath -8451 3391 m 8451 3498 l 8512 3498 l 8512 3391 l 8512 3391 l 8482 3472 l 8451 3391 l cp -eoclip -n 8482 2177 m - 8482 3483 l gs col3 s gr gr - -% arrowhead -n 8451 3391 m 8482 3472 l 8512 3391 l 8451 3391 l cp gs col3 1.00 shd ef gr col3 s -/Times-Roman-iso ff 266.67 scf sf -952 6796 m -gs 1 -1 sc (0) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -1454 6796 m -gs 1 -1 sc (4) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -1956 6796 m -gs 1 -1 sc (9) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -2458 6796 m -gs 1 -1 sc (...) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -4968 6796 m -gs 1 -1 sc (L) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -4366 6796 m -gs 1 -1 sc (L-6) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -1354 3081 m -gs 1 -1 sc (Cell #0) col0 sh gr -/Times-Roman-iso ff 266.67 scf sf -9385 3081 m -gs 1 -1 sc (Last Cell) col0 sh gr -/Times-Roman-iso ff 266.67 scf sf -3663 3081 m -gs 1 -1 sc (Cell #1) col0 sh gr -/Times-Roman-iso ff 266.67 scf sf -1052 7700 m -gs 1 -1 sc (Size of array = nbOfCells+1.) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -5570 6796 m -gs 1 -1 sc (Nodal connectivity index array.) col5 sh gr -/Times-Roman-iso ff 266.67 scf sf -11996 3884 m -gs 1 -1 sc (Nodal connectivity array.) col0 sh gr -/Times-Roman-iso ff 266.67 scf sf -4767 2579 m -gs 1 -1 sc (size of array = L.) col0 sh gr -/Times-Roman-iso ff 183.33 scf sf -450 2077 m -gs 1 -1 sc (Type of cell#0) col3 sh gr -/Times-Roman-iso ff 183.33 scf sf -2458 2077 m -gs 1 -1 sc (Type of cell#1) col3 sh gr -/Times-Roman-iso ff 183.33 scf sf -4968 2077 m -gs 1 -1 sc (Type of cell#2) col3 sh gr -/Times-Roman-iso ff 183.33 scf sf -7879 2077 m -gs 1 -1 sc (Type of last cell) col3 sh gr -/Times-Roman-iso ff 266.67 scf sf -5972 3081 m -gs 1 -1 sc (Cell #2) col0 sh gr -% here ends figure; -pagefooter -showpage -%%Trailer -end -%EOF diff --git a/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.fig b/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.fig deleted file mode 100644 index 9258298a6..000000000 --- a/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.fig +++ /dev/null @@ -1,159 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5b -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 450 1575 14807 7800 -6 751 3149 2759 3483 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 751 3483 919 3317 1421 3317 1757 3149 - 0.000 -1.000 -1.000 0.000 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 2759 3483 2593 3317 2090 3317 1757 3149 - 0.000 -1.000 -1.000 0.000 --6 -6 2759 3181 5269 3483 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 2759 3483 2969 3333 3596 3333 4016 3181 - 0.000 -1.000 -1.000 0.000 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 5269 3483 5062 3333 4432 3333 4016 3181 - 0.000 -1.000 -1.000 0.000 --6 -6 8281 3181 11293 3483 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 8281 3483 8533 3333 9285 3333 9790 3181 - 0.000 -1.000 -1.000 0.000 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 11293 3483 11044 3333 10289 3333 9790 3181 - 0.000 -1.000 -1.000 0.000 --6 -6 4265 1575 8381 1875 -4 0 0 50 -1 0 16 0.0000 4 181 402 4868 1675 and\001 -4 0 2 50 -1 0 16 0.0000 4 241 2932 5370 1675 nodal connectivity per cell\001 -4 0 3 50 -1 0 16 0.0000 4 241 562 4265 1675 Type\001 --6 -6 5269 3181 7378 3483 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 5269 3483 5446 3333 5972 3333 6325 3181 - 0.000 -1.000 -1.000 0.000 -3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 4 - 7378 3483 7203 3333 6675 3333 6325 3181 - 0.000 -1.000 -1.000 0.000 --6 -2 2 0 2 0 3 50 -1 20 0.000 0 0 -1 0 0 5 - 751 3583 1253 3583 1253 4085 751 4085 751 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 1253 3583 1755 3583 1755 4085 1253 4085 1253 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 1755 3583 2257 3583 2257 4085 1755 4085 1755 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 2257 3583 2759 3583 2759 4085 2257 4085 2257 3583 -2 2 0 2 0 3 50 -1 20 0.000 0 0 -1 0 0 5 - 2759 3583 3261 3583 3261 4085 2759 4085 2759 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 3261 3583 3763 3583 3763 4085 3261 4085 3261 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 3763 3583 4265 3583 4265 4085 3763 4085 3763 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 4265 3583 4767 3583 4767 4085 4265 4085 4265 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 4767 3583 5269 3583 5269 4085 4767 4085 4767 3583 -2 2 0 2 0 3 50 -1 20 0.000 0 0 -1 0 0 5 - 5269 3583 5771 3583 5771 4085 5269 4085 5269 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 5771 3583 6273 3583 6273 4085 5771 4085 5771 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 6273 3583 6775 3583 6775 4085 6273 4085 6273 3583 -2 1 1 2 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 - 6775 3583 8281 3583 -2 1 1 2 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 - 6775 4085 8281 4085 -2 2 0 2 0 3 50 -1 20 0.000 0 0 -1 0 0 5 - 8281 3583 8783 3583 8783 4085 8281 4085 8281 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 8783 3583 9285 3583 9285 4085 8783 4085 8783 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 9285 3583 9787 3583 9787 4085 9285 4085 9285 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 9787 3583 10289 3583 10289 4085 9787 4085 9787 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 10289 3583 10791 3583 10791 4085 10289 4085 10289 3583 -2 2 0 2 0 2 50 -1 20 0.000 0 0 -1 0 0 5 - 10791 3583 11293 3583 11293 4085 10791 4085 10791 3583 -2 2 0 2 0 3 50 -1 -1 0.000 0 0 -1 0 0 5 - 751 6495 1253 6495 1253 6997 751 6997 751 6495 -2 1 0 2 5 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 120.48 160.64 - 952 6394 952 4185 -2 2 0 2 0 3 50 -1 -1 0.000 0 0 -1 0 0 5 - 1253 6495 1755 6495 1755 6997 1253 6997 1253 6495 -2 2 0 2 0 3 50 -1 -1 0.000 0 0 -1 0 0 5 - 1755 6495 2257 6495 2257 6997 1755 6997 1755 6495 -2 2 0 2 0 3 50 -1 -1 0.000 0 0 -1 0 0 5 - 2257 6495 2759 6495 2759 6997 2257 6997 2257 6495 -2 1 1 2 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 - 2759 6495 4265 6495 -2 1 1 2 0 7 50 -1 -1 3.000 0 0 -1 0 0 2 - 2759 6997 4265 6997 -2 2 0 2 0 3 50 -1 -1 0.000 0 0 -1 0 0 5 - 4265 6495 4767 6495 4767 6997 4265 6997 4265 6495 -2 2 0 2 0 3 50 -1 -1 0.000 0 0 -1 0 0 5 - 4767 6495 5269 6495 5269 6997 4767 6997 4767 6495 -2 1 0 2 5 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 120.48 160.64 - 1554 6394 3060 4185 -2 1 0 2 5 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 120.48 160.64 - 2068 6402 5570 4185 -2 1 0 2 5 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 120.48 160.64 - 4577 6401 8482 4185 -2 1 0 2 5 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 120.48 160.64 - 5173 6389 11594 4185 -2 1 0 2 5 7 50 -1 -1 0.000 0 0 -1 1 1 2 - 1 1 1.00 120.48 160.64 - 1 1 1.00 120.48 160.64 - 5269 7298 751 7298 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 - 1 1 1.00 120.48 160.64 - 1 1 1.00 120.48 160.64 - 11293 2679 751 2679 -2 2 0 1 0 7 50 -1 46 0.000 0 0 -1 0 0 5 - 11293 3583 11795 3583 11795 4085 11293 4085 11293 3583 -2 1 0 1 3 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.24 80.32 - 1052 2177 1052 3483 -2 1 0 1 3 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.24 80.32 - 3060 2177 3060 3483 -2 1 0 1 3 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.24 80.32 - 5570 2177 5570 3483 -2 1 0 1 3 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.24 80.32 - 8482 2177 8482 3483 -4 0 5 50 -1 0 16 0.0000 4 181 141 952 6796 0\001 -4 0 5 50 -1 0 16 0.0000 4 181 141 1454 6796 4\001 -4 0 5 50 -1 0 16 0.0000 4 181 141 1956 6796 9\001 -4 0 5 50 -1 0 16 0.0000 4 20 181 2458 6796 ...\001 -4 0 5 50 -1 0 16 0.0000 4 181 161 4968 6796 L\001 -4 0 5 50 -1 0 16 0.0000 4 181 382 4366 6796 L-6\001 -4 0 0 50 -1 0 16 0.0000 4 181 803 1354 3081 Cell #0\001 -4 0 0 50 -1 0 16 0.0000 4 181 984 9385 3081 Last Cell\001 -4 0 0 50 -1 0 16 0.0000 4 181 803 3663 3081 Cell #1\001 -4 0 5 50 -1 0 16 0.0000 4 241 3052 1052 7700 Size of array = nbOfCells+1.\001 -4 0 5 50 -1 0 16 0.0000 4 241 3454 5570 6796 Nodal connectivity index array.\001 -4 0 0 50 -1 0 16 0.0000 4 241 2771 11996 3884 Nodal connectivity array.\001 -4 0 0 50 -1 0 16 0.0000 4 241 1787 4767 2579 size of array = L.\001 -4 0 3 50 -1 0 11 0.0000 4 160 1124 450 2077 Type of cell#0\001 -4 0 3 50 -1 0 11 0.0000 4 160 1124 2458 2077 Type of cell#1\001 -4 0 3 50 -1 0 11 0.0000 4 160 1124 4968 2077 Type of cell#2\001 -4 0 3 50 -1 0 11 0.0000 4 160 1245 7879 2077 Type of last cell\001 -4 0 0 50 -1 0 16 0.0000 4 181 803 5972 3081 Cell #2\001 --6 diff --git a/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.png b/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.png deleted file mode 100644 index 95ec95024..000000000 Binary files a/medtool/doc/user/doxygen/figures/MEDCouplingUMeshConn.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/MEDFileConcepts.fig b/medtool/doc/user/doxygen/figures/MEDFileConcepts.fig deleted file mode 100644 index 3dbd216fa..000000000 --- a/medtool/doc/user/doxygen/figures/MEDFileConcepts.fig +++ /dev/null @@ -1,85 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5b -Landscape -Center -Inches -Letter -110.00 -Single --2 -1200 2 -6 675 675 3075 4650 -2 2 0 1 0 2 50 -1 30 0.000 0 0 -1 0 0 5 - 675 675 3075 675 3075 4650 675 4650 675 675 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 675 1275 3075 1275 -4 0 0 50 -1 0 16 0.0000 4 225 975 900 1650 (1) name\001 -4 0 0 50 -1 0 16 0.0000 4 225 1635 900 1950 (1) coordinates\001 -4 0 0 50 -1 0 16 0.0000 4 225 1185 1275 2250 (?) fam ids\001 -4 0 0 50 -1 0 16 0.0000 4 225 1305 1275 2550 (?) numbers\001 -4 0 0 50 -1 0 16 0.0000 4 240 2010 900 2850 (*) geometric type\001 -4 0 0 50 -1 0 16 0.0000 4 240 1725 1275 3150 (1) connectivity\001 -4 0 0 50 -1 0 16 0.0000 4 225 1200 1275 3450 (1) fam ids\001 -4 0 0 50 -1 0 16 0.0000 4 225 1320 1275 3750 (1) numbers\001 -4 0 0 50 -1 0 16 0.0000 4 225 1275 900 4050 (+) families\001 -4 0 0 50 -1 0 16 0.0000 4 240 1125 900 4350 (*) groups\001 -4 0 0 50 -1 14 24 0.0000 4 240 960 1425 1125 MESH\001 --6 -6 9450 675 11625 2100 -2 2 0 1 0 6 50 -1 30 0.000 0 0 -1 0 0 5 - 9450 675 11625 675 11625 2100 9450 2100 9450 675 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 9450 1200 11625 1200 -4 0 0 50 -1 0 16 0.0000 4 225 975 9825 1650 (1) name\001 -4 0 0 50 -1 0 16 0.0000 4 225 705 9825 1950 (1) ids\001 -4 0 0 50 -1 14 24 0.0000 4 240 1680 9750 1050 PROFILE\001 --6 -6 9450 2550 12525 4875 -2 2 0 1 0 29 50 -1 28 0.000 0 0 -1 0 0 5 - 9450 2550 12525 2550 12525 4875 9450 4875 9450 2550 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 9450 3150 12525 3150 -4 0 0 50 -1 0 16 0.0000 4 225 975 9825 3525 (1) name\001 -4 0 0 50 -1 0 16 0.0000 4 225 1515 9825 3825 (1) dimension\001 -4 0 0 50 -1 0 16 0.0000 4 240 2250 9825 4125 (1) number of points\001 -4 0 0 50 -1 0 16 0.0000 4 225 1860 9825 4425 (1) reference cell\001 -4 0 0 50 -1 0 16 0.0000 4 240 1230 9825 4725 (1) weights\001 -4 0 0 50 -1 14 24 0.0000 4 240 2880 9525 2925 LOCALIZATION\001 --6 -6 4425 675 8025 6000 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4425 1200 8025 1200 -2 2 0 1 0 3 50 -1 30 0.000 0 0 -1 0 0 5 - 4425 675 8025 675 8025 6000 4425 6000 4425 675 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 4425 1275 8025 1275 -4 0 0 50 -1 0 16 0.0000 4 225 975 4650 1650 (1) name\001 -4 0 0 50 -1 0 16 0.0000 4 240 2250 5025 2550 (1) component name\001 -4 0 0 50 -1 0 16 0.0000 4 225 1470 5025 2850 (1) unit name\001 -4 0 0 50 -1 0 16 0.0000 4 240 1485 4650 3150 (*) time steps\001 -4 0 0 50 -1 0 16 0.0000 4 225 1290 5025 3450 (1) iteration\001 -4 0 0 50 -1 0 16 0.0000 4 225 960 5025 3750 (1) order\001 -4 0 0 50 -1 0 16 0.0000 4 225 870 5025 4050 (1) time\001 -4 0 0 50 -1 0 16 0.0000 4 240 2430 5025 4350 (*) per geometric type\001 -4 0 0 50 -1 0 16 0.0000 4 240 2010 5325 4650 (1) geometric type\001 -4 0 0 50 -1 0 16 0.0000 4 240 2280 5325 4950 (+) per discretization\001 -4 0 0 50 -1 0 16 0.0000 4 225 1080 5700 5250 (1) values\001 -4 0 0 50 -1 14 24 0.0000 4 240 1200 5550 1125 FIELD\001 -4 0 0 50 -1 0 16 0.0000 4 240 2565 4650 2250 (+) info on components\001 -4 0 2 10 -1 0 16 0.0000 4 225 1620 4650 1950 (1) mesh name\001 -4 0 6 10 -1 0 16 0.0000 4 240 1755 5700 5550 (?) profile name\001 -4 0 29 10 -1 0 16 0.0000 4 225 2295 5700 5850 (?) localization name\001 --6 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 1 - 8850 4200 -2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 1 1 4 - 1 1 2.00 120.00 120.00 - 1 1 2.00 120.00 120.00 - 4500 1875 3825 1875 3825 1575 2025 1575 -2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 1 1 4 - 1 1 2.00 120.00 120.00 - 1 1 2.00 120.00 120.00 - 9675 1575 8550 1575 8550 5475 7575 5475 -2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 1 1 4 - 1 1 2.00 120.00 120.00 - 1 1 2.00 120.00 120.00 - 9825 3450 9000 3450 9000 5775 8025 5775 diff --git a/medtool/doc/user/doxygen/figures/MEDFileConcepts.png b/medtool/doc/user/doxygen/figures/MEDFileConcepts.png deleted file mode 100644 index 466ce594b..000000000 Binary files a/medtool/doc/user/doxygen/figures/MEDFileConcepts.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/MED_small.eps b/medtool/doc/user/doxygen/figures/MED_small.eps deleted file mode 100644 index bf0b75825..000000000 --- a/medtool/doc/user/doxygen/figures/MED_small.eps +++ /dev/null @@ -1,13779 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: (ImageMagick) -%%Title: (MED_small.eps) -%%CreationDate: (Fri Nov 30 12:59:05 2007) -%%BoundingBox: 0 0 500 324 -%%HiResBoundingBox: 0 0 500 324 -%%DocumentData: Clean7Bit -%%LanguageLevel: 1 -%%Pages: 1 -%%EndComments - -%%BeginDefaults -%%EndDefaults - -%%BeginProlog -% -% Display a color image. The image is displayed in color on -% Postscript viewers or printers that support color, otherwise -% it is displayed as grayscale. -% -/DirectClassPacket -{ - % - % Get a DirectClass packet. - % - % Parameters: - % red. - % green. - % blue. - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/DirectClassImage -{ - % - % Display a DirectClass image. - % - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { DirectClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayDirectClassPacket } image - } ifelse -} bind def - -/GrayDirectClassPacket -{ - % - % Get a DirectClass packet; convert to grayscale. - % - % Parameters: - % red - % green - % blue - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/GrayPseudoClassPacket -{ - % - % Get a PseudoClass packet; convert to grayscale. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassPacket -{ - % - % Get a PseudoClass packet. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassImage -{ - % - % Display a PseudoClass image. - % - % Parameters: - % class: 0-PseudoClass or 1-Grayscale. - % - currentfile buffer readline pop - token pop /class exch def pop - class 0 gt - { - currentfile buffer readline pop - token pop /depth exch def pop - /grays columns 8 add depth sub depth mul 8 idiv string def - columns rows depth - [ - columns 0 0 - rows neg 0 rows - ] - { currentfile grays readhexstring pop } image - } - { - % - % Parameters: - % colors: number of colors in the colormap. - % colormap: red, green, blue color packets. - % - currentfile buffer readline pop - token pop /colors exch def pop - /colors colors 3 mul def - /colormap colors string def - currentfile colormap readhexstring pop pop - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { PseudoClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayPseudoClassPacket } image - } ifelse - } ifelse -} bind def - -/DisplayImage -{ - % - % Display a DirectClass or PseudoClass image. - % - % Parameters: - % x & y translation. - % x & y scale. - % label pointsize. - % image label. - % image columns & rows. - % class: 0-DirectClass or 1-PseudoClass. - % compression: 0-none or 1-RunlengthEncoded. - % hex color packets. - % - gsave - /buffer 512 string def - /byte 1 string def - /color_packet 3 string def - /pixels 768 string def - - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - x y translate - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - currentfile buffer readline pop - token pop /pointsize exch def pop - /Times-Roman findfont pointsize scalefont setfont - x y scale - currentfile buffer readline pop - token pop /columns exch def - token pop /rows exch def pop - currentfile buffer readline pop - token pop /class exch def pop - currentfile buffer readline pop - token pop /compression exch def pop - class 0 gt { PseudoClassImage } { DirectClassImage } ifelse - grestore -} bind def -%%EndProlog -%%Page: 1 1 -%%PageBoundingBox: 0 0 500 324 -userdict begin -DisplayImage -0 0 -500 324 -12.000000 -500 324 -0 -0 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000030000000000370000 -760000000000010000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000030000000000350000780000050000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000050000 -0000003700007A0000010000010000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000030000000000340000790000030000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000080000630000720000070000000000010000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000100000000000900007500005D0000 -070000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000100000000000600007C00002E0000000000030000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000010000020000 -7C0000310000000000040000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000100000000000700007D0000310000000000030000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000010000 -0000000700007C00002D0000000000030000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000100000300007B0000300000000000 -030000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000100000000000600007C0000320000000000030000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000100000000000700007D0000 -2F0000000000030000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000200000000000500007C00002F0000000000030000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000020000000000 -0400007C0000320000000000030000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000010101040404040404040404000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000200000000002C00007B0000310000000000030000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000020202010102 -000000000000000000000000000000000000000000000000000000010102030302020202 -020202020202000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0300000000004600008B0000280000000000030000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000101010303030202020000002B2C2B7273716565646E6F6D -0D0E0D000000000100000000000000000000000000000000000000000000030303030304 -030303030303040304020202000000010101010101010101000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000400000000004B00006A0000000000 -000000020000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000010101040404 -0000000000003030287E7F8D827DB2B2ADD18170825A4F9E938FB0A29DA19F9AA49F999F -A39FB664667C42443B494B48484946484A46080807000000000000000000000000000000 -000000000000000000000000010101050505040404040404040404040404000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000400000000004F00006A0000000000040000010000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000303030000000000000304032527248685868682B54A3C7B -0D002B6453706F687D09001F3018442E17432D1643311941200B4B5B4E8B8F8194847792 -867893867893908D93929193929094908E909998A34A4C551D1F18262825242522272924 -1A1A10000000000000000000000000000000000000000000000000000000010101030303 -030303030303030303030303000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000300000000004F0000 -680000000000030000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000020202010102 -020200020300242523838284978DA0503B621E073B260E3529133C4B395D8F859B2F1943 -2C16402C17402C17402C16402F193E230B3118012F1A03301A022F1A022F3F2953453059 -442E584731543723667067A4A298A2988EA39990A19B91AB8281B8767770787879777777 -7A7B7A6D6E70080A08070805070806080906040504000000000000000000000000000000 -030303030303030203030303020203010102010101010101010101010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000300000000004C0000690000000000020000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000003030303030300000011110D5C5E609897B5948A98533F67 -1D0533250F392F19412E1843301B441C0431998FA338244B29123D2D17412C17412D1740 -2C16412E1943301B44301A44301A44301A4428123C26103B27113B26103B281238220A31 -1B03321D05321E06331700302E1A586653755F4C70604D73604C6C584DA19D99ACA19BA5 -9F99A5A6A0AC8682884F514D575855555653595B5851524B000000000000000000000000 -000000000000000000000000000000000000020202050505040404040404040404030303 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000040000 -0000004E00006A0000000000020000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000020202040404010101 -0000001415115B5D609292B3675C9A23104C250D38210B37301B442D17412C16412D1741 -2E1842240D396758777D708A1F08342F1A432C16402D17412D17412D17412D17412D1741 -2D17412C17412D17412D17412D17412D17412C17412F1944301B44301B44301A44311C44 -2C163B1F0834200A35200935200935210A3327103C27103D29113E210937463158847592 -7E6E8C796989766581584FA3A8A8B0B9BAB7A09EA3A3A1A19493A744474E2D2F28323431 -30322F363831191911000000010100000000000000000000000000000000000000000000 -000000030303040404040404040404040404010101000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000300000000004F0000690000000000030000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000202020101020000000101010809076263629A949B6B5E9324114E -1E062F30193E2E18422E18422C16402D16412D16412D17412D1741240E3948355A988DA2 -1D0633301B442D17412D17412D17412D17412D17412D16412D16412D17412D17412D1741 -2D17412D16412D16412D16412D17412D17412D17412C16402D17422E18422E18422E1842 -2E18422E18432E18422E18412E1842311C4429123D16012C0C022326103A432F538D839D -ACA0B47C6D8A432D58B1A5B12C1B677C71A0998D9E92869E94889A9085AE7F7FB183837B -83838581818189898966676E0B0C0913141111131012130E141404010100000000000000 -000000000000000001010101010101010101010002010102020202020202020202020202 -020202000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000300000000004D0000680000000000020000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000010101040404010101 -0000004243406869679A94A071607F2E18441E052E2E183E2F1A432C16412D17402C1741 -2D16412D16412D16412D16412D17412F1A43200935948A9F513F62220B372E18422D1741 -2D17412D17412D16412D16412D16412D16412D17412D17412D16412D16412D16412D1641 -2D16412D17412D17412D16412D16412D16412D16412D17412C16402D17412D1741301B44 -2E1842200835260F3A3C2950897C94AAA0B192869C544263331E451C053119012E7C708A -6F61770D001F1C05331B03301C04301400303522585B476A544067564368503C65574EA2 -A49DA99E96A6A098A49E97AF8C8ED966676B62635F6364626162606B6C671F201E000000 -010101000000000000000000000000000000000000000000000000040404040404040404 -040404040405030303000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000600000000004C00006A0000 -000000020000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000202020303030000000404033739378B8C9D7670AB6D5C832C1640 -1F07342B153F301A442C16412D17402C16412D17412D17412D16412D16412D16412D1641 -2C1640301A441C043281758D685977220A372E18422D17412D17412D17412D16412D1641 -2D16412D16412D17412D17412D16412D16412D16412D16412D16412D17412D17412D1641 -2D16412D16412D17412C1640301B442A133E260F3A1C053227103B655674A49BAD9F95A9 -675876250E39210A36220B372A143E301A442F194320093581769063547429123D331D46 -301A44321C442A133A210A36230C37220C37230C37240C33220A38220A38230B3620093D -1606636B5B7F74648272618274637E5751C78682B2A4A09FA19DA79994989593B75F5F82 -282923393A392E2F2F3F413A3A3A2D000000000000000000000000000000000000000000 -000000000000000000000000040404040404040404040404040404010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000100000300000000004F00006A0000000000030000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000010101020202000000000000 -0505043435328F8E918D829937286C2008351B04312D18412F19422D17412C16402D1741 -2D16412D17412D17412D17412D17412D16412D16412D16412D17412C16402B153F331D46 -A59BAD260F3A2E18422D17412D17412D17412D16412D16412D16412D17412D17412D1741 -2D17412D16412D16412D16412D17412D17412D17412C16402D1741301A432D17412D1741 -1A023037224A4A365A94889EA095A8877B9338234B2A143E1E06332F19432F19432E1841 -2D17412C16402D17412D1741250E3AB2A9B92C164029133E2E18422C16402D17412E1841 -2E18412E18412D18412E18432F1A432F19432F1943301A41321B391E07321C04311E0733 -2009341B04332C15412B13401C0334442E4F433587C1C1FBFFFFFFBAB4C5F8F6F2988FBF -7170D68E8D8C8C8B8E8D8B8C8788968C8EA76D6F7E1618131D1F1D1E1F1721200F1F1F0F -020201000000000000000000000000000000000000000000000001000001000001020202 -030303030303030303030303010101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000020000000000140000 -8D0000600000000000030000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000303030101020303010000003839378B8A8E90849B442E571C0531 -2A12372F19422F19432D17412C16402D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412A133E38234BA499AC220B372F19432C1640 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2C16402D17412D17412F1A432B153F1B033129133D2E19427769859D92A5A097A9544264 -3E29501B02302A143E2D17412F19432D17412C16402D17412D17412D17412C16402E1842 -27103C4E3B5E94879D28113C2A133E2D18412C16402D17412D17412D17412D17412D1741 -2D17412D17412C16402D17412D1743301B44341E4727103B1D063329133D29133D5C4B6B -8F839995899FACA3AA867887230C3949375A998FA10900271E0A484C375E4A355F4D3758 -3D2F892B23AB4C43A4A39AA69D93A19691B68789E58889DC7172776F706C70706F6D6E6F -77787A232523000000040503050500060500070700010100000000000000000000000000 -010101030303030304030304030304030303010101010101010101010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000100000000001300007F0000290000030000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000040404020202000000 -202018656772A2A1B6887B8E48335D1A033027113B301A442D17422C16402D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412F194220093583768E6858761E07342F19432C17402D17412D17412D1741 -2D17412D17412D17412D17412D17412C16402D17412C16402F19432D1741240D381E0633 -37224A6C5C7A8E839AAEA6B5736682331D4619012F250F3A28113C301B442D17412C1640 -2D17412D17412D17412D17412D17412D17412D17412C16402F19431F08345542648F8298 -2A133E2D18412D17412D17412D17412D17412C16402D17412C16402E1842311C4529133D -230C38240D391A0230503E61756682C3BDC9AEA7B6867890625171311B4417002F1F0837 -2C1640250E3990859C53416228103726103A250F39250F3A27103429112F260E311D0635 -1F07321B053F110059150357614F766A577765547D4F4AC24843CA8A86B2A9A5A698929B -8B8BBB8788C78A8AC94C4D5847484146474240413E57584A24241F000000010101000000 -000000000000000000000000000000000000020202050505040404040404040405030303 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000020000 -0000001700008200001C0000000000030000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000001010103030300000000000017191772726C8F8DB45B4E8D210C46260E37 -230D38311B452D17412D17412C16402D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412C1740301A431C0432 -6E607C7F718A1F07342F19432D17412D17412D17412D17412D17412D17412D17412C1640 -2D1741301A432E18422B153F2008352A133E503D60756681CCC7D1AAA1B2443157250E39 -210A362A143E311C452D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412C1640331D4614002A8C80976A5B791A022F301A432C1640 -2C16402E1842301B442E18422B143F230C3816002C3A254C4E3B5F6D5F7CADA6B58A7F96 -83758E695977250E39260F3A1D06332C1640311C452F1943311C4519012F8C7F975C4B6C -210A362F19422D17412D17412D17422C17432D1843301A43301A44311B41331C3A341D3D -240D372009351B04301D053017042A15002B1A01324C375943368A41379C8582D9F5F4FF -A399BAAFADE4E1E0F75957DE8381B798968F8E8EA98A8DAD9395B58E909221231F2C2D23 -2C2C1A30301E13130C000000000000000000000000000000000000000000000000000000 -000000030303030303030303030303020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000020000000000170000820000180000000000 -020000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0302036A696B9E96A5675476271143210934331C422F1943301A432E18422E18422E1842 -2D17412C16402D17412D17412D17412D17412D16412D16412D16412D17412D17412D1741 -2D17412D16412D16412D17412D17412D17412C16402E184227103BA499AC2F1A432B153F -2C16402D17412D17412D16412C16412D16402E18422E19422E18421B0431230C38321C45 -5F4F6F9C91A49E93A76B5B78311C451E0633250E3A2F19432E18422D17412C16402D1741 -2D16412D17412D17412D17412D17412D17412D16412D16412D17412D17412D17412D1741 -2D17412C16402F19432B153F8E849B4C3A5E27113C301A43311C45260F3B1A0230250E39 -321C45655473978DA1CFCAD4A399AC75678239254C2A143E17002D2109362E19422E1841 -2F19422D17412C16402D1741301B441B033190849B5C4A6B210A362E18422D16412D1641 -2D17412C16402E18422E18422E18422E18422F1A45240D3A1A0330240D383C284F341F48 -5240639A90A391879C978CA29D909B988C9347324A341F440B002584799657466906002D -2F194B462F532F2188291F9C271C989186AD9E929C8D87C18081E58383E97E7FA97B7B73 -7B7C7F77798180818A5C5D620304020E0E060E0D000F0F00060500000000000000000000 -000000010101040404030303040404020203030303020202010101010101020202010101 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000100000000001400008200001A0000000000020000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000101010000001111126D706BF0F5EA8A7E9315022A17032B -240E35251138220C36230A38230A39230A39230A39220A382E1842311B45301B44301B44 -311B442F19422D17412D17412D17412D17412D17412C16402D17412D16412D16412D1641 -2D17412D17412C16402E1942240D3990839A52406226103B2D18412D17412D17412D1741 -2D1741301B44230B3820093529123D72637F82768FADA4B5857A92422E5418002E230C38 -2A143E2F19432E18422C16402D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412E1842311B44301B44301B44301B44301B44301B44301A44311C4527113C1D0633 -200E35A59DAF250F3A210A3613002948355A72647F84778FB3ABBA85768F5847684B395C -1C0532240D392D17412F1942311B442F1A432D17412D17412D17412D17412D17412D1741 -301B441B033090849B574567210A362E19422D17412F1A43301B44311B44240D38200835 -230C3828113C1E07345442657E718A82748DA79DAFAAA1B293869C544264594869220B37 -1902311C043428113F230C394B385B9A90A3240D38341E432C163E26103C2A13332B1330 -2B14311B042F1C042F17023F1301500C004A3B296064506D56457D433CBE3D36BB5B54B6 -A9A1A19694C09092DB8D8FD9C4C6E06D6F66575956504F4955544E393934000000010101 -000000000000000000000000000000000000000000010101040404040404040404040405 -020202000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000020000000000150000820000 -1C0000000000020000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -040404000000575954FFF8FFA06AD7AA88CBB4A6C0B5A5C5B2A2C1B6A6C5A797B554465F -554861554860544760574A6225103919012F1C05311C05311A022F2109372A133F29113E -29123E29113E2F1943301B44301A44301A44301B442E18422C16402D17412D17412E1842 -210A37534264877B9218002E311B442E1942311B4429133D260F3A1D05325240626B5B78 -A69CAE7C6F89645473200935250E3929133D352048321C45301A44301B44301A44301B44 -2F194328123D27113C27113C27113C27113C27113C27113C28123D230C371B03311C0532 -1C04321C04321C04321C04321D063318002E4734595F4F6F4735598C7F9593879C6F617E -E2DFE5E7E4E9ADA4B45747670E002414012A10002716002C2109361F08341A022F210A36 -29123D27113C27113C27113C27113C27113C27113C2D1741341F47200935887A92695876 -250E392C164028123D1E07341C04321A02305341635948687E728CACA3B4AAA0B28A7F96 -766883675775200935250E3A230C38210A37220B372F1943311B44301A442E1842240D39 -503E61968CA01B0330301B442D17412D17412C16432C16432C1643301A44301B44311B41 -321C3C341D3E2912391F0835240E37260F33260F33250E36230A3417044D120169000057 -392D676F5B746A5E938B8DFF9092FF9899E8BFBFB7C9CBCACED0C99B9CBFA8AAB940423C -34352F3939293C3C2C1C1C1A000000000000000000000000000000000000000000000000 -000000030303040404040404040404030303000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000200000000001700008200001A0000000000020000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000040304000000585855B78BE5 -8E55C67A31C29150D28C4ACF8D4BCF8B48CE9355D2C09DE3BF9CE3BF9CE3BF9CE2C19DE5 -A393B19B90A49D91A89A8DA5A89EB06C60753120413C2C4B3A2A493B2B4A2009351A0231 -1C04321C04321A0230260F3B2F19432D17422E17422E18432B143F3C284F978A9F39244C -2D1841250E391B03303A254D4B395D9A8EA3968B9F83768E331D461D06331F0835311C45 -26103B1A02301B03311B03301B03301B03301B03301A02301E06333C274E422E54402D53 -412D53412D53412D53422F543A254C665776A298AB998EA29B90A49A8FA49B90A49C92A6 -9C91A5978BA18478919D93A6C2BCC7EDECEF9B91A4CBC4CF93889D887C93AFA6B6A9A0B2 -978CA19D92A69C91A59C91A59B90A4988CA1A89EB06D5C7A38234B432F54412D53412D53 -412D53412D53412E5329123D1B03311A0230220C379E95A816002C321D463A264D877A92 -9F95A99A8FA492869B9990A36656752F19433B274E2A133E19012F2009352F1A432E1942 -2E19422E18422E18422D17412C16402D17412D1841240D39503E60998EA21C0532301B44 -2D17412D16412D16412D17412C16402E18422F19422E19432F19442D17422D17422F1A43 -2009351B03321B03322009363E2A51473251402A43978A939B8F9E7F728CABA2B3A9A2B9 -5A4B71B2AABDFAFAFA968AA3A599A933288E6559999D919B8A80AD7676E48181E8CACAD6 -81807E8887897E808F92939F4749450B0C09161816191A0C0E0D05000000000000000000 -000000000000000001000001000000000002020202020202020202020202020202000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000010000000000 -160000820000180000000000020000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000010001000000190F249467C3B895DCA272D37933BF8241C3 -803EC2803EC27F3CC27730BF7830BF7830BF7830BF762EBE975AD49F64DA9E62D99A5DD7 -AB75E0D2BBE9BEA5D8C2A9DBC1A8DBC3A9DD897C957D72858075897D7287877D8F4B3C5A -200C3329153B2713392814392A153D0A00238C849749355B0E00265745687E708A968CA1 -9E94A8503E612008351B03312B153F2F1943301A44240D395441638B7F9682758E84768F -84768F84768F8578917C6E88A59CAEC7C2CC9A91A4A49BACA299ABA299ABA299ABA197AA -A9A1B17D718A473358503D604E3C5F503E614E3C5F412D534733586353728B7E9590859A -7C6E88311C451F083591869D23153815002B2C1540503D604E3B5F4E3B5F4E3B5F4E3B5F -4F3D60483459675876B4ADBB9E95A8A39AACA299ABA299ABA39AACA097A9B4ACBAC3BDC9 -6B5B797E708A8B7F96C4BEC98B7F96FAFAFBADA6B55F4E6D48355A503D611F0A35080020 -15022B1E05331C0431200835321D45321D46301A43301A43301A442E18422D17412D1741 -2D17412D17412D1741240D3949375B998FA21D0532311C452D17412E1942301B44301A43 -301B44230C381E06331F08341D063328113C2D174127103B70627E8A7D957A6C87AAA1B2 -C5BFCA9A90A5A69DB1A79FB24E3B605544654532572D17407768827A6A832F194219012E -16002D2B1332210A3019012E1902351300471200433E2A54554065523E66332AA45952B7 -B5ADB69A92A4A39AA38A88CBC0C2EC7E7F756162626768666D6E6B4F4F4E000000010101 -000000000000000000000000000000000000000000030303040404040304040404040404 -000000000000000000010101000000000000000000000000000000000000000000000000 -0000000000000000000000000000000200000000001200008200001B0000000000020000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000020102000000A99DB4823FC6A374D18442C67F3BC38342C58240C48341C58544C6 -8544C68544C68544C58544C67D3AC17C38BF7C38C07C39C07A36BF7931C07E37C47D36C4 -7D36C47C34C3A771DCB07FE2AE7CE0AF7DE0AE78E2B496D4BAABC8B9A7CBB8A7C9BFADD0 -9F90AF54485F877D8D9E94A5BEBCBFB9B5BE8E8298695A768E839790869AA49AADA69CB0 -A298ACA298ACA399ADB1AAB992869B69597870617E6D5D7B6B5B796B5B796B5B796B5B79 -6D5D7B351F481B04312109362008352008352008352008351F0835210A36260F3A27103B -1E063318002E210B366252719E95A793899F61507027103B230D392B153F2A143E3B274E -ACA4B527103C2E1842240D39240D39240D39240D39240D39240D39250E3A210A361C0431 -2109361F0835200935240D391C043217002D0F0025695977C2BAC7FBFCFCADA4B4B1A7B7 -7767835B4A6B968CA0A097A99F96A8A39AAC9B91A46858766A5A78675775685876665574 -240D391D05331F07341F07341E0733230C38250F3A250E3A250E3A250F3A311B4527113C -6251708D81971A023027113C260F3B2009351C05312008351C04315241636D5D7A5D4C6D -92869CC1BBC7A299ABACA4B4C1BAC66858766B5C796C5D7A321C461C0431210A361D0532 -1E0633100027635271AAA2B36F607D2E184227113C311B45311B442C17432E1943311B44 -311B43321C3E321C3F28113B230C37230D38270F31220A2E1C0432210A38230B34110050 -3A296974627E6D5C80715E7863569EBBB8DCA19D9E9E9AA49A959CACACCC888B89373834 -4647444446423F403E070707000000000000000000000000000000000000000000000000 -020202050505040404040404040404010101000000000000000000000000000000000000 -0300000000001700008200001B0000000000020000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000020102000000A99EB3 -8240C68D59C3BF9EE08545C68240C48341C58341C58341C58341C58341C58341C58240C4 -8341C58341C58341C58341C58342C58444C58443C58443C58443C58443C57A35BF7832BE -7833BE7933BE7731BD813DC68945CD8743CB8845CC843FCA965AD2C099E6B68DDEE2D1F2 -B88CE3DDCAEFFAF9FCE7E2EBA599B1A99EB54F415D42324F4535524738543C2B4B1B0231 -15022C0B00230B002215022C1F06351D05331E05341D05342008352D1841331E47321D46 -321C452F1A432F1A43301A44321D462E1942260F3B210936463257665776A69CAD83758E -35204829133E1F08342F1A432F19432D1741301A432009367D6E886A5A77240D39301A44 -2D17412D18412D18412D18412D18412D17412E1842321C45321D462F19432C16401D0532 -3A264D5D4C6DA79FB0877C947D6F8A422F5508001F6A5B786F617E120028321D462F1A43 -2F1A432A133E4430558C8097867991877A92877A92887B93A095A8A198AAA097A99F96A8 -A79FAF6656744431564D3A5D4E3B5F4B385C1F07340B00229A90A429163D351F484F3D60 -412D53756782B1A9B89C92A5A49BADD0CBD484768F8679928D819845325728123C301A43 -220B371D06331E07331D06332C1640331E472D184129123D4E3C5FA299AB7C6D87260F3B -1F08352D17412E18422C16402D17412D17412C17412D17402C16412C16412C16412D1741 -2D18412D18412D17432E1843301A432F1A432F1944331C3D2912371C05321D06321D0632 -1C0531220B37311A463019462D16403121718B7D9A897B948B7D977F708CBDB5C6ABABAB -88878A8F8E919391948F908E1E201C21221F20221F20221F080808000000000000000000 -0000000101010000000000000000000000000303030103030403032B03038203031A0202 -000000020000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000020103000000ABA0B48A4BCA712FB59866CA9F6CD2 -7932C08544C58240C48341C58340C58340C58340C58341C58341C58341C58340C58340C5 -8340C58340C58341C58341C58341C58240C48442C58443C58443C58443C58443C58241C4 -8140C38140C38140C38241C37F3DC27229BC9157CBE0D0EF9158CA7A34C0894AC7894AC9 -985AD69658D5BD9BDEC3A6DFC1A3DEC4A5E2B79CCF887E908C82968B8195958C9E5C4E6A -281539321F42301D40301E41230C391E06351E06341E0534210837301A44311B452D1741 -210A372F19434B385B948A9FA298AB83768F37234A1B04312B153F2D17412F19432D1741 -2C16402D17412C1640301A4319022FAAA1B2422E54230C382E18422C16402D17412C1640 -2D17412D1841301A44250E3A1B03312D17413C274E93889DD6D2DA897C9445325737224A -18002E29133D321C4528123DA79FAF38234A2B153F2C16402C16402D174128113C19012F -1B03301A03301A02301B0431412D534531564430554532573E2A5083758EA69DAF988DA2 -8B7F968D8198948A9F8C8097CBC5CF988EA3D2CED69A8FA49A8FA4ABA2B35F4E6E3D294F -4734592F1A4318002E1B033119012F27113C2D17412C16402E18422F19432F1942311B44 -2D17411E06332A143E7D6E889E94A748355A250E392C16402F19432D17412C16402D1741 -2D16412D16412D16412D17412D17412D17412D16412D16412D16412D16412D17412D1741 -2D17412C16412D17402C16412D18422F19432F19432F19432F19432E18422C163F2C163F -2C17402C14371A022F1A02301A033018002E230D3846315949345C4A355D422D56988BA3 -A39AAB9D93A5998FA1B1A9B9B6B5B65857596867696463646F6E6F191919000000040503 -0405030405030100000000004B00007A00000C0000000000050303020303030303030303 -030303020202010101010101010101010101010101000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000002010200000082758D813EC57E42BC722EB7AB83D69D68D17D39C28442C58240C4 -8340C58340C58340C58340C58341C58341C58340C58340C58340C58340C58341C58341C5 -8341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58341C58240C4 -8545C67B35C1BF9EE19A64D0C7A9E5803CC38240C4803DC37D3AC07E3BC17B34C17A33C2 -7B34C27830C08440C8AB76DFA872DEA974DEA66EDFB38ED8BFADD0BDA7D2BDA8D1C1ABD5 -7B6E86685D716C61766E647861556C1F09331A012F28123D6D5F789E93A791839C4C395E -15002C17012E220A38341F48311B44301B44301B44311B442F1A432C16402D17412E1842 -28113C4735598C82992D18412D17412D17412E1842321C4529123D230C381D05324F3C5F -766782A196A9A297AA635372412D531A023027113C2A143E311C452E18412E1842200936 -6A59777F718B1A0230311B442C16402C16402D1741301B44301A44301A44301B44301A44 -27113C27113C2B143F2B143F1F083516012D0D00242D1B41675876655573DBD7DEBCB5C2 -695A77B0A9B8321D451C05321E07341A0330230C3728113C260F3B2B153F311B44301A44 -301B442D18412C16402D17412D17412C16402F1943220B372B153F71637FA9A0B2695876 -16002D27113C2E18422D17412C16402D17412D17412D16412D16412D16412D16412D1641 -2D17412D17412D16412D16412D16412D16412D17412D17412D17412D16412D16412D1641 -2D16412D17412D17412D16412D17412C16402D17412D17412D17402D1742301B44341E47 -341F47341F47321D4626103B1B03301C05311C053211002712002913002A14002B0E0026 -756683B3A9BC9E92A9988CA4C1B8C7FBFDF8B4B1B8B6B2B8AFAAB399929C46545086524F -A7534F33524E535653434240000000000000000000000000000000000000000000000000 -000000000000000000040404040404040404040404040404030304000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000101020000002A2A2A -A87CD77433B77E41BD7D40BCBA99DD8848C8803DC38342C58240C48340C58340C58340C5 -8341C58341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58340C5 -8340C58341C58341C58340C58340C58340C58340C58341C58442C57D38C2C3A3E38C4FC9 -AF83D9A373D47A34C18544C58341C58341C58443C58444C58443C58544C68240C47934BE -7A35BF7A35BF7934BE7E39C4843EC9833DC8833EC9813AC7AE7EDEBA90E4B78CE3B88CE5 -B68EDEAFA1BCB8B0BECBC7D0FFF6FF8677903C2E4A45355251445D52455E4636531A012F -1B04311B03311B03311A02301F08352B14402A133F2A133F2F184314002B887A93776883 -1A0230331E4628113C15002B3C284E5645678D8299D3CED7887D94331D46230D39200835 -27113C311B442D17412D17412C16402D17412E1842250F3A463257D5D0D9341F482A143E -2D17412D16412D17412D17412D17412C16402F1943301A432B153F250F3A1A022F1B0331 -4A375B615271ABA2B39A90A57E728B7E708A210A3619012F250E3A84758E4834592C1640 -311C45301B442E18422D17412D17412D17412C16402D17412D16412D16412D17412C1640 -2F1A432D1741220B374633588C7E9581748D2E1842220B37311B442D17412D17412C1640 -2D17412D17412D17412D16412D16412D16412D16412D16412D17412D17412D16412D1641 -2D16412D16412D17412D17412D17412D16412D16412D16412D17412C16402F1943301A44 -301A43301B442B153F28123D29133D29133D29123D1C04321B03301C043118002E2A143E -594869554465524063645473AAA1B3AAA0B2AAA0B2A99FB17C6D876B5C78968CA0C1BAC5 -F2F1F29C90A5321C4780728D6F607E1D05338374907E718E75718D84728E80708D847890 -9796999694999794999592979E9BA07574752527232F302D2D2E2B2E302D2B2C22010100 -000000000000000000000000000000000000000000000000000000000000030303040404 -030303030303040404030303000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000020202000000373C31BB98E1702DB57F43BE7A3ABB -7F40BEAD81D87D38C28341C58341C58341C58340C58341C58341C58341C58341C58340C5 -8340C58341C58341C58341C58341C58341C58340C58340C58341C58341C58341C58341C5 -8340C58340C58340C58342C57C36C19E6BD1BF9CE17125BC9D69D1DAC6ED803CC38341C5 -8341C58341C58340C58340C58341C58240C48341C58442C58442C58442C58442C58342C4 -8241C48341C48241C48342C47933BF772FBE7731BE762FBD7B35C19252D2F8F3FCDFCCF3 -945DCE9E68D7C8ACE7C1A0E4C0A0E3C2A1E6BA9DD9958A9D968AA0968A9F94899E9C91A5 -7A6E862E1C3E36254535234435244436254516002D81728C4D395E14002A4C395E9E93A8 -9489A09C92A6513F632D16411D05332D1741301B44301A44301A432E18422E18422D1741 -2C16402D17412D1741301B441C0532978DA1503E61250E392D17412C16402E18422E1942 -2E18422F19432009351C0432331E47524062A095A992879D988EA28B7F963C284F301B44 -19002E1C05322E1942311B4428123C352048B1A9B82009352D18412D17412D17412D1641 -2D17412D17412D17412D17412D17412C16402D1741301A431E073327103B635372A49BAD -523F6215002B2D17412E19422C16402D17412D16412D16412D17412D17412D17412D1741 -2D16412D16412D16412D17412D17412D17412D17412C16402D17412E19422E18422E1842 -2E19422E18422E18422E18422E18412F19432008351A02301C043219012F301A433D294F -3A264D3A264D3D284F8F8299978CA1958A9F968AA0948AA0958BA0958A9F9B91A4887D94 -3B264E341E47301A434633586455748B7D958D8198574566250E3A20093527103B27113C -8A7F9651406313002A1D05321C03301B033019012E210A373F29533D27513E28523F2953 -38214C5B486B9C93A694899E958BA0988C9D8783C07E7E867F7F7D7F7F7F7E7E7D838387 -686972090B070F100D0E0F0D0E0F0B121102020200000000000000000000000000000000 -010102010102010102010103010103010102020202020202010101000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000002020200000033382EB895DE712EB67F42BD7E40BD7838BAA379D0B58DDC7B36C1 -8443C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58342C5 -7C37C19B66D0BE9BE07931C0813DC4CAAEE68B4EC9803DC48341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C4 -8443C58544C58443C58748C77931C0B28BD9CEB6E7955DCDB48CDC9864D07127BF7A35C3 -7932C27730C17F3BC6A36BDDA169DCA26ADCA26ADCA066DCAA7BDBC2AED9C0A8D9C0A9D9 -C1AADABEA8D670647B9991A0A096A99E95A4FFFFFF81758C210E341000241E0931230E36 -271339230B38210938220A38220A38220938220A382F1A43311B44301B44301B44311B45 -2A133E49365A9A90A41D0633331E47311C45230C381F0734250E3A220B3766557484778F -9D93A6B8B1BF8377904D3A5E250F3A1B033029133D2B153F301B44301A432D17412C1640 -2F1943250E396050707F738D230C382E18422C16402D17412D17412D17412D17412D1741 -2C1640311B4428113C1E0733675776A297A98478911B0331250E3A311C452D17412C1640 -2D17412D17412D17412D17412D17412D17412C17402D17412D17412D17412D17412D1741 -301A43301B44301A44311B442E18422008352009352009351F0835230C3828113C27113C -29123D220B3768587782748E7D6F897A6B86968CA1A89FB0A49BADA59DAEA49AAC5C4A6B -53416455436558476846335818002E2008350F00261303291E0634432F54867B93A79FAF -82768F422E541B033026103B2D17412F19432F19422C1540240D39AFA6B7341F472C1740 -301B44301A43301A442E194228123C28123C28123C28123C29133D240D391A02301B0331 -1B03311A022E1B074357436C59456A58456C5C47654B3C844E49B5A49DA59F99A7A19AA5 -9E99AB8F91D764656C5D5E595F605E5E5F5D61625C595A54030302000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000020202000000353A2F -BA97E0702DB57F42BE7C3EBC7E41BD6F2BB6AE85D6B289DB762EBF8645C68240C48341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58342C57C37C2A575D5B58EDC7A33C1 -7E38C2A06DD2B892DD7831C08544C68240C48341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48442C57E3AC3 -9C67D0B690DD8D50C9C3A3E3782FBFC9ACE6955ECF7F3DC58647C88545C88343C67B37C1 -7B38C17B38C17B38C17B37C17C38C37F3AC87F3AC87F3AC87E39C7813DC9B282E3AE7FE0 -E9DCF4D7C0EE9961D3A78FC1B4A6C2BAABCBB6A6C6B5A5C5B8A8C9685A73554860594C64 -584B63594C645649621F09341B03301C05311C05311B04301F09341B023291849B554365 -13002A1A02305A496A604F6F867890B5AEBC82748D6D5D7B2A133E1E06331F0734230C38 -2E1842301B442D17412D17412C16402D17412D17412D17412C16402F19431C0432A298AA -46325728123C2D17412D17412D17412D17412C16402F1943301A431A02303C274E80748D -887C943D284F1D0532301A442E19422C16402D17412D17412D17412D17412C16402F1943 -301B44301A44301B44301A4427113C26103B27103B27103B1E07341C05321D06331A0230 -27103C625171604F6F6150705A486A81738CAEA6B5A69DAFA79EAFAAA3B37E718B70607D -71627F796A853E2A501D0532240D39220B37220B37220B37220B37250E3A260F3A220B37 -2A143E210A365A486970617DADA5B4988DA15D4C6C200835230C3826103B321C452E1842 -2C16402D17412C16402F1943240D395D4B6B8B7D94210A362E18422C16402D17412D1741 -2D17412D17412D17412D17412C16402E1842311B44301B44301B44301B45301A3F220B36 -210B36220B36210B37220B34240C31240C3A240C39240C38220B3D1403626A5981796886 -7564857766815F59BF5F5CCE9A97A09D9A9E9B98A39092BC989BC68182A72A2A2830322E -222322000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000010150B7B5AA07E3BC27C3FBB7D3FBD -7D3FBD7C3DBC7E42BEC1A3E18C4FC97D39C28442C58240C48341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58342C57F3BC3CAAFE68645C6813EC48340C5803CC3C6A9E48D50C9 -7F3BC38342C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C57D38C2D1B9E98544C67C37C2CBB0E7 -7E39C39A63CFBE9CE17C38C38241C68342C78342C78343C78343C78343C78343C78343C7 -8343C78344C68343C68343C68444C68545C76F25BC9B67D1B48FDDAD85DA8648C88643CD -8D4CD28B49D08B49D08B4AD08A47D0B68DE1C09DE4BE99E3BE9AE3BF9AE4BD99E2A194AE -9F94AAA094AB9F94AAA398AE9589A13523435C4F6A8E8499796F83AAA5B0776886847690 -513D611A01302008361E05342E1843301A452F1944301A442F19432F19432F19432E1842 -2C16402D17412D17412D17412D17412E1842240D395441649B90A415002C311C452C1640 -2C16402D17412F1A43220B371F0835877C94A196A8695A7818002E29123D311C452F1943 -2F19432F19432E18422C16402C16402C16402E184221093619012F1B03301A02301B0331 -402C53453157443156412D538F8399A097A99C92A59E94A79990A48C80988D81988C7F96 -95899F6554732B153F341F48321D46341F47220B371B04311D06331B033129123D301B44 -2F19422F1943301B44301B442F1A43230B371A012F3C284E4E3C609C92A594879D7E708A -321C452A133E1F0734301B442E18422D17412C16402D17412D17412D17412D17412C1640 -2F19431C04326756758A7D931D0532301A442C16402D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412C16402C17412E18422E18422E18422E18422D1842 -2D18432F19422F19422F19432F1941321B391E07321B04311C05311C05311A04331C0636 -341D493620493520522215840C0074332885E0DFDEF1E6FDAFA8B7000000020202000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000404040000008A858E985CD47637B77D3FBD7C3EBC7E40BD7939BB8246BF -C3A3E38A4BC8813EC48341C58341C58341C58340C58340C58340C58340C58341C58341C5 -8341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58240C48443C5 -7C36C1C9ACE58949C8813DC48442C57A33C1A574D4B48DDC7D38C28342C58341C58340C5 -8340C58341C58341C58341C58340C58340C58340C58340C58341C58341C58341C58341C5 -8240C48342C57D38C2B994DE9D68D17E3AC38442C5CBAFE68544C67A32C19E69D1BD99E0 -7D39C48241C68342C78241C68342C78342C78342C78342C68342C68342C68342C68342C7 -8342C78342C7803EC5B894E09C68D28748C9D1BAEB7832C18241C58140C48040C48040C4 -8140C47933C17730C17731C17731C17730C17933C2995DD89C61DA9B60DA9B60DA9A5DD9 -A16ADBC1A5DDC9B5DDE9E1F2EAD8FCC4B2D8756C7D6F627A786D82897F92433252271338 -2B173C29163B29153A2007361F07362007361E0635250D3A311B45301A44301A44301A44 -2E18422D17412F1943250E3A776A856C5D7B200935301A432F1A432D1741210A36594868 -9A91A56657762C1640210936341E47321C4527113C1C05321E07341D0532230C382F1943 -2D17412F1A4326103B6758768E8298867991877B92887C939F94A8A197AAA095A9A499AC -5947684734584B385C4C3A5D43305519012F1B03301B033019012F220B372C16402B143F -2B153F2B153F2E18422F1A432F19432F1A432D17412D17412D1741301B4426103B1D0633 -230C386556748C81979C92A6988DA24A385C1F07341C04312B15402D17412F19432C1640 -2D17412D16412D16412D16412D17412D17412D17412D17412C16402F1942230D389D94A8 -3F2B5228123D2E18422D17412D17412D17412D17412D17412D17412D16412D16412D1641 -2D17412D17412D17412D16412D16412D16412D16412D17412D17412D17412C16412D1740 -2C16412C16422F19432F1A432F19432F1A43301A422F1A422E184129133E1D05312D1732 -7A6C75B2A0B47851A19B7ABCC5BCCE191919000000010101000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000040404000000 -908D92985DD47637B77D3FBD7D3FBD7C3EBC7F43BE712EB7A67AD1B893DE762EBF8443C5 -8240C48240C48340C58340C58340C58340C58341C58341C58341C58340C58340C58340C5 -8340C58341C58341C58340C58340C58340C58443C57B35C1A676D5B48CDC7C35C18441C5 -823FC48340C5823EC4C4A5E37D38C28443C58240C48340C58340C58341C58341C58341C5 -8340C58340C58340C58340C58341C58341C58340C58341C58342C57F3BC3955CCDC5A6E3 -7831C08544C5813FC4CBAFE68442C58443C57931C09E6AD1BD99E07D39C48241C68342C7 -8241C68342C78342C68342C68342C68342C68342C68342C78241C68342C7813FC6C5A7E3 -7F3CC57E3BC5AB7ED8AB7ED87D39C48444C78241C68342C78241C68444C78545C78545C7 -8545C78545C88445C77D3BC27C3AC27C3AC27C3AC27C3AC27F3DC37126C1B58BDFB58DDC -AB7FD6823FC5B483E5B07DE3AF7CE1AB76E1B79CD2BBAACCBAA7CDBCA9CFB4A2C7665B71 -63586D63576D695E724D3E5B18012D1F09331E08321D0731230C38260E3C260E3B230B39 -28113DAFA5B62E19422A143E240D3927113C93889E8A7C94422F5415002B200936230C38 -2109361A022F412E5371637F6B5B7966577580728BADA4B5A79DAFA79DAFADA4B57D708A -635371685977685876665674250E391D05321F08341E0734240D39250E3A250E3A250E39 -27103B311B44301B44301B44311B442F19422C16402D17412D17412D17412D17412D1741 -2C16402D1741321C452A143F250E3A1B033049365A6F607C988BA0C7C1CD72637F27113C -1D0532260F3A2F1943301A442C16402D17412C16402D17412D16412D16412D16412D1641 -2D17412D17412D16412D16412D17412D17412A143E311C45ABA3B4250E3A2D17412C1640 -2D17412D16412D17412D17412D16412D16412D16412D16412D17412D17412D17412D1641 -2D16412D16412D16412D17412D17412D17412D16412D16412D16412D16412D17412D1741 -2C16402E1842311C452B143F1E06332E1B41756880B1A2C39875BE68379D4D14869170B2 -BDA2D9585859000000040404000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000404040000008D8A8F995ED57637B77D3FBD -7C3EBD7D3FBD7C3EBC7F42BE7433B8AE85D5A879D67D39C28443C58240C48341C58340C5 -8340C58340C58341C58341C58341C58340C58340C58340C58340C58341C58341C58341C5 -8340C58340C58443C57931C0B085DAAB7ED87830C08442C58340C58341C57E38C2BA95DE -9E6AD17B36C18443C58341C58340C58341C58341C58341C58340C58340C58340C58340C5 -8341C58341C58341C58240C48544C6762DBFC6A7E4965FCE7E39C28342C58240C4C9ABE5 -7F3AC38340C58543C67931C09E6AD1BC99E07D39C48241C68342C78342C78342C78342C6 -8342C68342C68342C68342C78444C77C37C3A678D7B189DC7E3AC48444C77934C2CEB5EA -8B4ECA7F3CC58343C78241C68342C68342C78342C78342C68342C68241C68342C78342C7 -8342C78342C78342C78546C87832C2B189DAB188DB6F25BEC6AAE6955ECC732BBC7934BE -7933BE7832BD823EC78742CB8642CA8540CA8947CCB990E3BB93E4BA92E3BC91E7B596D4 -A79CB1A99BB6A799B3B1A3BD695B7640314D483A55493A5640314E3B2D4C8E7F98230D39 -625170B5AEBD6959783F2A52422D545C4B6DA398ADA59AADA59BADA79EB0998DA1847890 -8477908A7E95675775240E392D17412B153F2C1640230C381E06331F07341E07341F0734 -2E1842301B44301A43301A442E18422D17412D17412D17412D17412C16402D17412D1741 -2D17412D16412D16412D16412D17412C16402D1741301A432E184227113C15002C341F48 -4C395D8B8097978BA0847890412D531E07341E06332D1741301B442D17412D17412C1640 -2D17412D17412D17412D17412D16412D16412D16412D16412D17412D17412D17412D1641 -2D16412C16402F1A43210A367464807A6A851C05322F1A432C16402D17412D17412D1741 -2D17412D16412D16412D16412D17412D17412D17412D16412D16412D16412D16412D1741 -2D17412D17412D16412D16412D16412D17412C16402F19422E1843260E3B17002E301D42 -766981AF9FBF9C7ABF63309757228C5E2C916C3E9BA489C0A27EC55F615D000000040404 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000404040000008E8A90985CD47637B77D3FBD7D3FBD7D3FBD7D3FBD7D3EBD -7E42BD712DB7CBB2E68F53CB7D39C28342C58240C48341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58340C58443C57931C0 -AE82D9AF85DA7930C08442C58340C58441C57D37C29359CCC4A4E37D39C28342C58240C4 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48443C5 -7A34C1AE82D9AB7ED77D38C28442C58342C57E3AC3BA96DE9B66D07E38C28341C58543C6 -7931C09F6BD2B994DE7E3BC48444C78241C68342C78342C78342C68342C68342C78342C7 -8545C87831C2B893E09E6BD37B36C38444C7813FC68D52CCC2A3E48242C78241C68241C7 -8342C78342C78342C78342C78342C68342C68342C78342C78342C78342C78342C78140C6 -884ACAC8ACE78546C87E3AC4945DCEC4A5E37B35C18646C68442C58443C58241C48240C3 -8240C38241C3813FC37730BE7730BE7730BE752DBD813CC59759D69455D39657D4914FD3 -B288DCC5A9E1C1A2E0C1A3E0C5A8E18A7B98BCB6C3D8D5DBE2DFE4C8C4CC968F9DA09AA6 -A39DA8908897413050331E47311A45351E49210F3707001F19052F1D0433230C38311B45 -2F19432F19432E18422F1A43301B44301A44301A442F19422D17412C16402D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412C16402D1741 -2E18422F19432C16401A0330210A364C3A5D94889E91879DA198AA5C4C6C27103B18002E -29133E2F19432F19422D17412C16402D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412C16402F1943 -1C04327C6E8773637F1F0734301B442C16402D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412C1640 -2D17412E1842301B44220A37210A3556476592889BA797B89C7ABE663399541F89623093 -6332955D2A917549A1A58AC08B60B7666A62000000040404000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000010101000000 -252921B89BD67633BB7E41BD7D3FBD7D3FBD7D3FBD7C3EBC7D40BD7A3BBB8B55C4BE9DE0 -823FC48240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C5813FC48748C7C6A7E48543C6823FC48340C5 -8340C5823FC48543C67931C0BD9AE09963CF7D38C28342C58240C48341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C5823FC48544C6CBB0E6823FC4823FC4 -8341C58442C57A34C19F6CD2B892DE782FC08543C6823FC48544C6762CBFAC80D8B690DF -752DC08647C88241C68342C78342C78342C78342C78342C7803DC58D51CBC5A7E4803EC6 -8343C78342C78545C8772FC1B892DFA778D67A34C38444C78241C68342C78342C78342C7 -8342C78342C78342C78342C78342C78241C68546C8762EC1D8C3EDB48CDE7730C18647C8 -7A35C2C1A0E29B66CF7A34C18443C58240C48341C58341C58341C58240C48341C58544C5 -8544C58444C58544C68241C47E3BC17E3BC17E3BC17E3CC17B35C17931C17932C17B34C2 -762CBFAC79E0E7D6F7CBAEE9975DD29D6DCDB19CC5AE97C5AE97C4B19AC7B7A2CD6F637B -695D736A5E746D61777A70823C2A4D200A33251038210B34210C34220C36230B3A230B39 -230B39230B39250D3B311B44301B44301B44301B44311B442D17412D17412D17412D1741 -2D17412D17412C16402D17412D17412D1741301B442F1942220B371F0834341E46746581 -8F8298978EA25C4B6C3F2B5116002C250E392D1741311B442D17412C16402D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412C16402D17412C16402C1640A79FB1311C45 -27103B2E18422C16402D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412C16402E18422F1943240C391E0733554763 -A093ABA88EC38960B36A399B541F8A602E92643395612F9364329558238DAC92C67F57A7 -5E2994A799B60A0D07000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000014180FBCA5D67632BB7E41BD -7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7E41BD7533B9915EC7C5A5E37932C08544C68240C4 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58240C4823FC48443C5C7A9E47D37C28442C5823FC48340C58340C58340C57E39C3 -9359CCC7A9E47C37C28443C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58240C48443C57C36C1C7AAE58E53CA7F3BC38342C58341C58442C57A34C1A677D5 -B791DD782FC08543C58340C58340C58240C58340C5BF9EE2935CCE7B36C38545C88241C6 -8342C78342C78342C78342C77E3BC59965D1C09FE17933C28545C78241C68241C68545C8 -7A34C2C3A3E3965ED07C38C38443C78241C78342C78342C78342C78342C78342C78342C7 -8241C78444C77A35C39E6BD3BC98E07932C28545C88342C77E3BC5935BCEBD9BE08544C6 -823FC48341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48341C5 -8341C58341C58341C58341C58443C58544C58545C6813EC4894AC7BC9ADE7933C3BE9CE2 -8748C57C35C28641CB8540CB8540CB843FCA833EC8B384E1B78BE4B689E3B689E2B687E6 -B29BCAB0A4BCB1A2BFAFA1BDB8AAC68A7C98493B5553455F51435D53465F4A3B571A0230 -1B04311B03311B04311B033027103C2A133F29123F2A133F29123E2D1741301B44301A44 -2F1A432D17411E0633230C38544164736682A49AAC7D6F895947681E0633210A3628123D -321C452E18412C16402D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2D17412D17412D17412D17412E184227103B402C5291889E311B452C16402D17412D1741 -2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 -2C16402F19432E1842240C39200935534360A296ADAA90C57A4DA857218D57238B602E92 -643395612F93623094612F93653496531C89AF96C8774DA2531B8CB19EC312160E000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000014190FBBA3D47633BB7E41BD7D3FBD7D3EBD7D3EBD7D3FBD -7D3FBD7C3EBC7E42BE7533B9B998DB9F6CD27A33C08443C58240C48341C58341C58341C5 -8341C58341C58340C58340C58341C58341C58341C58341C58341C58442C57C37C2A576D5 -B38ADB7D37C28341C58340C58340C58340C58340C5823FC48442C5DCCAEF9157CB7E3AC3 -8341C58341C58341C58341C58341C58340C58340C58341C58241C58443C57B36C19F6DD2 -BB96DF7A33C08443C58240C48341C58442C57A34C1A475D4B993DE782FC08543C58340C5 -823FC48341C5803BC38340C4C2A2E3935BCE7B36C38545C88241C68342C78241C68545C8 -7831C1C2A2E4925ACE7F3CC58342C78342C78342C78443C77D39C49964D1C2A3E47F3CC5 -8343C78241C68342C78342C78342C68342C68342C78342C78241C68443C7803EC5BF9FE3 -945CCF7E3BC48343C78241C68545C8762EC1AC80DAB48DDC7932C08443C58341C58341C5 -8340C58340C58340C58341C58341C58341C58341C58340C58340C58341C58341C58341C5 -8240C48341C58240C48240C4E7DAF3945CD07329C2D0B7EAB58EDC7B36C18444C58342C4 -8342C48342C48341C47832BE7730BE7731BE7831BE752EBC8845CB904FD18E4DD0904FD1 -8B47CFA26DD7C4A4E4BF9CE2C09DE2C19EE4BA9BDA988EA2998EA3998EA3988EA39C92A6 -4737563422433827473726463A294828133B1A01311D05331F073429123E7F728C9B92A6 -998EA47768852E17421D0532250F3A321C45301A432F1A432E18422C16402D17412D1641 -2D16412D16412D17412D17412D17412D17412D16412D16412D17412D17412D17412D1741 -2D17412D16412D16412D17412D17412D17412D17412D17412D16412D16412D17412D1741 -2C1640301B441A012F6859778F849A14002A311C452C16402D17412D16412D16412D1741 -2D17412D17412D17412D17412D17412C16402E18412E1942301A44220A37210B36544461 -A094ABAD94C77749A558228D5B278E643395633194623094612F93623094623094623094 -5E2B9171449EAE94C76737975A2390B3A1C40F130C000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -14190FBAA1D57430BA7E42BD7C3EBC7D3EBD7D3EBD7C3EBD7C3FBD7D3FBD7D3FBD7D3FBD -7736B9BA99DC9A66D07D38C28443C58240C48341C58341C58341C58340C58340C58340C5 -8340C58341C58341C58340C58240C48544C6772FBFBB97DF9860CE7C36C28341C58340C5 -8340C58340C5823FC48543C57931C0A97BD7AD82D87A34C18443C58240C48341C58341C5 -8340C58340C58340C58341C58240C48443C57D37C2C5A6E39157CB7E3AC38342C58341C5 -8341C58442C57A34C1A576D5B48CDC772EBF8543C6823FC48340C5823FC48441C5803CC3 -823FC4C2A2E3935BCE7B36C38545C88241C68342C78140C6894BC9C1A1E4894CCA813FC6 -8342C78342C68342C78241C68545C8762EC1D7C2EBB28ADD7832C28545C88241C68342C6 -8342C68342C68342C68241C68546C8742CC0BC99E1A678D77831C18545C78241C68342C7 -8241C68444C7803DC5C9ACE68747C7823FC48240C48341C58340C58340C58340C58340C5 -8341C58341C58340C58340C58340C58340C58341C58341C58240C48544C6772FBFB28ADB -B792E17C38C67F3DC79A65D2C4A5E37830BF8544C68240C48341C58240C48341C58443C5 -8443C58443C58443C58544C6813FC37F3DC2803DC27F3DC2803EC27D38C1772FBF7831BF -7831C0762FBF7D38C3A066DA9F65DA9F66DAA066DA9E63DABB9DD9C2ABD9C1A7D9C0A7D8 -C7ADE19989AA776F7F7567817F7389F6F8F496909F3B294C14002819042C25113826103A -220A3921083721093720083627103B311C45301A44301A44301B442E18422D17412D1741 -2D17412D17412D17412C16402D17412D17412D17412D17412D16412D16412D16412D1641 -2D17412D17412D16412D16412D16412D16412D16412D17412D17412C16402F194226103B -85768F5E4D6C220B372F19432C16402D17412D16412D16412D17412D17412D17412D1741 -2D1741311B4428113D2008361F09345647639D91AAAE94C7794BA7551F8B5D2A90633294 -633194612F9362309462309462309462309462309463319458238D845EABA284BF541D8A -5D2991A287BD383A36000000010101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000010000005B48708949CC793CB9 -7D3FBD7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3EBC7E40BD7837BA8851C2CAAFE67B34C1 -8341C58341C58240C48341C58341C58340C58340C58340C58340C58341C58341C58340C5 -8341C58443C57C36C1CAAEE69D68D17C36C28341C58340C58340C58340C58340C5823FC4 -823FC48442C5CAADE68544C6823FC48341C58341C58341C58340C58340C58340C58240C4 -8545C67830BFBC99DFA170D37A34C18443C58240C48341C58341C58442C57D38C29862CF -E3D4F28442C5823EC48340C58340C58340C5823FC48441C5803CC3823FC4C2A2E3935BCF -7C37C38443C78443C77B36C39D6BD2B48DDC772FC18545C88241C68342C68342C78342C7 -8342C78342C77E3BC5C9ADE58646C7803EC68342C78241C68342C68342C68241C68343C7 -7F3CC59761CFBA95DE813FC68342C78342C68342C78342C78241C68443C77B36C3A87AD8 -B58EDC7830BF8544C68240C48340C58340C58340C58340C58341C58341C58340C58340C5 -8340C58340C58341C58240C48444C67831C0AD82D8B088DE7730C38444C9803DC78C51CD -C1A0E2823FC48341C58341C58341C58341C58340C58340C58340C58340C58341C58240C4 -8341C58341C58341C58341C58240C48342C58544C68544C58544C58544C68342C57B37BF -7B37BF7B37BF7B37BF7B37BF7D37C47E37C57E37C57F39C57931C29C62D5AB78E0EFE4F9 -DAC0F2A26BD7A87FD0B0A0BEBBAACBB8A7C7BFADCF83748F5549605E52695B4F6660546A -45335518012E1D07321D06321B0530230C3828113E27103D27103D27103D2F1943311B44 -301B44301B44311B442E18422C16402D17412D17412D17412D17412D17412D17412D1641 -2D16412D16412D16412D17412D17412C16402D1741260F3B3A264DA9A1B2220B372C1640 -2D17412C16402D16412D16412D17412C16402D1741301B442A133F1A0230402E515F526B -9D91AAAC91C57B4EA9551F8B5C298F643395623094612F93623094623094623094623094 -6230946230946230946230945E2B91AF96C97549A15F2C925A288D7D4CAD858386000000 -040404000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000404040000006A6C67AB78DE7131B57E40BD7D3EBD7D3EBD7C3EBD -7C3FBD7C3FBD7D3FBD7C3EBC7E41BD7736BA9969CBB690DC7F3AC38443C58240C48341C5 -8341C58340C58340C58340C58340C58341C58341C58341C58341C57E3AC2945CCDDBC8EE -8441C5823FC48340C58340C58340C58340C58340C58340C58442C57931C0AD81D8AF85D9 -7A33C08443C58341C58341C58340C58340C58341C58341C57F3BC38E52CAC5A7E47F3BC3 -8342C58240C48341C58341C58341C58240C48544C67932C0C5A6E49156CB7F3AC38340C5 -8340C58340C58340C5823FC48441C5803CC38340C5C1A0E29057CD803EC58444C77F3CC5 -BA96E09A66D27E3BC58343C78342C68342C68342C78342C78241C68444C77C37C3A87CD8 -B087DC7D39C48444C78241C68342C78342C78342C78443C77934C2CFB6EA8A4DCA7E3BC5 -8342C78241C68342C78342C78342C78342C78241C68241C7C7A9E5894AC7803DC38341C5 -8341C58340C58340C58341C58341C58341C58341C58340C58340C58240C48240C48444C6 -7831C0AC81D8B18ADE7933C48444C98342C98545CA7831C4B893E09D69D07B35C18442C5 -8341C58341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C5 -8340C58341C58341C58341C58341C58240C48341C58341C58341C58341C58341C58341C5 -8443C58443C58443C58342C48646C67832BF9864CDA578D3BE9CE08240C27C35C08B47CC -8945CA8A47CB853EC8A875D9C19DE5BC95E3BC95E2C29CE8DCD3E49E92A9A497AFA194AC -AB9FB666587339294742335040314E41314E1F08341A01301B03311B03311A0130260F3B -2E17432C16412D16412D16412F19432F19432F19432F19432F1A432D17412C16402D1741 -2D17412D17412C16402F1943240D39534265887D9527113C2F19422C16402D17412C1640 -2E18412F19432B143F1C0432372447877B90AA96BFAC8FCA784BA558228D5A278E653496 -623094623094612F93623094623094623094623094623094623094623094612F93633295 -5A258EB7A1CE62319462309459268C8457B1848385000000040404000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000040404 -0000006A6C68AB78DE7231B57E40BD7D3FBD7D3FBD7D3FBD7D3FBD7C3FBD7D3FBD7D3FBD -7C3EBC7F43BE6E29B5B490D8AC7FD8762DBF8545C68240C48341C58341C58341C58341C5 -8341C58341C58341C58341C58341C57D39C2945CCDBD9AE0772DBF8544C6823FC48340C5 -8340C58340C58340C58340C58340C58340C5823FC4CBAFE68341C58240C48240C48341C5 -8341C58341C58240C48544C57A34C1B791DDA473D47A34C18443C58240C48341C58341C5 -8341C58341C58443C57B34C1C6A8E49055CB7F3AC38340C58340C58340C58340C58340C5 -823FC48441C57F3AC38949C8D0B7E97933C28545C8803DC5C7AAE7813FC68342C78241C6 -8342C68342C78342C78342C78342C78241C68546C8742CC0C3A4E39E6CD37933C28444C7 -8241C68241C68444C77C38C4B691DFA171D57E3AC48444C78241C68342C78342C78342C7 -8342C78241C68445C77934C2A97DD9B289DB7B35C18443C58240C48341C58341C58341C5 -8341C58341C58341C58341C58341C58240C48443C57A33C0AC81D8B18ADE7933C48444C9 -8342C98241C88443C97C38C6A575D7B38ADB7E3AC28342C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48342C5 -7E39C28D50C9D1B8E97328BDB690DDA777D47B35BF8240C1813EC1813EC18240C17B35BE -762DBC772FBC772FBC762DBB8A4AC79B5DD5995BD49A5CD49655D3B289D9C5ABDEC1A4DD -C2A6DEC2A6DE8E8199857B8E877C91857A8F8E84974D3D5B2411362D1A3E2B183C2B183C -2008361E06351F07351F07351E06342B143F311B452F1943301A44301A442E18422D1741 -321C4517002D7E718B7B6D8716002C321C452C1640301B4428123D1E063336224784788F -B2A0C49069B6622E95501A875E2B90633294633194612F93623094623094623094623094 -6230946230946230946230946230946230946231945D2A91794EA3AB91C6602E93623194 -59268C8456B1868587000000040404000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000404040000006A6C67A975DE7131B5 -7E40BD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7F42BE -BE9EDE9054CB7E3AC28442C58240C48341C58341C58341C58341C58341C58341C58341C5 -8342C57D38C2A372D4B791DD7B34C18442C58340C58340C58340C58340C58340C58340C5 -823FC48441C57D38C2C2A2E2935ACC7E3AC38342C58240C48341C58240C48544C6772FBF -AB7ED7B690DD762EBF8545C68240C48341C58341C58341C58341C58341C58443C57A34C1 -C6A7E49257CC7F3AC38340C58340C58340C58340C58340C58340C5823FC48442C57D38C2 -A778D6B48DDC7025BEAB80D9B38CDC7D39C48343C78342C78342C78342C78342C78342C7 -8342C78342C78342C7813FC68B4ECABE9BE1894BC98140C68342C78343C77F3DC58B4FCA -C8AAE67B36C38443C78241C68241C78342C78342C78342C78342C78342C78241C68546C8 -762EC1BC9AE0A270D37B35C18443C58341C58341C58341C58341C58341C58341C58341C5 -8240C48544C67A33C0A678D6B28BDF7933C48444C98342C98241C88342C98241C88342C8 -8140C8C5A7E57D38C28443C58240C48341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C5823FC4BB96DF965FCE7C37C1 -8B4FC9C6A7E2823FC28340C38340C38340C3823FC28441C38543C48543C48543C48543C4 -803CC17D38BE7D39BE7D39BE7D39BE7C35C07B32C07B33C07B32C07B32C0A56EDAAC77DE -AA75DDAB76DDA971DEB696D5BDADCEBCA8D0BDA9D0BBA8CE6F637B665A70685C72675B71 -6B5F763521471A042F200A341F09331F0933240D3A250D3B250E3B240D3A29123E988CA0 -4C395D26103B2B15401C043239264981758DB4A2C5906AB75E2A9358238C612F93653496 -623094612F93623094623094623094623094623094623094623094623094623094623094 -623094612F93643395531D8A9877B88E6AB2551F8B6432956231945C2891A791BE232720 -000000010101000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000404040000005F625CAB7CDC7332B67E40BD7D3FBD7D3FBD7D3FBD -7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7D40BD793ABB7E41BDC8AEE48645C6813EC4 -8341C58240C48341C58341C58341C58341C58341C58341C58443C57C36C1C7AAE58A4AC8 -803CC38340C58340C58340C58340C58340C58340C58340C58340C58341C57C36C19A64CF -C09FE17A33C08443C58341C58341C58341C5813EC48A4CC8BF9EE1894BC8813EC48341C5 -8341C58341C58341C58341C58341C58341C58443C57B34C1C5A7E48B4DC8803BC38340C5 -8340C58340C58340C58340C58340C58340C58340C58341C57A32C1AF83D9A97BD8B28ADB -9862D0742CC08342C7803EC68241C68444C78444C78445C78343C78241C68241C68545C7 -7730C2A87AD7BB97E0752DC08546C88342C77D39C4E7DBF49964D07D39C48443C78342C7 -8342C78342C78342C78342C78342C78342C78342C78342C7803EC68E53CBC6A8E47D39C2 -8442C58240C48341C58341C58341C58341C58341C58240C48544C67932C0A676D5E3D5F2 -762FC38444C98342C98342C98342C98342C98342C98342C9803EC7DDCCF0A16FD27D37C2 -8442C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58240C48544C6772FBFA87AD6BA96DF742BBE8848C77830BFB892DE9A63CE7C35BF -8341C38340C38340C38340C38340C38340C38340C3823FC38340C38340C38340C38340C3 -8340C38442C38443C38442C38443C38443C37A34BD7932BC7933BC7933BD7832BB803AC3 -853FC8843EC7843EC7853FC8B487DFBA90E2BA8FE2B487DED0AFEECBC4D2A596B3ADA0BA -AC9FB9AA9CB652435E4839554A3B574E405A3A2B4A15002C978A9F301B44331F4484798F -B19EC3936DB95D289257238C623194633295612F94612F93623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094602E93663596 -AF96C96F419C5F2C92623094653496531C89AB8FC732362E000000010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000001000000B0A3C08140C47C3EBB7D3EBD7D3EBD7D3FBD7C3FBD7C3FBD7C3FBD7D3FBD -7D3EBD7D3FBD7C3EBC7F42BE7331B8A57BD1B38BDC7931C08442C58240C58341C58340C5 -8341C58341C58341C58240C48443C57B35C1C8ABE58E52CA803BC38340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58543C57A33C1C4A4E3945CCD7F3BC38341C5 -8240C48545C67831C0C2A1E29B66D07A33C08443C58240C48340C58340C58341C58341C5 -8341C58341C58442C57C37C1AF84D9AA7CD77C36C28441C58340C58340C58340C58340C5 -8340C5823FC4823FC48442C5823FC46F22BCB48CDBE5D8F4C1A1E4A475D68444C78B4FCA -8241C67831C17933C27831C17F3CC58444C78343C78444C78546C87D3AC4B690DFA475D6 -7D39C47C37C3AA7FD9B590DE7C37C48444C78342C78342C68342C68342C68342C78342C7 -8342C78342C68342C68241C68444C77933C3BA97E0A170D27B35C18443C58240C48341C5 -8341C58341C58240C48442C5803CC38240C4C6A7E49259CF803DC78343C98241C88342C9 -8342C98342C98342C98444C97933C4AC81DBAF84D97830BF8544C58240C48341C58340C5 -8340C58340C58341C58341C58341C58341C58340C58340C58341C58341C58341C58341C5 -8341C58340C58340C58341C58341C58341C58341C58341C58341C58442C57E39C2955DCD -BF9DE1803CC38442C58442C57D38C2A372D4B38ADA7E38C08341C38340C38340C38340C3 -8340C28340C28340C28340C38340C38340C38340C38340C28340C28340C28340C38340C3 -833FC3823FC28441C38441C38441C38441C38441C38340C28240C18240C28240C28240C1 -7830BC772EBC772FBC772EBC7831BC8D4CCC9453D29352D19251D19454D1BE9BDEC2A2DF -C0A0DEC4A2E3B89ED0847A8EC0BBC7A49CACAA96BC926CB8602C9455208A633294633194 -623094612F93623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094612F935F2D92693998B59ECC56218C643395612F93 -643395541E8AAF95CA2F332B000000010101000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000001000000B1A4C08140C5 -7C3EBB7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7D3FBD7C3EBC -7F42BE7330B8A981D3AC80D87C37C28443C58240C48341C58340C58341C58341C58442C5 -7B35C1A373D4B791DD7B33C18442C58340C58340C58340C58340C58340C58340C58340C5 -8340C5823FC48340C57E39C29860CEC09FE17831C08544C68442C57C36C1955DCDC4A5E3 -7B35C18544C68240C48341C58340C58340C58340C58341C58341C58340C58341C57F3BC3 -8E53CAC4A4E37A32C08543C58340C58340C58340C58340C5823FC48341C58543C57A33C1 -8B4DC9B892DDC3A3E3FBF9FDC09EE1D0B7E8CAAEE6C9ACE5E2D2F0B48DDDAE84DBB38CDD -935BCE7B35C3803DC57A35C37B37C37832C28545C7C8AAE57F3CC58342C7CBB0E68546C7 -813FC68342C78241C68342C68342C68342C68342C78342C78342C68342C68342C68342C7 -8342C77F3CC58F55CCC5A5E37E39C28442C58240C48341C58341C58240C48442C5803CC3 -8341C5C2A2E29158CF7B37C68444C98241C88342C98342C98342C98342C98342C98443C9 -7D38C69C68D4B893DE7F3BC38341C58341C58340C58340C58340C58340C58340C58341C5 -8341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58340C58340C5 -8341C58341C58341C58341C58240C48544C67932C0C09EE19C67D07B35C18443C58240C4 -8240C48341C5C5A7E27C36BF8442C3823FC28340C38340C28340C28340C28340C28340C2 -8340C38340C38340C28340C28340C28340C28340C28340C38340C38340C28340C28340C2 -8340C28340C38340C38340C38340C28340C2823FC28340C38442C38543C38443C38543C3 -8442C3803CC07E3BBF7F3BBF7F3BBF7E3BBF7931BE7930BE7931BF762DBD8643C69D5FD8 -D5B9F1E1D9EA541C8D59258D613093643395612F93623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946231945D29908158A9A88CC45B278F63319462309464329557228C9C7ABE515250 -000000020202000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000001000000AFA2BD8241C57B3EBB7D3FBD7D3EBD7C3EBD -7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7C3EBD7D3FBD7C3EBC7E41BD7533B8CDB4E6 -894BC87E3AC28342C58240C48340C58341C58341C58443C57A33C0A87BD6B38ADB782FBF -8543C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C5813EC4 -8442C5E6D8F3955CCD7E3AC28443C58241C4BB97DF965ECE7E39C28342C58240C48340C5 -8340C58340C58340C58341C58341C58340C58341C57E3AC2955DCDC4A4E37931C08543C5 -8340C58340C5823FC48442C58341C57E38C2772EBFB38BDBC9ACE5A371D48746C6D2BBEA -B289DB813DC47C35C17A33C19A64D0B188DAAA7CD7BC98DFE0D0F0C7AAE5CAAFE6D8C3EC -A373D69F6DD49A65D2A06ED4B28ADBB791DD8F54CC7B37C3803EC58342C78545C88444C7 -8241C68342C78342C68342C78342C68342C68342C68342C68241C68546C87730C1BE9DE2 -A06ED27A33C08443C58240C48240C48442C5803CC38341C5C2A1E29259CF7B37C68545C9 -8241C88342C98342C98342C98342C98342C98342C98241C88545C97A34C5C4A5E48747C6 -813EC48240C48340C58340C58340C58340C58340C58341C58341C58340C58340C58340C5 -8340C58341C58341C58341C58340C58340C58340C58340C58341C58341C58341C58240C4 -8544C6772FBFB38ADBAC80D87932C08544C58240C48341C58342C57E39C2B58EDBA271D2 -7B34BF8442C38340C38340C28340C28340C28340C28340C28340C38340C38340C28340C2 -8340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C38340C2 -8340C28340C28340C28340C28340C38340C38340C2823FC28340C38340C38340C38340C3 -8340C38340C38443C38543C38543C38644C47F3BC18140BFC9ABE6B69BD2613092643395 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094612F93653496521B89A98EC4 -794FA45B268F623094623094612F935F2E9169359E9E97A6000000020203000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000001000000AEA0BE7D3AC37C3FBB7C3EBC7D3EBD7D3EBD7C3FBD7C3FBD7C3FBD7D3EBD -7D3EBD7D3EBD7C3FBD7C3FBD7C3FBD7D3FBD7A3BBC874FC2BF9EE08545C68240C48341C5 -8341C58341C58341C58443C57A33C0A97CD7B48BDC7830C08443C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58543C6782FC0B68EDCA778D67D39C2 -762EBFB28ADBB289DB752CBE8545C68240C48341C58340C58340C58340C58341C58341C5 -8341C58341C58341C57E3AC2945BCDC5A6E47A32C08543C5823FC48340C58442C57B34C1 -7D37C29B65D0CAADE6A675D57F3AC3772FBF9053CBC1A2E18647C3C9ACE6823FC48543C5 -7D37C27830C07931C07930C08341C5894AC8833FC5AC7FD8C2A2E3B994DECCB0E7DBC8EE -DCCAEEE8DDF4A476D68A4ECB9158CE803EC6762EC17B37C38343C78241C68342C78444C7 -8444C78343C78241C68342C78342C78241C68342C7803EC5C3A4E49055CB7F3AC38342C5 -8342C5803DC38342C5C2A1E29259CF7B37C68545C98241C88342C98342C98342C98342C9 -8342C98342C98342C98342C98343C97D3AC6AE84DCA97BD67C37C28442C58341C58340C5 -8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 -8340C58340C58340C58340C58341C58341C58240C48341C5813FC48A4DC8C2A3E28544C6 -823FC48341C58341C58240C58443C57931C0A97BD7B288DA7931BE8442C38340C38340C3 -8340C28340C28340C28340C38340C38340C38340C38340C28340C28340C28340C38340C3 -8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C2 -8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C28340C2 -823FC28543C37931BEBB96DD9A64CFAB7BD99575B456208C643295623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230945F2C916D3F9CAE95C8693998602D92623094623094 -6230945E2C90703DA29F98A6000000020203000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000010102000000898290955DCF -7738B97D40BD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD -7D3FBD7C3EBC7E41BD7431B89565C9C4A6E4752BBE8646C68240C48341C58341C58240C4 -8443C5C8ABE58543C6823FC48340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C5823EC48746C7CBAFE67A33C09B66D0BB97DF813EC48443C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C57E3AC2 -945CCDC2A2E2782FC08543C68443C5823EC47B34C19E6AD1C3A4E3BF9CE19055CB7D37C2 -8340C5813EC48D50CAC8ACE46C20B7B58FDAAB7DD7782FC08543C68442C58442C58442C5 -823FC4813DC4823FC47B33C1782FC0782FBF6D1EBAA778D6EADFF5EADFF5AC80D9CDB3E8 -C8ABE6BC99E0B893DEA87AD67E3BC58343C77F3DC57A34C37A34C37E3BC58546C88444C7 -8443C78342C78545C87A34C3A272D5B994DE7A33C18443C58241C5823FC4C09FE1925ACF -7B37C68545C98241C88342C98342C98342C98342C98342C98342C98342C98342C98342C9 -8342C97D3AC6945CD0BD9BE0772FBF8544C68240C48341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58240C48443C57730BFCCB1E78F54CB7D38C28442C58240C48341C58341C5 -8341C58342C5813FC4C9ADE58645C4813EC2823FC28340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C3803CC28B4DC7C9ACE6 -752BBEB48ADE9373B457218C633295623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6231945A258E7D54A7A88DC4521B89653496612F936230946230945E2C906F3CA2A19AA8 -000000020203000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000002020200000043483EB990E2702DB57F42BE7D3FBD7D3FBD -7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7E40BD -7838BAB28DD8A270D47A34C18544C58240C48240C48341C5803CC3C8AAE5813DC48340C5 -823FC48340C58340C58340C58340C58340C58340C58340C58340C5833FC58340C5823FC4 -8544C67D37C2B58DDCA372D4B791DD9258CC7730BF7F3BC38443C58544C68544C68544C6 -8544C68544C68544C68544C68544C68442C58341C57F3CC38E53CAC3A3E38341C5823EC4 -7A32C08443C5C7AAE5BC98DF9359CC7830C07F3BC38441C5823FC48441C57C36C2B992DE -A16FD07228B9B590DAA26FD37D38C28442C5823FC48340C58340C58340C5823FC48544C6 -8340C5823FC4DDCBEFB086DAA16FD3D5BEEBA06ED27125BC7A32C09860CEA87AD6B187DA -CDB3E9CEB4E9BE9CE2A171D4A97DD8935BCE7730C17B36C37C38C47E3BC57F3CC58748C8 -7F3CC5C9ADE68D51CA8342C5742ABED4BDEABC9AE3742CC28647CA8241C88342C98342C9 -8342C98342C98342C98342C98342C98342C98342C98342C98342C9803DC78E52CDE3D5F2 -8F54CA7F3CC38341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48443C57D38C2 -A779D6AE83D97D38C28443C58240C48341C58341C58341C58240C48443C57C36C2C2A2E1 -945BCA7E39C18341C3823FC38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C3823FC28441C37E39C1CBAFE78A4BC8762CBEB58BDE8B68AE56208C -643295612F94623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230946230946231945B278F8B66B0A284BF -57228D64329562309462309462309463319459258EA183BE3F423C000000020202000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -02020200000044493FB78DE0702EB57F42BE7D3FBD7D3FBD7D3FBD7C3FBD7D3FBD7D3FBD -7D3FBD7D3FBD7D3FBD7C3FBD7C3FBD7D3FBD7C3EBC7D3FBD7D3EBD7432B8BD9EDE9B66D0 -7B36C18443C58442C57C36C1A575D4B38ADB7D38C28341C58340C58340C58340C58340C5 -8340C58340C58340C5823FC48340C58442C58340C5823FC47D37C27328BD823FC4DECDF0 -C9ACE58C4EC99760CE945BCD7B34C1772FBF7830C07830BF7830BF7830BF7830BF7830C0 -772FBF7D38C28240C48443C5762DBFB893DE9962CF7F3AC3B187DAC9ADE69054CB7A33C1 -7E38C28543C68340C58340C5823FC48543C6782FBFB186DAA97CD47730BC7F3CBFD2B9E9 -813EC4813DC48340C5833FC58340C5823FC48441C5803BC38341C5BF9CE1B68EDC762CBE -B48CDCB085DAB993DE8F53CA8341C57E39C27930C07D37C28543C57F3AC3955CCDBC99DF -B68EDCBE9BE0C7AAE6CBB0E8AE84DA9158CD9158CD7832C27026BE9862D1BC99E07125BC -A270D3BA97E27D3AC68444C98241C88342C98342C98342C98342C98342C98342C98342C9 -8342C98342C98342C98342C98241C88545CA7730C4BC99E1965ECD7D38C28342C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58240C48341C5803CC38748C7D0B7E97B35C18341C58341C5 -8341C58341C58341C58341C58341C58342C57D38C29861CEC1A0E17A33BE8442C38340C3 -8340C38340C28340C38340C38340C38340C38340C38340C38340C28340C38340C38340C3 -8340C38340C38340C28340C28340C38340C38340C38340C38340C38340C28340C28340C3 -8340C38340C38340C38340C38340C28340C28340C38340C38340C38340C3823FC28442C3 -7A32BEA777D3B58DDC7B33C1813DC3955ACFB296CE5F2C91623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094612F9364339556218CB69ECD6939995F2D92623094623094623094 -612F93643395531E889C76C1575A53000000030303000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000002020200000043483EBB92E3 -702EB57F42BE7D3FBD7D3EBD7C3FBD7C3FBD7C3FBD7D3EBD7D3EBD7D3EBD7C3FBD7C3FBD -7C3FBD7C3FBD7D3FBD7C3EBC7E41BD7736BA905AC6C3A4E27E38C2813FC48544C67830C0 -BA96DF9E6AD17B33C18441C58340C58340C58340C5823FC48340C58341C58341C58442C5 -8340C57830C07E39C38340C5A473D5C2A1E3B38CDBE8DEF3ECE1F6B995DDC5A8E3C3A4E1 -BC99DFBC98DFBC99DFBC99DFBC99DFBC99DFBC99DFBB97DFC0A0E19F6CD2823FC4894BC8 -7C37C2C19DE0C5A9E4BE9DE1AF84D98341C57F39C38442C58341C5823FC48340C58340C5 -8340C58443C57830C0B48CDCA87AD37832BD7F3CC0955DCBBC98E07F3BC38441C5823FC4 -823FC48543C6803CC38340C5C2A1E29359CC7429BE8645C6E4D5F28D50CA9054CBC8AAE5 -7931C08645C68442C58341C5823FC48340C57F3AC3772EBF762CBF823FC49359CC8B4DC8 -AA7CD6CAADE5C2A2E3BB98E1C09FE3AD83DABF9EE1A474D4B995E17F3BC78241C88342C9 -8342C98342C98342C98342C98342C98342C98342C98342C98342C98342C98342C98342C9 -8342C98443C97C38C6A87BD8AF84D97E39C28342C58341C58340C58340C58341C58341C5 -8341C58341C58340C58340C58340C58341C58341C58341C58340C58340C58340C58341C5 -8240C48341C5813EC4C09FE19157CB803DC38342C58240C48341C58341C58340C58340C5 -8340C58341C58544C57A33C1C3A3E2945BCA7D38C08340C38340C28340C28340C28340C3 -8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C28340C28340C2 -8340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C38340C2 -8340C28340C28340C38340C38340C38340C38340C3823FC2803CC2C6A8E48C4EC97F3BC3 -8442C57D36C3C3A8DD653594612E93623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623194 -5D2A917448A0AD94C7623194612F93623094623094623094623094643295541E89A17EC5 -545851000000030303000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000002020200000030352A996DC47432BA7E41BD7C3EBC7C3EBD -7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3EBD7C3EBD7D3EBD -7C3EBC7E41BD7533B99764C9BA97DE803CC38646C6772EBFB48DDCA676D57A33C18441C5 -8340C5823FC48441C58544C68341C57C36C17D37C27B34C1823FC4AA7CD7B58DDCD0B8E7 -B189D89E6ECE8E57C7BC9BDEB18DD89B65CE6D20B77934BD9B67CDA16FD09F6DCFA06ECF -A06ECFA06ECFA06ECFA16FD09C68CDB791DCCDB4E7C9AFE5CDAAE5B2B4E7D5BFEA904BCA -6E25BC8442C58442C5823FC48340C58340C58340C58340C58340C58543C5782FC0B48CDC -A97BD47730BC8443C2762EBBA374D2BD99E0752ABE8645C68442C57931C0813EC4C2A2E2 -9258CC7B34C18441C58C4EC9C5A6E47B34C17C36C2BF9CE19C67D17A32C08442C5823FC4 -8340C5823FC48341C58543C68543C6823FC47E39C3803BC37D36C2772EBF7F3AC3A270D3 -A16ED3A06DD2EADFF5E4D6F47C38C77933C48546CA8241C88342C98342C98342C98342C9 -8342C98342C98342C98342C98342C98342C98342C98342C98342C98241C88140C88546CA -C4A6E47A34C18544C58240C48340C58340C58340C58341C58341C58340C58340C58340C5 -8340C58341C58341C58341C58340C58340C58340C58240C48443C57A34C1A372D4BB97DF -762EBF8544C68240C48341C58341C58340C58340C58340C58340C58240C48443C57A33C1 -B48CDBA575D47D38C08341C38340C38340C28340C28340C28340C38340C38340C28340C2 -8340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C38340C2 -8340C28340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C3 -8340C3823FC28442C37C35BFA372D2B892DE782FBF8543C68340C4823DC5C4ABDE653694 -612E93623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094643295551F8B9473B69574B7541D8A -643395612F9362309462309462309463329557238B9067B86C6B6D000000020202000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000302040000008171938D4FCE783AB87D3FBD7C3EBD7C3FBD7C3FBD7C3FBD7C3EBD -7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7D3FBD7C3EBC8044BE6E28B5 -BB9CDCA371D4762EBF8C4EC9C1A0E28747C7813EC48543C68340C5813DC47C36C2762CBF -803BC39961CFAE82D9CEB4E7C5A6E3B38ED99F70CF7834BB7A37BC7733BB742EB9A377D1 -A67ED2AC86D6AA7DD67932BC7C38BF7832BD7933BD7933BD7933BD7933BD7933BD7933BD -7933BD7B36BE7C3BBF883BC04120BC0049A76EB5CED4C6EDA25DD07C35C17C39C28544C6 -823FC4823FC48340C58340C58340C58543C5782FC0B48CDCA97BD47730BC8241C1813FC1 -7E3BBFBC9ADD975FCF7D37C27930C0B289DBD5BFEB8E51CA7C36C28543C6803CC38B4CC8 -CAAEE67E39C2803BC39358CCBD9AE08543C68340C58340C58340C58340C58340C58340C5 -823FC48340C58340C58340C58441C58544C68340C57D38C27226BD955BCDC7A9E5CBB0E6 -CBAFE7B188DC7730C48545CA8241C88342C98342C98342C98342C98342C98342C98342C9 -8342C98342C98342C98342C98342C98342C98342C97F3CC7B791DE9D68D17D37C28442C5 -8340C58340C58340C58341C58341C58340C58340C58340C58340C58341C58341C58341C5 -8340C58340C58240C58342C57D38C2945ACCC4A5E37B36C18443C58240C48341C58341C5 -8341C58340C58340C58340C58340C58341C58240C4813EC4894AC8C3A3E37931BE8543C4 -823FC28340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C3 -8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C2 -8340C38340C38340C28340C28340C28340C28340C28340C38340C38340C38441C37B34BF -CCB1E6894AC8813DC4823FC48340C4823DC6C3A9DC5E2C8F623094612F93623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -62309462309462309463319559248D9978B99775B857218C643295623094623094623094 -623094612F936332945B2592AC9DBC060A03000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000303040000009A96A0 -9154D07839B87D3FBD7D3FBD7C3FBD7C3FBD7C3FBD7D3FBD7D3EBD7D3EBD7D3FBD7C3FBD -7C3FBD7C3FBD7D3EBD7D3EBD7D3EBD7D3FBD7C3EBC7D40BD7B3DBCBB9BDD8F54CB8A4CC8 -C3A2E27931C08543C6772EBF7F3AC38847C7A878D6C5A6E4BE9CDFC3A6E1A67BD38345C0 -864AC2732EB97734BB8041BF7F40BF8041BF7B39BD8E55C6C0A3DF6722B3B492D9A678D4 -7730BC8444C28140C18240C18240C18240C18240C18240C18140C17F41C18D42C24124BD -005BAE057CAB0067A71280B27EB8D5C1A7E39F59CF722BBE8341C58441C5823FC48340C5 -8340C58543C5782FC0B48CDCA97BD47730BC8241C1813FC17F3CC07D3ABFC4A5E19054CB -A271D3CEB4E89359CC7B34C18543C6823FC4803CC38B4DC9CAADE67C36C28645C6762DBF -AA7DD7B48BDB7328BD8644C6823FC48340C58340C58340C58340C58340C58340C58340C5 -8340C5823FC48543C67A33C1A06DD2BC98DF8340C5B68FDBA270D2CAAEE6A373D67934C5 -8546CA8342C98241C88342C98342C98342C98342C98342C98342C98342C98342C98342C9 -8342C98241C88545C97831C4AC81DBAD81D87932C08443C58340C58340C58341C58341C5 -8341C58341C58340C58340C58341C58341C58341C58341C58341C58341C58240C48443C5 -7D38C2BA96DF9D69D17C37C18443C58341C58341C58341C58341C58341C58340C58340C5 -8340C58341C58341C58240C48341C5BD9AE0935ACA7F3AC18341C38340C28340C28340C3 -8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C28340C2 -8340C28340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C2 -8340C28340C28340C38340C3823FC28442C37B33BFBB96DE9D69D27E38C28341C58340C5 -8341C57E38C3B58EDB8661AB5A268F633194623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094612F93612F93 -623094BBA5D05E2B91623194622F94623094623094623094623094623094623193602A95 -AE9FBD070A04000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000004030400000095919B9256D07739B87D3FBD7D3FBD -7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD -7D3FBD7D3FBD7C3EBC7D3FBD7A3BBB7E42BDCCB1E6A270D4B288DB7830C08644C6B085DA -B992DECEB6E8AE85D6945FC8915BC7722BB87834BB7D3CBE7D3CBE8142C08041BF7E3EBE -7F3FBF7F3FBF7937BC945FC9BEA0DE702EB77434B9B28ED8A778D4762FBB8342C2803EC0 -813FC1813FC1813FC1803EC17E3FC08C40C14123BD005AAE0179AB006FAC0274AC016EAA -0068A43580BA9FA2DABA87DC823BC47B36C18442C5823FC48340C58443C57830C0B38ADB -A97CD47731BC8241C1803EC08443C27730BC9359C9C9ACE6A778D67227BD803CC48442C5 -823FC48340C5803CC38B4DC9CAADE67C36C28442C58442C57D37C2D2BAEAA16FD37B35C1 -8441C5823FC48340C58340C58340C58340C58340C58340C5823FC48543C67931C09F6BD2 -BC98DF7F3AC3762CBFB892DE9C67CF6E21B9B790DBA87BD9742CC28140C88443C98241C8 -8342C98342C98342C98342C98342C98342C98342C98342C98342C98342C98443C97D39C6 -9F6DD6DECEF0813EC48240C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58240C48544C6752DBEB188DAB188DA762DBF8545C6 -8240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48544C6 -772FBFAE83D9A575D37A33BF8442C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3823FC3 -8341C37E39C19258CAC5A6E37B34C18441C5823FC48340C58441C57B34C09E66D4A88EC3 -541E8B643395623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946231945C29907C53A6AC92C65C288F633194 -612F936230946230946230946230946230946231935F2994B0A1BE060902000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000004030400000097929E8B4CCD783AB87D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD -7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7D3FBD -8044BE7634B9925EC7E0D0F0AF85D9CBB0E6C8ABE4AC83D49B69CC7530BA7937BC7835BC -7A38BC8143C08040BF7E3EBE7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7B39BD8E55C6 -C0A2DF7738BB7C40BE7130B8B28ED8A778D4762FBB8342C2803EC0813FC1803EC17F3FC0 -8B40C14123BD005AAE027AAB006FAC0072AB0071AB0072AC0574AD0069A70476AA779BCD -B897DE9A5ACF7935C18240C48341C58442C5782FC0B48CDCA272D17730BC8241C18241C1 -7D38BF8344C2AA7DD5E7DAF4C9ADE5975FCE7A32C08341C58340C5823FC4803CC48A4BC8 -C8ABE57D36C28442C58441C57B34C1A575D5CBB0E77C36C18442C5823FC48340C58340C5 -8340C58340C5823FC48340C58341C5782FC09F6BD2BC98DF7C36C28442C57931C0BB97DF -A16FD27D38C07B34BFB188D8DDCCF1884BCC7E3AC68444C98241C88342C98342C98342C9 -8342C98342C98342C98342C98342C98342C98241C88444C97C37C6C5A7E58341C48240C4 -8240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8240C48341C5803DC38F54CBBD9BE08544C68240C48341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C5813EC48E53CAC5A6E47E38C0 -8341C3823FC28340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C3823FC28543C47A32BEBD99DF9D68D1 -7C35C18441C58340C58340C58441C57A34C0A572D7A78CC2541E8A643395612F93623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094612F93643395541D8AA98EC48058A859248E633194623094623094623094623094 -62309462309463319459258D9571B95C5D5A000000030303000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000020202000000545553 -AB80D77534B87E41BD7D3FBD7C3FBD7C3FBD7C3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3FBD -7C3FBD7D3FBD7D3FBD7D3FBD7C3EBC7D3FBD7E41BD7B3CBC722FB7864DC2AB83D4F2EBF7 -D3BEE88041BF7E3EBE7632BB7834BB8142C07F40BF7F40BF7F3FBF7E3EBE7F3FBF7F3FBF -7F3FBF7F3FBF7F3FBE7F3FBE7F3FBF7E3EBF8142C0732DB9B996DD996BCC7333B97D40BE -7130B8B18ED8A778D4762FBB8342C2803EC07F3FC08B40C14223BD005AAE027AAB006FAC -0072AB0071AC0072AC0071AC0071AB0173AC0571AC0061A3278CB9B8ADDFAB72D6813EC4 -7E3CC38544C67F3AC3975FCEBC99DD7D3ABF8443C27C38BE8444C2E6D9F2B48EDCC3A5E2 -894FC3B997DCA06CD37F3AC3813DC48442C5803CC38D50CACAAEE67C36C28442C5823FC4 -8644C67327BDBB96DFA371D4782FC08443C5823FC48340C58340C5823FC48441C5813DC4 -803BC3A574D4BB96DF7D36C2823FC48544C6782FBFBC98E09B65CF7C35BF8442C37B34BF -B086D7C4A5E5894CCC7E3AC68545CA8241C88241C88342C98342C98342C98342C98342C9 -8342C98342C98342C98343C97E3AC6B28BDEA576D57C37C28442C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58240C48544C6762DBFCAADE6 -955CCD7B36C18442C58240C48341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58240C48443C57A34C1B68EDDA473D27C36C08441C38340C38340C3 -8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C28340C2 -8340C38340C38340C38340C38340C38340C28340C28340C38340C38340C38340C38340C3 -8340C28340C2823FC28441C37D36C09156C9C8ABE47A32C18543C6823FC48340C58340C5 -8441C57B34C0A26ED6A98FC4551F8B643395623094623094623094623094623094623094 -62309462309462309462309462309462309462309462309462309462309464339556218C -A98EC48660AD59248E63319462309462309462309462309462309462309463319458248B -8659B47A7B7A000000040404000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000101010000001F241ABFA1DB7330B87F42BD7C3EBD -7C3FBD7C3FBD7C3FBD7D3EBD7D3EBD7D3EBD7C3FBD7C3FBD7C3FBD7D3FBD7C3EBD7D3FBD -7F42BE793ABB7331B8844AC1B591D9C7ADE29666CBAB86D5C1A4DCC4A8E08E57C77936BB -8244C07E3EBE7F3EBE7F3FBE7F3FBE7F3FBE7F3EBF7F3EBF7F3EBF7F3FBE7F3FBE7F3FBE -7F3FBE7F3FBF8142C0742FB9BA97DD996BCC7333B97C40BD7C3FBD7130B8B18ED8A778D4 -742DBB7F41C18C40C14123BD005AAE027AAB006FAC0072AB0071AC0072AC0072AC0072AC -0072AC0071AB0072AC0375AD016BA90064A66EACCFCDA1E39048C97A32C17F3DC37F39C3 -C7AAE48545C2752EBB8C4FC6C0A1DF8F55CA762FBDC9AFE58142C07A38BCBE9EDDBD99DF -8340C5803CC37931C0C2A2E2C4A5E37931C08442C58340C58340C58340C58543C6BF9DE1 -9054CB7F3AC38341C58340C5823FC48441C5803BC3823FC4C3A2E2BB96DF7D36C2823FC4 -8341C58442C57C35C1A778D6B187D97D37C08341C38443C3762DBD8A4BC6C3A4E58A4DCD -7832C48444C98342C98241C88342C98342C98342C98342C98342C98342C98342C98343C9 -7C37C59A66D3B994DE772FBF8544C68240C48341C58341C58341C58341C58340C58340C5 -8340C58341C58341C58240C48443C57B35C1AD82D9AA7DD77D38C28443C58240C48341C5 -8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 -8342C57C36C19D69D1B790DB772EBD8543C4823FC28340C28340C38340C38340C28340C2 -8340C28340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C3 -8340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C3813DC2 -8644C3C09FE18D50C9813DC48340C58340C58340C58340C58340C58442C57C35C2C2A4E0 -73489D5D2991623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230945C29907347A0B8A1CE58238D643295623094 -62309462309462309462309462309462309463319457238B8D62B8797A78000000040404 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000001010100000021261CBE9FDB7330B87F42BD7C3EBD7C3FBD7C3FBD7C3FBD7C3EBD -7D3EBD7D3EBD7C3EBD7C3FBD7C3EBC7D3FBD7F42BE7A3BBB722FB7874DC2B48FD8C5AAE2 -9E72CE7638BA702EB7854CC2B99BD96B29AEBDA1DB925CC9742EB97F40BF7F3FBF7E3EBE -7F3FBE7F3FBE7F3EBE7F3EBF7F3EBF7F3EBE7F3FBE7F3FBE7F3EBE7F3EBE8142C0742EB9 -BA98DD9261C87333B97B3FBD7B3EBD7C3FBD7230B8AF8DD8AC7FD58A3BBF4224BD005AAE -027AAB006FAC0072AB0071AC0071AC0071AC0072AC0072AC0071AC0071AC0072AC0071AB -0273AC0175AD0063A52077B3A2BFDFB88FDD924FCB7832C0C8ACE57D39BFA06DCFBF9FDF -8648C67B37C07E3CC1C8ADE48548C27E3EBE722CB8945DC9D1B8E8A372D46E20BBBF9CE1 -975FCE7E38C28340C58340C5823FC48442C57931C0A271D3BA95DE7A33C18543C5823FC4 -8441C5803BC38340C5C2A1E29358CC772DBF8441C58340C5823FC4823FC4823FC4823EC4 -C9ABE4803BC18341C3823FC28644C47E39C08644C4D7C2ECC09FE37730C48444C98342C9 -8241C88342C98342C98342C98342C98342C98342C98342C98342C98240C9C0A0E38E52C9 -7F3CC38341C58340C58341C58341C58340C58340C58340C58340C58341C58341C58341C5 -813EC48645C6CDB2E77F3BC38240C48240C48240C48340C58340C58340C58340C58341C5 -8341C58340C58340C58340C58340C58340C58341C58341C58341C58341C58240C4C4A4E2 -8C4FC7803BC18340C38340C28340C38340C38340C28340C28340C28340C28340C28340C3 -8340C38340C28340C28340C28340C28340C28340C38340C28340C28340C28340C28340C2 -8340C38340C38340C28340C28340C2823FC28441C37A33BFAC7FD7B289DB762DBF8543C6 -823FC48340C58340C58340C5823FC48543C57931C0C3A4E1754C9F5C2891623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946231945B268F8761ADA78BC356218C643395612F93623094623094623094623094 -6230946230946231945A278D8052AE85818A000000010102000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000101010000001F241A -BEA1DB7330B97F42BD7D3FBD7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7C3FBD7C3EBC -7D40BD7B3DBC712EB7864CC1B591D9C3A7E1A075CF7636BA7332B97C40BD783ABB8953C4 -C1A6DD6E2FAF763BB3B89AD99E6DCE7B3ABD7D3DBE7F40BF7E3EBE7F3FBE7F3EBE7F3EBF -7F3EBF7F3FBE7F3FBE7F3FBE7F3FBE7F3EBF7F40BF7A37BC9764CBB795DA7536BA7C3FBD -7A3DBC7B3EBD783CBD7E3DBA885ACF2413BD015DAE0179AB006FAC0072AB0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0071AB0275AD0270AA -006DA64C99C3BBA4DFA064D1C8AFE5BB99DEE3D5F2803FC27D3BC18344C47D3AC1C7ABE4 -7F3FBF7E3EBE8142C07B39BD7936BBB693DAA06DD3C6A7E49155CB7931C08340C4813DC4 -8441C58442C58644C67A33C1CAAEE68D50C97E38C28543C5803BC38340C5C2A1E29258CC -7B35C18644C6823FC4823FC58340C58340C5813EC48747C7C9ADE47F3BC18341C38340C3 -823FC28442C37D38C08A4AC6BF9CE0B086DA7A35C58343C98443C98241C88342C98342C9 -8342C98342C98342C98241C88545CA7730C4C2A3E49B66D07D38C28341C58341C58341C5 -8341C58341C58340C58340C58340C58341C58240C48341C57E39C2C7A8E48D51CA803CC3 -8342C58341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C5 -8340C58341C58341C58341C58240C48544C67831C0C2A1E39860CD7E39C08340C38340C3 -8340C38340C38340C28340C28340C28340C28340C28340C38340C38340C28340C28340C2 -8340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C28340C2 -8340C28340C38340C38340C2CAAEE68441C58340C5823FC48340C58340C58340C58340C5 -8340C58443C57A32C1C3A5E2754B9F5D2891623094623094623094623094623094623094 -62309462309462309462309462309462309462309462309462309464339558238DB8A1CE -6E409C5E2B91623094623094623094623094623094623094623094623094612F93653495 -541D8BAE95C6252921000000010101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000101010000001F251ABD9FDB722FB87F42BD7C3EBC -7C3FBD7C3FBD7C3FBD7D3FBD7C3EBC7D3FBD7D40BD7E41BD7737BA8449C0B592D9C4A8E1 -9F73CF7839BB7130B87C40BD7C3FBD7B3EBD7D41BE702EB7B491D99C70C86C2BAE763AB3 -BB9DDBBB96DE7A38BC7E3DBE8040BF7E3EBE7F3FBF7F3FBF7F3FBF7F3FBF7F3FBE7F3FBE -7F3FBF7F3FBF7E3EBE7E3EBE7F3FBEC6ACE27739BB7B3FBD7B3EBD783CBC8242BC6A31BE -061FB30059AE027AAA006FAC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AB0172AC0273AD0064A60474AB92ADD8 -F2DDF7A477D5742DBC8140C38242C38141C37B37C0B590DC9C6CCD7936BC7F40BF7F40BF -8142C07531BAAC83D6E7DBF4CBAFE69358CC8543C68949C87C35C1772EBF7E39C28340C5 -8E51CAC3A3E38543C67F3AC38340C5C2A1E29258CC7B35C18543C6823FC48340C58340C5 -8340C58340C5813EC48746C7CAAEE57E39C08441C3823FC28340C3823FC28441C3813DC2 -7429BBAA7CD4B58DDD7A35C57F3CC78444C98241C88342C98342C98342C98342C98342C9 -8444C97B36C5B28ADDD0B6E87932C08443C58341C58341C58341C58341C58341C58341C5 -8341C58240C48443C57D38C2A170D3B893DE7933C08544C58240C48341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C57F3BC3945BCDC3A2E1782FBD8543C4823FC28340C38340C38340C38340C2 -8340C28340C28340C38340C38340C38340C38340C28340C28340C38340C38340C38340C3 -8340C38340C28340C28340C38340C38340C38340C38340C3823FC28442C37931BEAD81D7 -AF84D97A32C08442C58340C58340C58340C58340C58340C58340C58543C57A32C1C3A5E2 -73499D5D2991623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094612F9364339557218CB7A0CE7447A05D2A90623094623094 -62309462309462309462309462309462309462309464339556208CAF98C721251D000000 -010101000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000020203000000827F859D66D67535B67D40BD7D3FBD7D3FBD7D3FBD7C3EBC -7D40BD7E41BD7736BA7230B7A174CFCAB1E49D70CE7738BB7232B87B3EBD7C40BD7A3DBC -7B3EBD7A3DBD7D41BE6F2DB7B491DA9566C46F2FAF793DB46824AC9464C4BD9BDC7937BD -7936BC8041BF7E3EBE7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7D3CBE -8548C1C4A9E17535BA7C40BD783CBC8243BC692CBE0A3AB4007DAA0276AB0070AC0072AB -0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AB0274AD0274AC005BA399BCDDDDC5EB9562CD7731BF -803FC28242C37A35BF9862CEBB99DC742EB98142C08041BF7733BB8649C2B491DAE0D0F1 -A97ED3BB98DDCCB3E7CAB0E6B389DBB186DA9860CF7C35C17328BDB085DAA473D47F3BC3 -C4A4E39258CC7B35C18543C6823FC48340C58340C58340C58340C58340C58341C57D37C2 -DBC8EEA87AD67A33BE8442C38340C38340C3823FC28340C38644C47931BEA473D1E9DEF6 -945DD17B36C58545CA8241C88342C98342C98342C98342C98342C9803EC78B4ECCC2A2E3 -7831C08544C68240C48341C58341C58341C58341C58341C58240C48342C57D39C28F54CA -CBAFE67932C08443C58240C48341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5803DC38A4CC8 -C5A6E28442C3823EC28340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C3823FC28340C3813DC28340C3CBB0E78442C5823FC48340C58340C5 -8340C58340C58340C58340C58340C58340C57E39C29A62D2B096CA57228C643295623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -63319558248D855EACA98EC558238D633295623094623094623094623094623094623094 -623094623094623094643395541E8AB7A0CF4A4E46000000020202000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000040404000000 -777977A36EDB7333B57D40BD7D3FBD7C3EBC7E41BD7D40BD7736B97534B99665CAC6ACE2 -AC85D57332B97333B97B3EBD7C40BD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7738BB -8D58C6BA9BD97436B2773BB47A40B56C2CAE9362C2BD9BDD8D55C67835BB8041C07E3EBE -7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7D3DBE8244C0CEB7E67D41BE773CBC -8243BC692CBE0A3AB40079AA0170AC0070AC0072AB0071AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0071AB0373AC006BA73997BEB189CDA581CBC8AAE5803FC37D3AC07B37C09F6CD2 -BA98DC7530BA8041BF7530BAAE84D6CBB3E57E3FC0BA97DE8B51C5742EB97B3ABD7835BB -A476D1AD85D5B996DCCBB0E7CDB3E7B48DDCC8ABE5AF85DA8E52CA7B35C18646C6823FC4 -8340C58340C58340C58340C58340C5823FC58442C57930C0A778D6B288DA7830BD8442C3 -8340C38340C38340C38340C3823FC28442C37B34BF9D67CEC3A3E4955ED27A34C48545CA -8342C98241C88342C98342C98342C98342C9803EC7BC99E19963CF7D38C28342C58341C5 -8341C58341C58341C58341C58341C58342C5803DC4B994DE9A63CF7E39C28442C58240C4 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58240C48544C6772FBFB289DBAB7ED67C35BF8441C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8341C37E39C0B086D8A677D67C35C18441C5823FC48340C58340C58340C58340C58340C5 -8340C58340C57F3AC29153CEB9A2D157228C643395623094623094623094623094623094 -62309462309462309462309462309462309462309462309463329558238D9675B79B7CBB -551E8B643395612F93623094623094623094623094623094623094623094623094633194 -59258C8E65B8A09EA2000000040404000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000040404000000777876A36FDB7333B57D40BD -7D40BD7F42BE7533B97635B99766CAC2A5E0BA9BDC8953C47535BA7B3FBD7C3FBD7B3EBD -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD793BBCC2A7DE7233B0783CB4 -763AB3793EB56D2DAE8F5DC0C6ACE19B6ACD7530B98143C07F3FBF7E3EBE7F3FBF7F3FBE -7F3FBF7F3EBF7F3FBF8040BF7733BACEB6E6A781D47834B76B2FBF083AB40079AA0171AC -0071AC0072AB0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC -0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0273AC0068A6 -3B9CC2B38DD06020A18B5EB9BD9CDD8D51CA742DBC9E6CD1BD9CDD7029B78041BFB28AD8 -AB80D77B3ABF7631BCA476D3B28BD97937BC8142C08041BF7733BB722CB97C3BBD894EC4 -7B39BDAC84D5FFFFFFD7C1EC9D68D1823EC47932C08442C58441C58340C5823FC48340C5 -8340C58340C58442C57931C0AD80D8B188DA7930BE8442C38340C38340C38340C28340C2 -8340C3823FC28443C37B33BF813CC1C09FE29964D37933C48342C98342C98241C88342C9 -8241C88545CA7730C3B28BDEA87AD67A34C18442C58341C58341C58341C58341C58240C4 -8544C6762DBFAC80D8B892DD742BBE8545C68240C48341C58341C58341C58341C58341C5 -8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 -8341C58341C58240C48240C48444C6C8ABE47E38C08441C3823FC28340C38340C38340C2 -8340C28340C28340C38340C38340C38340C38340C28340C28340C38340C38340C38340C3 -8340C38340C28340C28340C38340C38340C38340C38340C37E38C09861CDC5A5E3752BBE -8543C6823FC48340C58340C58340C58340C58340C58340C58340C58340C57E3AC29356CF -BAA2D157228C643395623094623094623094623094623094623094623094623094623094 -623094623094623094623094612F93623094BDA9D2612F93623094612F93623094623094 -6230946230946230946230946230946230946230946230945D2B8F703DA3948F99000000 -030303000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000040404000000777876A06ADA7434B67F43BE7635B97533B99A69CBC0A2DF -BA9CDD8B55C5702EB77739BB7B3FBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBC793CBCBA9BDB8854BD7335B2773CB4763AB3793DB57133B1 -6C2BAEB292D5A071D0712AB87E3EBE7F40BF7E3EBE7F3FBE7F3EBE7F3EBF7E3EBF8041BF -752FB9A175D2B289D45F1CB90B3DB50079AA0171AC0071AC0072AB0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0373AC006DA899BBDA8A48B46428A4 -824FB4CAB3E09E6DD19A65D0B894DA8447C1CDB6E5A779D4742FBB7F3FC17E3EC08244C2 -C6AAE27936BC8041BF7E3EBE8041BF8142C08142C0732DB8A678D2C4A6E08B52C5CCB2E6 -B695DAC5A7E3A675D57E38C27B34C18341C58441C5823FC48340C58340C58442C57931C0 -AD80D8AD81D8782FBD8543C4823FC38340C28340C28340C28340C28340C3823FC28543C4 -813EC27D37C0D0B7E9D2BAEB7A34C58342C98343C98241C88342C98342C98240C8884ACB -C4A5E4803CC38341C58240C48341C58340C58341C58342C57F3BC3945BCCBD9AE08241C4 -8341C58341C58341C58340C58341C58341C58341C58340C58340C58340C58340C58341C5 -8341C58340C58340C58340C58340C58340C58341C58341C58340C58340C58341C58341C5 -813EC4BF9DE09359CB803BC18340C38340C38340C28340C28340C28340C28340C28340C3 -8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C2 -8340C38340C3823FC28543C47A32BEC5A5E29258CC803BC38340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C57E3AC29457CFB69DCF541E8A653496612F93 -623094623094623094623094623094623094623094623094623094623094623094612F93 -6231945E2A91BBA6D1633194612F93623094623094623094623094623094623094623094 -6230946230946230946230945C2A8F7847A898949C000000030304000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000030303000000 -636562A677D86F2CB57534B99867CAC1A5E0B899DB8C57C5702EB77738BB7D41BE7B3EBD -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD -712FB89D70CEAC88D16B2AAD793EB5773BB4763AB3783DB4773CB46F2FAFAE8DD3AE86D7 -8142C07B39BC8041BF7E3EBE7F3FBE7F3EBE7E3EBF8041BF732FB9B087D69672D6012BAF -007BAB0171AC0071AC0072AB0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0071AB0374AD0068A67BB3D2945EBC6E34AA7036AB6829A5A079C7D1BDE7 -E0CFEFB18CD87D3DC07835BE8041C17F3FC17C3BBF884DC6C7ACE27835BB8041BF7E3EBE -7F40BF7E3EBE732EB9AB80D5B188D87531BA7B39BDC5A9E26D2AB6854DC2B28FD8C8ABE4 -A472D47E39C37D37C28544C68340C5823FC48340C5813EC48848C7C4A4E28645C4813EC2 -8340C38340C28340C28340C28340C28340C28340C3823FC28441C3803CC1813DC2AD81D7 -BA96DE7E3BC7803DC78444C98241C88241C98342C9803DC8D1B9EA8C4FC9813EC48341C5 -8341C58341C58240C48544C6772FBFC4A4E39A64CF7B34C18443C58240C48340C58340C5 -8341C58341C58341C58340C58340C58340C58340C58341C58341C58340C58340C58340C5 -8340C58340C58341C58341C58340C58340C58340C58443C57932C0A473D4AF83D8772EBD -8543C4823FC28340C28340C28340C28340C28340C28340C38340C38340C28340C28340C2 -8340C28340C28340C38340C28340C28340C28340C28340C28340C3823FC28442C37A33BE -9C67CFBF9CE07B33C18442C5823FC48340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58341C57E38C3BA97DC7E57A55B268F633194623094623094623094623094 -623094623094623094623094623094623094612F9364329557228D916FB49A7ABA5A258E -633194623094623094623094623094623094623094623094623094623094623094623094 -6231945B2790A389BD31352E000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000020600BBA9CB965FCEC2A8E0 -B99ADC8A54C47231B87536BA7D41BE7B3EBD7B3EBD7A3DBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD7231B8A277D1AE8AD26C2CAE -783DB5773BB4773BB4763AB3773BB4773BB47031AFAA86D2C1A0E18243C17B39BC8142C0 -7E3EBE7E3FBF7F3FBF7C3EBF823EBC7F47CA1D57BE0072A80272AC0071AC0072AB0071AC -0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC -006CA91886B5B49FD56726A4773FAE7339AC692BA6AC8BCDC2A6DDB089D98345C47B3ABE -8040C18040C17C3BBF874CC5C8ADE37936BC8040BF8041BF7B39BD7F3FBFAE84D6B087D7 -7430B98143C07A38BCB08AD8A075CF712FB87332B9834AC0B391D9C8ACE59D68D1742ABE -823FC48442C58340C58442C57B33C1C7A9E48B4CC6803CC28340C38340C38340C28340C2 -8340C28340C28340C38340C3823FC28340C38341C3762CBC9D67CEBD9BE08545CA7D39C6 -8444C98241C88443C97A35C5C4A6E6B792DD7830C08544C58341C58240C48544C67931C0 -B288DBAA7DD77B35C18443C58240C48341C58340C58340C58341C58341C58341C58340C5 -8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 -8341C58340C58340C58341C5803DC38F53CABF9DE08543C3823EC28340C38340C28340C2 -8340C28340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C3 -8340C28340C28340C28340C28340C38340C38340C3823FC2BE9BE0945ACD7E38C28441C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C5823FC48543C6772EBF -B68DDE8C6AAE58228D633295623094623094623094623094623094623094623094623094 -623094623094623094643395551F8BA88CC38A65AF57218C633295623094623094623094 -623094623094623094623094623094623094623094612F93643395521C88A280C4484D44 -000000020202000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000CCC6D3BD9AE28954C37130B87738BB7C40BD7B3FBD -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7C3FBD7536BAC3A8E0824CB97436B2773BB4773BB4773BB4 -763AB3773BB4783DB46926AD854FBBC1A2DE8243C17430B98041BF7E3EBE7C3DBE8644BE -6E2DC10A35B30073A80172AC0071AB0072AB0071AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC006FAA067AAF99ABD58144B1 -6F35AA6C30A8B597D39164BE6D31A89C74C3C8B0E09761CE7733BD7835BD7E3EC0884DC5 -C5A9E17631BA8345C17936BC874CC2C6ACE3AD83D67530BA8041BF8041BF7632BB9B6ACC -B28ED86F2DB77F43BF793BBC702EB7844CC1B490D9BC97E08949C87A32C0803BC38645C6 -7E38C2C9ACE58B4DC6803CC28340C38340C38340C38340C28340C38340C38340C38340C3 -8340C3823FC28340C38644C47B33BF965DCBEDE4F7A273D87832C48545CA8444C97A34C5 -A170D6B48DDC7830BF8544C68341C58341C5823FC48748C7C7A9E48342C5823FC48341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C4 -8544C67932C0C4A5E28B4DC6803CC28340C38340C38340C38340C28340C38340C38340C3 -8340C38340C38340C28340C28340C38340C38340C38340C38340C38340C28340C28340C3 -8340C38543C4782FBDB790DDA97AD7772DBF8543C6823FC48340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58543C5782FBFBA94E08561AA58228D633295 -6230946230946230946230946230946230946230946230946230946230946230945F2C92 -6A3B99DACEE67448A05D2A91633194623094623094623094623094623094623094623094 -623094623094623094623094643395531E89A888C8464A42000000030303000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000100C9C2D19F70D26D2BB57E42BE7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC -7C40BD7332B9C2A7E07D44B67437B2773BB4773BB4773BB4773BB4773BB4763AB37A40B5 -6F30B0844EBBC0A0DE9D6DCE7734BB7D3FBE8845BE6D2CC00B3AB5007AAA0272AC0071AB -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0071AB0474AD0063A36DADCD9E64C06427A4B89BD59469C06B2EA7 -763EAE6D30A86D31A8B99BD6BFA0DE9964CF742FBB8244C2C6A8E28548C1742FB98A50C4 -BFA2E08345C07530BA8041BF7E3EBE7F3FBF7F3FBF7E3EBEBFA0DF8750C37739BB7B3EBD -7D41BE7637BA783ABB9E72CEC7ACE3B68EDC8C4DC97A32C07B34C1C9ACE58544C3813EC2 -823FC2823FC38340C38340C38340C38340C38340C38340C38340C38340C38340C3823FC2 -8543C37D36C08C4DC6BC99E0A273D87730C38443C98342C98343C9C6A8E58A4CC8803DC4 -8341C58442C57A33C0CBB0E78D51CA7E3AC38342C58240C48341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C57D39C2A16FD3B993DE -7931BE8543C4823FC38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C3823FC3813DC2894AC5C8AAE4 -803BC38441C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58442C57A33C0AD80DA9878B859258E633194623094623094623094623094 -6230946230946230946230946230946230946230945E2B916C3D9BB299CA541E8A653496 -612F93623094623094623094623094623094623094623094623094623094623094623094 -63329556228B9772BC5E5E5D000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000101020000006C6771C9AEE4A57ED0 -7230B87C40BD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7535B9A277D0A883CF -6F30AF783DB4773BB4773BB4773BB4773BB4773BB4763AB3793EB57031B0834BB9BA9BDB -A981D4803ABD6727C00D3CB50079AA0171AC0071AC0072AB0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0374AD0067A565AECE9E6AC29D79C68857B85C199E692BA66627A46829A56F34AA6729A5 -8553B5B899D5AA7ED7742FBCA273D2A97DD48F58C7BEA0DF8446C17B39BD8143C07E3EBE -7F3FBF7E3EBE8142C0752FBAC0A1E0854DC27739BB7B3EBD7A3DBC7B3EBD7B3EBD7332B9 -7536BAA076CFC5A9E2B891DE8543C6A26FD3AE82D87931BE8543C48543C48442C38443C3 -8340C3823FC28340C38340C38340C38340C38340C38340C3823FC28442C37F3AC17A33BE -B893DEA97CDB7E3AC68342C97A35C5C3A4E5955DCD7E3AC38443C57E39C2A473D4B38ADB -7C37C28443C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C57E3AC29359CCC4A5E37C35BF8442C38340C38340C3 -8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C3823FC28543C47830BEB68EDCA777D57B33C18442C5823FC48340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5823FC48340C4 -823DC6C2A9DB5F2E91623094623094623094623094623094623094623094623094623094 -62309462309463329559248E9D7EBC906DB35B278F623194623094623094623094623094 -623094623094623094623094623094623094623094623094612F93623193602A96A99DB5 -000100000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000003030300000054584F9C6CCC946ABDAF8AD7702FB87C40BD7B3EBD -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7536BA8D58C6B898D86A28AD793FB5763AB3773BB4 -773BB4773BB4773BB4773BB4763AB3783DB47336B26A2AACA775CC3433BE003FB00277AB -0071AC0071AC0072AB0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC -0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC -0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0173AC006BA8D8EEF4 -D7C0E5AA8BCDBA9ED6B699D4B699D4BA9ED68756B87942B0763DAE6F34A9B395D1BC9DDB -D3BDEACCB1E6B692D9864AC27B39BD8041BF7E3EBE7F3FBF7F3FBE7F3FBF8040BF7835BB -AB80D5A57CD17535BA7C3FBD7B3EBD7A3DBC7B3EBD7C3FBD7C40BD7130B87739BBA075CF -C1A3E1C4A5E3C2A2E2813DC27F3AC1772FBD7931BE772FBD803BC18442C38341C38341C3 -8341C38341C38341C38341C38341C38340C38441C38341C37830BEC4A4E2DFCFF1803EC8 -7C37C69761D2C3A4E37A34C1803DC48A4CC8CFB6E87933C08442C58341C58341C58341C5 -8341C58340C58340C58341C58341C58341C58341C58341C58340C58340C58341C58341C5 -8341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C58341C5 -8341C58544C67931C0BF9DE09C66CE7C36C08341C38340C38340C28340C28340C38340C3 -8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C38340C3 -803CC28A4BC5C7A9E4813DC4823FC4823FC48340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C5823FC48643C8C3ABDB5F2E91623094 -623094623094623094623094623094623094623094623094623094612F93653496531D8A -AE95C87448A05C2890623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094612F92653099AA9EB6000100000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000020202 -000000373A34AB8CC96321A3A27DC6AD87D6702FB87C40BD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7739BB8851C4BC9DDA783DB4763AB3773BB4773BB4773BB4773BB4773AB4763AB4 -773BB4753AB4773EB47F3BB52319B30064AC017DAA0070AC0071AC0072AB0071AC0071AC -0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0071AC0071AC0072AB0272AC006BA83C9BC1C7B4DF8E57B98E62BD9063BD -9063BD8D5EBBB89BD5C6AEDDC7AFDDC0A6DAAE8CCFD8C8E8FFFFFFD4BEEB8244C2752FB9 -7B39BC8142C07F3FBF7E3EBE7F3FBE7F3EBE7F3FBF7B39BD8A50C4BD9EDD6F2DB77D41BE -7A3DBC7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7C40BD712FB86C29B5C5ABE1E3D6F1C3A7E0 -B892DDAF83D9B085D9B58CDC9054CA7B34BF7F3AC17F3AC17D37C07B34BF7C35BF7C35BF -7B34BF8340C38543C48543C48543C47D37C09B65CFC1A0E18240C88E53CEC1A0E27830BF -8443C5BC99DF945CCD7F3CC38342C58240C48341C58341C58340C58340C58340C58340C5 -8341C58341C58341C58340C58340C58340C58340C58341C58341C58340C58340C58340C5 -8340C58340C58341C58341C58340C58340C58340C58340C58240C58341C5803CC39055CB -C6A7E37C35BF8442C3823FC28340C28340C28340C28340C38340C38340C28340C28340C2 -8340C28340C38340C38340C38340C28340C2823FC28543C47830BEB48CDBA97BD67931C0 -8543C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C5823FC48542C8C3AADB5D2A8F633195612F93623094623094623094 -623094623094623094623094623094623094612F93653496AF96C870429D5E2B91623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094613092642F99ACA0B7000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000030203000000A29BAA8248BC -6425A1A27CC7AD87D6702FB87C40BD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D42BE6E2BB6B593DA -9465C36F30B0773CB4773BB4773BB4773BB4763AB4773BB3763AB4773DB37D38B42A23B7 -0069AE0278AB006EAC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0071AC0072AB0274AD0067A53D94BE9C81C86728A56C30A86B2EA76C30A86E32A9692BA6 -6221A2814DB4B79AD4A581C9B99DD6BB9FD6B595D3BE9DDF8F57C9732EB97E3EBE8142C0 -7E3EBE7F3FBF7F3FBF7F3FBF7D3BBDBA97DD915FC87536BA7B3FBD7B3EBD7B3EBD7A3DBC -7B3EBD7C40BD7333B98249C0C2A6E0BD9DDEB897DB6C28B59D70CEAB85D5A881D3A57DD2 -BE9FDECCB2E5C8ACE3CDB4E6B38BDA9C65D0A06CD29F6BD1A16DD27F3AC1772EBD7931BE -7930BE7F3BC1772DBD8D4FC7BE9BE09259CFBD9AE18A4CC8A271D3BC98DF752CBE8545C6 -8240C48341C58341C58341C58340C58340C58340C58340C58341C58341C58341C58340C5 -8340C58340C58340C58341C58341C58340C58340C58340C58340C58340C58341C58341C5 -8340C58340C58340C58340C58341C58240C4823FC48544C6C7A9E58543C4823FC28340C3 -8340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C38340C2 -8340C28340C28442C37A33BFA473D2B993DE782FC08543C6823FC48340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5823FC4 -833FC6C1A5DC683A97602D93623094623094623094623094623094623094623094623094 -62309463319459248E7F56A8A588C1521B89653496612F93623094623094623094623094 -6230946230946230946230946230946230946230946230946230946231945A258E9B7ABB -4D4F4B000000030303000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000020203000000A098A88147BB7138A96728A5A17CC7AD87D6 -702EB77C40BD7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7D41BE702EB7B999DC9466C37030B0773CB4773BB4 -773BB4763AB4773BB3763AB4763DB37D38B42A23B70067AD0277AB006FAC0072AB0071AC -0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC -0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0073AC0072AB0676AE -0063A27EBED6A260BF642BA5783FAE6E32A96B2EA78755B7BA9ED6BCA1D78F62BC5F1F9F -9F7BC59B70C4611FA19265BDBCA0D8BF9EDF8142C1742FB98041BF8040BF7F3FBF8142C0 -722CB8B48EDA9768CB7232B87C3FBD7B3EBD7A3DBC7B3EBD7B3EBD7536BA8C57C5BC9FDD -8C58C56924B4BB9CDD9666CA6D29B6702FB7712FB86F2DB77A3DBC8147C08047BF7A3EBD -9E72CEBEA0DEB897DBB999DCB999DCC2A1E0C4A4E1C2A2E1C7A9E39D68CF8E51C98A4AC7 -9A63CEDECCEFD7C2EEB186DAB690DD813EC48544C68240C48341C58341C58341C58341C5 -8340C58340C58340C58340C58341C58341C58341C58340C58340C58340C58341C58341C5 -8341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C58340C5 -8341C58341C58443C57931C0AE84D9A97BD47830BE8442C3823FC28340C28340C38340C3 -8340C38340C28340C28340C28340C28340C38340C38340C38340C3823FC28340C37F3AC1 -C6A7E28E51CA803BC38340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58442C57932C0A978D9A184BD551E8B -6433956230946230946230946230946230946230946230946230946331945C2890A386C0 -8660AD5B278F633194623094623094623094623094623094623094623094623094623094 -62309462309462309462309462309463319556218A8E64B96D6F6B000000040404000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -010101000000353931B392D2682AA5773FAE6728A5A17BC7AD88D66E2BB67739BB7C40BD -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD783ABB854DC2C1A6DE7234B1783CB4773BB4763BB4773BB3763AB4773DB3 -7D37B42923B70067AD0277AB006FAC0072AB0071AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0072AC0072AC0073AC0072AC0072AC0073AC0072AB0577AE96ABD58B48B4 -642AA58959B9B698D4BDA2D88A5BB9682CA46A2FA67239AA733BABC3AADB773DAE6B2CA7 -6C2EA78F61BBBE9FDCA477D27A37BD7733BB7F3FBF8041BF7834BBA477D2AB84D57636BA -7B3FBD7A3DBC7B3FBD7D41BE7231B8AA83D4C7AEE38249C07638BA7230B8BD9FDE8F5CC7 -7637BA7D41BE7C40BD7D41BE7A3DBC793BBC793BBC7A3DBC7434B96E2CB66F2DB76F2DB7 -6E2BB68954C4905EC78F5DC78B57C5B795DBC8AEE4C6ABE3C5AAE3B690DADECEF1FFFFFF -A473D5752CBE7F3BC28545C68341C58341C58240C48341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58442C57D37C2 -9E6AD1B891DB7F3BC18340C38340C38340C38340C38340C38340C38340C38340C38340C3 -8340C38340C38340C38340C3823FC28442C37C35BFA16ED1BA95DF7830C08543C6823FC4 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58442C57932C0AA79D9A185BE551F8B643395623094623094623094 -623094623094623094623094612F936332955B268FB8A1CE623094612F93612F93623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -62309463329555218A956DBE6C6E6A000000040404000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000101010000002E3329B290D3 -6425A3753DAD753CAD682AA59B73C4E2D5F18B55C67332B87D41BE7A3DBC7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD793BBC8147C0 -C1A5DE6D2DAE793EB5763AB3773BB3763AB4773DB37D37B42A23B70067AD0277AB0070AC -0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0071AC -0071AC0071AC0072AC0073AB0074AC006EA90D7EAF91A5D2BA8AD0B194D2875BB8692DA5 -6B30A6723AAA7139AA7139AA6C31A7C4ABDC763DAE7338AC753AAD692AA67D48B1AC8BCE -C6ABE1A272D07B39BD7A38BC8143C07D3DBEC2A6E07435BA7C3FBD7C3FBD7839BB6E2CB6 -B08AD7A57BD26D2AB6793CBC7C40BD7637BA905DC7BB9CDD7535BA7C3FBD7B3EBD7A3DBC -7B3EBD7B3EBD7B3EBD7A3DBC7C3FBD7D41BE7D41BE7D41BE7D41BE7738BB7535BA7536BA -7636BA7333B97333B9702FB7631BB0A57CD2EFE9F6E6D9F4C1A1DFBB97DE955CCE7831C0 -7E3AC2813EC48544C68240C48341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58240C48443C57B35C1C4A4E38442C3823FC2 -823FC28340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 -823FC28442C37B33BFCAADE48D50CA803BC38340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58442C5 -7932BFAB7BDA997AB8531C8A643396612F93623094623094623094623094623094623094 -623094602E936A3A99B49CCB653596602E93623094623094623094623094623094623094 -62309462309462309462309462309462309462309462309462309463319458258C885DB4 -79777C000000020202000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000050703978AA3834BBA6F34A87339AC753BAD -692BA69970C1BFA3DB8B54C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7738BBB593D99363C27032B0783CB4 -763AB4763DB37D37B42A23B70067AD0277AB006FAC0072AB0071AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0071AC0072AC0072AC0072AC -0071AB0173AC006CA90677AD9AB6D9AE84CC7734A9652BA46E37A9723AAB7138AA7138AA -6D33A8C4ABDC773EAE7136AB7237AB743AAD6F32AA692AA67A43AFB293D0B18DD7894CC5 -742FB97937BCB38FD99B6CCD7637BA7333B98B57C5CAB2E49F72CF712FB87E42BE7B3EBD -7A3DBC783BBB8248C0C1A4E0712FB87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7C3FBD7D41BE7738BB8953C4 -BFA1DFB38FD97535BAA77ED3B594D7976AC4BB9DDABF9DE1955CCE894AC77730BF8341C4 -8443C58341C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58342C57D38C2B289DBA87AD47931BE8543C3823FC28340C38340C3 -8340C38340C38340C28340C28340C38340C38340C3823FC28543C47931BEBC98DE9E6AD2 -7D36C28441C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C5803CC38E4FCBB79BD3643494 -612E93623094623094623094623094623094623094612F93643395541E8A9573B69472B6 -551F8B643295612F94623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094612F93643395561F8DAF9AC4171B13000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000404040000008483868F58C56B30A57339AC7238AB753CAD6829A67238AABC9ED9 -8C56C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7A3DBC7D40BE6F2DB7A47AD2A883CF6C2BAE773DB5773DB37D37B42923B70067AD -0277AB006FAC0072AB0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0071AC0071AC -0072AC0072AC0073AC0072AC0072AC0071AC0071AC0072AC0072AC0071AB0173AC016DAA -0170AA3F9DC3A0BADAB289CE7D3EAE652AA36C35A8733CAB6E34A8C3A9DB7238AB7237AB -7237AB7237AB7339AC743AAD7236AB6322A39468BFC5AADEB894DD7C3BBE9E6DCFA982D4 -6823B39464C9BB9CDD864EC27536BA7C3FBD7A3DBC7A3DBD7B3EBD7A3DBC7C40BDBB9BDD -8953C47739BB7B3FBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7A3DBC7A3DBC7D41BE793BBC7535BA9F72CFC7ADE39869CB6D29B6B795DB8D58C5 -8349C2B897D97233B09362C1C1A6DEC3A4E3B085DA8340C57A33C08240C48443C58341C5 -8341C58240C48341C58340C58340C58340C58341C58341C58341C58341C58340C58340C5 -8340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C58341C5 -7F3CC38B4EC8C3A3E38544C4823EC28340C38340C38340C38340C38340C28340C28340C2 -8340C28340C38340C38341C37F39C09055CAC5A6E37D37C28341C5823FC48340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C5823FC48543C57930C1C2A3DF6F439A5E2B92623094623094623094 -6230946230946230946230946230945F2C92A98DC47E55A75B288F633194623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -62309462309464329559238FB19CC5181C14000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000030303000000676768 -9C70C86B2FA6733AAC7339AC7238AB753DAD7034AA7339ABBC9ED98C56C67333B87D41BE -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD702EB7 -AC86D6A178CA6A2AAE7B40B47D36B42A24B70067AD0277AB0070AC0072AB0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0071AC0072AC0072AC0072AC0073AC0072AC0072AC -0073AC0072AC0072AC0071AC0071AB0072AC0071AB0171AC0270AB0067A6086FAA3E9CC3 -A1BADAAE86CC8141AF662AA3672EA5BA9FD58553B76F32A9753BAD753BAD753BAD753BAD -743AAC6F32A96523A36828A59266BDB797D6CAADE5BEA1DEAA83D4C3A8E17A3DBC7536BA -7C40BD7A3DBC7B3EBD7B3EBD7A3DBC7D41BE6F2CB7A77FD3A47AD1702FB77C40BD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3FBD7D41BE7130B8 -8046BFC7AEE3AF89D76F2DB77739BB702EB7BA9ADC9E72CE651FB2B391DAA67DCC6823AA -6D2BAE7E42B7A880CDC8ADE3AD81D98341C57B35C17D38C28443C58342C58240C48341C5 -8340C58340C58340C58341C58341C58340C58340C58340C58340C58340C58341C58341C5 -8340C58340C58340C58340C58340C58341C58341C58240C48545C6772FBFBC99E09258CA -7E38C08340C38340C28340C38340C38340C28340C28340C28340C28340C2823FC28442C3 -7A33BEBA96DEA06ED37B34C18442C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8442C57D36C2C4A7E06F439B5E2B92623094623094623094623094623094623094623094 -5F2D92693A99B69FCD56218C643395612F93623094623094623094623094623094623094 -62309462309462309462309462309462309462309462309462309462309464339558228E -B29EC6171A13000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000E1209B8A3CC6D2EAB743BAC7238AC -7339AC7238AB743AAC6F34AA7339ABBC9ED98C56C67333B87D41BE7A3DBC7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD783ABB874FC3BA9DDB7B3DB37235B4 -2C2BB60065AD0277AB0070AC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC -0071AC0072AC0073AC0073AC0073AC0072AC0073AC0073AC0072AC0073AC0072AC0072AB -0071AC0072AC0071AC0070AC0070AC0272AD0471AC0067A7006EA9449FC59EB7DAAF89CD -7A35AB8051B3B393D26524A36B2DA76726A46727A56625A46C2EA88E5EBC8F60BC8F60BD -814CB59E76C5EFEAF4FAF7FCAF8AD86924B47536BA7E43BE7A3DBC7A3DBC7B3EBD7B3EBD -7B3EBD7C40BD7130B8A881D3A881D37231B87C40BD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7A3DBC7B3EBD7C40BD7637BA6E2BB6AD87D6C6ADE2834AC17231B87C40BD -7E43BE6F2CB7AC85D59767CB7536BA7535BAB390D89869C57739B3783BB36F2EAF7A3EB4 -AA84CEC6AAE2C3A4E29A63D07B35C17E39C2813EC48443C58341C58240C48341C58341C5 -8341C58340C58340C58340C58340C58340C58341C58341C58340C58340C58340C58340C5 -8340C58341C58341C58341C58342C57E3AC29F6DD2B892DC7C35BF8442C3823FC28340C3 -8340C38340C28340C28340C28340C28340C38340C3813DC28E51C8C7A9E47B35C18543C5 -823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58442C57C35C2C3A7E0673995 -5F2C926230946230946230946230946230946230946230945F2C9271459EB59DCC5C2890 -633194623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946331945A268E8F68B5676768000000030303 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000F130BB7A2CC6D2EAB743BAC7339AC7339AC7339AC7238AB743AAC -6F34AA7339ABBC9ED98C55C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7A3DBC7C40BD7032B9C8AAE05D2DBA0046B10077AB0173AB0070AC0072AB -0071AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC -0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0073AC0072AC0072AC -0072AC0073AC0073AC0073AC0073AC0072AC0073AB0072AB0072AB0071AB0070AB0070AB -0070AB0070AB0071AB0271AC0272AC0165A50070AA429FC496ABD5D1BAE1AE90D06D31A9 -B08FD0BB9FD6B89AD4B89BD5B89BD5B89BD5B89BD5B79AD4BEA4D8A27CC86325A1C6AEDD -BCA0D6C0A4DF905DC86C28B57B3FBD7C3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3FBD7839BB -C7AEE37F43BF7A3CBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C3FBD7B3EBD -702EB78F5CC7C5AAE2A176D07839BB7839BB7C40BD7B3EBD783ABB844CC19D71CE7536BA -7C40BD7B3EBC7535BACFB8E5793CB3773AB37A3EB5783BB46E2CAE7C42B58955BCBC9ED9 -C3A3E29760CF8748C77932C0813EC48443C58341C58240C48341C58341C58340C58340C5 -8340C58341C58341C58341C58341C58340C58340C58341C58341C58341C58341C58341C5 -8341C5803DC38A4CC8C6A8E37C35BF8442C3823FC38340C38340C38340C38340C28340C2 -8340C3823FC28544C4742ABCC09FE19E6AD17C36C28341C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58441C57C36C2AF85DA916FB35A258E633295623094623094 -623094623094612F93653496521B89A98EC4835BAA59258E633194623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230945B298E7847A98D8A8F000000040404000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000030303000000 -6A6A69A172CF682BA3743BAC7339AC7339AC7339AC7238AB743BAC6F34AA7339ABBC9ED9 -8C55C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBD7B3EBD783EBD -823FBB8D72D7054DB30079AA0171AC0071AC0072AB0071AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC -0072AC0072AB0072AB0073AC0071A9006FA9006FA9006FA9006FA9006FA9006FA9006FA9 -006FA90371AA026FAA0065A4086FA8399BC0DDE2EFCBABDE926ABF895CB88B5EB98C60BA -8657B66426A26427A26427A26426A26A2FA6672BA4BFA4D87238A87F4DB0B292D1AF8AD8 -7A3EBD7535BA7D41BE7B3EBD7B3EBD7A3DBC7B3EBD783ABBC6ABE27A3DBC7A3DBC7A3DBC -7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD7D41BE7637BA7332B9CFB8E7CBB4E58952C47535BA -7A3DBC7B3FBD7A3DBC7B3EBD7536BA8F5BC7C0A4DF702FB77D41BE7C3FBD7738BA9260C9 -B595D77434B17A3DB4793CB47B3FB5773AB37536B26E2DAE8B58BDBB9DD9CAAEE5B58CDD -8849C87A33C0803DC38645C68341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58341C58341C58341C58341C58341C58443C57B35C1B994DE -A16FD27B33BF8442C38340C38340C38340C38340C38340C3823FC28442C37C35BFA372D2 -B38ADB7F3AC38340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C57D38C29357CFB39BCC55208B643395623094623094623094623094623094612F93 -623094AF96C97347A05D2A90623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230946230946230946230946230945A278D -8051AE8E8C90000000040404000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000004040400000061645DA679D26629A2743BAC -7339AC7339AC7339AC7339AC7238AB743AAC6F34AA7339ABBC9ED98C55C67333B87D41BE -7A3DBC7B3EBD7B3EBD7B3EBD7A3DBD7B3EBD783DBC8442BC5927BE023FAF007AAA0070AC -0071AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0072AC0073AC -0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AC0070A9 -006FAA0070AA0070AA0070AA0070AA0070AA0070AA0070AA0070AA0070AA006FA90272AB -0570AA0060A02C89B5A391CD6A25A3622AA36B30A7692DA56B30A6733BAB733BAB733BAB -733CAB723AAA7138AABFA4D97B45AE6729A27037A7A07AC4C8B0E09D6FCE6D29B67739BB -7B3FBD7B3EBD7B3FBD7434B9A67DD2A880D37232B87C40BD7B3EBD7B3EBD7A3DBC7D41BE -7B3EBD6C28B59A6CCCCAB2E4A67DD27A3DBC7433B97C40BD7A3DBC7B3EBD7B3EBD7B3EBD -7636BA8E5AC6C0A3DF702FB77D41BE7A3DBC7C40BD702EB79E70CFB797D66B28AC7C41B6 -783BB3793CB4793CB47B3FB57334B17130AF7637B4A076CAC7ACE1B48BDC8B4DC9762EBF -7E39C28341C48443C58240C48341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58341C58341C58341C58240C48443C57932C0AD82D9AF84D87A33BF8442C3823FC3 -8340C38340C38340C38340C38340C38340C3813DC2CAAEE68746C7803BC38340C5823FC4 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C57D37C19A62D2B39ACB -551F8B643396612F936230946230946230946231945A268F7E55A7AB91C6521B89653496 -612F93623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230945C298F7747A8928C99000000010101 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000403040000005D615AA77BD2672AA3743BAC7339AC7339AC7339AC7339AC -7339AC7238AB743AAC6F34AA7339ABBC9ED98B56C67333B87D41BE7A3DBC7B3EBD7A3EBC -7B3DBD783DBC8443BC5927BE0047B2027DAB0070AC0071AB0072AC0071AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0073AC0072AC0072AB0073AC0071AB006FA9006FAA0070AA0070AA0070A90070A9 -0070AA0070AA0070AA0070AA0070AA0070A90070A9006FAA0070A80473A90066A22D93B9 -AC9BD18340AF6A32A6733BAB7138AA7038AA7038A97038A9723AAB6629A39D77C4A582C8 -6425A0743BAA7036A76729A26F35A5A885CAC1A4E08B55C67636BA7A3DBC7D41BE7332B9 -9868CBB18DD86E2BB67D42BE7A3DBC7B3EBD7D41BE702EB77C40BDC2A5E0B08DD77A3DBC -7231B87A3DBC7C3FBD7A3DBC7A3DBD7B3EBD7B3EBD7B3EBD783ABB864EC2996BCC7637BA -7C3FBD7B3EBD7A3DBC7B3FBD7739BBBD9EDC8D59BE7030AF7A3EB5783BB3793BB4793CB4 -793CB47A3EB5793DB3702EAF7637B1A279CAC1A2DEC8ABE5A16ED37F3BC37A34C08443C5 -8443C58342C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C5 -8341C58240C48342C5803DC4CAAFE58644C3823FC28340C38340C38340C38340C2823FC2 -8442C37B33BFA97BD4B38ADB7830C08543C6823FC48340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C57D38C1985ED1B49CCD56218C643395623094623094 -6230946230946230945B278F7F56A7AF95C856208C643395623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094612F93643396531C89A98BC7383D34000000020202000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000001 -000100A89BB57A3EB57137A97339AC7339AC7338AC7338AC7338AC7339AC7238AB743BAC -6F34AA7339ABBC9ED98B56C67333B87D41BE7A3DBC7B3EBD783DBC8543BC5927BE0147B2 -007BAA0070AC0071AB0072AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0071AC -0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AB0073AC -0071AB006FAA0070A90070AA0070AA0070AA0070AA0070AA006FA90070AA0070AA0070AA -006FA9006FA9006FA9006FAA0070A8006FA70372A90065A22E8BB5A2C3DD9563BE6529A3 -733BAB7037A97038AA7038A9723AAB6629A39D77C4A885CA6526A0723AA97137A87239A9 -6F34A76C30A48858B5C0A7D9A77FD27637BB7332B87738BB8C58C5BA9BDC7B3EBD7A3DBC -7D41BE7839BB6F2DB7A379D1BEA0DE9462C97637BA793BBC7C40BD7B3EBD7A3DBC7B3EBD -7B3EBD7B3EBD7B3EBD7C40BD7333B9BEA0DE8248C0783ABB7B3EBD7B3EBD7A3DBC7B3EBD -793BBB793BBCBDA0DD8A53BC7436B17A3DB4783BB3793CB4793CB4783BB3793CB47A3EB4 -793DB46E2CAE7C41B58A55BCB392D5C3A6E2A472D57E38C37933C07F3BC38544C68341C5 -8341C58340C58340C58340C58341C58341C58341C58340C58340C58341C58442C57B34C1 -A97CD6B48CDB772EBD8543C4823FC28340C2823FC28340C3823FC27F3AC1CDB2E78544C6 -823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58442C57A32C1BE9BE07F59A65A258F633194623094623094612F9364339556218C -B8A2CF7347A05D2A91623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094643395 -541E8AAB8DC83A3E36000000020202000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000010102000000A89BB37537B37239AA -7238AB7339AC7338AC7338AC7338AC7338AC7339AC7238AB743BAC6F34AA7339ABBC9ED9 -8B56C67333B87D41BE773CBC8543BD5926BE0247B2007BAA0070AC0072AB0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC -0073AC0073AC0073AC0073AC0072AC0072AC0073AB0071AC0070AA006FA9006FA9006FA9 -006FA9006FA9006FA9006FA90070AA0070A90070AA0070AA006FA9006FA9006FAA006FA8 -0070A70070A8006FA70271A9016AA50067A173AECF9F67C16428A3723BAB7037A97038AA -723AAB6629A39D77C4A885CA6526A0723AA97036A87036A77037A87137A86C30A562239F -9D75C1C7AFE1A175D17B3EBD6924B3BD9FDE8D59C6783ABB702EB7854DC2B391D9B18ED8 -844BC17231B87C3FBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD -7332B9C5ABE28953C47738BB7B3EBD7B3EBD7B3EBD7A3DBC7D41BE7231B89565CBBEA0DA -6C2AAD7A3DB4793CB4783BB3783CB4783CB4783CB4793CB4783BB37B3FB5773AB37435B1 -6E2CAD854FBAB491D4C3A6E2A97BD8945BCE7830BF7F3CC38544C68341C58240C48341C5 -8341C58341C58341C58340C58340C58340C58442C57C37C29B66D0BB97DF7E38C08341C3 -8340C38340C28340C38341C37E39C1B289DAA473D47D37C28341C5823FC48340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C5823FC48543C6772FBFBD99E1 -825DA759248F633194623094623094623094612E93663596B69FCD673797602D92623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094643395531D89AC8FC9383C34000000 -020202000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000201020000006261639F73CA6A2DA6743BAC7339AC7338AC7338AC -7338AC7338AC7339AC7339AC7238AB743AAC6F34AA7339ABBC9ED98C56C67031B88645BD -5926BD0147B2007BAA0070AC0071AB0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC -0071AC0072AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC0073AC0072AC0072AC -0072AC0073AC0071AB0070AC0070AB0070AA0070AA0070AA0070AA0070AA0070AA0070AA -006FA9006FA9006FA9006FA9006FA9006FAA006FA7006FA80070A80070A70070A8006FA7 -0171A80570A80068A272AECF9F67C06428A3723CAB7037A9723AAB6629A39D77C4A885CA -6526A0723AA97036A87037A87036A77037A87137A8733AA9692CA3753EAAAF8FCCB593D8 -8146C2B390D98B56C56E2BB6B593DAC2A6E0A074CF702DB7783ABB7C40BD7A3DBC7A3DBC -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D41BE6F2DB7BFA2DF8953C47738BB -7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D40BE7332B9A176D0A983CF7334B17A3EB4783BB3 -793CB4783CB4783CB4783CB4793CB4783BB3793CB4793CB47B3FB57536B26F2EAE844DBA -B08DD2BC9DDBBD9AE08F54CB7831C0803DC38240C48443C58341C58240C48341C58340C5 -8340C58340C58240C48544C67932C0C2A3E28C4EC6803BC18340C38340C28340C37F39C0 -955CCCC6A8E5762DBF8543C6823FC48340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58543C6782FBFBE9BE1825DA75A258F633194623094 -62309463329556208C9473B69B7BBA541E8A643395623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946331945B288E8257AE7E7A82000000020102000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000020202 -0000003B4036B08CD46425A2753CAD7238AB7339AC7339AC7339AC7339AC7339AC7339AC -7339AC7238AB743AAC6F34AA7339ABB89DD8985EC75521BC0148B2017BAA0070AC0071AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC0072AC -0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AC0073AC0071AC0070AC0071AB -0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AB006FA90070AA0070AA0070AA -0070AA0070A80070A80070A7006FA7006FA7006FA8006FA8006FA70070A8036FA80068A2 -71AED09F67C06428A3733CAB723AAB6629A39E78C5A784C96526A0723AA97037A87037A8 -7037A87036A77137A87138A8733AA97138A861219F8555B3B291D2C1A4E0DAC8ECB18ED8 -A176D07738BB7130B87D41BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7739BB8750C3BC9EDD7D41BE7A3CBC7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7A3DBC7D42BE6C28B5C1A4E09464C26F2DAE7A3EB4783BB3783CB4783CB4793CB4 -793CB4793CB4793CB4793CB4783BB3793DB47A3EB47739B36B28AC7436B19768C3C3A6DE -BC98E08E52CB8442C67932C08342C58442C58342C58341C58240C48341C58341C58442C5 -7D37C2AF85D9A879D47D37C08341C3823FC38543C47931BEC3A2E1965DCE7F3AC38340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58543C6782FBFBE9BE1805AA65A258F63319462309462309463329556218C916EB4 -A183BF541E8B643395623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094612F93 -602F9265309AA39AAD000000010102000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000010101000000272A23AA8FC47034AC -7339AB7339AC7339AC7339AC7339AC7339AC7339AC7339AC7339AC7339AC7238AB743AAC -6B32AA8042AC8F76D60146B2007BAA0070AC0071AB0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC -0072AC0073AB0072AB0072AB0071AC0070AB0071AC0070AC0070AB0070AB0070AB0070AB -0070AB0070AB0070AB0071AB0071AC0071AC0071AC0071AC006FA9006FA7006FA80070A8 -0070A80070A80070A70070A70070A7006FA70070A8036FA80068A273AED09F68C16524A2 -703AAA672AA4976EC0A886CA6426A0733AA97037A87137A8733AA9743BAA6D32A6682BA3 -692DA36A2EA46E33A5956BBE9871C0DBCCE9EFE6F7AD88D66A26B47E42BE7D41BE7A3DBC -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD7130B8 -A176D0AC86D56E2BB67D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD793BBC -834AC1BB9BDA8046B77739B3793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 -793CB4793CB4783BB3793CB47B3FB5793CB47231B07232B09768C3C5A9DFC6A9E1AB7ED9 -803DC47B36C17D38C28544C58341C58240C48341C58341C57F3BC38F53CABF9DE1772EBD -8544C48341C37D37C0975FCDC1A0E27B34C18442C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C57F3BC39154CD -B89FD25B278E633195623094612F93623094602E93B9A3CF683898602E93623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230946230945F2D916C389FA69EAD000000 -020102000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000040404000000918E948C54C36C32A67339AC7339AC7339AC -7339AC7339AC7339AC7339AC7238AC7339AB7238AC723AAB8241AA5120B10040AE017BAA -0070AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0072AC -0073AC0072AC0073AC0073AC0073AC0073AC0073AB0072AC0072AB0073AC0071AC0070AC -0070AB0071AB0070AB0070AB0070AB0070AB0070AB0071AC0071AB0070AB0070AB0071AC -0071AC0070AC006FA8006FA6006EA5006EA6006EA5006FA5006FA5006FA6006FA8006FA8 -006FA80070A8006FA80070A8046FA80069A26FAACDBDA9D97639AB6A31A7BC9FD7804DB2 -7036A77238A86D32A66D32A66628A161219E7F4BB08C60B89C73C2C9B0DEC3AADAAC88D1 -AB85D1905FC2C9B2DFA885CFAA82D46C28B5793BBB7C3FBD7A3DBC7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD7231B8A176D0B390D9702EB77D41BE -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D41BE6E2BB6A379D2B392D46A27AB -7B3FB5783BB3793BB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 -793CB4783BB37A3DB47A3DB47231B07131AF7D42B5AB87D0C9AEE3A777D69860D07932C0 -7E3AC28442C58442C58240C48341C5813EC4BD9BE0955CCB7E38C08543C47931BEC3A3E1 -975FCE7E38C28341C5823FC48340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C5823FC4813EC38845C9C0A9D85B288E633195623094 -6230945F2C926D3F9CB9A3CF5C288F633194612F93623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094602E9167349C9893B6040601000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -040304000000918D948C55C26C32A67339AC7339AC7338AC7338AC7339AC7339AC7238AC -7339AB7138AC763CAB6E31AD3513B6054BB2007CAB0070AC0071AC0072AC0071AC0072AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC -0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC -0071AC0071AC0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC -0073AC0073AC0072AC0072AB0073AC0070AB006FA90070AA0071AC0071AC0071AC0071AC -0071AC0071AC0071AC0070AB0070AC0071AC0071AC0070A9006FA8006FA6006EA5006EA5 -006FA6006FA6006FA6006EA6006EA6006EA6006EA6006EA6006EA6006FA6006FA5006FA7 -0070A8036FA80069A4168AB3A3A6D37E3EAEBDA4D86426A06324A06B30A47C48AE7D48AF -B697D2BC9FD5B89AD5BC9FDBAA85D07D41B68147B9702FAF6824AA8650BBBEA2DA5F1AA5 -A681CDC5AAE2854DC27434B97D41BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7C40BD7231B89B6CCDB28ED86F2DB77D41BE7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7434B9AE87D69C70C77333B07A3EB4783BB3793CB4 -793CB4793CB4793CB4783CB4783CB4793CB4793CB4793CB4793CB4793CB4783BB3793CB4 -793DB47A3EB5773AB36F2DAE7C41B5AF8BD2BD9FDAC2A2E2965DCE7B35C17D38C28443C5 -8646C6772FBFB791DDA270D17C36C07F3BC19A63CEBD99E07C36C18441C5823FC48340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C5813DC38A49CAC1A9D85C298F633195623094643395541E8AA98EC48863AE -58238D633194623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094612F94 -643295531F897F67CD5E615A000000040404000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000001010100000023261FB499CE -6B2DA8743BAC7339AC7338AC7338AC7338AC7238AC7339AB7138AC753CAB7333AC1A1EB6 -0045B3017BAA006FAC0071AC0072AB0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC -0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0072AC0073AB0073AC -0071AB0070AA0070A9006FAA0070AA0070AA0070AA0070AA0070AA0070AA0070AA0071AC -0071AB0070A8006FA6006FA6006EA5006EA5006FA6006FA6006EA5006FA6006EA6006FA5 -006FA5006FA5006FA5006FA5006FA5006EA5006EA5006EA6006EA6006FA60371A70065A1 -1781AFA7AED7CAA8DB8F64BBAF8ECDAF8FCEC5ADDFC1A7DC9463C39361C37B3FB56A26AB -702FAF773AB37639B27A3EB57739B38953BDC2A7DC6C2EAD7134B08B59BDBA9CD98A53C5 -7231B87C40BD7C3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3CBC -986ACB8045BF793CBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7C40BD6F2DB7C8AFE38751BB7233B07A3DB4783BB3793CB4793CB4783CB4783CB4 -783CB4783CB4793CB4793CB4793CB4783CB4783CB4783CB4793CB4783BB3793CB47A3EB5 -773AB36E2CAE702FAF8E5BBFBEA1DBC09FE1975FCF7E38C37C37C17F3BC38E52CAC8ABE4 -7C36C08645C4CEB3E77E38C38340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5813DC38B4ACB -BEA6D658238C643295612F93653496531C8AA386C08B66B058228D633194623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230946230946332955520899F77BF5E625D -000000030303000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000191E15B49ACE6727A6753DAD7238AB7338AC -7338AC7238AC7339AB7138AC753CAB7230AD1B29B40072AC037AAA0070AC0072AB0071AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC0072AC0073AC0073AC0072AC -0073AC0073AC0073AC0073AC0072AC0073AB0073AC0071AB0070AA0071A90070AA0070A9 -006FA9006FA9006FA9006FA9006FA9006FA9006FA90070AB0070AA006EA5006EA5006EA5 -006FA6006FA6006EA5006FA5006FA5006FA6006FA6006FA5006FA5006FA5006FA5006FA6 -006EA6006FA5006FA6006FA5006FA5006FA5006EA50271A60067A2167AACE6F5F7B992D6 -9A6BC79767C56E2CAE7232B07233B07232B0783AB37C40B57A3EB4783BB3793CB4793CB4 -7536B18852BDC1A6DB6B2CAC783FB46C2EAD783EB3C2A8DEB290D8702FB87637BA7C40BD -7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBDC7AEE3793CBC7B3EBD7A3DBC -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C3FBD7738BA8E5AC6 -BA9BD97637B1783BB3793CB4793CB4793CB4783CB4783CB4783CB4783CB4783CB4793CB4 -783CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4783BB37B3FB57A3EB57434B1 -6E2DAE9260C0BA9AD9CDB4E6AE84DA894AC87125BCB690DD9C66CEAC80D7AA7CD77B34C1 -8442C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58341C57C36C2B58DDC8A66AD59238E643295 -5E2B916D3F9BB49CCC623194612F93623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094633295541F899B76C25E615A000000040404000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000008C83948A54BF6D32A7733AAC7338AC7238AC7339AB7138AC753DAB -7230AD1A29B40071AC0274AB006FAC0072AB0071AC0071AC0071AC0071AC0071AC0072AC -0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0072AC0072AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0072AC -0073AB0073AB0071AB0070A90071A90070AA0071A90071AA0070AA0070AA0070AA0070AA -0070AA006FA90070AA006FA8006EA7006FA8006FA6006FA6006FA6006FA5006FA5006FA5 -006FA6006FA6006FA6006FA5006FA5006FA5006FA5006FA6006FA6006FA5006FA6006FA6 -006EA5006EA5006EA6006FA60273A90070A7BEC7E3C09DD99A6EC76924AA7D42B67A3EB4 -793DB4793DB4793CB4783BB3793CB4783CB4783CB4793CB47536B18852BDC1A6DB6B2CAC -773CB3763CB27338B16D2FAD976BC5CAB2E3915EC87130B87D41BD7B3EBD7A3DBC7B3EBD -7B3EBD7B3EBD7A3DBC7B3EBDC7ADE37B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7231B89361C9BD9FDA702FAF7B3FB5 -783BB3793CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4783CB4783CB4783CB4 -783CB4793CB4793CB4793CB4783CB4783BB3793CB4793CB47B3FB57131B07537B1783CB3 -A57DCBC7ACE1A97BD7AA7CD8BB97DDBA96DF8443C5813EC48442C58442C58340C5823FC4 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C5823FC58442C57830BFAD7EDB9A7BB8551F8C6433955C28907B51A5B49CCB541D8A -653496612F93623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094612F93633295 -643396602B8D6741AE7E81A3040300000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000404040000006F716D -9B69CD682CA3743AAC7238AC7339AB7138AC753DAB732FAD1929B40071AC0274AB0070AC -0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC -0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AB0071AC0070A90071AA -0070AA0071AA0070AA0070AA0071AA0070AA0070AA0070A90070AA006FA90070AA006FA9 -006EA7006FA8006FA8006FA8006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6 -006FA5006FA5006FA6006FA6006FA6006FA6006EA5006EA5006FA60071A70072A90073AC -0072AC007AADACB0D97735ABA886CBAB84D06E2CAE7B3FB5793CB4783BB3793CB4793CB4 -783CB4783CB4793CB4793CB47536B18852BDC1A6DB6B2CAC773DB37439B1753AB2763BB2 -6F31AE7E48B6B696D69767CC7232B87A3DBC7C40BD7A3DBC7B3EBD7A3DBC7B3EBD783ABB -C7ADE37B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7A3DBC7D41BE7130B8BA9CDD9464C26F2EAE7A3EB4783BB3793CB4783CB4 -783CB4793CB4793CB4793CB4793CB4793CB4783CB4783CB4793CB4793CB4793CB4793CB4 -793CB4783CB4793CB4793CB4783BB37A3DB4793CB4793CB46E2CAE783CB3A57ECCBB99DB -F1EAF9C1A0E27A31C28644C77931C07931C0823FC48443C58340C58341C58340C5823FC4 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58442C57830BF -B286DD9373B4551F8B66369758238DB39BCB774CA25D2A90623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094612F9362309462309463319464339659248E58238D5C288E8560B3E1E4E8 -020100000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000030303000000565854A37ACB6B2EA7733AAC7339AB -7138AC753DAB722FAD1B2AB40071AC0274AB0070AC0072AB0071AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0072AC0073AC0073AC0071AB0070AC0071A90070A90071A90071A90071A90071A9 -0070AA0071AA0070AA006FAA0070A90070AA006FA9006FA8006EA7006FA8006FA7006FA7 -006FA8006FA8006FA7006FA5006FA5006FA6006FA6006FA6006FA5006FA6006FA6006EA5 -006EA5006EA50070A60071A80073AC0074AC0074AC0376AD0068A55BABCBD5BBE3682BA6 -682AA5A47EC8AB84D06C29AD7738B27A3DB4783BB3793CB4793CB4793CB4793CB4793CB4 -7536B18852BDBEA2DA6A2BAC773DB37439B1753AB27439B1763CB27033AF6F33AEB899D7 -BEA0DE7739BB7434B97C40BD7A3DBC7C40BD7130B8A880D3A87FD37333B97C3FBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBC7637BBB998DB8E5CC07435B17A3DB4783BB3793CB4793CB4793CB4793CB4793CB4 -793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 -793CB4793CB4793CB4783BB37B3FB57A3DB46620A9A077CAFFFFFFE0D2EFC1A5DDC5A8E1 -A97AD8AD80DA8543C67A32C17D38C27C36C1823FC48544C68340C58340C58340C5823FC4 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C58340C58340C58340C58340C58442C57B34C0A572D7A385C15A258E663697 -531D8AB199CA7549A15D2990623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094612F93623094612F936332956534965E2A91 -5A268F5B268F56208B855EAC9877B9BDA9D2B8A0CFCEC3D7262825000000010101000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000200B1A3BF7537B17239AA7138AC753CAB7230AD1B29B40070AC -0274AB0070AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC -0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AC0071AC -0070AC0071AC0070AB0071AB0071AB0071AB0071AC0071AB0071A90070A90071A90070A9 -006FA9006FA9006FA8006EA7006FA8006EA7006FA7006FA8006FA7006FA7006FA7006FA8 -006FA7006FA5006FA5006FA6006FA6006EA5006EA5006FA50070A70072AA0074AB0074AC -0074AC0073AB0073AB0476AD0067A46EB4D19C60BE682EA7763DAE682AA59E76C5CAB2E1 -854EBB7231AF7C40B5783BB3783BB3793CB4793CB4793CB47536B18751BCC6AEDE6E31AE -763BB2753AB2753AB27439B27439B1753BB2753AB26B2CAC8957BCCBB4E49F72CF702EB7 -7B3FBD7D42BE6F2DB7B391D99D70CE7230B87C40BD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3FBD7637BA854EC3CAB1E1 -6E2CAD7A3DB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 -793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4783BB3793CB4 -7A3EB56E2CADAB87D0A376CABD9DD9BB9DD87D4AB6763FB0AC8CCFA885CDC2A6E0C5A7E3 -9A62D19C65D2823EC5762CBE803CC3803DC38340C58543C68442C5823FC48340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 -8340C58340C5823FC48442C57C35C3C3A8DF693B975A258F794FA4AC92C65F2D92623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -612F93623094643395623094602D9258248D521B8971449E7A4FA49D7EBCC1ADD5A68AC2 -9D7EBC59248E7950A2FFFFFF807F81000000040404000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000300 -B2A3C07436B17138AB753CAB7330AD1929B40071AC0274AB0070AC0072AB0071AC0071AC -0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC -0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC -0072AC0071AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC0073AC0073AC0073AC -0073AC0073AC0073AC0072AC0073AC0073AC0071AC0070AC0071AC0070AC0071AB0071AB -0071AB0071AB0071AB0071AB0071AB0071AB0070AB0071AB0070AB006EA7006EA8006FA8 -006EA7006FA8006FA8006FA8006FA8006FA8006FA7006FA7006FA7006EA7006FA7006FA6 -006EA5006FA60071AA0074AB0074AB0074AC0073AB0073AB0073AB0074AC0073AC0476AD -0067A46DB3D0A168C1682DA6743AAC743AAC6D31A87E49B2BA9CD68954BD6B28AC7A3EB4 -793CB4783BB3793CB4793CB4793CB47537B2D9C8E99468C46D2EAD763BB2743AB2743AB2 -753AB27439B1753AB2773CB37033AF753AB2AC8AD0A57AD27636BB7B3EBC702FB7AD88D6 -A277D07130B87C40BD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7535BA9B6DCDB08BD27233B07A3EB5783BB3 -793CB4783CB4793CB4793CB4793CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4 -783CB4783CB4783CB4793CB4793CB4793CB4783BB37A3DB46E2DAEA881CEAC84D06820A9 -CFB8E3AD85D0C3A9DD682BAA682BAA6628A97741B18251B8B99CD8BA9FD8BE9DDEBF9CE1 -8F51CB8A4AC9803BC3762DBE7B34C18442C58341C58341C58341C5823FC48340C58340C5 -8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58341C5 -7F39C4C5ABDF693B9756208C8B66B0A183BF531C89653496612F93623094623094623094 -623094623094623094623094623094612F93623194633194633295612F93531C895F2C91 -6636979573B6B7A0CDDBD0E7B59ECD8E6BB26A3B995B278F541E8A612F939C7EBBE4D9F1 -A499A90B0D07000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000020202000000565853A67ED2692EA27532AE -1A29B40071AC0274AB0070AC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0072AC0071AC -0071AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0072AC0073AC -0073AB0071AB0070AB0071AB0070AB0070AB0070AB0071AC0071AC0071AC0071AB0071AC -0070AC0070AB0071AC0070AB0070A9006FA6006FA7006FA8006FA7006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA60072AA0074AB0074AC0073AC -0073AC0073AB0073AB0074AC0074AC0073AC0073AC0476AD0067A46EB4D1A067C1682DA6 -743AAC7339AC743BAC6D30A8753CADB89AD6A67CCD7434B1783BB3793CB4783BB3783BB3 -7B3FB56B29ACAD88D19A70C76C2CAC763BB2743AB2743AB2743AB1753AB1753AB27439B1 -763BB27338B16B2CACAA86CFC5ADE18248C16E2BB6B99ADC9463C97535BA7C3FBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7A3DBD7A3DBC7D41BE6D29B5B28ED9A57ECC6B28AC7B3FB5783BB3783CB4793CB4793CB4 -793CB4783CB4783CB4783CB4783CB4793CB4793CB4783CB4783CB4783CB4783CB4783CB4 -793CB4783BB37A3EB57232B0A47BCCAA82CF712DAE7534B19E70C8B796D69562C2A986CD -6D31AC763FB27137AF6F34AE682BA96425A78351B89267C0BFA4DCC9B1E1B894DDB287DC -A675D67C35C27E38C37B34C07D37C28543C68442C58340C58340C58340C5823FC58340C5 -8340C58340C58340C58340C58340C58340C58340C58341C57F39C4C5ABDF6536945F2C92 -B69FCD6C3D9B602D92623094623094623094623094623094623094612F93623094623094 -6331946535965C299059248D5A258E6737979A7BBAA78BC3C4B1D79674B78158A96F429D -511A885B268F5F2C92623194643395633194B198CAA88BC09C86D0484C50000000010102 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000030303000000474D44B98DD5661AA41D2DB60071AC0274AB0070AC0072AB -0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC -0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC0072AC0073AC0073AC -0072AC0073AC0073AC0073AC0073AC0072AC0073AC0073AB0071AC0070AC0071AC0071AC -0071AC0071AC0071AC0071AB0071AB0071AB0071AC0070AB0071AC0071AC0070AA006EA6 -006EA5006FA5006EA7006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA8006FA7 -006FA8006EA7006FA70071AB0072AC0073AC0074AB0073AC0074AB0073AC0073AC0074AC -0074AC0073AC0073AB0476AD0067A46DB2D0A066C1682DA6743AAC7238AC7238AB743BAC -7035AA7035AAD9CAE8BA9AD8702FAF793CB47A3EB4783BB37B3FB56D2BADB593D5996FC7 -6C2DAC763BB2743AB2743AB2743AB1743AB1753AB1743AB17439B1753AB2763CB36D30AD -8049B7B594D7A075D0BB9CDD6925B47E43BE7D41BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD793CBC -8045BFB99ADA834BB97739B3793CB4783CB4783CB4793CB4783CB4783CB4783CB4783CB4 -783CB4793CB4793CB4783CB4783CB4783CB4783CB4793CB4783BB37A3EB47436B17E43B7 -CBB3E27431AF7C3EB57533B0915CC0BC9DD9671EA8CAB2E18352B97035AE733AB0733AB0 -753DB1763EB16E34AD6B2FAB6D33AC682BA98D5FBEA481CBAA86CECEB6E6B48DDB9E68D3 -9B64D1782FBF7B35C1803BC37F3BC38442C58543C68340C5823FC48340C58340C58340C5 -8340C58340C58340C58341C57E38C3C0A2DE73489E57218DB9A3CF623194612F93612F93 -623094623094623094612F936230946433956331945E2B915B278F511A88764BA28863AE -B8A2CEB7A1CE9C7CBB8058A956208C5B278F59248D5E2B91653496633194623094643295 -57228C9877B88E6BB2B59CC96740AA908CA0000000030203000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000030203000000 -4C4A448878DB0937A7006FAE0275AB0070AC0072AB0071AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC -0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC -0072AC0071AC0072AC0072AC0073AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC -0072AC0073AC0073AB0071AC0070AB0070A90070AA0070A90070AB0070AC0070AB0070AC -0071AC0071AC0070AB0071AC0070AA006FA8006FA5006EA5006FA6006EA5006FA7006FA7 -006FA8006FA7006FA8006FA8006FA8006FA8006FA8006EA8006FA8006EA70070AA0072AC -0071AB0072AB0073AC0074AC0073AC0074AC0074AC0074AC0074AC0074AC0074AC0476AD -0068A571B6D2A067C1682DA6743AAC7339AC7339AC7238AB743AAC7238AB6626A4966BC0 -B695D66F2EAE7232B07B3FB57B3EB56D2BADB491D4996FC76C2DAC763BB2743AB2743AB2 -753AB27439B1753AB2763CB2763BB2753BB27438B16A2AAC6C2DAD8654BBEAE0F3F3EDF9 -8C58C67738BB6E2BB6793CBC7B3FBD7C3FBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7231B89260C9C2A7DD6A26AB -7B40B5783BB3793CB4793CB4793CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4 -783CB4783CB4793CB4783BB37A3EB47536B17B3FB5BEA0DA864CBA7838B27C3EB47432B0 -9461C2BD9ED96D28AC8951BC966DC5692CAA743CB17239AF733AB07239AF733AB0743BB0 -743BB0753DB16D31AC6628A96D31AC733BAF946AC2B99ED7B596D6C7AAE5B086DA8C4CCA -8F52CB7931C0772DBF7F3BC38341C58341C58442C58340C5823FC48340C58340C58341C5 -7B35C1A069D5A68BC2764BA2A88CC45D2990623094612F93623094633295633295623194 -623094541D8A5B278F6D3E9B8E6AB2BAA4D0AD93C7AB91C670429D633295541E8A5B278F -643395623194633194623194612F93623094623094643395551F8BAB91C67D54A6B098C9 -73419E9D85B1252823000000010101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000104000000060B57075CBD007BA80172AB -0071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC -0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AC0073AC0071AB0070AB -0071AC0070A9006FA7006FA7006FA8006FA8006FA80070AA0071AA0070AA0071AC0070A8 -006EA5006EA5006FA6006FA6006EA5006FA6006FA5006FA6006FA8006FA7006FA8006FA7 -006FA8006FA8006EA8006FA8006EA7006FA80072AC0071AB0072AC0071AB0072AC0073AC -0074AC0073AC0074AC0074AC0074AC0074AC0074AC0070AA0D7EB1D7DAED824BB46F34A9 -733AAC7339AC7339AC7339AC7238AB7339AC753DAD6829A59265BDC0A4DB905EC1702FAE -7D43B66D2AADB491D5996FC76C2DAC763BB27439B1753AB2753AB2773DB3753BB26C2DAD -6C2CAD7034AF7A42B4AA88CFB596D7C9ADE3A277CFE5D9F1EAE2F2B18ED6B38FDA834AC1 -7738BB7231B87B3FBD7D41BE7B3EBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7536BAA981D3A379CB7030AF7B3FB5783BB3793CB4 -793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4783BB37A3EB4 -7536B17A3FB5BFA1DA8951BC7432B07C3EB47B3CB47432B09360C2BE9FDA722FAF7331AF -A378CA9A71C56B2EAB743CB17239AF733AB0733AB0733AB0733AB07239AF743BB0753DB1 -733BB07239AF6C31AC6426A86C31AC8453B89D76C8C7AFE0C0A5DCB68EDDBB95E09358CD -7F39C37C35C17931C0803CC38544C68340C58340C58441C57B35C1A26CD79F81BE906CB3 -8E6AB256218C64339564339563319457228D56218C5D2A916332959D7EBCA78CC3BFABD4 -9D7EBC784DA3612F93511A895F2C92612F93643395633194612F93623094623094623094 -6230946230946230945D2A9172469FAD93C78963AEA689C2470E819D79C250544C000000 -030303000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000030000000005510057BB0179A9016FAC0071AC0072AB0071AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0073AC0073AC0072AC0072AC0073AC0071AC0070AB0070AB0071AC0070A9006FA7 -0070A80070A70070A7006FA7006FA7006FA7006FA8006EA8006EA6006FA5006FA5006FA6 -006FA6006FA6006FA6006FA5006FA6006FA8006FA7006FA8006FA8006FA8006FA7006FA8 -006FA70070AA0072AC0071AB0071AB0072AC0071AC0071AC0073AC0073AC0073AC0073AC -0074AC0074AC0074AC006EA9198CB7B49FD56725A4753DAD7238AB7339AC7339AC7339AC -7339AC7339AC7238AB753CAD6B2DA78756B7B89AD59565C47130AF7130AFB491D5996FC7 -6C2CAC773DB3783EB37236B07032AF6A2BAC7135B0986EC5996EC5C2A6DEC6ABE1A67CD3 -9563C96E29B58951C4BB9BD98F5ABFC3ABDA9469BFC2A8DEC4AAE09F72D07637BB7130B8 -7536BA793BBB7D41BE7A3DBC7B3EBD7A3DBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC -7B3EBD7C3FBD6E2BB6BC9DDD9969C46F2DAE7B3FB5783BB3793CB4793CB4793CB4793CB4 -793CB4793CB4793CB4793CB4793CB4783BB37A3EB47536B17A3FB5BFA1DA8950BC7431B0 -7D3FB57A3BB37B3DB47432B09562C2B795D66D28AC7C3EB48245B8C7B0E06E33AD733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB07239B0733AB07239AF743BB0763EB1 -743BB06D32AD6C30AC682CAA6D32AC9A72C59870C3BA9CDACBB3E4A979D7A979D88E50CA -772DBF7E39C27D38C2823FC47E3AC2A16BD5AE94C7A386C06D3F9C5F2C915C289057218C -5D2A918660ADAD92C7D1C3E0B8A1CE9776B8845DAB551F8B5A268E5B278F612F93653496 -623094612F93623094623094623094623094623094623094623094612F9364339557218C -AC92C7784DA38D69B19F80BD521C887141A19A91A3000100000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000300000000034F0059BD -007AA9006FAB0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC -0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0072AB -0073AB0071AB0070AC0071AB0071AC0070AB0071AC0070A9006FA70070A8006FA80070A8 -006FA80070A8006EA7006FA7006FA7006FA8006FA7006FA5006FA5006FA6006FA6006FA6 -006FA6006FA6006FA8006FA7006FA8006FA8006FA8006EA70071AA0072AC0071AB0072AC -0072AC0071AC0072AC0072AC0071AC0073AC0074AC0074AC0073AC0074AC0074AC006EA9 -178AB6BAA8D96B2AA6743CAD7339AC7339AC7339AC7339AC7339AC7339AC7339AC7238AB -753BAD6C2FA86B2EA7B595D3996BC65E15A5B592D59A70C76C2CAC7034AF6524A97E48B6 -8B5ABDB999D8D4C1E7D3BEE9B08BD78950C37A3BBC7331B87736BA7C3EBC8B54C4C5ABDF -6A23AAA174CAA079C86527A57B46B2AF90CFC3A9E0BA9BDD8F5AC88147C16F2DB67A3DBC -7B3EBD7C40BD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7739BB8851C4 -BDA0DB783CB37638B2793DB4783BB3793CB4783CB4783CB4793CB4793CB4793CB4793CB4 -783BB37A3EB47536B17B3FB5BFA1DA8950BC7431B07D3FB57A3BB37B3CB47B3DB47635B1 -8B54BDE1D3EE8044B77A3BB37635B1905BC0BA9ED9692DAA743CB17239AF733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0733AB0743BB0753DB1 -743BB06A2DAB682BAA6F36AD733BAFA886CEAE8ED0BB9CDACAAEE69E69D2965BCF8948C8 -7429BD7B34C2C9B1E2BDA9D042057E6D3F9C784DA3AD93C7B9A3CFA487C1AA8FC57549A1 -5E2B9158238D59248E653496633194623094623094612F93623094623094623094623094 -6230946230946230946230946230946230946332955A268FBBA5D0643295906DB39F81BE -56208B5F2A95AFA0BD0B0E08000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000010400000000034F0059BD007AA9006FAB0072AC0071AB0071AC -0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0073AC0073AC -0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0071AC0070AC0071AB0070AB -0070AB0070AB0071AB0070AC0070A9006FA70070A8006FA7006FA8006FA7006FA8006FA8 -006FA8006FA8006FA7006FA7006FA7006FA5006FA5006FA5006FA5006FA6006FA8006FA7 -006FA8006FA8006EA70070AA0072AC0071AB0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0072AC0073AC0074AC0073AC0074AC006EA9188BB7B9A6D96A29A6743CAD -7339AC7339AC7339AC7339AC7338AC7338AC7339AC7339AC7339AC753CAD7339AC6E33A9 -B596D3A67DCDB28DD3966BC56B2CAB9568C3B99AD8BC9EDCC0A4DF905BC78A51C37736BA -702CB67B3CBB7D3FBD7E41BD7E40BD7939BB8952C4C4A9DE7533B07230AFA67BCCAB89CE -6628A76324A57E4AB48C5EBCBFA6D9BEA3DBAA82D57D41BF783ABC7232B87D41BE7B3FBD -7B3FBD7B3EBD7A3DBC7B3EBD7B3EBD7A3DBC7C40BD7433B98B56C6BD9FDB7639B2793CB4 -783BB3793CB4783CB4783CB4783CB4793CB4793CB4783BB37A3EB47536B17B3FB5BFA1DA -8950BC7431B07D3FB57A3BB37B3CB47B3CB47B3CB47D3FB5702DAEBFA0DA9461C27432B0 -7D3FB57330AFBB9BD88A5ABC6E33AD743BB07239AF733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0743CB0743CB0733AB0 -7239B0682BAA6425A8763FB1804EB6B292D3C1A8DCBC9CDDC19EE3A878D6BD9AE0CBBDD9 -A486C1B198CAB9A2CF7F56A86D3F9B551F8B531C8A5E2A91623094633295633194612F93 -623094623094623094623094623094623094623094623094623094623094623094623094 -62309463319558228D8660ACAB90C54A10839776B89F81BE56208B5A278D9168BA747672 -000000040404000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000103000000 -0004500059BD007AA9006FAB0072AC0071AB0071AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC -0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0072AC -0071AC0071AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC -0072AB0073AC0072AB0071AA0070AA0070AB0071AC0071AC0071AC0071AC0071AC0071AC -0071AC0070A9006FA70070A8006FA7006EA8006FA8006FA8006FA8006FA7006FA8006FA8 -006FA8006FA7006FA7006FA6006FA5006FA5006FA6006FA8006FA8006FA7006FA80072AC -0071AB0072AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC -0073AC0074AC0074AC006EA91788B5B8A4D76A2AA6743CAD7338AC7339AC7238AB7339AC -7339AC7339AC753CAD753CAD6D31A96C2EA86D30A86B2FA76525A3AE8ECEFCFBFCB494D7 -C6AEE1B391D89D6DCD8043BE702CB67939BB7939BB7D40BD7F42BE7D3FBD7C3EBC7D3FBD -7D3FBD7939BB8B54C5BFA2DB6F2AAD7F43B6712DAE9E70C7E5DBF08859BB6729A77137AC -6526A57740B0A27DC9CAB3E0BA9ADB9665CB7130B87536BA7333B97B3EBD7C40BD7A3DBC -7B3EBD7B3EBD7A3DBC7E43BE6D2AB6B594DAA074C96D2BAD7A3EB4783BB3783CB4783CB4 -783CB4793CB4783BB37A3EB47536B17B3FB5BFA1DA8950BC7331B07D3FB57A3BB37B3CB4 -7B3CB47B3CB47A3BB37D3FB56F2BADBB9AD89461C27432B07B3DB47B3CB47634B1CAB2E0 -763FB17035AE733AB07239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0753CB1763EB17138AF -6F34AE6A2EAB6425A77C48B5946BC19B73C6FAF7FDA285BF8761AD6B3C9A521B895D2990 -5E2B91643395643395623094612F93623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230946230946230946331945B268F9878B9 -9776B84B12849675B79F81BD551F8B5C2A8F8052AE88848C000000010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000300000000044F0059BD007AA9006FAB0072AC -0071AB0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC0073AC0072AC -0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AB0070AA006FA9 -006FA90070AA0070AB0070AB0070AB0070AB0070AB0070AB0070AB0071AC0070A90070A7 -0070A8006EA7006FA8006FA8006FA8006FA8006FA8006FA7006FA7006FA8006FA8006FA7 -006FA6006FA6006FA5006FA7006FA8006EA70070A90072AC0072AC0072AC0072AC0072AB -0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0074AC0174AC006DA8 -2793BBBDA8DA6929A5743CAD743AAC753CAD753CAD7238AB7035AA6E33A96728A46627A4 -8756B78E60BB8D5EBABEA2D9C9B2DFA57DD0C8AEE4EFE6F67533B97634B97533B87C3DBC -7F43BE7D3FBD7D3FBD7D3FBD7C3EBC7C3FBD7C3FBD7C3EBD7D3FBD7B3CBC8045BFE2D5F0 -8D57BE7635B17D40B5722FAF9967C5BFA2DA8656B96B2EA97842B17036AC6C30A96B2FA9 -8757B9B496D5CBB3E3AA84D49360CA783ABB7332B9793BBC7C3FBD7B3FBD7A3DBC7A3DBC -7C40BD7535BAB594D99463C27435B17A3DB4783BB3783CB4783CB4783BB3793DB47537B2 -7B3FB5BEA0DA8950BC7331B07D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47D3FB5 -702BADBD9DD99461C27432B07B3DB47C3EB47432B09D6EC7AA87D06E33AD743CB07239AF -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0733AB0743CB1763EB17138AF -6323A78A5BBCD3C1E89976BB511B88612F93653496623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094612F936331945B278FB7A0CE62309456218C9472B69F81BD -541E8B673797541D8AAF94C72E322B000000010101000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000400000000024E0059BD007AA9006FAB0072AC0071AB0072AC0072AC0072AC0071AC -0071AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC -0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC -0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC -0073AC0073AC0072AB0072AB0073AB0070A9006FA90070AA0070AA006FA9006FA9006FA9 -006FA9006FA9006FA9006FA9006FA90070AB0071AC006FA9006FA7006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA7006FA7006FA8006FA8006FA8006EA6006FA5 -006EA70070A90072AC0071AB0071AB0071AB0071AB0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0476AD0067A49AC9DEB484CD682DA6763DAE -6D31A96627A46626A47339AB7A44AF8757B7BC9FD7B89AD4BC9DDCBD9FDEBC9EDD8952C5 -8449C27C3EBEB08BD59867C3BB9BDB7E41BE7B3CBC7E41BD7C3EBC7D3FBD7D3EBD7D3EBD -7C3FBD7C3FBD7C3FBD7D3FBD7D3EBD7F42BE712EB7B48FD9A074C8722EAF7C3DB47D3FB5 -722FAE7938B3BC9ED98757BA6A2DA8763EAF733AAE753DAF6C31AA6D32AA7842AF9C74C5 -BCA2D9BFA4DE9A6BCD8046C07332B97738BA7C40BD7B3FBD7C3FBD7A3CBC783ABCCFB8E5 -7537B1783BB3793CB4793CB4793CB4793CB4793CB47A3EB4BC9DD98A51BC7331B07D3FB5 -7A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47D3FB5702BADBC9CD99563C37432B0 -7B3DB47A3BB37D40B56B25ABBE9FDA9368C2672AA9753CB17239AF733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB07239AF753CB16F35AEC1A7DC864FBEB59CCE -57228C653496612F93623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -6331945B288F8159A9A68AC2602D9256218C9472B69F81BD541E8B6433955D2A8F7848A8 -939097000000040304000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000010001050000000004500059BD007AA9 -006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC -0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0072AB0073AB -0070A9006FAA0070AA006FA90070A90070AA0070AA0070AA0070AA0070AA0070AA0070AA -0070AA006FA9006FA9006FA9006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA7006FA7006EA7006FA8006EA7006FA90072AE0072AD0072AD -0072AD0072AD0072AC0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB -0071AB0072AB0474AD006CA791BBD87F3AAE6930A76A2DA68A5AB9AD8BCDA47FC8B899D6 -CAB3E3BB9CDC925ECA9664CB7534BA6E2AB6702DB77838BB7433B98B55C5C0A3DC671FA8 -8F5ABFBFA0DD7D3EBD7A3BBB7E40BD7C3EBC7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD -7D3FBD7F42BE712EB7B38ED8A073C8722EAF7C3EB47A3BB37D3FB57838B27939B3BC9ED9 -8757B96A2DA9753DAF7239AD743BAE733BAE7137AD6C30AA6527A6804DB4B08FD2C7B0E0 -B492D98852C47434BA7433B97434B97E43BE7738BA9665CAB391D57232B07A3EB4783BB3 -783BB37C41B66A26ABC1A4DC9461C2712DAE7D3FB57A3BB37B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47D3FB5702BADBC9CD98F5ABF7533B07B3DB47B3CB47B3CB47A3BB3 -8043B7B999D67D48B57036AE733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0743CB1692CAA9B73C6AE8AD27334B2B99ED36A3C99602D92623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094612F93643395531D8A9C7CBB8B66AF -58238D58238D9472B69F81BD541E8B6433955E2C906D3B9F9A8DA60A0C08000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000010001020000000004500058BD007AA9006FAB0072AC0071AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC -0073AC0073AC0073AB0072AC0072AB0073AC0073AB0070A9006FAA0070AA006FAA0070AA -0070AA0070AA0070AA0070AA0070AA0070AA0070AA0070AA006FA90070AA006FA9006FA8 -006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006EA7006FA8006EA7006FA90072AC0073AF0075B00075B00075B00075B00075AF0074AE -0074AF0074AE0074AE0074AE0074AF0072AC0072AC0072AC0072AC0072AC0475AD0066A4 -92B7D6A571C5B89DD7CBB5E1B695D9A377D2AC84D68B54C5702DB87535BA7433B97433B9 -7C3EBD7D41BE7D40BE7B3DBD7737BB8952C4C3A7DD7533B07533B08C55BDBFA1DD7C3EBD -7A3BBB7E40BD7C3EBC7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7F42BE712EB7B490D9 -A074C8722EAF7C3EB47B3CB47A3BB37C3DB47838B27939B3BC9ED98757B96A2DA9753DAF -7239AD733AAE7239AD743BAE763EAF6E33AB6C30AA6B2EA9956ABFBCA1DAC9B1E3A176D1 -9461CA702EB7783ABB6D2AB5A57BD3B492D46B28AC7C40B57B3FB56E2CAE996DC6B28DD3 -7635B17C3DB47A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47D3FB5 -702BADB897D7C8AFE0702DAE7C3EB57B3CB47A3BB37D3FB56F2BADA073C9B294D46425A7 -763EB17239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733BB06F34AD -C1A7DB814ABA6825ABA982D1906FB256218C633295623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094602D92683898B39BCB68389862319456218C9472B69F81BD -541E8B643395643396521C88A280C342463D000000020202000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000200010000001A000477 -0058B5007AAA006FAB0072AC0071AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0072AB -0073AC0071AB0070A9006FAA0070AA0070AA0070AA0070A90070A90070AA0070AA0070AA -0070AA0070AA0070A9006FA90070AA006FA9006FA8006EA7006FA8006EA7006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA8006EA7006FA90072AC -0073AB0072AB0074AE0075B00074AF0074AF0074B00075B00075B00075B00075B00075B0 -0075B00074B00074B00074B00075B00175B00072AD1379B1DEF2F5EFE1F67E43C07F42BF -7839BC6F2CB7702DB77737BA7D40BE7C3EBD7B3EBD7B3EBD7B3DBD7A3CBC7B3DBD7B3DBD -7636BA8C56C6C1A4DC712EAE7F42B67330AF8C55BDBFA0DD7C3EBD7A3ABB7E40BD7C3EBC -7D3FBD7C3FBD7C3FBD7D3FBD7D3FBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB4 -7B3CB47A3BB37C3DB47838B27939B3BC9ED98757B96A2DA9753DAF7239AD733AAE733AAE -7239AD733AAE743BAE753DAF692CA87137AC7740B0AB89CEB79AD5BFA1DF8F5AC7844AC2 -6C28B5B897DA8A55BC7335B1702FAE996CC6B693D57432B07A3BB37B3CB47A3BB37B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47939B28145B7C5AADE7433B0 -7C3EB47B3CB47B3CB47A3BB37D3FB5722FAFAE88D19C75C8692CAA753DB17239AF733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB07239AF753CB1692CAA9B73C7B08CD36F2FAF6E2EAEAC87D2 -916FB358238D633295623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -5E2B9173469FB7A0CE56208B66369756208C9573B69E80BD551E8B6433956331945B288F -8258AD7B777F000000010101000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000020002000000170030A20072BE0075A80070AB0072AC0071AB -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC -0072AC0072AC0072AC0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC -0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0070AB006FAA006FA90070AA -006FAA0070AA006FA9006FA9006FA9006FA90070AA0070AA0070AA006FA9006FA9006FA9 -0070AA006FA8006EA7006FA8006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006EA7006FA8006EA7006FA90072AC0073AB0072AC0072AB0073AC0075B0 -0075AF0074B00075AF0074AF0074AF0074AF0074AF0074AF0074AF0075AF0075AF0075AF -0074AF0377B1006BAA6DAFD0AC74CC9163C2AA81D47230B87D40BE7C3FBD7C3FBD7B3EBD -7A3CBC7B3DBD7B3CBD7B3DBD7B3DBD7B3DBD7B3DBD7D40BE712FB8BE9FDE905BBF7634B1 -7B3CB47D3FB57330AF8C56BDBFA0DD7C3EBD7A3ABB7E40BD7C3EBC7D3FBD7C3FBD7C3EBD -7D3EBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB47B3CB47B3CB47A3BB37C3DB4 -7838B27939B3BC9ED98757B96A2DA8753DAF7239AD733AAE733AAE733AAE733AAE7239AD -743CAE733AAE7238AD6729A76A2EA98859B9BDA2D8BFA3DBB592DA9D6FCFBA9BDC8045B7 -986BC6B796D67331AF7B3CB47B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47838B28349B9C5AADE7432B07C3EB47B3CB47B3CB47B3CB4 -7B3CB47737B28448B9C0A5DB7037AE733AB07239AF733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB06F34ADBEA4DA8049B97436B2763BB3793EB6C1ABD85E2C91623094612F93 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094612F93653496531D8AAE95C8825AA95B278F -64339556208B8F6CB39F81BE541E8B643395612F93623093612B97A69BB2000000010001 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000002000200 -0000180030A3007AB40073A60070AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC -0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0072AC0071AC0071AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC0073AC0072AB -0072AB0073AC0072AA0070AB006FAA006FA90070AA006FA90070AA0070A9006FA9006FA9 -006FA9006FA90070A90070AA0070A9006FA9006FA90070AA006FA8006EA7006EA8006FA8 -006FA8006FA8006FA8006FA8006FA7006FA8006FA8006FA8006FA8006EA7006FA8006EA7 -006FA90072AC0073AB0072AB0073AC0073AB0072AC0073AF0075B00074AF0074B00075B0 -0075B00075B00075B00075B00075B00075AF0075B00074AF0377B10067A850A7C8B889D3 -6927AC6E2CAEB491D4A378D26F2BB67D41BE7A3CBC7B3DBD7B3CBD7B3CBD7B3CBD7B3CBD -7B3DBD7B3DBD7B3DBD7D40BE712FB8C2A6E08B54BC7635B17B3CB47A3BB37D3FB57330AF -8C56BDBFA0DD7C3EBD7A3ABB7E40BD7C3EBC7C3FBD7C3EBD7D3EBD7F42BE712EB7B490D9 -A074C8722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47838B27939B3BC9ED9 -8757BA6A2DA8753DAF7239AD733AAE733AAE733AAD733AAD733AAD733AAD7239AD753DAF -743CAE6E33AB672AA7733BAE9C75C5A580CBD3C0E7C1A5DCA176CA702CAE7B3DB47C3EB5 -7A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7838B28348B8C6ABDF7432B07C3EB47B3CB47B3CB47B3CB47A3BB37C3DB47534B18953BB -8C5EBE6B2FAC743CB17239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF743BB06E33AD8F62C08854BE -7132B0783CB4773BB47335B2BBA0D771459D5E2B92623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094602D92B199CA73469F5D299063329559248E9D7EBC916EB4 -57228D63329562309462319459258D9A78BB535650000000030303000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000002000200000016002FA3007AB40071A80071AC -0072AB0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0073AC -0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AB0072AB0070A9006FA9 -0070A90070AA006FA90070AA0070AA0070AA006FA9006FA9006FA9006FA90070AA0070AA -0070A9006FA90070AA006EA8006FA7006FA7006FA7006EA7006EA7006EA7006EA7006EA7 -006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA90072AC0073AB0072AB0073AC -0073AB0073AC0072AB0073AB0075AF0074B00075AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00073AF097CB49BABD98644B8763AB37738B38046B7BEA0DD -8145C07636BA7C3FBD7A3CBC7B3DBD7B3CBD7B3CBD7B3DBD7B3DBD7B3DBD7A3CBC7D41BE -6E2AB6BD9DDD8E58BE7634B17B3CB47B3CB47A3BB37D3FB57330AF8C56BDBFA0DD7C3EBD -7A3CBB7D3FBD7C3EBC7C3EBD7D3EBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47838B27939B3BC9ED98757BA6A2DA8753EAF -733AAE7239AD733AAE733AAD733AAD733AAD733AAD7239AD733AAE733AAE763EAF753EAF -5E1CA26C30AAC9B4DFFEFEFEC2A5DC9460C27635B17331AF7C3DB47B3CB47A3BB37B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47838B28348B8C5AADE7433B0 -7C3EB47B3CB47B3CB47B3CB47B3CB47A3BB37C3EB47431B0BD9FDA8859BC6C30AC743BB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB06E34AD9D72C8773BB4773BB4763AB3783CB46E2EAE -9869C8A68BC2541E8B643395623094623094623094623094623094623094623094623094 -62309462309462309462309462309462309462309462309462309462309462319459258E -7D53A6A88DC4531D8A653496612E93663596BBA5D05B278F633194612F93623094633295 -55218A9167BA71726F000000030303000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000002000200000015002FA4007AB30071A80071AC0072AB0071AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0072AC0073AC0072AC0071AB0070A9006FAA0070AA0070AA0070AA0070AA0070AA -0070AA0070AA0070AA0070A90070A90070AA0070AA0070A90070AA0070AA006FA80070A7 -0071A90070A90071A9006FA9006FA9006FA90070A9006FA8006EA7006EA7006EA7006EA7 -006EA7006EA7006FA90072AC0073AB0072AB0073AC0073AC0073AC0073AB0073AC0072AB -0073AB0075AF0074B00075AF0075B00075B00075B00075B00075B00075B00074AF0577B1 -0066A787C1DAA059C26C2FAE7A3DB47A3CB47333B18249B8BFA1DD8045C07636BA7C3FBD -7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3DBD7B3DBD7839BB844BC2BD9DDB7F42B67939B3 -7B3CB47B3CB47B3CB47A3BB37D3FB57330AF8D56BDBFA0DD7A3ABB7D40BD7C3EBC7D3FBD -7D3FBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47A3BB37C3DB47838B27A39B3BC9ED9895ABB6628A7733BAE733AAE7239AD733AAE -733AAD733AAD733AAE733AAE7239AD743CAE7035AC6527A6A079C7C1A9DB7D47B2CBB6E0 -D1BFE3B596D3BFA1DA9968C57533B0793AB37C3EB57B3CB47A3BB37B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47838B28349B9C5AADE7331AF7C3EB47A3BB37B3CB47B3CB4 -7B3CB47B3CB47C3EB47331B09562C2B495D46C30AB743CB17239AF733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF743CB0 -6A2EABB091D28D5CC07031B0783CB4773BB4783CB46D2EAE9E71CBA589C1541E8B643395 -623094623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946331945B278F9C7DBC8E6AB25A258E633295 -612E93653496BDA8D25F2C926230946230946230946230936332945B2590B19FC313170F -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000020002000000180030A30079B4 -0071A80071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC -0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AC0071AB -0070AC0071AC0071AC0071AC0070AA006FA9006FA9006FA90070AA0070AA0070AA0070AA -006FA90070AA0070A90070AA0070A90070A80070A7006FA70070A80071A90070AA0071AA -0071AA0071AA0071AA0070A90070A90070A90070A9006FA9006FA9006FA90072AC0073AB -0072AB0072AC0073AC0073AC0073AC0073AC0073AB0073AC0072AB0073AF0075B00074AF -0075B00075B00075B00075B00075B00074AF0276B0006DAC469CC4A586CF7434B17A3DB4 -783AB3783AB37A3DB57332B08248B8BFA1DD8145C07636BA7C3FBD7A3CBC7B3DBD7B3DBD -7B3DBD7B3DBD7C3EBD7230B89D6FCEB18BD26E28AC7D40B57A3BB37B3CB47B3CB47B3CB4 -7A3BB37E41B56D28ACB794D69F73CF712EB77F42BE7C3EBC7D3FBD7F42BE712EB7B490D9 -A174C8722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB4 -7939B27635B1CAB1E1CBB6E0692CA7733AAE733BAE7239AD733AAE733AAE733AAE7239AD -763FB06C30AA7E4AB4B293D2A985CC7C46B1682AA6B79BD4B090D09061BD7A43B0B697D3 -BFA2DA7C3DB4722EAE7839B27D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47737B2DDCCEB9C6DC67330AF7C3EB47B3CB47B3CB47B3CB47B3CB47A3BB37D3FB5 -6E29ACA980CEAA88CE6425A7753EB17239AF733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB0733AB07239AF733BB06E33AD8453BAC1A5DC7031B0783DB4 -763AB3773BB4773BB4773BB47537B3BA9FD66C3E995E2B92623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094612F9364339559248EB49DCC643395612E93612F93612E93653496BEA9D25E2B91 -623094623094623094612F9362319459258D895FB47B7C7B000000040404000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000002000100000017002FA3007AB40071A80071AC0072AB0071AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC -0073AC0073AC0073AC0072AB0073AB0072AC0071AC0070AC0071AB0070AB0070AB0070AB -0071AC0071AC0071AC0070AB006FA9006FA9006FA9006FA90070AA006FA90070AA0070A9 -0070A80070A7006FA80070A80070A7006FA80071A90070AA0070A90070AA0070A90071AA -0071AA0071AA0071AA0071AA0071A90071AA0072AC0072AB0073AC0073AC0072AC0072AC -0072AC0073AC0073AC0073AC0072AB0073AC0075AF0074B00075AF0075B00075B00075B0 -0074AF0075B00072AE0077AFB3C0E28136B47539B3793BB4783AB3793BB4783AB37A3DB5 -7332B08248B8BFA2DD8044C07635BA7C3EBD7A3CBC7B3DBD7B3DBD7B3DBD7C3EBD7331B8 -9B6CCDB795D6702BAD7D3FB57B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47533B0 -B795D69969CC7330B77F42BE7C3EBC7F42BE712EB7B38ED89F72C8722EAF7C3EB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47838B27A3AB3AE87D1 -B291D26D33AA7238AD733BAE7239AD7239AD743BAE753DAF6426A5814EB6BBA0D8986DC2 -692BA67137AB6E32A9C2A9DA7E49B3C8B1DE692AA66829A5824FB5C8AFDFAB83CF8044B7 -6F2BAD7B3DB47C3DB47A3BB37B3CB47B3CB47B3CB47A3BB37D3FB56F2BADA87ECDA77DCD -702DAE7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37D3FB5B899D8814FB8 -7036AE733AB07239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733AB0733AB0743CB1692CAAB597D59363C36F30AF783CB4773BB4773BB4763AB3793EB5 -6B2AAEC0A5DB7E57A65B2790623194623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094612F9363329558228D845DAB -A88DC45B278F623194623094612E93653496BEA9D25E2B91623094623094623094623094 -6230945B298E7A49AA918C96000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000002000200000014 -002EA4007AB30071A80071AC0072AB0071AC0071AC0071AC0072AC0072AC0072AC0072AC -0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC -0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC -0072AC0071AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC -0072AB0071AB0070AB0071AB0070AB0071AC0071AB0071AC0070AB0070AB0070AB0070AB -0070AB0070AB0071AB0070AA006FA90070AA006FAA006FA8006FA70070A8006FA7006FA7 -0070A80070A70070A80071AA0071A90070A90071AA0070A90070A90070A90070AA0070A9 -0070AA0071AC0072AB0072AB0072AC0072AC0073AC0073AC0072AC0072AC0072AC0073AB -0073AC0072AB0074AC0075B00074AF0075B00075B00075B00074AF0275B00073AF87AFD6 -9154BF7336B17A3CB4783AB3793BB4793BB4793BB4783AB37A3DB57332B18248B8C2A6DF -8146C0793BBC7B3DBD7B3DBD7B3DBD7B3DBD7C3EBD7331B89C6ECEB694D56F2BAD7D3FB5 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37533B0B897D79968CC7330B7 -7F42BE7E41BD712EB7B490D9A175C9722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47A3BB37B3CB47B3CB46C26AB9765C4B697D46D31AA7238AD -733BAE753DAF6C31AA692CA7AD8CD0BBA0D8753CAD6729A5753CAD743BAD6D31A8C2AADB -7136AB8A5AB9B798D46D30A87135AA7035AAA17AC7C2A7DBAF88D17736B17634B17C3EB5 -7B3DB47A3BB37B3CB47B3CB47C3EB5702CADAE87D1A67CCC712DAE7C3EB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47A3BB37C3DB47432B08B53BDC5AEDE6526A8753DB17239AF733AB0 -733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB06F34AE8351B9 -BFA4DB6E2EAF793EB5763AB3773AB4773AB4773BB4783DB46E2EAEAC87D3C0ACD4551E8B -643395623094623094623094623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230945F2D92AF96C8774CA25B278F633194623094 -612E93653496BEA9D25E2B91623094623094623094623094623094643395541E8AAC8FC8 -33382F000000020202000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000040002000000170030A3007AB40071A80071AC0072AB -0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC -0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0071AC0072AC0072AC0071AC0071AC0072AC0071AC0071AC0071AC0072AC0072AC0073AC -0072AC0073AC0073AC0073AC0073AB0072AC0073AC0072AA0071AC0071AC0071AC0071AC -0071AC0070AB0071AB0070AB0070AB0070AB0071AB0071AB0071AB0070AB0071AC0071AC -0070AB006FA80070A80070A8006FA8006FA8006FA7006FA8006FA70070A8006FA70070A8 -0070AA0071A90070A90071A90071AA0071AA0071AA0070A90071AA0072AC0071AB0071AC -0071AC0072AC0072AC0072AC0073AC0073AC0073AC0072AC0073AC0073AB0072AC0074B0 -0075B00074AF0075B00074AF0477B10065A771B9D4AD6DCA6A2AAD7B3EB5783AB3783AB4 -783AB4783AB4793BB4793BB4783AB37C3FB56B26ACB492D4D2BBE96A24B47E42BE7A3CBC -7B3DBD7B3DBD7B3EBD7738BBC4A8E08348B87939B37B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47A3BB37B3DB47A3BB37532B0B897D79968CC7330B78044BE7533B9A174CF -DAC9EA7533B07B3DB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47A3BB37B3CB47E41B6712EAE9764C4B698D46F35AC7138AD6628A68B5CBCBA9DD6 -9D74C47339AC6F34AA753CAD7238AB743AAC6C2FA8B192D19164BE6323A2BB9FD78A59B9 -6D30A8743AAD6828A57439AC9C73C4E9DEF29460C2712DAE7533B07D3FB57B3CB47A3BB3 -7D3FB5702BADAD86D0A77DCD702DAE7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7A3BB37C3EB47534B0A478CAA37DCA6B2FAB743CB17239AF733AB0733AB0733AB0733AB0 -733AB0733AB0733AB0733AB07239AF753EB16729A9B79BD79261C27132B0773BB4773AB4 -773AB4773AB4773AB4773BB47235B1854DBDB298CB541E8A653496612F93623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -612F93602E93663596B59ECC58238D643395612F93623094612E93653496BEA9D25E2B91 -62309462309462309462309462309463329557238C9773BB595959000000010101000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000002 -000100000018002FA3007AB40071A80071AC0072AB0071AC0071AC0071AC0071AC0071AC -0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC -0072AC0071AC0072AC0072AC0072AC0073AC0072AC0072AC0073AC0073AC0073AC0073AB -0072AC0073AB0072AB0071A90070AB0070AB0070AB0070AB0070AB0071AC0071AC0071AC -0071AC0071AC0070AC0071AC0071AC0071AC0070AA006FA7006FA8006EA5006EA6006EA7 -006FA70070A70070A8006FA8006FA8006FA80070A8006FA80070A70070AA0071A90070A9 -0071AA0070A90071AA0070A90071AA0072AC0071AB0071AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0073AC0072AC0073AC0072AB0074AC0075B00074AF0074AF0176B0 -0070AD288DBCA699D47937B3783CB4793BB4793BB4783AB4783AB4783AB4793BB4793BB4 -793BB4783AB37A3EB5702DAEAC85D0A276D1702CB77D40BE7A3CBC7B3DBD7B3DBD793ABC -C8AEE27C3EB47A3BB37A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB3 -7B3CB47A3BB37533B0B897D79968CC7330B78043BE7838BBC5ABE07B3CB37A3BB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37B3CB47D3FB57D3FB57D40B57939B3 -7838B26D28AC925EC2AB87CD7137ADA07AC9B698D38B5CBA682AA57238AB733AAC7238AB -7339AC733AAC6C2FA88958B9B89AD4611FA18D5EBBB99CD56A2CA77439AC753BAD7237AB -6929A68755B8B99CD6BD9ED9915CC1702CAD793AB37D3FB57C3EB4702CADAC85D0A57ACB -712DAE7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37A3BB37B3CB47533B0 -C9B2E17741B37036AE733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 -733BB06D32AD8858BBBDA1DA6F31B0783CB4773BB4773AB4773AB4773AB4773AB4773BB4 -773BB47336B2B495D47D55A55B278F633194623094623094623094623094623094623094 -623094623094623094623094623094623094623094612F9364339556218C9C7DBC916FB4 -5B278F623194623094623094612E93653496BEA9D25E2B91623094623094623094623094 -623094612F93602E9167329CA098A9000000020202000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000002000100000054002FA3007AB40071A8 -0071AC0072AB0071AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC0073AC -0073AC0072AC0073AC0073AC0073AC0073AC0072AB0072AC0073AB0072AB0071A90071AA -0070A9006FA9006FA9006FA9006FA90070AB0070AB0070AB0070AB0070AB0071AB0071AB -0070AA006FA8006FA5006EA5006EA5006FA6006FA5006FA5006FA5006FA5006EA70070A7 -0070A70070A70070A80070A8006FA80070A70070AA0071AA0070A90071AA0070A90071AA -0072AB0072AC0071AB0071AC0071AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC -0073AC0073AB0073AC0073AB0074AD0075B00075AF0375B0006DAAA3C5E18C41B97235B1 -793BB4783AB3783AB4783AB4783AB4793BB4793BB4793BB4783AB4793BB4793BB47A3CB4 -702FAFB28DD3A175D0702DB77D40BE7A3CBC7C3FBD7432B9C5A9E07F42B57A3AB37B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37B3CB47A3BB37533B0 -B997D79868CC7330B78044BFC8AFE27A3BB37B3CB47B3CB47A3BB37B3DB47C3EB47C3EB4 -7C3EB47A3BB37A3BB47939B36F2BAD702BAD6D27AC7E41B58D57BD8C56BC844BB8DBCAEA -D7C6E7A783CB6E32A96C2FA7753CAD7339AC7238AB7339AC7338AC733AAC6B2FA79062BD -B698D46A2CA66A2DA7BB9ED68856B86E32A97338AC7338AC753BAD6D2FA86A2CA68A5AB9 -B99CD5C1A3DB8144B76F2AAD7E40B5712EAEAD86D0AA82CF712DAE7C3EB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3DB47838B2854BBAC0A5DC6F35AE733AB0 -7239AF733AB0733AB0733AB0733AB0733AB0733AB07239AF753CB1692CAAAD8AD19363C3 -7031B0783DB4763AB3773AB4773AB4773AB4773AB4763AB3793EB56A28ACB08DD4825BA8 -58238E633194623094623094623094623094623094623094623094623094623094623094 -62309462309462309462309464339556218CB096C97F56A759258E633194623094623094 -612E93653496BEA9D25E2B916230946230946230946230946230946230946130935F2B93 -9E85B630332E000000020202000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000103000000000E6A0062C30076AE0071A90071AC0072AB0071AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0072AC0073AC0073AC0073AC -0073AC0072AC0073AB0073AC0072AB0071A90070AA0070A90071AA0070AA006FAA0070AA -0070AA006FA9006FA9006FA9006FA90070AB0070A8006EA5006FA5006EA5006EA6006FA6 -006FA6006EA5006FA6006FA6006EA6006EA6006EA5006FA5006FA5006FA7006FA80070A7 -0070A7006FA70070A80071A90070AA0071AA0070A90071AB0072AC0071AB0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0072AC0072AB -0072AD0074B00276B0006DAB6FACD19D6AC67134B07A3DB4783AB3793BB4793BB4783BB4 -793BB4793BB4793BB4793BB4793BB4793BB4783AB3793BB47A3CB46F2DAEB28ED3A075D0 -702DB77E41BE7636BA8E59C7BA99D97838B27B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37B3DB47A3BB37433B0B997D79969CC7432B8 -CAB3E37B3CB37C3EB57C3EB47D40B57736B1702CAE712DAE712EAF7C3EB47B3DB38146B7 -B491D4B693D5B390D3BE9EDCC7A9E4C6A8E3C4A6E28B50C8D9C6ECA57FC96A2DA7733AAC -7339AC7238AB7339AC7339AC7339AC733AAC6B2FA78F61BDB799D46728A57136AA8756B8 -C0A5D96524A3753BAD7237AB7237AB7439AC743AAD6C2FA86A2BA68958B8BC9ED8A87DCD -793AB36C26AB9664C3DFD0ED7838B27B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47A3BB37D3FB5702CAEB48FD3966BC36A2EAB743CB07239AF733AB0733AB0 -733AB0733AB0733AB0733BB06E33AD8554B99262C26D2DAF783DB5763AB3773BB4773BB4 -773BB4773BB4773BB4773BB4783CB46F30AF9D71C99F7FBE5C2890623194623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -5C288F764BA2B59ECC58228D643395623094623094623094612E93653496BEA9D25E2B91 -623094623094623094623094623094612F93643295531E889770BE5A5D56000000030303 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000102000000000E6B0066BE -0078A60070AA0071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC -0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AB0072AC0071AA -0071A90070AA0071AA0071AA0070AA0071AA0070AA006FAA0070AA0070AA0070AA0070AA -0070AA006FA8006EA8006EA6006FA5006FA6006FA6006FA6006FA6006FA6006FA6006FA6 -006FA6006FA6006FA6006EA6006EA6006EA5006FA5006FA6006FA8006FA80070A70070A8 -0071A90070AA0070A90071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0071AC0073AC0073AC0072AB0075AE006FAE1C8AB7 -BEB2DF772FB07B41B6793BB4793BB4793BB4793BB4793BB4793BB4793BB4793BB4793BB4 -793AB3793BB4793BB4783AB3793BB47A3CB46F2DAEB28FD39F71CF7433B9722FB8AE88D7 -9F71C8702DAE7C3EB47B3BB47B3CB47B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47A3BB3 -7C3DB47D3FB57D3FB57E40B57D3FB57634B0B38FD49360C9BFA3DD7736B17330AF7432AF -6F2BAD8C56BDA87FCCA277C9A57BCBC8ACE2CCB1E5C6AAE2A273D3A170D3A577D58B50C8 -742DBD7A36C06F24BAAE85D89969C79A6AC9C8B1DD6C2FA8743BAD7238AB7339AC7339AC -7339AC733AAC6B2FA78F61BDB799D46728A5763DAD6D31A8A682CA9B71C36C2EA87439AC -7237AB7338AC7237AB7439AC753BAD6A2CA77942AFA783CBC5ABDDA67BCC722FAFC0A2DB -7E41B67D3FB57B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB3 -7B3DB47736B19C71C7753EB17239AF733AB0733AB0733AB0733AB0733AB07239AF743CB0 -6D32AC976DC67F47B87539B3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4 -763AB3763BB37638B4BAA1D45A268D633295612F93623094623094623094623094623094 -6230946230946230946230946230946230946230946231945B278F8A65AFA386C057218C -643395612F93623094623094602E93663697BDA8D25E2B91623194623094623094623094 -623094623094623094612F9269369BA69DB0050702000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000102000000000D6A0067BE0077A7006FAC0072AC0072AB0071AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC0073AC -0073AC0073AC0072AC0072AC0073AC0072AC0070AB0070AC0070AB0071A90070A90071A9 -0071AA0070AA0071AA0070AA006FAA0070AA0070AA0070A90070AA006EA7006FA7006FA8 -006FA6006FA5006FA5006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6 -006FA5006FA6006EA6006EA6006EA6006EA6006FA5006FA7006FA90071A90070AB0071AB -0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB -0071AB0071AB0071AB0071AB0072AB0072AA0577AD9FA7D7752CAF6B2AAD6D29AD7535B2 -7739B37738B37738B37738B37738B37738B37738B37A3DB47B3EB57A3DB57B3DB57B3DB5 -7A3DB57B3EB57C40B56E2BAEBA9BD89A6ACD6720B3AF8AD7A67CCC712DAE7E41B57C3EB5 -7C3EB57C3EB57D3FB57A3AB37939B37939B37939B37A3AB37533B06E2AAD6F2BAD6F2BAD -6F2AAD7432B08C56BCD0BBE4DFD1ED8B54BDC7ACE0C6AAE0C8ADE0BD9BDEB189DAB48EDB -B089DA8241C47E3CC27F3CC27934BF7934BF7832BE7E3CC18344C48546C47832BEBB98DE -996AC86D29B1D7C3EB9266BD6728A5753DAD7238AB7339AC7339AC733AAC6B2FA78F61BD -B799D46728A4753CAD7237AB6F34A9C6AFDD763CAE7237AB7338AC7338AC7338AC7237AB -7237AB743AAC7034AA692AA6773EAEAB88CDBFA2D9DECFEC8043B76C26AB7737B27B3DB4 -7D3FB57B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47533B09663C3A886CF -682BAA753CB17239AF733AB0733AB07239AF753DB1672AA9A581CCA880CF6C2CAE783DB5 -763AB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB47234B1AD88D0 -8964AD5A258E633295623094623094623094623094623094623094623094623094623094 -623094623094612F93653496551F8BB39BCB6C3D9B5F2C91623094623094623094612F93 -6230945F2C92BAA5D05F2D92623094623094623094623094623094623094612F93633295 -57228C9B77BE565855000000030303000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000103000000 -000B6A0067BE0077A7006FAC0072AB0071AB0072AC0071AC0071AC0072AC0072AC0072AC -0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC -0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC -0072AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0073AC0073AC -0072AC0070AC0070AC0071AC0071AB0070AB0071AB0071AB0071A90071A90071A90070A9 -0070AA006FAA0070AA006FA9006FA9006EA7006FA8006FA8006FA7006FA7006FA7006FA5 -006FA6006FA5006FA5006FA5006FA5006FA6006FA6006FA6006FA5006EA5006FA5006FA6 -006FA6006FA6006EA6006EA5006FA40070A70073B00074AF0073AF0073AF0073AF0073AF -0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF -0376B10064A752A5CBDCCDECB08CD2BC9DD9BFA1DA8953BC7D41B68045B77F45B77F45B7 -7F45B78045B77D42B66F2DAF6D2AAD6E2BAE6E2BAE6E2BAE6E2BAE6E2BAE6E2BAE6F2CAE -8B56BDC2A6E06D28B6AA83D5A77ECC712EAE722FAF702CAE702CAE702CAE6F2AAD7C3EB4 -8248B78146B78247B77D3FB49A69C5C0A2DBBA99D7BB9BD8BB9AD8BC9CD9C0A1E0B792DB -FAF7FCD8C6EC8443C58D52C98D52CA813FC3742DBC7630BE7630BE803FC28140C38140C3 -8241C38241C38241C38140C3803FC28343C4742DBDB590DB9D70CA712EB37535B6BA9BDA -8756B76A2CA7753CAD7238AB7339AC733AAC6B2FA78F61BDB799D46728A4753CAD743BAD -692CA69E76C5A985CC6728A5753BAD7237AB7338AC7338AC7338AC7237AB7338AC743AAC -7338AC621FA28D5DBBEBE4F2B799D4BE9FDA8F59BF7431B06F2AAD7A3BB37C3EB47B3DB4 -7B3CB47A3BB37B3CB47B3CB47A3BB37C3EB5712EAE9364C28858BB6E33AD743BB07239AF -733AB0733AB07138AF753DB0C0A6DB7A3FB67538B3773BB4773BB4773BB4773BB4773BB4 -773AB4773AB4773BB4773BB4773BB4783DB46C2BAD9E73CB9979B8541D8A643395612F93 -6230946230946230946230946230946230946230946230946230946230946231945E2A91 -7448A0AD92C7643295612E936230946230946230946331945B268F855FACA588C15B278F -63319462309462309462309462309462309462309462309459268C8254B07C7C7C000000 -040404000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000102000000000D6B0067BE0077A7006FAC0072AB -0071AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC -0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0072AC0073AC0073AC -0073AC0073AC0073AC0073AC0073AC0073AC0072AC0071AC0071AC0070AC0071AC0070AB -0071AC0071AC0071AC0071AC0071AB0071AB0070AB0071AA0070A90070A9006FA9006FA9 -006EA7006FA8006FA7006FA7006FA8006FA8006FA7006FA7006FA5006FA6006FA6006FA5 -006FA5006FA5006FA6006FA6006FA5006FA5006FA6006FA6006EA5006EA5006EA50071AA -0072AD0076B20076B40076B40076B40076B40076B40076B40076B40076B40076B40076B4 -0076B40076B40076B40076B40076B40076B40076B40378B5006BAF59B1D1CBADE0C5A8DF -9E73D08F5BC7BA9BDDD0BCE7C4A9E0C6ADE2C6ADE2C6ADE2C7ADE2C2A7DFD8C6EBC7ACDE -A47ACBAB84CFAA82CEAA82CEAA82CEA981CEAE88D0915FC16823AA8953BCBC9DDDC2A5DE -7330AF793AB2A87ECCAB84CFAA83CEAB83CEA880CDBFA0DCCAB0E4C8ACE2C7ACE2CBB2E5 -B690DA9861CD9D69CF9C67CE9D69CF9760CC732ABA8647C3B997DAAC85D49A66CE742EBD -803EC2803FC28343C48242C38242C38140C3803FC28040C28040C28140C38140C38040C2 -8140C38140C27E3CC2BD9BDF8E5AC27737B67A3CB77A3BB8BC9EDB8756B76B2EA7753CAD -7238AB733AAC6B2EA78F61BDB799D46728A4753CAD7339AC7339AC7036AAC4ADDC773EAE -6F33AA7338AC7237AB7338AC7338AC7338AC7338AC7237AB753BAD6D30A8AC89CEBB9ED6 -AA8BCB8152B2BBA2D6B795D6AA81CF7F41B67432B07330AF7635B17E40B57C3DB47A3BB3 -7B3CB47B3CB47A3BB38143B7CBB4E17037AE7138AF733AB07239AF743CB0692CAAA27DCB -AA83D06B2AAD793EB5763AB3773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4 -773BB4783CB47031B09465C5A78BC45C2990623194623094623094623094623094623094 -62309462309462309462309462309462309463329556218C8C67B09A7ABA531C8A643395 -612F93623094623094643395541E8AA88DC4825AA958238D633194623094623094623094 -6230946230946230946230946332945C2790AB97BF20241C000000010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000102000000000D6B0067BE0077A7006FAC0072AB0071AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0072AC0071AC0072AC0072AC0073AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0070AC0071AC0071AC0071AC0070AC0071AC0071AB0071AB0071AC0071AB -0071AC0071AC0071AC0071AB0070AA0071AA0070AB0070AA006EA7006EA8006FA8006FA8 -006FA7006FA7006FA7006FA8006FA6006FA6006FA5006FA5006FA6006FA5006EA5006FA6 -006FA6006EA5006EA5006EA4006FA80071A90075B00077B40077B40077B40076B30075B3 -0075B30075B30075B30075B30075B30075B30075B30075B30075B30075B30075B30075B3 -0075B30075B30076B40072B20476B2C6D1EA863FB6A279CAA67CD36721B27333B97433B9 -7636BA7536BA7536BA7536BA7637BA7332B98045BFAA83D5A981D4A981D4A981D4A981D4 -A982D4A67ED3B28FD9DED0EEC6ACE0BEA0DCDFD1EEF4EFF7C4A8DFC6ABE0AF85D7AD81D7 -AE82D7AD81D7B188D98A4CC57832BD7C38BF7B37BE7C37BE7B36BE7A34BD7A34BD7A35BD -7934BD7D3ABF7832BCB791DB996AC96E2AB4BA9ADB9C69D07732BE8343C4803FC28140C3 -8040C28040C28040C28040C28040C28140C38140C38040C28140C37C39C0935BCCBE9EDC -6E2BB17D40B97C3EB97839B67A3BB8BB9DDB7F4BB36C30A8743BAC733AAC6B2EA78F61BD -B799D46728A4753CAD7238AB743AAC6C2FA7956AC0AB87CD6F32A97338AC7338AC7338AC -7338AC7338AC7237AB7439AC6C2EA88552B7BFA4D96728A5C1A7DA6D34A76125A08C60B9 -A381C7C1A6DBC1A5DB9C6BC78C54BE6C26AB7331AF7A3BB37D3FB57B3CB47C3DB47330AF -A073C9A682CE6D32AD743CB0733AB07239B0733AAFC3AADD783DB5763AB3763AB3773BB4 -773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4773BB4763AB3793EB56D2CAF -BEA3D96D3F9A5F2B92623094623094623094623094623094623094623094623094623094 -623094612F936230945F2D92B198CA73469F5F2C92623094623094623094623094643395 -541E8AA78BC38A65AF58238D633194623094623094623094623094623094623094612F93 -643395541E8AA98CC6393B36000000010101000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000103000000000C6A0067BE0077A7 -006FAC0072AB0071AB0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC -0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC -0073AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AC -0070AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AB0071AB0070AB0070AB -0071AC0070AC0070AB006FA8006FA7006FA8006EA8006EA8006EA8006EA8006EA8006EA7 -006FA8006FA6006FA6006FA6006FA5006FA6006FA6006EA5006EA5006EA6006FA80073AD -0076B30077B40077B40076B30076B30076B30076B40076B40076B40076B40075B40075B4 -0075B40076B40076B40076B40076B40075B40075B40075B40076B40076B40175B40078B4 -97BADC8B4ABA7233B07737B2B38FD49869CC7738BB7D42BE7C3FBD7C3FBD7C3FBD7C3FBD -7C3FBD7C40BD793CBC702EB7702EB7702EB7702EB7702EB7702EB7702EB7702EB77A3DBC -834AC1793BBCB999DCA880D1BF9EDF7F3BC07934BD762FBB762FBB7730BC762EBB7F3CC0 -8241C18240C18240C18240C18240C18140C18140C18140C18140C18343C2772FBCB58FDB -A075CD712FB67636B8B898DA9C69D07731BE8343C4803FC28140C38040C28040C28040C2 -8140C38140C38140C38140C38140C37C39C0935ACCC1A3DE712FB37D40B97A3CB87C3EB9 -7637B68044BBE7DDF17A44B07035AA743BAD6B2FA78F60BCB799D46728A5753CAD7339AC -7238AB763DAD6322A2B89CD59163BE6C2EA87339AC7338AC7338AC7338AC7338AC7135AA -773FAEBEA2D87840AF6829A5A078C6A585C9652AA26A31A56225A06F38A87C4AB0B296D0 -B697D3C8AEE0A77CCD7938B36D28AC7737B27B3DB47E41B66D28ACC4A8DD8A5BBD6A2DAB -763EB1682BAAA27DCAA881CF6C2CAE793DB5773BB4773AB4773BB4773BB4773BB4773AB4 -773AB4773AB4773AB4773BB4773BB4773BB4783DB47132B1C0A6DA6E409B5F2C92623094 -623094623094623094623094623094623094623094623094623094612F93612F93653596 -BBA6D15C2890633194612F93623094623094623094643395541E8AA98DC48964AF58238D -6331946230946230946230946230946230946230946230946230945E2C907240A49A949F -000000030303000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000103000000000D6B0066BE0077A7006FAC0072AC0071AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0072AC0073AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0070AC0070AC0071AC -0071AC0071AC0071AC0071AC0070AB0070AB0071AC0071AC0070AA006FA7006EA8006FA7 -0070A80070A7006FA8006FA8006FA8006FA8006FA8006FA8006EA7006EA8006EA8006EA7 -006EA5006EA5006EA50070A90072AA0075B20076B40077B50077B30076B30076B30076B3 -0077B40076B40077B40077B40075B40076B40076B40076B40076B40076B40076B40076B4 -0076B40076B40076B40076B40075B30679B60065AB81C6DCD3A3DE6A28AC7E41B67B3CB4 -7230AECCB4E38046C07739BB7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD7C40BD -7C40BD7C40BD7C40BD7C40BD7C40BD7C40BD7C40BD7B3EBD7434B98D58C6C0A3DF6821B1 -BE9FDE9964CD7933BC8545C38241C18241C18241C1813FC1803EC0813FC1813FC1813FC1 -813FC1813FC1813FC1813FC1813FC17D3ABF8E52C7C3A5E17535B77C3FBB7A3CBA7533B7 -B998DA9C69D07731BE8343C4803FC28140C38140C38140C38140C38140C38140C38140C3 -8140C37C3AC08F54CAC1A3DE712FB37D40B97B3DB87A3CB87C3FB97332B4A980D0B191D0 -6628A4753CAD6B2FA79062BDB494D26526A4753DAD7238AB7339AC7339AC7136AA7F4AB3 -C0A6DA6B2CA7753BAD7237AB7338AC7237AB753AAD692AA6A47EC9A47EC96727A5753BAD -7237ACC1A7DA743FAB6D35A7713AA96E36A76C33A660239F6A30A5966FBFCCB9E0B698D4 -B692D68E57BF7735B27431AF722FAE8449B9BB9CD77943B37036AE7740B2C7AFE0783CB4 -763BB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4 -773BB4773BB4773CB47031AF9767C7AC92C6531D8A653496612F93623094623094623094 -623094623094623094623094612F93643395541D8AA081BE9270B558238D633194623094 -623094623094623094643395541E8AA98DC48964AF58238D633194623094623094623094 -6230946230946230946230946230945F2E9169369C9D8DAC121410000000010101000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000002000201000000000E6B -0066BE0077A7006FAC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0073AC0072AC0073AC0073AC0072AC0073AC0072AC0071AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0071AC0071AC0070AC0070AC0071AC0070AB0070AB -0071AC0071AC006FA9006FA8006EA7006EA7006EA7006FA8006FA70070A80070A80070A8 -0070A80070A80070A80070A7006FA8006FA7006FA7006FA8006FA70070A70074B00077B4 -0077B50077B40077B40076B30076B30077B40077B40077B40077B40077B40076B40076B4 -0075B40076B40076B40076B40076B40076B40076B40076B40076B40076B40076B40075B3 -0177B5006DAF3290C1A793D4742FAF7B3EB47A3BB37C3DB47635B19360C1B797DA7535BA -7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7A3DBC7D41BE6F2DB7C0A2DE915DC57636B87738B8BC9CDE9862CD7832BC -8241C1803EC0813FC1813FC1813FC1813FC1813FC1813FC1813FC1813FC1813FC1813FC1 -813FC17E3BBF894BC5C2A4E07130B67D3FBB7B3DBB7A3CBA7433B7B998DA9C69D07731BE -8343C4803FC28140C38140C38140C38140C38140C38140C38242C37934BFBA98DD9664C6 -7535B57B3EB87B3DB87A3DB87A3CB87C3FB96E2BB2A377CDAB88CC682AA5753BAD7035AA -B99DD58451B66E32A97339AC7339AC7238AB743BAC692BA6B292D19468C06A2BA6743AAC -7338AC7338AC7236AB7237ABC6AEDD7237AB7338AC753AAD6828A5A179C7A381C76429A1 -7039A86E36A76E37A8713BA96E37A8672CA35F219E7B49AF9972C1B497D2C9B2DFA67BCC -9B6AC7651CA7A276CAA987CF5E1CA4976DC49B70C87031B0783CB4763AB3773BB4773BB4 -773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB47234B1 -8853BFB59CCE5D2A90623194623094623094623094623094623094623094623094623094 -62309463319559248EAC92C68159A95A258E633194623094623094623094623094643395 -541E8AA98DC48964AF58238D633194623094623094623094623094623094623094623094 -612F93643395521C889D7AC14C5048000000020202000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000001000102000002000C690067BE0077A7006FAC0072AB0071AB -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC -0073AC0073AC0073AC0072AC0073AC0072AC0071AB0071AB0071AB0071AB0071AB0071AB -0071AB0072AB0071AB0071AB0071AB0070AB0070AB0071AC006FA9006FA9006EA7006EA7 -006FA8006FA8006FA8006EA7006EA80070A8006FA8006FA8006FA8006FA8006FA8006FA8 -0070A80070A80070A8006FA70071AA0073AD0076B30077B40076B30076B30076B30077B4 -0077B40077B40077B40077B40077B40077B40076B40077B40075B40076B40076B40076B4 -0076B40076B40076B40076B40076B40076B40075B30277B40070B1278BBEE1E2F27D36B2 -783BB37B3CB47A3BB37A3BB37C3EB4712DAE9A6AC5B999DC702EB77D42BE7A3DBC7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7637BA -9565CAB594D97534B77C3FBB793ABA7737B8BC9BDD945CCB7D39BF8140C1803EC0813FC1 -813FC1813FC1803FC1813FC1813FC1813FC1813FC1813FC18241C17A34BDAE84D6A377CE -7434B77C3EBB7A3CBA7B3DBB7A3CBA7434B7B998DA9C69D07731BE8343C4803FC28140C3 -8140C38140C38140C38140C38242C37933BFC4A8E2864EBE7738B67B3DB87B3DB87B3DB8 -7B3DB87A3CB87D40B9702DB3A579CEAA87CC6B2EA76728A5B699D48C5DBB6C2FA8733AAC -7339AC7339AC733AAC6E32A9824EB4BEA3D86C2FA87339AC7237AB743AAC6B2DA7BCA1D7 -8450B66F32A97339AC7237AB7339AC7034AAC2AADB723CAA6D36A76E37A86E37A86E36A7 -6E37A86F38A8713BAA6B33A66226A16B33A66E38A7A380C7B193CFC3A8DD8C53BEBD9EDA -9B73C7966AC57031B0783DB4763AB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4 -773BB4773BB4773BB4773BB4773BB4773BB4763AB3793EB56A29ADB696D7815BA75A258F -6331946230946230946230946230946230946230946230946230945D2990794FA4B49CCC -551F8B643396612F93623094623094623094623094643395541E8AA98DC48964AF58238D -6331946230946230946230946230946230946230946230946230946231945D2A8F7C4FA9 -8D8990000000010001000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000003000100 -00012C0028AD0064B50078A9006FAC0072AB0071AB0071AC0071AC0071AC0071AC0072AC -0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC -0072AC0071AC0071AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AC -0073AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0070AC0071AC006FA9006EA7006EA7006FA8006FA8006FA8006FA7006FA8006FA8 -006FA8006FA8006FA80070A80070A80070A8006FA8006FA8006FA80070A8006FA8006FA7 -0073AA0072AC0072AB0074AF0077B40077B40076B30076B30077B40077B40077B40077B4 -0077B40077B40077B40076B40076B40076B40075B40075B40075B40076B40076B40076B4 -0076B40075B30076B40276B40069AD81B3D7A468C67234B07C3EB47A3BB37B3CB47B3CB4 -7A3BB37C3EB57432B0BFA1DB8F5BC77332B87C40BD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBC7C3FBDCBB4E47737B87A3CBA7B3DBA -7B3EBB7839B97B3EBACFB8E77B35BE813FC1813FC1803EC0813FC1803EC1803EC1803EC1 -813FC1813FC1813FC1803EC08342C2752DBBBE9DDE8953C17636B87B3DBA7B3DBA7A3CBA -7B3EBB7A3CBA7434B7B998DA9C69D07731BE8343C4803FC28140C38140C38140C3803FC2 -8343C47731BEC3A6E18B55C07637B67B3DB87B3DB87B3DB87B3DB87A3CB87A3CB87D40B9 -702DB2A67BCEAB88CC601EA1BCA1D78B5BBA6C30A8733AAC7339AC7339AC7238AB753CAD -682AA5B291D19366BF6C2EA8753BAD6C2EA79061BDB596D36829A5753BAD7237AB7338AC -743AAC692AA69F76C6A785CA6327A1703AA96E37A86E36A86E37A86E37A86E36A76F37A8 -7039A96E37A86E37A86226A1642AA28050B2B496D2C5AEDCCFBBE3793CB56E2FAF793EB5 -763AB3773BB4773AB4773AB4773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4 -773BB4773BB4773BB4793EB56B2AADBA9BD97D55A55A258F623194623094623094623094 -623094623094623094612F93653496541D8AB29ACA7B51A55C2890623094623094623094 -623094623094623094643395541E8AA98DC48964AF58238D633194623094623094623094 -623094623094623094623094623094612F9363329458228EA88EC2323430000000010101 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000300010000002D0040B2007FB00073A80070AC -0072AB0071AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC0073AC -0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AB0073AC0071AA0071AA -0071AB0071AA0071AB0070A90070A80070A80070A80070A80070A80070A8006FA8006EA7 -006FA8006FA8006EA7006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA80070A8 -0070A80070A8006FA8006FA80070A7006FA80070A70072AA0072AC0073AB0072AB0072AB -0073AD0076B20077B40076B30076B30077B40077B40077B40077B40077B40077B40076B4 -0077B40076B40075B40075B40075B40075B40076B40076B40076B40075B30378B5006CAF -8ACADFAD74CB6B29AC7D3FB57A3BB37B3BB47B3CB47B3CB47B3CB47B3CB4793AB3793AB2 -BC9CDA8B55C57739BB7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD -7A3DBC7D41BE6F2DB7AD88D6A479D07331B67C3FBB7A3CBA7A3CBA7C3FBB7635B89B6DCB -B58FD97933BD813EC0813FC1803EC0803EC1803EC1803EC1803EC1813FC1813FC1813FC1 -803EC08240C1BF9FDF874FC07738B97B3DBA7B3CBA7B3DBA7A3CBA7B3EBB7A3CBA7434B7 -B998DA9C69D07731BE8343C4803FC28140C38140C38241C37A35BF9D6AD1B694D77332B4 -7C3EB97B3DB87B3CB87B3DB87B3DB87B3CB87B3DB87A3CB87D40B96F2BB2E6DAF38E60BB -AE8DCF9063BD6F33A9763DAD7339AC7339AC7339AC7339AC743BAD692BA6C4ABDC7E48B2 -7236AB692AA6BEA3D98551B66E31A97339AC7338AC7338AC7338AC7338AC7236ABBDA4D7 -723CAA6C34A76E37A86E36A86E37A86E37A86E36A86E36A86E36A86E36A86E36A7703AA9 -703AA96E36A758189A926ABDF0ECF5B395D39565C56E2EAF7A3FB5773BB4763AB3773BB4 -773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4773BB4773BB4773AB4773BB4 -7335B18853BFB49BCE5B288F633195623094623094623094623094623094623094623094 -612F93643395B29ACA6E3F9C5E2B91623094623094623094623094623094623094643395 -541E8AA98DC48964AF58238D633194623094623094623094623094623094623094623094 -62309462309463319457248B885CB46F716D000000040404000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000300010000002B0040B2007CAE006EA90071AC0072AB0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0073AB0072AC0073AC0072AB0072AB0070A9006FA9006FA7006FA7006FA7006FA7 -006FA7006FA7006FA7006FA70070A7006FA7006EA7006FA8006EA7006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006EA8006FA80070A80070A80070A8006FA8006FA7 -006FA80070A70072AA0073AC0072AB0073AC0073AC0073AC0072AB0073AC0076B20077B4 -0077B40076B30077B40077B40077B40077B40077B40076B40077B40076B40075B40075B4 -0075B40075B40076B40076B40075B30177B4006BAE2B92C0D9C3E87838B27B3DB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3EB47331B08F59BEC4AAE26E2BB67C40BD -7A3DBD7A3DBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBD7B3EBD783ABB7E43BEC5ABE1 -7B3EBB7A3BBA7B3DBA7B3DBA7B3DBA7A3CBA7C3FBB712EB5A075CDB088D77C38BE8241C1 -803EC0813FC1803EC1803EC1803EC1813FC1813FC18240C17933BDA06DD0B490D96E2AB4 -7D40BC7A3CBA7B3CBA7B3DBA7B3DBA7A3CBA7B3DBB7A3CBA7534B7B898DA9C69D07731BE -8343C4803FC28140C38241C37833BEA676D5B18CD56F2BB27D40B97A3CB87B3CB87B3DB8 -7B3DB87B3CB87B3DB87A3CB87B3EB87B3DB88247BDAB87D0C1A9DA7F4BB3611FA16728A4 -6F34A97035AA7035AA7035AA7137AB6B2EA7966CC1B799D45B169DB494D2976BC16A2BA6 -743AAD7237AB7338AC7338AC7237AB753BAD6524A3C9B2DFB090CF6327A17039A96E36A7 -6E37A86E37A86E36A86E36A86E36A86E37A86E36A76F38A86C34A65E209EA280C69E7BC3 -8557B4B9A1D0AD90CBA175CB6724AB7539B3783CB4763AB3773BB4773BB4773BB4773AB4 -773AB4773AB4773AB4773BB4773BB4773BB4773AB4773AB47438B27E44B9B9A0D156218B -643396612F9362309462309462309462309462309463319458238D825AAAA386C0531C89 -653496612F93623094623094623094623094623094643395541E8AA98DC48964AF58238D -633194623094623094623094623094623094623094623094623094623094623094602E92 -6B399C9B8DA80B0E08000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000030002000000290040B3007CAE -006FA90071AC0072AB0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC -0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC -0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC -0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AC0073AB0072AB -0070AB006FA9006FAA0070A90070A90070A70070A70070A70070A80070A80070A8006FA8 -0070A8006FA8006EA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006EA80070A80070A8006FA80070A8006FA70070A8006FA70070AA0073AC0072AB -0073AC0073AC0073AC0073AB0073AC0072AB0072AB0074AE0077B40077B40076B30076B3 -0077B40077B40077B40076B40077B40076B40076B40075B40075B40076B40076B40075B3 -0176B40071B21889BCABACDB7833B17739B27B3DB47A3BB37B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47A3BB37C3EB47432B0A175C9AB84D47434B97C40BD7A3DBC7B3EBD7B3EBD -7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7333B9AF8AD7A67CD0712FB57D3FBB7A3CBA7B3CBA -7B3CBA7B3DBA7A3CBA7E42BC6B25B2BEA1DC9E6ACF762FBB8342C2803EC0813FC1803EC1 -813FC1813FC1813FC18240C17934BD9F6BCFB997DB702CB57D40BB7B3DBA7B3DBA7B3DBA -7B3DBA7B3DBA7A3CBA7B3EBB7A3CBA7534B7B898DA9C69D07731BE8343C4803FC28241C3 -7833BE9F6CD2B591D76F2CB27D40B97B3DB87B3DB87B3DB87A3CB87B3DB87C3EB97C3EB9 -7A3CB8712FB37A3BB79563C6FFFFFFBEA3D8B89AD5BB9FD7814CB47B45B17C47B27C46B1 -7D48B27339AC6222A2B08FD08C5CBBB799D47237AB7439AC7237AB7338AC7338AC7338AC -7338AC7338AC6D30A88957B9B99ED56428A1713AA96E37A86E37A86E37A86E37A86E37A8 -6E37A86E36A7703AA9672DA37945AEBDA4D79E7BC360229D8251B1AE91CB4F118EA585C7 -C0A4DD7D45B87133B0793EB5763AB3763AB3773BB4773BB4773AB4773AB4773BB4773BB4 -773BB4773BB4773BB4773BB4763AB3763AB4B495D2794FA35D2990633194623094623094 -6230946230946230946231945C2890A284BF8761AD5B278F633194623094623094623094 -623094623094623094643395541E8BA98DC48963AE58238D633194623094623094623094 -623094623094623094623094623094623094612F93653495551E8CAD97C31C2017000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000300010000002C0041B2007BAE006FA90071AC0072AB0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC -0073AC0073AC0073AC0072AC0073AB0073AC0072AB006FA9006FA90070AA0070AA0070AA -0070AA0070A90070A90070A80070A70070A80070A7006FA80070A8006FA8006EA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA8006FA8 -0070A8006FA80070A8006FA70070AA0073AC0073AB0072AC0073AC0073AC0073AC0073AC -0072AB0073AC0073AC0072AB0073AC0075B10077B40077B40076B30077B40077B40077B4 -0076B40077B40076B40075B40076B40076B40076B40075B30578B5006AADC3E3EEAB6EC9 -6F2FAE7D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3BB47A3BB3 -7D3FB56C26ABBA9AD79D70CF702DB77D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7C3FBD -7535BA9361C8E6DBF37433B87B3EBB7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA -7A3CBA8044BDBF9FE08B4EC67B36BD8241C1803EC0813FC1813FC1813FC1813FC18140C1 -7E3ABFC3A6E0854CBF7839B97B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA -7B3EBB7A3CBA7533B7B998DA9C69D07731BE8343C48141C37A36BFB087DAA277CE7331B4 -7C3FB97A3CB87B3DB87B3DB87D40B97738B67230B37535B57C3EB9AA83D1C8AFE2B18ED7 -C9AFE5E1D8EB703CA6BAA2D4C9B4DDBFA7D7C1A9D9C2AAD9C0A8D8DFD3ECA47EC9BFA3D9 -DED1EB9E75C5611FA16F33A9753CAD7338AC7338AC7237AB7338AC7338AC743AAD692AA6 -B89BD58659B6682EA46F38A86E37A86E37A86E37A86E37A86E36A7703AA9672DA37B48B0 -B99CD4885AB4692FA26C34A47946ACB79CD36E3BA3632B9B865CB0B69AD3824ABB6E2EAF -783CB4773BB4763AB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4763AB3 -793EB56A29ADA47ACE916FB2551F8B643295612F93623094623094623094612F93633295 -5B278FB7A0CE602E93623094612F93623094623094623094623094623094612F93653496 -531C89A386C08A65AF58238D633194623094623094623094623094623094623094623094 -6230946230946230946230945B288E8255AE868587000000040304000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000300010000002C -0041B2007CAE006FA90071AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AB -0072AC0071AA006FA9006FA9006FA90070AA0070AA0070AA0070AA0070AA0070AA0070A9 -0070A80070A7006FA80070A7006FA8006FA8006EA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006EA8006FA8006EA8006FA80070A80070A8006FA70070A9 -0073AC0073AB0072AC0073AB0073AC0073AC0073AC0073AC0073AC0073AC0073AB0073AC -0072AB0072AB0074AE0076B30077B40076B30076B30077B40076B40077B40076B40075B4 -0076B40076B40075B30278B5006AAD57A2CCA376CA712FAE7D3FB57A3BB37B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47939B38348B8BD9EDC -8045C07739BB7B3FBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7333B9C2A7E1854CBF7737B9 -7B3EBB7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7C3EBB7636B88045BDC2A3E1 -894CC57C38BE8240C1803EC0813FC1813FC1803EC08241C17933BDC4A7E17E42BC7A3BBA -7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7B3DBB7A3CBA7434B7 -B998DA9B69D07731BE8343C4803EC3C6ACE27738B67B3DB87B3DB87D41BA7A3BB87738B7 -6F2BB28851C09C6DCABFA1DEC7AEE2A981D47738BB864EC3B392D3A17AC68C61B85B1F9A -652D9F652C9F652C9F652D9F61279D895FB69772BEBCA5D6EBE4F3B59AD2B597D38552B7 -6727A56F32A97135AA753BAD7237AB7337AC7339AC6D30A88958B9B89DD46428A1713AA9 -6E36A76E37A86E37A86E36A7703AA9672DA37A47AFBCA0D6743FA96429A07039A7713BA7 -60239DAB8ACC8D66B6622B9B61299A703EA3C2ACD9AC87D16D2CAE7538B2783CB4763AB3 -773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB47538B2824ABAB69BD0 -633394612F93623094623094623094622F9463329558238D8E6AB29F80BD5B278F633194 -6230946230946230946230946230946230946230945E2B916E409CB39BCB633295612F93 -623094623094623094623094623094623094623094623094623094623094623094623094 -5D2A8F7443A6978F9E000000010101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000300020000002A0040B3007CAE006FA90071AC0072AB -0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC -0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AB0070AC0070AB0070AB0070AB -0070AB006FA9006FA9006FA9006FA9006FA9006FA9006FAA0070A90070A8006FA70070A8 -006EA8006EA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006EA8006FA8006FA70070A8006FA70072A90073AC0072AB0073AC0073AC -0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0072AB0073AD -0076B30077B40076B30076B30076B40077B40076B40075B40076B40075B30479B50069AD -5FB1D1D8BCE66D25AB7D40B57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47A3BB37C3EB47533B0854AB8C3A7DF793CBC7B3EBC7B3EBD -7B3EBD7B3EBD7C40BD7332B99969CBB896D97230B67C3FBB7A3CBA7B3DBA7B3DBA7B3DBA -7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7C3FBB7636B87F44BCC6A9E38443C27F3DC0813FC1 -813EC0813FC18240C17B36BE9B66CEB592D97738B87B3DBB7B3DBA7B3DBA7B3DBA7B3DBA -7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7B3DBB7A3CBA7434B7B998DA9C69D07732BE -8242C4C8AEE37E42BA7B3EB97839B76C27B17D40B9884FBFB38FD5BEA1DFB898DC8A55C5 -7B3DBD7231B87434B99361CAB292D1601DA0CDBAE1703CA66B34A36E39A56E38A56D38A4 -6E39A5662DA05F239BA989CA9C79C2A282C67E52B0BBA2D5B698D48550B67940B06626A4 -7338AC743AAC7338AC7439AC6A2CA7B99BD5885AB7672DA36F38A86E37A86E36A7713BA9 -672DA37A47B0BCA0D6743EA96930A2703AA76E36A5703AA763279EAE90CE8E67B661299A -6D39A167329E622A9A9874BDB08CD37A3EB67234B1793EB5773BB4763AB3773BB4773BB4 -773BB4773BB4773BB4773BB4763AB3783DB47132B1BDA4D7613092612F94612F93623094 -62309462309464329556208BA183BF8F6CB356208B643295623094623094623094623094 -6230946230946230945C2890774CA2B29ACA541D8A653496612F93623094623094623094 -623094623094623094623094623094623094623094623093643395531D89A788C63D4239 -000000020202000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000003 -00010000002B0041B2007CAE006FA90071AC0072AB0072AC0072AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0072AC0071AC0071AC0071AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC -0072AC0073AC0072AC0070AC0070AB0071AC0071AC0071AC0071AC0070AB0070AB0070AB -0070AB0070AB0070AB0070AB006FA9006FA9006FA70070A8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA8006EA7 -006FA80070A70072A90073AC0073AB0073AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0073AC0073AC0073AC0072AB0073AC0073AC0072AB0072AB0075B00077B40077B4 -0076B30077B40076B40076B40075B30077B40071B10575B2AABADF8E4CBB7639B27B3CB4 -7A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47A3BB37E40B56F2BADAF89D1A67DD36F2DB77C40BD7A3DBC7A3DBC7C3FBD7535BA -BFA3DF8B55C27635B87B3EBB7B3DBA7B3DBA7B3DBA7B3CBA7B3CBA7B3CBA7B3DBA7B3DBA -7B3DBA7A3CBA7D41BC702CB5A981D1AF86D7752DBB8342C1803EC0813FC18342C1762EBB -AD82D7A176CF702DB57C3FBB7A3CBA7B3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3CBA7B3CBA -7B3CBA7B3DBA7A3CBA7B3EBB7A3CBA7535B7B998DA9E6CD1752EBDC7ADE27331B37230B4 -8A54C0B593D7BA99DAC8AEE39E71CE793CBC6D2AB6783ABB7A3DBC7D41BE7535BAA880D3 -A179C76829A58858B9B497D06932A16C36A46C36A46C35A36D38A4652C9F966FBDAF91CD -591C98C3ACD96D3AA65F279D875EB5BCA5D6BBA1D6A57ECA7236AB692AA67237AB763DAE -6C2FA88B5BBAB59AD2652BA26F38A86E37A87039A961249F7B48B0BC9FD6743EA96930A2 -7039A76E36A56E37A66E37A66C34A47642AABDA6D566309E6A35A06A35A06B37A15E2598 -936DBAC5AFDB8956BF6927AC773CB4773BB4763AB3773BB4773BB4773BB4773AB4773AB4 -773BB4773CB47234B1B090D3825BA95C28906331946230946230946230945F2D92683898 -BCA6D15E2B916331946230946230946230946230946230946230946230946230945C2990 -764BA1B69FCD57218C643395623094623094623094623094623094623094623094623094 -62309462309462309462309463329558248C916BB76A6A69000000020202000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000500010000002C0041B2007CAE006FA9 -0071AC0072AB0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC0072AC0072AC -0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AC0070AC0070AB -0071AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC -0070AB0070AB0070AA006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA7006FA8006FA8006FA70071A90073AC0072AB -0072AB0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AC -0073AC0073AC0072AB0073AC0072AB0072AB0073AD0076B20077B40076B30077B30076B4 -0076B40075B3077AB5AFD0E68F4ABB7132AF7C3DB47A3BB37B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3EB5 -722FAFB18CD29D70CE7535BA7C40BD7C40BD7332B99665CABC9CDC6F2CB47D41BC7A3CBA -7B3DBA7B3DBA7B3CBA7B3CBA7B3CBA7B3CBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7D3FBB -712FB5AC86D3A87BD37831BC8342C2803EC08240C17A35BEB58DD99D6FCC7332B67C3EBB -7B3CBA7B3CBA7B3CBA7B3DBA7B3DBA7B3CBA7B3CBA7A3CBA7B3DBA7A3CBA7B3DBB7D40BB -7E41BC7635B8712FB5A980D2C2A3E2A57BCE9969C8B796D9C0A3DFA074D08A53C46E2BB6 -7535BA7A3DBC7E42BE7B3EBD7A3DBC7C3FBD7737BBC4AAE0743BAC743BAD6525A3B596D3 -8D63B8652C9F6D37A46C36A4672FA07F4FAFBEA5D662299E642B9FB194CE8A62B8642EA0 -652FA15D249C6E3CA69E7DC4C2AADAA17AC77338AC6828A57034AA6A2BA6BC9FD78556B6 -6930A46F38A8682FA4966EC0B89AD4743FA96930A27039A76E36A56E37A66E36A56E36A5 -6D35A5723CA8BDA5D561299A6B37A169349F69349F6C38A161299A67329DB194CEA57CCF -7537B27539B3793DB5763AB3773BB4773BB4773AB4773AB4773AB4773CB46F2FAF9260C5 -A487C0521B89653496612F936230946230945D2A917C52A5AE94C859248E633295612F93 -6230946230946230946230946230946230946230945C2990764BA2B69FCD56208C643395 -623094623094623094623094623094623094623094623094623094623094623094623094 -612F936231935F2995AC9BBD11130F000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000010200010000002B0040B2007CAE006FA90071AC0072AB0071AC0072AC0072AC -0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0072AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC -0073AC0073AB0072AC0073AC0072AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC -0071AC0070AB0070AB0070AB0070AB0070AB0070AB0071AC0070AA006FA9006FA8006EA7 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006EA7006FA8006FA8006EA70071AB0073AC0074AB0073AC0073AC0074AC0073AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0073AC0073AC0073AC0073AC0073AB -0073AC0073AC0072AB0073AC0076B20077B40077B40076B30378B50066AB65B3D3D1A2DE -6D2EAE7D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 -7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB47736B1CEB7E47A3DBD -793CBC7839BB864EC2C2A6E07737B87B3EBB7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3CBA -7B3CBA7B3CBA7B3DBA7B3DBA7B3DBA7B3CBA7B3DBA7A3CBA7C3FBB6F2BB4B593D8A372D1 -7730BC8342C27E3BBF894BC5C4A9E07230B67C3FBB7A3CBA7B3CBA7B3CBA7B3DBA7B3DBA -7A3CBA7B3DBA7C3FBB7D40BB7A3CBA793BBA7737B86F2BB46F2BB48D58C48B56C4A67CD0 -FAF7FBD7C4EBB390D9915FC87637BB7231B87738BB7E42BE7B3FBD7B3EBD7A3DBC7B3EBD -7A3DBC7D41BE7130B8C2A7DF7C47B07035AA7035AA7D48B2C4ACDA60269C6D38A56E39A5 -60269CB196D0895DB6662DA06932A27A4AADBAA3D5622B9F6C39A56D3AA66833A360289D -6B38A4A282C6BEA4D8BDA2D88C5BBB6524A38450B6B99FD46429A1682EA4A484C8B296D0 -743FA9692FA27039A76E36A56E37A56E37A56E36A66E37A66F38A66930A2AB8ACC8C64B6 -622B9B6B36A06A35A069349F6C38A167319E69349EA88BC6B492D47132B16E2FAE793EB5 -763AB3773BB4773AB4773AB4773AB4773CB47132B08F5CC1D9CCE5663596602E93623094 -612F93653496521B89AA8FC57B51A55B268F623094623094623094623094623094623094 -6230946230946230945C2990764BA2B69FCD56208C643395623094623094623094623094 -62309462309462309462309462309462309462309462309462309463329556218A936BBB -61645F000000040404000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000010001000001090000550041AB -007BB0006FA90071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC -0072AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AB0072AB -0070AB0070AB0070AB0070AB0070AB0070AB0070AB0070AB0070AB0070AB0071AB0070AB -0070AB0071AC0071AC0070AA006EA7006EA7006EA7006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA8006FA7006EA70072AB -0074AE0074AD0073AC0074AB0073AC0074AC0073AC0073AC0073AC0073AC0073AC0073AC -0073AC0073AC0073AC0072AC0072AC0072AC0072AC0072AC0072AB0072AC0072AC0072AB -0072AB0074AE0077B40278B5006EB03F9FC8AD92D4702CAD7D3FB57C3DB47C3EB47C3DB4 -7C3DB47C3DB47C3DB47C3DB47C3DB47C3DB47C3DB47B3DB47B3DB47B3DB47B3DB47B3DB4 -7B3DB47B3DB47B3DB47B3DB47C3EB57838B28F5ABFB998DB7B3DBD7231B8B492D99F73CE -7331B67D40BC7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA -7B3DBA7B3DBA7B3DBA7A3CBA7B3EBB7738B8854CC0C5A7E3803CC07E3BBF803EC08748C4 -C7ADE27535B77C3EBB7B3DBA7A3CBA7B3DBB7B3EBB7B3EBB7C3FBB7C3EBB7230B66F2BB4 -7A3CBA7E42BC8C57C4BC9DDBB897DAC0A0DFC6ABE2A679D2B48ED6E6DBF1B593DA9A6CCD -6F2CB77A3CBC7D42BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3FBD7738BA8C57C6B799D6 -7137AB7238AC743AAC6D30A8966BC1A98AC9642A9E6A33A28051B0B79DD2652C9F6D37A4 -6E39A560269CB093CE8C64B9612A9E6B37A46A36A46B38A46A35A45D249C703FA87D51AF -B59BD2BDA2D7834EB6B597D38151B3A585C89771BF5D1E9B6D35A56F38A66E36A56E37A6 -6E37A56E37A66E37A66E36A67039A763279E9971C19D7BC05D23976C38A169349F6A35A0 -69349F6A36A06A36A0591D958459B0C4ABDE986BC86C2CAE793FB5773BB4763AB3773BB4 -773BB4773BB4793EB56D2DAFBEA3DA72479E5C2990623094623094602D926A3A99AE95C8 -6C3E9B5F2C926230946230946230946230946230946230946230946230946230945C2990 -764BA2B69FCD56208C643395623094623094623094623094623094623094623094623094 -6230946230946230946230946230946231945B288E7D50AB847D8B000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000001000200000004001C830064C50075AB0071AA0071AC0072AB0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0073AC0073AC0072AC0073AC0073AC -0073AC0073AC0073AC0073AC0072AB0073AC0072AA0070A90070A9006FA90070A9006FA9 -0070AB0071AC0071AC0071AC0071AC0071AC0070AB0071AC0071AC006FA9006FA8006FA7 -006EA7006FA8006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006EA7006FA8006FA7006EA70072AB0074AE0073AD0073AE0074AC0074AB -0074AC0073AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AC0073AC0073AC -0073AC0073AC0073AC0073AC0073AC0073AC0073AB0073AC0072AC0072AB0173AC0072B0 -1180B8DFDCF0813CB47231AF7634B17533B07533B07533B07533B07533B07533B07533B0 -7533B07533B07533B07432B07431B07431B07431B07431B07431B07431B07431B07431B0 -7431B07634B16921AA9867C3B08CD87738BBC0A3DE6F2CB47433B77535B87D41BC7D40BB -7D40BC7D40BC7D40BC7D40BC7D40BC7D40BC7C3FBB7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA -7B3DBA7C3FBB7534B78B55C3C1A1E18342C2752DBAB993DC9B6DCB7434B77C3EBB7D40BB -7E41BC7738B97331B77433B77534B77535B8A479CFA77ED0BB9ADCCEB6E6BD9EDE9966CA -9D6CCC7A37BA712AB58141BEBDA0DBB594D6874EBFB18DD4B592DA844CC1712FB8793BBC -7C40BD7A3DBC7B3EBD7B3EBD7C40BD702EB7AB83D69F77C56728A5753CAD7238AB733AAC -6B2EA7C2A9DA7848AB672FA1C6B2DC6B34A36B34A36C36A46E38A561279DA17DC4D0C1E2 -5E269D6C38A56935A36935A36A36A46C39A56733A2652FA160299E8055B1AA8CCBBDA2D8 -D8CAE88A5FB7652AA0723BA86E37A66E36A56E37A66E37A66E37A66E37A66E37A66E37A6 -6F38A6672DA18F65BBA98BC8642C9C6A36A06A35A06A35A06A35A069349F6A35A06E3BA2 -5E24988961B4D8CBE69364C46B29AD763AB3783CB4763AB3773BB4763AB3783DB46E2EAF -AD89D18A66AE5B268F6331946231945A268E7B51A5A88CC3521B89653496612F93623094 -6230946230946230946230946230946230946230945C2990764BA2B69FCD56208C643395 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094612F93643395571F8EAC99BF10140C000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000001000100000003 -0019840071BC0077A50070AB0071AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC -0072AC0071AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AB0072AB -0073AC0072AA0070A90070AA0071AA0070AA006FAA0070AA006FA9006FA9006FA9006FA9 -0070AA006FA90071AC006FA9006FA9006EA7006EA7006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA8006FA7 -006EA70071AA0074AE0073AD0074AD0074AE0074AD0074AC0074AB0074AC0074AC0074AC -0074AC0074AC0073AC0073AC0074AC0073AC0074AC0074AC0074AC0074AC0074AC0074AC -0074AC0074AC0074AC0074AC0073AB0073AC0375AC0068A571B9D5E2CDEDBBA0DBCAB1E2 -C7ACE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C8AEE0C6AADF9969C4 -9563C29664C39664C29664C29664C29664C29664C29664C29664C29664C29765C39664C2 -C8AFE0C3A8E1B38ED78F5AC49969C98E5AC46E2AB4702DB5702DB5702DB5702DB5702DB5 -702DB56F2BB4712FB6793AB97838B97839B97839B97839B97839B97738B97B3DBB7534B8 -8E5BC4C2A2E2772FBCB994DC9361C7712FB57839B9712FB56C28B38851C19665C7A377CF -CBB3E5C6ACE2AF87D6B18AD79058C57632B87B39BA7734B97734B98244BE7632B8B48ED8 -996CC6A57CCDA175CD6A25AFA175CCC4A8E1B28FD87F44BF7434B97C3FBD7C40BD7A3DBC -7C40BD702EB7A277D1A884CA6729A5753BAD7238AB753BAD7239AB763DAEB192CFA17DC4 -9772BF642B9F703CA66C35A36C35A36C36A46932A2BEA6D66E3CA66934A36A36A46A36A4 -6A36A46935A36A37A46A37A4622C9F612A9E875DB5DBCFE8F0ECF68558B5662BA0713AA7 -6E36A56E37A66E37A66E37A66E37A66E37A66E37A66E37A66E36A5703AA764299FBCA4D5 -7442A667319E6A35A06A35A06A35A06A35A06A35A069349F6C37A1642D9C5E2497A98AC7 -A67ECF793DB57335B1793FB5763AB3773BB4773BB47336B18148BBB9A1D157238C643395 -6332955A268EA98EC58057A85D2990623094623094623094623094623094623094623094 -6230946230946230945C2990764BA2B69FCD56208C643395623094623094623094623094 -6230946230946230946230946230946230946230946230946230946230946231945B278E -906BB5616261000000030303000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000010002010000000018840072BB0074A7006FAC0072AB -0072AB0071AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC -0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC -0071AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0073AC0072AC0072AC -0073AC0073AC0073AC0073AC0073AC0072AB0072AB0073AC0072AA0070AA0070AA0071A9 -0070A90070AA0070AA006FAA0070AA0070AA0070AA0070AA0070AA0070AA006FA9006EA7 -006EA7006FA8006FA8006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006EA8006FA7006FA8006EA70071AB0074AE0073AD0073AE -0074AE0074AD0074AE0073AC0073AB0074AC0074AC0074AC0074AC0074AC0073AC0073AC -0074AC0074AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AB -0074AC0074AC0074AB0075B20B84BDA1B7DF9C56C77C41BD884DC28649C18649C18649C1 -8649C18649C18649C18649C18649C18548C0884CC2BA97DBBE9DDDBD9CDDBD9CDDBD9CDD -BD9CDDBD9CDDBD9CDDBD9CDDBD9CDDBD9CDDBD9DDDBC9ADCBA98DBFDFDFECAB2E4B897DB -BC9DDDBC9CDDBFA0DEBEA0DEBFA0DEBFA0DEBFA0DEBFA0DEBD9EDDC4A9E1AE88D48044BC -874EC0854CBF854CBF854CBF854CBF864EC08146BD7230B66219AE9869C9B792DCAD84D3 -8044BD854CBF874EC1BA9BDCBFA3DFBC9BDDC0A0DEAF86D58244BE864AC07632B8732DB6 -7B39BB8041BE7F40BD7F40BD8041BD7C3BBB894EC2BFA3DD6E2FAF9567C4B592D8722FB3 -7433B57535B5A276CCEBE2F49261C97536BA7332B97D41BE7B3EBD793BBCB796D98958B8 -6F34AA743BAD743BAD6B2EA76D30A8733AACC2AADAE4D9EC895DB661279D5F249B6C35A3 -6E38A56F3AA562289D9C77C1A383C75E269C6C39A56935A36A36A46C39A56631A26732A2 -9470BEBDA6D6A889CA794AADB79CD3A07EC2966FBF63269E713AA76E36A56E37A66E37A5 -6E37A56E37A66E36A66E36A66E37A66F39A6682EA2C0A8D77342A667319E6A35A06A35A0 -6A34A06A34A06A34A06A35A069349F6B36A06B36A0622A9AA484C3BB9FD87B40B66B2AAD -793EB5763AB3773BB47335B18650BEB9A1D158248D6432956332955C2890BAA4D0663697 -602D92612F936230946230946230946230946230946230946230946230946230945C2990 -764BA2B69FCD56208C643395623094623094623094623094623094623094623094623094 -6230946230946230946230946230946230946230945A278D7E4FAE858386000000040404 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000001 -000201000003001A850071BB0074A70070AC0072AB0071AC0072AC0071AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC -0072AB0073AC0073AC0072AA0070A90070A90071A90070AA0071AA0070AA0071AA0070AA -006FA9006FA90070A9006FA9006FA90070AA006FA9006EA7006FA8006FA7006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8 -006FA7006FA8006EA70071AB0074AE0073AD0074AE0074AD0074AD0074AD0073AE0073AC -0073AB0073AC0074AB0074AC0074AC0073AC0073AC0073AC0073AC0074AC0074AC0073AC -0073AC0073AC0073AC0073AC0074AC0074AC0073AB0074AC0073AB0073AA0078B5007EBF -0075B90B81B59CB0DB9348C26D2DB57E3EBC7D3CBC7D3CBB7D3CBB7D3CBB7D3CBB7D3CBB -7D3CBB7D3CBC7C3BBB742FB7732EB7742EB7742EB7742EB7742EB7742EB7742EB7742EB7 -742EB7742EB77632B86A20B2A67BD2B998DBA87ED2661BB1712CB77937BA9662C9945FC8 -945FC8945FC8945FC89460C8935DC79967CBD0B9E6C5AAE1C6ABE1C5ABE1C5ABE1C5ABE1 -C5AAE1C6ACE2C1A5DFAE89D6B18DD7AA82D3EAE0F4D6C4EAA479D1CAAFE3C6A9E19865CA -9763C98042BE712AB57733B87D3DBC7D3CBC8041BD8142BE7F40BD7E3EBC7F3FBD7F3FBD -7F40BD7834B99864CAB18ED46B2AAD7538B2C2A7DE854DBE793BB77B3DB87433B48349BC -BB9BDBC0A2DE996ACC6E2CB6793BBB8045C0C0A6DC6C2FA76C2FA86D30A86D31A88C5CBA -D0BDE3D4C2E59F77C7D1C0E1B69CD0B193CEA482C66F3AA661279D632A9E6E39A56C35A4 -BFA8D86F3DA76833A36D3AA56630A15F289D7241A9BCA4D6A789C97342AA5B219B6D3AA6 -B59AD26B37A2A889C8946CBD63279F713AA76E36A56E37A66E37A56E36A56E36A66E36A6 -6E36A66F38A6672DA18F63BBAE92CC5F26986C38A16A35A06A34A06A34A06A34A06A34A0 -6A35A069349F6A35A06C37A15B20967648A7BCA0D89E74CB6E2EAF793EB5773BB4783DB4 -6C2CAEB493D68762AB5A258F58228D8F6BB2A385C057228C633295623094623094623094 -6230946230946230946230946230946230946230945C2890774BA2B69FCD56208C643395 -623094623094623094623094623094623094623094623094623094623094623094623094 -62309462309462309463329558238EAC95C42A2E26000000010101000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000001000200000004001A840071BB0074A7 -0070AC0072AB0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC0072AC -0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AB0072AA0070A9 -0070AB0071AB0070AA0071A90071A90071A90070A90071AA0070A90070A9006FA9006FA9 -0070AA006FA8006EA7006FA8006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA8006FA8006EA70071AB0074AE -0073AD0074AE0073AD0073AD0074AD0074AD0073AD0073AE0073AD0073AB0074AC0074AB -0074AC0073AC0073AC0073AC0073AC0074AC0074AC0073AC0073AC0073AC0073AC0074AC -0073AB0074AC0074AC0073AA0075AF007AB9007CBD007BBC017DBC0073B10D83B69BAEDB -AF69CF7A38BA7E3FBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD8142BE -8142BE8142BE8142BE8142BE8142BE8142BE8142BE8142BE8142BE8142BE8244BE7B39BB -C4A7E08248BEA479D0C2A5E17836BA7F42BE7634B97735BA7735BA7735BA7735BA7735BA -7735BA7634B9722EB77634B97533B97533B97533B97533B97634B97330B87E40BEA87ED3 -A67AD1A375D0E3D5F1F9F6FBBE9EDD7632B87531B87A38BA7835B97E3DBC8243BE8041BD -7E3EBC7F3FBD7F3FBD7E3EBD7F3FBD7F3EBD7F3EBD7E3EBC8040BD7936BABC9DDC8A58BE -7639B36D2DAEB898D79360C67535B57B3DB87C3FB97839B7702CB28C56C0B796D9AC86D6 -7B3EBD844BC2B89BD6682AA59163BDA783CACBB6E0AE8CCF9C72C46F32AAA07BC5C2B0D4 -865BB28054AE9E7CC1BEA9D7D2C1E28E64B9652CA0591C98B298D08155B2612B9F5E269C -7747ACA88BCAC0A9D87240A95E259C6731A26F3CA75C229B9F7DC49A76BF551995AC8FCB -946CBD63279F713AA76E36A56E37A66E36A56E36A56E36A66E36A56F38A6672DA1895CB7 -AD91CB5B20966D39A269349F6A34A06A34A06A34A06A34A06A35A06A35A06A35A069349F -6D3AA2632C9B7343A6AB8EC8A57FCE6927AD7437B27A3FB56C2BADA67ECF9878B858238D -633194B6A0CD6B3D9A5F2C92623094612F93623094623094623094623094623094623094 -6230946230946230945C2990754AA1B69FCD56218C643395623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094612F93643395 -541F8AA585C4464843000000020202000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000010002010000020019840071BB0074A70070AC0072AB0071AC0071AC0072AC -0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC -0073AC0073AC0072AC0073AC0072AB0070AA0070A90070AA0071AB0070AC0071AB0071AA -0071AA0071AA0071AA0070A90071A90070A90070A9006FA90070AA006FA9006EA7006FA8 -006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006EA7006FA8006FA8006EA70072AB0074AE0073AD0074AD0073AE0073AE0074AD -0074AD0074AD0073AE0073AD0073AE0073AD0074AB0074AC0074AC0073AC0073AC0073AC -0074AC0074AC0074AC0074AC0073AC0073AC0073AC0073AB0074AC0073AB0073AB0075AF -007BBC007CBE007BBC007CBD007BBB017AB40073B10E7FB673BFD8AA8BD67B32B97D40BD -7F3FBD7E3EBC7F3FBD7F3EBD7F3FBD7F3FBD7F3FBD7F3EBD7F3EBD7F3EBD7F3FBD7F3FBD -7F3FBD7F3FBD7F3EBD7F3EBD7F3FBD7F3FBD7936BA9A66CBBB9BDA6F2CB47C3EBCDFCFEE -905AC67533B97F41BE7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3FBD7F40BE7E40BD -7E40BD7E40BD7E40BD7E40BD7E40BD7F41BE7C3CBC7432B86B25B4B390D98F5AC7B38FD7 -B593D8BD9CDC8142BE7C3ABB8142BE7F3FBD7E3EBC7F3FBD7F3EBD7F3EBD7F3FBD7F3FBD -7F3FBD7F3EBD7F3EBD7F3FBD7F40BD7C3CBCC7AEE2793EB4763AB37235B18651BCC3A7DE -7332B47C3FB97B3DB87B3DB87D40B97635B67230B3AC86D3BA9ADAD6C4EA9E75C5CBB5E0 -DBCBE9966AC17338AC6E32A96A2CA66829A6BA9FD56D409ABEA7D460279960279968329E -A07EC1AF93CCBDA6D6A789C98F64B9B297CF6C39A5AE92CDBBA2D5926CBC632BA06732A2 -6C38A56A35A46C38A55D249CA586C89874BE5F279B622B9DAA8DCA946BBC63279F713AA7 -6E36A56E37A66E36A66E36A66E36A66E37A66D35A5733DA9B499CF7645A766309E6A35A0 -6A34A06A34A06A34A06A35A06A35A06A35A06A35A06A35A069349F6B37A167319E5B2196 -9874BCC7ADDF854FBC6E2FAF793EB57538B4C1A9D8602F926B3C9ABBA6D15A258E633295 -612F936230946230946230946230946230946230946230946230946230946230945C2890 -7A4FA4B39BCB56218C643395623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094612F935F2D916B389FA29BA9000000 -020202000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000001000201000002001985 -0071BB0074A70070AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AB0072AC0073AB0072AC -0070AA0071A90071AA0071AA0070A90071AB0071AC0071AC0071AC0071AC0071AC0071AA -0070AA0071AA0070A90070AA006FA8006FA8006EA7006FA7006FA7006FA7006FA7006FA7 -006FA7006FA7006FA7006FA7006FA7006FA7006FA7006FA7006EA7006FA8006EA7006EA7 -0072AB0074AE0073AD0073AD0074AE0074AE0074AE0074AE0074AD0074AE0074AE0074AE -0074AE0074AD0074AB0074AC0074AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC -0074AC0074AC0073AB0074AC0073AB0073AB0079B7007CBD007CBD007BBC007BBC007CBD -007BBC0079B5017AB40377B30068AA41A3C8B390D97931B87D40BD7F3FBD7E3EBC7F3FBD -7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD -7E3EBC8142BE7531B8C5A9E18851C2783AB97838B97A3BBABFA1DE8549C07A3ABB7D3EBD -7D3EBD7D3EBD7D3EBD7C3EBD7C3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7C3EBD7C3EBD -7D3EBD7C3DBC7F42BE7431B89B6BCCBEA1DE651DB2B998DC8951C2864EC1C0A0DE8345BF -7936BA8040BD7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD8041BD -742FB7AA7FD3A984CF6D2CAE793DB5763AB3763AB3E0D2ED925FC57433B47C3EB97B3DB8 -7A3CB87B3EB87E41BA6D28B07C3EB9E8DDF4E3D8EE763DAE7035AA692BA67338AC7439AC -7136AB814BB5B49ACE59248D9D7EBC9B77C05F27996C38A15E25985F27997B4CAA8458AF -B79ED2D5C7E5CDBBE1875DB66731A260279E6B37A46A35A46934A36A35A46C38A55D249C -A484C79975BF5F279B6C38A360289BAA8DCA946BBD63279F713AA76E36A56E37A66E37A6 -6E37A66E36A5713BA760239DB093CE8256AF632B9B6A36A06A35A06A35A06A35A06A35A0 -6A35A06A35A06A35A06A35A06A35A069349F6A36A06B37A1642C9C794BA8B69AD38C58C0 -6E2FAF783CB5C5AFDB4F1886A78AC38C67B059248E633194623094623094623094623094 -62309462309462309462309462309462309464339557228CB49DCC784DA35C2990623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094623094643295551F8AA382C452564D000000030303000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000003000201000004001A850071BB0074A70070AC0072AB0071AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0073AC0073AC0072AC0073AC -0073AC0073AC0073AC0073AC0072AB0073AC0072A90070A90070AA0071AA0071AA0071AA -0071A90071AC0071AB0071AB0071AB0071AB0071AB0070AC0070AC0071AC0071AC0070AB -006EA5006EA6006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 -006FA8006FA8006FA8006FA8006FA8006EA70070A90072AB0074AE0073AD0074AD0074AE -0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AD0074AC0074AB -0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AC0073AB0074AC0074AC0073AB -0075AE0079B7007CBE007BBC007BBC007CBD007CBD007BBC007CBD007BB90078B30079B4 -067CB6006DAD43A3C8B390D97931B87E40BD7F3FBD7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD -7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7E3DBC8446BFC1A3E0 -7F43BD793AB97D41BC702DB5A57BCFB28CD8702CB67F41BE7C3DBC7D3EBD7D3EBD7D3EBD -7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC7F41BE732FB89765CA -BA99DC7738BB702EB7BD9DDE9766C96D28B38A54C2CEB6E6A376D07530B78243BE7F3FBD -7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7E3FBD7F3FBD7A38BAE1D2EF9669C56F30AF -783DB4793EB56C2BAEA078CBA67DCF7434B57B3EB87B3DB87A3CB87C3EB97738B68044BC -AF8BD3C3ACDAB49AD19C73C4692AA67439AC7339AC743AAC6829A59E74C79A7BB94A1084 -8E6AB1A889C76028996B36A06F3CA368339F581D94865AB2AE92CCF3EFF7C3ADD8916ABB -5E259D6A35A46B36A46934A36A35A46A35A46C38A55D239CA586C8916BBA5E259B6C38A3 -6A35A260289CAA8DCA946BBD63279E713AA76E36A56E37A66E37A66E37A67039A7652AA0 -A887C9936CBB632B9B6B36A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A0 -6A35A06A35A06A35A069349F6B37A1632B9B6A35A0BDA4D5B292D46826ACA177CB9473B5 -A284BF7D54A65B278F623194623094623094623094623094623094623094623094623094 -62309462309464339557218CB7A0CE7347A05D2990623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -63329557238B9067B86D6C6E000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000002000100 -0000030019840071BB0074A70070AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC -0072AC0072AC0071AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC -0073AB0072AC0071A90071A90071A90070A90070A90070AA0070AA0070A90071AB0071AC -0071AB0070AB0070AB0071AC0071AC006FAA006FA7006EA5006EA6006FA6006FA5006FA6 -006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006EA6006FA6006FA6 -006EA50070A80074AD0074AD0073AE0074AE0074AE0074AE0074AE0074AE0074AE0074AE -0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AB0074AC0074AC0074AC0074AC -0074AC0074AC0074AC0073AB0074AC0073AB0073A90076B1007CBD007CBD007BBC007CBC -007CBD007CBD007CBD007BBC007CBD007AB80078B30079B40078B3047BB5006DAE41A3C8 -B390D97930B87E40BD7F3FBD7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD -7F3FBD7F3FBD7F3FBD7F3FBD8041BD7530B7A273CFAA83D26F2BB57D40BB7A3CBA7D40BB -712EB5B38FD6A172CF7431B87F41BE7C3DBC7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD -7D3EBD7D3EBD7D3EBD7C3DBC7F41BE7431B89664CABB9ADC7535BA7C3FBD712EB8B694DB -996ACB7535B8793ABA7230B6AD88D4A87FD36F27B47C3CBB8041BD7E3EBC7F3FBD7F3FBD -7F3FBD7F3FBD7F3FBD7C3BBB8C51C3C2A6DD6E2FAF793DB5763AB3763AB3773BB4783DB4 -C1A5DD7433B57C3FB97A3CB87C3EB97838B67B3CB9C0A3DE7540ABAA8ACC8257B2916CBC -AD8ACE7236AB6E31A9763CAE692AA6A27AC89A7BBA58238E5A268EBBA4D17848AA66309D -5A20967B4CACCDBCDFB093CA6F3B9FA585C3865CAF9672B9A686C96F3BA7632C9F6B37A5 -6A35A46934A36A36A4662FA17C4EAFB399D16732A06A35A26A35A26A35A260289CAA8DC9 -946BBD63279E713AA76E36A56E37A66E37A66E37A66C34A4743EAABEA6D6632B9B6B37A1 -6A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A069349F -69349F6B36A069349F5E25988F68B5A986CFA77ED0B49DCBA284C057218C653496612F93 -62309462309462309462309462309462309462309462309462309462309464339557218C -B7A1CE7549A05D2990623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094623094623094612F93633294602B94AC9EBA -040701000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000300020000003300188C0071B90074A70070AC -0072AB0071AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC -0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC -0071AC0071AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0072AC0072AC -0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AB0070AC0071AB0072AB -0071AB0071AB0071AB0071A90071A90071A90071A90071AB0070AC0070AC0071AC0070A9 -006FA7006EA5006EA5006FA6006FA6006FA5006FA6006FA6006FA6006FA6006FA6006FA6 -006FA6006FA6006FA6006FA6006EA6006FA6006FA5006EA50070A80074AE0073AC0073AB -0074AE0074AD0074AD0074AD0073AD0073AD0074AD0074AE0074AD0074AD0074AE0073AE -0073AE0074AD0074AD0074AC0074AC0074AC0073AC0073AC0074AC0074AB0073AB0074AC -0073AB0074AD0078B5007CBD007CBD007BBC007CBD007BBD007BBD007CBD007CBD007BBC -007CBD007AB80078B30079B40079B40078B3037BB5006DAE3FA2C8B490D97930B87D41BD -8040BD7E3EBC7F3FBD7F3EBD7F3EBD7F3EBD7F3FBD7F3FBD7F3FBD7F3FBD7F3EBD7F3FBD -7F3FBD7C3BBBB792D99563C77535B87C3EBB7B3DBA7B3EBB7737B9864EC0C2A3DF7635B9 -7B3BBC7D3EBD7C3DBC7C3EBD7C3EBD7C3EBD7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC7E40BD -7735BA925DC7BD9EDE7434BA7A3BBC7B3EBD7839BB8349C1C6ACE17534B77D40BB7C3EBB -7230B6A87FD1C7ACE28A4EC27835B98142BE7E3EBC7F3FBD7F3FBD7E3EBC8143BE722CB6 -B894DA9567C47031B0773CB4773BB4773BB4773BB47437B2B493D5925FC47636B67D40B9 -7838B67B3CB9BD9FDC8454B4591A9BB599D28E67BA5519979C7AC2EAE1F2804AB36B2CA7 -793FB0C0A9D6602F926534965C2890835CAAAB8EC9632B9BA687C6BEA8D6A17FC05A1E91 -642C987645A4BEA9D5561B909A77BCBBA4D47F51B1632B9F6A35A36B36A46934A36B37A4 -632C9FBEA6D76D39A46933A16934A16A35A26A35A260289CAA8DC9936BBD63279E713AA7 -6E36A56E37A66E37A66B33A47946ADBEA8D6612A9A6B37A169349F6A34A06A34A06A35A0 -6A35A06A35A06A35A06A34A06A34A06A34A06A35A06A35A06A35A069349F6A35A06D39A2 -61289A875CB1C7B2DCCEBFDE8A65AF5C2990633195623094623094623094623094623094 -62309462309462309462309462309462309464339557218CB7A1CE7448A05D2990623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094623094623094612F936534964F1885A782CB535750000000030303000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000003000000000244004DBE0074B50073A80070AC0072AB0071AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC -0073AC0072AC0073AC0072AC0070AC0071AB0070AC0071AC0072AC0072AC0072AB0072AB -0072AB0071AB0070AB0070AA0071AB0071AB006FA8006EA5006EA5006FA6006FA6006FA6 -006FA5006FA5006FA5006FA5006FA6006FA6006FA5006FA5006FA5006FA5006FA5006FA6 -006FA6006EA5006EA60072AB0074AE0073AE0073AC0074AB0073AB0074AB0074AB0073AD -0073AE0073AE0073AE0074AD0074AD0074AD0073AD0073AE0073AE0073AD0074AD0074AE -0074AC0073AC0073AB0073AC0073AB0074AC0074AC0073AA0074AC007ABA007CBE007BBC -007BBC007CBD007BBC007BBD007BBD007BBD007BBD007BBC007CBD007AB80078B30079B4 -0079B40079B40078B3047BB5006DAE42A2C8B391D97D30B9793ABB8041BD7E3EBC7F3FBD -7F3EBD7F3EBD7F3EBD7F3FBD7F3FBD7F3EBD7F3FBD7E3EBC7F3FBD7E3EBCC2A5E07433B7 -7C3FBB7A3CBA7B3DBA7A3CBA7C3FBB7230B69261C7D6C3EA7939BB7D3FBD7D3EBD7D3EBD -7C3EBD7C3EBD7D3EBD7D3EBD7D3EBD7C3DBC7D3EBD7D3FBD732EB7C1A3DF905CC87432B9 -7C3FBD7A3CBC783ABB8348C1C5AAE07331B67C3FBB7B3DBA7D3FBB6F2BB4B796D9D1B9E6 -8548C07937BA8243BE7E3EBC7F3FBD7F3FBD7E3EBC7F3EBDBD9BDB8753BD7234B1773BB4 -773AB4773AB4783DB46C2BAE9C71C8A981D1702DB27A3CB77B3CB9BD9FDC8151B2682FA4 -6429A2B295D08C64B8632DA0632DA0794CADB59AD28753B86828A6BEA6D556218B57228C -5A258E623094CEBDDDC4AFD89068B56C379D5C22936D389E68319A7340A1BDA7D4642F99 -5E279568349CBBA4D3AA8BCA61299E642DA06B37A56A35A46833A3C0AAD96C38A36934A1 -6A35A16934A16A35A26A35A260289CAA8DC9936CBD63279F713AA76E36A56E37A67039A6 -652AA0A787C8946EBA60289A6B37A16A34A06A34A06A34A06A35A06A35A06A34A06A34A0 -6A34A06A34A06A34A06A35A06A35A069349F6B36A06A36A0642D9C5B21978B61B3D8CAE4 -5E2B91612F93612F93623094623094623094623094623094623094623094623094623094 -62309462309464339557218CB7A1CE7448A05D2990623094623094623094623094623094 -623094623094623094623094623094623094623094623094623094623094612F93633194 -5A278D8053AD817B88000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000030000000001440051BB007CAA -0071A80071AC0072AB0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC -0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC -0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AB0072AB0070AB -0071AC0071AC0070AB0071AB0072AB0071AB0071AC0071AC0071AC0072AC0072AC0072AA -0070A7006FA7006EA5006FA6006FA6006EA5006FA6006FA5006FA5006FA5006FA5006FA5 -006FA6006FA6006FA5006FA5006FA5006EA5006FA6006FA6006EA50071A90073AD0074AE -0073AD0073AE0073AD0073AB0073AC0074AC0074AC0073AB0073AB0073AB0073AC0074AE -0074AE0074AE0073AD0073AD0073AD0073AD0074AD0074AE0074AB0073AB0073AC0073AB -0074AC0074AC0073AA0077B3007BBB007CBD007BBC007BBC007CBD007CBD007BBD007BBD -007BBD007BBD007BBD007BBC007CBD007AB80078B30079B40079B40079B40079B40078B3 -047BB5006FAE409AC6C0BEE5985BC77533B88142BE7E3EBC7F3FBD7F3EBD7F3EBD7F3FBD -7F3FBD7F3EBD7E3EBC8142BE742FB7A97CD2AC85D47433B77B3EBB7B3DBA7B3DBA7B3DBA -7A3CBA7C3FBB7331B6CAB1E3A377D0722DB77F41BE7C3DBC7C3EBD7C3EBD7C3EBD7D3EBD -7C3DBC7D3EBD7C3DBC7633B9B693DA9A6BCC7331B97C3FBD7A3CBC7B3DBD793ABC8044BF -C3A7E07C3FBB7A3CBA7B3DBA7A3CBA7D40BB6F2BB47F44BDC2A3DF894DC2732DB78041BD -7F3FBD7F3FBD7A38BA8F57C5B797D76A28AC793FB5763AB3773AB4773AB4773BB47538B3 -7E47B8C0A4DC7A3CB87A3BB8BD9FDC8151B2662BA3733EAB6125A0B295D18C64B8612A9E -6D3AA6622C9F6C39A5AE8FCDB696D49A79BA7A4FA5B299CBCABBDAAB95C4D5CDE1B79CCF -723FA16128966E3A9F69339B67309A7542A3B9A1D15C24946D3A9F67339C5921928E66B4 -AF93CE794AAE61299E6B36A46832A2C1AAD96C37A36934A16934A16A35A16934A16A35A2 -6A35A260289CAA8DCA946BBC63279F713AA76E36A5703AA762259EA481C6936DBA5E2598 -6C37A16934A06A34A06A34A06A35A06A35A06A34A06A34A06A34A06A34A06A35A069349F -6A35A06A35A061299A642D9B8E66B7BFA9D6A182C29F80C1A184BF541E8A653496612F93 -62309462309462309462309462309462309462309462309462309462309464339557218C -B7A1CE7448A05D2990623094623094623094623094623094623094623094623094623094 -623094623094623094623094623094623094612F9364339558238DAF99C4272C23000000 -010101000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000030001000000430051BB007BAA006FAB0071AC0072AB0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC -0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0073AC0072AC0073AC0073AC -0073AC0073AC0073AC0072AB0073AC0072AC0070AC0071AB0071AB0071AB0071AB0070AB -0071AB0072AB0071AB0072AC0072AC0072AB0070A9006FA6006EA5006EA5006FA6006EA5 -006FA5006FA6006FA6006FA6006FA5006FA5006FA5006FA6006FA6006FA6006FA6006EA5 -006FA5006FA6006EA5006EA50071A90074AE0074AE0073AD0073AD0073AE0073AC0073AB -0074AC0074AB0074AB0074AC0073AC0073AC0073AC0074AC0074AC0074AB0073AD0073AE -0073AE0073AE0074AD0074AD0074AE0073AC0074AB0074AC0073AB0073AB0077B4007CBE -007CBD007BBC007CBD007BBC007CBD007CBD007CBD007BBD007BBD007BBD007CBD007BBC -007CBD007AB80078B30079B40078B30079B40079B40079B40078B3027AB40273B10081B5 -86B4D8A25DC97333B88142BE7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7D3DBC -8345BFBFA2DF8248BD7838B97B3DBB7B3DBA7B3DBA7B3DBA7A3CBA7B3DBA7B3DBA6F2CB4 -BB9ADB935FC87634B97E3FBD7D3EBD7C3EBD7D3EBD7D3EBD7C3DBC7E40BD7836BAB18BD7 -9E70CE702DB77D40BE7A3CBC7B3DBD7A3CBD7D3FBE702DB7AA82D5A87FD2702EB57C3FBB -7B3DBA7A3CBA7D41BC7636B87F44BDC3A6E0B089D67733B87F40BD8243BE7530B7B28AD7 -9F75C97031B0783CB4783DB4783DB4783CB4763AB37A3FB56A28ACB99AD88D57C3BA9BDB -8353B3652BA2713AA9703AA96225A0B295D18C64B8612A9E6A37A46E3BA6652FA05F289D -D4C5E5B8A3CC9F88B9AB97C1613A8B714D95F4F0F7926BB7BAA2D18E65B45E24946C379D -6A349C67309AAE93CA8054AB622C9869359C6B389E5C25948960B1BCA4D38C63B96630A2 -652FA1C2ACDA6D3AA46933A16A35A26A35A16A35A26934A16A35A26A35A260289BAA8DCA -936BBC63279F713AA76F38A66930A28657B5B092CE67329E6A35A06A35A06A34A06A35A0 -6A35A06A35A06A35A06A34A06A35A069349F6A35A06C37A167319E662F9D8E66B8BAA3D3 -AB90C87243A35A2494612C98B69DCE70439D5E2B91623094623094623094623094623094 -62309462309462309462309462309462309464339557218CB7A1CE7448A05D2990623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094612F936432955420898B5CB9878787000000050505000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000004000000000144 -0052BB007BAA006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC -0072AB0070AA0071AA0070AC0070AC0070AC0070AC0070AC0071AC0071AC0072AC0071AB -0070A9006FA5006EA5006EA5006FA6006FA6006EA5006FA6006FA6006FA6006FA6006FA6 -006FA6006FA6006FA6006FA6006FA6006FA6006EA6006FA6006EA6006EA5006FA60073AC -0074AE0073AD0073AD0074AE0074AD0074AE0074AD0074AC0074AB0074AC0074AC0074AC -0074AC0074AC0074AB0074AB0074AB0074AB0074AC0074AC0074AC0074AC0074AE0074AE -0073AE0074AC0074AB0073AA0075AE007BBB007CBD007BBC007BBC007CBD007BBC007CBD -007CBD007CBD007CBD007CBD007CBD007CBD007CBD007BBC007CBD007BBA0078B30079B4 -0079B40079B40079B40079B40079B40078B3027AB40074B20077B187B6D9A25CC97333B8 -8142BE7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7B39BB8D54C4BC9CDD6F2CB47D41BC -7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7C3FBB7534B7925FC7BD9EDE7532B87E40BE -7C3DBC7D3EBD7D3EBD7C3DBC8042BE6F2AB6A87DD2B390D96B26B57E41BE7A3CBC7B3DBD -7B3DBD7B3DBD7C3FBD702DB7AB83D5A87FD2712EB57C3FBB7B3DBA7B3DBA7A3CBA7C3FBB -7738B97B3DBAA77ED0B28DD87531B87835B98A50C3BFA3DD773BB4793DB5773BB46D2DAE -6D2DAE6F30AF773BB47235B1824AB9C0A5DDDDCFEC7641AC5F229E733EAB6E37A8713AA9 -6225A0B295D18C64B8612A9E6D3AA660299E6C38A5D9CCE8FEFDFFA790BD3D0C714B1D7A -4D1F7EA18DB5B2A7BA7B49AB54198EAA8DC8936BB75F25946B359C5E23949B77BC9B79BD -5C24946A369D67339B6A379D6029975E2896AF94CAB79DD261299F8C63B9A98BC95E259B -6C39A36A35A26934A16A35A26934A16A35A26A35A260289CAA8DCA936BBD63279F703AA7 -7039A6672CA1BCA4D66B37A069349F69349F6A35A06A35A06A35A06A35A06A35A06A35A0 -6A35A06C38A167319E5F27996D39A2B49ACEAD92CA7344A4592293632F9A6B399F582193 -A486C4825BA95A258E623194623094623094623094623094623094623094623094623094 -62309462309464339557218CB7A1CE7448A05D2990623094623094623094623094623094 -6230946230946230946230946230946230946230946230946230946230945E2C906F3DA0 -9689A20A0C08000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000030000000001450051BB007BAA006FAB0072AC0071AB -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0073AC0072AC0072AC -0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AB0070AC0070A9006FA7006FA8 -006FA8006FA8006FA80070AA0071AB0071AB0071A9006FA5006EA5006EA6006FA6006FA6 -006EA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6 -006FA6006FA6006FA6006EA5006EA50071AA0073AD0074AE0073AD0073AD0074AE0074AE -0074AE0074AD0074AE0074AD0074AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC -0074AB0074AC0074AB0074AB0074AB0074AC0074AD0074AC0074AD0073AD0074AC0075B0 -007BBB007CBD007BBC007BBC007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD -007CBD007CBD007CBD007CBD007CBC007BBD0079B50078B30079B40079B40079B40079B4 -0079B40079B40078B3007AB40276B30077B188B6D9A25CC97332B88142BE7E3EBC7F3FBD -7F3FBD7E3EBC8041BD7632B8B896DA9766C87636B87B3DBB7B3DBA7B3DBA7B3DBA7B3DBA -7B3DBA7B3DBA7A3CBA7D40BB702DB5A479CFB48FD9702BB68043BE7C3DBC7C3DBC7F41BE -7633B98A52C3BD9DDD7E42BE7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3DBD7C3FBD702DB7 -AC85D6A175CF702DB57C3FBB7A3CBA7B3DBA7B3DBA7A3CBA7B3EBB7A3CBA6F2BB49F72CC -BB9ADC8648C09D6CCDA47DCC621DA86E2FAF7437B29E73C99A6EC7A57DCDC9B0E0CAB2E1 -BB9AD8B292D4E2D8EDB599D28C60BA6429A2682FA4723CAA6327A1B294D08D65B9632DA0 -632C9F895EB8AB91C88C6DABC0B3CEB4A3C6592E854E227C8666AA7D6E8F9382A1885AB5 -622C975F2796A688C5BEA7D46E3A9F591E91A788C59874BB5C24946A369D67339B69359C -6C3A9E6D3B9F561C907A4CA7A483C5A686C9A687C6571B9666309F6934A16D39A46A35A2 -6934A16934A16A35A26A35A260289CAB8DC9936BBD63279E713BA86B32A4B79DD37A4AA9 -66309E6A35A06A35A06A35A06A35A069349F69349F6C38A167329E5D24987240A5A382C5 -C2AED8774BA7582093622E9968369D66339C66339C622E997B4FA9B39BCB58228D643395 -612F9362309462309462309462309462309462309462309462309462309464339557218C -B7A1CE7448A05D2990623094623094623094623094623094623094623094623094623094 -623094623094623094623094612F93653496511B88A887C953584E000000030303000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000003 -0000000000430051BB007BAA006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0071AC0071AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC -0072AC0073AC0072AC0070AB0071AB0071AC0070A9006FA70070A70070A70070A70070A7 -0070A70070A7006FA8006FA6006FA5006FA5006EA5006EA6006FA6006FA6006FA5006FA5 -006FA6006FA6006FA6006FA6006FA6006EA6006EA6006EA6006EA6006EA5006FA5006FA5 -0071AA0074AE0074AE0073AD0074AE0074AE0074AD0074AD0074AE0074AD0074AE0074AD -0074AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AB0074AC0074AC -0074AC0074AB0073AB0074AC0074AB0073AC0077B4007CBE007CBD007BBC007BBC007CBD -007CBC007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBC -007CBD007BBD0079B50078B30079B40079B40079B40079B40079B40079B40079B40078B3 -007AB40376B30077B187B6D9A25CC97332B88244BE7F3FBD7E3EBC7F3FBD8041BD7835BA -C5A9E1864EC07737B97B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA -7A3CBA7B3DBBBD9DDC854AC17735BA7E3FBD7E3FBD7634B98951C3C0A2DF7E42BE7736BA -7C3EBD7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3EBD7737BB8B55C5BB9CDC793BB97A3CBA -7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7B3DBA7D40BB7231B69868C9B591D9C3A8E09D72C9 -C0A3DBC3A9DEC1A4DCB18ED3B493D5A780CE7739B27C40B57738B3AF8DCFB59BCDA178C8 -B08ED0BCA3D6875AB7692FA55B1C9CB497D2875EB5501394A686C9E2DBEA592C878B6CAE -7B6298AF9DC25B318750237FB3A0C43920529D8EAA8759B4632D986B379E6129977B4DA8 -BBA2D1642C98946DB89F7DC05F289668349C67339B5F28965A2193581F917749A67342A3 -A485C4FFFFFFD1C2E37C4DAE8356B16933A15A1F986732A06833A16A35A26C38A36A36A2 -6A35A260289CAB8DC9936BBD64289F682FA28E63B9AE91CB5D23976C38A16A35A06A35A0 -69349F6B37A16A36A05D2397713FA4A687C7BAA4D29672BA602C98622E9968369D66339C -66339C66339C65329B67359C5C2695AE94CB825AA958238D633295612F93623094623094 -62309462309462309462309462309462309464339557228DB7A1CE7448A05D2990623094 -623094623094623094623094623094623094623094623094623094623094623094612F93 -64339555208A936ABB70716F000000030303000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000040000000000430051BB007BAA006FAB -0072AC0071AB0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC -0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC -0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AC0070AC0071AC -0071AB0071AB0070AC0070A9006FA70070A8006FA8006FA8006FA8006FA80070A80070A7 -0070A7006FA7006EA7006FA5006FA5006FA5006FA6006FA6006FA6006FA6006FA6006FA5 -006FA5006FA5006FA5006FA5006FA5006FA7006FA80073AD0074AE0073AD0073AD0074AE -0073AE0074AD0074AD0074AD0074AD0073AD0073AE0073AD0074AB0074AC0074AC0074AC -0073AC0073AC0073AC0074AC0074AC0074AC0073AC0073AC0073AB0074AC0074AC0073AB -0073AB0079B50079B4007AB6007BBB007CBD007CBC007BBC007CBD007BBD007BBD007CBD -007CBD007CBD007CBD007BBD007BBD007BBD007CBD007CBC007CBC007BBD0079B50078B3 -0079B40079B40079B40079B40079B40079B40079B40079B40078B3007AB40276B30077B1 -86B5D9A35ECA6D2BB57E40BD7F3FBD8040BD7733B99C6BCCB795DA702EB57D40BB7B3DBA -7B3DBA7B3DBA7B3DBA7B3DBA7B3CBA7B3CBA7B3CBA7A3CBA7B3EBB7637B88045BEE2D5F1 -8549C07B3BBC7B3BBC874DC2C0A1DF7D41BE7737BB7C3FBD7A3CBC7B3DBD7B3DBD7B3DBD -7B3CBD7B3CBD7A3CBC7C3FBD7331B9C5AAE18146BD793ABA7B3DBA7B3CBA7B3DBA7A3CBA -7B3DBA7B3EBB7C3FBB7738B87939B9AF8AD6FCFBFECBB3E1844CBA8A54BD844CBA6D2AAD -6D2AAD6F2EAE7A3FB56E2CADA278CD9976BDA98AC68A58BA6321A28652B7B99BD5BCA2D7 -7C4CB0AD8ECDA384C8B398D18E6FAD5527864A187EB29DC84E2C75B9ACC88D70AB734F9B -988CA61700369D8EAA7B4AAC541A8E5D24945E269654188F69359DAF92CA8C62B2B69DCF -622D996B389E67339B9771BAB398CDAD8FC8B299CDBEAAD4916FB88760B0B6A1CFA68BC5 -BAA4D1B195CDAF92CE7645A96E39A4662F9F5C22996933A16C38A36B36A261299DAB8DC9 -956DBE5A1A99966EBEAB8DC95C22976C38A16A35A06A35A06C39A160289A67309EA88AC8 -BBA4D39470B964319B5A239467349C66339C65329B66339C66339C66329C66339C67349C -5F2A977D51ABAF95C85E2C91623094623094623094623094623094623094623094623094 -623094612F93653496541E8AB39CCB7549A15D2990623094623094623094623094623094 -623094623094623094623094623094623094623094612F93623093612D95A796B81E211A -000000010101000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000050000000001450051BB007BAA006FAA0072AC0071AB0071AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC -0071AC0071AC0072AC0071AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC -0073AC0073AC0072AC0073AC0072AC0070AC0071AC0071AC0071AC0070AC0071AB0070AC -0070A9006FA70070A8006FA7006FA8006FA8006FA7006FA8006FA8006FA80070A80070A6 -006EA7006EA6006EA5006EA5006EA5006EA5006EA5006EA6006EA6006FA80070A90070A9 -0070A9006FAA0070AA0072AC0072AE0073AE0074AD0073AD0073AE0073AD0074AD0074AD -0073AD0073AD0073AE0073AD0073AB0074AC0074AB0073AC0073AC0073AC0073AC0074AC -0074AC0074AC0073AC0073AB0074AC0073AB0073AB0075AE0079B7007BB9007AB60078B3 -0079B4007BBA007BBD007CBD007BBC007BBC007BBD007BBD007CBD007CBD007BBD007BBD -007BBD007BBD007BBD007BBC007CBC007BBD0079B50078B30079B40079B40079B40079B4 -0079B40079B40079B40079B40079B40078B3017AB40276B30079B183AFD7BC7FD67F3CBC -7B3CBB8142BE7632B8AC84D4A77DD1722FB67C3FBB7A3CBA7B3CBA7B3DBA7B3CBA7B3DBA -7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7D3FBB7432B7B391D8B995DB722FB77A3ABBCCB4E5 -8045C07736BA7C3FBD7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3CBD7B3CBD7B3DBD7B3DBD -7839BCC6ACE17A3CBA7A3CBA7A3CBA7B3CBA7A3CBA7B3DBA7B3EBA7535B7702CB5A074CF -CBB4E29767C4E8DDF1B390D36A27AC7537B27637B27B3FB57B3FB57A3EB5793DB47333B0 -AE88D18E67B57441A4BA9DD66D2FA87034AA6727A58958B9AF8ECFD8C8E7D7CCE29578B1 -4C1C7F55268577529DD7CEE0431D6D775D959376B19C86B3422F5A220340BCB2C4A785C7 -9670B99C78BD9A76BC9D7ABE956EB9A482C2D6C6E3EBE4F2926CB7BCA7D3C3B1D89E7DBF -855DB08E69B667369C561F90521A8E8D67B4A286C148118755218F764DA58A67B1B69FCF -C4B0D8AA8ECA9C78C26F3CA660279B642C9E622A9D60289CAE92CC946DBD60229DBBA1D6 -794BA966309E6C38A1632C9C5F2699885DB2B296CE9571BA622F9A5B259565329B68369D -65329B66339C66339C66339C66329C66329C66329C65329B68369D5B2595B49CCD663697 -612E93612F93623094623094623094623094623094623094623094623094612F93643395 -B39BCB6C3D9B5F2C92623094623094623094623094623094623094623094623094623094 -623094623094612F93653496531D8AAE94C7383E32000000010101000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000010001020000000000440051BB -007BAA006FAB0072AC0071AB0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC -0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AC -0070AC0071AC0071AC0071AC0071AC0071AC0070AB0071AB0071AC0070A90070A7006FA8 -006FA7006FA8006FA80070A70070A8006FA8006FA8006FA80070A80070A60070A60070A7 -0070A90070A80070A80070AA0070AA006FAA006FAA006FAA006FAA0070AA0071AA0071AC -0071AB0072AB0074AD0074AE0073AD0073AE0074AD0074AD0073AD0073AE0073AD0073AE -0073AD0074AB0074AC0073AC0073AC0073AC0073AC0074AC0074AC0074AC0073AB0074AC -0073AB0074AC0075AE007BB8007BB9007BB8007AB70078B30079B40078B30078B5007BBA -007CBE007BBD007BBC007CBC007CBD007CBD007BBD007BBD007BBD007BBD007BBD007BBC -007CBC007BBD0079B50078B30079B40079B40079B40079B40079B40079B40079B40079B4 -0079B40079B40078B3007AB40076B30777B256B4D0A99EDA8338BC7A3CBB8547C0C7ACE1 -7738B87C3EBB7D40BB7D3FBB7D3FBB7D3FBB7D40BB7C3FBB793AB97839B97839B97839B9 -7839B9793AB97635B86016ADA47BD19E6ECD9664CAA57AD27230B87A3CBC7C3EBD7D40BE -7C3FBD7B3DBD7A3CBC7B3DBD7B3CBD7B3CBD7B3CBD7C3EBD7433B9A880D3A67CD07231B6 -7C3FBB7B3DBA7D40BB7939B97636B89361C8C4A9E0AB84D07130AF7535B2BB9ED99870C3 -AC88D07435B17A3EB4783BB3793CB4783BB3793CB3793AB4BDA2D5612998703CA1C6B0DD -7236AB7338AC763DAE6B2EA7692AA6EFE5F7B19EC649177D5C2F8A5021827E5AA39783AE -3209616D508DE5DEEC998AA85B4471CFCDD3CCBCE0D2C6E39B7CBD9D7FBE9E81BF9D7FBE -9F82C09A7BBC9474B9E6E0F0D5C8E4582191602D975D2A965A25935A249363309968389D -5D29958760B0AA90C75A289367399B5C2B945724915E2D95582591815BACA084C1B79FD1 -BCA5D4885DB58A60B76B36A3511492AA8DCA8557B3AC8CCC794BA95F26996028998459B1 -B89FD2AF96CB7D52AA57209267349C67359D65329B66339C66339C66329C66339C66339C -66329C66329C66329C66339C67349C5E29979A78BD9979B9541E8B643395612F93623094 -62309462309462309462309462309463329557228C8D68B1A183BF531C89653496612F93 -623094623094623094623094623094623094623094623094623094612F9363319459268C -7D4CAD918D96000000020202000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000100000000001300006A0051B3007BAC006FAB0072AC0071AB0071AC -0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC -0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC -0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0073AC0073AC0072AC0073AC -0073AC0073AC0073AC0073AC0072AC0073AC0072AC0070AC0071AC0071AC0071AC0071AC -0071AC0071AC0071AC0070AB0070AB0071AC0070A90070A7006FA8006FA80070A80070A8 -0070A70070A7006FA7006FA7006FA9006FA9006FAA006FAA006FAA006FAA006FAA006FA9 -006FA90070A90070A90070A9006FA90070AB0072AC0071AB0072AC0072AC0072AB0073AD -0074AE0073AD0073AD0074AD0074AD0073AE0073AE0073AE0074AD0074AB0074AC0074AC -0073AC0073AC0074AC0074AC0074AC0073AB0074AC0073AB0074AC0079B6007BB9007BB8 -007AB8007BB8007AB70078B30079B40079B40078B30079B3007AB8007BBC007CBD007BBC -007BBC007CBD007CBD007BBD007BBD007CBD007CBD007CBC007CBD007BBD0078B40078B3 -0079B40079B40079B40079B40079B40079B40079B40079B40079B40079B40079B40078B3 -0079B40479B40068AB2596C0B2A6DE7626B5A781D3A57AD17332B67839B96F2BB4702DB5 -702DB5702DB5702CB5702DB58147BE834ABF8349BF834ABF844BBF7E42BCA175CEBFA1DD -C3A8DEE5D9F2E3D5F18850C38147C0844BC17231B86F2BB7702DB77A3CBC7C3EBD7B3EBD -7C3EBD7C3EBD7B3DBD7B3EBD7332B99462C9B997DB6F2CB47E42BC7B3DBA702EB57C3FBC -AC85D4BFA1DB8650BB7332B0793BB47B3EB5C9B2E16120A3BBA0D89767C56E2CAE7A3EB5 -783BB37A3EB4702FAF996AC7AC8DCA642D9A642C9ACBB9DCA077C7692AA6753CAD6D2EA9 -9E77C4D5CEDD997DB7A68DBF582B87512283A188BB6C4F8C340C62654588DCD5E49389A0 -918D96AF9CC6541E907951A89E81C14E188A541F8E55218F5723904912889270B78B68B3 -8058AA9F81C05B2694612E9867369C65339A64329A63319966359B592392B7A1D1754CA4 -5C2B946333986333986232986434995B2993531E8E66379A7147A2AE95CAB099CBB399CD -B59AD07442A8AF93CEC1ABD99670BB7E51AEB8A0D2B299CD7B4FA95C26955F2A9768369D -66339C65329B66339C66329C66329C66339C66339C66339C66339C66329C66329C66329C -66339C632F9A6A399FB49DCE6A3A995F2D92623094623094623094623094623094623094 -62309463329558228D8B66B0A78BC3541E8B643395623094623094623094623094623094 -623094623094623094623094623094612F936332945A268FA187BB3D4139000000020202 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000100000000000F -00179C0051C5007BA8006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC -0072AC0071AC0073AC0072AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC -0073AC0072AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC -0071AB0070AB0071AC0070A9006FA70070A70070A70070A70070A80070A90070A90070A9 -0070AA0070AA0070AA0070A90070A90070A90070A90070AA0070AA0070AA0070AA006FA9 -0071AB0072AC0071AB0072AC0072AB0072AC0072AB0071AC0073AD0074AE0074AE0073AD -0074AE0074AE0074AE0074AE0074AD0074AB0074AC0074AC0074AC0074AC0074AC0074AC -0073AB0074AC0073AB0074AC0079B7007BB9007AB8007AB8007AB8007BB8007AB70078B3 -0079B40078B30079B40078B40078B30079B4007AB8007CBD007CBD007BBC007CBC007CBC -007CBD007CBD007CBD007CBC007CBC007BBD0079B60078B30079B40079B40079B40079B4 -0079B40079B40079B40079B40079B40079B40079B40079B40078B30079B4057CB6006EAF -2895BFAD9DDAC094DB8C5CC66E2AB48E5AC4B18DD6AC85D3AD86D3AD86D3AC86D3AD87D4 -C7AAE4C9AEE4C9ADE4C9ADE4C8ACE4CDB3E6B189D9955DCB9A65CED8C4EBD0BAE6B590D9 -CCB4E5C7ACE2B08BD7AC86D6AC85D57C3EBD7637BA7534BA7331B87230B8793BBC7F42BF -7535BA9C6DCDB593D9712FB57636B8793ABAAA83D2C8AEE09F73C96924AB7637B2793CB4 -783AB37A3DB5C6AEDF7036AC7943B1B99BD78249B97638B2793DB4793CB47739B3BA9ED7 -7A4BA8662F9C5D23969A76BC9E74C6692AA66E31A99E77C59A88AFA28ABB4B1A8078539F -AE97C5572988AA96C1654788B9ABC9D0CAD9C4C0C93D314BD9D7DC8157AE5E2E955A2893 -8864B2AA91C95F2E9665369A63349967399BBEAAD36333985825919473B8E5DCEE7345A3 -5C279466359B63319964329A66359B592392B7A1D1754CA45C2B94623298623298623298 -6131976333986435996030975E2D95562290511C8D7247A28561AEAD93C9B299CDE8E1F1 -E8E2F1A486C47B50A95B2595612C9867359D67349C65329B66339C66339C66339C66339C -66339C66339C66339C66339C66339C66339C66339C66339C65329B69379E582092AA8EC8 -7A4FA35C289062309462309462309462309462309462309462309463329557228D8C67B0 -A78BC3541E8A643395623094623094623094623094623094623094623094623094623094 -612F93653496501A87A37DC762675B000000030303000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000010000000000238E007EBD0075A20070AC0072AB -0071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0073AC0072AC0072AC -0073AC0073AC0073AC0073AC0073AC0073AB0072AB0073AB0072AC0070AC0071AC0071AC -0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AB0070AB0071AC -0070AA006FA90070A90070A80070A9006FAA0070AA0070AA0070AA0070AA0070AA0070AA -0070AA0070AA0070AA0070AA0070AA0070AA0070AA006FA90071AB0072AC0071AB0072AB -0072AC0072AB0072AC0072AB0071AC0072AD0073AD0074AE0073AD0074AE0074AE0074AE -0074AD0074AB0074AC0074AC0074AC0074AC0073AB0074AC0074AC0073AA0076AF007AB7 -007BB8007AB8007BB8007AB8007AB8007BB8007AB70078B30079B40079B40078B30079B4 -0079B40078B30078B30079B5007BBB007CBE007CBD007BBC007CBD007CBD007CBD007CBD -007BBC007CBD007BBA0078B30079B40079B40079B40079B40079B40079B40079B40079B4 -0079B40079B40078B30079B40079B40079B40078B3037AB4006FB02794C2DEE8F5CDA7E2 -C8B2E4BE9DDFA77AD4AB7FD6AA7ED6AA7ED5AB7FD6A97CD57E3BC07A34BD7B36BE7B35BE -7B35BE7B35BE7C37BE732AB9945CCBB491D4D4BFE7864CC2732FB77634B9A074CFA980D3 -A77ED3C5A9E1CDB6E5AD86D69665CB9F72CF7E42BF6F2BB76B25B58E59C6BA99DC6B26B2 -905CC5B795DAAA83CF783AB37130AF7B3FB5793BB4783AB3783AB37A3DB5C5ADDF733BAE -6729A79B73C5B493D56B28AC7C40B57435B1874FBDB396CD5D22956D39A067309C7645A5 -BA9FD46F33A98046B7B4A2C7583A7CB099C65121835627866F4898BFADD2E9E4EECBC4D3 -7E7192D1CADA545360D0D0D28C65B7491287562390602F964D168AB59ECD855FAE5B2993 -5724909E80C09474BA57249165369A592692825CACB39CCF764AA65B269466359B633199 -66359B592392B7A1D1754BA45C2B94623298623298623298623298623298623298623298 -62329867399B6232985825914E198B784FA6AA90C6AA90C6D4C7E28963B365319B64309A -6A389E65329B66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C -66339C66339C66339C66339C66339C66339C612C98835AAFAD93C7551F8B643395612F93 -62309462309462309462309462309463329557228D8C67B0A78BC3541E8A643395623094 -623094623094623094623094623094623094623094612F936230945E2B907344A28D8397 -0A0C08000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000001000000001218006B9D0075B4006FA80072AC0072AB0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC -0073AB0072AC0073AC0072AC0070AB0071AB0070AB0070AB0070AB0071AC0071AC0071AC -0071AC0071AC0070AB0070AB0070AB0071AC0071AC0070AA006FA7006FA7006FA9006FAA -006FAA0070AA006FA90070A90070A90070A90070A90070AA0070AA0070A90070A90070AA -0070AA0070AA006FA90070AB0071AC0072AC0071AB0072AC0072AC0072AC0072AB0071AC -0072AB0071AB0072AB0073AD0074AD0073AE0073AE0074AE0074AD0074AB0074AC0074AC -0074AC0073AB0074AC0073AB0073AA0076B0007BB9007BB8007AB8007BB8007BB8007BB8 -007AB8007BB8007AB70078B30079B40079B40079B40079B40079B30079B40079B40078B3 -0079B4007BB8007BBC007CBD007BBC007BBC007CBC007CBD007BBC007CBD007BBA0078B3 -0079B40079B40079B40079B40079B40079B40079B40078B40079B40079B40079B40078B3 -0078B30078B3007BB7007CB90381BF0073BB2592C5B7AADF893EC27C3BBF772FBB7730BC -7730BC7730BC7730BC7730BC8140C18241C18241C18241C18241C18241C18241C17D39BF -BB97DD8A53BCAE88D1CAB0E5722DB78144BF7431B8722EB7732FB88043BE7C3CBCA275D0 -BC9DDDB694DABEA0DEC1A4E0C8AEE38C56C5BD9FDDCAB1E3BA9BD9915EC06A26AC793CB4 -7A3DB4783AB3793BB4793BB4783AB37B3EB5C5ADDF7137AC753DAF6A2DA8AA88CD9F74CA -702FAF7536B1A983CF956FB9632B996C369F6D38A0642C9ABBA1D47A40B1AF97C94F2D76 -5A397FB09AC6501F8262368F512383D4C5E0A097AD230A45968DA4A09BA5817B89DCCFE9 -A68CC4B8A2D0BDA9D47B54A97045A15A2792A082BE6B3D9D5F2E96BCA7D1653599623298 -623298643599572491623398B49CCF764AA65B269466359B66349B592392B7A1D1754BA4 -5C2B9462329862329862329862329861319762329863349961309754208E6C3F9F7C54A9 -B59FCEB199CA7A50A45C298FAC91C6B39BCBB095CA6B399F59219368369D65329B65329B -66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C -66339C65329B66339C602A98B095CB7B52A55C2890633194623094623094623094623094 -62309463329557228D8C67B0A78BC3541E8A643395623094623094623094623094623094 -623094623094623094612F93643395521A8ABAA3D1242A1F000000010101000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000001000000 -000F16006BA20078B5006EA60071AC0072AC0072AC0071AC0071AB0072AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC -0072AC0072AC0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC -0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0072AC0073AB0072AA006FAA -0071AC0071AC0071AC0071AC0071AC0070AB0070AB0070AB0070AB0070AB0071AC0071AC -0071AC0070A90070A8006EA6006EA5006EA5006EA6006EA5006FA70070A9006FAA006FAA -006FAA006FAA006FAA006FA90070A9006FA9006FA9006FA9006FA90070AA006FA90071AB -0072AC0071AB0072AC0071AC0071AC0071AC0072AC0072AB0071AC0072AC0071AC0071AB -0072AD0074AD0074AD0073AD0073AD0074AB0074AC0073AC0073AB0074AC0073AB0074AE -0077B1007BB8007BB8007AB8007BB8007BB8007BB8007BB8007AB8007BB8007AB70078B3 -0079B40079B40079B40079B40079B40079B30079B30079B40078B30078B30079B4007ABA -007CBD007CBD007BBC007BBC007BBC007CBD007BBA0078B30079B40079B40079B40079B4 -0079B40079B40079B40079B40078B30078B30078B30079B5007BB7007CBB007FBF007FC0 -007EBE0381C10072B82695C5AD9FDB7F38BF8243C28241C18241C18241C18241C18241C1 -813FC1803EC0813FC1803EC1803EC1803EC08240C17D38BFC5A8E07939B27B3DB4DAC7EA -8B53C47837BA7F41BE7E40BD7E40BD7C3CBC7C3DBC7533B9712CB76F2AB6864BC1935EC7 -8B51C3BA99DCFFFFFFB895D66721AA7636B27C3FB5793BB4783AB3793BB4793BB4783AB3 -793BB47738B3C3ABDE7138AD733BAE6F35AB7C47B3C3A8DD7B3EB56C29ADBCA0D97645A5 -69339D632B995E2496602797A583C6D4C3E5624684350B638D78A6B8A3CC52228448167C -BFA9D3CECBD40C00326A5881CAC9C9AFA9B58157AAA68AC29270B46B3E9AA88CC3BCA8D2 -CBBBDCC6B4D9A589C4DBCFE6AC94C98A67B34B14885B299364359963339865369A5F2D95 -623399B39CCE764AA65B26946A3A9E582392B69FD0774DA55C2B94623298613197623298 -6232986435995F2E96572390673A9CA286C2B8A1CEB299CA784EA257238C5F2D92541F8A -A083BE8057A8653596B9A1D09471BA5C259568369D66339C65329B66339C66329C66329C -66329C66339C66339C66339C66339C66329C66329C66329C66339C66339C68369D592193 -9978BD906DB357218C63329562309462309462309462309462309463329557228D8C67B0 -A78BC3541E8A643395623094623094623094623094623094623094623094612F93633295 -57228C9977BC545454000000030303000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000102000000001018006CA2007FBF -0070AB0071AB0071AC0072AB0072AC0071AB0072AC0072AC0071AC0071AC0071AC0071AC -0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC -0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0072AC0073AC -0073AC0073AC0072AB0073AC0073AB0072AA0070A9006FA90070AA0070AA0070AA0070AA -0070AB0071AC0071AC0071AC0071AC0071AC0071AB006FA7006FA7006EA6006EA5006FA5 -006FA6006FA6006FA5006FA5006EA5006EA5006EA7006EA60070A90070A80070A90070AA -006FAA006FAA006FA9006FA90070AA0070A90070AA0071AB0072AC0072AB0071AC0071AC -0071AC0071AC0071AC0072AC0072AC0071AC0072AB0071AC0072AB0072AD0073AE0074AE -0073AD0073AE0074AB0074AC0074AC0073AA0075AE007AB8007BB9007AB8007AB8007BB8 -007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B50078B30079B40079B40079B4 -0079B40079B40079B40078B30079B40079B40079B30078B30079B6007BBB007BBD007BBD -007BBC007CBD007BBA0078B30079B40079B40078B30079B40079B40078B40078B30078B3 -0079B5007AB6007DBD007EBE007FC0007FBF007EBE007EBE007FBF007DBC057EBC006DB3 -7FBDDBAD67D17330BB8342C2803EC0813FC1803EC1803EC1803FC1813FC1803FC1803EC1 -803EC18241C17831BCA679D4AD85D07634B1722FAFAE88D0BFA1DF722EB77E40BD7C3DBC -7C3EBD7D3EBD7C3DBC7E40BD7F41BE7F42BE7A3ABB7A39BB702AB69765CAEEE9F4AB89CE -A276CB6D29AD7739B37A3CB4783AB3793BB4793BB4793BB47636B2874FBBBCA0D96F35AC -733AAE743CAE6D31AA8555B9B291D39765C5AC8EC95B20945E23968659B09872BD9F7CBF -C7B3DAC2B6D04620703F196AB4A5C6805DA64A187D8360A98F829D9389A3624D7A736E78 -C4C0C89A75C04E18867C53A5AF95C9511B885A268E541E8A5E2D91906EB38761ADD2C4E0 -FAF9FBAE96CB8D6AB48965B15623905A27925B29935E2C9560309766379BB49ECF764AA6 -541E905B2694B69FD06E42A05D2C956131976434996232985C2A945622906A3D9E9F81BF -BCA7D2906EB35F2D9256218B5C2A90643395653596541F8AA78CC38964AF5119886D3E9B -A488C19B7ABF572092632F9A67359C65329B66339C66329C66329C66329C66339C66339C -66329C66329C66329C66329C66329C66339C66339C64309A7041A2B9A2D05D2A90633194 -612F9362309462309462309462309463329557228D8C67B0A78BC3541E8A643395623094 -623094623094623094623094623094623094623094602F9269369BA79EB0030500000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000102000000000F16003F5F007BBA0072AC0072AB0071AC -0071AB0072AC0071AC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC -0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC -0071AC0072AC0073AC0073AC0073AC0072AC0072AC0072AC0072AC0072AB0073AC0071AB -0071AA0070A90070AA0070AA006FA9006FA9006FA9006FA90070AA0070AB0070AB0070AB -0070AB006FA8006FA6006EA5006EA5006FA5006FA6006EA6006FA6006FA6006FA6006EA5 -006FA6006FA6006FA5006FA5006FA5006FA5006EA6006FA80070A90070A90070AA0070AA -0070AA006FA90072AC0071AC0072AB0072AC0072AC0071AC0071AC0071AC0072AC0072AC -0072AC0071AC0071AC0072AB0071AC0071AC0071AB0073AC0074AE0074AD0074AC0074AC -0073AB0076B1007AB8007BB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 -007BB8007AB8007BB80079B50078B30079B40079B40079B40079B40079B40079B40079B4 -0079B40079B30079B40079B30078B30078B3007AB9007CBD007CBD007CBD007BBA0078B3 -0079B40079B40079B40078B30078B20079B3007BB8007DBC007EBE007FBF007FBF007FBF -007EBE007EBE007FBE007EBE007FBF007CBB007ABA017BBB0078B987B5DDA35CCD7633BC -8342C2803EC0813FC1803EC1813FC1813FC1813FC1803EC1813FC18241C17831BCB58FDB -A073C8722EAF7B3CB47D3FB5DAC7EA8A50C37A39BB7D3EBD7C3EBD7D3EBD7D3EBD7D3EBD -7D3EBD7C3DBC7E40BD7533B99A6ACDAB88D1B89AD6B08FD09C73C4C8AEE08045B87333B0 -7A3DB5783AB3793BB47B3EB56D29ADB491D49369C06A2DA9743BAE7239AD763EAF6628A6 -9E77C5DED0EC9068B7B69CCEC0AAD5AA8FC5A68BC28C68B19678B5C5BBD2674889391266 -AF9FC25E338C7A53A48C809A6457746E5A868D8796746F79A789C74A13825E2D915B288F -AF97C87F58A85B288F6636976535964B128458258DA285C0845EABD1C2DF9E7FBCA78BC2 -BFABD4A184C0764CA57950A75723914F198B5D2B95B5A0D0B9A3D1561F90916DB7A083C1 -5A289365369A572491602F96784FA79D7FBEB9A5D19371B55E2B9158248D623194643495 -6231946231946232945C2A907B52A5AC91C65F2C92602D92531D8A9270B5C2ADD77647A6 -5C269668359D66339C65329B66339C66339C66339C66339C66339C66329C66329C66329C -66339C66339C65329B67359D5A2494A487C4906DB356208B643395612F93623094623094 -62309463329557228D8C67B0A78BC3541E8A643395623094623094623094623094623094 -623094612F936534964F1986AA87CC555951000000030303000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000100020300000000344F007EBE0073AD0073AE0072AB0071AB0072AB0072AC -0072AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0071AC -0072AC0073AC0073AC0073AC0073AB0073AB0072AC0070AA0070A90071AA0070A90071AA -0070AA0070AA0070AA0070AA006FA9006FA9006FA9006FA9006EA7006EA5006EA6006FA6 -006FA6006FA6006FA5006FA6006FA6006FA6006FA6006FA5006FA5006FA6006FA6006FA6 -006FA6006FA6006EA5006FA5006FA6006FA6006FA8006FA9006FA90070AA0072AB0072AB -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AB0071AC0072AC0073AE0073AB0073AA0077B1007BB9007BB8007AB8 -007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B5 -0078B30079B40079B40079B40079B40079B40079B40079B40079B40079B40079B30079B4 -0079B40079B40078B30079B5007BBB007CBE007BBA0078B20078B30078B30078B3007AB8 -007BB9007EBD007FBF007FBF007FBE007EBE007EBE007EBE007FBF007FBF007FBF007EBE -007FBF007CBB007ABA007BBB0278BA007AB887B7DEA35CCD7633BC8342C2803EC0813FC1 -813FC1813FC1813FC1813FC1803EC07F3CC08647C4C6AADF7534B07C3EB47D3FB56F2AAD -B491D4C5AAE2712CB77F41BE7C3DBC7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC7E40BD7837BA -BE9FDD8451BA7F49B8C1A8DB6424A38755B7BA9DD88248B97332B07A3DB5783AB37B3EB5 -6D2AADB490D4986FC36A2DA9743BAE7239AD753DAF6A2EA98958BAF7F3FBC3B1D66D409B -73479F5E2B91531D8956208CB19DC65E3F81AF9FC12F065EAC9CBF6B3F98AD98C337274C -7C6F8CD6D1DCA9A4B18B64B1A588C2BAA4CF8159A94910837C54A6B39ACB59258E653696 -56218C9575B7BBA5D0774CA24E1786AD94C76F429D4F17876E409C8A65AFBAA4CFB29ACB -AB91C8B39BCD784FA666379BB39BCD9270B767359BB8A1CF4E188B5E2D958966B3B39ACB -B8A3CF916FB4602E9256218C633295633295623194613093623194623194613093623294 -5D2B91BCA6D16230946230946332955B278F70439DB096CA7E53AC5E289766339C67349C -65329B66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C -622D997243A4B49BCC643395612E9362309462309462309462309463329557228D8C67B0 -A78BC3541E8A643395623094623094623094623094623094612F9363329558248B8A60B4 -747177000000020202000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000101000203 -000000003450007EBD0074AE0074AE0073AF0071AC0071AB0072AB0072AC0071AB0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0071AC0071AC0070AC0070AC0071AC0071AC0071AC0072AC -0072AB0071AC0070A90070A90070AA0071AA0071AA0070AA0071AA0070AA006FAA006FA9 -0070AA0070AA0070AA006FA9006EA7006FA8006FA8006EA6006FA5006FA6006FA6006FA6 -006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA5006FA6006FA6 -006EA5006EA5006EA40070A70071A70073AB0073AC0072AB0071AC0072AC0071AC0071AC -0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AB0072AC -0071AC0072AC0074AE0078B2007BB9007AB8007AB8007BB8007AB8007BB8007BB8007BB8 -007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B50078B30079B40079B40079B4 -0079B40079B40079B40079B40079B40079B40079B40079B40079B30079B40079B40078B3 -0079B40079B8007AB90079B4007AB7007CB9007EBD007FBE007FC0007FBF007EBE007EBE -007EBE007FBF007FBF007FBF007FBF007FBF007FBF007EBE007FBF007CBB007ABA007ABA -017CBB0278BA0079B789B8DE9D59CB7531BC8241C1803EC0813FC1813FC1813FC1803EC0 -8140C17B36BD9964CEBA98D87331AF7C3EB47B3CB47A3BB37B3CB4E3D6EF8B52C47939BB -7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC8043BE6F2AB6B896DC9B72C76624A98450BBBFA4DA -6C2FA76D30A87A44B0BDA0D98147B97332B07A3DB57B3EB56D29ADB491D5986FC26A2DA9 -743BAE763FB0682BA79163C0A182C0E8E1EEB59ECD511B88602E9264349559268D9674B9 -907AA9340B62A18DB67459939E87B6A18BB7463A580A0026B9B2C0F8F1FEA789C556218C -511A889573B7CDBEDD9878B959258EAA90C57C53A5521B89916FB4D6CAE3754AA159258E -6130936F439DB098C96B3B9A5C28905B278F541D8A59248E855EAB8159A9AD94C7C0ADD4 -8965B1B9A4D1CCBBDCA78CC57951A8BCA7D1A78CC372459E521C895A278F613093643495 -613093623194623194623194623194623194623194613093653496BBA6D15C288F633194 -612F936332955B278F623094B8A2CEA78BC75D2896602B9867359D65329B66339C66339C -66339C66339C66339C66339C66339C66339C66339C65329B69379E582193AE94CA71459E -5E2A9162309462309462309462309463329558228D8D69B1A589C2541E8A643395623094 -623094623094623094623094612F936332945A2490B29FC521261D000000010101000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000203000000003551007DBD -0073AE0074AF0074AF0072AC0071AC0071AB0072AC0072AC0072AB0072AC0072AC0072AC -0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0072AC0072AC -0072AC0072AC0071AC0071AC0070AC0070AC0070AC0070AC0070AC0071AB0071AC0071AA -0071A90070A90070AA0070AA0071AA0070AA006FA90070AA006FA90070AA006FA9006FA8 -006EA7006FA7006FA7006FA8006FA6006FA5006FA5006FA6006FA6006FA6006FA6006FA6 -006FA6006FA6006EA6006FA6006FA6006EA6006EA5006EA5006FA60070A70072AB0073AC -0074AC0073AB0072AB0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC -0073AC0073AC0073AC0073AC0073AB0073AC0073AC0072AB0073AB0074AE0078B5007AB6 -007BB8007BB8007AB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 -007BB8007AB8007BB80079B50078B30079B40079B40079B40079B40079B40079B40079B4 -0079B40079B40079B40079B40079B40079B40079B40079B40078B30078B2007AB7007EBD -007FC0007FBF007FBF007EBF007EBE007EBE007EBF007FBF007FBF007FBF007FBF007FBF -007FBF007FBF007FBF007EBE007FBF007DBB007ABA007BBA007ABA007CBB0378BA0078B6 -A1C3E4A460CE7939BE8240C1803EC0813FC1813FC1813FC18241C17B36BEC1A3E08B54BC -7634B17B3CB47A3BB37D3FB56F2AADB592D4C9AFE4702BB67F41BE7C3DBC7D3EBD7C3DBC -7E40BD7634B98B53C4B696D67338B17235B0834EBABFA4DA692CA6773EAE6D31A87A43AF -BDA1D98147B97332B07E43B76D29ADB491D5986EC26A2EA9753DAF6223A49061BFAE93C8 -623294B39FCACBBED9794FA45C2A9064349557228CA487C17B63983A136757367DD9D4E1 -BDA6D2A398B034214BB6B2BBDFD1EB4C1484BBA5D0683898673797551F8B5A268F9877B8 -B098C99F82BEAB91C68964AE9B7DBB511B88613093633395643495521D899675B79F80BD -57218C65349665349663329559248E59258E5E2A915B278F8964AE9F81BDE4DCECF9F8FC -B7A1CE6939985A268E5D2B91653696633294613093623194623194623194623194623194 -6231946231946231946332945A278E9E80BD8F6BB258238D633295612F93633194612F93 -541D8A8762ADAB91C97547A65E299768369D65329B66339C66339C66339C66339C66339C -66339C66339C66339C66339C66349C5F2A978E67B5A689C2541E8A643396612F93623094 -62309463319558228D845DABA68AC2541E8A643395623094623094623094623094612F93 -643395541D8AAC90C83F433B000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000204000000003450007EBE0073AD0073AE0075B0 -0074B00073AC0071AB0071AB0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC -0072AC0071AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC -0071AC0071AC0071AC0071AC0071AC0072AB0072AC0072AB0071AB0071AB0071A90070A9 -0070A90071A90070AA006FAA0070A90070AA006FA8006EA7006FA8006EA7006FA7006FA8 -006FA7006FA7006FA7006FA5006FA5006FA6006FA6006EA5006FA6006FA6006FA6006EA5 -006EA5006FA5006FA60071AA0074AB0074AB0074AC0074AB0074AB0073AB0072AC0073AC -0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AB -0073AC0072AB0072AB0074AE0078B2007AB70077B30077B30078B5007AB8007BB8007BB8 -007AB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B5 -0078B30079B40079B40079B40079B40079B40079B40079B40079B40079B40078B30079B4 -0079B40079B40078B30079B3007AB6007DBB007DBC007ABB007EBD007FBF007EBE007EBE -007FBF007FBF007FBF007FBF007FBE007FBE007FBF007FBF007FBF007FBF007EBF007FBE -007EBF007BBB007ABA007BBA007BBA007ABA037DBB0070B644A4CCDAC9ED782BBB8041C1 -813FC1803EC0813FC18140C17A35BD965ECCBA99D8702CAE7D3FB57B3CB47B3CB47A3BB3 -7A3BB47B3CB4DFD0ED8B52C47838BA7D3FBD7D3EBD7D3FBD7938BB894FC3E6DBF2763DB3 -7235B07235B0824EBAC1A7DB6A2DA6743BAD743BAD6D31A97943AFBDA0D98147B96E2BAD -6F2CAEB491D49970C3672AA77239ADB79AD7AE92C84F1986A386C179599C8768A6C2AED5 -55208B6231936E409DB3A2C5421D6C4D2A753C1569AE9DC1FFFFFF787083ABA9B0B89DD2 -73479E9371B5B7A1CE5F2C92521B896C3D9B71449E5E2B91845CABEEE9F3FFFFFFC7B6D8 -613094623194531D89602F936232946434965E2C91C0ADD46635965E2B91623094623194 -653596602D92551F8B6B3D9AA88DC4D0C1DFB099C8DBD1E5A58AC18059A9521C89623194 -633395613093623194623194623194623194623094623094623194623194623194633395 -56228C8A67AFA487C1541E8A643395623094612F9362309465349656218C825BAABDA7D1 -855BAF5A249469379D66339C65329B66339C66329C66329C66339C66339C66339C66339C -66339C65329B632F9AB29ACD73479F5E2A916231946230946230946231945C2890A68AC2 -835CAB5B278F6331946230946230946230946230946230945D2B90784AA68F8995010300 -000001000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000102000000003450007EBE0077B30073AD0075B00075AF0074AD0072AD -0071AB0071AB0072AC0072AB0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC -0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0070AC0071AC0071AC -0070AC0072AC0071AB0071AC0072AC0072AB0072AB0070AB0071AB0071A90070A90070A9 -0070AA006FA8006EA7006FA8006FA7006FA8006FA8006FA7006FA8006FA8006FA7006FA7 -006FA7006FA5006FA5006FA6006EA5006EA5006EA50070A80070A80073AA0074AB0074AC -0073AB0073AC0073AB0073AB0074AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC -0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AC0072AB0073AC0076B1007AB7 -007AB60079B60077B30078B40077B30078B40078B4007AB8007BB8007BB8007AB8007AB8 -007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B50078B30079B40079B40079B4 -0079B40079B40079B40079B40079B40078B30079B40079B40078B30078B3007AB6007DBB -007EBD007EBD007CBB007ABA007BBA007EBD007FBF007EBE007FBE007FBF007FBF007FBE -007FBE007FBE007FBE007FBF007FBF007FBF007EBE007FBE007EBF007ABB007BBA007ABA -007BBA007BBA007ABA027DBB006FB53B99C9B691D97B30BD8040C1813FC1803FC18140C1 -7B37BEA97CD4A87FCD7330AF7C3EB47B3CB47B3CB47B3CB47C3EB4712DAEAE88D0C3A5E0 -722EB77E40BD7C3DBC7F41BE7330B8B895DAA37CCB6D2FAE773DB37439B17338B1DBCDEB -9164BE6B2EA7743AAC743BAD6D31A97A43B0BB9ED8A87ECE661FA9B694D6956BC1682BA9 -B599D38865AC613093531D89A386C1896BA7441576D9D1E47F57A84D1686AB8FC6775D95 -3710644722728A76A1DDD8E350485B211D2BCCC4D29D7DBD9573B6CBBBDCFFFFFFBFABD4 -9371B6B69FCDBBA6CFBFACD3A88EC16636939E81BAB39FC9B9A4CDAA90C4A183BF6A3C9A -5D2B915D2A91521C887B51A5AE94C75E2C916332955F2C92521C896B3C9AB39BCBDFD5E9 -B39DCA653595693C98AD94C64D1682A98EC4A68AC264339557238C643495623194613093 -62319462309462309462309462309462319462319463339556228C9371B59D7EBC531D8A -643395612F93623094623094612F936433955A258E57228CAC91C68A62B35A239465329B -67349C65329B65329B66329C66329C66339C66339C66329C66329C68369D582093A080C2 -8761AD58248D633194623094623094623094612E93BAA5D05E2A91623094612F93623094 -623094623094612F936332945F2A95B0A4BA0C1007000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000203 -00000000344F006EA50079B60072AC0075B00075B00074B00073AD0072AC0071AB0071AC -0072AC0071AC0071AC0071AC0072AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC -0071AC0071AC0071AC0071AC0072AC0071AC0070AC0071AC0070AC0072AC0071AC0072AC -0071AB0071AC0071AC0072AC0072AC0072AB0071AB0070AB006EA7006EA8006EA8006EA7 -006EA8006EA8006EA8006EA8006EA8006EA7006EA8006EA8006EA8006EA7006EA6006EA5 -006FA6006FA80073AA0074AB0074AC0074AC0074AC0073AB0074AC0073AB0073AC0073AC -0074AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB -0073AC0073AC0072AB0072AA0076B20079B5007AB60079B60079B6007AB60077B30078B4 -0078B40077B30077B30078B40078B4007AB8007BB8007BB8007AB8007BB8007BB8007BB8 -007BB8007AB8007BB8007AB60078B30079B40079B40079B40079B40079B40079B40078B3 -0079B40079B40078B30078B3007AB6007DBB007EBD007EBD007DBC007EBD007CBB007ABA -007ABA007ABA007EBE007FBE007EBF007FBE007FBF007FBE007FBE007FBE007FBE007FBE -007FBF007FBE007EBE007FBE007EBF007ABB007BBA007BBA007BBA007BBA007BBA007ABA -047DBC0072B543A4CDB590D97B30BD8040C1813FC18342C17831BDC1A3E07E41B5793AB3 -7A3BB37B3CB47B3CB47B3CB47B3CB47A3AB37D3FB5D6C3E88951C37939BB7F42BE702BB6 -AD83D5A984CE6523A9773DB37439B1773DB36727AAAA84CE9B73C3692BA6743BAC7238AB -743BAD6E31A97841AFB091D0A378CBAA81CE9B72C5AE90CF7B54A3541F8B65359655208B -A285C08B6EA93C0B70967BB1C9B7DA4D1586B5A0CB56367B64428A8D7BA3B2ACBBA3A1A7 -27212EAA93BF8D69B09071AD9374B18461A69A7CB6FCFCFCDCD2E75E2B8E4F198359268A -57238958258A623291B6A0CC4F1C8079529E9375B1B39DCAC3B0D5A387C08D6AB255208B -9F81BD855EAC541D8A6B3C9AB49CCCDED4E8B199C9683A98501C8758268C764EA1B7A2CD -541F875E2D8E9473B3AB91C48159A959258D602F93633294613093623194623094623094 -623094623194623194623194612F93653696B39BCB6B3C9A5F2C92623094623094623094 -623094612F936432956230945A268EAB8FC5B69FD064319B5F2A9767359D65329B66339C -66329C66339C66339C66329C66339C66339C632E99784BA8B49DCC59248E643395612F93 -623094623094602D92BDA8D2653496612F93623094623094623094612F93643396521D88 -9D76C3636461000000030203000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000203000000000507005E8D -007DBC0072AB0075B00075AF0075B00074B00072AD0072AB0071AB0072AC0072AC0072AC -0071AB0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AC0072AC0071AC -0071AC0072AC0071AC0070AC0071AC0072AB0071AB0071AB0071AB0071AB0072AC0072AC -0071AB0072AB0071AB006FA80070A7006FA7006FA8006FA7006FA8006FA8006FA8006FA8 -006FA8006FA8006FA7006FA7006FA7006FA8006FA60070A70073AB0074AC0074AC0073AC -0073AB0073AB0073AB0074AC0073AC0073AC0073AC0073AC0074AC0073AC0072AC0073AC -0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0072AB0072AB0074AD0077B3 -007AB6007AB60079B6007AB60079B6007AB60077B30078B40077B40078B40078B40077B3 -0077B30078B4007AB8007AB8007BB8007AB8007AB8007BB8007BB8007AB8007BB8007AB8 -0079B40078B30079B40079B40079B40078B30079B40079B40079B30078B3007BB6007DBB -007EBD007EBD007DBC007DBC007DBC007EBD007CBB007ABA007BBA007ABA007ABA007EBE -007FBE007EBF007FBF007FBE007FBE007FBE007FBE007FBF007FBF007FBF007EBE007FBE -007EBF007ABB007BBA007BBA007BBA007BBA007BBA007BBA007ABA047DBB0070B53FA4CD -B58FD97C31BD8142C17C37BE9862CCB693D67939B27B3CB47B3CB47B3CB47B3CB47B3CB4 -7A3BB37D3EB5702BADB28DD2C2A3DF722FB77E3FBD8348C0BB9DDB7A41B47338B1753AB2 -753AB2773DB36929ABB18FD29B73C3692BA6743BAC7238AB7238AB763DAD7338AC6221A1 -8A5AB9EBE1F4C2ADD86E429C5C2990653596643495541F8AA385C0876AA64B1D7B532881 -D1C4DD9F7FBF8C74A669498D948A9D91889CF7F6F9635C6BD1CDD76B3D974A167B552384 -53218349137B825DA5997CB663388FAE94C76E41995B288C623291633492531E869D7FBA -9577B24D197F5220825F318C5B2B88835FA5AA92C1B198C8C2AFD5C2AED56D3F9CE3DAEB -B29ACA683A97501C875D2C8F6334945B298E744B9FB49ECB552088633492501A8472489B -B49CCA9574B76333955D2B90653596613093613093623194623094623194623194613093 -64349556218CB49CCC6B3B9A5F2C92623094623094623094623094623094612F93623094 -62309458238D7B51A4AF96CB7648A75F2A9767359D66339C65329B66339C66339C66339C -66329C65329B67359D5B2595AE92CA855FAB58228D643295612F93623094602D92BEA9D2 -633295612F93623094623094623093623094602E926A389B9A8DA8131610000000010101 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000102000000000506005E8D007DBC0072AC0075B0 -0074AF0075AF0075B00074AD0072AD0071AB0071AB0072AB0071AC0073AB0073AC0072AC -0072AC0072AC0072AC0072AC0073AC0073AC0072AC0071AC0072AC0072AC0071AC0070AB -0070AB0072AB0072AC0072AC0072AB0072AC0070AA0070AA006FA7006FA5006FA5006EA5 -006FA5006FA70070A8006FA70070A80070A80070A80070A80070A80070A80070A80070A8 -0070A80070A70070A90071AC0071AC0072AB0073AB0074AB0074AC0073AC0073AC0074AC -0074AC0074AC0074AC0073AC0074AC0073AC0072AC0073AC0072AC0073AC0073AC0073AC -0072AB0073AC0072AB0072AA0074AE0077B3007AB5007AB60079B60079B6007AB6007AB6 -0079B6007AB60077B30078B40078B40078B40077B30078B40078B40077B30077B40078B3 -007AB7007BB8007BB8007AB8007AB8007AB8007BB8007AB70078B30078B30079B40079B4 -0079B40079B40078B30078B30079B4007CBB007EBD007EBD007DBC007DBC007EBC007DBD -007DBC007EBD007BBB007ABA007BBA007BBA007ABA007ABA007EBE007FBF007EBE007FBF -007FBE007FBE007FBF007FBF007FBF007FBF007EBF007FBE007EBF007ABB007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007ABA037DBC006FB543A5CDB18CD97B36BE7833BD -A97CD5A67CCC6F2BAD7D3FB57B3CB47A3BB37B3CB47B3DB47B3DB47B3DB47A3BB37C3EB4 -E3D6EF8C55C56C25B5C9AEE28856BB6D2FAE763BB27439B1753AB1773DB36929ABAF8BD1 -956BC0692BA6743BAC743AAC743AAC682BA66A2DA78350B6A985CCDCCFE9CABAD970429D -541F8B633294663696531E8A9E7FBD896CA74D1F7C4F237E7F5FA1DBCEE7CBBFD97F718C -140728C7C1CCDEDFDE917BA770469DAB96C3673B925A2A8863368F5624858561A7A88FC1 -44117A7B57A1BEACD18561A95724895E2D8E613190623291B9A6CE5D2E8A61338D5D2E8A -5E2F8B5725864E1A7F65388F7A539EDDD4E6D1C3E05F2F914B15835F3091623293603192 -6030915B2A8E6F449CB49ECB5520876232916333915C298C4F19849A7BB8BBA5CF6D3F9C -531E8A6433956231946130936231946231946231946231946332945A278EA082BE8B67B0 -5A268F633194623094623094623094623094623094612F9362309464339558238D7448A0 -BFABD4946FB9561E92632F9A67359D65329B66339C66339C66339C66339C67349C602B98 -794DA9AF97CA602D92623094623094623094602D92BEA9D2633295612F93623094623094 -612F93643395521A8AB8A1CE2B3225000000010101000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000101000000000609005E8D007DBC0072AC0075B00074AF0074AF0075B0 -0075B00074AE0072AC0071AC0073AB0072AC0072AC0073AB0073AC0073AC0073AC0073AC -0072AC0072AC0073AC0073AC0073AC0073AB0071AB0071AB0071AC0072AB0070AB0071AB -0070A7006FA6006EA5006EA5006EA5006EA6006EA6006FA6006EA5006FA7006FA80070A7 -006FA80070A70070A80070A80070A80070A80070A80070A8006FA70070A80071AC0070AB -0070AB0070AC0071AC0071AC0073AC0074AC0074AC0074AC0073AC0074AC0074AC0073AC -0074AC0073AC0073AC0072AC0073AC0073AC0072AB0073AC0073AC0072AA0073AD0076B0 -007AB5007AB70079B60079B6007AB6007AB6007AB6007AB60079B6007AB60077B30078B4 -0078B40078B40078B40078B40078B30078B40078B30077B30077B30079B7007AB7007BB8 -007AB8007AB8007BB8007AB80079B40078B30079B40079B40078B30078B30079B4007BB8 -007DBC007EBD007DBC007DBC007EBD007EBC007EBD007EBD007DBC007EBD007BBB007ABA -007BBA007ABA007BBA007ABA007ABA007EBD007FBF007EBE007FBF007FBE007FBF007FBF -007FBF007FBF007EBE007FBF007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007ABA047CBB0073B6A2C3E4994CC77736BDC7ABE18349B87C3EB47D3FB5 -7D3FB57D40B57B3CB47533B07533B07533B07737B26922AAAF8AD1C1A2DF9460C8A37BCC -6D2EAD7940B4773DB3773DB3773DB37940B46929ABB08DD2AE8CCE6B2EA7733AAC6A2CA6 -7035AA996DC2AE8CCFBDA6D78A61B8ECE4F5A084C3A487C49979B85F2D925B288F5E2C91 -A98EC47B5B9D4516764D207D7F5CA2D1C6DA5E516B17012C968F9FD7DAD5CAB7DD572888 -512283694195B09BC7653890552384552485CCBDDA9678B4522384592B884E1E82A187BB -BBA4CE6333925824895623899B7BB99576B2511E8160328D5D2E8A60328C5F318C572686 -A68DC06941957C57A2A890C3754BA057258C6233935F2F9161319259278D835EA9A58BBF -5622886231905F2E8F613090633391531E86663793AF96C68F6CB35B288F5D2A90633395 -6130936231946231946231946231945C29907348A0B49CCB56208C643395623094623094 -623094623094623094623094623094612F936332955E2B91531C899B7BBBA98CC76E3FA2 -5F2A9769389E65329B66339C66339C66339C65329B69379E5A2394B299CC6A3B99602D92 -612F93623094602D92BEA9D2633295612F93623094612F936332955A268D8D67B3666468 -000000020202000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000101 -000000000608005E8D007DBC0072AB0075B00074AF0074AF0074AF0075B00075B00073AF -0073AB0072AB0073AB0073AC0073AB0073AC0073AC0073AC0073AC0073AC0072AC0072AC -0072AB0073AC0073AC0072AC0070A80070A6006EA5006EA5006EA5006EA5006FA6006FA6 -006FA6006FA6006FA6006EA6006FA6006EA5006FA7006FA80070A7006FA80070A70070A8 -0070A80070A80070A70070A8006FA70070A80071AC0070AB0071AB0071AC0070AC0070AC -0070AC0072AC0072AC0074AC0074AC0073AC0073AC0074AC0073AC0074AC0073AC0072AC -0073AB0073AC0073AC0072AB0072AB0076AF0078B5007AB70079B60079B6007AB6007AB6 -007AB6007AB6007AB6007AB60079B6007AB60077B30078B40078B40078B40078B40078B4 -0078B40078B40078B40078B40078B30077B30077B30079B6007BB8007BB8007BB8007AB7 -0079B40079B40078B30078B30079B4007BB8007DBC007EBD007EBD007DBC007EBD007EBD -007EBD007EBD007EBD007EBD007DBC007EBD007BBB007ABA007BBA007BBA007ABA007BBA -007ABA007ABB007EBD007FBF007EBE007FBF007FBF007FBF007FBF007FBF007EBE007FBF -007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -0078BA0C81BC9CAFDFA460CEB698D86922A9712DAE6F2BAD702CAD6E28AC7838B2915DC0 -925EC0925DC0925DC0925DC09360C0E7DBF2DFD0ED8958BC7D46B66625A9692AAB6929AB -6828AB6B2CAC6F31AE8753BCD3C2E66525A3743AAD9A70C3D1BFE3D1C2E38C63B85A1E9A -8861B4CFC9D77549A85B2796A083C3BEABD48560AB623195AB95C2401073825FA4A491B9 -BCB3C9E7E5E81B053149395BA9A9AAB9A6CD3D07744D1E7F5C308A512181653C90A993C2 -7B54A0582786B9A6CD5D318C5D308B5D308B5E318C5121836D4697AF97C77A51A2572389 -643492B7A4CC5E2F8B5D2E8A5F308B5C2C895A2A88AC96C477539F542585542585805EA5 -B69ECC7A51A355228A63339362329354218AB69FCC6F42995B298C602F8F602F8F602F8F -5F2E8F6333915A288C663693A98EC2A284BF6D3F9C5A278E633294623194613093623194 -6231945B288F7E56A7AD94C7521B89653496612F93623094623094623094623094623094 -623094623094612F9362319464339558238D916EB3B39CCD7142A4571F9268369D66339C -65329B66339C66339C66349C5F29979673BB9C7CBB541E8B643395623094602D92BEA9D2 -633295612F936230946230945F2D90652F9BB3A9BD000200000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000101000000000405005E8D -007DBC0071AA0074AF0075B00074AF0074AF0075AF0075B00075AF0073AD0072AC0072AB -0073AC0073AC0073AB0072AC0073AC0072AB0072AB0072AB0073AC0072AB0070A8006FA6 -006EA5006EA6006FA8006FA7006FA5006FA5006FA5006FA5006FA6006FA6006FA6006FA6 -006EA6006FA5006EA6006FA60070A8006FA7006FA80070A80070A80070A80070A8006FA7 -0070A80070AC0071AC0070AB0071AC0070AC0071AC0071AC0071AC0070AC0070AC0072AC -0073AC0074AC0074AC0073AC0073AC0074AC0073AB0072AC0073AC0073AC0072AB0073AD -0076B0007AB6007AB60079B60079B6007AB60079B60079B6007AB6007AB6007AB6007AB6 -0079B6007AB60077B30078B40077B40077B40078B40078B40078B40078B40078B40077B3 -0078B40078B40078B40077B30077B30079B5007BB9007BB80078B30078B30079B4007BB8 -007DBC007EBD007EBD007DBC007DBC007EBD007EBD007EBD007EBD007EBD007EBD007DBD -007DBC007EBD007BBB007ABA007BBA007BBA007BBA007ABA007BBA007ABA007ABB007EBD -007FBF007EBE007FBF007FBF007FBF007FBF007EBE007FBF007CBA007ABA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBB0177B9047DBAB8DDED -CFAFE0B797D7BB9BD8BB9BD8BC9CD9B592D5D8C6E9D0BBE8BA9ADCBFA1DFBEA0DEBFA2DF -BA9ADCD8C6EBF5F0F9B896D6BC9FDAB899D7B99AD8B899D7BB9DD9AF8CD27A43B47941B5 -BFA5DBA17AC7BFA5D8A484C7713FA8642DA05E269D7645ACCEC0DE7B6397A286C25E2B98 -58249468399F9F81C1B59ECCD7CCE2A691BC8F81A17A689070657C91899A39264CBAB6BE -DFE0DDCFC1DFA890C1A98EC56638976D419C643495734AA0AB97C38461A4AF9BC5502282 -5223835D318B5C2F8A5F338C5526856B4295B8A4CC997AB6521D869878B89677B3532183 -5E2F8B5A2988AC95C477529E5121835E328D5E328C512183572887AD96C57C53A5542289 -66379654218AB69FCD754A9D5A288B602F8F602F8F602F8F602F8F5F2E8F6130905E2D8E -4E17828864ACBAA6CF8058A85B288F612F93633395613093623194602E92683A98B097C9 -6C3D9B5F2C92623094623094623094623094623094623094623094623094623094612F93 -612F93643395541D8A683797B49DCDA181C25D279666349C67349C65329B66339C66339C -64309A69369EB69DCE6B3D9A5F2C92623194602D92BEA9D2633295612F93612F93623193 -5D2893A791BC222420000000010201000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000101000000000608005D8C0081C20074AE0074AF -0075B00074AF0074B00074AF0075B00075B00074AF0074AC0072AB0072AB0072AC0073AC -0072AB0072AC0073AC0073AC0072A9006FA6006EA5006FA5006FA5006FA6006FA8006FA8 -006FA7006FA7006FA7006FA6006FA5006FA5006FA6006FA6006FA6006FA6006EA5006FA6 -0070A7006FA8006FA7006FA80070A8006FA70070A8006FA70070A80071AC0070AB0071AC -0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AC0070AC0071AC0073AC0074AC -0074AC0074AC0073AC0072AC0072AB0072AB0077B1007AB6007AB70079B60079B6007AB6 -0079B60079B60079B60079B60079B6007AB6007AB6007AB60079B6007AB60077B30078B4 -0077B40077B40077B40078B40078B40078B40077B40077B40077B40077B40078B40078B4 -0077B40078B30079B60079B60079B4007AB8007DBC007EBD007EBD007DBC007DBC007EBD -007DBC007DBD007DBD007EBD007EBD007DBD007DBD007DBD007DBC007EBD007BBB007ABA -007BBA007BBA007BBA007BBA007ABA007BBA007ABA007ABA007EBE007FBF007EBE007FBE -007FBF007FBF007EBE007FBF007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007ABA017CBB0075B90E85BFC0C3E8965CC89A69CC9866CB -9866CB9967CB9562C97634B9712CB7722EB7722EB7702AB67D3DBDB492D4B799D47F42B6 -7C3DB49B6BC69663C39765C49562C29D6FC7C8AFDFC3A8DCE4D9EF9D7BC37140A85D239C -6832A36B37A5632D9F895DB9A895BA3B1364BAA5CD64329D66369D61309A572393A889C9 -C5BDCE4B34682107469185A17A7382675975AEA4B6A1A2A01616172C2E29292E259B9D9A -A39EAA9D98A39B95A1B0ACB4B9A2D3CEB9DEF3EFF89F7FBF835DAB5422875B2B8C5A2A8C -5627884C1C7E400C758465A6B19DC774499DAE97C55B2B885C2D89AE99C67A56A0522283 -5F338D5C2F8B5C2F8B5F328D5A2C89582A88AD96C57C54A6531F8855228AB8A1CE74499D -5A288C602F8F5F2E8F602F8F602F8F602F8F5F2E8F602F8F63339257238958258AAF96C6 -AF97C95E2B9159268E643395613093653596521C89A589C28862AD59248D633194623094 -623094623094623094623094623094623094623094623094623094612F936534965D2A91 -6433959A79B9A586C45B2495612C9867359D65329B65329B69379E572092A689C57E55A6 -5A268F633194602D92BEA9D2633295612F936331955A278D8459B0868686000000030203 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000010100000000080C002E460077B30076B10073AE0075B00074AF0074B0 -0074AF0074AF0075B00075AF0074AF0073AC0073AB0072AB0073AC0073AB0071A9006FA7 -006EA5006EA5006FA6006FA6006FA5006FA6006FA8006FA7006FA8006FA8006FA8006FA7 -006FA6006FA6006FA5006FA5006FA5006FA5006FA6006EA5006FA50070A7006FA7006FA7 -0070A80070A8006FA70070A80070AB0071AC0070AB0071AC0071AC0071AC0071AC0071AC -0071AC0071AC0070AB0071AC0071AC0071AC0070AC0071AC0073AB0074AB0073AB0072AB -0075AF0079B5007AB6007AB60079B5007AB60079B6007AB6007AB60079B60079B60079B6 -0079B6007AB6007AB6007AB60079B6007AB60077B30078B40077B40077B40077B40078B4 -0078B40078B40077B40077B40077B40077B30078B40078B40077B30077B30078B4007AB7 -007CBB007EBE007DBD007DBC007DBC007EBD007EBD007DBD007DBD007DBD007DBD007EBD -007EBD007DBD007DBD007DBC007EBD007CBC007BBB007ABA007BBA007BBA007BBA007BBA -007BBA007ABA007BBA007ABA007ABA007EBE007FBE007EBF007FBE007FBE007EBE007FBF -007CBA007ABA007BBA007BBA007BBA007BBA007ABA007BBA007BBA007BBA007ABA007ABA -007CBB007DBB0380BE0072B56DAACEA15ECB6A27B47836BA7633B97533B97634B97E3FBD -7F41BE7F41BE7F41BE7C3EBC874CC3B798D58452B6C0A3DB702CAE7433B07432B07431B0 -7431B07635B16D27AC9662C3C0ADD4875CB55E259D6E3BA66934A36B37A561279FB49CD0 -5F3F8148236FBCA8CF63319C64339B67379E562292CCBBE2C4BECC0C00369E91AF4C4258 -463A54FFFFFF979796000000000000000000000000000000000000000000000000080908 -52554F4B4D4A4A4B4A4B504677737AB5A7C4ACA0B9A89BB6C4BAD0A989C8855EAE8056AA -9470B8AB8FC6AE96C79474B29477B46D449844107B572A87562985562985562985562885 -572A86542684542684AC94C49473B655228AB59DCC774D9F5C2A8D602F8F602F8F602F8F -602F8F5F2E8F5F2E8F602F8F5F2E8F623190613090511C857C54A3AE96C8794FA459258E -613093653596541F8BAD94C77D53A659258E633194623094623094623094623094623094 -623094623094623094623094623094623094612F93633194612E93521B898E6AB1AC8FC8 -7344A55E299769389E66339C66339C612C998157ADB096C956208B643396602D92BEA9D2 -633295612F93643394551E8DB8A3CD242920000000010101000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0002030000000023360079B70075B10073AE0075B00074AF0075B00074B00074AF0074B0 -0075B00075AF0074AE0072AD0072AB0070A8006EA5006EA5006FA6006FA6006EA6006FA6 -006FA5006FA6006FA7006FA8006FA7006FA7006FA7006FA8006FA8006FA7006FA6006FA6 -006FA6006FA6006FA5006FA6006FA6006FA50070A8006FA7006FA80070A7006FA80070AB -0071AC0070AB0071AC0071AB0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC -0070AB0070AB0070AB0070AB0071AC0071AC0072AB0078B3007AB7007AB60079B50079B6 -0079B60079B6007AB6007AB6007AB60079B60079B60079B60079B6007AB6007AB6007AB6 -0079B6007AB60077B30078B40077B40077B40077B40078B40078B40078B40078B40077B3 -0078B40078B40077B30077B30078B4007AB8007DBC007DBC007ABA007CBC007EBC007EBC -007DBC007EBD007EBD007DBD007DBD007DBD007DBD007EBD007EBD007EBD007DBD007DBC -007EBD007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA -007ABA007ABA007EBE007FBE007EBE007EBF007FBE007EBF007BBA007ABA007BBA007BBA -007BBA007BBA007BBA007ABA007ABB007ABB007CBB007DBB007EBD007DBD017FBE0072B4 -1D87B4ABA8DD803EBD7D40BD7D3FBD7D3FBD7D3FBD7D3EBD7C3DBC7D3EBD7E3FBD7634B9 -A57BD2A580CA6221A2BEA3D98D56BE7837B27C3DB47B3DB47B3DB47B3DB47C3CB5B699D2 -987BB7A788CA5F269D6C38A56B36A4632C9F8A60B99F8AB4411B6A4E2B74BBA7CE63319C -66369D5925957E54AEFFFFFF75628C442965A09AA900000A6E627BA8AAA7000000040404 -010101010101010101030303030203030203030203020203000000000000000000000000 -010300050802060903000000282B258283807475737B7C796E6F6C9C91A8FCFAFFFFFFFD -C8BBD7A38CBCB5A3C9815BA96F419E7347A07246A07246A07246A07549A26C3E9A49197C -9C80B88C6BAFB39BC96537924F1A8260308F5F2E8E5F2E8E5E2E8D60308F613190613190 -613190613190602F8F633392552188784EA0B8A2CC8E6BB2602E925F2D925D2A908762AD -A387C05B268F633194623094623094623094623094623094623094623094623094623094 -623094623094623094612F9362309465349656208C8862ADBAA4D17F55AD541B9066349C -66339C66349C5E2997AD93CA7E55A75C2890623094BDA9D263329564329556208BA385C2 -464843000000020202000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000001000203000000002336 -0079B70075B10073AE0075B00074AF0075B00075B00075AF0074AF0074AF0075B00074AF -0071A9006EA5006EA5006EA6006FA6006FA6006FA6006FA6006FA6006FA5006FA6006FA8 -006FA7006FA7006FA8006FA7006FA7006FA8006FA8006FA8006FA8006FA6006FA5006FA6 -006FA6006EA6006FA80070A70070A80070A7006FA80070AB0071AC0071AC0071AC0071AC -0071AC0070AB0070AB0070AB0070AB0070AB0070AB0070AB0073AE0073AE0072AE0075B1 -0076B30076B30076B30076B40078B40079B5007AB6007AB60079B60079B60079B6007AB6 -007AB6007AB6007AB6007AB6007AB6007AB6007AB6007AB60079B6007AB60077B30078B4 -0078B40078B40078B40078B40078B30078B40078B40078B40077B30077B30078B4007AB8 -007DBC007EBD007EBD007DBC007ABA007BBA007CBD007DBC007EBC007DBC007EBD007EBD -007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007CBB007ABA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007ABA007ABA007EBE -007FBF007EBE007FBE007DBF007ABA007BBA007BBA007BBA007BBA007ABA007ABA007BBA -007DBC007DBD007EBD007EBD007DBC007DBC007EBE027BB80066A6399DC0C19ADE6F27B5 -7F42BE7C3DBC7D3EBD7D3EBD7D3EBD7C3DBC7F41BE712CB7BA9BDC8451B56828A68B5BBA -BD9ED9702CAE7D40B57A3BB37C3EB4722FAEA172CAA58AC14E1786BDA8D37443AB6631A1 -6C38A55D249CA07DC67B60953F176A4E2B74BBA8CE64329D5F2D97794BAD907DA4A399AC -432963827297585264736880747276000000020202000000000000000000000000000000 -000000000000000000000000030303030303030303030303020202000000000000000000 -0000000000000000000000000000001214101616151110111C1E19242820191D14787679 -9D99A094919796929996929996929995929898919FA588C3916FB5C0ACD6FEFDFFAD91CA -9571B9602B93643196632F956531975B278C521F8454208553208555218660308F623290 -6434925C2B8D521D85A083BBB9A3CF6B3D9A59258E633395BBA6D15E2B91623194623094 -623094623094623094623094623094623094623094623094623094623094623094623094 -623094612F9364339558238D5C2990AA8FC6A688C664309A64309A6A389E5922949571BA -9472B657228C5F2C91BBA6D16534965D2B8F703EA1A099A7000300000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000002030000000024380079B60075B10073AE -0075B00074AF0075B00075B00075B00075AF0074AF0075B00075B00074AF0070A9006FA5 -006EA5006FA6006FA6006EA6006FA5006FA5006FA6006FA8006FA7006FA8006FA8006FA8 -006FA8006FA7006FA7006FA7006FA7006FA8006FA8006FA7006FA5006FA6006EA5006FA8 -006FA8006FA70070AB0070AC0070AB0070AB0070AB0070AB0070AB0072AD0072AD0071AD -0074B00075B20075B20075B20077B40077B40077B40077B40077B40077B40076B40075B3 -0075B30076B40076B50078B5007AB6007AB6007AB60079B60079B6007AB6007AB6007AB6 -007AB6007AB6007AB6007AB60079B60079B50077B40078B40078B40078B40078B40078B3 -0078B40077B30077B30077B30078B4007AB8007DBC007EBD007EBD007DBC007EBD007DBC -007ABA007BBA007ABA007BBA007DBC007EBD007DBC007EBD007EBC007EBD007EBD007EBD -007EBD007EBD007EBD007DBC007EBD007CBB007ABA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007ABA007BBA007ABA007ABA007EBD007FBF007FBE007DBF -007ABA007BBA007ABA007ABA007ABA007BBA007DBD007DBD007EBC007EBC007EBC007DBC -007EBD007DBC007EBD0078B50274AD0071AB78A9D19C63CB7636BA7D3FBD7C3DBC7D3EBD -7D3EBD7D3FBD7736BA915AC7B899D66F33A9753AAD6B2DA7BB9ED78F59BF7534B07B3DB4 -7B3CB47837B3C1A6D96D419A541F8BAE94C8875CB6632C9F6A35A36E38A8B6A2CC512D75 -4B25724D2972BAA6CD64339D582594AC90CB4F3F5E746384998AAC6F657B6F6778575955 -090909000000010101000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000010101050505040404040404 -050505010101000000000000000000000000000000000000000000000000000000000000 -000000000000080807444841474C423F423C3939393D42395C5D5CB1A5BBAA9FB3AA9FB5 -ADA5B49D83B79268BB946DBA956DBB8D67B45C298E55208957228A58238B5B298B4C1680 -61328FB8A3CC9372B3623294B9A4CF59248E673797633295612F93623094623094623094 -623094612F94623094623094623094623094623094623094623094623094612F93643395 -602D92602D929776B7AD91C9622D995E299767349C6D3DA1BAA4D1551F8B9472B69B7BBB -58248C612B97B2A4C113170E000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000002030000000024370079B60075B10073AE0075B00074AF0075B0 -0075B00075B00075B00074AF0074AF0075B00075B00074AE0070AA006FA5006EA5006FA6 -006FA6006FA6006EA6006FA6006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA7 -006FA8006FA7006EA7006FA7006FA7006FA7006FA8006EA5006FA60071AB0071AC0071AC -0071AC0073AF0074B10074B00074B10077B40077B40077B40077B40077B40077B40077B4 -0076B30076B30076B30076B30077B30076B30075B30076B40076B40075B30075B30075B3 -0076B50078B50079B5007AB6007AB60079B60079B60079B6007AB6007AB6007AB6007AB6 -0079B60077B30078B40078B30077B30078B40078B40078B40077B30078B40078B4007AB8 -007DBC007EBD007EBD007DBC007DBC007DBC007EBD007DBC007ABA007BBA007BBA007ABA -007BBA007DBC007EBD007DBC007EBD007DBC007EBD007EBD007EBD007EBD007EBD007DBC -007EBD007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007ABA007BBA007ABA007ABB007EBD007FBF007DBE007ABA007ABA007BBA007BBB -007CBD007EBC007EBC007EBC007DBC007DBD007EBD007EBD007DBC007EBD007DBB0074AD -0074AE006FAC087EAFB6B7E17B36BB7D40BD7C3DBC7D3EBD7D3EBD7D3FBD7533B99E6FCF -B292D06525A4773DAE6C2EA88D5DBBBB9BD8712EAE7E40B57230AFA071CAA488C055208B -602E9273499FB9A1D3642CA060289E9873C18770A13F18694E29744B2771B9A5CC602E99 -7445ABADA1BA2C1441DEDAE2C5BCCF8E88942A2B2A000000040404000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000010101010101 -010101010101000000030303040404040304040304040304040304040404030303000000 -000000000000000000000000000000000000000000020202000000393A3872746F696C67 -5D5F5BA8ABA5C9B9D8AD99BFB29EC4B6A4C58B64B17D4FAB7C4EA97544A5AE90CB8D6AB0 -A68BC2794FA34B128359258D602F915F2D915F2D915F2D90623194643395633295643295 -643295633194612F93623094623094623094623094612F93623094623194521B897A4FA4 -C2AED68C67B65C25955C2695A687C58660AC9573B7916EB44F1887926FB6626361000000 -020202000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0002030000000023350079B70075B10073AE0075B00074AF0075B00075B00075B00075B0 -0075B00074AF0074AF0075B00075B00074AE0070AA006EA5006EA5006FA5006FA6006FA6 -006FA8006FA7006FA8006FA8006FA8006FA8006FA7006FA8006FA8006FA8006FA8006EA7 -006EA7006EA7006EA7006FA70071A90072AC0077B40077B40076B30077B40077B40077B4 -0077B40076B30076B30076B30076B30076B30076B30076B30076B40077B40077B40076B4 -0077B40076B40075B40076B40076B30076B40076B40076B40075B30075B30076B30077B5 -0079B6007AB6007AB6007AB60079B60079B60079B6007AB60079B60077B30078B40078B4 -0078B40077B40077B30077B3007AB6007DBB007DBC007EBD007EBD007DBC007DBC007EBD -007DBD007DBC007EBD007DBC007ABA007BBA007ABA007BBA007ABA007BBA007DBB007EBD -007DBC007EBD007DBD007EBD007EBD007EBD007DBD007DBC007EBD007CBB007ABA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA -007ABA007ABB007EBD007EBF007AB9007BBC007DBC007EBC007EBD007DBC007DBD007DBD -007EBD007EBD007EBD007EBD007DBC007EBD007DBB0074AE0073AD0476AF0068A760AECE -B576D46D2BB67F41BE7C3DBC7D3EBD7D3FBD7938BBC3A9DF7B43B07135AB7237AB743AAD -6A2CA7BB9FD78F59BF7636B17736B2C2A9DA693C98602F9364349556218BAD93C7875CB7 -632C9FD3C4E35D3C7F46206F4E2A7541196B81699BA386C9A289BC2F19443C2652FFFFFF -9E9F9E252525000000040404000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000020202020202020202020202020302 -020202000001000001000001000001000000000000000000000000020203131610151911 -161A130D11096D6D6E918F948A898C8C8C8D827A89D7CAE2FFFFFFC3AED7AC8FC99773BB -66319C6D3AA06B389F6E3AA15C2790521D87541F89541F89531E8859268D643395623194 -6332946332946331946231946231946231946635965D2990653496A487C19370BA5B2495 -6F3FA2A88DC5A588C18C69AF6D3AA1979797000000040304000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000203000000002437 -0079B70075B10073AE0075B00074AF0075B00075B00075B00075B00075AF0075B00074AF -0074AF0075B00075B00074AE0071AA006EA6006EA5006FA5006FA7006EA7006FA8006FA8 -006EA8006FA8006FA8006EA7006EA7006EA7006EA7006FA9006FA90070A80072AB0072AB -0073AC0071AC0071AD0075B10077B40077B40076B30076B30076B30076B40077B40077B4 -0077B40077B40077B40077B40077B40077B40077B40076B40077B40076B40075B40076B4 -0076B40076B40075B40075B40076B40075B40075B40075B30076B30076B40078B6007AB6 -007AB6007AB60079B60079B60079B60077B30078B40077B40077B30077B3007AB6007DBB -007EBD007EBD007EBD007DBC007DBC007EBD007DBC007DBD007DBD007DBC007EBD007DBC -007ABA007BBA007BBA007ABA007BBA007ABA007ABA007DBC007EBD007DBC007EBD007EBD -007EBD007DBD007DBD007EBC007DBD007BBB007ABA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007ABA007BBB007BBB -007DBB007EBC007EBD007DBD007DBC007DBD007DBD007DBD007DBD007EBD007EBD007DBD -007DBC007EBD007DBB0074AE0073AD0074AE0072AD0579AF8FAAD69250C57738BA7D3FBD -7C3DBC7E40BD7431B9C2A7DF7941AE7135AB7338AC7439AC6B2DA78E5FBBBC9CD96921A9 -A477CCA285BF57228C64339564349557238C9A7AB9936DBD7947AFB2A3C347216F512D77 -512D773A116571568FCEBFE36D5C7E48325BD6D0DC717271000000030303020202000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000020202040404040404040404020202000000000000000000000000000000000000 -0000000000000404042D2F2C2929283235302F34295C5C5CADA4B6A29BAAA49CADA59FAB -A084BB9D75C49D79C29C77C2A27EC6855AB157208F5E28935D27925D27935A258E58258B -58258C58258C57238B5E2C906331955A258EA386C0C4B0D8612C999876BBBAA5CF7D53A8 -A88BC42F332B000000010101000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000002030000000024380079B60075B10073AE -0075B00074AF0075B00075B00075B00075B00075B00075B00074B00074AF0074AF0075B0 -0075B10073AE0071A9006EA6006EA4006FA8006FA8006EA7006FA8006EA7006EA7006FA8 -006FA80070AA0071AA0072AC0073AC0073AC0073AC0073AC0073AB0071AB0070AB0070AB -0072AD0074B10077B40077B40076B30076B30076B30077B40077B40077B40077B40077B4 -0077B40077B40077B40076B40077B40076B40075B40076B40076B40076B40075B40075B4 -0075B40076B40076B30076B40075B40075B40075B40076B30078B60079B6007AB6007AB6 -0079B60077B30077B30077B3007AB6007CBB007EBD007EBD007DBC007DBC007DBC007DBC -007EBD007DBD007DBD007DBD007DBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA -007ABA007BBA007BBA007ABA007CBC007EBD007DBC007DBC007EBD007DBD007DBD007EBC -007DBD007BBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007ABA007ABA007ABB007BBB007DBC007DBC0078B6007EBD007DBD007DBC007EBC -007EBD007DBD007DBD007DBD007DBD007EBD007EBD007DBD007DBC007EBD007DBA0074AD -0073AE0073AD0275AE0069A82F96BDBB9EDD7330B87F41BE7E3FBD7634B99B6ACDAF8ED0 -6D30A87339AC7338AC7237AB753BAD692AA6BFA4D98950BDBB9FD5683B975C2990602E92 -5F2D925E2C91613193B197CEAC8ECC6141813309603E17683F17685C397F8871A3FDFEFC -887D94C2C0C87E807D000000060607010101000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000030303040404040404040404040404000000 -0000000000000000000000000000000000000101010000003C3E3A61655E595D565C5F59 -5459507B777FB8A7CAAFA0BFB0A0C1B4A6C29571B88557B4895DB5875AB48C60B87443A4 -511A8857218D4B1184633294A98CC49574B9DDD5E6AA8DC7706A77000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000002030000000022350079B70075B10073AD0075B00075B00075AF -0075B00075B00075B00075B00075B00075B00074B00074AF0074AF0075B00075B00073AE -0071A8006EA7006EA7006FA8006EA70070A80071AA0072AA0073AC0073AC0073AC0073AB -0072AB0072AB0072AB0072AB0073AC0071AC0070AC0071AC0070AB0070AB0072AD0074B1 -0077B40077B40076B30076B30077B40077B40077B40077B40077B40077B40077B40076B4 -0077B40076B40075B40076B40076B40076B40076B40075B40075B40075B40076B40076B4 -0076B40076B40076B40075B40075B40076B40077B40078B40079B60077B3007AB6007CBB -007EBD007EBD007DBC007DBC007DBC007EBD007EBD007EBD007EBD007EBD007DBD007DBD -007DBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA007BBA007ABA007BBA007BBA -007ABA007CBC007EBC007DBD007DBD007EBD007DBD007EBC007DBD007BBB007ABA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007ABB007BBB007CBA007DBC -007DBD007EBE007CB90077B2007DBA007EBD007DBC007EBD007EBD007EBD007DBD007DBD -007EBD007EBD007EBD007EBD007DBC007EBE0077B40073AC0074AE0074AE0073AD0576AF -0069A890BDD99D53C87234B88042BE722FB7AC83D59F77C56727A5753BAD7237AB7338AC -753BAD6C2EA77941AFE3D6F09F80BE6434956E429C6C3E9B6C3F9B6C3F9B6B3E9AAB8EC8 -A691BD81669BAE9EC19F8CB4B0A0C2D4CCDCD1CCD66E68796E68795B5B5C000000040405 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000020202020202020202020202020202 -0201020201020201020202030000000000000000000000000000000305020B0F070A0D06 -0C0F090105005B5C598787877D7D7D8080807B7D7992899CB499CFAF97C8B29ACBAD94C7 -916AB7B99ED5FFFFFFD4D6D2000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0002030000000024370079B60079B60073AD0075B00074AF0074AF0075B00075B00075B0 -0075B00075B00075B00075AF0075B00074AF0074AF0075B00075B10072A9006FA90072AB -0072AB0073AB0073AC0073AC0072AB0072AB0072AB0072AC0073AC0073AC0073AC0072AC -0073AC0071AC0070AC0071AB0071AC0071AC0070AB0070AB0072AD0075B10077B40077B4 -0076B30076B30077B40077B40077B40077B40077B40076B40077B40076B40075B40076B4 -0076B40076B40076B40076B40076B40076B40076B40076B40076B40076B40075B40075B3 -0075B30075B30075B40078B70078B7007CBB007EBD007EBD007DBC007DBC007EBD007EBD -007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007CBC -007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007EBD -007EBC007DBD007DBD007EBC007EBD007BBB007ABA007BBA007BBA007BBA007BBA007BBA -007ABA007ABA007ABA007CBB007DBD007DBD007EBD007EBD007EBC007DBD007AB70077B2 -007BB8007EBD007DBC007EBC007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBC -007DBC007EBE0077B40073AC0074AE0074AE0074AE0074AE0070AC1382B4A2A5D98441BF -7A3CBB7F41BFC4AADE7439AC7338AC7439AC763DAE6F32A96829A57E48B3AB87CDDFD4EB -BDA8D2BAA5D0BCA7D1BCA7D1BBA6D1BDA8D2B49DCCE8E1F0BFB3CBBAAEC6705B88644C7E -4F346C9580AA9190993A364A6B6A6B000000020202000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -020202040404030303030303040404020202000000000000000000000000000000000000 -00000000000000000010110E2C3027282C232A2E2621271C78757C958C9FB2B1B3383837 -000000020202000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000020300000000263A -006AA00079B60073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00074B00075B00074AF0074AF0075B00074B00074AD0073AC0072AB0072AB0073AB -0072AC0072AB0073AC0073AC0073AC0073AC0073AC0072AC0073AC0071AC0070AC0071AC -0071AC0070AB0071AC0071AC0070AB0070AB0072AD0076B20077B40077B40076B30076B3 -0077B40076B30076B40077B40076B40075B40076B40076B40076B40076B40075B30076B4 -0076B40076B40075B30075B30075B30075B30076B40076B50078B8007ABA007ABB007CBD -007BBC007AB9007BB9007DBC007EBD007DBC007EBD007EBD007EBD007EBD007EBD007EBD -007EBD007EBD007EBD007EBD007EBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007EBD007EBC007DBC007EBD -007CBA007ABA007BBA007BBA007BBA007ABA007ABA007ABA007BBA007CBC007DBD007EBD -007EBC007EBC007DBC007DBC007EBD007DBC0077B30078B30077B4007DBD007EBC007EBD -007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007FBE0077B50073AC -0074AE0074AE0074AE0073AD0376AF0064A65DAECBB680D76B27B48F59C7BCA1D96E30A8 -7439AC6C2FA86524A37F49B3AF8DCFBBA2D69976C1DBCEE77A52A3521E8859278D58258C -58268C56238A5E2E90EFEAF56F578724024A39185B2A074E543773958CA0554E62707070 -000000030303000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000030303050505040404040404050505020202 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000102000000000000004E74007FBF0072AC -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0074AF0075B00074B00074AE0073AB0072AB0073AB0073AC0072AC0073AB -0073AC0073AC0073AC0072AC0073AC0071AC0070AC0071AC0071AC0071AC0071AB0071AC -0071AC0071AC0070AB0071AC0073AF0076B30077B40077B40076B30076B30076B40077B4 -0076B40075B40076B30076B40076B40076B40076B40075B30075B30075B30076B40075B3 -0078B70079B9007ABA007CBD007CBD007CBD007CBD007CBD007ABA0079B70079B8007AB8 -007DBC007EBD007DBC007DBC007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD -007EBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007ABA007CBC007DBD007EBD007EBD007BBA007ABA007BBA007ABA -007ABA007BBA007BBA007CBC007EBC007EBC007EBC007DBC007DBD007DBD007EBD007DBC -007EBD007BB90077B30078B40077B4007CBA007EBD007DBC007EBD007EBD007EBD007EBD -007EBD007EBD007EBD007DBC007EBD007DBB0075B00073AD0074AE0074AE0074AE0074AE -0073AD0375AF006CA97EB5D49753C6B28FD89163BC611FA27136AB996FC3C1A8DAB89DD4 -936DBD5D259B7E4FB2AF9DC0AA94C15F2E92633493613293643594532088B69DCED4D0D9 -2E0C524628663E1F5F50356ED0CCD6A5A3AB5C5B5D000000030303000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000010101010101010101010101 -020203030303040404010101000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000101000001000000004D74007FBF0072AC0075B00074AF0074AF -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0074AF -0075AF0075B00075AF0073AE0072AB0072AB0073AB0073AC0072AC0073AB0073AC0072AC -0073AC0071AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC0070AB0071AC0070AB -0070AB0071AC0074B00076B30077B40077B40076B30077B40076B40076B40076B40075B3 -0075B30075B30075B30076B40078B70078B7007BBC007BBC007CBD007CBD007CBD007BBC -007BBC007BBC007BBC007CBC007AB90079B8007AB80079B80079B8007CBC007EBD007EBD -007DBC007EBD007EBD007EBD007EBD007EBD007DBD007DBD007DBD007DBC007EBD007CBC -007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007ABA007BBB007DBB007EBD007BBA007ABA007ABA007BBB007BBC007DBC007EBC007EBD -007DBD007DBD007DBC007EBD007DBD007DBD007EBD007DBC007EBD007AB60077B30078B4 -0077B3007BB8007EBD007DBC007EBD007DBD007DBD007DBD007EBD007EBD007EBD007DBC -007EBD007CB80073AC0073AD0073AD0073AD0073AD0073AD0073AD0174AE006CAA278FB7 -AB95D7B78FD98E61BB9567C0C0A6D9A687C87C4EAE6A36A461299E61299FB8A2D0684A87 -B29DC857248B6232936030915A2A8D7448A2A196A89B8FA73E1E6044266426044ACCC3D5 -CBCACE4E4D51010100010102000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000001000101000000004E74007FBF0071AA0074AF0075B00074AF0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075AF0074B00074AF0075B00074B0 -0074AE0073AC0072AC0072AB0073AB0073AC0073AB0072AC0073AC0071AC0070AC0071AC -0071AC0071AC0071AC0071AC0071AC0071AC0070AB0071AC0071AC0070AB0070AB0071AC -0074B00076B30077B40077B30076B30075B30075B30076B40077B5007AB9007ABB007BBC -007CBD007CBD007CBD007CBD007BBC007BBC007BBC007CBD007BBC007CBC007BBD007CBC -007AB80079B80079B8007AB80079B80079B8007AB9007DBB007EBD007DBC007DBD007EBC -007EBD007DBD007DBD007DBD007DBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007DBB -007BBA007ABB007CBB007EBC007EBD007DBD007DBD007DBD007DBD007EBD007EBD007DBD -007DBD007DBD007DBC007EBD007CBB0078B40077B30078B40077B30078B5007DBC007EBD -007DBC007DBD007DBD007DBD007DBD007EBD007EBD007DBC007EBD007DBA0074AF0074B0 -0074AF0074AF0074AF0074AF0074AF0074AF0478B10065A791C5DEE5C5EBB69ED4A88ACA -7343A95E259C652EA16A35A46B36A46F3AA8B5A0CA48216F947EAC8B67B056238A643594 -54208BA187BBA19AA5715A8A38185A2F0D528C78A1FFFFFF727272000000040404000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000101000000 -004D730083C50075B00073AE0075B00074AF0075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075AF0074B00075AF0075B00075B00074AF0074AC -0072AC0072AB0073AC0072AC0073AB0071AC0070AC0071AC0071AC0071AC0071AC0070AB -0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AA006FAA0070AB0074B00077B4 -0076B50078B80079B9007ABB007CBD007CBD007CBD007CBD007BBC007BBC007BBC007BBC -007BBC007CBD007CBD007CBD007CBD007BBC007CBD007ABA007AB80079B80079B80079B8 -007AB8007AB80079B8007AB8007CBB007EBD007EBC007DBC007EBC007EBD007DBD007DBD -007DBC007DBD007EBC007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007ABA007BBA007BBA007BBA007ABA007ABA007BBB007BBA007DBA007EBC007EBD007EBD -007DBC007DBC007DBC007DBD007EBD007EBD007EBD007EBD007DBD007DBC007DBC007EBD -007BBA0077B30078B40077B30078B40077B3007BB8007EBD007DBC007DBD007DBD007DBD -007EBD007EBC007EBC007DBC007DBC0078B40077B30078B40078B40078B40078B40078B4 -0078B40078B40077B4017AB6006EACA4CCD99660BA5219976A35A46C38A56A35A46C37A5 -5E259C9D78C58E77A630025E8D75A49878BA5420895C2C8F835AAC7D6D8A84798C6C5388 -2E0D527A668FCECFCE757675000000050505000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000001000203003752006DA50079B6 -0073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00074B00074AF0074AF0075B00075AF0074AF0073AC0072AB0072AB -0073AC0071AC0070AC0071AC0071AC0071AC0071AC0071AC0070AB0070AB0070AB0070AB -0070AB0070AB0071AC0075B20075B10075B10078B70079B60079B7007CBD007CBE007CBD -007BBC007BBC007BBC007BBC007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD -007CBD007BBC007CBD0079BA0079B8007AB80079B8007AB8007AB8007AB8007AB80079B8 -0079B8007BBB007EBD007EBD007DBC007DBD007EBD007DBD007DBC007EBD007CBB007ABA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007ABA -007BBB007CBD007EBF007EBF007ABA007DBC007EBC007DBC007EBD007EBD007EBD007EBD -007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD0079B60077B30078B40078B4 -0078B40077B3007AB6007EBD007DBC007EBD007EBD007EBD007EBD007EBD007DBC007FBE -007AB70070A90075B10078B40077B30077B30077B30077B30077B30077B30078B40078B4 -026091005E9288AED28D52B358229B6A37A46A35A46B37A55E269C9974C3957FAB31035F -937CA99674B8532088623095BAADC710001F8B7F93684E833F205EFFFFFF5B5A5B000000 -050505000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000001020000000015210070AA0078B50073AD0075B00074AF -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00074AF0074AF0075B00075AF0074AC0072AC0072AB0072AB0070AB0070AB -0070AB0070AB0070AB0070AA0073AE0074AF0073AF0077B60078B60078B60078B7007AB9 -007AB9007AB9007AB90079B60077B20078B5007BBB007CBD007CBD007BBC007CBD007CBD -007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007BBC007CBD007ABA -007AB8007AB8007AB8007AB8007AB8007AB8007AB8007AB8007AB80079B8007AB8007DBA -007EBD007DBC007DBC007EBD007DBC007EBD007CBB007ABA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007ABA007ABA007ABA007CBB007EBD007EBF007FBF007FBE007EBF -007ABA007BBA007DBB007EBD007DBC007EBC007EBD007EBD007EBD007EBD007EBD007EBD -007EBD007DBC007EBD007DBC0079B50077B30078B40078B40078B40078B40078B4007CBB -007EBD007DBC007EBD007EBD007EBD007DBC007EBD007CBA0073AD0071AB0075B10078B4 -0077B30078B40078B40078B30078B40077B30079B5006DA5015C880163980470A587AACE -A673C2662FA16733A36A35A36A34A5B8A3CD542F784C2473522C77B4A1C857258B9979BC -6B5E753723459B8DAA321155DCD4E5727371000000040404000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000003040000000016220070AA0078B50073AD0075B00074AF0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0074AF0074B00075B00074B00074AC0072AC0072AE0072AD0073AE0077B50076B40076B4 -0079B8007AB9007AB9007AB8007AB8007AB8007AB80079B80079B80079B80079B80079B5 -0077B30077B30077B3007AB8007BBC007CBD007BBC007BBC007CBD007CBC007CBD007CBD -007CBD007CBD007CBD007CBD007CBC007BBD007CBC007AB8007AB8007AB8007AB8007AB8 -007AB8007AB8007AB8007AB8007AB8007AB80079B8007AB7007BBA007EBD007EBD007DBC -007DBC007EBD007CBB007ABA007BBA007ABA007BBA007BBA007BBA007ABA007ABA007BBB -007DBE007EBD007FBF007FBF007FBF007EBE007FBE007EBF007ABA007ABA007CBC007EBD -007EBC007DBD007EBC007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007AB9 -0077B30078B40078B30078B40078B30078B40077B3007BBA007EBD007DBC007EBD007DBC -007EBD007DBC007FBE0076B20070AA0071AC0073AD0078B40077B40077B30078B40078B3 -0077B30078B40078B5006191005D8A016699026BA500659FA6D9E3BBA2D564289E6532A1 -7846AEB29FC6461E6E542E7A492271B09EC4653399B3A3C12915373C2A4AA194B0CCC2D8 -81847E000000050505000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000203000000 -00141E0071AB0078B50072AB0075B00075B00074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075AF0074AF0075B0 -0075B00075B00079B6007AB9007AB8007AB9007AB9007AB9007AB80079B80079B80079B8 -0079B80079B80079B8007AB80079B8007AB80079B70077B30078B40078B40078B40077B3 -0078B4007BBB007CBD007CBD007BBC007BBC007CBD007BBD007BBD007CBD007CBD007CBD -007CBC007BBD007CBB007AB8007AB80079B80079B8007AB8007AB8007AB8007AB8007AB8 -0079B80079B8007AB8007AB80079B8007ABA007CBA007EBD007EBC007EBD007CBB007ABA -007BBA007BBA007ABA007ABA007ABA007CBB007DBD007EBF007FBF007FBF007EBE007EBE -007EBE007EBF007FBE007EBF007ABA007BBA007ABA007CBC007EBD007DBC007EBD007DBD -007EBD007EBD007EBD007EBD007DBC007DBC007EBD0079B60077B30078B40078B40078B4 -0078B40078B40077B30079B5007EBD007DBC007DBD007EBD007DBC007EBE0078B50071AB -0072AC0071AB0072AC0078B30077B40077B30077B30078B40077B30079B500679A005E8C -005E8B006598006EA6046BA3005E9C2D90B7AD9CD1591696A386C9795E9542196C41196B -370D6381649DBFA8D45A516701001362516FE5DDED797B76000000050505000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000001020000000015200070AA007DBC -0073AD0074AF0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0074B00074AF0074AF0077B2 -007AB8007AB80079B80079B80079B8007AB80079B8007AB8007AB80079B80079B80079B8 -0079B8007AB80079B70077B30078B40077B30078B40078B40077B30077B30079B7007BBB -007CBD007BBC007BBC007BBD007BBD007BBD007CBD007CBD007CBC007BBD007AB9007AB8 -0079B80079B80079B80079B8007AB8007AB80079B80079B80079B80079B80079B8007AB8 -007AB80079B80079B7007CBA007DBD007EBD007CBB007ABA007ABA007ABA007ABA007CBB -007EBD007FBF007FBF007EBE007EBE007EBE007FBE007FBF007FBF007EBF007FBE007BBA -007ABA007BBA007BBA007ABA007CBB007EBD007DBC007EBD007DBD007EBD007EBD007DBD -007DBC007DBD007EBC0078B40077B30078B40077B40078B40078B40078B40078B40077B3 -007BB9007EBD007DBC007DBC007EBD007DBC0073AD0071AB0072AC0072AC0071AB0074AF -0078B40077B30078B40077B30079B50072AB005D8A005F8D005D8B006598006CA5006CA3 -036EA500609D308EB5A898D2B896CD633C824F2374977BAD9879AC977FADF9F9FA81748B -6C5D76CEC8D3636165000000030303000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000102000000000C12003E5D007EBE0073AD0074AF0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075B00075B00074AF0075B10078B5007AB90079B8 -0079B8007AB80079B8007AB8007AB80079B80079B80079B80079B8007AB80079B70077B3 -0078B40078B40078B40077B30078B40077B30077B30078B4007ABA007CBD007CBD007BBC -007BBC007CBD007CBC007CBD007CBC007BBD0079B9007AB80079B80079B80079B80079B8 -007AB8007AB80079B80079B80079B80079B80079B8007AB8007AB8007AB8007AB80079B7 -007AB9007DBD007CBB007ABA007BBC007DBE007EBD007FBF007FBF007EBF007EBE007EBF -007FBE007FBE007FBE007FBF007FBF007EBF007FBE007BBA007ABA007BBA007BBA007BBA -007ABA007CBC007EBD007DBC007EBD007EBD007EBD007EBD007DBC007EBD007BB90077B3 -0078B40078B40077B40078B40078B40077B30078B40077B3007AB8007EBD007DBC007DBC -007EBE0074B00071AA0072AC0071AB0072AC0071AB0073AF0078B40077B30077B30078B5 -0076B1005F8E005E8C005F8D005D8B006598006DA5006BA3006BA3036EA5005F9D388EB2 -C0CBD59C9DBABBBCD09ABCC62F738AAEBCC75E4D6750455EAEA8B67B7C79000000050505 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000101000102000000003C5A007EBE0073AD0073AE0075B00074AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075AF0076B3007AB8007AB80079B80079B8007AB8 -007AB80079B80079B80079B80079B8007AB80079B70077B30078B40078B40078B40077B4 -0077B40078B40078B40078B40077B30079B6007BBC007CBD007CBD007BBC007CBD007CBC -007BBD007BBC0079B9007AB80079B80079B80079B8007AB8007AB8007AB8007AB8007AB8 -007AB8007AB8007AB80079B80079B70079B7007AB7007AB8007AB7007BBA007DBD007DBD -007FBF007FBF007FBF007EBE007EBE007EBE007FBF007FBE007FBE007FBE007FBE007FBF -007FBF007EBF007FBE007BBA007ABA007BBA007BBA007BBA007BBA007ABA007CBC007EBC -007DBD007EBD007EBD007DBC007DBD007DBC0078B50077B30078B40077B40078B40078B4 -0078B40078B40078B40077B30078B4007EBC007DBC007EBE007AB70071AB0072AC0072AC -0072AC0072AC0071AB0072AD0077B30077B40077B30079B5006A9F005D8A005F8D005F8D -005D8B006598006DA5006BA3006CA4006AA20174AD01436F003D60004E6F024A6C002F56 -345D82807E9300000C5248615D5B5E000000040304000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000101000203 -000000003B58007FBF0076B20073AD0075B00074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF -0075B00075B00074AF0075B1007AB8007AB90079B80079B8007AB8007AB8007AB8007AB8 -0079B8007AB80079B40077B30078B40078B40078B40078B40078B40078B40077B30078B4 -0078B40077B30078B40079B8007BBC007CBD007BBC007BBC007CBD007CBB0079B7007AB8 -007AB8007AB8007AB8007AB8007AB8007AB80079B70079B70079B70079B80079B7007AB9 -007BBC007BBB007DBB007FBE007EBE007EBE007BBC007DBC007FBF007EBE007EBE007FBE -007FBF007FBF007FBF007FBF007FBE007FBE007FBF007FBF007FBF007EBF007FBE007BBA -007ABA007BBA007BBA007BBA007BBA007BBA007ABA007DBC007EBC007DBC007EBD007DBC -007EBD007DBB0077B30078B40077B30078B40078B40078B40078B40078B40078B40077B3 -0078B4007CBA007EBE007AB80071AB0071AB0072AC0072AB0072AC0071AB0072AC0071AB -0077B20077B30079B60070A7005C89005F8D005F8D005F8D005D8B006598006DA5006BA3 -006BA2006EA8005684013D5B01476B0043690047670C3A70B4A0CF332D3B594D69707070 -000000030203000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000020400141E006295 -007CBA0072AC0075B00074AF0075AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B00074AF -0075B00077B4007AB9007AB80079B8007AB8007AB8007AB80079B8007AB80079B50077B3 -0078B40078B40078B40078B40078B40078B40078B40078B40078B30078B40077B30077B3 -0078B5007BBB007CBD007CBD007BBC007BBA0079B8007AB80079B80079B80079B80079B8 -0079B70079B8007ABA007ABA007CBA007EBD007EBD007EBD007FBF007FBF007FBF007EBF -007EBF007FC0007BBC007ABA007CBC007FBF007EBE007EBF007FBF007FBF007FBF007FBF -007FBF007FBF007FBF007FBF007EBF007FBF007EBE007BBA007ABA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007DBC007EBD007DBC007DBC007EBD0079B70077B30078B4 -0078B40078B40078B40078B40078B40078B40078B40078B40077B30079B7007FBE0074AE -0071AB0072AC0072AC0072AC0072AC0072AC0072AC0071AB0073AF0078B40079B6006495 -005E8B005F8D005E8D005F8D005D8B006598006DA5006AA1006FA900619200344F004163 -00476B03476B003E636762AC8D80924D495C717071000000030203000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000203000000000A0F006498007CBA0072AC0074AF -0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00074AF0075B00074AF0074AF0076B20079B7 -007AB90079B80079B8007AB80079B8007AB80078B40077B30078B40078B40078B40078B4 -0078B40078B40078B40078B40078B30078B40078B40078B40078B30077B30079B8007CBD -007BBD0079B80079B70079B8007AB9007AB9007AB9007DBB007DBC007DBC007FBF007FBF -007FBF007FBF007FBF007FBF007EBE007EBE007EBE007EBE007FBF007DBC007BBB007BBA -007ABA007CBC007FBF007EBE007EBE007FBF007FBF007FBF007FBF007FBF007FBF007FBF -007EBF007FBF007DBE007ABA007BBA007ABA007BBA007BBA007BBA007ABA007BBA007ABA -007BBA007DBC007EBD007DBC007EBD0078B50077B30078B40078B40078B40078B40078B3 -0078B30078B30077B30077B30077B30079B80076B20071AB0072AC0071AB0071AB0071AB -0071AB0071AB0072AC0071AB0072AC0079B5006EA5005E8C005F8D005F8D005F8D005F8D -005D8B006598006CA5006CA4006CA500466A00375300416201476C0043652240619885A4 -5A50686D6D6D000000030304000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000010200000000080D006395007CBB0074AF0074AE0075B00074AF0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00074AF0075B00075B00074AF0075B00078B40079B8007AB80079B8 -007AB80078B60077B30078B40078B30078B30078B40078B40078B40078B40078B40078B4 -0078B40077B30077B30077B30077B30078B40077B30078B4007CBB007DBB007CBA007CBB -007EBF007EBF007EBF007FBF007FBF007FBF007EBE007EBE007EBE007EBE007EBE007EBE -007FBF007FBF007FBE007EBE007FBF007DBB007ABA007BBA007BBA007ABA007CBC007FBF -007EBF007EBE007FBF007FBE007FBE007FBE007FBE007FBF007EBF007FBF007DBE007ABA -007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007ABA007BBA007DBB007EBE -007DBA0077B30078B40078B40077B30077B30077B30077B40077B40077B40079B60079B6 -007AB70077B50070AC0075B00074AE0073AD0073AD0073AD0073AE0072AC0071AB0071AB -0072AD0075AF005E8C005E8C005F8D005F8D005F8D005F8D005D8B006598006CA5006CA5 -00466A003652003957003F60024E7100214184689DA49EAB5C5B5D000000020202000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000101 -000000000305002C41007BB90074AF0073AD0075B00074AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0075B00074AF0074AE0076B20079B7007AB8007AB80078B70077B30078B4 -0078B40078B40077B30077B30077B30077B30077B30077B30077B30079B50079B60079B6 -007AB7007DBB007DBB007DBB007BB9007CBA007FBF007FBF007FBE007FBE007FBE007EBE -007EBE007EBE007FBF007FBE007FBE007FBE007FBE007FBF007FBF007FBE007EBE007EBE -007FBF007CBB007ABA007BBA007BBA007BBA007ABA007CBD007FBE007EBF007EBE007FBE -007FBE007FBE007FBE007FBF007EBE007FBF007DBE007ABA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007ABA007BBA007ABA007BBA007DBC007BB80077B30077B30077B3 -0078B50079B50079B5007AB9007ABA007ABA007BBB007ABA007CBD0074AF006CA40076B1 -0074B00075B00075B00075B00075B00074AF0074AF0074AF0073AD006396005F8E005E8D -005E8C005E8D005F8D005F8D005D8B0064970071AD005C8C003552003B5900385602486C -003957312058E6D3F5616460000000020202000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000001000203000000002B3F -007DBC007AB80072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0075B00074AF0074AF0078B6007AB90078B70077B20077B30077B30077B30078B40078B5 -0078B50079B5007CBA007CBA007CBA007DBC007EBD007EBD007EBD007EBD007EBD007EBD -007CBA007AB7007CB9007FBF007FBF007EBE007EBE007FBE007FBF007FBF007FBE007FBE -007FBE007FBE007FBE007FBF007FBF007FBE007EBE007FBE007EBF007ABB007ABA007BBA -007BBA007BBA007BBB007AB9007CBD007FBE007EBF007EBE007FBE007FBE007FBE007FBE -007EBF007FBE007DBE007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007ABA007BBA007ABA007BBA0079B50079B80079B90079B9007ABB007BBB007BBB007BBA -007BBA007BBA007ABA007BBA007ABA006EA7006DA50075AF0074AF0074AF0074AF0074AF -0074AF0075B00074AF0078B400699D005A87006294006091005F8F005F8D005E8D005F8D -005D8A00669A005F91003956003A58003856034263003155464E59B8A7C5727470000000 -050505000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000203000000001F2E005886007DBC0072AB -0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0075B0 -0077B40078B6007AB7007BB9007BB8007BB8007DBB007EBD007EBD007EBD007EBD007EBD -007EBD007EBD007DBC007DBC007DBC007DBC007DBD007DBC007BB8007BB8007AB8007CB9 -007FBF007FBF007EBE007FBF007FBF007FBF007FBF007FBE007FBE007FBE007FBF007FBF -007FBF007FBF007EBE007FBE007EBF007BBB007ABA007BBA007BBA007BBA007BBA007BBA -007ABA007CBC007FBF007EBE007EBE007FBE007FBE007EBE007FBF007EBD007BB9007ABA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBB -0078B7007BBA007BBA007BBA007BBA007ABA007ABA007ABA007ABA007ABA007ABA007BBA -0079B9006CA5006BA20072AC0075B10074AF0075B00075B00075B00074AF0076B2006FA6 -005580005D8C00619200619100619100619100609100608F005D8B00689C003F5F003754 -003A58003A58003A56081E2AC0C1C1797B77000000050505000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000102000000000102005480007EBE0072AB0075B00074AF0075AF -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00074AF0075B00075B00074AE0076B2007DBD007FBE -007EBD007EBD007EBD007DBC007DBC007DBC007DBC007DBC007DBC007DBC007EBD007EBC -007EBD007DBC007EBD007DBC007BB8007AB8007BB8007AB8007BB9007DBD007FBF007EBE -007EBE007FBF007FBF007FBF007FBF007FBF007FBF007FBF007FBF007FBF007EBE007FBF -007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007FBF -007EBE007EBF007FBF007EBE007FBF007EBD007BBA007ABA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007ABA007BBB007AB80073AE0079B6007BBC007ABA -007ABA007BBA007BBA007BBA007BBA007BBA007ABA007CBC0073AE006BA2006BA30070A8 -0075B00074AF0074AF0074AF0075B00074AF0076B200609100527C005E8D006192006091 -00609100619100609100619200639500456400334D00355000334D023B5700153152504F -2E2E2E000000020202000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000203000001000203005581007EBE0072AD0075B00074B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00074AF0075B00075B00074AE0076B4007CBA007EBD007DBC007DBC007EBD -007EBC007EBC007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007DBC -007BB8007BB8007AB8007BB8007AB8007AB8007DBD007FBF007EBF007EBE007FBF007FBF -007FBF007FBF007FBF007FBF007FBF007FBF007EBE007FBF007CBA007ABA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007FBF007EBE007EBF007EBE -007FBF007EBD007BBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007ABA007BBC0077B20073AC0075B1007ABA007BBA007ABA007BBA007BBA007BBA -007BBA007ABA007BBB0079B9006CA5006BA3006BA3006CA40075B00075AF0075B00075B0 -0074AF0076B20070A800558000557F005D8C006192006091006191006091006091006497 -003F5C002E4400344E00324C003851002142000009000000000000020202000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000001000001000102 -00557F007DB30072AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0074AF0075B00074AF0074AE007AB6007EBE007DBC007DBC007EBD007EBD007EBD007EBD -007EBD007EBD007EBD007EBD007EBD007DBC007EBD007BB9007AB8007BB8007BB8007BB8 -007BB8007AB8007AB8007DBD007FBE007FBF007EBE007FBF007FBE007FBF007FBF007FBF -007FBF007EBF007EBE007FBF007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007ABA007CBC007FBF007EBE007EBE007FBF007EBD007BBA007ABA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBC0077B2 -0073AD0073AC0078B3007BBB007ABA007BBA007BBA007BBA007BBA007ABA007BBB0077B5 -006AA2006CA4006CA4006BA30072AB0075B00074AF0074AF0075B00073AE005984005580 -005580005D8D006192006091006091006091006497003D5900263700355000324C003852 -00214000000B000000020202010101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000100010000000B0056B4007AB20073AE -0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B0 -0074AE007AB6007EBE007DBC007DBC007EBD007DBC007DBD007DBD007DBD007EBD007EBD -007EBD007DBC007EBD007BB9007AB8007BB8007BB8007BB8007AB8007BB8007AB8007AB8 -007BB9007EBE007FBF007EBE007FBF007FBE007FBF007FBF007FBF007EBF007FBE007EBF -007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007ABA007CBC007FBE007EBF007FBF007DBD007ABA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007ABA007BBC0077B20073AD0074AD0074AF007ABB -007BBA007ABA007BBA007BBA007BBA007ABA007CBB0070A9006BA3006CA4006CA4006BA2 -0070A90075B10074AF0074AF0076B200669A00537D005680005885006192006091006191 -006090006395003E5B002534002E4300324B003854002132000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000202000000002042007DB90074B00074AE0075B00074AF0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00074AF0075B00075B00074AE007AB6007EBE -007EBD007DBC007EBD007DBC007DBD007DBD007DBD007EBD007EBD007DBC007EBD007BB9 -007AB8007BB8007BB8007BB8007BB8007AB8007BB8007BB8007AB8007BB9007EBE007FBF -007EBE007FBF007FBE007FBF007FBF007EBE007FBE007EBF007ABA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007AB9007CBD007FBE -007FBF007CBD007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007ABA007BBC0078B30073AD0074AE0073AD0077B2007BBB007ABA007ABA007ABA -007ABA007BBC0076B4006BA2006CA4006CA4006CA4006BA3006CA40074AF0074AF0076B2 -006CA400537D005681005580005885006192006091005F8F006497005885002636002C40 -003046003855002132000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000101000000002B40007BB90074AF0074AE0075B00074AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00074AF0075B00075B00074AF0077B3007CBC007EBD007DBC007EBD -007DBC007DBD007DBD007EBD007DBC007EBD007DBB007AB8007BB8007BB8007BB8007BB8 -007BB8007BB8007BB8007AB8007BB8007AB8007BB8007EBE007FBF007EBE007FBF007FBF -007FBF007EBE007FBE007CBC007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007BBA007BBB007AB9007CBD007FBF007CBD007ABA007BBA -007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007ABA0075AF -0073AD0074AE0074AE0073AD0078B8007BBB007ABA007BBA007ABA007CBB0074B1006AA2 -006CA4006BA3006BA4006CA4006BA30073AD0075B00076B2005E8C00547F005681005580 -005885006193005F8F006496005A87002B3F00293B002C3F003650002134000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000020400000000293D -007CBA0074B00074AF0075B00074B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0074AF0075B00075B00074AE0075B1007CBC007EBD007DBC007EBD007DBC007EBD007EBD -007DBC007EBD007DBB007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 -007AB8007BB8007AB8007BB8007DBC007FBF007EBE007EBF007FBF007EBE007FBE007BBA -007ABA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007BBA007BBA007BBA -007BBA007BBA007ABA007AB9007DBD007DBF007AB9007BBA007BBA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007ABA007BBA0079BA0073AE0074AD0074AD0074AE0073AE -0074AE0079B9007BBB007ABA007BBA007ABA006DA5006BA3006CA4006CA4006CA4006CA4 -006BA3006EA60076B2006BA200547F005681005681005580005885006090006396005A87 -002B3F002535002C40003046001F2D000000000001000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000203000000002A40007BB50076AD0074B0 -0075AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00074B00075AF0075B0 -0074AF0075B1007CBC007EBD007DBC007EBD007EBD007EBC007EBD007DBC007BB8007AB8 -007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB8007AB8 -007AB8007DBC007FBF007EBE007EBE007FBF007EBE007BBA007ABA007BBA007BBA007BBA -007BBA007BBA007BBA007BBA007ABA007ABA007ABA007ABA007ABA007ABA007BBB007CBB -007CBC007BBA007BBA007BBB007ABA007BBA007ABA007BBA007BBA007BBA007BBA007BBA -007ABA007BBA007ABA0073AE0074AD0074AE0073AD0074AE0073AD0077B4007BBB007ABA -007CBC0073B1006BA2006CA4006BA3006BA3006BA3006CA3006BA20070A90073AC005580 -005580005681005681005580005784006598005A87002B3F002534002A3D003147001C29 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000204000000002C520075C20073AA0074B00074AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0075B1007CBC -007EBE007DBC007DBC007EBD007EBC007DBD007BB9007AB8007BB8007BB8007BB8007BB8 -007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB8007BB8007AB7007DBC007FBF -007FBF007FBE007DBE007ABA007BBA007BBA007BBA007ABA007ABA007ABA007ABA007ABA -007BBB007BBB007BBB007CBB007EBE007DBD007EBF007FC0007DBB0077B20079B6007AB8 -007BBB007ABA007ABA007ABA007BBA007BBA007BBA007BBA007ABA007BBA0079BA0073AE -0074AD0074AE0074AE0073AD0074AE0073AC0078B7007BBB007BBB0071AD006AA2006CA4 -006CA4006CA4006CA4006CA5006BA2006EA800619200547D00568100568100568100557F -005986005986002B3F00253400293A003045001D29000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000001 -00030000001100529B007FB90071AC0075B00074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075B00074AF0075B2007AB6007EBD007DBD007DBC -007EBD007DBC007BB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 -007BB8007BB8007AB8007BB8007BB8007BB8007AB8007CBB007EBD007FBF007DBE007ABA -007ABA007ABA007ABA007ABA007BBA007ABA007CBD007DBC007DBE007FBF007FBF007FBF -007FBF007FBF007EBE007FBF007AB70077B30079B30078B4007AB8007BBA007BBA007ABA -007ABA007BBA007BBA007BBA007ABA007BBA007ABB0073AE0074AD0074AE0074AE0074AE -0074AE0073AD0074B0007ABA0078B6006CA3006CA4006CA4006BA3006BA30069A000699F -00699F005F8F00517900557F00557F00558000558000537D005E8D003750002331002839 -003044001D2A000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000090E006498 -007BBA0072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0075B00074AF0073AE0079B4007EBD007DBC007EBD007CBA007AB7007BB8 -007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8 -007AB8007AB8007AB8007AB7007BB8007EBC007BBA007ABA007BBC007CBC007CBC007EBD -007EBF007EBE007FBF007FBF007FBF007EBE007EBE007EBE007EBE007EBE007FBF007EBE -0078B60078B30079B40078B30078B30079B40079B8007BBB007ABA007ABA007BBA007BBA -007ABA007BBB0078B60073AE0074AD0074AE0074AD0073AD0073AD0074AE0073AC0077B5 -0071AE006AA0006AA1006AA000679C00679C00669B00669A00689E004367004C73005681 -00547E00547E00547E00598500405D002737002738002D41001D29000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000002000000000A10006498007CBB0073AD0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0075B00074AE0079B4007EBD007EBD007DBB007AB8007BB8007AB8007AB8007AB8007AB8 -007AB8007AB8007AB7007AB7007AB7007AB7007AB7007BB8007BBA007BBA007BBA007BBA -007BB9007EBF007EBE007EBD007EBF007FBF007FBF007FBF007FBF007FBF007EBE007EBE -007EBE007FBF007FBE007FBE007EBE007EBE007FBF007AB80077B20078B40078B30079B4 -0078B40079B40078B30079B5007BBB007BBB007ABA007ABA007ABA007BBB0076AF0073AD -0074AE0073AD0073AD0073AD0074AE0074AE0073AC0071AA00689F00669C00669B00669B -00669B00669B00669B006AA0005987003D5E00517900558000547E00547E005681003B56 -002332002839002B3D001C27000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000102000000000A100062940077B20073AE0075B00074AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075AF0075B00074AE0079B4 -007DBD007BB9007AB6007AB7007BB8007BB8007BB8007BB8007AB8007CBB007EC0007EBF -007EBF007EBF007EBF007FC10080C30080C30080C30080C30080C4007DBE007AB7007EBE -007FBF007EBE007EBE007EBE007EBE007EBE007EBE007FBE007FBF007FBF007FBF007FBE -007FBE007EBE007FBF0078B50077B30077B40077B40079B40078B40079B40079B40078B3 -0079B50079B7007BBB007BBA007ABA007BBB0076B00073AD0074AE0074AE0074AE0074AE -0073AC006FA80070A700689E00609200689D00669B00679C00679C00669B00669B00689D -00456A00456800578200547E00547E005783004F7700202F00293A002C40001A26000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000102 -000000001723007EBE0074AE0074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075AF0075B00074AF0074AF007BBA007EBE007DBE -007FC2007FC2007FC2007FC2007FC2007FC20080C30080C30080C30080C30080C30080C3 -007FC2007FC2007FC2007FC20080C4007BBA0078B4007CBA007FBF007EBE007EBF007FBF -007FBF007FBE007FBE007FBF007FBF007FBF007FBF007FBF007EBE007FBF007DBB0078B4 -0077B30078B40078B40079B40078B40079B40078B30079B40078B30078B30079B5007BB9 -007BBB007BBB0076B00073AD0074AE0073AD0071AA0070A8006FA5006EA5006FA6006396 -005B8900679C00669B00679C00679C00669B0069A0005988003B5C00466B00568000547E -00557F00527C00273B002536002D41001A25000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000102000000003C59007AB8 -0073AE0074AF0075AF0075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074B00075AF0075B00074AE0079B60081C50080C30080C30080C30080C30080C3 -0080C30080C3007FC2007FC2007FC2007FC2007FC2007FC20080C30080C3007FC2007FC2 -0080C3007BB90079B50079B5007CBA007FBF007EBE007FBF007FBF007FBF007FBF007FBF -007FBF007FBF007FBF007FBF007EBE007FC0007AB80077B20078B40077B30078B40079B4 -0078B40079B40079B40078B30079B40079B40078B30079B5007AB8007BBC0077B10071AB -0071AA006FA6006EA5006EA5006EA6006EA60070A6005C8A005B8900659900679C00669B -00669B00679C00679C00476C003C5D00466B00568100537C005B88002B41001C28002E42 -001A25000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000040600689D0077B40074AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF -0075B00074AE007AB70080C3007FC3007FC2007FC2007FC2007FC20080C30080C30080C3 -0080C30080C30080C30080C30080C30080C3007FC20080C3007FC2007AB60079B6007AB6 -0079B5007CBB007FBF007EBE007FBF007FBE007FBF007FBF007FBF007FBF007FBF007EBE -007FBF007FBF0078B50077B30078B40078B40078B40077B40079B40078B40079B40079B4 -0079B40079B30079B40078B30079B40075B00070A6006FA6006EA5006EA5006FA6006FA6 -006EA50070A700689D005B8800598700619400689D00669B00669B00699F005988003D5E -003F6100466A00557F005885004363001B27002C3F001A26000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000203000000003048007DBC0072AC0074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00073AE007AB7 -0080C4007FC2007FC20080C30080C30080C30080C30080C3007FC2007FC20080C30080C3 -0080C30080C3007FC20080C3007FC2007AB60079B6007AB60079B5007AB7007FBE007FBF -007EBE007FBF007FBE007FBF007FBF007FBF007FBF007EBE007FBF007BBA0077B30078B4 -0077B30077B40078B40077B40078B40078B40079B40079B40079B40078B30078B30079B4 -0077B1006EA200699D006FA6006FA6006FA6006EA5006FA6006EA50070A800659A005885 -005B89005E8D00669B00679C00669B00689D00466B003E60003F60004569005985004567 -001722002535001B27000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000101 -00679B0078B40074AE0074AF0075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074B00075B00075B00073AE0079B70080C4007FC2007FC2 -0080C30080C30080C3007FC2007FC2007FC2007FC20080C30080C3007FC2007FC20080C3 -007BB90079B5007AB60079B6007AB60079B5007AB7007FBE007FBF007EBE007FBE007FBE -007FBF007FBF007FBF007EBE007FBF0079B60077B30078B40077B40077B40078B40077B4 -0079B40079B40078B30079B40078B30079B30079B40072AC0070A7006EA500689A006CA0 -006FA6006EA5006FA5006EA5006EA6006FA6006294005987005B89005A8800669A00669B -00699F005988003D5E004063003E5F00466A005A8600273C001F2D001D2A000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000102000000003048007EBE0072AC0075B0 -0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075AF0075B00074AE0079B70081C4007FC2007FC20080C30080C2007FC2 -007FC2007FC2007FC20080C20080C30080C3007FC20080C3007BB80079B5007AB60079B6 -0079B6007AB60079B5007BB8007FBF007EBE007EBE007FBE007FBE007FBF007EBE007FBF -007EBE0078B40077B40078B40077B40077B40078B40077B40078B40078B40079B40078B3 -0079B40079B40072AC006FA60070A8006EA500689B006A9D006FA6006FA6006EA5006EA5 -006FA6006EA3005A87005A89005A89005B8800649700679C00689D00466B003E5F004062 -003E6000496F003149001A26001924000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000005080065980079B60073AE0074AF0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AE0079B70080C4007FC2007FC20080C30080C2007FC2007FC2007FC20080C3 -0080C3007FC20080C3007FC1007AB60079B6007AB60079B60079B6007AB6007AB60079B5 -007DBC007FBF007EBE007FBF007FBF007EBF007EBE007FBF007AB70077B30078B40077B3 -0077B40077B40077B40078B30077B40078B30078B30079B50076AF0072AB006FA70070A8 -0070A8006EA400689B00689B006BA0006FA6006EA5006EA50070A700669A005A87005B89 -005B89005A87005E8F00699F005783003D5E004164004062004469003D5C000D1300090D -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000102 -00000000344F007BBA0073AD0075B00074AF0075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B00074AE007AB7 -0080C3007FC20080C30080C30080C20080C20080C30080C30080C3007FC20080C3007FC0 -0079B5007AB60079B6007AB6007AB6007AB6007AB6007AB60079B5007DBC007FBF007EBE -007FBF007FBF007EBE007EBF0078B40077B30078B40078B40077B40078B40077B40078B4 -0077B30079B40079B50075AE006FA6006FA70070A8006FA70070A8006A9D00689B00699C -00689B006DA4006FA6006EA50070A8006194005986005B89005B89005987005E8F006194 -003E5F004063003957003B59002F46001018000103000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000609006A9F0078B5 -0073AE0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075B00075B00074AF007EC00080C4007FC20080C3 -007FC20080C30080C30080C30080C3007FC20080C3007DBE0079B5007AB6007AB6007AB6 -007AB6007AB6007AB6007AB6007AB60079B5007DBD007FBF007EBE007EBE007FBF007CBC -0077B30078B40078B40078B40078B40077B40078B40078B30078B40077B20072AB006FA7 -0070A80070A8006FA7006FA70070A800699D00689B00699C00689B006A9E006EA5006FA7 -006BA0005B89005A88005A88005B89005B8A005B8900466A00355000304900304800283B -000F16000102000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000100000000131D0074AE0075B00074AF0074AF0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075AF0075B00074AF0076B2007EC10080C3007FC20080C3007FC20080C30080C3 -0080C30080C3007FC20079B60079B6007AB6007AB6007AB6007AB6007AB6007AB6007AB6 -007AB60079B5007BB8007FBF007EBF007FBF007EBE0079B60077B30078B40078B30078B4 -0078B40078B40077B40077B30078B50072AB006CA30070A8006FA70070A70070A7006FA7 -0070A800699D00689B00699C00699C00689A006BA00070A800689C005986005D8C005B89 -005985005582004365002A3D002E44002E4400293D000F16000102000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000101000000004970007DBC0073AD0075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0074AE0075B2007EC10080C3007FC20080C3007FC20080C30080C20080C3007FC2007AB6 -0079B6007AB60079B60079B60079B6007AB6007AB6007AB6007AB6007AB60079B5007BB8 -007FBF007FBF007EBD0077B30078B40077B30077B40077B40077B40078B40077B40076B3 -0077B50072AC006CA30070A8006FA7006FA70070A7006FA70070A800699D00689B00699C -00699C00699C00689A006DA400609200598600527C004E76004668004669003147002D43 -002E4500324B000D13000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000101000000001722 -0074AE0075B10074AF0074AF0075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AE0075B2007EC1 -0080C3007FC20080C3007FC2007FC20080C3007EBE0079B5007AB6007AB60079B60079B6 -0079B60079B6007AB6007AB60079B60079B6007AB60079B5007CBA0080C0007BB90077B3 -0078B40078B40077B40076B40076B40076B40076B40076B30077B50072AC006CA2006DA5 -0070A8006FA7006FA8006FA70070A800699E00689B00699C00689B00699C006A9D006A9F -00558200476A004567004466004B7100344F00213200304700324A001723000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000102000000004C73007BBA0073AD0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075B00074AF0075B1007FC20080C3007FC20080C3 -007FC20080C4007EBF0079B4007AB60079B60079B60079B60079B60079B6007AB60079B6 -007AB6007AB6007AB60079B50079B6007DBD007AB80076B30077B40076B40076B40077B4 -0077B40077B40077B40076B30077B50072AC006CA2006DA3006DA50070A80070A70070A8 -006DA300689B00689B00689B006A9D00679A00608E004D7500426300476A00476A00486C -004060002130002C4200334C001723000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000100000000111A0075B00074AF0074AF0074AF0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0075B00074AF0075B1007EC10080C3007FC20080C3007FC2007BB90079B5 -007AB6007AB60079B60079B6007AB6007AB6007AB6007AB60079B50079B50079B6007AB7 -007BB90079B70076B40077B30076B40077B30077B40076B40077B40077B40077B40076B3 -0077B50072AC006CA2006DA4006CA3006DA5006FA80070A8006DA200679A006A9D006A9D -00649600527C00517A00406200436500486B00456800496E002739001D2A00344D001622 -000000000101000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000102 -00000000486C007DBC0072AC0074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0074AE0077B30080C4007FC20080C3007FC00079B5007AB6007AB6007AB6007AB6007AB6 -007AB60079B60079B60079B5007AB7007AB7007BBB007BBD007CBF0072AB0073AD0076B0 -0077B30077B40076B30077B30077B40077B40076B30076B30077B40070A9006CA3006DA4 -006DA4006CA3006DA50070A9006DA200699D00649600598600507900517C004C74003A58 -004467004669004A6F003E5B001C27002F44001825000000000001000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000100000000111B0075B00075B0 -0074AF0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF007BBA0080C4 -0080C3007EC00079B5007AB60079B60079B60079B50079B50079B6007AB6007BBB007BBC -007CBD007CBD007CBD007CBD007BBB006EA50072AA0075B00076AF0076B30077B40076B4 -0077B30077B40076B30077B40075B2006CA3006DA4006CA3006DA4006CA3006CA2006EA7 -006DA200608F00507A004F7800517A00527C00406300395700446700476A004466002535 -00202E001825000000000001000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000010100000000486C007DBD0072AC0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00074AF0075B00074B00074AE007BBA0081C5007CBB0079B40079B5 -007AB60079B6007ABA007BBB007BBB007CBD007CBD007CBD007BBC007BBC007BBC007DBF -0077B4006CA00073AC0075B00074AF0074B00075B30077B30076B40076B30076B30077B4 -0076B2006DA4006CA3006DA3006CA3006DA4006EA5006BA2005A88004E7700517B00517B -00517C004F76003A58003A59004365004C72003149001A27001E2E000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0001010000000016220073AE0075B10074AF0074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0074AF0075B00075B00073AE007CBC007DBC0079B6007BBA007BBC007BBC007CBD007CBD -007CBD007BBC007BBC007BBC007BBC007BBC007CBC007CBD0073AD006CA10072AB0075B0 -0074AF0075AF0074B00075AF0077B30077B40076B30077B40076B2006DA4006CA3006CA3 -006EA6006AA1006193005986004C7100517A00517B00507A00527D00486E003A58003958 -004669003C5800202C000F1D000008000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000102000000004C71 -007CBA0073AD0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B0 -0074AE007AB8007CBD007CBD007BBD007CBD007BBC007BBC007BBC007CBD007BBC007BBD -007BBD007BBC007CBD007BBC006DA4006DA20073AC0075B00074AF0074B00075AF0074AF -0075AF0076B30076B40077B40076B2006CA3006DA4006DA400689C005C8A005884005681 -00496E004F7900517B00517B00517A003C5D003A58003A5900496C002333000506000001 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000010000000015200074AF0074AF0074AF0074AF -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00074AF0075B00074AF0076B4007BBD007BBC -007BBC007BBC007BBD007CBD007CBD007BBD007BBD007BBD007BBD007BBC007CBE0076B3 -006DA3006DA3006FA70074B00075AF0074AF0074B00075B00074AF0074AF0075B30077B4 -0076B2006EA6006CA3006191005783005985005C8A004F7800486B004D7300517B00527C -00486D003856003B5B003D5C00243A000306000000000001000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000203000000004D74007EBD0072AC0075AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00074AF0075B00074AE0078B6007DBE007BBC007CBD007CBD007CBD -007CBD007CBD007BBD007BBD007CBD007BBC007DBF0074AD006CA1006EA4006EA40074AF -0075B00074AF0075B00075AF0075B00075AF0074AF0076B30075B0006395005B89005885 -005A87005A87005885004C7200496D004C7100517B00517B003C5D003B5B003D59001C34 -00000C000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000102000000 -003550007CBB0073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074B00075AF007AB8007CBD007BBC007CBD007CBD007CBD007CBD007CBD007CBD -007BBC007CBD0079BA006EA4006EA4006DA3006EA50074AF0075B00074AF0075B00075AF -0075B00074AF0075B00075B1005F8D005782005A87005A87005986005A8800578200486C -004A6F00496D004F77004E77003F61002F44001122000011000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000050700689C0077B40074AF -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0075B2 -007CBD007BBC007BBD007CBC007CBD007CBD007CBD007BBC007BBC007CBD0077B6006DA2 -006EA4006DA3006EA50074B00075B00074AF0075B00075AF0074AF0075B00075B100608F -00547C005884005A87005986005986005A88004F7700496D004A6E00486C00517B004366 -002B41000E12000005000001000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000010200000000324B007DBC0072AC0074AF0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00074AF0075B00074AF007AB8007CBE007BBC007CBD -007CBD007CBD007CBD007CBD007BBC007DBF0072AA006CA2006EA4006EA3006DA40072AC -0075B00074AF0074AF0075B00074AF0076B200609000567F005882005580005986005A87 -005986005B89004C7300486C00496D004C7100476C001B26000B0E000001000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000010100689C0078B50074AE0074AF0075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00074AF0075B0007BBA007CBD007BBC007CBD007BBD007BBD007BBC -007CBD007ABA0070A7006DA3006EA4006EA4006DA20071A80075B10074AF0075B00074AE -0077B3006EA4005780005983005681005580005784005A87005A87005884004B70004A6E -004E7400364F00151D000D11000102000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000102000000002D43007DBC -0073AD0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0074AE0078B5007CBE007BBC007CBD007BBC007BBD007BBC007DBE0076B5006CA1006EA4 -006DA3006EA4006DA30071A90075B00074AF0074AE0077B3006EA5005882005982005883 -005581005680005580005883005B8900547D004A6E00476C003750001116000D11000102 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000102000000001C2A0079B50073AE0074AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0078B8007CBE -007BBC007CBD007BBC007BBC007CBD0072AC006DA3006EA4006EA4006EA4006DA20071A9 -0075B10074AE0077B3006EA5005882005882005983005783005581005681005580005580 -005987005077004263002639001A24000F14000101000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000010200000000527C007BBA0073AD0074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00074AF0076B0007BBB007CBD007BBC007CBD007BBC -007CBC006FA5006DA3006EA4006EA4006EA4006DA3006FA70074AF0077B3006EA5005882 -00588200598300598200578200558100568100557F005784005B8800314800202E001A23 -000A0F000101000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000001000000001926 -0079B70073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0074AF0075B00074AF0077B2007CBD007BBC007BBC007DBF0075B3006DA2006EA4006EA4 -006EA4006DA3006EA4006CA20075B1006FA5005882005882005983005882005982005680 -00558000547F005884004F7700344C001F2C001F2F000710000101000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000100000000527A007DBD0072AC0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074B0 -007ABA007CBD007BBD007BBB006FA7006DA3006EA4006DA3006DA3006EA4006DA3006FA6 -006DA2005982005882005983005882005883005982005680005580005B88004C71002437 -001A28002435000C29000003000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000101000000001C2C0072AC0075B00074AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00074AF0075B00074AF0077B2007CBC007CBD007AB9 -006DA3006DA4006DA3006EA4006EA4006EA4006DA3006AA0005A85005881005983005883 -00588200598300588200578200547F003F5E00283C001B2A002432000E17000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000203006CA30077B30074AF0074AF0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00074AF0075B00074AE0077B5007DC00072AD006DA2006EA4006EA4006CA2 -006CA100679C00699F005C8B005580005A86005885005983005982005882005883005682 -00334E00253600203000202F00151D000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000101000000003A59007EBE0072AC -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075AF0074B1007BBC0071AB006DA2006BA100689D00679C00669B00669B00669C004E78 -005681005985005884005985005884005A8500588400334D002639002437001B29001A27 -000204000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000001000000000B10006CA30077B30074AE0074AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0074AF0075B00071AA00689D -00689D00669B00669B00679B00669B00699F005C8C004970005783005985005885005883 -00598600598500324B002538002A3E001F30001621000102000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000102000000003E5E007DBC0073AD0075B00075AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075B00073AE00679D00669B00679C00679C00669B -00679C00669C004E77004F78005A86005884005884005986005A86003248002131002A3F -002637001520000102000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000D13006DA4 -0076B20074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0076B2006BA300659A00679C00679C00669B00689E005D8D00476E00517B -005A8600588400598500598400334B001F2F002639002A3D001521000103000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000203000000003E5E007CBB0073AD0074AF0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00074AF0074AF0075B1006CA2 -00669A00679C00669B00669B00669B004F7900487000517A005A86005783005C8A00354E -00223000243500293D001B2A000101000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000060A006EA60076B10074AF0074AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00074AF0075B00073AD00669B00679C00669B00699F -005D8D004970004A7200517A005984005C8A004C7200253500253500243600121C000202 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000102000000 -003A56007EBE0072AC0075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0075B00074AE00699E00669B00669B00689E005785004970004A72004F78 -005E8C004C73002638002536002538000C13000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000090F006DA40077B30074AF -0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0076B1 -006EA600659900679D006397004B73004A72004A72005784004C72002536002636002638 -000C13000000000001000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000102000000003C59007DBD0072AC0075B00075AF0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075AF0074AF0076B1006DA600659900699F005683 -00486F004A72004D76005C8A002B3F00273900283B000B12000000000001000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000001 -000000000D14006DA50077B30074AE0075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00074AF0075B00074AF00699F006396004A73004B73004C75004B71003750 -002536001E2E000B12000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000102000000003F5F007BB9 -0072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0074AF006AA1005785004A7200476E003D5C00283900212F001722000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000080D0073AE0077B30074AE0075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00074AF0074AF0076B200699D004263003D5B -003B56002E44001E2C001925000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000001010000000021320076B30074AE0074AF0074AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00073AE0079B6006294003147003A55003046002435001824000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000001000000 -005782007FBF0073AD0075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 -0075B0004363003750003147001E2A00151F000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000006080059850077B40073AE -0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0077B3003D5B003954002131 -00131C000102000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000001000000000F16007BB90075B00074AF0075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0074AF0077B3006498003A56002638000E16000102000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00010200000000324C0079B60073AD0075B00074AF0075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00073AD007AB7 -005782002A3D00070A000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000006597 -007BBA0072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00074AF0075B00073AD0079B500537B000E13000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000001000000000D14006A9F007AB80072AC0075B0 -0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF -0075B00073AD0079B5006EA7001017000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000001000000000D13006A9F007AB80071AA0075B00075B00074AF0075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00074AF0075B00073AD0078B30073B2001734 -000000000102000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000102 -000000000E1500699E0080C10073AD0074AF0075B00074AF0075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 -0075B00074AF0075B00073AD0078B40073AD001926000000000102000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000102000000000E14003D5C -007AB90074AE0072AC0074AF0075B00074AF0075B00075B00075B00075B00075B00075B0 -0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AE0072AB0078B4 -0073AD001826000000000202000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000100020300000000314B007DBD007CBB0075B0 -0073AD0074AF0074AF0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 -0074AF0075B00074AF0073AE0072AB0077B3007EBE0072AD001724000000000203000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000010100020300000000324D0057830071AB007DBC0078B40073AE0073AE -0075B00074AF0074AF0074AF0074AF0074AF0074AF0074AF0074AF0072AB0075B00079B7 -0081C200669A005580001C2C000000000103000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00010200000100000000131E004B70006A9F0079B6007AB70074AF0075B10075B00075B0 -0075B00075B00075B00075B00077B30080C10077B3004F7800213200111A000000000101 -000101000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000102000203000000 -00000000000000273B0060910077B30072AC0073AE0073AE0073AE0073AE0073AD0077B3 -006497003955001E2C000000000001000001000203000001000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000010200000100000000000000060A -000B11000A0F000A10000A10000A10000A10000A0F000B1100080C000000000000000000 -000102000001000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000102000001000000000000000000000000 -000000000000000000000000000000000203000101000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 - -end -%%PageTrailer -%%Trailer -%%EOF diff --git a/medtool/doc/user/doxygen/figures/MED_small.png b/medtool/doc/user/doxygen/figures/MED_small.png deleted file mode 100644 index dfa6c0c2f..000000000 Binary files a/medtool/doc/user/doxygen/figures/MED_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/MedCoupling_Architecture.png b/medtool/doc/user/doxygen/figures/MedCoupling_Architecture.png deleted file mode 100644 index 23ee26b01..000000000 Binary files a/medtool/doc/user/doxygen/figures/MedCoupling_Architecture.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/NonCoincident.png b/medtool/doc/user/doxygen/figures/NonCoincident.png deleted file mode 100755 index 72f011ab7..000000000 Binary files a/medtool/doc/user/doxygen/figures/NonCoincident.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/NonCoincident_small.eps b/medtool/doc/user/doxygen/figures/NonCoincident_small.eps deleted file mode 100644 index 25bc47382..000000000 --- a/medtool/doc/user/doxygen/figures/NonCoincident_small.eps +++ /dev/null @@ -1,15904 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: (ImageMagick) -%%Title: (NonCoincident_small.eps) -%%CreationDate: (Thu Nov 29 18:36:36 2007) -%%BoundingBox: 0 0 375 281 -%%HiResBoundingBox: 0 0 375.052 281 -%%DocumentData: Clean7Bit -%%LanguageLevel: 1 -%%Pages: 1 -%%EndComments - -%%BeginDefaults -%%EndDefaults - -%%BeginProlog -% -% Display a color image. The image is displayed in color on -% Postscript viewers or printers that support color, otherwise -% it is displayed as grayscale. -% -/DirectClassPacket -{ - % - % Get a DirectClass packet. - % - % Parameters: - % red. - % green. - % blue. - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/DirectClassImage -{ - % - % Display a DirectClass image. - % - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { DirectClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayDirectClassPacket } image - } ifelse -} bind def - -/GrayDirectClassPacket -{ - % - % Get a DirectClass packet; convert to grayscale. - % - % Parameters: - % red - % green - % blue - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/GrayPseudoClassPacket -{ - % - % Get a PseudoClass packet; convert to grayscale. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassPacket -{ - % - % Get a PseudoClass packet. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassImage -{ - % - % Display a PseudoClass image. - % - % Parameters: - % class: 0-PseudoClass or 1-Grayscale. - % - currentfile buffer readline pop - token pop /class exch def pop - class 0 gt - { - currentfile buffer readline pop - token pop /depth exch def pop - /grays columns 8 add depth sub depth mul 8 idiv string def - columns rows depth - [ - columns 0 0 - rows neg 0 rows - ] - { currentfile grays readhexstring pop } image - } - { - % - % Parameters: - % colors: number of colors in the colormap. - % colormap: red, green, blue color packets. - % - currentfile buffer readline pop - token pop /colors exch def pop - /colors colors 3 mul def - /colormap colors string def - currentfile colormap readhexstring pop pop - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { PseudoClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayPseudoClassPacket } image - } ifelse - } ifelse -} bind def - -/DisplayImage -{ - % - % Display a DirectClass or PseudoClass image. - % - % Parameters: - % x & y translation. - % x & y scale. - % label pointsize. - % image label. - % image columns & rows. - % class: 0-DirectClass or 1-PseudoClass. - % compression: 0-none or 1-RunlengthEncoded. - % hex color packets. - % - gsave - /buffer 512 string def - /byte 1 string def - /color_packet 3 string def - /pixels 768 string def - - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - x y translate - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - currentfile buffer readline pop - token pop /pointsize exch def pop - /Times-Roman findfont pointsize scalefont setfont - x y scale - currentfile buffer readline pop - token pop /columns exch def - token pop /rows exch def pop - currentfile buffer readline pop - token pop /class exch def pop - currentfile buffer readline pop - token pop /compression exch def pop - class 0 gt { PseudoClassImage } { DirectClassImage } ifelse - grestore -} bind def -%%EndProlog -%%Page: 1 1 -%%PageBoundingBox: 0 0 375 281 -userdict begin -DisplayImage -0 0 -375.052 281.289 -12.000000 -500 375 -0 -0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEFCFCFCFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFBFBFBFCFCFCFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA -FAFAFAFAFAFAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D48080808A8A8A898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -8989898989898989898989898A8A8A7B7B7B7676768A8A8A898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -898989898989898989898989898989898989898989898989898989898989898989898989 -8989898989898989898989898989898989898989898989898989898A8A8A7B7B7BD2D2D2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9AEAEAEF8F8F8F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F7F7F7BABABAA5A5A5F8F8F8F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 -F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F8F8F8ABABABBCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC8C8C86464644D4D4D747474 -D6D6D6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B49B9B9BFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFD7D7D73C3C3C8A8A8AA0A0A07979794C4C4CEEEEEEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBD2D2D2404040636363FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFF9C9C9C -7C7C7CFFFFFFFFFFFFF8F8F8434343B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFA6A6A6303030 -3C3C3C656565FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6F4F4F4FFFFFFFFFFFFF0F0F0 -434343B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB8B8B8888888626262FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3787878898989F9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF898989626262FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF3F3F3787878868686F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -898989626262FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3797979868686F8F8F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF898989626262FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFF4F4F4757575797979EEEEEEF3F3F3F2F2F2FBFBFBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF898989626262FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F -0C0C0C303030383838373737383838C4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -8B8B8B656565FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4C6C6C6C5C5C5C4C4C4C5C5C5 -C5C5C5EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2D8D8D8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5 -F2F2F2EBEBEBE5E5E5E1E1E1D9D9D9D7D7D7CECECECCCCCCC6C6C6EFEFEFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FBFBFBF5F5F5F3F3F3EBEBEBE9E9E9E2E2E2DEDEDED9D9D9D2D2D2CFCFCFC3C3C3C1C1C1 -B5B5B5B0B0B0A8A8A8A0A0A09B9B9B8F8F8F8F8F8F9393939494949797979999999B9B9B -9F9F9FA0A0A0A4A4A4A1A1A16E6E6EDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBF7F7F7F3F3F3EDEDEDEBEBEBE4E4E4E2E2E2DBDBDBD8D8D8D0D0D0 -C7C7C7C3C3C3B6B6B6B3B3B3A7A7A7A3A3A39A9A9A919191939393959595959595979797 -9898989A9A9A9C9C9C9D9D9D9F9F9FA2A2A2AFAFAFB2B2B2BFBFBFC4C4C4CDCDCDD6D6D6 -DBDBDBE8E8E8E9E9E9EEEEEEEFEFEFF3F3F3F6F6F6F8F8F8FCFCFCFDFDFDFFFFFFE4E4E4 -9B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEFEFEFEBEBEBEA3A3A3F5F5F5ECECECE7E7E7E5E5E5DFDFDF -DDDDDDD0D0D0CCCCCCC3C3C3BABABAB5B5B5A8A8A8A6A6A6999999959595969696979797 -9797979797979898989999999999999A9A9A9A9A9AA3A3A3ACACACB0B0B0BDBDBDC0C0C0 -CDCDCDD1D1D1DBDBDBE3E3E3E6E6E6EBEBEBECECECF2F2F2F3F3F3F8F8F8FBFBFBFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBCB7B7B7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFBFBFBF9F9F9F4F4F4F3F3F3EDEDEDEBEBEB -E8E8E8E4E4E4DFDFDFD2D2D2CFCFCFC2C2C2BEBEBEB5B5B5ACACACA6A6A69A9A9A9A9A9A -9B9B9B7575756767679A9A9A979797979797969696969696969696A4A4A4A8A8A8B0B0B0 -B9B9B9BEBEBECBCBCBCECECEDBDBDBDEDEDEE4E4E4E7E7E7EAEAEAF0F0F0F1F1F1F8F8F8 -F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFB999999E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFCFCFCF9F9F9F6F6F6F4F4F4 -F0F0F0EFEFEFEAEAEAE8E8E8DFDFDFD6D6D6D1D1D1C4C4C4C1C1C1B5B5B5B1B1B1A6A6A6 -9F9F9F9E9E9E9C9C9C9B9B9B989898989898969696959595939393919191969696A3A3A3 -A5A5A5B2B2B2B5B5B5BEBEBEC6C6C6CCCCCCD8D8D8DADADAE5E5E5ADADADA0A0A0F1F1F1 -F1F1F1F7F7F7F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E09A9A9A -FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFEFAFAFA -F8F8F8F5F5F5F3F3F3F1F1F1EDEDEDEBEBEBDEDEDEDADADAD0D0D0C8C8C8C2C2C2B7B7B7 -B4B4B4A7A7A7A4A4A4A0A0A09F9F9F9C9C9C9999999898989494949393939090908E8E8E -9797979F9F9FA4A4A4B0B0B0B2B2B2BEBEBEC1C1C1CCCCCCD2D2D2D7D7D7DDDDDDE0E0E0 -E8E8E8E9E9E9F1F1F1F5F5F5FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEFBFBFBFAFAFAF8F8F8F6F6F6F3F3F3F2F2F2ECECECE0E0E0DDDDDDD0D0D0CDCDCD -C2C2C2BCBCBCB5B5B5AAAAAAA8A8A8A3A3A3A2A2A29C9C9C9A9A9A979797939393929292 -8C8C8C8D8D8D9999999C9C9CA5A5A5ABABABB2B2B2BCBCBCBEBEBECACACACCCCCCD5D5D5 -D9D9D9DFDFDFE5E5E5E8E8E8F1F1F1F3F3F3FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9999999E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -FCFCFCF9F9F9F4F4F4E3E3E3D1D1D1C0C0C0A9A9A99F9F9FA4A4A49D9D9D929292818181 -9494948E8E8E8989898E8E8E9898989B9B9BA5A5A5A8A8A8B2B2B2B7B7B7BDBDBDC5C5C5 -C8C8C8D2D2D2D4D4D4DEDEDEE2E2E2E9E9E9EFEFEFF3F3F3FDFDFDFDFDFDFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9C9C9CFCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEFCFCFCF9F9F9ECECECDBDBDBCACACABABABAACACACA0A0A09595958C8C8C969696 -A5A5A5B2B2B2767676ADADADD4D4D4DDDDDDD3D3D3999999CECECEF7F7F7FCFCFCFCFCFC -FDFDFDFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEFCFCFCF4F4F4E4E4E4D4D4D4C4C4C4B5B5B5A8A8A89B9B9B8E8E8E919191 -9E9E9EAAAAAAB7B7B7C7C7C7D7D7D7E8E8E8F7F7F7FCFCFCFFFFFFE3E3E39D9D9DF8F8F8 -FFFFFFFFFFFFFFFFFFE4E4E4A7A7A7E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F7969696E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEFEFEFEFAFAFAECECECDDDDDDCECECEBFBFBFB0B0B0A1A1A19292928D8D8D -989898A3A3A3AEAEAEBCBCBCCDCDCDDFDFDFF0F0F0F9F9F9FCFCFCFEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DCDCDCA7A7A7EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D99E9E9EFDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDF3F3F3E5E5E5D8D8D8CACACAB9B9B9A9A9A99999998E8E8E -9494949D9D9DA6A6A6B1B1B1C3C3C3D6D6D6E8E8E8F4F4F4F9F9F9FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EDEDED979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3ABABABF5F5F5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9EDEDEDE1E1E1D4D4D4C4C4C4B3B3B3A2A2A2929292 -929292999999A0A0A0A7A7A7B9B9B9CBCBCBDEDEDEEEEEEEF5F5F5FAFAFAFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFECACACAB1B1B1F8F8F8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 -979797E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3F3F3E8E8E8DDDDDDCFCFCFBEBEBEABABAB999999 -9292929797979B9B9BA0A0A0ADADADC1C1C1D3D3D3E6E6E6F0F0F0F6F6F6FCFCFCFEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF5F5F5989898E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDC0C0C0BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A1A1A1FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8EFEFEFE5E5E5DADADAC8C8C8B5B5B5A3A3A3 -9595959696969898989B9B9BA3A3A3B5B5B5C9C9C9DDDDDDEAEAEAF1F1F1F8F8F8FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB -AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -B7B7B7C4C4C4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFACACACC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF5F5F5ECECECE2E2E2D2D2D2C0C0C0ADADAD -9C9C9C9797979898989898989A9A9AABABABBEBEBED1D1D1E2E2E2EBEBEBF4F4F4FCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9F9F9FDBDBDBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3969696 -ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9F2F2F2EAEAEADEDEDECACACAB7B7B7 -A4A4A49B9B9B999999969696959595A1A1A1B4B4B4C6C6C6D8D8D8E4E4E4EEEEEEF8F8F8 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD8D8D8A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2A3A3A3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF7F7F7F1F1F1E8E8E8D5D5D5C1C1C1 -AFAFAFA1A1A19C9C9C979797929292989898AAAAAABCBCBCCECECEDCDCDCE7E7E7F2F2F2 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA7A7A7CFCFCF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECECA7A7A7E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF5F5F5EFEFEFDFDFDFCDCDCD -BABABAA8A8A8A0A0A0999999929292919191A0A0A0B2B2B2C3C3C3D3D3D3DFDFDFECECEC -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F6F6F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 -A6A6A6E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1969696EDEDED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9F5F5F5E9E9E9D7D7D7 -C5C5C5B2B2B2A6A6A69E9E9E9595958E8E8E989898A8A8A8B8B8B8C9C9C9D7D7D7E5E5E5 -F2F2F2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA8A8A8EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF9F9F9F2F2F2E0E0E0 -CECECEBDBDBDAFAFAFA4A4A49999998E8E8E919191A0A0A0AFAFAFBEBEBECDCDCDDCDCDC -EBEBEBF9F9F9FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ACACACF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA5A5A5D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFEFEFEFCFCFCF8F8F8E9E9E9 -D8D8D8C8C8C8B8B8B8ABABAB9E9E9E9292928C8C8C9A9A9AA7A7A7B4B4B4C3C3C3D3D3D3 -E3E3E3F3F3F3FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEC9C9C9B2B2B2F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED979797F0F0F0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFCF5F5F5 -A6A6A6939393C6C6C6B4B4B4A6A6A69898988C8C8C949494A0A0A0ABABABB9B9B9C9C9C9 -DADADAEBEBEBF8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 -999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0 -BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCACACAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8 -E9E9E9DBDBDBCDCDCDBEBEBEAEAEAE9E9E9E8F8F8F9393936F6F6F777777B2B2B2BEBEBE -D0D0D0E2E2E2F2F2F2F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBB7B7B7C4C4C4FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -A1A1A1D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -F1F1F1E4E4E4D7D7D7C9C9C9B7B7B7A7A7A79696968F8F8F9696969E9E9EA6A6A6B3B3B3 -C6C6C6D9D9D9EBEBEBF9F9F9B5B5B5B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA979797F2F2F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F7EBEBEBDFDFDFD2D2D2C2C2C2B1B1B19F9F9F9191919494949A9A9A9F9F9FA8A8A8 -BBBBBBCECECEE1E1E1EFEFEFF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A1A1A1 -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF2F2F2AAAAAAD6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC6C6C6ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEF4F4F4E7E7E7DCDCDCCDCDCDBBBBBBA8A8A89696969494949898989B9B9BA0A0A0 -B0B0B0C3C3C3D7D7D7E8E8E8F0F0F0F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDA7A7A7 -DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9E9E9E -D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79696968C8C8C9B9B9B -A5A5A5B8B8B8CCCCCCDFDFDFEAEAEAF2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E39B9B9BF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A6A6A6E7E7E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7989898F4F4F4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1A8A8A8FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA8A8A8EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC2C2C2B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFAAAAAAAD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD2D2D2ACACACF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9C9C9CDCDCDC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E89E9E9E -EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9B2B2B2 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9AEAEAEFBFBFBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4989898E7E7E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBFBBBBBBFCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFBEBEBEB4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFCABABABCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAB6B6B6C4C4C4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB999999E1E1E1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEA9E9E9EEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9D9D9D -DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F7AFAFAFCECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE0E0E09A9A9AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDABABABFBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9BABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCADADADCACACAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA6A6A6CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA6A6A6DFDFDFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA979797E4E4E4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEDEDED9E9E9EE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E39A9A9AF8F8F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE4E4E4A6A6A6E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDCDCDC9D9D9DFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF -A9A9A9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DCDCDCA8A8A8EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6 -BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB0B0B0C7C7C7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EDEDED979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ACACACF5F5F5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAEBEBEAEDECECFBFBFBFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8959595E8E8E8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9E9E9EE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC9C9C9B2B2B2F9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED5D6D6929899808D8E818D8E979C9D -E2E3E3C3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDADADA9E9E9EFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD2D2D2A8A8A8F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF5F5F5999999E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDC0C0C0BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C97979797A7A7AC9C9C9FFFFFFFFFFFF -FFFFFFFFFFFFCECFCF849495A2C2C5B1D5D8B0D4D69FBEC08896979F9F9FAEAEAEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2C2C2C2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB2B2B2C4C4C4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB -AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -B7B7B7C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC7C7C7585858707070565656313131D0D0D0FFFFFFFFFFFFEFEFEF879192ACCED1 -BCE2E5BBE0E3BBE0E3BDE2E5A8C9CC535B5BA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6969696EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0A0A0A0E3E3E3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9EDCDCDCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6AFAFAFCECECEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD7C7C7CB2B2B2FFFFFF -F7F7F74747479D9D9DFFFFFFFFFFFFD2D2D27D9193BCE2E5BBE0E3BBE0E3BBE0E3BADFE2 -BCE1E4516162A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD5D5D5A1A1A1FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD5D5D5A6A6A6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD8D8D8A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1F1F1F1F6F6F6DFDFDF4E4E4EBFBFBFFFFFFF -FFFFFFC8C9C983989ABCE2E5BADFE2BBE0E3BBE0E3BADFE2BCE1E45C6E70A6A6A6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC5C5C5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -B6B6B6C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA7A7A7CFCFCF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECECA6A6A6E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC1C1C13A3A3A242424969696FFFFFFFFFFFFFFFFFFDFDFDF7A8B8CB9DEE1 -BBE0E3BADFE2BADFE2BBE0E3B8DCDF485556A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5949494ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A0A0A0E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 -A5A5A5E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBC1C1C1 -595959888888FFFFFFFFFFFFFFFFFFFBFAFAA2A7A894B0B2BAE0E3BDE3E6BDE3E6B9DEE1 -91ABAD737676ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D2D2D2A3A3A3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A3A3A3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA8A8A8EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAC5C5C5F0F0F0FFFFFFFFFFFFBCBCBC3B3B3BF6F6F6FFFFFF -FFFFFFFFFFFFEFEFEF9DA3A48196988EAAAC8DA9AB809496ABAFB0B8B8B8ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAACACACAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEB9B9B9BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED979797EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ACACACF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 -4E4E4EAAAAAAFFFFFFEEEEEE565656525252F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFF9F8F8 -CCCDCDADAFAFAFB0B0D2D3D3FFFFFFC3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF2F2F2959595EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4A1A1A1 -DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEC9C9C9B2B2B2F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF3F3F3F535353393939 -424242DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD -A7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA2A2A2F4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 -9A9A9AE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0 -BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD7D7D79C9C9C9E9E9EDFDFDFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CECECEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEBBBBBBBBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF3F3F3DDDCDCD9D9D9EDEDEDFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBB7B7B7C3C3C3FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF0F0F0949494F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6A3A3A3DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE6E6E6F3F3F3FFFFFFFFFFFFFFFFFFFFFFFF -FDFDFDD1D1D28B94957B8D8E7A8D8F838F90C1C2C3FAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B0B0B0CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFA1A1A1F3F3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC9C9C9393939BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFD2D3D3839395A8CACCB9DEE1 -BADFE2AED2D5879C9EBBBDBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A0A0A0 -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF2F2F2AAAAAAD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA4A4A4D2D2D2FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFB8B8B8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8949494303030393939F2F2F2 -FFFFFFFFFFFFFFFFFFF5F4F48C9596A7C8CBBCE2E5BBE0E3BBE0E3BCE1E4B3D7DA829091 -E5E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA6A6A6 -DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFECECEC969696F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F7A3A3A3D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF5F5F55A5A5A6262627474744C4C4CFBFBFBFFFFFFFFFFFFFFFFFFE2E1E1 -79898BB8DDE0BBE0E3BBE0E3BBE0E3BADFE2BCE1E4849C9EC1C2C2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E39B9B9BF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A6A6A6E8E8E8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 -A0A0A0F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDDDDDD -F1F1F1535353A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFE0E0E078898BBADFE2BBE0E3BBE0E3 -BBE0E3BADFE2BCE1E4869EA0BEBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2C2C2C2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA8A8A8EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA1A1A1D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B5B5B5FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F73E3E3EB4B4B4FFFFFF -FFFFFFFFFFFFFFFFFFF1F1F1869091ACCED1BCE1E4BADFE2BBE0E3BBE0E3B7DBDE809091 -DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD2D2D2ACACACF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E9E9E9969696F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A5A5A5D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBABABA262626CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C4C6C685999BB1D5D8BCE1E4BCE2E5B6DBDE8DA6A8ADB0B1FDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8B2B2B2 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B0B0B0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE4E4E49E9E9EF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A6A6A64A4A4AFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBEC0C1828F9082999B -839B9D7F8F90AEB1B2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4999999E7E7E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBFBABABAFCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFC9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B2B2B2 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888676767FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE8E8E8C6C6C6C1C2C2DFDEDEFCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAB6B6B6C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -989898F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A8A8A8D2D2D2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF8F8F8696969CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9D9D9D -DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F7AFAFAFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE5E5E59F9F9FEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2AAAAAAD7D7D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA9C9C9CDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C9C9C9AFAFAFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA6A6A6E0E0E0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2999999 -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAAAAAAACFCFCFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E39A9A9AF7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE4E4E4A6A6A6E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB8B8B8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E99E9E9EECECECFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DCDCDCA8A8A8EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9999999E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCBCBCBADADADFBFBFBFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -ECECEC979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ADADADF4F4F4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9C9C9CFAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBACACAC -CCCCCCFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC8C8C8B3B3B3F9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB9E9E9EEAEAEAFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF5F5F5989898E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDBFBFBFBABABAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8989898E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCECECEABABABFAFAFAFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB -AAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -B7B7B7C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9E9E9EFBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFCAEAEAEC9C9C9FFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9EDBDBDBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B0B0B0CDCDCDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED9F9F9FECECEC -BABABAB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD8D8D8A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -959595E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1ADADADB4B4B4B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6CFCFCF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECECA6A6A6E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A1A1A1FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEB5B5B5808080B7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5 -A5A5A5E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3 -6E6E6EB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB1B1B1C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA7A7A7EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5949494 -EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF7F7F7FFBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE979797EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3ACACACF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A3A3A3FDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBABABA6C6C6CC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEC9C9C9B3B3B3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFABABABC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BABABAA8A8A8A5A5A5E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 -9A9A9AE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBF -BBBBBBFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3949494EFEFEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B8B8B8DBDBDBA5A5A5 -F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCAAAAAAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAB7B7B7C3C3C3FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA7A7A7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFB6B6B6C0C0C0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B0B0B0CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA9A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFF3F3F3A1A1A1DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF1F1F1AAAAAAD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0949494F2F2F2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -D9D9D9A3A3A3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA6A6A6 -E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCCCCCCA9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFEFEFEBABABABCBCBCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE2E2E29B9B9BF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A5A5A5E8E8E8FFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -A5A5A5D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFF5F5F5A1A1A1DEDEDEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA7A7A7EFEFEFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF949494F3F3F3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFDCDCDCA2A2A2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD3D3D3ACACACF4F4F4FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC6C6C6ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC -B9B9B9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BDBDBDB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8B2B2B2 -FCFCFCC3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA3A3A3 -D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6A3A3A3D9D9D9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3999999E8E8E8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBFBEBEBEC0C0C0ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB949494F6F6F6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE0E0E0A0A0A0F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCACACAABABABFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBBABABA878787ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC4C4C4B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC0C0C0B6B6B6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99D9D9D -DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFA8B8B8B9C9C9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0D8D8D8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A4A4A4D7D7D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A2A2A2FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2686868DBDBDB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8979797F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A3A3A3F1F1F1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA7A7A7D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C39C9C9CAFAFAFE2E2E2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC0C0C0B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B96D6D6D9A9A9A989898989898989898989898989898 -9898989898989999996B6B6B737373989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -9898989898989898989898989898989898989898989898989898988B8B8B5B5B5B919191 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -9A9A9A7474746969698181816868688F8F8F999999989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -9898989898989898989898989898989898989898989898989797975F5F5F808080999999 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -989898989898989898989898989898989898989898989898989898989898989898989898 -9898989898989898989898989898989B9B9B6C6C6CBCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B99D9D9DDFDFDFDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -909090B2B2B2DDDDDDDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDCDCDC939393ADADADDEDEDEDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDFDFDFA7A7A7959595E1E1E1 -C7C7C7898989CCCCCCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDCDCDCC2C2C2828282D9D9D9DBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB -DBDBDBDFDFDF9A9A9ABCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6A1A1A1F0F0F0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -ECECEC999999F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFD4D4D4AFAFAFF5F5F5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BCBCBCB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4B2B2B2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F6F6F7F7F7 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFEFEFEC8C8C8B3B3B3F9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99B9B9BDFDFDFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9A9A9A9D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF4F4F4989898E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF8F8F8F9F9F9FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE2E2E29EA3A3838D8E858F8FA7AAABEAEAEAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFDFDFDBFBFBFBBBBBBFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE1E1E19A9A9AFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E79F9F9F -EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA -ABABABFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEBEBEB6363633A3A3A494949CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6 -85939499B7B9ABCDD0A9CBCE94B1B38B9697E3E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -B6B6B6C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7 -BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8AEAEAEFCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9E9E9EDCDCDCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC535353424242 -B7B7B76868683D3D3DEDEDEDFFFFFFFFFFFFF2F2F28A9495A7C9CCBDE3E6BBE1E4BCE1E4 -BDE3E69EBDBF989E9FF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7999999E3E3E3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAAAAAAACECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD7D7D7A1A1A1FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB5A5A5AE0E0E0FFFFFFD7D7D7313131E5E5E5 -FFFFFFFFFFFFCFD0D0819496BBE0E3BADFE2BBE0E3BBE0E3BBE0E3B8DDE0788889E5E5E5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2AAAAAAD6D6D6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDDDDDD9C9C9CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEA9E9E9EEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA5A5A5D0D0D0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDFBFBFBFEFEFEFFFFFF8B8B8B383838ECECECFFFFFFFFFFFFC0C1C1869EA0 -BBE1E4BADFE2BBE0E3BBE0E3BADFE2BBE1E47A8C8DDBDADAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEEEEEEA9A9A9E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BFBFBF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCABABABFBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29A9A9AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 -8888884B4B4BC6C6C6FFFFFFFFFFFFFFFFFFD8D8D87F9092B9DFE2BBE0E3BADFE2BADFE2 -BBE0E3B5D9DC7A8889EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED616161 -7A7A7AEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6979797E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBAEAEAECACACAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB0B0B0C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F77777772B2B2BC6C6C6FFFFFFFFFFFF -FFFFFFFFFFFFF9F9F9989F9F9BB9BBBCE2E5BCE2E5BCE2E5BAE0E391ACAEA9ADADFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA646464030303999999ABABABEFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD9D9D99F9F9FFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECEC9E9E9EE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF7F7F78383836C6C6CCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8 -949C9D88A1A39AB9BC98B7BA869D9E9EA4A4F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB1B1B1414141232323BBBBBBD7D7D7ABABABF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC3C3C3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -E5E5E5E3E3E3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF -AAAAAAF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F77A7A7A616161DCDCDC -E5E5E5E1E1E1F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F2F2BCBDBD999C9C9C9F9F -C4C5C5F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E73A3A3A8F8F8F404040 -B8B8B8FFFFFFC9C9C9B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF4F4F4969696EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFF2F2F28888883A3A3A343434757575DBDBDB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB0B0B0C8C8C8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 -999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC2C2C21B1B1B2A2A2A3232323131312D2D2DA0A0A0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF919191636363F5F5F53E3E3EB8B8B8FFFFFFFCFCFCBFBFBF -BBBBBBFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D5D5D5A2A2A2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFBABABA515151CDCDCDD9D9D9565656606060FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEDEDED9F9F9FE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBABABABFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F4F4F4DDDDDDDCDCDCDBDBDBDBDBDBDADADAEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2 -2B2B2BB5B5B5EAEAEA393939ABABABFDFDFDFFFFFFFAFAFAB6B6B6C4C4C4FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFE7E7E7E8E8E8 -FFFFFFFFFFFF9A9A9A555555FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD3D3D3A7A7A7F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFF8D8D8D0808082E2E2E3333330C0C0C -262626C4C4C4FFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF2F2F2949494EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4959595525252C5C5C5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB1B1B1C5C5C5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFE9E9E9CECECECDCDCDC7C7C7313131949494F3F3F3FFFFFFFFFFFF -FFFFFFF2F2F2AAAAAAD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0 -A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB2B2B24E4E4E4C4C4CAFAFAFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F09E9E9EE4E4E4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF8F8F8414141B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA7A7A7 -E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9CBCBCBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFDFDFD -FFFFFFFFFFFFDFDFDF404040CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD5D5D5A6A6A6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E39B9B9BF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCFCFCF -EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A6A6A6E8E8E8FFFFFFFFFFFF -FFFFFFFFFFFFF0F0F0959595F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFF9C9C9C7F7F7FF8F8F8FFFFFFF6F6F63B3B3B -BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -B4B4B4C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA7A7A7EFEFEFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFC6C6C6383838A5A5A5C4C4C4949494656565EBEBEBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19F9F9FE2E2E2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD3D3D3ABABABF5F5F5FFFFFFFEFEFEA5A5A5CFCFCFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8 -464646363636626262E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A4A4A4F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BDBDBDB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFECACACAB2B2B2 -F9F9F9EEEEEE949494F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF5F5F5F4F4F4F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB8B8B8BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3999999E8E8E8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0BFBFBFC6C6C6ACACACFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A1A1A1 -DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF7F7F7A2A2A2747474D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA2A2A2F6F6F6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99D9D9D -DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF1F1F1E0E0E0C5C5C5A6A6A6989898 -7C7C7C7A7A7AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBBBBBBBBBBBBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7E9E9E9 -D3D3D3B2B2B29C9C9C979797999999AEAEAECDCDCDE2E2E29D9D9DD1D1D1FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F4F4F4A1A1A1DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFBF0F0F0DEDEDEC0C0C0A4A4A4999999969696A1A1A1C1C1C1DADADAECECEC -FBFBFBFFFFFFFFFFFFD4D4D4A6A6A6FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA1A1A1F4F4F4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29B9B9BF7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFEFEFEF6F6F6E8E8E8CECECEAFAFAF9D9D9D969696989898 -B3B3B3D0D0D0E4E4E4F6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F69D9D9D -E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB8B8B8FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEBABABA909090C1C1C1 -A4A4A4989898939393A6A6A6C3C3C3DBDBDBEFEFEFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B4B4B4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F6A3A3A3D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -ECECEC979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -F6F6F6E5E5E5C9C9C9AEAEAE9F9F9F6E6E6E6E6E6EB9B9B9D0D0D0E7E7E7FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEBEBEB9B9B9BECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0 -A0A0A0F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEFBFBFBEEEEEED5D5D5BABABAA4A4A4929292959595ABABABC4C4C4 -E2E2E2B9B9B9ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB2B2B2C2C2C2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1B6B6B6FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF4F4F4989898E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7E0E0E0C5C5C5AEAEAE989898 -909090A2A2A2B8B8B8D2D2D2EDEDEDFCFCFCFEFEFEFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9F9F9FF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A5A5A5D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA -ABABABFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCEAEAEA -D1D1D1B8B8B8A1A1A18E8E8E9A9A9AAEAEAEC5C5C5E2E2E2F8F8F8FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -A5A5A5D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E39F9F9FF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9E9E9EDDDDDDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F3DBDBDBC3C3C3AAAAAA939393949494A5A5A5BABABAD6D6D6F1F1F1 -FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA9A9A9FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4B2B2B2 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD7D7D7A1A1A1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE5E5E5CFCFCFB5B5B59B9B9B9292929E9E9E -AFAFAFCACACAE8E8E8F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF4F4F49E9E9EE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA7A7A7D3D3D3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEFEFEFDADADAC1C1C1 -A5A5A5939393999999A5A5A5BEBEBEDBDBDBF1F1F1FAFAFAFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFB7B7B7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE7E7E79E9E9EEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29A9A9AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -F6F6F6E4E4E4CDCDCDB1B1B19999999696969D9D9DB2B2B2D0D0D0E8E8E8F6F6F6FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E99B9B9BEFEFEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C6C6C6B0B0B0FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB0B0B0C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBEDEDEDDADADABCBCBCA1A1A1979797989898A6A6A6C3C3C3 -DEDEDEF0F0F0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEAEAEAEC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAAAAAAAD0D0D0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898F0F0F0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3F3F3E5E5E5CACACAACACAC9A9A9A -9797979B9B9BB7B7B7D3D3D3E8E8E8F7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA0A0A0F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E89F9F9FEDEDEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9EDEDED -D8D8D8B8B8B8A0A0A0989898959595A9A9A9C7C7C7DFDFDFF1F1F1FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F9A3A3A3D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9C9C9AEAEAEFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 -999999E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFCFCFCF3F3F3E4E4E4C6C6C6A8A8A89B9B9B9393939E9E9EBBBBBBD5D5D5E9E9E9 -FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB -AAAAAAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBABABAB -CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8EDEDEDD3D3D3B4B4B4A0A0A0949494959595 -AEAEAECACACAE1E1E1F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9BE6E6E6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB9E9E9EEAEAEAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF4F4F4DEDEDEC1C1C1 -A9A9A9989898909090A3A3A3BEBEBED7D7D7EEEEEEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBBBBBBB9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCDCDCDAAAAAAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -F9F9F9E8E8E8CDCDCDB3B3B39E9E9E9090909B9B9BB2B2B2CBCBCBE5E5E5F9F9F9FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E79A9A9AF2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FBFBFBAEAEAECACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDF1F1F1D8D8D8BFBFBFA8A8A8929292949494A8A8A8BEBEBE -DADADAF2F2F2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEABABABCBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED9E9E9EE8E8E8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E39A9A9AF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9E2E2E2CACACAB2B2B29A9A9A -909090A0A0A0B3B3B3CDCDCDEAEAEAF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D9D9D9A2A2A2FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0A9A9A9FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C4C4C4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDECECEC -D5D5D5BDBDBDA4A4A49090909A9A9AA9A9A9C1C1C1DEDEDEF4F4F4FCFCFCFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A1A1A1DADADAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFCB1B1B1C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECECEC999999F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF5F5F5DFDFDFC9C9C9AFAFAF959595959595A1A1A1B5B5B5D1D1D1EDEDED -F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC8C8C8ADADADFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE -9F9F9FE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE9E9E9D4D4D4BABABA9E9E9E9494949B9B9B -AAAAAAC5C5C5E3E3E3F4F4F4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9C9C9C -E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A7A7A7F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3999999E7E7E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF1F1F1E0E0E0C7C7C7 -A9A9A9969696989898A0A0A0B9B9B9D7D7D7EDEDEDF9F9F9FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BDBDBDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB2B2B2C5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -F7F7F7E9E9E9D3D3D3B5B5B59C9C9C979797999999ACACACCBCBCBE4E4E4F3F3F3FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE4E4E49D9D9DF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF1F1F19F9F9FE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99D9D9D -DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBF1F1F1E0E0E0C1C1C1A5A5A5999999959595A1A1A1BFBFBF -DADADAECECECFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCAAAAAACCCCCCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A5A5A5 -F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A2A2A2FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF6F6F6EAEAEACFCFCFAFAFAF9D9D9D -969696979797B2B2B2CFCFCFE4E4E4F6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A4A4A4FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB5B5B5C1C1C1FFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF2F2F2 -DCDCDCBCBCBCA4A4A4989898929292A6A6A6C3C3C3DBDBDBEFEFEFFDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -9F9F9FDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF2F2F2A0A0A0E1E1E1FFFFFFFFFFFFFFFFFFE2E2E29B9B9BF7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDF7F7F7E7E7E7CACACAADADAD9D9D9D9191919B9B9BB7B7B7D0D0D0E7E7E7 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6B0B0B0FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DADADAA3A3A3F6F6F6FFFFFFFFFFFFB0B0B0C4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF0F0F0D6D6D6B9B9B9A4A4A4949494949494 -ABABABC4C4C4DDDDDDF3F3F3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFEEEEEE9B9B9BEAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BDBDBDFFFFFF -EBEBEB989898F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7E0E0E0C5C5C5 -AEAEAE999999909090A2A2A2B8B8B8D2D2D2EBEBEBFBFBFBFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFB5B5B5C0C0C0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4A2A2A2DFDFDFBFBFBFB8B8B8FFFFFFFEFEFE -FCFCFCEAEAEAD1D1D1B9B9B9A1A1A19090909A9A9AADADADC5C5C5E1E1E1F6F6F6FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFE1E1E19D9D9DF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDDDDDD9999998A8A8AC6C6C6C6C6C6ACACAC939393959595A5A5A5B8B8B8 -D5D5D5F0F0F0FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FBFBFBA6A6A6D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 -5555559A9A9AADADADC8C8C8E7E7E7F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFD2D2D2A6A6A6FBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B0B0B0C1C1C1FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2AEAEAEF9F9F99D9D9DE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B2B2B2CCCCCCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2AFAFAFC6C6C6 -B3B3B3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF2F2F2ADADADD4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C49A9A9AA0A0A0EDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEA9A9A9 -DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC4C4C4626262C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8A9A9A9E1E1E1FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF737373F9F9F9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A7A7A7E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFD828282A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDEDEDEA9A9A9ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D3D3D36D6D6DABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABAB -F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4A2A2A2A6A6A6AEAEAEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0AEAEAEF5F5F5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBEBEBEBABABAC3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFECACACAB2B2B2F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA9A9A9A -F3F3F3C3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFDC2C2C2B9B9B9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFEFEFDFCFCF1F1F1F7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEAFAFAFC6C6C6FFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBCBCBCBEBEBE -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFCCCCDCD888F8F7F898A7F8889 -A6AAAAEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDCDCDC9F9F9FF7F7F7FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAB5B5B5C6C6C6FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC868686FBFBFB -FFFFFFFFFFFFFEFEFEBBBDBE879A9CA7C8CBB2D6D9AFD3D694B0B3929A9BEDEDEDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA3A3A3D7D7D7FFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6F6F6B1B1B1CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBCBCBC1F1F1F7E7E7EFFFFFFFFFFFFFFFFFFDFDFDF829293 -B3D7DABCE1E4BBE0E3BBE0E3BCE2E594B0B2A6AAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCCCCCCAAAAAAFDFDFDFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F3F3F3ADADADD4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB -585858232323B1B1B1FFFFFFFFFFFFFFFFFFB4B6B68CA6A8BCE2E5BADFE2BBE0E3BBE0E2 -BBE0E3B1D5D87C8687F6F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3 -9C9C9CE5E5E5FFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEAAAAAADADADA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC5C5C5CA9A9A9484848D6D6D6FFFFFF -FFFFFFFFFFFFA6AAAA93B0B2BCE1E5BADFE2BBE0E3BBE0E3BADFE2B6DADD798586EFEFEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBBABABAFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A8A8A8E2E2E2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFBDBDBD5A5A5AD8D8D8ADADAD464646FCFCFCFFFFFFFFFFFFFFFFFFC3C4C4869C9E -BCE2E5BBE0E3BADFE2BADFE2BCE1E4A9CCCF848D8EFAF9F9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE7E7E79B9B9BF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE3E3E3A8A8A8E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C34D4D4DC6C6C6F4F4F4 -767676414141F8F8F8FFFFFFFFFFFFFFFFFFF1F0F08D9798A2C3C6BDE3E6BDE2E5BDE3E6 -B7DBDE869C9EC4C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDACACACCACACA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DEDEDEA9A9A9ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF8B8B8B1818183838383434340B0B0B131313C3C3C3FFFFFF -FFFFFFFFFFFFFFFFFFDDDEDE8E9899869D9F94B1B38EA9AB819394B5B8B8FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A1A1A1F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF1F1F1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E7E7E7C9C9C9C9C9C9C1C1C1313131949494F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EEEEEEC0C1C1A6A9A9B0B2B2D8D8D8FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8A1A1A1D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1AEAEAEF5F5F5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 -4D4D4DEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ADADADFDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEC9C9C9B3B3B3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5CFCFCFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF0F0F09B9B9BE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -C2C2C2B8B8B8FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 -BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBCBCBCBEBEBEFCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E49D9D9DF3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B5B5B5C6C6C6FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFCFCFCAAAAAACDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F6B1B1B1CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A4A4A4FAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3 -ADADADD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F79F9F9FDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEAAAAAADBDBDBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C5C5C5B0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A7A7A7E2E2E2FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9B9B9BEAEAEAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE3E3E3A8A8A8E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB6B6B6BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD -A8A8A8EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29D9D9D -F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF0F0F0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA7A7A7D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFED0D0D0AEAEAEF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD3D3D3A5A5A5FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEC9C9C9B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F69D9D9DE0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC3C3C3 -B8B8B8FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBBBBBBBFBFBFFCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC -9A9A9AEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B6B6B6C5C5C5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB2B2B2C3C3C3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF7F7F7B0B0B0CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDFDFDF9E9E9EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ADADAD -D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA5A5A5D3D3D3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFA9A9A9DADADAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFA9A9A9FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A9A9A9E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F4F4F49E9E9EE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E3A8A8A8E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B5B5B5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA9A9A9 -ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE9E9E99C9C9CEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF0F0F0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB0B0B0 -C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD0D0D0AFAFAFF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA0A0A0F7F7F7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFECACACAB3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9A3A3A3D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC3C3C3B9B9B9 -FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCAAAAAAFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBBBBBBBFBFBFFCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF2F2F29B9B9BE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F9B6B6B6C5C5C5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BABABAB9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6B0B0B0CDCDCDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E89B9B9BF1F1F1FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ADADADD3D3D3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEACACACCACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAAAAAAD9D9D9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAA1A1A1 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEAEAEAA8A8A8E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A1A1A1DADADAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E4E4E4A7A7A7E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC9C9C9ADADADFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA9A9A9EDEDED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19C9C9CE7E7E7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF2F2F2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD0D0D0AFAFAFF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5 -9C9C9CF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -C9C9C9B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCAAAAAACCCCCCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC2C2C2B9B9B9FBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD7D7D7A3A3A3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBCBCBCBEBEBEFCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7A0A0A0DCDCDC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F9B6B6B6C6C6C6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6B0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 -B1B1B1CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EEEEEE9C9C9CE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ADADADD3D3D3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BFBFBFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAAAAAADADADAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE2E2E29E9E9EF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEAEAEAA8A8A8E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA7A7A7 -D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 -A8A8A8E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A5A5A5FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA9A9A9EDEDEDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF5F5F59E9E9EDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6ABABABF1F1F1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B2B2B2FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD0D0D0AFAFAFF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECECEC9A9A9AEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC9C9C9 -B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B3B3B3C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC2C2C2B8B8B8FBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E09E9E9EF6F6F6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBCBCBCBFBFBFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBA5A5A5D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFAB5B5B5C6C6C6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFA8A8A8 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B9B9B9B5B5B5FFFFFFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFEF6F6F6B0B0B0 -CCCCCCFEFEFEFEFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFEFEFEF4F4F49C9C9CE2E2E2FFFFFFFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFFFFFFC2C2C2ACACACFFFFFF -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFFFFFFB2B2B2BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C67272728D8D8D8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D8D8D8080806262627777778C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C6D6D6D6161618B8B8B8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8D8D8D7676766E6E6E8D8D8D8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D8D8D727272C8C8C8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEFEFEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEEEEEEE4E4E49C9C9CC9C9C9EFEFEFEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEEEEEED9D9D98F8F8FE2E2E2EEEEEE -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEEEEEEEFEFEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEFEFEFFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEBEBEBA9A9A9E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEB1B1B1C5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A8A8A8 -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD -A0A0A0F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEA8A8A8EDEDEDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA5A5A5D5D5D5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6ACACACF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCDCDCDAAAAAAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD0D0D0AEAEAEF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F39D9D9DE4E4E4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9B3B3B3 -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC2C2C2B9B9B9FAFAFAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E8E8E89B9B9BF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBBBBBBBBFBFBFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDADADADC8C8C8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F9F9F9B6B6B6C5C5C5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD9D9D9A1A1A1F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6B0B0B0CDCDCD -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A1A1A1 -D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ACACACD4D4D4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ACACACFDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFEFEFAAAAAADADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF0F0F09B9B9BE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEAA8A8A8E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BCBCBCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A7A7A7E6E6E6 -FFFFFFFFFFFFFFFFFFFFFFFFE5E5E59C9C9CF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEA9A9A9EBEBEBFFFFFFFFFFFFFDFDFD -AAAAAACDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD7D7D7ABABABF1F1F1FFFFFFD6D6D6A4A4A4FAFAFAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D0D0D0AFAFAFEEEEEEA0A0A0DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB8C8C8CAEAEAE -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC8C8C8ECECECFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - -end -%%PageTrailer -%%Trailer -%%EOF diff --git a/medtool/doc/user/doxygen/figures/NonCoincident_small.png b/medtool/doc/user/doxygen/figures/NonCoincident_small.png deleted file mode 100644 index aabe93bf2..000000000 Binary files a/medtool/doc/user/doxygen/figures/NonCoincident_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/NonOverlapping.fig b/medtool/doc/user/doxygen/figures/NonOverlapping.fig deleted file mode 100644 index 5493cdd9b..000000000 --- a/medtool/doc/user/doxygen/figures/NonOverlapping.fig +++ /dev/null @@ -1,45 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5b -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3600 4800 7200 4800 7200 6000 3600 6000 3600 4800 -2 2 2 1 4 7 50 -1 -1 3.000 0 0 -1 0 0 5 - 7425 4200 8700 4200 8700 4725 7425 4725 7425 4200 -2 2 0 0 0 2 0 -1 15 0.000 0 0 -1 0 0 5 - 4800 3900 6000 3900 6000 4050 4800 4050 4800 3900 -2 2 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6000 3900 4800 3900 4800 5700 6000 5700 6000 3900 -2 2 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3600 450 7200 450 7200 4050 3600 4050 3600 450 -2 2 2 1 2 7 50 -1 -1 3.000 0 0 -1 0 0 5 - 2250 3000 3225 3000 3225 3375 2250 3375 2250 3000 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 3225 3150 4800 3975 -2 2 0 0 0 2 1 -1 15 0.000 0 0 -1 0 0 5 - 4800 4800 6000 4800 6000 5700 4800 5700 4800 4800 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 3231 4489 4806 5314 -2 2 2 1 2 7 50 -1 -1 3.000 0 0 -1 0 0 5 - 2250 4275 3225 4275 3225 4650 2250 4650 2250 4275 -2 2 2 1 1 7 50 -1 -1 3.000 0 0 -1 0 0 5 - 7350 1725 8625 1725 8625 2625 7350 2625 7350 1725 -2 2 2 1 1 7 50 -1 -1 3.000 0 0 -1 0 0 5 - 7425 5100 8700 5100 8700 5925 7425 5925 7425 5100 -4 0 1 50 -1 0 12 0.0000 4 135 1170 7425 1950 Source Cell#0\001 -4 0 1 50 -1 0 12 0.0000 4 135 600 7425 2175 Area=9\001 -4 0 4 50 -1 0 12 0.0000 4 135 750 7500 4650 Area=1.5\001 -4 0 4 50 -1 0 12 0.0000 4 180 1140 7500 4425 Target Cell#0\001 -4 0 2 50 -1 0 12 0.0000 4 135 885 2325 3225 S00=0.125\001 -4 0 2 50 -1 0 12 0.0000 4 135 780 2325 4500 S01=0.75\001 -4 0 1 50 -1 0 12 0.0000 4 135 1170 7500 5325 Source Cell#1\001 -4 0 1 50 -1 0 12 0.0000 4 135 600 7500 5550 Area=3\001 -4 0 1 50 -1 0 12 0.0000 4 135 465 7425 2475 F0=4.\001 -4 0 1 50 -1 0 12 0.0000 4 135 675 7500 5775 F1=100.\001 diff --git a/medtool/doc/user/doxygen/figures/NonOverlapping.png b/medtool/doc/user/doxygen/figures/NonOverlapping.png deleted file mode 100644 index 471b47d91..000000000 Binary files a/medtool/doc/user/doxygen/figures/NonOverlapping.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/OverlapDEC1.fig b/medtool/doc/user/doxygen/figures/OverlapDEC1.fig deleted file mode 100644 index 31166cd1e..000000000 --- a/medtool/doc/user/doxygen/figures/OverlapDEC1.fig +++ /dev/null @@ -1,95 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5b -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 5775 5775 6750 6600 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6450 5850 6750 5850 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6450 6450 6750 6450 -2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6450 6150 6750 6150 -4 0 0 50 -1 0 12 0.0000 4 180 525 5775 5925 proc 0\001 -4 0 2 50 -1 0 12 0.0000 4 180 525 5775 6525 proc 2\001 -4 0 1 50 -1 0 12 0.0000 4 180 525 5775 6225 proc 1\001 --6 -6 2700 4050 3150 4500 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2925 4275 212 212 2925 4275 3075 4425 -4 0 0 50 -1 0 14 0.0000 4 165 120 2925 4350 0\001 --6 -6 9300 3825 9750 4275 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 9525 4050 212 212 9525 4050 9675 4200 -4 0 0 50 -1 0 14 0.0000 4 165 120 9525 4125 0\001 --6 -6 4275 3525 4725 3975 -1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 4500 3750 212 212 4500 3750 4712 3750 -4 0 1 50 -1 0 12 0.0000 4 135 105 4425 3825 0\001 --6 -6 7950 3225 8400 3675 -1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 8175 3450 212 212 8175 3450 8387 3450 -4 0 1 50 -1 0 12 0.0000 4 135 105 8100 3525 0\001 --6 -6 2775 2550 3225 3000 -1 3 0 1 2 7 50 -1 -1 0.000 1 0.0000 3000 2775 212 212 3000 2775 3212 2775 -4 0 2 50 -1 0 12 0.0000 4 135 105 3000 2850 0\001 --6 -6 8775 2475 9225 2925 -1 3 0 1 2 7 50 -1 -1 0.000 1 0.0000 9000 2700 212 212 9000 2700 9212 2700 -4 0 2 50 -1 0 12 0.0000 4 135 105 9000 2775 0\001 --6 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3975 4425 212 212 3975 4425 4125 4575 -1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 4248 2814 212 212 4248 2814 4460 2814 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 - 3600 3600 4800 4800 3600 4800 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3600 4800 2400 4800 2400 3600 3600 3600 3600 4800 -2 2 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4875 3375 3675 3375 3675 2175 4875 2175 4875 3375 -2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 - 4875 3375 4875 4650 3675 3375 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 6225 5250 6225 975 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 3075 1425 3975 1425 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 8700 1425 9525 1425 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 - 7800 4800 10200 4800 10200 2400 7800 4800 -2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 - 7800 4650 8925 3525 7800 2475 7800 4650 -2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 4 - 9000 3450 10125 2325 7875 2325 9000 3450 -2 2 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3600 3375 2400 3375 2400 2175 3600 2175 3600 3375 -4 0 0 50 -1 0 12 0.0000 4 135 105 2325 5100 0\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 4725 5100 2\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 3600 5100 1\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 2175 3750 3\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 3450 3825 4\001 -4 0 0 50 -1 0 20 0.0000 4 225 930 3075 1275 Source\001 -4 0 0 50 -1 0 14 0.0000 4 165 120 3900 4500 1\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 2175 3450 0\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 3450 3300 1\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 3825 3300 1\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 5025 3375 2\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 3750 2025 3\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 4950 2025 4\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 4950 4875 0\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 4200 2850 1\001 -4 0 0 50 -1 0 20 0.0000 4 300 885 8625 1275 Target\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 7575 4725 0\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 7500 2475 2\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 7725 5100 0\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 10125 5100 1\001 -4 0 0 50 -1 0 12 0.0000 4 135 105 10425 2400 2\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 9000 3300 0\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 7800 2175 1\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 10050 2175 2\001 -4 0 1 50 -1 0 12 0.0000 4 135 105 8700 3600 1\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 3525 2025 3\001 -4 0 2 50 -1 0 12 0.0000 4 135 105 2325 2025 2\001 diff --git a/medtool/doc/user/doxygen/figures/OverlapDEC1.png b/medtool/doc/user/doxygen/figures/OverlapDEC1.png deleted file mode 100644 index d6fbd3f0b..000000000 Binary files a/medtool/doc/user/doxygen/figures/OverlapDEC1.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D1.eps b/medtool/doc/user/doxygen/figures/SampGeo2D1.eps deleted file mode 100644 index 3d2234264..000000000 --- a/medtool/doc/user/doxygen/figures/SampGeo2D1.eps +++ /dev/null @@ -1,131 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: SampGeo2D1.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 -%%CreationDate: Mon Jul 28 11:05:25 2008 -%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) -%%BoundingBox: 0 0 844 468 -%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 468 moveto 0 0 lineto 844 0 lineto 844 468 lineto closepath clip newpath --13.4 552.9 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06299 0.06299 sc -% -% Fig objects follow -% -% -% here starts figure with depth 50 -% Polyline -0 slj -0 slc -7.500 slw -n 6982 8765 m - 6185 7386 l gs col0 s gr -% Polyline -n 225 8659 m - 225 8366 l gs col0 s gr -% Arc -n -2044.5 -6869.0 16460.0 60.0017 30.0004 arcn -gs col0 s gr - -% Arc -n -2044.5 -6869.0 18052.0 29.9999 59.9993 arc -gs col0 s gr - -% Arc -n 225.0 -5558.0 13924.0 90.0000 60.0010 arcn -gs col0 s gr - -% Arc -n 225.0 -5558.0 14216.5 60.0012 90.0000 arc -gs col0 s gr - -% Polyline -n 12210 1361 m - 13589 2157 l gs col0 s gr -% Polyline -n 7187 6501 m - 7333 6754 l gs col0 s gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D1.png b/medtool/doc/user/doxygen/figures/SampGeo2D1.png deleted file mode 100644 index 4f48e7928..000000000 Binary files a/medtool/doc/user/doxygen/figures/SampGeo2D1.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D2.eps b/medtool/doc/user/doxygen/figures/SampGeo2D2.eps deleted file mode 100644 index fbf9b8a6a..000000000 --- a/medtool/doc/user/doxygen/figures/SampGeo2D2.eps +++ /dev/null @@ -1,146 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: SampGeo2D2.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 -%%CreationDate: Mon Jul 28 11:25:21 2008 -%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) -%%BoundingBox: 0 0 844 468 -%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 468 moveto 0 0 lineto 844 0 lineto 844 468 lineto closepath clip newpath -0.8 467.8 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06299 0.06299 sc -% -% Fig objects follow -% -% -% here starts figure with depth 50 -% Arc -7.500 slw -0 slc -n -2269.5 -8219.0 16460.0 60.0017 58.7158 arcn -gs col0 s gr - -% Arc -n -2269.5 -8219.0 16460.3 58.7158 55.4365 arcn -gs col0 s gr - -% Arc -n -2269.5 -8219.0 16459.1 55.4365 30.0004 arcn -gs col0 s gr - -% Arc -n -2269.5 -8219.0 18052.0 29.9999 59.9993 arc -gs col0 s gr - -% Arc -n 0.0 -6908.0 13924.0 90.0000 60.0010 arcn -gs col1 s gr - -% Arc -n 0.0 -6908.0 14216.5 60.0012 63.7954 arc -gs col0 s gr - -% Arc -n 0.0 -6908.0 14217.2 63.7954 90.0000 arc -gs col0 s gr - -% Polyline -0 slj -n 11985 11 m - 13364 807 l gs col0 s gr -% Polyline -n 6757 7415 m - 5960 6036 l gs col0 s gr -% Polyline -n 6962 5151 m - 7068 5335 l gs col0 s gr -% Polyline -n 7068 5335 m - 7108 5404 l gs col0 s gr -% Polyline -n 0 7309 m - 0 7016 l gs col1 s gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D2.png b/medtool/doc/user/doxygen/figures/SampGeo2D2.png deleted file mode 100644 index 46fb25444..000000000 Binary files a/medtool/doc/user/doxygen/figures/SampGeo2D2.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D3.eps b/medtool/doc/user/doxygen/figures/SampGeo2D3.eps deleted file mode 100644 index 71fd7b3d6..000000000 --- a/medtool/doc/user/doxygen/figures/SampGeo2D3.eps +++ /dev/null @@ -1,146 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: SampGeo2D3.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 -%%CreationDate: Mon Jul 28 11:18:27 2008 -%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) -%%BoundingBox: 0 0 844 468 -%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 468 moveto 0 0 lineto 844 0 lineto 844 468 lineto closepath clip newpath -0.8 467.8 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06299 0.06299 sc -% -% Fig objects follow -% -% -% here starts figure with depth 50 -% Arc -7.500 slw -0 slc -n -2269.5 -8219.0 16460.0 60.0017 58.7158 arcn -gs col0 s gr - -% Arc -n -2269.5 -8219.0 16460.3 58.7158 55.4365 arcn -gs col0 s gr - -% Arc -n -2269.5 -8219.0 16459.1 55.4365 30.0004 arcn -gs col0 s gr - -% Arc -n -2269.5 -8219.0 18052.0 29.9999 59.9993 arc -gs col0 s gr - -% Arc -n 0.0 -6908.0 13924.0 90.0000 60.0010 arcn -gs col1 s gr - -% Arc -n 0.0 -6908.0 14216.5 60.0012 63.7954 arc -gs col2 s gr - -% Arc -n 0.0 -6908.0 14217.2 63.7954 90.0000 arc -gs col1 s gr - -% Polyline -0 slj -n 11985 11 m - 13364 807 l gs col0 s gr -% Polyline -n 6757 7415 m - 5960 6036 l gs col0 s gr -% Polyline -n 6962 5151 m - 7068 5335 l gs col1 s gr -% Polyline -n 7068 5335 m - 7108 5404 l gs col2 s gr -% Polyline -n 0 7309 m - 0 7016 l gs col1 s gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D3.png b/medtool/doc/user/doxygen/figures/SampGeo2D3.png deleted file mode 100644 index da88cb57a..000000000 Binary files a/medtool/doc/user/doxygen/figures/SampGeo2D3.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D4.eps b/medtool/doc/user/doxygen/figures/SampGeo2D4.eps deleted file mode 100644 index 036447b2b..000000000 --- a/medtool/doc/user/doxygen/figures/SampGeo2D4.eps +++ /dev/null @@ -1,114 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: SampGeo2D4.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 -%%CreationDate: Mon Jul 28 11:32:45 2008 -%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) -%%BoundingBox: 0 0 844 521 -%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 521 moveto 0 0 lineto 844 0 lineto 844 521 lineto closepath clip newpath -0.5 522.3 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06299 0.06299 sc -% -% Fig objects follow -% -% -% here starts figure with depth 50 -% Arc -7.500 slw -0 slc -n -101040.6 -197010.0 228811.3 60.0003 63.7947 arc -gs col2 s gr - -% Arc -n -137567.0 -218110.0 264913.0 58.7153 55.4354 arcn -gs col2 s gr - -% Polyline -0 slj -n 12727 42 m - 13364 1147 l gs col2 s gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/medtool/doc/user/doxygen/figures/SampGeo2D4.png b/medtool/doc/user/doxygen/figures/SampGeo2D4.png deleted file mode 100644 index dd630fd17..000000000 Binary files a/medtool/doc/user/doxygen/figures/SampGeo2D4.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-0.png b/medtool/doc/user/doxygen/figures/UML-0.png deleted file mode 100644 index ce143b48d..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-0.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-1.png b/medtool/doc/user/doxygen/figures/UML-1.png deleted file mode 100644 index f5b8fcf07..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-1.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-2.png b/medtool/doc/user/doxygen/figures/UML-2.png deleted file mode 100644 index 30940d893..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-2.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-3.png b/medtool/doc/user/doxygen/figures/UML-3.png deleted file mode 100644 index dbb152466..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-3.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-4.png b/medtool/doc/user/doxygen/figures/UML-4.png deleted file mode 100644 index 0c78ad753..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-4.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-5.png b/medtool/doc/user/doxygen/figures/UML-5.png deleted file mode 100644 index f251b5a59..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-5.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-6.png b/medtool/doc/user/doxygen/figures/UML-6.png deleted file mode 100644 index 9cdcfaa75..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-6.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-7.png b/medtool/doc/user/doxygen/figures/UML-7.png deleted file mode 100644 index d316de52c..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-7.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML-8.png b/medtool/doc/user/doxygen/figures/UML-8.png deleted file mode 100644 index a43d2c1b7..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML-8.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML.png b/medtool/doc/user/doxygen/figures/UML.png deleted file mode 100644 index 28418d122..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML_light.png b/medtool/doc/user/doxygen/figures/UML_light.png deleted file mode 100644 index 08ecacdbb..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML_light.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/UML_small.png b/medtool/doc/user/doxygen/figures/UML_small.png deleted file mode 100644 index 791728fa4..000000000 Binary files a/medtool/doc/user/doxygen/figures/UML_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/connectivity_arrays.eps b/medtool/doc/user/doxygen/figures/connectivity_arrays.eps deleted file mode 100644 index fdbdfbe38..000000000 --- a/medtool/doc/user/doxygen/figures/connectivity_arrays.eps +++ /dev/null @@ -1,19480 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: (ImageMagick) -%%Title: (connectivity_arrays.eps) -%%CreationDate: (Thu Nov 29 18:16:01 2007) -%%BoundingBox: 0 0 720 540 -%%HiResBoundingBox: 0 0 719.91 540 -%%DocumentData: Clean7Bit -%%LanguageLevel: 1 -%%Pages: 1 -%%EndComments - -%%BeginDefaults -%%EndDefaults - -%%BeginProlog -% -% Display a color image. The image is displayed in color on -% Postscript viewers or printers that support color, otherwise -% it is displayed as grayscale. -% -/DirectClassPacket -{ - % - % Get a DirectClass packet. - % - % Parameters: - % red. - % green. - % blue. - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/DirectClassImage -{ - % - % Display a DirectClass image. - % - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { DirectClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayDirectClassPacket } image - } ifelse -} bind def - -/GrayDirectClassPacket -{ - % - % Get a DirectClass packet; convert to grayscale. - % - % Parameters: - % red - % green - % blue - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/GrayPseudoClassPacket -{ - % - % Get a PseudoClass packet; convert to grayscale. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassPacket -{ - % - % Get a PseudoClass packet. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassImage -{ - % - % Display a PseudoClass image. - % - % Parameters: - % class: 0-PseudoClass or 1-Grayscale. - % - currentfile buffer readline pop - token pop /class exch def pop - class 0 gt - { - currentfile buffer readline pop - token pop /depth exch def pop - /grays columns 8 add depth sub depth mul 8 idiv string def - columns rows depth - [ - columns 0 0 - rows neg 0 rows - ] - { currentfile grays readhexstring pop } image - } - { - % - % Parameters: - % colors: number of colors in the colormap. - % colormap: red, green, blue color packets. - % - currentfile buffer readline pop - token pop /colors exch def pop - /colors colors 3 mul def - /colormap colors string def - currentfile colormap readhexstring pop pop - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { PseudoClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayPseudoClassPacket } image - } ifelse - } ifelse -} bind def - -/DisplayImage -{ - % - % Display a DirectClass or PseudoClass image. - % - % Parameters: - % x & y translation. - % x & y scale. - % label pointsize. - % image label. - % image columns & rows. - % class: 0-DirectClass or 1-PseudoClass. - % compression: 0-none or 1-RunlengthEncoded. - % hex color packets. - % - gsave - /buffer 512 string def - /byte 1 string def - /color_packet 3 string def - /pixels 768 string def - - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - x y translate - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - currentfile buffer readline pop - token pop /pointsize exch def pop - /Times-Roman findfont pointsize scalefont setfont - x y scale - currentfile buffer readline pop - token pop /columns exch def - token pop /rows exch def pop - currentfile buffer readline pop - token pop /class exch def pop - currentfile buffer readline pop - token pop /compression exch def pop - class 0 gt { PseudoClassImage } { DirectClassImage } ifelse - grestore -} bind def -%%EndProlog -%%Page: 1 1 -%%PageBoundingBox: 0 0 720 540 -userdict begin -DisplayImage -0 0 -719.91 539.933 -12.000000 -960 720 -1 -1 -1 -8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 -000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000 -FFFFFFFFFFFF0000FFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFF -FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00 -00FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF00000000FFFFFF000000FFFFFF -FF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF00 -00FFFFFFFF0000FFFFFFFF000000FFFFFFFFFF000000FFFF0000FFFFFFFFFFFF000000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF00 -00FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF -0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -0000FFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000FF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFF00 -00FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFF00 -000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFF0000FF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FF000000000000FFFFFFFFFFFF0000 -0000000000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FF00000000FFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF -FF0000FFFFFFFF00000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF00 -000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF000000FFFF -FFFFFF000000FFFF0000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF0000FF000000000000FFFFFFFF -FFFF00000000000000FFFFFFFFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFF -FFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFF -0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF -FFFFFFFF0000FFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FF -0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF000000FFFF -FFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF00000000FFFFFF000000FFFFFFFF000000 -FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000 -00FFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF00 -000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97EF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20BFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFDF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF10AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC700E7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF009F -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB700DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE70087FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF8F00AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDF007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF504070FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF0060 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10BF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2840FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFBF40FF20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF609710F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFF7F7FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20DF40 -BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7FFDF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF20FF708FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF7F7FFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9F60FFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE720F7FFFFFFE720F7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFEF -18F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFF7887FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7FFFF50AFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFAF50FFFFFFFFFFFFF740C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9768FFFFFFBF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE730E7FFFFFFFFFFFFFFD730 -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFF -FF28D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF748BFFFFFFFFFFFFFFFFFFFA758FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFF8F70FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF750 -B7FFFFFFFFFFFFFFFFFFFFFF9768FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF6897FFFFFFFFFFEF18F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7589FFFFFFFFFFFFFFFFFFFFFFFFF -FF7F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFF -FFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFDF38A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F40EFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF30CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9768FFFFFFFFFFFFFFFFFFC738FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9740EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDF38AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFFFF -FFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFEF6868FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7507FF7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF750B7FFFFFFFFFFFFFFFFFFFFFFEF40CFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F2897FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F28A7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFDF40DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFAF2870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFDF5838BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDF30EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 -4050D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC740 -50D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF787FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF38E7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB75038BFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2868C7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE738 -87FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF28B7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD7701848AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF9738207FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF28C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF4878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE78F28288FE7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDF7F203897EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFB75050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 -3097EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFD7A778381870D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC76810407F -AFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F2048AFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7682068D7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFAF7F400828 -5887C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF7F502010487FB7E7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFAF7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F5840101070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF97280038407F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F9FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFBFBFBFAF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7040404020000020507FBFF7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFEFB77F4818000028404040787F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7FB7BFBFCFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFA750080040507F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7FA7BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC7BF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F604018003887E7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC797684018000000404040507F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F8F -BFBFBFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD7BFBFBF877F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F -7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F484040300000002040709FCFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1858 -AFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7782060C7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFCF9F703800386897BFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFDFBF8F6030084078A7D7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F207FE7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF79F3858EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7701830608FC7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7BF8758282887E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFEF5860F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFA738C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFE79730288FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 -7818489FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC730A7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7408FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7501868CFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7601060BFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF38DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7707FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB73058AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F4040CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFDF30EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFCF4048CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFBF3058DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE738DFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE76030BFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA72870 -EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEF40CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF750B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF7F209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F2097FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE728EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF507F -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEF6868F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC738FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD738AFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF9748EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF738CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFB738D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF30CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8778 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F48EFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF38AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE720F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609F -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF7509FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48B7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18E7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF38C7FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF748BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 -58FFFFFFFFFFFFFFFFFFFFFFFFFFC740F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFE730E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FFFFFFFFFFFFFFFFFFFF -FFEF30DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE718FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF7887FFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AF50FFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFEF28E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFF -40BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F -70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFBF40FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF6897FFFFFFFFFFFFFFFF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFEF18 -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D728FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFD728FFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFDF20FFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000 -0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF30CF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40BFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 -000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF08F7FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 -0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD728FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF20DFFFFFFFFFFFDF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE718FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFCF30FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF000000FF -FFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FF0000000000FFFFFFFFFFFF0000FFFF000000FFFFFF00000000FFFFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF87E7FFFFFFFFFFDF8FFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000 -FFFFFFFFFFFF0000FFFF000000FFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFF -FFFF0000FFFF000000FFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF000000 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFF00000000000000FFFFFFFFFF0000000000000000FF000000000000FFFFFFFFFF -FFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF -0000000000000000FF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF000000000000 -0000FF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF0000000000000000FF00 -0000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000 -FFFFFFFF000000FFFFFF00000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF00000000FFFF -FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF00000000FFFFFF000000FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FF000000FFFFFF000000FFFFFFFF000000FFFFFF00000000FFFFFF000000FFFFFFFFFFFF -FFFFFFFFFF00000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 -0000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFF00 -00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFF0000FFFFFF0000 -FFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF000000000000000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF -000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF000000000000000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF000000FF -FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFF0000FF -FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF000000000000000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF -0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 -00000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFF -FF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000 -000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF00000000000000000000 -00FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFF0000000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFF0000000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -0000000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFF0000000000000000000000FFFFFF0000FFFFFFFFFF00 -00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000 -000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000000000000000 -000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000000000000000000000FF -FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFF -FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF00 -00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000 -00FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFF -FF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF000000FF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FF -FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF -0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFF -FF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFF0000FF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFF00000000000000FF -FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000 -0000FFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF00 -00FFFFFFFFFF00000000000000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFF -FFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFF -FFFF00000000000000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000FFFFFFFF00FFFFFFFF000000FFFF -FFFF00FF000000FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 -000000000000FFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFFFFFFFF00 -00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFF -FF0000000000FFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFF0000000000 -FFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF00 -00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFF -FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FF0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000FFFFFF0000FFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00 -FFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 -FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00000000000000FFFF00FFFF00000000000000FFFF00FFFFFFFF00FFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFF00FFFF00FFFFFFFFFFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 -FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF -FFFF00FFFFFFFF000000FFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF409F -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF700F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF409FFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF6868FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF00DFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8F30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF308FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF6060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC700C7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF207F -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5858FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFB700B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0860FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF3030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F107FFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF3808D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCF1030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF0808F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF407F40FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710589FFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA75808 -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD72830CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF710EF10F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF409F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708F38C7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F60708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FF38C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF7F7FD728FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF20DF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF58A7B748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFAF50FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FF50AFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD728FFCF -30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7F710F7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE718FFFFFF18E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFF20DFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFAF50FFFF50AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFF8F -70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF30CFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF720E7FFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -40BFFFFFBF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC738FFFFFFFFF738CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9768FFFFFFFFC738FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFFFF -F720E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFF30CFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF730D7FFFFFFFFFFCF38F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FFFFFFFF8778FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF48B7FFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFF -FF8778FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 -AFFFFFFFFFFFFFE738DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF6897FFFFFFFFFFFF40BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70 -FFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFDF40DFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFF -FFFFE728DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC740F7FFFFFFFFFFFFF740C7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFEF589FFFFFFFFFFFFFFFFFFFFFFF7F60EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFEF589FFFFFFFFFFFFFFFFFFFFFDF30C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50F7FFFFFFFFFFFFFFFFD740DFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFC740EFFFFFFFFFFFFFFFFFEF40CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB728A7FFFFFFFFFFFFFFFFFF -FFFFFFFF9F28B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB728A7FFFF -FFFFFFFFFFFFFFFFFFFFD73878FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFDF5050F7FFFFFFFFFFFFFFFFFFFFDF287FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE76838EFFFFF -FFFFFFFFFFFFFFFFEF3068E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF972848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7482897EFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F3848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -871878DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B77F50404040404040404040404040404040404040 -404040404040404040404040404040404040404040404040402820AFFFFFFFFFFFFFFFFF -FFFFFFFFFFF77F0838404040404040404040404040404040404040404040404040404040 -404040404040404040404040404040406887CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFC77F584040404040404040404040404040404040404040404040404040 -4040404040404040404040404040404040301897FFFFFFFFFFFFFFFFFFFFFFFFFFFF9718 -304040404040404040404040404040404040404040404040404040404040404040404040 -4040404040404040607FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFDFB77F78404040404040404040404040404040404040404040404040404040404040 -4040404040404040404040404040404040404040404040404040404040404040181068D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD768101840404040404040404040404040 -404040404040404040404040404040404040404040404040404040404040404040404040 -40404040404040404040404040787FB7DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDFAF7F704040404040404040404040404040404040404040 -404040404040404040404040404040404040404040404040404040404040404040404040 -404040280860C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE787201040404040404040 -404040404040404040404040404040404040404040404040404040404040404040404040 -40404040404040404040404040404040587F97C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFAF28487FAFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7BFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBF97783048D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF38387FA7BFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF9F7F3838 -C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA74820487F87BFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFE7BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BF877F482048A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB750 -20507F8FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFD7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFA77F68382097EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F50DFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB730B7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F40C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7389FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFD73858B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB75838D7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF4848AFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6828C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF707FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF750B7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F30C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7309FFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFBF28B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE73887FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8770 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF730D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF40BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9760F7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF7609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB748E7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF787FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF38F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC738 -FFFFFFFFFFFFFFFFFFFFFFFFFFEF28E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609F -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF40EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFF -FF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE728EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE720F7FFFFFFFFFFFFFFFFFFFFDF20FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF18E7FFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE730E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58A7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF28E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -708FFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFFFFFFFFFF -FFFFFFFFFF48B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A758FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA758FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD728FFFFFFFFFFFFFFFFFFF7 -10F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7FFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF20DFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF58A7FFFFFFFFFFFFFFFFFF48B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7887FFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFF -FFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF720E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FFFFFFFFFFFFFFFF20 -DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFF7887FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8778FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFDF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB748FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF20DFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF18E7FFFFFFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFF -FFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF10EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFE718FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48B7FFFFFFFFFFFF8778 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7887FFFFFFFFFFFFAF50FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20DFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40BFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9F60FFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF7887FFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFF -FFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFF50AF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFF609FFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7887FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20E7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF877FFFFFFFFFFFFF40C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBF48FFFFFFFFFFFF40C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF48FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF877FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF7EFFFFFFFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFF -FFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF300000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000090000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000900000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000900 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000003030000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000009000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000009000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -090000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000090000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000090000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000900000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000900000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000030FFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F00 -00007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000 -007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000000C000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000090000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000090000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000090000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000007FFFFF7F -7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF -7F00000040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF100000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000010000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000100000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000100 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000001010000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000001000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000001000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -010000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000010000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000010000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000100000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000100000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000010FFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F00 -00007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000 -007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F00000004000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000010000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000010000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000010000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000007FFFFF -7F7FFFFF7F0000007BBFBF5F5FBFBF5F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFF -FF7F000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF8F7F4028009FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF300000 -0000000008C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF72800000000000030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF0000000000008FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CF080000000000AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF280000000058FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F0000000038FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF302800 -000028F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE74808000000CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2048BFFF200010D7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F -1887E7100050FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF78F1858CFFFFFFF8F00AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028CFFFFFA700CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1060DFFFFFFFFFFFF7 -87FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9FCFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCFBFBFAF7F7F7F60EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFB71878F7FFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE7701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF730F7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE74040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFEF9F500008EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA700 -00000000000087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6010 -7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF8F008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF18 -0040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9F5000000000 -48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38000000000030F7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF58188FF7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7180018F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8700000040FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7480000000000009FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCF0000000008CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF8710AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBF48209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F0000008FFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFEF480000000040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF7480000000008EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD748 -0800000078FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3830AFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF71800000018F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1800000000 -0040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72800000048 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF78108FE7180028F7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F1097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F2840BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F0000000000 -8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF600000000040FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F204000009FFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF971868E7FFFF9700C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 -4838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F -2050C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718000000000018F7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF7F20000040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF7F20DFF74808EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFF -FFFF97FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7107FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1860D7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFD77F7F7F007F7F7FD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFDF -6040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFF78FFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE7701870DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFEFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF7871878EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC71870F7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF68187FE7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFCF60188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFDF4820B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFD72858EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BF50209FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7781887 -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF40309FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F -20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE73840E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9F3040AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFCF3830C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972050BFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF681897FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5038D7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F1860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFE77F1868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BF2840D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76028C7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF701878E7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75018AFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD760187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF7818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750208FF7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2050E7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB740289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74028BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA73038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E74838DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48BFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971868EFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC73038CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF6028CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE758 -18A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871878EFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF0000FFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFB72848DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718 -CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718AFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF -000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFA71860E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F1097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF -00000000FFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFF -FFFFFF0000000000FFFFFF00000000000000FFFF0000FF0000FFFFFFFFFFFFFF0000FFFF -0000FF00000000000000FF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF00000000000000FFFFFFFFFF0000FF000000000000FFFFFFFFFF0000 -FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFFFF00000000000000FFFF00 -000000000000FFFF0000FF0000FFFFFFFFFFFFFF0000FFFF0000FF00000000000000FF00 -00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFB7107FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF -FF000000FFFFFFFF00000000FFFFFF000000FFFFFFFF00000000FFFFFF000000FFFFFFFF -000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFF0000FFFFFFFFFF0000FFFF -0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070 -EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FFFFFF000000FF -FFFFFFFF0000FFFFFFFF000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF000000FFFF -000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF -0000FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF2848D7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72070F7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000 -FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFFFF -0000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFDF5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00 -00000000000000000000FFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFF -FF0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD72858EFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFF -FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000000000000000000000FFFF -0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF -0000FFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF1858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000 -FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF -FF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20 -DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CF4030BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFE73840E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFF -FFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFF -FFFF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF000000FFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF0000FFFF -FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFF -000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF -0000FFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF971068EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFEF5030D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF -000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000 -FFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFF000000FFFF -FF0000FFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF -FFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878 -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000FFFFFFFFFFFF00000000 -000000FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF -FF00000000000000FFFFFFFFFFFF00000000000000FFFFFFFF0000000000FFFF0000FFFF -FFFFFF000000FFFFFFFFFFFF0000FFFFFF0000000000FFFFFFFFFF000000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76028C7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF -FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFF -FFFFFF0000000000FFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF00FFFFFFFFFFFFFF -0000FFFFFFFF00000000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF7871078F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72050DFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7818B7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF78 -1087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1860E7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F -20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028 -CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF871078EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F -50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF77818BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF5020B7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF7781087F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858 -E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFAF3030AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030BFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1097FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2040BFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFEF681097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF78F2050C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB710 -7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F -1860D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7701870DFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E75818AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFC72068F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDF60187FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF58188FEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73058EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF482097F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF20CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828BFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AF40309FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE73840E7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F3040AFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF971868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF7972050BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF50 -30D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF871860CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE76018A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7781868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF787 -1878EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF76828C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFDF681870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD760187FEFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFDF4828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC750208FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB740289FFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F189FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA73038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFCF3830C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF79F2048BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF681897FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 -1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F1850CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20 -DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028CFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFE77F1060DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF2840 -D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7701070 -E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75020AFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60107FEFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFCF50188FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF1850E7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40209FFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFD74028BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFAF3030AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20 -40B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971868EFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 -4838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F1850C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC73038CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7107FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFEF7F1860D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7701870DFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72068F7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFDF60187FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F -20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFB72048DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF -58188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFD73050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF482097F7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFAF38309FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F -1860E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE73840E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2840AFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972050BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5030D7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EF871860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1078EFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7781868DFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F18DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76820C7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFDF681870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFDF5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF60187FEFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF7818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF50208FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFB740289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030 -BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA73038AFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF79F2048BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF971070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71887FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F1850CF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1060DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 -AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF1878F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDF701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7871078F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60107FEFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCF50188FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718A7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4020 -9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781087FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3030AFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF9F2040B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F1850C7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFB7187FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEF7F1060D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF871078EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE770 -1070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 -2848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72068F7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60187FE7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10 -CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF4820B7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCF58188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF7781087F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73050EFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF482097F7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF38309FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFE74040E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F2840AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFEF681097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F2050BFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFEF5030D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFEF871860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFBF3040D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878 -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7781868DFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75018 -AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76820C7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF681870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFCF60187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F18B7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF50208FF7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828BFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAF40289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F -10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA73038AFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF971868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F2048BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF -30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838CFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFA71887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFEF8F1850CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028 -C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1060DFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871878EF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF1878F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFDF701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD760107F -EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDF4828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750188FF7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFBF40209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3030AFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF -3838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F188FFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9F2040B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F18 -50C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB718 -78FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1060D7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF2840D7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFE7701070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFC72068F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60107FE7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFCF58188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF1850E7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF -482097F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFD74030BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF38309FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7010 -8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74038E7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9F2840AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971068EFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F2050BFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC73038CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF58 -30D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E7701868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871078F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF76820C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF681870E7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB72048DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFCF60187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F10B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF50208FF7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF781887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF40289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10 -CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1860E7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97189FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF9F3038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972048BFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 -1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF8F1850CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF871078EFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1060DF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFBF1878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF -5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD760107FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F1087F7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF2860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750188FF7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFB740209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030BFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3030 -AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2040B7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 -4838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF78F1850C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F -10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1060D7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE7701070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78710 -7FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72868F7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60 -107FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF50188FEFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFD73050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBF402097F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF78108FFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF38309FFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE74038E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2840AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 -8F2050BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5828D7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1860CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF871878EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE7701868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76820C7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF601870E7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF4820B7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF60187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF7781887F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF7F10B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBF50208FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF40289FFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFCF3830C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF97109FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9F3038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 -AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF -681097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972048BFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71887FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF871850CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFBF3040D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFE7781060DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75018AFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF1878F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF701070E7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFD760107FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFAF2050E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFCF2860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750188F -F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74028BFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB740209FFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFA73030AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9718 -68E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F2040B7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF300000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000090000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000900000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000900 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000003030000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000C0000007FFFFF7F0000007FFFFF7F0000007F -FFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFF -FF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF -300000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000090000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000090000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000007FFFFF7F7FFFFF -7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000 -007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF -DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF100000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000010000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000100000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000100000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000001010000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000040000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000 -007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F000000 -7FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF100000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000010000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000010000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F -0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF730F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72808FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F008FFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFEF68000020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7180018F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71800000038 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8F0000008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE758000000000040FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71800000018F7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF77F080000000060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF8F87CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F00000000008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73800000070 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F00001860A7 -EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF718000000000018F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7188718007FFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF000000000000389FFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD77F7F7F007F7F7FD7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF7858FFF7789FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFE7A700000000000048EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD710E7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401010401000000000 -7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF488FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7BF8F68380028507FB7E7FFFF50000018BFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFAF30F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280038688FBFF7 -FFFFFFFFFFFFFF870038E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718C7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFCFA7784010104078A7CFFFFFFFFFFFFFFFFFFFFFFFFFFFAF78FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F68380028507FB7 -E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFCF18E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE7B77F50280040688FBFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF408FFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401010407F -A7CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFA730FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF7BF8F68380028507FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F718C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280040 -688FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7060FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCFA778401010407FA7CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCF18E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F683800 -28507FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 -8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280040688FBFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA730FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77840 -1010407FA7CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F68380028507FBFE7FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7068FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F -50280040688FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF18E7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401010407FA7CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF3897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF -8F68380028507FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F30FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280040688FBFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF18CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CFA778401018407FA7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF7068FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F68380028587FBFE7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF18E7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFE7B77F502800406897BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFF0000000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401018407FA7D7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00000000 -00FFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFFFF -FF0000000000FFFFFFFFFFFFFFFF0000000000FFFFFF00000000000000FFFF0000FF0000 -FFFFFFFFFFFFFF0000FFFF0000FF00000000000000FF0000FFFFFFFFFFFF0000FFFFFF00 -00FFFFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF00 -00000000FFFFFFFF000000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FF000000000000FFFFFFFFFF0000FFFFFF000000000000000000FFFFFFFFFFFF00000000 -00FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFF00000000 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF000000FF0000FFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9F38FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF7BF8F68380028587FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFFFF0000FF0000 -00000000FFFFFFFFFF0000FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFF -FF00000000000000FFFF00000000000000FFFF0000FF0000FFFFFFFFFFFFFF0000FFFF00 -00FF00000000000000FF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000FF00000000 -0000FFFFFFFFFFFF000000000000000000FFFFFFFFFF00000000000000FFFFFFFF0000FF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000000000FFFFFFFF -0000FFFFFF000000000000000000FFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF18CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F502800406897BFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF000000FFFFFF000000FFFFFFFF00000000FFFFFF000000FFFFFFFF000000 -00FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFF -0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF0000 -FFFFFFFFFF0000FFFFFFFF0000FFFFFFFF00000000FFFFFF000000FFFFFFFF000000FFFF -FF00000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF000000FFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFF000000FFFFFFFF000000FFFFFF0000FFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6870FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFCFA778401018407FA7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF -FF000000FFFFFF000000FFFFFFFFFF0000FFFFFFFF000000FFFFFFFFFF0000FFFFFF0000 -FFFFFFFFFFFF000000FFFF000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFF00 -00FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFF00 -00FFFFFFFF000000FFFFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF0000FFFF -FFFFFFFF000000FFFFFF000000FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF00 -00FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFF000000FFFFFFFF0000FFFFFFFFFF -FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFCF18EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F68380028587FBFE7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFF -FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF00 -00FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF00 -00FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFF -FF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF00 -00FF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -00000000000000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF309FFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFE7BF7F502800406897BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FF -FFFFFFFFFF0000FFFFFF0000000000000000000000FFFF0000FFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF -FFFFFF0000FFFFFF0000000000000000000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFF000000000000FFFFFFFFFFFF0000FFFFFFFFFFFF000000FF -FFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFF -FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF9738FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018407FA7D7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000 -000000000000000000FFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFF00 -00FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF00000000 -00000000000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FF00000000000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFF00000000000000 -00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFBF8F68400028587FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFF -FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF -FF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFF -0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6870FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502800406897BFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FF -FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF -FF0000FF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF -FFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFF000000FFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCF18EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFCFA77F401018407FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFF -FF000000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000 -00FFFFFFFFFFFF0000FFFF000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFF -FF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFFFFFF00 -00FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF000000FFFFFF000000FF -FFFFFFFFFF0000FFFFFF000000FF000000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF00 -00FFFFFFFFFFFF0000FFFFFF0000FFFFFF000000FFFFFFFFFFFFFFFFFF000000FFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 -A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F68400030587FBF -EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF000000FFFFFFFFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF -FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF -0000FFFFFFFF000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF -FF0000FFFFFFFF000000FFFFFF00000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000 -FFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFF000000FFFFFF -0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9740FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE7BF7F502800407097BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000 -00FFFFFFFFFFFF00000000000000FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FF -FFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFFFF00000000000000FFFFFFFF -0000000000FFFF0000FFFFFFFFFF000000FFFFFFFFFFFF0000FFFFFF0000000000FFFFFF -FFFF000000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF00000000 -0000FF0000FFFFFFFFFF00000000000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFF0000000000000000FFFFFFFF0000FFFF0000000000000000 -0000FFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFF00FFFFFFFF000000FFFF -FFFF00FF000000FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE720CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018407F -AFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFF00000000 -00FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF -FF0000000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF00000000FFFF0000FFFFFF -FFFFFF00FFFFFFFFFFFFFF0000FFFFFFFF00000000FFFFFFFFFF0000FFFFFFFFFFFFFF00 -00FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF00 -00000000FFFFFFFF000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FF000000000000FFFFFFFFFF0000FFFF00000000000000000000FFFFFFFFFFFF00000000 -00FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -0000FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000FFFFFF0000FFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6870FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFBF8F68400030587FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00 -FFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC718F7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F50280040 -7097BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 -FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF30A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018407FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00000000000000FFFF00FFFF00000000000000FFFF00FFFFFFFF00FFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F40FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F684000 -30587FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFF00FFFF00FFFFFFFFFFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502800407097BFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 -FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF6078FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F40 -1018407FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FFFFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC718F7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F68400030587FBFEFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF -FFFF00FFFFFFFF000000FFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F -502800407097BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF8F48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018487FAFD7FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE718D7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF -8F684000305887BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6078FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502808407097C7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFBF18F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CFA77F401018487FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF730AFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F684000305887BFEFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF8F48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFE7BF7F502808407097C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E710D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018487FAFD7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF587FFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFBF8F684000305887BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFBF20F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502808407097C7FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF730 -AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFCFA77F401018487FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F684000305887BFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE710DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFE7BF7F582808407097C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF587FFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A77F401820487FAFD7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF20F7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFBF97684000306087BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF728AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F58280840709FC7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8750FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFD7A77F401820487FAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE710E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF97684000306087BF -EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF5087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE7BF7F58280840709FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB728F7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A77F401820487F -AFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF728B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFBF97684000306087BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF8750FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F58280840 -709FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE710E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD7A77F401820487FAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF97684000 -306087BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFB728F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F58280840709FC7FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF300000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000090000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000900000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000030FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF100000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000010000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000100000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000010FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF00000000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000 -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000 -00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFF00000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000 -0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FF0000000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF00000000FFFF -FFFFFFFFFFFF0000000000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFFFF0000FF -FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFF000000FFFFFF00000000FFFFFFFFFF -0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FF000000FFFF00 -00FFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF00000000FFFF0000FFFFFFFF0000FFFF -FFFF0000FFFF00000000FFFFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF0000000000 -FFFFFFFF000000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF000000 -000000FFFFFFFFFF0000FFFFFF000000000000000000FFFFFFFFFF0000000000FFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFF00000000FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF000000FF0000FFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF -FFFF00000000000000FFFFFFFFFF0000FF000000000000FFFFFFFFFF0000000000000000 -FFFFFFFF0000FFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF00 -00FFFFFFFF0000000000000000FF000000000000FFFFFFFF0000FF000000000000FFFFFF -FFFFFF00000000000000FFFFFFFFFF000000000000FFFF0000FFFFFF0000FF0000000000 -00FFFFFFFFFFFF000000000000FF0000FFFFFFFF0000FFFFFFFF0000FF000000000000FF -FFFFFFFF000000000000000000FFFFFFFFFF00000000000000FFFFFFFF0000FFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000000000FFFFFFFF0000FFFF -FF000000000000000000FFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFF -FFFF00000000FFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF0000FFFFFFFF0000 -FFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000FFFFFF00 -000000FFFFFF000000FFFFFF00000000FFFFFF000000FFFFFFFF000000FFFFFF000000FF -FFFFFF000000FFFFFFFFFF0000FFFFFF00000000FFFFFF000000FFFFFFFF000000FFFFFF -00000000FFFFFFFF0000FFFFFFFF00000000FFFFFF000000FFFFFF000000FFFFFF000000 -00FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF000000FFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFF000000FFFFFFFF000000FFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFF -FF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF000000FFFFFFFFFF0000 -00FFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFF0000FF -FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -000000FFFFFFFFFF000000FFFF0000FFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFFFF00 -00FFFFFF000000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF000000FFFFFFFF0000FFFF -FFFF000000FFFFFFFFFF0000FFFF000000FFFFFFFFFF000000FFFFFF0000FFFFFFFFFFFF -000000FFFFFF000000FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF -FFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFFFF000000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF00000000000000FFFFFFFF0000FFFFFF -0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFF0000FFFFFF000000FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF00 -00FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF -FF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF -0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000 -FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FF0000 -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF0000FFFF -FFFFFFFFFF000000FFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000 -0000000000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFF00000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF -FFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000000000FFFFFF0000FFFFFFFF0000 -FFFFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF -0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000 -FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF -FFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF00 -00FFFFFF0000000000000000000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFF000000000000FFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFFFF -0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF00 -00FFFFFFFF0000000000000000FFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFF0000FF -FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000FFFFFF0000FFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FFFF -FFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000000000000000 -000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF000000 -00000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000000000000000000000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFF -0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF00000000FFFFFF00 -00FFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFF0000FFFFFFFF0000FFFFFFFFFFFF00 -00FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF -FF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF -0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000 -FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFF0000FFFF -FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF -FFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000 -FFFFFFFFFFFF0000FF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF -0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF -FFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFF000000FFFFFFFFFFFFFF -0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF -FF0000FFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF000000FFFFFFFFFF0000 -FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFF00000000FF -FFFFFF0000FFFFFFFFFF000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -000000FFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF000000FFFFFFFF0000FFFF -FFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF000000FFFFFF000000FFFFFFFFFF -FF0000FFFFFF000000FF000000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF -FFFFFF0000FFFFFF0000FFFFFF000000FFFFFFFFFFFFFFFF000000FFFFFFFFFFFF0000FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF00000000FFFFFFFF0000FFFFFF -FF000000FFFFFF000000FFFFFFFF00000000FFFFFF000000FFFFFF000000FFFFFF000000 -00FFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFF000000FFFFFF000000 -00FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF00000000FFFFFF000000FFFF -FFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF -0000FFFFFFFF000000FFFFFF00000000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000 -FFFFFF000000FFFFFF00000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF00 -00FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFF000000FFFFFF0000FFFF -FF0000FFFFFFFFFFFFFFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFF0000000000000000000000FFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFF -FFFF0000FF000000000000FFFFFFFFFF000000000000000000FFFFFF0000FFFFFFFF0000 -FFFFFFFFFFFFFFFF000000FFFFFFFFFF000000000000FF0000FFFFFFFF0000FFFFFFFFFF -0000FFFFFFFFFF0000FFFFFF0000FF000000000000FFFFFFFFFFFF00000000000000FFFF -FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF0000000000 -00FF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000000000FF00 -00FFFFFFFFFF00000000000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -0000FFFFFFFFFFFF0000000000000000FFFFFFFF0000FFFF00000000000000000000FFFF -FFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF00 -00FFFFFFFFFFFF0000FFFF0000000000FFFFFFFFFF00FF00FF000000FFFFFFFFFFFF0000 -00FFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FF -FFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF00000000FFFF -FFFFFFFFFF00000000FFFFFF0000FFFF0000FFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FF -FFFFFFFFFF00000000FFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF -0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFFFFFFFFFF00 -00FFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF00000000FFFF0000FFFFFFFF0000FFFF -FFFF0000FFFFFFFFFFFF0000FFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF0000000000 -FFFFFFFF000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF000000 -000000FFFFFFFFFF0000FFFF00000000000000000000FFFFFFFFFF0000000000FFFFFFFF -FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF -00FFFF00FFFFFFFFFF00FF0000FFFFFF00FFFFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF00FFFFFFFF00FFFF00 -FFFFFFFFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF -FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFF00FFFFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFF -FFFF00FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF000000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFF00FFFFFF00FFFF00FFFFFFFFFF00FFFF00000000000000FFFFFF00000000FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF00FF00FFFFFF00 -FFFFFFFFFF00FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 -00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF00FF00FFFFFF00FFFFFFFFFF00FFFF00FFFFFF -FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -00FFFFFFFF00FF00FFFFFF0000FFFFFF00FFFFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF00FFFFFFFF00 -FF000000FFFFFFFFFFFF000000FFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFend -%%PageTrailer -%%Trailer -%%EOF diff --git a/medtool/doc/user/doxygen/figures/connectivity_arrays.png b/medtool/doc/user/doxygen/figures/connectivity_arrays.png deleted file mode 100755 index 1e46a517d..000000000 Binary files a/medtool/doc/user/doxygen/figures/connectivity_arrays.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/connectivity_arrays_small.eps b/medtool/doc/user/doxygen/figures/connectivity_arrays_small.eps deleted file mode 100644 index 16d766547..000000000 --- a/medtool/doc/user/doxygen/figures/connectivity_arrays_small.eps +++ /dev/null @@ -1,5488 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: (ImageMagick) -%%Title: (connectivity_arrays_small.eps) -%%CreationDate: (Thu Nov 29 18:20:32 2007) -%%BoundingBox: 0 0 375 281 -%%HiResBoundingBox: 0 0 375.052 281 -%%DocumentData: Clean7Bit -%%LanguageLevel: 1 -%%Pages: 1 -%%EndComments - -%%BeginDefaults -%%EndDefaults - -%%BeginProlog -% -% Display a color image. The image is displayed in color on -% Postscript viewers or printers that support color, otherwise -% it is displayed as grayscale. -% -/DirectClassPacket -{ - % - % Get a DirectClass packet. - % - % Parameters: - % red. - % green. - % blue. - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/DirectClassImage -{ - % - % Display a DirectClass image. - % - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { DirectClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayDirectClassPacket } image - } ifelse -} bind def - -/GrayDirectClassPacket -{ - % - % Get a DirectClass packet; convert to grayscale. - % - % Parameters: - % red - % green - % blue - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/GrayPseudoClassPacket -{ - % - % Get a PseudoClass packet; convert to grayscale. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassPacket -{ - % - % Get a PseudoClass packet. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassImage -{ - % - % Display a PseudoClass image. - % - % Parameters: - % class: 0-PseudoClass or 1-Grayscale. - % - currentfile buffer readline pop - token pop /class exch def pop - class 0 gt - { - currentfile buffer readline pop - token pop /depth exch def pop - /grays columns 8 add depth sub depth mul 8 idiv string def - columns rows depth - [ - columns 0 0 - rows neg 0 rows - ] - { currentfile grays readhexstring pop } image - } - { - % - % Parameters: - % colors: number of colors in the colormap. - % colormap: red, green, blue color packets. - % - currentfile buffer readline pop - token pop /colors exch def pop - /colors colors 3 mul def - /colormap colors string def - currentfile colormap readhexstring pop pop - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { PseudoClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayPseudoClassPacket } image - } ifelse - } ifelse -} bind def - -/DisplayImage -{ - % - % Display a DirectClass or PseudoClass image. - % - % Parameters: - % x & y translation. - % x & y scale. - % label pointsize. - % image label. - % image columns & rows. - % class: 0-DirectClass or 1-PseudoClass. - % compression: 0-none or 1-RunlengthEncoded. - % hex color packets. - % - gsave - /buffer 512 string def - /byte 1 string def - /color_packet 3 string def - /pixels 768 string def - - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - x y translate - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - currentfile buffer readline pop - token pop /pointsize exch def pop - /Times-Roman findfont pointsize scalefont setfont - x y scale - currentfile buffer readline pop - token pop /columns exch def - token pop /rows exch def pop - currentfile buffer readline pop - token pop /class exch def pop - currentfile buffer readline pop - token pop /compression exch def pop - class 0 gt { PseudoClassImage } { DirectClassImage } ifelse - grestore -} bind def -%%EndProlog -%%Page: 1 1 -%%PageBoundingBox: 0 0 375 281 -userdict begin -DisplayImage -0 0 -375.052 281.289 -12.000000 -500 375 -1 -1 -1 -8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 -BCBCBDBFBCBCC7FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C2BBD9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4393C2B12 -3A395AF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE45A3C3B4198FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF6FAAE3EF1F6F8E3 -E7FFFFEADFFEDBF1DDCCECFFFFFFE9CCCFF5FFFFFFFFFF8A66F1F9C244E0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFF7185FFFF89 -73FC4B7B482855E9FFE1492C257AF7FFFFFFFFBDCFFFFFED34CCFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF6DCDBDBDCDBDBDDF9FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF3E7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFFAA53F1F03AC5FD3D37 -CFDD475CE65A85E7CA3085FFFFFFFFFFFFFFFEA75CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFCC35312C1B2F303FDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA159FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFFDF38D9BB4CE8FB40A9FFFFC633 -CB256A77783F4EFEFFFFFFFFFFFEA961E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7E2E4BC2CCDE3E4F1F1FFFFF8EDFEF1F5F3E7F3FFFFFFF8E8E8F7FFFFFF -FFFFFFF1922B49FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFFFF77808A62FFFA40B4FFFFD035CB256876 -7577A6FEFFFFFFFFFEA961E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFD432E8FFFF9F6EFFFFBA5EFC7486662B5AE9FFF87E2B2B7DF7FFFFFFFFFFA8 -3B774BFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFB440FAFFFFFFD4334496FFFA3D79FAFE985DD82CACFFFCCEBAFF -FFFFFFFEAC66E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFD432E8FFFFB84BE9FF5898FF601D9ECD4756ED8858BFBF317FFCFFFFFFFFEDE9A74AFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB440FAFFFFFFF04412D8FFFA4037797D24B8FF9826856941C7FFFFFFFFAC -2176969398EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8 -FFFFF33AC2E445C8FF5E78FFFFD82CC63A78A2A16331F2FFFFFFFFFFFFA64AFDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFCF86FBFFFFFFFF805AFAFFFA41A78255AAFEFFFC9F575DC7FFFFFFFFFF9C585B5959 -61E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8FFFFFF89 -6EAF43FBFF5D8EFFFFEA33C6383D52515277F6FFFFFFFFFFFFA64AFDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEF46590FFFFFA40B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8FFFFFFE0425D67FD -FF5E6BFBFFCB42D5399EFFFFEBC4FBFFFFFFFFFFFFA64AFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 -473AE8FFFFFA42B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8FFFFFFFA5500B7FFFF602085 -B03386FF9A249A9D459BFDFFFFFFFFFFFFA64AFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B9D9FFFF -FFFDCAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE61EDFFFFFFFFA833E8FFFF5E827B3774F4FF -FE9B3A3A96FDFFFFFFFFFFFFFFBA73FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFDF9FEFFFFFFFF9160FEFFFF5D8EFFF8FBFFFFFFFCF8F8 -FCFFFFFFFFFFFFFFFFFCFAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF77827C5FFFFFF5D8EFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF9A1AFFBFFFFFFBBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDEFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF686EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF268DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA08AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE856D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFF8878F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D654C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E99594DAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB982B2FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDB8CCAB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA0BC9BFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE99EDF69DE0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA96F19AE1FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB1C6FFFFD6A6F7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBB8FFC1B2FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC9B1FAFFFFFEBDBBFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF49BE4FFED97EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCC9AEF5FFFFFFFFFAB8BDF9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFBFB6FFFFFFC0B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF6B9B0F3FFFFFFFFFFFFF8BBAEF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFE59EF1FFFFFFF5A0DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFEE5ABC0FAFFFFFFFFFFFFFFFFFDCDA5DCFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F0AAD8FFFFFFFFFFE0A7ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEB79CD1 -FDFFFFFFFFFFFFFFFFFFFFFEDDA0AEE7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAED1FEFF -FFFFFFFFFFD9A8EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE8BC9BBEF2FFFFFFFFFF -FFFFFFFFFFFFFFFFFFF7C89BB5E3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD8A1D0FEFFFFFFFFFFFF -FFFFD3A0D5FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEECAA197B8EBFEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF1BF989EC2EAF9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFEFAF8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F5EFD1A2A4E3FFFFFFFFFFFFFFFFFFFFFFE7 -A6A1CDEEF5F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8FAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFBF8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F7F3F1EDE0C4A89C95AAD6F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF9DBB1959BA6BFDCECF1F3F6F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 -F8F8F8F8FAFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D8 -B1A49C9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9A978FA4D4F7FFFFFFFFFFFFFFFFFFFFFFFFFFF9D7A78F -969A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9CA3AFD4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFCF6E6CCB6AAA6A29E9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9994918C97AFCADEF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF6E1CDB49A8D9093989B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9DA2A6AAB3C8E2F5FCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD09AA0C0D0DEE2 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E1E1E1E9F8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9EAE1E1E1 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E2DED1C1A39ACAFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCE5B9A29394A9BCC5CCD4DAE2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E5 -EEF3FCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFEFDF5EFE6E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E2DCD4CDC6 -BEAD9792A0B5E0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B4AAE0FCFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFDE3AEB0F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C5A097B9D5 -ECFCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDF0 -D8BE9A9CC0EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4ADC2FAFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFBC9AAF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C199AED8F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDE -B398B8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF8B2C9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCFAFF4FFFFFFFFFFFFFFFFFFFFFFFFFBCE9CB4ECFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2BD9A -C3F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBDB9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -C1B5FEFFFFFFFFFFFFFFFFFFFFF4B4AAE4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECB2ACEEFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE29FF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A1DAFF -FFFFFFFFFFFFFFFFE9A9C5FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD1A4E1FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB -A5D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9A1F9FFFFFFFF -FFFFFFE4A5D7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0A5DBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE9CF9FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA0D8FFFFFFFFFFFFECA6 -DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8A7E2FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0C4FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEA8FEFFFFFFFFF8A9D2FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEA2F2FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF495ECFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF097EDFFFFFFFFC4B2FEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9DFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9ED7FFFFFFF199EAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF49AE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC3AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFB9BAFFFFFFC5AEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFBCB6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFABC9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF8F8F8F8F8F8FC -FEF9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAF8F8F8F8F8F9FEFCFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF8F8FDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFD3A0FFFFFDA2D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFDF8F8F8F8F8F8FAFEFAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFEFAF8FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEFAF8F8F8F8F8F8FEFCFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE598F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA0D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC383E3E3E3E3CBAE161EDFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9395FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD70393E3E3E3C50EBA982FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7C3C4094ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDF95FFFFF690EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFDA443D3E3E3E3A84FC6CC5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBD57 -3C89E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFE77393E3E3E3D4CE7B17CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF698E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFE97DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F42BAB8B8B8B7E8D532E8FFFEFEFDFE -FFFFFEFEFEFDFEFEFDFDFEFFFFFFFFFFFFF4AD2478FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC467ABBB8B8B8BFFB8E5DFFFFFEFDFDFEFFFFFEFEFE -FDFEFEFDFEFEFFFFFFFFFB6D68BAB64C9AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 -94FCFFEB8EFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD29AB -B9B8B8B7D2FA40B4FFFFFEFDFDFEFFFEFEFEFEFEFEFEFDFEFFFFFFFFFFDE419ABB5650F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFE4E73BCB8B8B8BDF99955FFFFFEFDFDFEFFFFFEFEFEFDFEFEFDFEFEFFFFFFFFFFFE -FEFEFDFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 -DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC2F1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E5DFFFFFFFFFFFFD432E8FFD9594670F0FFD467 -A54D91CF564DC3FFFFFFFFFFFF85374677FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFC46ABFFFFFFFFFFFF8E5DFFFFAD49479FFEFF9F808D4BC0A746 -67E9FFFFFFFFEB64E0FFFFAB46FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C4FBFFF0 -C4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC34EDFFFFFFFF -FFFA40B4FFF3774655D3FFF46EA16468DB724599FDFFFFFFFFE3CBFEFFC039F4FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4D -A1FFFFFFFFFFFF9855FFFFB34A4799FDFFA67C914ABBAD4763E6FFFFFFFFFFAF8CA44669 -EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7E9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF8F47C7C5C5C4D1FFD432E9DC5564A83E61F4C41180982B48 -9C7130DDFFFFFFFFFFC9DA7675FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFC4683C8C5C5C3E2FF8E5DFFB0418992279DFF7821A0742563A64361FCFF -FFFFFEFAFEFFFF925FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFFFFFEFEFEFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD2BB7C5C5C4C7F4FA40B5 -F8784BA56339D5F22B54A94434869226ADFFFFFFFFFFFFEDC56D94FEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E7CC8C5C5 -C3DFFF9855FFB64285962895FF831D9D7A2460A64859F9FFFFFFFF911865A64164FDFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF92113837373462FBD432ED8552CDD3A91EBCC537F1FF6D77FFED34C9 -FFFFFFFFFFFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFC4621383737339BFF8E5EFB418DD1D1772EF37672FFEF35C1FFB43DF8FFFFFFFFFF -FFFFAC60E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF153337373741DAFC40B8C830BED2 -C23B75F435C5FFB03EF7FF5F89FFFFFFFFFFFFC43735AEFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E1F3837373393FF98 -55FD4786D1D17E29EE8068FFF339B8FFBD39F4FFFFFFFF903BE9FFB040FAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF8E59F5F2F2F2F5FFD432ED841335343630C7C439F4FF707AFFF035C9FFFFFFFF -FFFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC46 -A2F6F2F2F2F8FF8E5EFB3B243534324CF57675FFF237C5FFB83EF8FFFFFFFFFFFEAC5EE0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD32E1F3F2F2F3FCFA40B8C8113334352D8CF3 -35C9FFB440FAFF6289FFFFFFFFFFFFFBF3DC4DBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4D99F7F2F2F2F8FF9855FC4221 -35343347F1806BFFF63BBCFFC039F4FFFFFFFF8E5DFFFFB440FAFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -8E5DFFFFFFFFFFFFD432ED8157EEEFF0D4F3C139F4FF707AFFF035C9FFFFFFFFFFFFFF75 -75FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC46ABFFFFFF -FFFFFF8E5EFB3C9DF3F0EAD3FF7575FFF237C5FFB83EF8FFFFFFFFFEAD61E1FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFCC34EDFFFFFFFFFFFA40B8C62EDAF0F1DDE1F135C9FFB4 -40FAFF6289FFFFFFFFC791F7FFFF5598FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4DA1FFFFFFFFFFFF9855FC4295F3F0EBD2 -FF7F6BFFF63BBCFFC039F4FFFFFFFF8E5DFFFFB440FAFFFFFFFFC6E9FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E52E4E2 -E2E2E1F7D532EBBC2792E28C61E5C239F4FF707AFFF035C9FFFFFFFFFFFFFF7575FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4697E6E2E2E1E4FF8E -5EFF7E2FC4CF6C83FF7575FFF237C5FFB83EF8FFFFFFFEAB47C4E5E1EAFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCD30D2E2E2E2E1ECFA40B6E83E62E0AA5ABCF235C9FFB440FAFF62 -89FFFFFFFFCD2EADE7C851CAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4D8FE6E2E2E1E4FF9855FF852CBFD26F7EFD7F6BFF -F63BBCFFC039F4FFFFFFFF8E5DFFFFB440FAF9DFF0FF9AD8FFE3E8FFF8EFDFF2ECE1FBFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C1D313131312FB6 -DC44EAFFB02C2D3ACFFFC64AF5FF7C85FFF147CDFFFFFFFFFFFFFF8181FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC56243231313045EB996BFFF678 -272865F0FF8181FFF348CAFFBE4EF8FFFFFFEB3A1F33312D6AFDFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFD3252F3131312D7CFC51BAFFD8422D29A4FEF147CDFFBA51FAFF6F93FFFFFF -FFFFC5422F40C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFE5E233231313041E5A364FFF87E27295FEDFF8A78FFF74CC2FF -C64AF5FFFFFFFF986BFFFFBA51F6B794A3F19BD8CF9699E0C575988F9691C3FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0DCDBDBDBDBDBF2FAE4FBFF -FCE1DAE8FFFFF6E4FDFFECEDFFFDE4F7FFFFFFFFFFFFFFECECFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE6DBDBDBDBDBDEFBF0E9FFFFF5DCDBF2FF -FFECECFFFDE4F7FFF5E5FEFFFFFFFBE0DCDBDBDAE5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF8DEDBDBDBDBDAE8FEE5F5FFFFE9DAE0FBFFFDE4F7FFF5E5FEFFEAEFFFFFFFFFFFFEE4 -DAE3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEE7DBDBDBDBDBDEFAF1E8FFFFF6DCDBF1FFFFEEEBFFFDE5F6FFF6E4FDFF -FFFFFFF0E9FFFFF5E9CC96EFBAA39EC689E4D78CB8A1FF86DFDC98FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFC7669286B59EC4668F8C9ABAB3FF8DEDDC98FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFDAA1F1C4CE9DCC9BE5D9BBBBB3FF8DEDDC98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF8A -B2FDBBE6E6939EF3D3CCFFB2F3E7B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 -FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEF7FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFDFFFFFF -FEFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDB8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA1E7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF9A3E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFAFA3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF775D3FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF471D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFAB7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF998AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA5EBCFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE51C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFE9864FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF8574FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD473A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD769ACFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF59089DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFEE8F8BE4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFADB69AF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADB39AF3FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6A3 -B8BAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEA9B1 -C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE899F5B0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE99AF0ADC8FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA6D1E999F4FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA1D8E29BF8FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFAABCDFFEB9FE9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCAFC7FFE69DF0FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A3F9FFB6BFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFAAFAFDB0C7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB -C1BBFCFFFFD3AEF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFECBB1F9FFFFC9B3F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE3A6E4FFFFF4A8D0FCFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDCA7EBFFFFF0A8D7FDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEAAFBBF9FFFF -FFFED1A3D8FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFEF0B7B2F4FFFFFFFDC5A5E4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D6BEB9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9AA9FE0FFFFFFFFF1AAA3B8B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9B9BBCEEFFEFFFFFFFFFFFFFFFFFFFFF4D2BCB9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9B9B9B9B8A7A2E8FFFFFFFFEDA5A5B8B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9BCD0F2FFFFFFFFFFFFFFFFFFFFFFFFFBE8D0BFB9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B5A498C9FAFFFFFFFFFFFEDF -A19DB0B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BBC9 -DFF6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF8E0C9BBB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B8 -A898BEF6FFFFFFFFFFFDD49BA1B4B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9C4D7F2FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE09FA1B5B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9B9C9F1FFFFFFFFFFFFF9D2BAB9B9B9B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B7A798CCFDFFFFFFFFFFFFFFFFDA9BA3B6B9B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9BACCF5FFFFFFFFFFFFF7CFBAB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B6A599D4FFFFFFFFFFFFFFFFFFFEDFA495A5B4B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BDD1F3FFFFFFFFFFFFFFFFFFFBDDC2B9 -B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B8AB9999C8FA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD29C99 -ABB8B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BACAECFEFF -FFFFFFFFFFFFFFF6D4BDB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9 -B9B9B9B9B0A096BDF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEA6E0FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFEEAFCAFFFFFFFFFFFFFFDAA8E6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE9AAD3FFFFFFFFFFFFFFFECB9FD4F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AEB3F7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABCA9E0FCFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFEEEB8ABF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF29FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF19FE2FFFFFFFFFFED9FE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFEC9EE8FFFFFFFFFFFECEB0F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC8B4F7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBFB9F9FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -D2ADF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFBDB6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 -A7FDFFFFFFFFB6BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6AD -FFFFFFFFFFE0A1F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB7BEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A4F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB5FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF697E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF798E4FFFF -FFF394EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF395EDFFFFFF -FAA3D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29DE4FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF99EDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59BE3FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9E -FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4BFFFFFFFD1A4FE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADC6FFFFFFDC9EFAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD4A3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2B1FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB4FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD79DFFFFFFB4BDFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA7FFFFFFB1C1FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE895F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFADC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE697F6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8CDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE895F8FFFDA2D4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9CF9FFFB9BDEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFC96E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FB96E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB93E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE98DEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF97EEFFF998E3FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA96F4FFF197ECFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA7CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58AF6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9CE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF3A1ECFFF89EEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF09EF3FFEDA0F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFB7C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE9BF9FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFB2CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFEECFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFDEDFBFFFDECFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFDECFCFFFAEDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBECFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF1F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFD1AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0 -B0B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0 -B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B4B6B0B0B0B0B0B0B0B0B0B0 -B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0 -AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0 -B0B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFAF -B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0 -B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B4EED9 -AFD2F7C2B3E8EAB4C0F7D4AFD6F6BFB5EBE7B2C4F8D0AFDAF5BCB6EFE3B1C7F8CCB0DEF2 -B9B9F2DFB0CBF8C9AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFB0B0 -B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0 -B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AECCF7DFF7 -CBB0DFF2E3F4BCB6EEE8EDE8B3C2F7E0F5D7AEC7FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE85B2 -C0BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC39085C3BFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFBFC38C89C3BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB768BCBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC37747C0BFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFBFC37A9CC2BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC1A96FC1BFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC1A573C2BFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBFC06DADC0BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC2977EC3BFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC29382C3BFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFBFBFBFBA67B9BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC389C3E3BFDBF9CE -C2ECEEC3CCF8DDBEDEF8CCC3EFEBC1CFF9DABFE1F7C9C5F2E8C0D2FAD6BFE4F5C7C6F4E5 -BFD5FAD4AE6CC0BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC0AB6EC1BFBFBFBFBF -BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC271A7C1BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF -BFBFC29E78C3BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC29994FCE5F9D5BFE5F4 -E9F6C9C5F2ECF0ECC2CEF8E6F7DFBC7BF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFC98F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEECFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFDD9FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8 -FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB -98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD5FAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8CF1FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC -A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCADF5FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 -94FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD0F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEF3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDBCF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFB8AF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC6 -F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB -98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF0FDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD2FAFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC -A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF2FDFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 -94FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEDFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEE3FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFEDEFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88DDEEEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDEDF1B2A4F2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF1ACAAF1EDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE380E9EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEDF28D4FEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF196C1F0EDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDEDEFD189EFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDEDEFCC8DF0EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEE86D6EEEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDEDF1BB9CF2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED -EDF1B5A1F2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE77FE6EDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDEDEDF2A4BFFAEDF5FDF1EEFAFAEEF1FDF5EDF6FDF0EEFAF9EEF1 -FDF4EDF6FCF0EFFBF8EDF2FDF3EDF7FCEFEFFCF8EDF3FDF3D885EEEDEDEEEFF1F1EEEDED -EDEDEDEDEDEDEDEDEDEDEDEED488EFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF0 -8BCFEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF0C494F1EDEDEDEDEDEDEDEDEDED -EDEDEDEDEDEDEDEDEDEDF0BE9AFFFAFAFAEEF0FCFAFDF9EFF4FDF8FDF3EDF8FCF9FCEFDD -FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFA4878C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C807D8D8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D7F7E8D8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C8C8A768B8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -7C718C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D7B838C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C8C86788C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C85 -798C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C77878C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C8C827C8D8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C817D -8D8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8A768A8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8C8C82D9C88ABDF4A790DEE192A3F3C18AC3F3A293E3DC8FA8F5BB8AC9 -F09D95E8D68DAEF5B58BCEED9A99ECD08CB4F6B086788C8C897A62493D7A8C8C8C8C8C8C -8C8C8C8C8C8C8C8C87788C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C78868C8C -8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C847A8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C -8C8C8C8C8C8C8C8283E3E1E1E2939E9B64795E64BAF4D1F4B28CD2EBD7EE9B98F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFEFFFEFDFEFEFEFDFEFEFDFEFEFEFDFEFEFEFDFEFEFDFEFEFEFDFEFEFEFDFE -FEFDFEFEFEFDFEFEFDFDFEFEFDFEFEFEFDFEFDFFDA4B1D0B4BEDFEFDFDFDFDFDFDFDFDFD -FDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFD -FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD -FDFDFDFEFEFEFEFEFEFEFE8400002ED0FFFEFEFEFEFDFEFEFEFEFEFEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF766000FB2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFEEBB841B15B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFECA0974B58F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8 -B293B4E9888EFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFCE6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE1D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFBDDB3E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC9A59687BAFEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFDCE8DBDFAD8D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE2AB92B9EFFEFF -F2F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFD35FE5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBF -4096FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 -AC60263AE8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE89050021C9FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1A996DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCA795C0F2FEFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7C0598 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6961D0294FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16C030076 -FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFED971C048EFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED692B2F5FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD6A099C9F6FEFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3220037E5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB69090294FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA73615B7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF6BD8EB99E5BEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B391D5FEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF8D09C9BD0F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7502C58CBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5705FA3FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB293D994EAFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFBD493A2E5FFF6E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF97A7F1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF5C9989FD7FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8E884F1F9FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA1C6F8F3FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFBFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5A193D4 -FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BE8DCDFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1C4 -97A5DCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFDC91F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B78CBFF6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE79CA0EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEBB94ACE2FDFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFCB490EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACC8FA9EBFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBC98CC3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEAB493B1E6FDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDC91F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFDB490EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDF9C98DBFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEA5 -9AE3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AF94B9EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -A0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB490 -EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFAC8DC7F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD38EB8F7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCE0A894C0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD91F6FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB490EEFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8C28DB1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4AE92DBFEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBD8A296C5F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB390EEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD794 -9FE3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDB92AFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A6 -99CCF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD90F6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9A492D0FCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7B68FD3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DEF9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B98ABBF5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE296A7EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7C4C3D6FEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5FCFFDBE4 -FFFFFFFFFFFFECD4FEF3ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFDC90F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCF91A7E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFABF8FC9FCFFFFFFFFFFFFFFFFFFFFFFFFFFFDA24937363F78EEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD5FF8FF86A4FFFFFFFF -FFFFC16EFE81A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFEA0C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEE19E96D9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE89F9FE9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC23A7F4F4D53B9CFFFFE7D3D9FAFFFDDFF4E0D4F1 -FFFFE7EBEBD3E6FFFFFFF4D5D4EFFFFFFFECD3D6F7F69635CFF0DFE0DEFAFFFFEFE3EED8 -E2467EDFE5EAFFFFEEE3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDC90F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB2 -91EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFEFB08FC5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA8EBFFAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF154A3FFFFFFFFD8B0FED8402D2697FDF54786452667F1FF766A -602B3FD6FFF57226295CECFFE5502A2685BA240C2FB773754CD5FFFF9670B6506F0D1C55 -6883FFFF926FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD -A1C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 -C68EAEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFA995E2FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE231DBFFFFFFFFFFFFE53F61E5AB26A3F7323CCFD12FA6FF6F1AAAE65A64 -FF7E65D1DC4562E9534DDDBD3ACBA73AE3FA638A747EFFF340BFB343ED4D8AF3A754F1F2 -3EBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD90F5FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDA979DE0FEFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED590B6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFE231DBFFFFFFFFFFFFC930E6FFFF7867F838B3FFFF519DFF6C73FFFF9359FC3F5B84 -825C2CCB2FD3FFFDE9FCB440FAFF628CAE54F3C547E6B143FC5598FFE237D8C349E4FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA1C4FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB390EFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECA890CCFAFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF4B191D9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE436 -D4FFFFFFFFDFABC535F0FFFF8467F839C0FFFF519DFF6B7FFFFF9359FC3F4C6D6B6D8AD4 -32DEFFFFFFFFB440FAFF628AF654A56C8CFFAF43FC5598FFFE77808F5EFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD90F5FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB490EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6BD8BB7F3FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFEDD94ABF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7955EBFFFF -FD876BCA27C5FFF3586DF839C0FFFF519DFF6B7FFFFF9359FC4384FEFEE5B5DA2AB3FFF6 -ABE9B540FAFF6289FF85573ACFFFAF43FC5598FFFFD436498EFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA1C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDB490EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCD392A2E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 -BB8ECFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF44569F9F7D2ACBFA -7A2D975E37D4F639C0FFFF519DFF6B7FFFFF9359FFB82679873AA1FA8F53A16D2CDDBA2B -99DE6489FFD62A5FF8FFAF43FD5A5BAEF8F1440ED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFDD90F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFDB490EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFE5A192D5FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE69AA3ECFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9964F4F72D5FEFFF7864E5B -D3FFF87AD5FFFF8ABDFF9CA9FFFFB68FFFFFB8514FA2FEFFFC984E54C3FFEF754DC199AF -FFFCA1C8FFFFC981FEC4546AF1FF8553F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFDA1C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD -B390EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF2B58CC0F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC58BC6FBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF96B88FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDD91F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB390EEFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC98EAAED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDA09BE6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE94F34E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD -A0C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EEFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDC9A99DDFEFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFDCE8DBCF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F4B2D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC91F5FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDAA8EC9FAFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF2A896DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA0C5FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C18CB5F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFED692B2F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC91F5FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFCD693A0E5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B491 -D5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF7CFA5DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFCB291EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFEE6A392D1FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF97A8F0FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C9989ED6 -F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFDC91F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCB391EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B98B -BDF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BE8DCCFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C295A5DDFBFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACD91A8EAFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE89DA0EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEBB94ABE2FDFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFDF92F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB990EFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE19D97D9FDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFCC88EC3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDEAB491B0E7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -ADC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0AF8DC6F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEEA598E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDE5AE92B7EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE49BF6FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFF9C58EAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDD38EB8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCDFA794BFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADC7FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFDBE96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFDD9969DE1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3AF93DBFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD9A194C5F4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE39AF6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDBD96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA -A890CEFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDC91AFF3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D19D9ACBF7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFDBD97EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5BC8BB9F4FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B78FD2FDFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CB989ED3FAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE39AF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD192A4E8FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE398A6EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF3C294A3DAFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA7C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE39F94D7FDFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBBF8ECAFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEFBD91A8E1FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF0B28DC2F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE89F9FE8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -EAB793AEE6FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAC88DACEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA -8EBFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AE92B5ECFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDDC999ADEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFA897E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE0A992BBEEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFDBD97EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEECAB8FCAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED590B4F7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBA396C4F2FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFDBE96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C08DB5F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B291D9FEFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF9D59F98CBF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96 -EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD594A0E4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEDD95ABF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF7CD999BD1F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFEE6A392D2FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF8BB8DCFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5 -C7969FD6FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF4B68CBDF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFE59AA2EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1BF94A8DDFCFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBB92EEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFBCB8FA9EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC58CC5 -FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEDB891ACE4FEFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDF9C96 -DBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDA09BE6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8B091B3E8FEFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAD8DC7FAFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCE8DBCF8FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFDE2AB92BAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C48DB1F1FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2AA95DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFCDBA494C1F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA -8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD8949EE2FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFED891B2F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD5 -9E96C8F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFE8A591CFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF5B392D5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D09C9BCFF7FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF4BB8BBAF4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -DF97A8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C8979FD7F9FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEBFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCF -92A6E8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BE8FCBFDFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C194A3DCFBFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE39D95D8FCFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE79EA0EBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEEEBA92AAE2FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B18DC2F8FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC88DC2FAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEEAB492B1E6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC88DACEEFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFEEA598E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE4AD -91B7ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -BB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFDDC989CDFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFDD28FB9F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDEA792BDEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECA98FCBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF3AE92DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD8A296C5F4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6BE8BB7F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDC92 -AEF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D29B98CCF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE38DF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD492A1E6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B98FD2FDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6C9989DD3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4A193D5FCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE397A6EEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF3C494A2DAFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B68DC0F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC18EC9FCFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEBC92 -A9E1FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFACA8FA9EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEA9E9FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEAB591AEE7FDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFEDF9B99DCFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCC98FBEF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AE92B5EBFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BBFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFEEAC8FC8F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFEFA897E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE0A893BCEFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C28DB4 -F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED591B4F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFADBA394C3F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD7949FE2FEFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B290D8FEFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF9D49D96CAF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8A391D0FBFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDE94ABF2FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CE9A9A -D0F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5BA8BBBF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8BB8ECFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C596A0D7FBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCCE90A6EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFE59BA1ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1BF93A5DDFDFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFDBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEE29D94D8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFBC58EC5FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFEECB691ADE3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0AF -8CC4F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC -A29AE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFEE8B18FB2EAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C58EAEEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCF8CBCF8FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFDE1AA92B9EEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDA969DE1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2AB95DEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDBA394C0 -F3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9A88FCEFAFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED890B3F5FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD59E96C8F5FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF6BC8BB9F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF6B392D4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CE999AD0F8FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA8BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFBD393A3E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFEE098A7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF4C8969FD6F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFDBA8CEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -E4A193D6FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF8BE8FCBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEF1C193A4DDFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8C -EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B38EBFF7FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE79E9F -EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEEEBB92A9E1FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACA8EABECFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC98EC1FAFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE9B391B0E6 -FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BCFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDD9A9ADCFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEA59AE3FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE4AD91B7EBFEFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFEEAC8FC8FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED18FB8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDEA591BEF0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF7C18BB4F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF3AE91DBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBD8A194C4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFDD5949FE4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFEDB92ADF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9D09B99CCF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7A392D2 -FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7B88ED2FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6CA959CD3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA -8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B88DBCF6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE497A5EEFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C295A3D9FB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCC8FA8EBFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC28DC9FCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEBB92A8E1FDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE09B97DAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA9F9EE7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE9B390AFE6FDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEEAE8EC7F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA8FBEF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFEE5AE90B5EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9C48DB1EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFA897DFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFCDFA893BCEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAABEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEBD91EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDC9A -A2E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFED795B8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB -DDA598C8F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC29D9F9F9F9F9F985E9D9F9F9F9F9F9F9F9F -9F9F9F9F9F9C9B9F9F9F9F9F9F995C92A09F9F9F9F9F9F9F9F9F9F9F9F9B9B9F9F9F9F9F -9F9F9F9FA0904F8AA19F9F9F9F9F9F9F9E999F9F9F9F9F9F9F9F9F9FA08D4C6D9DA19F9F -9F9F9F9F9FA09F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9A9CB1F4CF9ECAF6 -B4A3E5E5A3B4F6CA9ECFF4B0A5E9E0A1B8F7C59ED3F2ADA8EDDBA0BDF7C09FD8EFAAABF0 -D79FC2F1A99E9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F999E9F9F9F9F9F9F91 -4F78A0A09F9F9F9F9F9F9F9F9F9F9C9A9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F84486997A2 -A09F9AC3F5D9F6BBA0DDECDFEFABAAEEE0EBDEA1BAF6D9F4CA9ECFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFE85C3D3D2D2D2D2D2D4D2D2D2D2D2D2D2D2D2D2D2D2D2 -D69E91D6D2D2D2D2D2D0CED3D2D2D2D2D2D2D2D2D2D2D2D2D69996D6D2D2D2D2D2D2D2D2 -D2CBD0D3D2D2D2D2D2D2D2D2C971CFD2D2D2D2D2D2D2D2D2D1CAD4D4D2D2D2D2D2D2D2D6 -7F49D3D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D685AADDFAE8D2E6FADCD4F2F2 -D4DCFAE6D2E8FADAD5F4F0D3DEFBE4D2EAF9D8D6F6EED3E0FBE2D2EDF7D7D8F8ECD2E4DB -83D5D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D377BED3D2D2D2D2D1C7D3D4D2D2 -D2D2D2D2D2D2D2D2D2D5A68AD6D2D2D2D2D2D2D2D2D2D2D2D2D2CECBD4D4D3D2D2D5A0A2 -FEEDFBDFD3EFF6F0F7D8D7F7F0F6F0D3DFFAEDFAE6D0CDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF892F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF99CF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEF0FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFCD5FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFDECFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB3F9FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB -98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF4FEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFEF4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAB3F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFCCDFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDECFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD5FCFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF0FDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB -98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99CF8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF892F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFDE5FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDDEFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFDE2FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF868F9A9A9A9A -9A9A9A9A9A9A939A9A9A9A9A9A9A9A9A9C79719C9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9A9C76749C9A9A9A9A9A9A9A9C948B9A9A9A9A9A9A9A9A9A9A945D989A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9D67469B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9A9C6A81AEF3CC99C7F5B09FE3E39FB0F5C799CCF3ACA1E8DE9DB5F6C299D1F1A8A3 -ECDA9BBAF7BD9AD6EEA5A6EFD49AC0DE719B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A -9A9A9B618D9B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9C7E6D9C9A9A9A9A9A9A9A -9A9A9A9A9A9A9A9A9A9A9A9A9A9C7A9BF7D7F5B89CDBEBDEEEA6A5EDDFEADD9CB6F5D7F4 -C799CDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9D8D8D8D8D8D8D8D8D8 -D9CA5DB9DAD8D8D8D8D8D8D8D8D9DAD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 -D8D9DAD8D8D8D8D8D8D9D9B34348D7D8D8D8D8D8D8D8D8D8D8DAD8D8D8D8D8D8D8D8D8D8 -D8D8D8D8D8D8D8D8D8D8D8D8DBDDD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 -DAD9DFFAEBD8E9FBE1DAF4F4DAE1FBE9D8EBFADFDBF6F2D9E2FBE7D8EDF9DEDCF7F0D9E4 -FCE5D8EFF8DCDDF9EED8E6FADFD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8DA -D9D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D9DAD8D8D8D8D8D8D8D8D8D8D8D8 -D8D8D8D8D8D8D8D8D8D8D9EAFBEFFBE4D9F1F7F2F8DDDCF8F2F7F2D9E3FBEFFAE9D8EBFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB41391 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFF9A7300064FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24F0031E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFF78D140077FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFB9F8EC4EDFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB39162DADFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE70 -5593FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFBF27200123DBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1DD7AD1EDFEFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9CC5F5ECFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFAEBD4BCA8 -978D63041383EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC99F9FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDF6E3CBB6A2908E9FB1C8DFF7C848 -B0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08EDDFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFEFDF0DAC5AF9B8C95A5B7D0E8F8FDFEFFFFFFF4E5FEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9E7D5BEA8928F9CA9C1D9F0F9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFE08EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF3E1CEB79F8F -959EB0C9E4F3FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFA9AC6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBECDDC7AE979199A1B8D3EAF5FCFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFC99AF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEF6E9D7BFA4939698A9C2DDEDF8FEFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF091DE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFCF2E4D0B59D96949BB0CDE2F0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAEFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9EFE0C6AC999593 -A0BCD3E7F3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 -EAEAF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFCF7FFFEEFFAFFFFFFFFFFFFF3F4FFF7FBFFFFFFFFFFFFFFFCEFFCFFFFFFFFFF -FFFFFFFFFFFFFFF5F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F4FFFFFFFFFFFF -FEF0F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEFFDFFF2F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE8EF0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6ECD7BDA59A9395ABC3DBEAFAFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBAF51313163C4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B697FFF460D0FFFFFFFFFFFF8D95FC80D6FFFFFFFFFFFFFFE04FE6FFFFFFFFFFFFFFFFFF -FFFFFF967DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE269C9FFFFFFFFFFFFFC69BFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA52F2FFBC6FEAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9BC8FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCF4E7CDB3A197909CB4CCDFF1FDFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9823A6D2D3862FDEFFFEF6 -F4F7FEFFFCF6FCF5F5FDFFFEF7FCF7F4FBFFFFFFF9F4F5FDFFFFFEF7F4F6FEFD7070F9FA -D3EEF8FEFFFFF8FBDFE1E331C8FAF7FCFFFFF8FCDB31E2FFF6FCF6F4FCFFFFFFF9F4FE84 -67FFFFFBF4F4FBFFF6F5FEFFFEF5FCFFFFFFFE6788FFFFF9F4F4F8FFFED5EDFDF4F4F4F4 -F9FFFFFBF4F4FCFFFFFFFFFFFDF6FDFFFFFFFFFFF7FBF8F4FAFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B0EEFFFFFFFCB8482BF0FFFE7777FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC79BFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -FAF2DDC5AC9F9291A6BCD2E5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE244AEFFFFFFFA98B7FFD5493552E0FF -D65EAC403CBBFFF864AA5A338DFBFFF371353AB1FFFFE2543547D593161948D5678C70FC -FFFF7DAA938350092B7963C6FFFF79ADDF31E2F25EAE51349AFDFFEE6733715668FFFC91 -353590FEAB52EAFFCB6AE9FFFFFFCD3FE2FFF373353661EBFD6BC3D83F393A3097FFFA87 -35359AFDFFFFFFFFEB60E0FFFFFFFFFF759D6B3276F5FFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFE832D4FFFFFFCA2C7236F0FFFFD63DDAFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFEF8EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9ECD5BBA9998D99AD -C3D7EDFCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF43FBFFFFFFFFFEFFD73863C25445E7D01451BA -802EE0F83730A3A726B0F97857BA8F28B4E74751C16546D45858C9E839AB45C5FFD63EDC -7275BE269CD55E95FFD23EDDDD31E2EF2A39AB9E24C0F45E3EBC80026AFF974BA9AA2A91 -F55D76E73A84FFFFFFFF9D59F9FF8931B7C04272FD43B0F6C2C4831BC9FE8E4EAEA3279B -FFFFFFFFF8CDF5FFFFFFFFFF522394B43090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFDFCE431D1FEFCFFEDD5C735F0FFFFF24FADFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFADB1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF7E4CCB7A3928FA0B4C9E0F4FDFEFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFAF43FBFFFFFFFFFFFF8F47F3FFEB37ABD228D3FFE832D4F9 -389CFFFF559ADD28A1B9B44C5AAE34E9FFF1C8FE7575FFF237C26395FFA951FA717BEF33 -D0FFAB46FFA553F9DB31E2EF2FADFFFC46AECE29D7FFFC6868F83787BAB96B31F4CA3F67 -7BF6FFFFFFFE4DA1FFFF8F2DAAC1D7D3FB43AFFFFFC42C83FBEE308FB9B8623AF8FFFFFF -FFFFFFFFFFFFFFFF517DFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -96403D0D384081FFFFFFC935F0FFFFFF8E5EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFDC8DF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFEFDF0DBC6B09D8D97A7BAD1E8F9FDFEFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFAF43FBFFFFFFFFDEDF8F5DFFFFFD4AAAD134EDFFE832D4F93BBCFFFF -559ADE1B3A41413F88AC46FCFFFFFFFF7575FFF237C8C546D950ADFF707BEF33D0FFE344 -C7559CFFDB31E2EF34CCFFFC46AECD35F0FFFF8467F8343041404065F5FF7811DCFFFFFF -FFFE4DA1FFFFF880380E42C2FD43AFFFF5577FFAFFED2B334140406DFAFFFFFFFFFFFFFF -FFFFFFFF519DFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2AFA022 -92B0C9FFFFFFC935F0FFFFFF8E5DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA99CAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA -E9D4C0AA94909DACC1DAF0FAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFE343ABFFFFFFFB6B8F934BF6FFEE3AABD134EDFFE832D4F93BBCFFFF559ADD29 -CBFFFEE3DAAC37EDFFF4D2FF7575FFF237C5FF4A6F3EF2FF707BEF33D0FFFF90574AB0FF -DB31E2EF34CCFFFC46AED93EDBFFFD6C67F836A4FFFEEECEFDD145487CF9FFFFFFFE4DA1 -FFFFDFE3F8BD6357FD43B0FA6E45F2FFFFED30B1FFFEEBCFFDFFFFFFFFFFFFFFFFFFFFFF -519DFFFF7575FFFFFFFFFFD2CCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE832D4FFFFFF -FFFFC935F0FFFFFF8E5DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC79DFBFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5E1D0B8A29196A2B1CB -E4F4FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FF9B23A2CFCF8233E5D3326FCE5E3DE2CE34EDFFE832D4F93BBCFFFF5599F9633CC29D4D -B2E34290D27144F7775DD4EA38C5FF932780FEFF707BEF30A6E0FFC50E36F3FFDB31E2EF -34CCFFFC46ABFF7245C8911A6AFF8A28B0B35291F8626DC035BFFFFFFFFF628EFFFF8B3B -C1CD4C6BFD43B2B51B9ECECBE5FC7E2DB6AD509AFEFFFFFFF9D6F7FFFFFFFFFF519DFFFF -7575FFFCD4DCFFBCB3FFDFD2FBF9E7D3E0EECCF1FFFFFFFFFFFFEC58DCFFFFFFFFFFC935 -F0FFFFFF7D73FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8FE1FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEDDDC8B198939BA3BBD3ECF6FDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB353 -323266C8FFFFCD3F3048D9FFD454F0FFEB52DBFA5AC7FFFF70A8FFEF672F31A4FEFFDC52 -313DCAFFBD3741D459CEFFE263D6FFFF878FFD782B7AFFFB4677FEFFE151E7F154D4FFFD -63B8FFE95B2E718780FFFA882E2E83FBAC4BE7FF9958EBFFFFFFBB3EF5FFEF672F3156E6 -FD61BD772735343095FFF77E2E2F8DFBFFFFFFFFEA5CE0FFFFFFFFFF6CACFFFF8B8BFFC2 -A2A0D5BDB4DBA0A2BEE267A38E8DA1A0FCFFFFFFFFFFFDF5FCFFFFFFFFFFD155F2FFFFEC -37CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADB4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEF6E8D7C1A695979CAAC2DFEEF8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3EDEDF6FF -FFFFFEF1EDF2FEFFFBF1FDFFFDF1FCFEF2FAFFFFF3F8FFFFF6EDEEFCFFFFFEF2EDF1FEFF -FDEFEEFBF1FBFFFEF7FEFFFFF5F6FFF7EDF3FFF449B1FFFFFCF1FDFDF1FBFFFEF2F9FFFF -F5ECF6F7F4FFFFF9EDEDF9FFF2EFFDFFF7ECFAFFFFFFE448C0FFFFF6EDEDF4FFFEF2F9F3 -EDEDEDEDF5FFFFF8EDEDFAFFFFFFFFFFFDF1FCFFFFFFFFFFF3F8FFFFF5F6EB7FD8CC85B8 -B28BC7DB81C68DFFA6BFFA89F8FFFFFFFFFFFFFFFFFFFFFFFFFFFBF1FEFFFFB04FECFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFDC8FF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF1E5 -D1B79F96989DB2CEE3F1FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFD6564BF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9664EDFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA689B98A3BBB27C919C -92D094FFA7C9FA89F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE55BA5FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFA99C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9EFE0C8AD9B9896A3BDD6E8 -F4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFD476CAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA4CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A1DACEBDBCB3B3C8DDAFD794FF -A7C9FA89F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5ACFCFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFC69EFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6EBDABDA69B9697ABC6DCEBF9FEFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC9DA9F8DAD5FAAD9AE8EFC3FFCEE0FCBD -FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EE8FE2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFCF4E8CEB6A19B929EB7CDE1F0FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEACB4FFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAF2DFC6 -ADA19493A7BED4E5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA90F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9EED5BDAA9C9199B0C5D9EDFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF897CCFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFCF8E4CDB6A69590A3B6CBE0F5FEFEFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC39FFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFCF1DCC4B39E9098A9BCD1E9F9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFEC90E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAEAD4C1AA -97909FAEC2DBF0FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFEABB6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E2CFBBA49398A4B2CBE4F6FBFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFD990F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCEEDCCAB29B949EA7BBD5ECF6FDFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 -97D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFEF8E8D9C1AA95999FACC4DFEFF8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0A1FCFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF2E4D2B9A098 -9AA0B4CFE5F1FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC8EE4FFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAEEE0CAAF9C9A9AA4BDD8E8F5FEFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADBBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFEF8F0DEC4ABA19D9FB1CCE0ECF9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5A0A2A2A2A2A2A2A2A2A2A05F99A2A2A2A2 -A2A2A2A2A29F9EA2A2A2A2A2A2A2A2A2A2985C97A2A2A2A2A2A2A2A2A29E9EA2A2A2A2A2 -A2A2A2A2A2A2966F48415B728494A1A4A2C1FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFE85C0CFCFCFCFCFCFCFCFCFCFD1CFCFCFCFCFCFCFCFCF -D29C8FD3CFCFCFCFCFCFCFCFCFCFD1D0CFCFCFCFCFCFCFCFD39794D3CFCFCFCFCFCFCFCF -CFCFCFD0D0D0D1D1D1D0CFCFC581FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE86D1 -E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E4A99BE5E1E1E1E1E1E1E1E1E1E1E1E1 -E1E1E1E1E1E1E1E1E5A3A1E5E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1D682FBFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB09094949494 -94949494949494949494949494949494948C8A9494949494949494949494949494949494 -94949494948B8B94949494949494949494949494949494949494949490AAFEFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBD4D3E2FFFFFFF7DFFC -FFFFFFFFFFFFFFF3E0FDFFFFFFFFFFFFFFFFFFFFFFE3EFFFE7EAFFFFFFFDE0F4FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E0FEFF -FFFFFFFFFFFFFFFFFFFFFFFFFFF7DEFBFFFFFFFFFFFFFFFFFFFFFFF9DEFAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF3DDFDFFFFFFFFFFFFEEE2FFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3EFFFF8DBFAFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE37129322F308CF4FFD041EEFFFFFFFF -FFFFFFBD4AF8FFFFFFFFFFFFFFFFFFFFFF5CA3FF7748E3FFFFF748C1FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFF7E7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC6CFDFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD340ECFFFFFFFFFFFFFFFFFFFFFFDD3FE4FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF67E8FFDFFFFFFFFFFFFB175FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFF651A4FFF3739DFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15242AFE9E5972FA8FFCC34EDFFFCE6E1EDFFFFB8 -3EF2E3E6FCFFFFFDE7E1EBFFFF519DFF700179FFFFF63BBCFFEBF4FFFFEFF0FFF2EEF5E2 -F8F8E2E8FDFF7576F6E1EDFFFFFFF8E3E1F3FFFFF1ECE6ECEEDAFEECF4EEE1F1FFFFFFF4 -E1EBF7EAFFD033EBFDE8F9E7E2F8FFFFF9E3E8D931E2FFFDE8E1EBFFF7E1F4FFFFF0EDFF -FFFFFFAE4AF3FFFAE4E1E5FBFFEBDCFEEAE1E2E2E6FCFFF2E1E3F9FFFFFFFFFFFAE7FCFF -FFFFFFFEEAF6EBE1F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BAB4FFFFFFFFCD660FA1FFFFDB3DD2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFAB28D6FFFFFFFFCCA8FFCC34EDFFB02E2D46DBFFB83A8E322F -B4FFED8B3D2D3FD4FF519DFF6D6660A9FFF63BBCFF60ACFFFF7F88FF9D417228848C2F33 -BEFF76636F2B46DBFFFA88292A65EFFF943D3C7BB55BFD65865A295CEAFFF36F284D9154 -FCD033ECE948983F288AFBFB8D283F6927E2FFBC322D3DD3E94F9CFFE860B4FFFFFFFC4F -A3FFFD9C2B312BA2FFA865FD6A2D332345F0EC5D2B2991FCFFFFFFFFDC5AECFFFFFFFFFA -56904F286CF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A70FFFF -FFFC5C6F479DFFFFFF7677FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFF716CFFFFFEF1EDEFF4FFCC34F0B92790DA5D40E8BD0D6CDA8D27C09E3D -CAE06554FE519DFF6B82B150E7F73BBCFF4DA1FFFF707AFF9129C7B9246FDD7E3AF57915 -96DA5D40E49357BDD14066FB872FC9EDAB46FD5224ADD13D85FF9B34C6BC313AFBD033EC -E72047CBB326C49727B1CD3A1AE6C64E9AE16F38DDBF30CA7C48EFFFFFFFD845D1FFD423 -9FE6A035E39F51FFE5DDBF2B88F46A6ED3B32A97FFFFFFFFF9E2FBFFFFFFFFFA3D2FBAC8 -319DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEEF27268F1EEFBFEE5F5 -529DFFFFFFAD52EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF707AFFFFF65C312D5CFECC34F27665FDFFE932C1BD33EAFFFC617BF0E5F1AB6246 -FD519DFF6B80F84F72F73BBCFF4DA1FFFF707AFF8E5DFFFB43AFFFCC34F27664FDFFE932 -BB4A6399976C25EA8567FFFFAB46FD518AFFFF7576F543BAFFFFA43CFBD033ECE62DC5FF -F83EB74E94FFFFCA2DE78D389896891EAEFE7F4960E0FFFFFFFFAB46FCFFE3396198C2DB -FD9D51FFFFE94854EBE0278397964A4DFEFFFFFFFFFFFFFFFFFFFFFA3FA0FFFF5D8EFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC40351917353CD6FFFFFF519DFFFF -FFE832D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 -55F6FFFCD6CF8F40FDCC34F27675FFFFF63BC1BC3EF8FFFF707AFD8236543946FD519DFF -6B7FFFDB3DC93EBCFF4DA1FFFF707AFF8E5DFFFB43AFFFCC34F27675FFFFF63BBA4A3B5B -595A74F48567FFFFAB46FD519DFFFF7576F234CCFFFFB83EFBD033ECE631D8FFF83EB74E -A6FFFFDB31E78E215B595A60CEFFD10B87FFFFFFFFFFAB46FCFFFFD2622C186CF79E51FF -FF9554E9FFDF214F5A595A92FEFFFFFFFFFFFFFFFFFFFFFA40B4FFFF5D8EFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6CFD0625AD0CEF5FFFFFF519DFFFFFFE832D4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC923B9FEFF -FFFFB340FDCC34F27954F4FFD82AC3BE29D9FFF35BA19C55CCF8AA46FD519DFF6B7FFFFD -9C5B2ABEFF4D9FFFF34E7BFF8E5DFFFB43AFFFCC34F27752F4FFD742D04A85FFFFEFBDFC -8467FFFFAB46FD519DFFFF7576F953A5FFFF8E3BFBD033ECE631D8FFF83EB97482FDFFB3 -28E78E46F0FFFCC2E6F15B573CC9FFFFFFFFAB46FCFFEDBBF9E6B42ADAA051FFA227C2FF -FFE029BBFFFFDEC7FFFFFFFFFFFFFFFFFFFFFFFA40B4FFFF5D8FF8DDFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A70FFFFFFFFFFFF519DFFFFFFE832D4FFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA832270B1B18D4076 -FECC34EFD33564AD3B60F5BC1358AD6040F2A428A18C2845FB519DFF6B7FFFFFF74F02C0 -FF703CAD721A7EFF8E5DFFFB43AFFFCC34F2791B74AC3A74FFB225859D4390FF8467FFFF -AB46FD519DFFFF7575FFB1259892303BFBD033ECE631D8FFF83EBBD62882A14121E4DE3F -58AF5664EBA445D87962F5FFFFFFC245E6FFDD2E76B67333E89F52E63059B0AEBBF4832A -A18343B8FFFFFFFFF1BFF7FFFFFFFFFA40B4FFFF5D91C36BBDF4FFE7D7D5B7E4FFFFD3BC -F4FFE0B4CCFDFFFFFFFFFFFFA19AFFFFFFFFFFFF519DFFFFFFC943E2FFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C184414165C8FDFFD969F2 -FFD14F3F6EF0FFCA72B24550D4FFFB8F3D6AB375DA80B6FF92A0FFFFFFE05ECFFFEE6B3E -92919DFFAB87FFFC74C4FFD969F59A948F3E6EF0FFFFB143408DFBFFA48EFFFFC176FD7E -B6FFFF9999FFFD9A3E6AA43FFADC68F1EC67E2FFFA70CAFFB44355BB68E9FFDC553F62EA -E55CB4FFE759B5FFFFFFFB43B0FFFFC147424AC6FFB682C8434543415EF1FA884044B6FF -FFFFFFFFDF68EEFFFFFFFFFB72C7FFFF87AEC36F7AD7FFA98476BAA3E5D0AAB7AFE792BE -AEE1FFFFFFFFFFFFFEFEFFFFFFFFFFFF7EB6FFFFFF7F6BFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFBFCFEFFFFFEFCFEFFFEFBFB -FCFFFFFEFCFEFBFBFEFFFFFDFBFCFFFBFCFCFDFFFCFDFFFFFFFEFCFEFFFFFCFBFDFDFDFF -FDFCFFFEFCFDFFFEFCFEFDFDFDFBFCFFFFFFFEFBFBFDFFFFFDFCFFFFFDFCFEFCFDFFFFFD -FDF36DC2FFF18E57FBFEFCFEFEFCFEFFFEFCFEFFFEFBFCFEFCFEFFFEFCFBFCFFFDFAFDFF -FEFBFBFFFFFFFF9161FCFFFEFBFBFBFEFFFDFCFDFBFBFBFBFBFEFFFDFBFBFEFFFFFFFFFF -FEFCFEFFFFFFFFFEFCFDFFFFFCFFDB9AD2A5F18FB0B9FFC3AC8AB0C97BCA92C6D7FDFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFDFFFFEC48B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7E26 -573E29BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE55AABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFDB98FC9BA0B9B5BCFFC6AB869EB19CECDDB195D5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFA8A71F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6AB979ADCFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DFB6FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDC7FEBB179D8B37BD1A5DAC3B6CDADEBBCD79FC9FFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFF3B0EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFF1A3CDE98AFFB499A6D7FFFDC3A8ECFFD09FBCFBFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6A0B7FFBCC4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE7F9FF -F7F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFend -%%PageTrailer -%%Trailer -%%EOF diff --git a/medtool/doc/user/doxygen/figures/connectivity_arrays_small.png b/medtool/doc/user/doxygen/figures/connectivity_arrays_small.png deleted file mode 100644 index 5c28cadc3..000000000 Binary files a/medtool/doc/user/doxygen/figures/connectivity_arrays_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/connectivity_example.png b/medtool/doc/user/doxygen/figures/connectivity_example.png deleted file mode 100755 index 83eeea394..000000000 Binary files a/medtool/doc/user/doxygen/figures/connectivity_example.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/connectivity_example_small.png b/medtool/doc/user/doxygen/figures/connectivity_example_small.png deleted file mode 100644 index 6a64827c8..000000000 Binary files a/medtool/doc/user/doxygen/figures/connectivity_example_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/fine_mesh.png b/medtool/doc/user/doxygen/figures/fine_mesh.png deleted file mode 100644 index 01b64e4ef..000000000 Binary files a/medtool/doc/user/doxygen/figures/fine_mesh.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/geom.png b/medtool/doc/user/doxygen/figures/geom.png deleted file mode 100644 index db02a3b93..000000000 Binary files a/medtool/doc/user/doxygen/figures/geom.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/grid_example.png b/medtool/doc/user/doxygen/figures/grid_example.png deleted file mode 100755 index 00339ace3..000000000 Binary files a/medtool/doc/user/doxygen/figures/grid_example.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/interpolationimage.png b/medtool/doc/user/doxygen/figures/interpolationimage.png deleted file mode 100644 index a823f7f37..000000000 Binary files a/medtool/doc/user/doxygen/figures/interpolationimage.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/med-file-uml.png b/medtool/doc/user/doxygen/figures/med-file-uml.png deleted file mode 100644 index 9e1986ced..000000000 Binary files a/medtool/doc/user/doxygen/figures/med-file-uml.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/med-loader-adv-classes.png b/medtool/doc/user/doxygen/figures/med-loader-adv-classes.png deleted file mode 100644 index 2fd796fe1..000000000 Binary files a/medtool/doc/user/doxygen/figures/med-loader-adv-classes.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/medlayers.png b/medtool/doc/user/doxygen/figures/medlayers.png deleted file mode 100644 index 179ae0bcf..000000000 Binary files a/medtool/doc/user/doxygen/figures/medlayers.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/medlayers_70pc.png b/medtool/doc/user/doxygen/figures/medlayers_70pc.png deleted file mode 100644 index f31997693..000000000 Binary files a/medtool/doc/user/doxygen/figures/medlayers_70pc.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/mesh_splitted.png b/medtool/doc/user/doxygen/figures/mesh_splitted.png deleted file mode 100644 index 98a8518a4..000000000 Binary files a/medtool/doc/user/doxygen/figures/mesh_splitted.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/mesh_unsplitted.png b/medtool/doc/user/doxygen/figures/mesh_unsplitted.png deleted file mode 100644 index 338eeb62c..000000000 Binary files a/medtool/doc/user/doxygen/figures/mesh_unsplitted.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/polygon_connectivity.png b/medtool/doc/user/doxygen/figures/polygon_connectivity.png deleted file mode 100755 index a5b8f4252..000000000 Binary files a/medtool/doc/user/doxygen/figures/polygon_connectivity.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/polygon_connectivity_small.eps b/medtool/doc/user/doxygen/figures/polygon_connectivity_small.eps deleted file mode 100644 index cb0726271..000000000 --- a/medtool/doc/user/doxygen/figures/polygon_connectivity_small.eps +++ /dev/null @@ -1,15904 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: (ImageMagick) -%%Title: (polygon_connectivity_small.eps) -%%CreationDate: (Thu Feb 28 14:07:46 2008) -%%BoundingBox: 0 0 375 281 -%%HiResBoundingBox: 0 0 375.052 281 -%%DocumentData: Clean7Bit -%%LanguageLevel: 1 -%%Pages: 1 -%%EndComments - -%%BeginDefaults -%%EndDefaults - -%%BeginProlog -% -% Display a color image. The image is displayed in color on -% Postscript viewers or printers that support color, otherwise -% it is displayed as grayscale. -% -/DirectClassPacket -{ - % - % Get a DirectClass packet. - % - % Parameters: - % red. - % green. - % blue. - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/DirectClassImage -{ - % - % Display a DirectClass image. - % - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { DirectClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayDirectClassPacket } image - } ifelse -} bind def - -/GrayDirectClassPacket -{ - % - % Get a DirectClass packet; convert to grayscale. - % - % Parameters: - % red - % green - % blue - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/GrayPseudoClassPacket -{ - % - % Get a PseudoClass packet; convert to grayscale. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassPacket -{ - % - % Get a PseudoClass packet. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassImage -{ - % - % Display a PseudoClass image. - % - % Parameters: - % class: 0-PseudoClass or 1-Grayscale. - % - currentfile buffer readline pop - token pop /class exch def pop - class 0 gt - { - currentfile buffer readline pop - token pop /depth exch def pop - /grays columns 8 add depth sub depth mul 8 idiv string def - columns rows depth - [ - columns 0 0 - rows neg 0 rows - ] - { currentfile grays readhexstring pop } image - } - { - % - % Parameters: - % colors: number of colors in the colormap. - % colormap: red, green, blue color packets. - % - currentfile buffer readline pop - token pop /colors exch def pop - /colors colors 3 mul def - /colormap colors string def - currentfile colormap readhexstring pop pop - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { PseudoClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayPseudoClassPacket } image - } ifelse - } ifelse -} bind def - -/DisplayImage -{ - % - % Display a DirectClass or PseudoClass image. - % - % Parameters: - % x & y translation. - % x & y scale. - % label pointsize. - % image label. - % image columns & rows. - % class: 0-DirectClass or 1-PseudoClass. - % compression: 0-none or 1-RunlengthEncoded. - % hex color packets. - % - gsave - /buffer 512 string def - /byte 1 string def - /color_packet 3 string def - /pixels 768 string def - - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - x y translate - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - currentfile buffer readline pop - token pop /pointsize exch def pop - /Times-Roman findfont pointsize scalefont setfont - x y scale - currentfile buffer readline pop - token pop /columns exch def - token pop /rows exch def pop - currentfile buffer readline pop - token pop /class exch def pop - currentfile buffer readline pop - token pop /compression exch def pop - class 0 gt { PseudoClassImage } { DirectClassImage } ifelse - grestore -} bind def -%%EndProlog -%%Page: 1 1 -%%PageBoundingBox: 0 0 375 281 -userdict begin -DisplayImage -0 0 -375.052 281.289 -12.000000 -500 375 -0 -0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F6F6F6F6F6F6FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -C2C2C25858582F2F2F303030767676D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A61212122F2F2F4949493B3B3B -020202343434EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC4C4C41111114A4A4AE5E5E5FFFFFFF5F5F5717171070707979797FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF939393101010 -C4C4C4FFFFFFFFFFFFFFFFFFF4F4F4B4B4B4D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8D6D6D6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8393939414141D8D8D87B7B7B525252535353 -9F9F9FFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -8D8D8D282828E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F83838381515151F1F1F1A1A1A2727271F1F1F101010999999FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA8A8A8A080808181818E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8393939050505 -707070D3D3D3F3F3F3E3E3E35555550F0F0FA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD5D5D5373737252525353535161616E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE4E4E4E0E0E0 -DFDFDFEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F83636363D3D3DF7F7F7FFFFFFFFFFFFFFFFFF -D5D5D50E0E0E797979FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF717171505050C4C4C4 -747474131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE6E6E67E7E7E212121121212111111383838A0A0A0F8F8F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F94141413C3C3CF5F5F5FFFFFFFFFFFFFFFFFFDDDDDD101010797979FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9F2F2F2FFFFFF737373131313E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -7979790404043E3E3E7575757070701E1E1E0A0A0ABBBBBBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A60D0D0D -AEAEAEFCFCFCFFFFFFFEFEFEA3A3A3131313AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E22A2A2A717171EFEFEFFFFFFF -FFFFFFB8B8B8141414555555FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F04343431717176F6F6F969696818181 -1414144C4C4CF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF8F8F8D4D4D4E9E9E9FFFFFFFFFFFFFFFFFFF8F8F8353535424242 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEDFDFDF6B6B6B060606050505131313686868E0E0E0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC2323236C6C6CFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F2F2F2CDCDCDCBCBCBD4D4D4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFD8080801A1A1AD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD919191252525B5B5B5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE4E4E4858585242424B4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF919191464646E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D93E3E3E323232 -B5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC3C3C3 -AAACADB7B8B9DFDFDFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAF7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD9D9D93D3D3D646464F0F0F0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDEDE8E9899839B9D92AEB089A3A5829293C0C2C2 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -6868680404045454546666666464646464646161618F8F8FFDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F0EFEF8B9596A3C4C7BDE3E6BDE2E5BDE3E6B3D8DA859899CECFCFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E13838381F1F1F1D1D1D1C1C1C -1C1C1C1C1C1C1818185B5B5BFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C1C1869EA0BDE2E5BBE0E3 -BBDFE2BADFE2BCE1E4A5C6C98C9293FDFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBEAEAEAE8E8E8E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8EFEFEF -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -FBFBFBF4F4F4ECECECE4E4E491949494B1B3BDE2E5BBE0E3BBE0E3BBE0E3BBE0E3B1D4D7 -818B8CF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFC -F7F7F7EFEFEFE9E9E9DEDEDECFCFCFBFBFBFAEAEAE9E9E9E999999989898979797979797 -6F71718DA8ABBDE3E6BADFE2BBE0E3BBE0E3BBE0E3AED1D4828A8BF6F5F5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9 -F3F3F3EDEDEDE4E4E4D4D4D4C4C4C4B3B3B3A3A3A39C9C9C9A9A9A979797949494979797 -A5A5A5B5B5B5C5C5C5D5D5D5E0E0E0E8E8E8F2F2F2FDFDFDD6D6D6829496B8DDE0BBE0E3 -BBE0E3BBE0E3BDE2E595B2B4A4A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF6F6F6 -F1F1F1E9E9E9D9D9D9C9C9C9B9B9B9A9A9A9A1A1A19C9C9C979797929292929292A1A1A1 -B0B0B0BFBFBFCECECEDBDBDBE4E4E4EFEFEFF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFCACB0B089A0A2AED1D3B5D9DCB4D8DB99B7B98F999A -ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF8F8F8F5F5F5 -EEEEEEDEDEDECECECEBEBEBEAFAFAFA5A5A59E9E9E9898989191918F8F8F9D9D9DABABAB -BABABAC8C8C8D4D4D4E0E0E0EBEBEBF7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F8BABCBC848D8E7B898B6470719A9F9FE9E9E9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFBFBFBF8F8F8F2F2F2 -E3E3E3D3D3D3C4C4C4B5B5B5AAAAAAA1A1A19999999191918D8D8D9A9A9AA7A7A7B5B5B5 -C1C1C1CECECEDBDBDBE7E7E7F4F4F4FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEF4F4F4 -DCDBDB8C8C8CE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCFAFAFAF5F5F5E7E7E7 -D9D9D9CACACABBBBBBAFAFAFA5A5A59B9B9B9191918C8C8C979797A3A3A3AFAFAFBBBBBB -C9C9C9D6D6D6E3E3E3F0F0F0FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9ED7D7D7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFDFD -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF8F8F8EBEBEBDDDDDD -CFCFCFC1C1C1B5B5B5AAAAAA9E9E9E9292928C8C8C9595959F9F9FAAAAAAB5B5B5C3C3C3 -D1D1D1DFDFDFEDEDEDF9F9F9FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEAB0B2B28F9596979C9DC5C6C6F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F9C7C7C7999E9E8E9595ACAFAFE6E5E5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFBFBFBEFEFEFE1E1E1D5D5D5 -C8C8C8BBBBBBAEAEAEA1A1A19494948C8C8C9494949C9C9CA6A6A6AFAFAFBCBCBCCBCBCB -DADADAEAEAEAF6F6F6FAFAFAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCFCFCFA4A4A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D8D9D98894958FA9ACA2C2C59DBCBE869C9E9EA4A4F4F3F3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A0A5A6 -869B9D9CBBBDA2C3C590ACAE869395D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF2F2F2E5E5E5DADADACECECE -C1C1C1B3B3B3A5A5A59797978C8C8C9393939A9A9AA2A2A2AAAAAAB5B5B5C5C5C5D5D5D5 -E6E6E6F3F3F3F7F7F7FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4969696FBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F18C9697A5C7C9BDE2E5BCE1E4 -BCE1E5BBE0E38FA8ABB0B3B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7BABA8CA4A6BAE0E3BCE2E5BCE1E4BDE3E6 -A8CACD8A9595EEEEEEFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5EAEAEADFDFDFD4D4D4C7C7C7 -B8B8B8A9A9A99B9B9B8F8F8F9393939999999F9F9FA4A4A4B0B0B0C0C0C0D0D0D0E1E1E1 -EFEFEFF4F4F4F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1989898EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCACBCB819698BCE2E5BBE0E3BBE0E3BADFE2BBE0E3B1D5D87C8687 -ECECECF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 -F6F6F6EFEFEF7D8787AED1D4BBE0E3BADFE2BBE0E3BBE0E3BCE2E5869D9FA0A1A1BFBFBF -AEAEAE9F9F9F9292929494949898989C9C9CA0A0A0AAAAAABBBBBBCBCBCBDBDBDBEAEAEA -F1F1F1F6F6F6FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFD9C9C9CDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B5B5 -8DA7A9BCE2E5BADFE2BBE0E3BBE0E3BADFE2B8DDE0687678878686979797969696969696 -969696969696969696969696969696969696969696969696969696969696969696969696 -969696969696969696969696969696969696969696969696969696969696969696969696 -969696969696969696969696969696969696969696969696969696969696969696969696 -969696969696969696969696969696969696969696969696969696969696969696969696 -969696969696969696969696969696969696969696969696969696969696969696969696 -969696969696969696969696969696969696969696969696969696969696969696969696 -9696969696969696969696969696969696969696969696969696968C8B8B616D6EB8DDE0 -BADFE2BBE0E3BBE0E3BADFE2BCE2E58FABAD747878B7B7B7C5C5C5D6D6D6E5E5E5EDEDED -F3F3F3FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACC6C6C6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C5839A9CBDE2E5BBE0E3BBE0E3 -BBDFE2BBE0E3B3D8DB788384DEDDDDEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 -E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E2E1E1778283B1D5D8BBE0E3BADFE2BBE0E3BADFE2 -BCE2E589A2A4BBBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ACACACFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEBEAEA859192ADD0D3BCE2E5BBE0E3BBE0E3BCE2E595B2B4A3A7A8 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA9ADAD92AEB0BCE2E5BBE0E3BBE0E3BCE2E5B0D3D6859293E6E6E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE1E1E1969696FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CBCCCD8494959FBFC1AFD2D5ABCED190ACAE929A9BEDECECFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF939B9B -8FAAACABCDD0B0D3D69FBFC2859697C7C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF959595 -F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDDBDCDC787D7D697272 -848C8CACAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0AFB2B3747B7C646C6D939999 -D5D5D5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9C9C9CDFDFDFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A6C5C5C5FDFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7A2A1A1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA7A7A7CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFA9A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC3C3C3AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF -B4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC969696F2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA9C9C9CFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEDEDED929292F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC3C3C3B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB3B3B3C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -9A9A9AE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9CBCBCBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4D0D0D0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EDEDED979797EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D1D1D1A4A4A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE999999FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9D9D9DDADADAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA929292FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE979797E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6959595EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -ACACACC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFD929292E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFDA2A2A2D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE979797E0E0E0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8C8C8CEEEEEEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C0C0C0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF0F0F0979797EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F98C8C8CF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF -9A9A9AFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F4F4F4909090F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E3969696FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAA8A8A8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF939393F4F4F4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5909090F1F1F1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE9E9E9969696F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9EDBDBDBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF989898 -DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E4E4E4999999F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFAEAEAEC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2949494EEEEEEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9C9C9CF9F9F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B0B0B0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE0E0E09B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDADADA9F9F9FFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9D9D9DFCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCA7A7A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D5D5D5A2A2A2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF2F2F28E8E8EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0A5A5A5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA989898 -E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9C9C9CDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCACACAA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAACACACAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5929292EEEEEE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C5C5C5ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBDBDBDB4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29B9B9BF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B0B0B0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4 -A3A3A3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCECECEA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB939393F8F8F8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BBBBBBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B6B6B6BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFA919191EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9F9F9FD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -A5A5A5D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8909090EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFACACACC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4989898F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A7A7A7CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCECECEA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCFCFCFA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E3E3E3999999F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BABABAB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFD9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F78F8F8FEFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA3A3A3D3D3D3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -979797E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9D9D9DDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFA909090ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC929292E8E8E8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB3B3B3BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 -959595F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFB8D8D8DEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9AAAAAAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A5A5A5FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -8A8A8AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9D9D9DFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBBBBBBB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F48E8E8EF5F5F5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF1F1F1929292F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA7A7A7 -CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFEFEF919191F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE969696E2E2E2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA949494E8E8E8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 -959595F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECEC929292F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4989898F9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC4C4C4AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A2A2A2 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDDDDDD9C9C9CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D89F9F9F -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB6B6B6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8 -A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB979797F3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A4A4A4FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFB949494E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA979797E3E3E3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCDCDCDA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5A5A5 -CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F08F8F8FF7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8 -ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD9D9D99F9F9FFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3AEAEAEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD4D4D4A0A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBCBCBCB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -999999F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4717171 -7373737373737373737373737474747A7A7AE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAACACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 -B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7949494EAEAEAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6565650F0F0F131313131313131313141414 -0D0D0D101010D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFA9B9B9BDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BFBFBFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEBEBEBDFDFDFE0E0E0E0E0E0E2E2E2D4D4D44F4F4F898989FBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1909090F5F5F5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B6B6B6BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF2F2F26969693D3D3DE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9B9B9BFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA -CBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0A3A3A3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B8B8B131313 -C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C2C2C2B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE2E2E2989898F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4282828626262FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAC8C8C8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDA1A1A1D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1F1F1979797ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8B8B8B151515C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFA9D9D9DDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9D9D9D -DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE999999DDDDDDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4282828636363FAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2 -929292F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB979797E3E3E3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF8A8A8A161616C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0979797FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA939393E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC9C9C9AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -696969191919E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC5C5C5AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F98F8F8F -EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF989898FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E42C2C2C606060F9F9F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACAC -C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88A8A8AF4F4F4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE979797EFEFEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD3D3D30A0A0A888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9D9D9DDBDBDBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF4F4F48B8B8BF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFB999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB -929292CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF1F1F1959595EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8F -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CCCCCC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3959595 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8949494F9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ABABABFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE2E2E2999999FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDBDBDB9B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFADADADC5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9D9D9D -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCD6D6D6989898 -969696ABABABF1F1F1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB929292 -EEEDEDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9D9D9DDADADA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFAFAFA8B8B8B1D1D1D0404040404040909093F3F3FD4D4D4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BDBEBE656B6B8089899CA0A0D3D4D4FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1979797ECECECFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD1D1D1A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -868686070707626262C9C9C9C8C8C8797979171717717171FCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8A4AAAA889EA0A0C0C3A7C9CC9BBABD839596BDBFC0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE4E4E4959595FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA9A9A9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4656565727272F1F1F1FFFFFF -FFFFFFFFFFFF595959232323EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFC1C1889FA1BADFE2BCE2E5 -BCE1E4BDE2E5B3D7DA829294DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA6A6A6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C5AEAEAEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFEFFFFFFFEFEFEFFFFFFB9B9B9191919444444 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFCFC8C9292A6C7CABCE1E4BADFE2BBE0E3BADFE2BDE3E690ABAE -ACAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFC7A7A7A4848481616161E1E1ED7D7D7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9E4E4E4D1D1D1C7C7C7B4B4B4 -656F6FAFD1D4BBE0E3BBE0E3BBE0E3BBE0E3BCE2E59BB9BC9BA0A0FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9C9C9CDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAB6B6B6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC646464 -2B2B2B252525101010A2A2A2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBE7E7E7D6D6D6CDCDCDC1C1C1 -9B9B9B8080807C7C7C8282827070706B6B6B7F7F7FA3A3A36C7273A6C8CABCE1E4BADFE2 -BBE0E3BADFE2BDE3E68FABADADAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3989898EAEAEAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7F5F5F5E3E3E34E4E4E111111 -B3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE9E9E9DBDBDBD3D3D3C6C6C6 -9F9F9F8686868181818787876F6F6F6A6A6A7D7D7DA1A1A1A7A7A7B2B2B2CACACAE9E9E9 -F3F3F3F7F7F7FCFCFCFFFFFFC2C3C3879D9FB9DFE2BCE2E5BCE1E4BDE2E5B3D7DA829193 -DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE5E5E5979797F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB0B0B0C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA0707078E8E8EFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEBEBEBDFDFDFD8D8D8CACACA -A2A2A28B8B8B8787878686866E6E6E6868687C7C7C9B9B9BA0A0A0ACACACC7C7C7E7E7E7 -EFEFEFF4F4F4FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F9F9F9A9ADAD869C9EA0C0C3A8CACC9CBBBD839496C1C4C4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D0D0D0A3A3A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACC7C7C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6888888999999F8F8F8FFFFFF -FFFFFFFFFFFFC2C2C20B0B0B999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEEEEEEE4E4E4DEDEDECECECE -A7A7A79191918E8E8E8B8B8B6C6C6C6767677D7D7D9999999A9A9AA6A6A6C2C2C2E3E3E3 -EAEAEAF0F0F0F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9C4C5C5959A9A -6971717C7F80D6D7D7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BDBDBDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F96868680A0A0A868686E7E7E7E7E7E7D1D1D13939392D2D2D -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1E9E9E9E3E3E3D1D1D1 -ABABAB9797979393938989896C6C6C6666667C7C7C939393939393A1A1A1C0C0C0E1E1E1 -E6E6E6EDEDEDF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB2B2B2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA5A5A5D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F0F0F0676767101010191919191919151515212121B5B5B5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF4F4F4ECECECE8E8E8D3D3D3 -B1B1B19D9D9D9A9A9A8B8B8B6C6C6C6767677C7C7C8F8F8F8D8D8D9B9B9BBDBDBDDBDBDB -E1E1E1E9E9E9F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A0A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 -969696E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0D8D8D8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4B6B6B6696969 -676767818181DDDDDDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF7F7F7F0F0F0ECECECD6D6D6 -B6B6B6A3A3A39F9F9F8B8B8B6D6D6D6868687C7C7C8A8A8A878787979797BABABAD7D7D7 -DCDCDCE6E6E6F5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E8E8E8919191FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5989898F6F6F6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9D9D9DDDDDDDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9F4F4F4F1F1F1D9D9D9 -BBBBBBAAAAAAA6A6A68E8E8E6F6F6F6969697C7C7C858585818181919191B5B5B5D0D0D0 -D6D6D6E2E2E2F4F4F4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2929292F2F2F2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD3D3D3A1A1A1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFA989898E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF7F7F7F3F3F3DBDBDB -BFBFBFB0B0B0ABABAB8F8F8F7070706B6B6B7F7F7F8181817C7C7C8D8D8DB3B3B3CBCBCB -D1D1D1DFDFDFF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F89A9A9AE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9 -BABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9959595E9E9E9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCFAFAFAF6F6F6DEDEDE -C5C5C5B7B7B7B2B2B29191917272726E6E6E7F7F7F7C7C7C777777898989B1B1B1C4C4C4 -CCCCCCDBDBDBF3F3F3FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0A0A0D5D5D5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE7E6E6818181E6E5E5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF7F7F7DFDFDF -C9C9C9BDBDBDB6B6B6949494767676717171818181797979737373868686AEAEAEBFBFBF -C6C6C6D7D7D7F1F1F1FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC4C4C4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F7959595E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 -9DA2A27B87886B7A7B7C8686B7B9B9F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDF9F9F9E2E2E2 -CECECEC3C3C3BABABA9595957A7A7A757575808080747474707070838383A9A9A9B8B8B8 -C0C0C0D3D3D3F0F0F0FAFAFAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6999999 -F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC8B969699B7B9B5D9DCB8DDE0B0D4D7 -8AA2A4ABAEAFFDFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9E5E5E5 -D3D3D3CACACABFBFBF9898987E7E7E7A7A7A8484847272726D6D6D818181A7A7A7B1B1B1 -BBBBBBD1D1D1EDEDEDF8F8F8FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD1D1D1A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A0A0A0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA8ABAB94B0B2BDE2E5BBE0E3BBE0E2BBE0E3B8DDE0829697CECECEE9E9E9 -D8D8D8D0D0D0C3C3C39B9B9B8282827E7E7E8383836F6F6F6A6A6A7E7E7EA2A2A2AAAAAA -B5B5B5CDCDCDECECECF4F4F4F8F8F8FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4949494FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4869090AACDD0 -BCE1E4BBE0E3BBE0E3BADFE2BDE2E594B1B35D60606F6F6F6969697F7F7F9F9F9FA4A4A4 -AFAFAFC8C8C8E8E8E8F1F1F1F5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F28E8E8EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A3A3D1D1D1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0828D8EAED1D4BBE1E4BBE0E3BBE0E3BADFE2 -BDE2E597B5B8939696EEEEEEF2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F8979797E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA939393E8E8E8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFB949A9AA0C1C3BCE2E5BADFE2BADFE2BBE0E3BCE2E589A1A3BABCBCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA1A1A1D7D7D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE8E8E8989898F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D3D3839697 -B2D6D9BDE3E6BDE2E5BDE2E5A2C2C58E9798F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACC6C6C6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A0A0A0FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC1C3C4839293869FA18EA9AB849A9C -8E9798DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBABABAB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEE5E5E58C8D8D858788C7C8C8F0F0F0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA7A7A7CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFAEAEAEC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9A9A9AFCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC939393E7E7E7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A6CECECEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF0F0F08E8E8EF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECECEC959595F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA1A1A1D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8929292 -EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D6D6D6A0A0A0FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFA9B9B9BE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9E9E9EDBDBDBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2AFAFAFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7959595E9E9E9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFABABABC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFABABABC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF4F4F48F8F8FF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9 -B8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -959595E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EFEFEF8C8C8CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ABABABFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0919191F4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6939393FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDADADA9E9E9EFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD9D9D99F9F9FFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDADADA9D9D9DFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC -919191F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3 -AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CFCFCFA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88E8E8EF0F0F0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC5C5C5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B0B0B0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFC9B9B9BDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFC999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A8A8A8CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38F8F8F -F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AEAEAEC2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BBBBBBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9C9C9CFBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CBCBCBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC6C6C6ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC5C5C5AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D7D7D7A1A1A1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC3C3C3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -9D9D9DDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7969696F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7999999E5E5E5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F68D8D8DF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF5F5F58F8F8FF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF3F3F3949494EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFC969696E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0999999FBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0 -8F8F8FF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA8F8F8FFDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB1B1B1C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDFDFDF989898FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC4C4C4ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0D8D8D8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 -A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A3A3A3FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6919191EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ACACACFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3999999F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E5E5E5959595FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF3F3F3919191F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAAAAAAAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 -C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC929292E8E8E8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB2B2B2C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CACACAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA1A1A1D5D5D5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -A1A1A1D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA1A1A1D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5949494ECECECFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9E9E9E -DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3AEAEAE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE9E9E9929292FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79B9B9BE2E2E2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A3A3A3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE -A7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F3979797EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE0E0E09C9C9CF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BFBFBFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF949494 -F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE959595 -F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB909090FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB909090EBEBEBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5989898 -E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE4E4E4939393FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9C9C9CD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA919191FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D99D9D9D -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAE -C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD3D3D3A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC1C1C1B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD0D0D0A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1A1A1D3D3D3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE -9C9C9CFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF6F6F6999999E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB979797F2F2F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA949494F7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA0A0A0D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF8F8F8939393EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D79E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9D9D9DD9D9D9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -989898DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFBBBBBBB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99B9B9BE1E1E1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9CBCBCBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2A2A2D2D2D2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF4F4F4999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBCBCBCB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7999999E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0979797EEEEEE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CFCFCFA4A4A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEA969696F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB959595F6F6F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9B9B9BFDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D99C9C9CFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE5E5E5939393FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE8E8E8999999F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBFBFBFB4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD989898FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F5F5F5969696EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A4A4A4CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF969696E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9989898E3E3E3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC6C6C6AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5A5A5CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEBEBEB979797F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB8B8B8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB8B8B8BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB -9B9B9BFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA8A8A8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B0B0B0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA4A4A4CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9B9BD8D8D8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE7E7E7989898F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC969696 -E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC999999DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1989898EBEBEB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC979797F1F1F1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6999999E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC979797E1E1E1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDCDCDC9C9C9CFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0989898ECECECFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA0A0A0D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6ACACAC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEBEBEB979797F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4C0C0C0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC8C8C8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E5E5E5969696F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ADADADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFE969696E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF969696FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDADADA9B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF969696F0F0F0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD6D6D69D9D9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6959595 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9D9D9DFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CACACAA9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0979797EDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC8C8C8A9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B4B4B4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F99A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C4C4C4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB5B5B5BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9E -D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE989898E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A9A9A9CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC4C4C4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F2F2F2939393F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD6D6D6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC2C2C2B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9C9C9CF9F9F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF969696DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6 -9E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC9C9C9A9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -969696E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7939393FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B3B3B3C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3979797EBEBEBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFEFEF959595F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9B9B9BDBDBDBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -9A9A9AE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF5F5F5919191F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -999999F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FD6D6D6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 -9B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF999999FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA8A8A8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD9D9D99B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB5B5B5BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF -A3A3A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A4A4A4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA0A0A0 -D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDECECECE8E8E8E9E9E9E9E9E9E9E9E9 -E8E8E8EDEDEDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4AFAFAFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4939393FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8909090EFEFEFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF2F2F24747471A1A1A1C1C1C1C1C1C1C1C1C191919464646F4F4F4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB8B8B8BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F0F0F0929292F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE5E5E5979797F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA1C1C1C -4E4E4E656565646464646464626262808080F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAE -C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6999999E6E6E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA7A7A7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF939393060606CCCCCCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A3A3D1D1D1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA0A0A0D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BABABAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF929292090909C8C8C8C0C0C0A8A8A8BEBEBEF9F9F9FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF989898DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA8A8A8C9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA3A3A3D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC707070252525 -4646460F0F0F0000000D0D0D545454DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD929292 -E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9929292EBEBEB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB242424161616696969B8B8B8BABABA9A9A9A -1313134E4E4EF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6959595EBEBEBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9949494F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F8B9B9B9CBCBCBFDFDFDFFFFFFFFFFFFFFFFFFA2A2A2101010B4B4B4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEFEFEF979797EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE0E0E0979797FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD0D0D0A6A6A6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8050505989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8999999 -F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8FF8F8F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B8B8B8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBD7D7D7E3E3E3FFFFFFFFFFFFFFFFFFFFFFFF -C8C8C8050505989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E19B9B9BF9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6959595EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA5A5A5D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF0F0F03E3E3E323232D1D1D1FFFFFFFFFFFFF7F7F77777771B1B1BCCCCCCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD9D9D99D9D9DFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFB9F9F9FDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F9F9F9959595E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9797970D0D0D -2F2F2F7474747575755A5A5A0A0A0A767676FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A1A1A1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8CBCBCB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED929292F9F9F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6BABABA2929291212121111112C2C2C -929292F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8AAAAAAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDDDDDDDAEB0B1898C8C7F8181EEEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDE6E6E6E0E0E0DFDFDFE7E7E7FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBDBDBDB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC8C8C8ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBB9BBBB8292938FAAAC -94B3B5859C9E8C9697DEDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C1C1C1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9D9D9D -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC9CACB85999AB4D9DCBCE2E5BCE2E5BCE2E5A2C2C58D9798 -F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CDCDCDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE8E8E8EFAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 -8E9596A5C6C8BCE2E5BADFE2BBE0E3BBE0E3BCE2E5869EA0BFBFC0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9D9D9DD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F6919191EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC7F8C8DB1D4D7BBE0E3BBE0E3 -BBE0E3BBE0E3BDE3E694B1B4A5A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF939393E3E3E3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9C9C9C -DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF2F1F1858F8FADCFD2BBE1E4BBE0E3BBE0E3BADFE2BDE3E68CA8AB -A9ABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB909090EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CDCDCDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -A6AAAA94B1B3BDE3E6BBE0E3BBE0E3BCE1E4B6DBDE758688838484BBBBBBEBEBEBFEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF2F2F2949494EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB4B4B4BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB8F979897B4B6B2D6D9 -B7DCDFABCDD0869C9EB2B5B5ECEBEBBABABA979797AFAFAFE0E0E0FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA979797F3F3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C5 -AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA2A7A77B8787748183848E8FC1C3C3FAFAFA -FFFFFFFEFEFEF3F3F3C5C5C59C9C9CA5A5A5D6D6D6F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29A9A9AF7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBF2F2F2EFEEEEF6F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8D2D2D2A2A2A29C9C9CCBCBCBF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDBDBDB9E9E9EFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE9E9E9939393FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBDFDFDF -AAAAAA999999BEBEBEEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A1A1A1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 -8E8E8EF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8B6B6B6989898 -B3B3B3E5E5E5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB999999E2E2E2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC1C1C19A9A9AA8A8A8DBDBDB -FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5CECECE9E9E9EA0A0A0CFCFCFF6F6F6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BDBDBDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B2B2B2BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAD9D9D9A7A7A79B9B9BC3C3C3F1F1F1FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1B0B0B0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDE3E3E3B1B1B1979797B6B6B6E9E9E9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA3A3A3D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A3A3A3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC2C2C2A0A0A0A0A0A0CCCCCC -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EDEDEDBDBDBD979797ACACACDFDFDFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE989898DFDFDFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E4E4E4979797FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEAEAEA606060121212010101010101181818737373F4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4C8C8C8 -9C9C9CA2A2A2D3D3D3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8F8F8FEAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F48D8D8DF5F5F5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A6A6A0A0A0A -8F8F8FC3C3C3C3C3C37C7C7C121212B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD6D6D6A4A4A49B9B9B -C7C7C7F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F78F8F8FF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBFBFB949494E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE4B4B4B2E2E2EF4F4F4FFFFFFFFFFFFE6E6E6 -191919696969FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE1E1E1AEAEAE979797BBBBBBEBEBEB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF949494F3F3F3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEA2A2A2D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF676767242424E0E0E0FFFFFFFFFFFFCECECE161616838383FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEAEAEAB9B9B9979797B0B0B0E2E2E2FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE6E6E6989898F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C1C1C1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB555555 -3636365656565656562F2F2F6A6A6AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEF2F2F2C4C4C49B9B9BA5A5A5D6D6D6FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DDDDDD9D9D9DFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C94B4B4B1A1A1A2727272626261A1A1A -595959D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF7F7F7D2D2D2A2A2A29D9D9DCCCCCCF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A2A2A2FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD0D0D0A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF5F5F5494949272727C8C8C8F2F2F2F2F2F2B7B7B71A1A1A626262FBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -DDDDDDA9A9A9999999C0C0C0EDEDEDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E09B9B9BFAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C10707079E9E9E -FFFFFFFFFFFFFFFFFFFFFFFF818181111111D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE7E7E7B4B4B4 -989898B3B3B3E5E5E5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF919191F5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC0101019B9B9BFFFFFFFFFFFFFFFFFFFFFFFF -7E7E7E0A0A0AD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEEEEEEC1C1C19A9A9AA9A9A9 -DDDDDDFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAB8B8B8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFB909090EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDBDBDB2D2D2D262626C2C2C2EDEDEDEEEEEEB0B0B01A1A1A404040E9E9E9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5CCCCCC9E9E9EA0A0A0D1D1D1F7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9E9E9ED9D9D9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC2E2E2E -1515152020202020201212123F3F3FDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD9D9D9A6A6A69B9B9BC3C3C3F2F2F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -A6A6A6CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC6C6C6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E38A8A8A5C5C5C5C5C5C989898 -E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDE2E2E2B1B1B1989898B8B8B8EAEAEAFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9E9E9ED9D9D9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEBEBEBBCBCBC979797ADADADE0E0E0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFD949494E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA6A6A6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 -C8C8C89B9B9BA4A4A4D3D3D3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -8C8C8CEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9D9D9DFAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9D3D3D3A4A4A4 -9C9C9CC8C8C8F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38F8F8FF4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F9F9F98888889B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE9E9E98A8989DFDEDEFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDFDFDFACACAC979797BCBCBC -ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE9E9E9959595F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9848484020202747474FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE8D9394606D6D -7A8889888F90CFD0D0FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEAEAEAB7B7B7989898B1B1B1E2E2E2FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 -9B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC7C7C7121212000000757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDBDBDB859394A2C2C5B5DADDB5DADCA8CACC869899C7C9C9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEF1F1F1C3C3C39B9B9BA7A7A7D9D9D9F9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A1A1A1FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4333333 -3E3E3E0C0C0C747474FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -8F9697A3C3C6BCE2E5BBE0E3BBE0E3BCE1E4AFD2D5839091EBEBEBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F7D0D0D0A0A0A09E9E9ECDCDCDF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCECECEA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA5C5C5C1F1F1FA4A4A4161616737373FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E47D8B8DB7DCDFBADFE2BBE0E3 -BBE0E3BBE0E3BDE2E5809596CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFADCDCDCA9A9A99A9A9AC1C1C1EEEEEEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4 -ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9292921E1E1EBBBBBBE1E1E1131313737373FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF4F4F4EBEBEBE2E2E2 -D5D5D5C3C3C3B2B2B28888886B7C7DBADFE2BADFE2BBE0E3BBE0E3BADFE2BDE2E5859C9E -C3C3C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE5E5E5 -B3B3B3999999B5B5B5E7E7E7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB5B5B5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9313131676767FBFBFB -E0E0E0131313737373FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF6F6F6EEEEEEE6E6E6 -D8D8D8C5C5C5B4B4B4A2A2A29999999898989797979696969E9E9EB1B1B1C2C2C2CAC9C9 -788484B2D6D9BBE0E3BADFE2BADFE2BBE0E3BADFE27B8D8FDBDADAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEDEDEDBFBFBF999999 -A9A9A9DEDEDEFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE2E2E23B3B3B525252E0E0E0F1F1F1D1D1D11212126C6C6CF3F3F3 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7F1F1F1E9E9E9 -DBDBDBC9C9C9B6B6B6A5A5A59C9C9C9999999696969393939C9C9CAEAEAEBFBFBFD0D0D0 -DEDEDEE8E8E8F3F3F3FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFB3B6B68CA5A7B9DEE1BDE2E5 -BDE2E5BCE1E498B6B89DA3A4F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4CCCCCC9D9D9DA2A2A2D2D2D2 -F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA -CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC -0303031919192424242323231E1E1E0202020F0F0F303030D9D9D9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9F3F3F3EDEDED -DDDDDDCBCBCBB9B9B9A8A8A8A0A0A09A9A9A9595959191919B9B9BABABABBDBDBDCDCDCD -DADADAE5E5E5F1F1F1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A6AAAA8093958FAAAD92ADB0829799989FA0ECECEC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD6D6D6A5A5A59B9B9BC6C6C6F3F3F3FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D45F5F5F5B5B5B5A5A5A5A5A5A -4F4F4F060606282828656565E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF6F6F6EFEFEF -DFDFDFCECECEBDBDBDACACACA3A3A39B9B9B9494948E8E8E9A9A9AAAAAAABABABAC9C9C9 -D6D6D6E3E3E3F0F0F0FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFAD4D4D4AEB0B1AAADADCACACBF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDE1E1E1AFAFAF979797B9B9B9EAEAEAFEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFC999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0131313737373FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF8F8F8F2F2F2 -E1E1E1D1D1D1BFBFBFB0B0B0A6A6A69C9C9C9393938D8D8D999999A7A7A7B6B6B6C5C5C5 -D3D3D3E1E1E1EEEEEEFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEEBEBEBBABABA989898AEAEAEE1E1E1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA909090 -EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE0E0E0151515757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFAFAFAF3F3F3 -E3E3E3D3D3D3C3C3C3B4B4B4A8A8A89D9D9D9292928C8C8C989898A5A5A5B3B3B3C1C1C1 -CFCFCFDEDEDEEDEDEDFAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F3F3F3C6C6C69B9B9BA4A4A4D6D6D6FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88B8B8BF4F4F4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6BDBDBDD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFCF4F4F4 -E5E5E5D6D6D6C7C7C7B8B8B8ABABAB9F9F9F9292928C8C8C989898A4A4A4AFAFAFBCBCBC -CCCCCCDCDCDCECECECF9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8D3D3D3 -A2A2A29C9C9CC9C9C9F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEFEFEF909090F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDF5F5F5 -E7E7E7D9D9D9CACACABCBCBCAEAEAEA0A0A09292928D8D8D979797A2A2A2ACACACB9B9B9 -C9C9C9D9D9D9EAEAEAF7F7F7FAFAFAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDFDFDFACACAC989898 -BEBEBEEDEDEDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5979797 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF6F6F6 -E9E9E9DCDCDCCECECEC0C0C0B1B1B1A1A1A19292928F8F8F9797979F9F9FA8A8A8B4B4B4 -C6C6C6D7D7D7E8E8E8F5F5F5F9F9F9FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8B6B6B6989898B2B2B2E4E4E4 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA9E9E9EFCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -EAEAEADFDFDFD3D3D3C4C4C4B3B3B3A3A3A39393939191919797979E9E9EA4A4A4B1B1B1 -C2C2C2D5D5D5E6E6E6F2F2F2F7F7F7FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF0F0F0C2C2C29B9B9BA7A7A7D9D9D9FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD1D1D1A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7 -EDEDEDE2E2E2D7D7D7C7C7C7B6B6B6A5A5A59494949393939797979C9C9CA1A1A1AEAEAE -C0C0C0D2D2D2E4E4E4EFEFEFF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6F6F6CFCFCFA0A0A09F9F9FCFCFCFF5F5F5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ACACAC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8 -EFEFEFE5E5E5DBDBDBCBCBCBB9B9B9A7A7A79797979595959797979A9A9A9C9C9CABABAB -BDBDBDCFCFCFE1E1E1ECECECF3F3F3FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFADADADAA7A7A79A9A9AC2C2C2F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9 -F1F1F1E8E8E8DFDFDFCDCDCDBBBBBBAAAAAA9A9A9A989898989898989898999999A8A8A8 -BBBBBBCCCCCCDEDEDEE8E8E8F0F0F0F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -E5E5E5B2B2B2979797B6B6B6E8E8E8FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB6B6B6BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFA -F3F3F3ECECECE2E2E2D1D1D1BEBEBEACACAC9D9D9D9A9A9A979797959595969696A7A7A7 -B8B8B8C9C9C9DADADAE5E5E5EEEEEEF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBDBDBD -989898ABABABDFDFDFFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2CBCBCB7D7F7FA1A2A2 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFB -F5F5F5EFEFEFE5E5E5D3D3D3C2C2C2AFAFAFA1A1A19C9C9C989898939393949494A4A4A4 -B5B5B5C6C6C6D6D6D6E1E1E1ECECECF7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4CACACA9C9C9CA2A2A2 -D3D3D3F9F9F9FFFFFFDBDBDB8D969783989A89A4A68297998B9596D7D8D8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -F7F7F7F2F2F2E8E8E8D6D6D6C4C4C4B2B2B2A5A5A59E9E9E989898919191939393A2A2A2 -B2B2B2C3C3C3D2D2D2DEDEDEEAEAEAF6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9D6D6D6A4A4A49D9D9DB8B8B8879293 -A4C5C7BBE1E4BCE2E5BCE1E4A6C7CA869394E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -F9F9F9F5F5F5EAEAEAD8D8D8C7C7C7B6B6B6A9A9A9A0A0A09898988F8F8F919191A0A0A0 -B0B0B0BFBFBFCECECEDBDBDBE8E8E8F5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE1E1E17F81818DA9ABBDE3E6BBE0E3BBE0E3BADFE2 -BDE3E693B0B29B9E9EDDDDDDCACACAB9B9B9ACACACA2A2A29898988E8E8E9191919F9F9F -ADADADBBBBBBCACACAD8D8D8E6E6E6F4F4F4FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFCFBFB949999A2C2C5BCE1E5BBE0E3BBE0E3BBE0E3BCE1E4A5C6C96168699A9999 -ABABABB7B7B7C6C6C6D5D5D5E4E4E4F4F4F4FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD969A9A9FBFC1 -BCE2E5BADFE2BBE0E3BBE0E3BCE2E5A2C2C5919697F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9BBBB8AA2A4BCE1E5BBE0E3BADFE2BBE0E3 -BDE2E58CA6A8B5B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF4F4F4969D9E94B1B3B6DBDEBBE0E4B7DCDF97B4B7929A9BF1F1F1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE -A3A8A87987887B8C8D788788A0A5A6EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEAEAEADCDCDCE9E9E8 -FBFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - -end -%%PageTrailer -%%Trailer -%%EOF diff --git a/medtool/doc/user/doxygen/figures/polygon_connectivity_small.png b/medtool/doc/user/doxygen/figures/polygon_connectivity_small.png deleted file mode 100644 index c0d84ccab..000000000 Binary files a/medtool/doc/user/doxygen/figures/polygon_connectivity_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/polyhedron_connectivity.png b/medtool/doc/user/doxygen/figures/polyhedron_connectivity.png deleted file mode 100755 index f7d579691..000000000 Binary files a/medtool/doc/user/doxygen/figures/polyhedron_connectivity.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/polyhedron_connectivity_small.eps b/medtool/doc/user/doxygen/figures/polyhedron_connectivity_small.eps deleted file mode 100644 index 25b81ec07..000000000 --- a/medtool/doc/user/doxygen/figures/polyhedron_connectivity_small.eps +++ /dev/null @@ -1,15904 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: (ImageMagick) -%%Title: (polyhedron_connectivity_small.eps) -%%CreationDate: (Thu Feb 28 14:07:37 2008) -%%BoundingBox: 0 0 375 281 -%%HiResBoundingBox: 0 0 375.052 281 -%%DocumentData: Clean7Bit -%%LanguageLevel: 1 -%%Pages: 1 -%%EndComments - -%%BeginDefaults -%%EndDefaults - -%%BeginProlog -% -% Display a color image. The image is displayed in color on -% Postscript viewers or printers that support color, otherwise -% it is displayed as grayscale. -% -/DirectClassPacket -{ - % - % Get a DirectClass packet. - % - % Parameters: - % red. - % green. - % blue. - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/DirectClassImage -{ - % - % Display a DirectClass image. - % - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { DirectClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayDirectClassPacket } image - } ifelse -} bind def - -/GrayDirectClassPacket -{ - % - % Get a DirectClass packet; convert to grayscale. - % - % Parameters: - % red - % green - % blue - % length: number of pixels minus one of this color (optional). - % - currentfile color_packet readhexstring pop pop - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/GrayPseudoClassPacket -{ - % - % Get a PseudoClass packet; convert to grayscale. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - color_packet 0 get 0.299 mul - color_packet 1 get 0.587 mul add - color_packet 2 get 0.114 mul add - cvi - /gray_packet exch def - compression 0 eq - { - /number_pixels 1 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add def - } ifelse - 0 1 number_pixels 1 sub - { - pixels exch gray_packet put - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassPacket -{ - % - % Get a PseudoClass packet. - % - % Parameters: - % index: index into the colormap. - % length: number of pixels minus one of this color (optional). - % - currentfile byte readhexstring pop 0 get - /offset exch 3 mul def - /color_packet colormap offset 3 getinterval def - compression 0 eq - { - /number_pixels 3 def - } - { - currentfile byte readhexstring pop 0 get - /number_pixels exch 1 add 3 mul def - } ifelse - 0 3 number_pixels 1 sub - { - pixels exch color_packet putinterval - } for - pixels 0 number_pixels getinterval -} bind def - -/PseudoClassImage -{ - % - % Display a PseudoClass image. - % - % Parameters: - % class: 0-PseudoClass or 1-Grayscale. - % - currentfile buffer readline pop - token pop /class exch def pop - class 0 gt - { - currentfile buffer readline pop - token pop /depth exch def pop - /grays columns 8 add depth sub depth mul 8 idiv string def - columns rows depth - [ - columns 0 0 - rows neg 0 rows - ] - { currentfile grays readhexstring pop } image - } - { - % - % Parameters: - % colors: number of colors in the colormap. - % colormap: red, green, blue color packets. - % - currentfile buffer readline pop - token pop /colors exch def pop - /colors colors 3 mul def - /colormap colors string def - currentfile colormap readhexstring pop pop - systemdict /colorimage known - { - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { PseudoClassPacket } false 3 colorimage - } - { - % - % No colorimage operator; convert to grayscale. - % - columns rows 8 - [ - columns 0 0 - rows neg 0 rows - ] - { GrayPseudoClassPacket } image - } ifelse - } ifelse -} bind def - -/DisplayImage -{ - % - % Display a DirectClass or PseudoClass image. - % - % Parameters: - % x & y translation. - % x & y scale. - % label pointsize. - % image label. - % image columns & rows. - % class: 0-DirectClass or 1-PseudoClass. - % compression: 0-none or 1-RunlengthEncoded. - % hex color packets. - % - gsave - /buffer 512 string def - /byte 1 string def - /color_packet 3 string def - /pixels 768 string def - - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - x y translate - currentfile buffer readline pop - token pop /x exch def - token pop /y exch def pop - currentfile buffer readline pop - token pop /pointsize exch def pop - /Times-Roman findfont pointsize scalefont setfont - x y scale - currentfile buffer readline pop - token pop /columns exch def - token pop /rows exch def pop - currentfile buffer readline pop - token pop /class exch def pop - currentfile buffer readline pop - token pop /compression exch def pop - class 0 gt { PseudoClassImage } { DirectClassImage } ifelse - grestore -} bind def -%%EndProlog -%%Page: 1 1 -%%PageBoundingBox: 0 0 375 281 -userdict begin -DisplayImage -0 0 -375.052 281.289 -12.000000 -500 375 -0 -0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE7E7E7DDDDDDE5E5E5FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF4F4F49696964343432E2E2E333333C9C9C9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9282828 -BFBFBFE2E2E2525252636363FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C48D8D8D8C8C8C -B4B4B4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3434343797979FFFFFFFFFFFFCFCFCF868686 -F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBDBDBD3030305050505959592424249F9F9FFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFAEAEAE292929B4B4B49A9A9AAFAFAFF5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 -434343B7B7B7F9F9F9FFFFFFA6A6A6252525CBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD797979101010424242 -545454232323555555F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6CECECEF8F8F8FFFFFFFFFFFF -F6F6F63B3B3BBCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF2F2F22B2B2B3C3C3CD3D3D3FFFFFFBABABA252525AFAFAF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFB -F9F9F9FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD414141CFCFCFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F2F2F2343434A6A6A6FFFFFFFFFFFFFFFFFF555555989898FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D78989899595959B9B9BA5A5A5B2B2B2 -C3C3C3DEDEDEF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF8383836D6D6DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2373737C5C5C5FFFFFF -FFFFFFF0F0F04E4E4EAEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBDBDBDA2A2A2EBEBEBDEDEDED1D1D1BFBFBFAFAFAF9B9B9B909090A9A9A9 -CFCFCFF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9C9C9C -686868EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE7C7C7C646464F4F4F4F2F2F26161614B4B4BF6F6F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBEEEEEECCCCCCA6A6A6949494B8B8B8E9E9E9 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9C9C9C676767EAEAEAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD9D9D93838384444444343433A3A3AD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDECECECBCBCBC999999B4B4B4ECECECFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFD9E9E9E6A6A6AEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7949494 -949494D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF2F2F2C1C1C19C9C9CC8C8C8F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD999999484848C7C7C7DDDDDD -DBDBDBDCDCDCF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFECECECAEAEAEABABABECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE4E4E4353535252525333333313131313131353535CCCCCCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD0D0D0 -A2A2A2DBDBDBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -E5E5E5E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A8A8A8D3D3D3FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFADADADCCCCCCFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F3AEAEAED0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0 -A9A9A9D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A1A1A1E9E9E9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A8A8A8F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB8B8B8BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9B -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F4F4DBDBDBD6D6D6E6E5E5FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA9A9A9FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -D8D8D88E97977D8F907D90927F8D8EADB0B0F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBDBDBD9A9A9AE3E3E3E8E8E8F1F1F1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F99E9E9EDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C9C9879798A5C6C9B8DDE0B9DEE1 -B4D8DB93AEB099A0A1F1F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF979797 -9C9C9C989898959595939393A9A9A9CBCBCBE4E4E4F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CCCCCCA9A9A9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE7E7E7859293ADD0D3BCE1E4BBE0E3BBE0E3BBE0E3BBE1E490ABADADB0B1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9F4F4F4EFEFEFE6E6E6 -CBCBCBA8A8A8999999969696B1B1B1E2E2E2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6989898E7E7E7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8ABAB94AFB2 -BCE1E5BBE0E3BBE0E3BBE0E3BADFE2BBE0E3B5D9DC7F8E8FE5E5E5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7E7E7E7 -C2C2C29B9B9BA2A2A2D3D3D3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFBFB868D8DA9CBCEBBE0E3BBE0E3BBE0E3BBE0E3 -BBE0E3BADFE2BBE1E4839B9CC4C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7D4D4D4A3A3A3 -A0A0A0DADADAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE2E2E29B9B9BF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF5F5F5838C8CAED1D4BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BDE2E5849DA0 -858686D6D6D6F0F0F0F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDCDCDCA3A3A3B5B5B5F1F1F1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB979797E2E2E2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFC8A9091A9CBCE -BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BADFE2BCE2E572898A1011111B1B1B3232325E5E5E -8D8D8DB3B3B3D4D4D4F1F1F1FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7C1C1C19D9D9DD6D6D6FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C3C3C3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F3F373767687A2A4BDE2E5BBE0E3BBE0E3BBE0E3 -BBE0E3BBE0E3B3D7DA7785869797977575754949492929290D0D0D0D0D0D1D1D1D353535 -6060608F8F8FB7B7B7D5D5D5F2F2F2FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE5E5E5A9A9A9CACACAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD1D1D1A3A3A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -CECECE5A5A5A0D0D0D465152ACCED1BCE2E5BBE0E3BADFE2BBE0E3BCE1E48EA8AAB4B6B7 -FFFFFFFFFFFFF7F7F7E1E1E1C8C8C89F9F9F7373734747472727270D0D0D0B0B0B1E1E1E -373737636363919191BABABAD7D7D7F2F2F2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F3F3F3B2B2B2C1C1C1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4989898 -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE8E8E8E202020161616808080B8B9B9 -8795969EBDBFB6DBDEB9DEE1AFD3D6738A8C4D5353E3E3E3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF8F8F8DFDFDFC6C6C69D9D9D6F6F6F4545452525250D0D0D0A0A0A -202020393939646464939393BCBCBCD9D9D9F2F2F2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B9B9B9B8B8B8 -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0979797EDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAC0C0C04848480A0A0A4B4B4BC2C2C2FBFBFBFFFFFFE3E3E3989E9E7683846A787A -838D8E6769690C0C0C989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8DDDDDDC2C2C29D9D9D6D6D6D4141412424240E0E0E -0909092222223C3C3C676767969696BFBFBFDBDBDBF2F2F2FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBBBBBBBBBBBBFDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFB969696E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E47C7C7C161616212121929292 -EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBE6E5E5D4D3D3F5F5F5E6E6E53C3C3C292929 -D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7DDDDDDBEBEBE9C9C9C6B6B6B3F3F3F232323 -0F0F0F090909232323404040676767989898C1C1C1DCDCDCF2F2F2FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAAFAFAFCACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF979797 -DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF6F6F6AFAFAF3838380C0C0C5B5B5BD0D0D0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F3E4E4E4FFFFFFFFFFFFB0B0B00F0F0F6C6C6CF9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF5F5F5DDDDDDBABABA9898986A6A6A3C3C3C -2020201111110909092323234545456B6B6B999999C5C5C5DEDEDEF3F3F3FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F2F2F2A5A5A5DCDCDCFFFFFFFFFFFFFFFFFFFFFFFF9E9E9ED5D5D5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76969690F0F0F2F2F2F -A4A4A4F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 -FFFFFFFFFFFFF7F7F7666666111111B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF3F3F3DCDCDCB8B8B8939393696969 -3A3A3A1D1D1D1212120C0C0C2222224848486F6F6F9A9A9AC7C7C7E1E1E1F2F2F2FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6A0A0A0ECECEC -FFFFFFFFFFFFFFFFFFA6A6A6CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFBABABA6969696B6B6B6B6B6B6E6E6EDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF1F1F19E9E9E2A2A2A1212126F6F6FDBDBDBFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0B6B6B6FFFFFFFFFFFFFFFFFFD4D4D4 -242424434343E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF2F2F2DADADAB6B6B68F8F8F -6666663A3A3A1A1A1A1212120E0E0E2323234A4A4A7373739C9C9CC8C8C8E4E4E4F3F3F3 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B1B1B1FEFEFEFFFFFFFFFFFFA8A8A8 -CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F25858586B6B6B808080 -7F7F7F818181DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCBCBCB5757570C0C0C -3E3E3EB3B3B3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF9191910B0B0B8D8D8DFEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF0F0F0D8D8D8B4B4B4 -8B8B8B6262623A3A3A1717171111111111112525254C4C4C777777A0A0A0C8C8C8E8E8E8 -F4F4F4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F69F9F9FDEDEDEFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD8D8D8373737DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEBEBEB8B8B8B1F1F1F191919828282E6E6E6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2CCCCCC -FFFFFFFFFFFFFFFFFFFFFFFFECECEC464646242424D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9EEEEEED7D7D7 -B0B0B08989895E5E5E3737371515151010101313132727274F4F4F7B7B7BA4A4A4C9C9C9 -E9E9E9F6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4 -A5A5A5FBFBFBFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -8484845B5B5B959595878787B0B0B0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFABDBDBD444444 -0B0B0B4D4D4DC4C4C4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCA7A7A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB8B8B8141414616161F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9ECECEC -D7D7D7ADADAD8585855B5B5B3535351313130F0F0F1515152828285252527D7D7DA8A8A8 -CCCCCCEBEBEBF7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA6A6A6D0D0D0FFFFFFA8A8A8 -CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F34E4E4E1A1A1A5D5D5D5D5D5D -2424249C9C9CFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE2E2E2797979151515242424949494EFEFEFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE7E7E7D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7070700F0F0F -ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 -E9E9E9D5D5D5ACACAC8181815858583333331212120E0E0E181818292929555555818181 -AAAAAACECECEECECECF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A1A1A1FFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE9E9E9676767969696FAFAFAFFFFFFA9A9A9252525CACACAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7ADADAD -3636360D0D0D5E5E5ED2D2D2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8F7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA2D2D2D383838E3E3E3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAE7E7E7D2D2D2ACACAC7C7C7C5555553131311111110C0C0C1A1A1A2C2C2C555555 -858585ADADADD0D0D0EDEDEDFAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8989898E7E7E7A9A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F63B3B3BBCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76767670D0D0D303030A6A6A6F5F5F5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDBCBCBCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9C9C9C0C0C0C818181FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFBE6E6E6CECECEAAAAAA7A7A7A5050503030301111110909091B1B1B2F2F2F -555555888888B1B1B1D1D1D1EEEEEEFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB9B9B9AAAAAA -CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3D9D9D9FFFFFFFFFFFFFFFFFF -DDDDDD2B2B2BBEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 -9A9A9A272727111111727272DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC8C8C8B5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0 -5252521C1C1CC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFAE6E6E6CBCBCBA8A8A87979794C4C4C2E2E2E1111110808081C1C1C -3333335757578A8A8AB5B5B5D2D2D2EFEFEFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E79898989D9D9DCCCCCCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF6D6D6D646464FBFBFBFFFFFFFFFFFF8080803B3B3BEEEEEEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC9C9C95252520B0B0B3F3F3FB7B7B7FAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3EFEFEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C31A1A1A555555F2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAE5E5E5C9C9C9A5A5A57979794949492B2B2B131313070707 -1B1B1B3737375A5A5A8A8A8AB9B9B9D4D4D4EEEEEEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF0F0F0767676868686CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3 -2B2B2B7A7A7AC6C6C68D8D8D252525B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E8E8E88787871C1C1C1A1A1A868686E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC7E7E7E0C0C0CA0A0A0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEFAFAFAE4E4E4C7C7C7A2A2A2777777484848272727131313 -0707071C1C1C3939395D5D5D8B8B8BBBBBBBD8D8D8EDEDEDFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2686868696969 -CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C13E3E3E363636626262 -C5C5C5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BABABA4040400B0B0B515151C7C7C7 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBBBBBBB9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE1E1E13737372D2D2DDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9E4E4E4C4C4C4A0A0A0737373474747252525 -1414140808081D1D1D3B3B3B6161618D8D8DBBBBBBDBDBDBEEEEEEFDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7A6A6A64F4F4FCFCFCFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCEFEFEFE7E7E7E5E5E5E9E9E9 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5F4F4F4F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDEDEDE747474121212272727989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECECCCCCC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A80E0E0E -737373FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF8F8F8E3E3E3C1C1C19E9E9E707070454545 -2222221414140A0A0A1D1D1D3E3E3E636363909090BDBDBDDDDDDDEFEFEFFCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E7E7E79A9A9ADFDFDF5E5E5ECBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEFEFEF -D7D7D7BABABA9F9F9F929292969696989898969696818181F7F7F7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6A8A8A83232320E0E0E636363 -D5D5D5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F55E5E5E151515BCBCBCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F6F6E3E3E3BEBEBE9A9A9A6F6F6F -4242422020201313130B0B0B1E1E1E424242666666939393BFBFBFDFDFDFF0F0F0FCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C3C3C3F8F8F8777777 -C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF4F4F4D3D3D3A4A4A49797979F9F9FB9B9B9D5D5D5E7E7E7 -F0F0F0F4F4F4F1F1F1878787F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDD4D4D46262620E0E0E343434AAAAAAF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCDCDCDD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCECECE2020204A4A4AEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF3F3F3E2E2E2BABABA959595 -6D6D6D4040401D1D1D1313130E0E0E1E1E1E4545456A6A6A969696C2C2C2E1E1E1F1F1F1 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE8E8E89A9A9AF3F3F3FDFDFD838383C5C5C5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF4F4F4DFDFDFDEDEDEDEDEDEDEDEDEE4E4E4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF -999999A3A3A3D1D1D1EFEFEFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF969696262626141414 -757575E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C1C1C1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -8B8B8B0B0B0B959595FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF0F0F0E0E0E0BABABA -9090906A6A6A3F3F3F1B1B1B1111111111111E1E1E474747707070989898C3C3C3E4E4E4 -F3F3F3FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 -C3C3C3FFFFFFFFFFFF8C8C8CC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A3A31C1C1C313131 -3131312E2E2E575757F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6C0C0C0999999B5B5B5E7E7E7FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBC7C7C75050500C0C0C424242B9B9B9FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEE4E4E4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7404040262626D5D5D5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEFEFEFDDDDDD -B9B9B98C8C8C6565653E3E3E1818180F0F0F1414142121214848487474749C9C9CC4C4C4 -E6E6E6F4F4F4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAA2A2A2F7F7F7FFFFFFFFFFFF8D8D8D -BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6414141777777E1E1E1DFDFDFDEDEDEE4E4E4FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDADADA -A0A0A0B5B5B5EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E78484841B1B1B -1C1C1C888888E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3101010686868F7F7F7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCEEEEEE -DBDBDBB7B7B78A8A8A6060603D3D3D1818180D0D0D151515242424484848777777A0A0A0 -C5C5C5E8E8E8F6F6F6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF4F4F4A1A1A1DEDEDEFFFFFFFFFFFFFFFFFF969696C1C1C1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F4F4F43F3F3FC1C1C1F5F5F5F2F2F2FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9C0C0C0A3A3A3DEDEDEFEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F9B7B7B73F3F3F0B0B0B535353C9C9C9FCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2D0D0D0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F8686868101010B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -EDEDEDD9D9D9B5B5B58989895C5C5C3A3A3A1818180A0A0A1616162727274B4B4B797979 -A4A4A4C7C7C7E8E8E8F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB8B8B8BFBFBFFFFFFF -FFFFFFFFFFFFFFFFFF9D9D9DD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D14646466E6E6E363636 -353535787878D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1F1F1AEAEAEB7B7B7F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD717171 -1111112828289A9A9AF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1CFCFCFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5262626 -404040E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FBFBFBEBEBEBD7D7D7B3B3B38686865959593636361818180808081717172929294E4E4E -7A7A7AA9A9A9CACACAE8E8E8FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDE5E5E5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8B2B2B2F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF969696 -E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9D9D9D1D1D1D7A7A7AC8C8C8CACACA666666464646F3F3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECABABABCDCDCDFDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A6A6A63030300D0D0D666666D7D7D7FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF1F1F1F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9595950B0B0B8A8A8AFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFCFCFCEAEAEAD4D4D4B0B0B08282825757573333331818180808081818182B2B2B -5050507D7D7DAAAAAACDCDCDE9E9E9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -747474E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5 -AAAAAAF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9969696E5E5E5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E7E7E7D8D8D8FFFFFFFFFFFFFFFFFFF3F3F3515151A9A9A9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEAEAEAA9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED2D2D2 -5F5F5F0C0C0C363636AEAEAEF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAEDEDED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEEEEEE4A4A4A1F1F1FCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDE9E9E9D1D1D1B0B0B0808080545454313131171717070707181818 -2E2E2E515151808080ACACACCFCFCFEAEAEAFCFCFCACACAC676767E3E3E3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8ACACACEEEEEEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F3979797EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF595959939393FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFA9A9A9D9D9D9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9393932222221414147A7A7AE3E3E3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD4D4D4FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BEBEBE1515155D5D5DF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDEAEAEACECECEAEAEAE7E7E7E5050502F2F2F171717070707 -1717173333334D4D4D4B4B4B616161BBBBBBECECECFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFED1D1D1AAAAAAEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7989898 -F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4D4D4D4FFFFFFFFFFFFFFFFFFFFFFFF595959939393 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6ADADADD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -C3C3C34C4C4C0B0B0B464646BEBEBEFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBEE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB7474740D0D0DA9A9A9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEFBFBFBEAEAEACBCBCBAAAAAA7E7E7E4C4C4C181818151515 -060606151515363636555555838383B1B1B1D4D4D4E5E5E5BDBDBDAFAFAFF2F2F2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A3A3A3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B0B0B0282828BDBDBDFFFFFFFFFFFFBDBDBD3E3E3ED3D3D3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -B7B7B7C1C1C1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E58080801717171E1E1E8C8C8CECECEC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD2E2E2E363636E1E1E1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6959595C3C3C36666666B6B6B4D4D4D282828 -1919190B0B0B1717172E2E2E2F2F2F7C7C7CB5B5B5D6D6D6EBEBEBFCFCFCFFFFFFFFFFFF -FFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA868686252525585858 -5959593D3D3D878787FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0AAAAAAF9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8B3B3B33B3B3B0C0C0C575757CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBABABAE8E8E8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA1A1A10C0C0C7C7C7CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFCA4A4A4D3D3D3FCFCFC9B9B9BE0E0E0FAFAFAEBEBEBBDBDBD6363634747474B4B4B -2727271717170C0C0C1717173939395F5F5F868686B5B5B5DBDBDBEBEBEB969696E1E1E1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8ABABAB919191939393D3D3D3FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEDEDED9D9D9DE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDADADA6C6C6C1111112C2C2C9E9E9E -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFB9C9C9CDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2565656 -1A1A1AC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A0A0A0FAFAFAFBFBFB -9A9A9AE2E2E2F4F4F4C9C9C99F9F9FBCBCBCEFEFEFF6F6F6E7E7E7C7C7C79F9F9F757575 -4B4B4B2222221414140E0E0E191919393939373737828282B6B6B6DDDDDDEEEEEEFAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C3C3C3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF2F2F2A1A1A12D2D2D1010106A6A6AD8D8D8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDDADADAF2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C71C1C1C515151F0F0F0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F9A4A4A4D6D6D6FFFFFFFBFBFB9090909F9F9F9A9A9AACACAC -E4E4E4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF4F4F4E5E5E5C4C4C49C9C9C -7272723535351818181313131010101A1A1A3D3D3D6565658F8F8FB7B7B7DEDEDEF0F0F0 -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9E9E9EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCCFCFCF5A5A5A0C0C0C393939 -AFAFAFF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEDEDEDFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFC8080800C0C0C9C9C9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2 -A4A4A4FCFCFCFFFFFFFDFDFDB7B7B7B6B6B6EAEAEAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7949494CACACAC3C3C3 -9999996E6E6E4545452020201010101212121B1B1B404040686868939393BABABADFDFDF -F2F2F2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9BFC0C1B1B3B3CCCDCDF4F4F4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEA9A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF1F1F1E5E5E5 -D5D5D5C6C6C6BFBFBF7B7B7BF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECEC9191912020201616167D7D7DE3E3E3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F8A3A3A3E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E3E3E33838382D2D2DDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A0A0A0DADADAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDADADA9F9F9FFBFBFBFFFFFFFFFFFFFCFCFCF0F0F0E2E2E2 -C0C0C09696966B6B6B4343431E1E1E0E0E0E1313131D1D1D4242426C6C6C969696BDBDBD -E0E0E0F4F4F4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFBC5C6C6828F90869EA08DA8AA819697909999DDDEDEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3999999F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEF3F3F3DCDCDCBABABAA1A1A1959595929292A1A1A1AEAEAEAFAFAFC3C3C3 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC0C0C04A4A4A0B0B0B -484848C0C0C0FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A7A7A7E7E7E7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACAC0F0F0F727272 -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCDCDCDAAAAAAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -AAAAAACBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEFEFEF -DFDFDFC0C0C09292926767674141411D1D1D0B0B0B141414202020424242707070999999 -C0C0C0E3E3E3F6F6F6FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBEBE869A9CB1D4D7 -BCE2E5BCE1E4BBE1E4A5C5C8879596DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE4E4E4B2B2B29595959B9B9B -B9B9B9D5D5D5EFEFEFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE4E4E47E7E7E1717172020208E8E8EECECECFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF1F1F1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6616161141414B9B9B9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F69C9C9CE0E0E0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAA1A1A1F9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -EFEFEFDBDBDBBFBFBF8F8F8F6262623F3F3F1C1C1C090909141414242424434343737373 -9D9D9DC1C1C1E4E4E4F9F9F9E0E0E0839293B2D6D9BCE1E4BADFE2BADFE2BBE0E3BDE2E5 -A0C0C3959C9CF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 -959595EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFAD3D3D3A4A4A4999999C2C2C2ECECECFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8AFAFAF393939 -0B0B0B595959CECECEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9D2D2D2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCFCFCF232323454545EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF8F8F8A1A1A1DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFDEFEFEFD8D8D8BCBCBC8F8F8F5D5D5D3C3C3C1D1D1D070707131313272727474646 -53555592AEB0BDE2E5BADFE2BBE0E3BBE0E3BBE0E3BBE0E3BADFE27D8F91D8D8D8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2A3A3A3FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8A8A8A8A4A4A4D3D3D3 -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDADADA6969691010102C2C2CA1A1A1F4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3969696E9E9E9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8E8E8E -0B0B0B909090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F3F3F39C9C9CE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6AEAEAE -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDEFEFEFD6D6D6B9B9B98E8E8E5C5C5C3535352D3333A2C3C6BCE2E5BBE0E3 -BBE0E3BBE0E3BBE0E3BADFE2BCE2E589A1A4BBBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF8F8F8C3C3C39C9C9CD1D1D1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F29E9E9E -2A2A2A1010106D6D6DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7BFBFBFF1F1F1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA444444232323D2D2D2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B0B0B0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8A0A0A0EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEEAE9E9818989A5C6C8BCE1E4BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3 -BCE2E58CA6A7B5B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9999999 -E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA8A8A8B3B3B3 -F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCCCCCC5555550B0B0B3C3C3CB3B3B3F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB7B7B7121212646464F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF2F2F29A9A9AE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F3F3F3A6A6A6DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -9EA2A29BBABCBDE2E5BADFE2BBE0E3BBE0E3BBE0E3BBE0E3BCE2E5829799C9CACAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB919191F9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A6A6A6D3D3D3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA -8B8B8B1D1D1D191919818181E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3B2B2B2F3F3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFA6E6E6E0F0F0FAEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBD -B7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B2B2B2C9C9C9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE2E2E2636363677C7EBCE1E4BBE0E3 -BADFE2BBE0E3BADFE2BCE1E4AED2D4848F90EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD6D6D6A0A0A0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA -A5A5A5E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BDBDBD4545450A0A0A4B4B4BC3C3C3FBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF989898EFEFEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D92A2A2A3C3C3C -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9A9A9AEDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBBFBFBFBABABAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF6F6F6ACACAC3737370101011A1F2090ADB0BCE2E5BCE1E4BCE1E4BCE2E5B7DBDE -879D9FBFC1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B1B1B1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A8A8A8E9E9E9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -E1E1E1797979151515232323949494EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFADDDDDDF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9999990B0B0B848484FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD9D9D99E9E9EFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BCBCBCBABABA -F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76A6A6A111111040404 -0000002E2D2D8289898CA5A7A5C6C9ABCDD09EBEC1859799B3B5B6F9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C1C1C1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE0E0E0A4A4A4ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6ABABAB3636360D0D0D5E5E5ED0D0D0 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE8E8E8FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEEEEEE4D4D4D1D1D1DCACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C87171716F6F6FB9B9B9F5F5F5FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA8A8A8 -D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5B5B5B5BFBFBFFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF2F2F2A1A1A12C2C2C1111112626260A0A0A2E2E2EC3C3C3F7F7F7BABBBC -8E9494879091969B9BD2D3D3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA9A9A9C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFEDEDEDA5A5A5E1E1E1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFED6D6D66666660F0F0F303030A5A5A5F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC9B9B9BF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0 -161616585858F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD3D3D32E2E2E5C5C5C7C7C7C353535999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E49E9E9EF1F1F1FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE5E5E5 -A9A9A9C7C7C7FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD0D0D05C5C5C0C0C0C -3737375F5F5F161616343434C8C8C8FFFFFFFFFFFFFFFFFFF9F9F9F4F3F3FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5A5A5CDCDCD -FFFFFFFFFFFFFFFFFFF7F7F7ACACACD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9B292929121212707070 -DCDCDCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEFEFEFA7A7A7F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC7979790D0D0DA4A4A4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE7E7E7E757575F7F7F7 -FFFFFF8A8A8A3B3B3BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B5B5B5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8C5C5C59F9F9FD4D4D4FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFEFEF9494942222221515157878788B8B8B1D1D1D363636CBCBCB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8F8F8FCCCCCCFFFFFFFFFFFFFFFFFFBCBCBC -BABABAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDC9C9C95454540C0C0C3E3E3EB6B6B6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF4F4F4FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDFDFDF323232343434E0E0E0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBED9D9D9FFFFFFFFFFFFC4C4C4353535F0F0F0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6A2A2A2DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -DEDEDEA5A5A5B2B2B2EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC7C7C74F4F4F -0A0A0A454545BABABA9E9E9E1818183B3B3BD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFD868686C7C7C7FFFFFFFFFFFFE4E4E49C9C9CF3F3F3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98888881D1D1D1A1A1A -828282E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3CACACAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA4A4A40D0D0D7A7A7AFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEF8F8F8E1E1E1494949595959F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA1A1A1F6F6F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9D6D6D6A4A4A49D9D9DD6D6D6FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE9E9E98686861C1C1C1A1A1A878787E6E6E69C9C9C161616 -3F3F3FD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D8D8DC1C1C1 -FFFFFFFCFCFCA8A8A8CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBBBBBBB4242420A0A0A4E4E4EC5C5C5FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE7E7E7919191FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2575757181818 -C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD717171 -2626264E4E4EE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB8B8B8BDBDBDFFFFFFFFFFFFFFFFFFFFFFFF -D7D7D79C9C9CA2A2A2D3D3D3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFABCBCBC -4545450909094E4E4EC7C7C7F8F8F8989898121212444444D9D9D9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8FB2B2B2FFFFFFD3D3D3A6A6A6FBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1767676131313 -242424969696EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1C1C1C1FCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C91C1C1C4E4E4EEFEFEFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED3D3D3A4A4A45C5C5CDCDCDCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF3F3F39F9F9FE1E1E1FFFFFFFFFFFFFBFBFB979797C7C7C7FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E27A7A7A151515212121929292F1F1F1F9F9F9 -8E8E8E0F0F0F4C4C4CDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF909090A1A1A1FDFDFD9C9C9CDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6F6F6AAAAAA3232320C0C0C616161D3D3D3FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFD8484840B0B0B999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF555555989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5 -A4A4A4F9F9F9FFFFFFFAFAFA9A9A9AE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 -B1B1B13737370B0B0B5B5B5BD1D1D1FEFEFEF6F6F68A8A8A0F0F0F4F4F4FE1E1E1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE929292828282 -DBDBDB9D9D9DFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD3D3D3626262 -0D0D0D313131A9A9A9F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE9E9E9A9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -3C3C3C2A2A2AD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3737373F2F2F2FFFFFFFFFFFF -F0F0F04E4E4EAEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB1B1B1C5C5C5FFFFFFFAFAFA -9A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC6A6A6A1010102B2B2BA2A2A2F3F3F3 -FFFFFFF5F5F58181810B0B0B575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE979797686868A6A6A6C7C7C7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE979797242424131313757575DFDFDFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4959595FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B01010106C6C6CF9F9F9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD6D6D6353535646464C8C8C8A7A7A73D3D3D4D4D4DF6F6F6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9D9D9DE8E8E8FCFCFC9A9A9AE1E1E1FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F5F5F5A2A2A22D2D2D0F0F0F6A6A6AD9D9D9FEFEFEFFFFFFF2F2F27D7D7D0D0D0D5A5A5A -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFE9E9E9E6969697B7B7BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC6C6C6 -5050500A0A0A424242B9B9B9F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7656565141414B6B6B6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D5D5D54747473636363434347A7A7ADDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCECECEAAAAAAF7F7F79A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED1D1D15D5D5D0C0C0C373737ADADAD -F7F7F7FFFFFFFFFFFFF2F2F27676760A0A0A626262EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA5A5A57B7B7B -9C9C9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E78383831A1A1A1D1D1D878787EAEAEAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF5F5F5E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD2D2D2252525444444EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF5F5F5F2F2F2F2F2F2 -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCAAAAAAC9C9C9 -9B9B9BE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEFEFEF979797232323141414767676E2E2E2FFFFFFFFFFFFFFFFFFEEEEEE6F6F6F -0C0C0C686868EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA5A5A5A7A7A7A4A4A4FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9 -B6B6B63F3F3F0B0B0B535353C9C9C9FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9E9E9EFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9191910A0A0A -8C8C8CFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8999999898989E2E2E2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC9C9C95151510A0A0A404040 -BABABAFAFAFAFFFFFFFFFFFFFFFFFFECECEC6B6B6B0A0A0A6D6D6DEEEEEEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA2A2A2CBCBCB989898EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDEDEDE7070701212122828289A9A9AF0F0F0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB464646222222CECECEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC2C2C2606060E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEAEAEA8989891C1C1C191919848484E8E8E8FFFFFFFFFFFFFFFFFFFFFFFF -EAEAEA6262620B0B0B747474EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5 -B5B5B5C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F5F5F5A6A6A63030300E0E0E656565D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFBF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBABABA151515606060F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 -B9B9B9EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFABEBEBE4646460A0A0A -4E4E4EC3C3C3FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFE6E6E66060600B0B0B787878F2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5E1E1E19D9D9DF9F9F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD1D1D15F5F5F0D0D0D343434AAAAAA -F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6CDCDCDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -717171101010ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE3E3E37C7C7C171717212121909090ECECECFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE5E5E55757570C0C0C828282F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA2A2A2D4D4D4FFFFFFA8A8A8CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEEEEEE949494242424141414777777E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D92E2E2E383838E5E5E5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B2B2B23B3B3B -0B0B0B585858CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E05353530E0E0E -848484F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D4D4D4 -FFFFFFDDDDDD9E9E9EF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC3C3C34D4D4D0A0A0A444444 -BBBBBBFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE2E2E2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9D0B0B0B808080FDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDDDDDD7070701010102929299E9E9EF2F2F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE0E0E04D4D4D0D0D0D8D8D8DF7F7F7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFEFEFEAFAFAFC7C7C7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE6E6E68181811818181D1D1D898989EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF0F0F05252521A1A1AC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A7A7A7 -2F2F2F0C0C0C666666D8D8D8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9 -484848111111929292F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFFFFFFECECEC9D9D9DE8E8E8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B3B3B33C3C3C0A0A0A -555555CBCBCBFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAC2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4181818 -545454F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D56060600C0C0C333333ACACACF6F6F6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7434343101010999999FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4D1D1D1 -FFFFFFFFFFFFFFFFFFCECECEAAAAAAFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDBDBDB6D6D6D1010102929299E9E9EF2F2F2FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEFEFEFEFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC2C2C2B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC7C7C7C0B0B0BA0A0A0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 -999999262626111111757575DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD2D2D23B3B3B1515159F9F9FFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8C9C9C9FFFFFFFFFFFFFFFFFFFCFCFC -B7B7B7C2C2C2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A2A2A22C2C2C -0E0E0E696969D9D9D9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BFBFBF5C5C5C4A4A4A797979 -F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0EEEEEEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE2E2E23535352F2F2FDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC9C9C95555550A0A0A3E3E3EB7B7B7FAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE393939161616A4A4A4 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB0B0B0C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6ACACACD2D2D2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBD6D6D6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDCFCFCF5A5A5A0B0B0B383838AFAFAFF7F7F7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9D9D9D2C2C2C9494949E9E9E3434346B6B6BF4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AAAAAA0D0D0D757575FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EBEBEB8C8C8C1D1D1D181818808080E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC9C9C93232321A1A1AABABABFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB7B7B7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDA8A8A8DCDCDCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADAD707070F6F6F6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED8F8F8F -2020201616167B7B7BE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB3B3B3B -858585FFFFFFFFFFFFD2D2D2292929C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB7B7B7BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F45D5D5D141414BEBEBE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC0C0C04747470A0A0A4A4A4AC4C4C4 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3303030 -1D1D1DADADADFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ADADADFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEAEAEAA9A9A9DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB9B9B96D6D6DC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC0C0C04949490B0B0B474747BFBFBFFBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFA4A4A4ECECECFFFFFFFFFFFFECECEC -343434BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8CECECEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC1E1E1E4B4B4BECECECFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE6E6E67D7D7D1717171F1F1F909090EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C02A2A2A202020B5B5B5FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE0E0E0999999FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED -ACACACD1D1D1FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAA7A7A79D9D9D -F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE3E3E3 -7C7C7C1717172020208D8D8DECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9797973E3E3EE2E2E2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFE8787870B0B0B949494FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B4B4B43B3B3B0C0C0C585858 -CBCBCBFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -B9B9B9272727262626B8B8B8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5939393 -EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEABABABB8B8B8F5F5F5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BCBCBCB9B9B9BEBEBEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6B0B0B03A3A3A0C0C0C595959CCCCCCFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEDEDED8787875C5C5CD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFCDCDCDDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E83E3E3E -292929D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDDDDDD7171711212122929299B9B9BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB7B7B7232323282828BEBEBEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA3A3A3D3D3D3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7BFBFBFA5A5A5E0E0E0FDFDFDFFFFFFFFFFFF -FFFFFFB9B9B9BCBCBCEFEFEF9A9A9AEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -D9D9D96A6A6A0F0F0F2C2C2CA0A0A0F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF616161393939D7D7D7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC6C6C6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B21111116A6A6AF8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A9A9A93232320D0D0D -636363D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEAFAFAF1E1E1E2F2F2FC1C1C1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBBBBBBB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFED9D9D99E9E9EB3B3B3EDEDEDFFFFFFFFFFFFB9B9B9BBBBBBFFFFFF -BEBEBEB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFF2F2F29F9F9F2B2B2B0F0F0F6B6B6BD9D9D9 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEC2C2C25B5B5B3E3E3ED8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF7F7F7686868121212B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDD7D7D76565650D0D0D313131A8A8A8F5F5F5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCABABAB1C1C1C303030 -C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 -9A9A9AFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6C2C2C29A9A9AB7B7B7EBEBEBB8B8B8BBBBBBFFFFFFF0F0F09A9A9AEBEBEBFFFFFF -FDFDFDCCCCCC5858580B0B0B3A3A3AB2B2B2F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE2E2E2E -8C8C8CEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF4F4F4F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D4D4D4272727404040E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F29E9E9E282828 -101010717171DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFCA6A6A6171717373737CDCDCDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9F9F9FD9D9D9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBCBCBC -9999997B7B7BBABABAFFFFFFFFFFFFC3C3C3B4B4B4ECECEC8D8D8D1F1F1F1616167E7E7E -E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2606060131313929292A4A4A4A1A1A1A5A5A5 -EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0D6D6D6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9393930B0B0B8A8A8A -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDCECECE5757570A0A0A3B3B3BB4B4B4F8F8F8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9E -1616163B3B3BD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4D0D0D0EAEAEAFFFFFF -FFFFFFF0F0F07979793F3F3F0A0A0A494949C2C2C2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE3E3E35858584E4E4E4D4D4D4D4D4D4D4D4D535353D9D9D9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC494949212121CDCDCDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED8E8E8E -1F1F1F1616167E7E7EE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9C9C9C111111404040D7D7D7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F2F2F2959595EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2797979141414181818 -919191EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFE -FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEEEEEEF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBDBDBD1616165D5D5DF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC2C2C24C4C4C090909474747BFBFBFFBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F9F9F9939393101010454545D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BABABAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F6ADADAD3535350C0C0C5A5A5A868686E0E0E0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBF1F1F1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA747474 -0E0E0EA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -8282821717171D1D1D8B8B8BEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79090900D0D0D4A4A4ADEDEDE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9BE7E7E7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76565650E0E0E -2F2F2FA4A4A4F6F6F6CECECEA9A9A9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A9A9AD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC313131343434E1E1E1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B8B8B83D3D3D0A0A0A545454CCCCCCFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F68686860C0C0C525252E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCCCCCCABABABFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF0F0F09A9A9A2727271212126F6F6FDCDCDCFFFFFFFFFFFFF8F8F8 -9E9E9EDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB8B8B8E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA1A1A10B0B0B7C7C7CFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E0E0E07373731212122525259B9B9BF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38383830B0B0B -545454E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA5A5A5 -D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC9C9C9535353 -0A0A0A3E3E3EB5B5B5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A5A5A5FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1F1F1555555191919C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AAAAAA3434340C0C0C626262D3D3D3 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF2F2F27B7B7B0B0B0B5D5D5DE6E6E6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A2A2A2EBEBEBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE9E9E98888881C1C1C191919838383E7E7E7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA0A0A0D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEBCBCBCE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C81C1C1C525252 -F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFED6D6D66666660E0E0E303030A6A6A6F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF -7474740C0C0C616161E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD3D3D3AAAAAAF6F6F6FFFFFFFFFFFFFFFFFFF9F9F9BABABA -4343430A0A0A4E4E4EC4C4C4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD5D5D5A4A4A4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFE999999DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8282820B0B0B9D9D9DFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F29F9F9F2A2A2A1111116D6D6D -DDDDDDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE6F6F6F090909686868ECECECFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEC2C2C2B7B7B7FCFCFCFFFFFFDFDFDF767676141414242424959595EEEEEEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA6A6A6D2D2D2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED5D5D5F1F1F1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE3E3E33939392C2C2CDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDCECECE5A5A5A0C0C0C383838B2B2B2F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEBEBEB6767670B0B0B6D6D6DEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAB7B7B7BEBEBE -A8A8A83434340C0C0C5F5F5FD2D2D2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA9F9F9FFBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF0F0F0FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA -0E0E0E717171F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF919191212121161616 -7B7B7BE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E96464640A0A0A747474 -F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC4646460A0A0A2F2F2FA7A7A7F4F4F4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD8D8D8A0A0A0FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAA4A4A4E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F65E5E5E131313BABABAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFCC5C5C54D4D4D0A0A0A454545BDBDBDFAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE7E7E75B5B5B0B0B0B7B7B7BF1F1F1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0BBBBBBFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F0F0F09797972727271414145858589B9B9BF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A0A0A0DFDFDF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA4A4A4E6E6E6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD0D0D0212121484848ECECECFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98484841A1A1A -1C1C1C878787EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3585858 -0A0A0A7F7F7FF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFE838383454545FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC7C7C75151510A0A0A404040B7B7B7 -F7F7F7CBCBCBA3A3A3DDDDDDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEFEFEFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF8C8C8C0A0A0A929292FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFABABABA414141090909515151C8C8C8FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E25050500B0B0B888888F5F5F5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3858585080808454545 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE9E9E98484841919191B1B1B858585E9E9E9FFFFFFFFFFFFFEFEFEDDDDDDA1A1A1 -B9B9B9F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E1E1E19E9E9EF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAD6D6D6F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA424242252525 -D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2787878 -121212242424969696F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DCDCDC4D4D4D0E0E0E8C8C8CF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF5F5F54E4E4E3838385F5F5F484848FCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B7B7B73E3E3E090909515151 -C7C7C7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5BCBCBC9E9E9ECCCCCCF6F6F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A4A4A4D6D6D6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4979797E7E7E7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5121212666666F6F6F6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6AFAFAF3535350B0B0B5E5E5ED3D3D3FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB4646460D0D0D959595F9F9F9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -BEBEBEF0F0F0ABABAB464646FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEDDDDDD7272721111112525259A9A9AF0F0F0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE2E2E2A9A9A9989898C1C1C1F0F0F0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC5C5C5B0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8BCBCBCF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F96B6B6B0F0F0FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDADADA -6868680E0E0E2C2C2CA4A4A4F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD5D5D5404040121212989898FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A6A6A62F2F2F0D0D0D -646464D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDE7E7E7B2B2B2919191DADADAFFFFFFFFFFFFFFFFFFE8E8E89D9D9D -EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEF9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E0E0E0C7C7C7C9C9C9C9C9C9CACACADDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7 -2929293C3C3CE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A0A0A02C2C2C0F0F0F6D6D6DDADADAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D23D3D3D121212 -9F9F9FFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646FCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDD0D0D05E5E5E0C0C0C343434AAAAAAF5F5F5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB3B3B3BABABAFFFFFFFFFFFFFBFBFBAAAAAACECECEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4B6B6B6F2F2F2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE646464333333363636353535 -0D0D0D757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9898980C0C0C848484FCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -CECECE5C5C5C0C0C0C383838AFAFAFF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCDCDCD353535171717A5A5A5FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFABABAB464646FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE939393242424 -141414757575E1E1E1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BBBBBBFFFFFF -FFFFFFCECECEAAAAAAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBEFEFEFF0F0F0F0F0F09898985B5B5BE5E5E5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEFEFEF4E4E4E1F1F1FCACACAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE959595222222151515787878E2E2E2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8 -343434191919A9A9A9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFCC3C3C34E4E4E0B0B0B434343BABABAF9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BBBBBBFFFFFFEEEEEE9E9E9EE8E8E8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F8F8F8DADADAFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDDDDDD3C3C3CD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC0C0C01818185A5A5AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FBFBFBC7C7C74F4F4F0A0A0A424242BCBCBCF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C32D2D2D1F1F1FB0B0B0FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646FCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7808080 -1919191E1E1E898989E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB9B9B9BBBBBBFFFFFFB0B0B0C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAECECECFDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F26060609C9C9C -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7878780E0E0E -A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98686861A1A1A1B1B1B878787 -E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEBDBDBD2B2B2B212121B3B3B3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB1B1B1545454FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B4B4B43C3C3C0C0C0C545454C9C9C9FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BCBCBCD9D9D9 -A5A5A5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE9E9E99F9F9FF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0505050EDEDEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE323232333333E0E0E0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFABCBCBC4343430A0A0A4F4F4FC6C6C6FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEBBBBBB252525252525BABABA -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2E4E4E4 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDCDCDC -6F6F6F1111112727279C9C9CF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9AFAFAFA3A3A3E0E0E0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEAA5A5A5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF7171717B7B7BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA4A4A40D0D0D787878FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E37A7A7A151515222222 -939393EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEB3B3B32222222B2B2BBCBCBCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A4A4A42F2F2F0D0D0D666666D7D7D7FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB9B9B9757575C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF2F2F2FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E23D3D3DCFCFCFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2 -585858181818C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4 -CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F7B0B0B03939390B0B0B595959D0D0D0FDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB0B0B01E1E1E -2D2D2DC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -D0D0D05C5C5C0B0B0B363636ACACACF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B27E7E7EF7F7F7 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF2F2F2CFCFCFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB2B2B24B4B4BEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA1E1E1E4E4E4EEFEFEF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB1717177E7E7EFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDCDCDC6D6D6D101010 -2A2A2A9F9F9FF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDAAAAAA191919333333C7C7C7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFDFDFEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED919191212121151515787878E2E2E2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E2E2E2949494FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -989898A6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8484840C0C0C999999FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF1F1F15B5B5B1414147E7E7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF4F4F4A5A5A52E2E2E0D0D0D686868D9D9D9FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -A4A4A4171717353535CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFECEBEBB8BABA9A9F9FA2A5A5CACACAF9F9F8FFFFFFFFFFFF -FBFBFBC1C1C1494949090909454545BDBDBDFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEC0C0C0FDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE6E6E63C3C3C2A2A2AD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F36262627C7C7C6F6F6F -7A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED3D3D35D5D5D -0D0D0D353535ADADADF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA0A0A01212123D3D3DD2D2D2FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED2D3D3 -8A969789A3A59BBABC97B4B784999B9FA5A5EEEEEEE5E5E57D7D7D1616161E1E1E8D8D8D -EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B00F0F0F -6C6C6CF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFADADAD3E3E3EDDDDDD7272727A7A7AFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF1F1F1959595232323141414777777E0E0E0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9989898121212404040D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB829192AACCCFBDE2E5BCE2E5BDE2E5 -BAE0E399B7B9747B7C3838380C0C0C585858CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E6E6E6B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7646464121212B6B6B6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7 -2B2B2BACACACFFFFFF7070707A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC8C8C8 -5151510A0A0A424242B9B9B9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F89494940E0E0E464646 -DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF8F8F8959C9CA1C0C3BCE2E5BADFE2BBE0E3BADFE2BBE0E3BDE2E5738A8C292A2B -9F9F9FF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF989898FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD3D3D3242424424242EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F46969697D7D7DFCFCFCFFFFFF707070 -7A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98A8A8A1B1B1B1A1A1A838383E9E9E9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF7F7F78B8B8B0E0E0E4C4C4CDCDCDCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDBDB7B8D8EBADFE2 -BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BCE1E4A5C7C9848C8CF7F6F6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -9090900A0A0A8D8D8DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBE0505054242426464646464642B2B2B2C2C2CACACACFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9 -BFBFBF4545450A0A0A4C4C4CC6C6C6FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5898989 -0D0D0D505050E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C6C6859B9DBCE2E5BADFE2BBE0E3BBE0E3BBE0E3 -BBE0E3BBE0E3B5D9DC5F6C6D7C7C7C8C8C8C9D9D9DA7A7A7B9B9B9C2C2C2D3D3D3DDDDDD -E2E2E2E6E6E6EBEBEBF0F0F0F4F4F4F9F9F9FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F5F5F5E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB464646222222D1D1D1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E18F8F8F -8B8B8B8989898B8B8B3C3C3C3F3F3FC2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE4E4E47B7B7B161616202020929292EDEDED -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F47F7F7F0B0B0B575757E2E2E2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFC5C5C6859B9DBCE2E5BADFE2BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3B6DADD475455 -1110101414141313131313131212121212121010101010101F1F1F2B2B2B383838444444 -5050505E5E5E6868687878788181819292929A9A9AABABABB4B4B4C6C6C6CDCDCDE0E0E0 -E4E4E4EAEAEAECECECF2F2F2F4F4F4F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A3A3A3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABA131313616161F6F6F6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF707070 -7A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F7B2B2B23A3A3A0B0B0B5A5A5ACDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1F1F17B7B7B0C0C0C5B5B5BE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC7C8D8EB9DEE1 -BBE0E3BBE0E3BBE0E3BBE0E3BADFE2BCE1E4A7C8CB858D8DC8C7C7C6C6C6B3B3B3ACACAC -9A9A9A9292928181817878786868685E5E5E5050504545453737372B2B2B1E1E1E101010 -1010101111111212121313131313131414141515151515151919192D2D2D343434474747 -4E4E4E6161616969697B7B7B8484849393939D9D9DABABABB5B5B5C2C2C2CFCFCFDBDBDB -E8E8E8EBEBEBEFEFEFF2F2F2F6F6F6F8F8F8FDFDFDFDFDFDFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCB0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFA6F6F6F0F0F0FACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C7C7C858585FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDBDBDB6E6E6E1111112A2A2A9D9D9D -F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F07474740B0B0B646464E8E8E8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8969C9CA0C0C2BCE2E5BADFE2BBDFE2BADFE2 -BBE0E3BCE2E571888A7E7F7FF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFCFAFAFAF4F4F4F0F0F0EBEBEBE7E7E7E2E2E2DDDDDDD2D2D2C2C2C2B8B8B8A6A6A6 -9E9E9E8B8B8B8484847070706A6A6A5858585353534141413B3B3B292929232323111111 -0B0B0B0E0E0E1010101111111414141515151818181A1A1A1B1B1B272727383838424242 -5454545C5C5C7070707777778B8B8B919191A3A3A3A8A8A8BABABABFBFBFD1D1D1D7D7D7 -E9E9E9EEEEEEF2F2F2F3F3F3F7F7F7F9F9F9FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA2B2B2B -3B3B3BE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFECECECEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF4F4F4A7A7A73131310E0E0E666666D6D6D6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEDEDED6E6E6E0B0B0B666666EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDBDBDB829192AACCCFBDE2E5BCE2E5BDE2E5BAE0E399B6B9414949101010 -787878EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEF9F9F9F6F6F6EEEEEEECECECE4E4E4E1E1E1D9D9D9D6D6D6C1C1C1B9B9B9A6A6A6 -9D9D9D8C8C8C8080807272726464645A5A5A4D4D4D4444443636362F2F2F1F1F1F181818 -0808080808080D0D0D0F0F0F1414141515151A1A1A1C1C1C212121232323383838414141 -5454545D5D5D6F6F6F7A7A7A8A8A8A989898A2A2A2AEAEAEB7B7B7C5C5C5CBCBCBDBDBDB -E2E2E2F2F2F2F3F3F3F6F6F6F7F7F7FAFAFAFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5D3D3D3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9B9B0B0B0B828282FCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED4D4D46262620D0D0D323232 -AAAAAAF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED6868680A0A0A -6F6F6FEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED5D5D6 -8B969689A2A497B5B795B2B4829799A1A7A7D1D1D16464640A0A0A555555DADADAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFAF5F5F5F1F1F1E9E9E9E5E5E5DCDCDCD8D8D8D0D0D0C9C9C9B3B3B3ADADAD -9797979191917B7B7B7474745F5F5F5858584949494343433535352E2E2E222222191919 -0D0D0D0404040808080E0E0E111111171717191919202020232323292929313131464646 -4D4D4D6363636969698080808686869C9C9CA3A3A3B2B2B2B8B8B8C6C6C6CCCCCCD9D9D9 -E1E1E1EDEDEDF7F7F7F8F8F8F9F9F9FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFEFEF5050501C1C1CC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF2F2F29B9B9B252525111111737373DFDFDFFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE9E9E96060600C0C0C737373EFEFEFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDB9BBBBA1A4A5A4A8A8 -CCCCCCF9F9F9FFFFFFF1F1F1848484111111383838C2C2C2FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFEF6F6F6F2F2F2E8E8E8E4E4E4DBDBDBD6D6D6CDCDCDC7C7C7B7B7B7A9A9A9 -9B9B9B8C8C8C8080806E6E6E6464645050504A4A4A3D3D3D3838382A2A2A262626181818 -1212120505050202020B0B0B0E0E0E1616161A1A1A2121212626262C2C2C323232424242 -5050505E5E5E6E6E6E7A7A7A8C8C8C979797AAAAAAB0B0B0BEBEBEC3C3C3D1D1D1D6D6D6 -E4E4E4E8E8E8F7F7F7FAFAFAFCFCFCFCFCFCFEFEFEFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E2E2E2CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C2C2C2181818565656F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCBCBCB5454540A0A0A -3D3D3DB8B8B8F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7 -5D5D5D0A0A0A7B7B7BF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FAFAFAA8A8A82222221D1D1DA1A1A1F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFAF0F0F0ECECECE1E1E1DDDDDDD2D2D2CDCDCDC2C2C2BCBCBCA7A7A7 -9F9F9F8A8A8A8181816D6D6D6363635151514646463C3C3C3535352C2C2C2424241C1C1C -1313130B0B0B0101010505050F0F0F1212121C1C1C1F1F1F2A2A2A2D2D2D3737373E3E3E -5353535B5B5B7070707979798D8D8D979797A9A9A9B4B4B4BFBFBFC6C6C6CFCFCFD8D8D8 -E0E0E0EAEAEAF1F1F1FCFCFCFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB7C7C7C0C0C0CA1A1A1 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFECECEC8C8C8C1E1E1E171717808080E6E6E6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E55454540C0C0C818181F3F3F3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC7C7C73B3B3B -101010808080EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEFEFEFEFDFDFDF3F3F3ECECECE3E3E3DADADAD3D3D3C9C9C9C2C2C2B8B8B8ACACAC -9A9A9A8F8F8F7C7C7C7373735F5F5F5656564141413B3B3B3131312C2C2C2222221E1E1E -1414140F0F0F0505050101010B0B0B1212121A1A1A212121292929323232383838424242 -4E4E4E6060606B6B6B7D7D7D8787879B9B9BA4A4A4B9B9B9BFBFBFCACACACFCFCFDADADA -DFDFDFEAEAEAEFEFEFFAFAFAFFFFFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCFCFCFC1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1353535313131DDDDDDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC0C0C04A4A4A -0A0A0A494949C2C2C2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE0E0E05252520C0C0C868686F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD5C5C5C0909095C5C5CDDDDDD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -FDFDFDFDFDFDFBFBFBF8F8F8EBEBEBE6E6E6D8D8D8D3D3D3C7C7C7C1C1C1B5B5B5AEAEAE -9A9A9A9090907D7D7D7272726161615454544444443636362F2F2F2929292323231C1C1C -1717170F0F0F0B0B0B0202020404041111111616162323232828283434343A3A3A464646 -4D4D4D6161616B6B6B7D7D7D888888999999A6A6A6B5B5B5C4C4C4CBCBCBD3D3D3D9D9D9 -E1E1E1E7E7E7F0F0F0F5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C7C7C7B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA7A7A70E0E0E757575FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE5E5E58080801616161E1E1E8D8D8DEEEEEEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE4A4A4A0F0F0F8F8F8F -F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE8080800E0E0E3C3C3CC9C9C9FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFE -FCFCFCFBFBFBF9F9F9F8F8F8EFEFEFE4E4E4DCDCDCD0D0D0C9C9C9BCBCBCB5B5B5A8A8A8 -9F9F9F8A8A8A8282826D6D6D6666665050504949493333332D2D2D2525252323231B1B1B -1818181111110E0E0E0808080303030C0C0C1717171F1F1F2B2B2B3232323F3F3F464646 -5353535B5B5B6F6F6F7878788D8D8D949494AAAAAAB1B1B1B6B6B6B8B8B8D7D7D7DADADA -E3E3E3E7E7E7EFEFEFF4F4F4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F55C5C5C -171717BEBEBEFCFCFCE8E8E8EAEAEAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B5B5B5 -3B3B3B0B0B0B565656CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD8D8D8454545111111929292F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9A0A0A01E1E1E232323A9A9A9F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFC -FBFBFBF9F9F9F8F8F8F5F5F5F3F3F3E4E4E4DDDDDDCFCFCFC8C8C8BABABAB2B2B2A6A6A6 -9D9D9D8C8C8C7F7F7F7171716262625555554545453A3A3A2727272424241E1E1E1C1C1C -1616161515150F0F0F0D0D0D0909090909091717171D1D1D2C2C2C333333404040494949 -5555555E5E5E6D6D6D7B7B7B8A8A8A989898A5A5A5B5B5B5C0C0C0D2D2D2D6D6D6DEDEDE -E1E1E1EAEAEAECECECF5F5F5F8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD222222404041888F90808D8E -808C8D929898D9D9D9FFFEFEFFFFFFDFDFDF6F6F6F1111112828289C9C9CF1F1F1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6404040 -1313139B9B9BFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0 -363636111111868686F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -FAFAFAF8F8F8F5F5F5F3F3F3F0F0F0EAEAEADADADAD3D3D3C3C3C3BDBDBDACACACA9A9A9 -6D6D6D6868687D7D7D7474745E5E5E5858584343433C3C3C2828281F1F1F1B1B1B1A1A1A -1717171414141212120F0F0F0D0D0D0909091010102020202727273838383D3D3D4F4F4F -5454546666666B6B6B8080808787879C9C9CA2A2A2B6B6B6BEBEBED1D1D1DADADAE0E0E0 -E4E4E4EAEAEAEEEEEEF3F3F3F9F9F9FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF8F8F77174745A6D6EA4C5C8B4D8DBB3D7DAA1C1C4859697BABCBC -A8A8A83131310E0E0E656565D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D03B3B3B1717179D9D9DFBFBFBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D95252520A0A0A666666 -E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACACACACAFFFFFFFDFDFD -F8F8F8F7F7F7F3F3F3F1F1F1EDEDEDEBEBEBDCDCDCD2D2D2C5C5C5BABABAAEAEAEA1A1A1 -9898988989898080806D6D6D6464645151514A4A4A3636363030301B1B1B181818161616 -1616161414141313131111111010100E0E0E0E0E0E1E1E1E2828283535354141414C4C4C -5A5A5A6464647373737C7C7C8E8E8E979797A9A9A9B0B0B0C3C3C3CACACADEDEDEE1E1E1 -E8E8E8EAEAEAF0F0F0F2F2F2F9F9F9FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1 -86999AB6DADDBCE1E4BBE0E3BBE0E3BCE1E4B4D8DB617173111111323232A7A7A7F6F6F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CCCCCC383838181818A5A5A5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA7676760D0D0D444444CCCCCCFEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFC -FAFAFAF5F5F5F3F3F3EEEEEEECECECE7E7E7E2E2E2CFCFCFC9C9C9B6B6B6B0B0B09E9E9E -9797978585857D7D7D6C6C6C6262625252524848483A3A3A2E2E2E212121131313121212 -1313131313131313131313131313131313131313131717172B2B2B3131314444444A4A4A -5D5D5D6464647777777F7F7F8F8F8F999999A7A7A7B2B2B2C0C0C0CCCCCCD9D9D9E6E6E6 -E9E9E9EDEDEDF0F0F0F4F4F4F7F7F7FDFDFDF4F4F48E9797A5C6C9BCE1E4BADFE2BBE0E3 -BBE0E3BADFE2BDE2E599B8BA535959D9D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C83131311D1D1DAAAAAAFCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F79797971818182A2A2AB2B2B2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D3D3D3DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -FAFAFAF5F5F5F1F1F1EDEDEDE9E9E9E4E4E4E0E0E0D4D4D4C5C5C5BBBBBBAAAAAAA2A2A2 -9090908888887575756F6F6F5D5D5D5656564444443D3D3D2C2C2C2525251313130D0D0D -0F0F0F1111111212121313131515151616161717171919192525253535353F3F3F505050 -5959596C6C6C6464646C7D7EB9DEE1BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3B5DADD -7C898AEFEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC1C1C12F2F2F1D1D1DAFAFAFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -B7B7B72E2E2E1616168F8F8FF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C2C2C2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -F9F9F9F7F7F7F0F0F0EDEDEDE6E6E6E3E3E3DCDCDCD8D8D8C5C5C5BCBCBCAAAAAAA0A0A0 -9090908585857676766969695D5D5D515151474747393939303030222222151414627576 -BEE4E7BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BADFE2B9DFE27B8A8BE2E2E2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF282828232323 -B5B5B5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D34C4C4C0B0B0B -6C6C6CE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD8D8D8E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFCF7F7F7F1F1F1EBEBEBE6E6E6E1E1E1C0C0C0758789BADFE2BBE0E3BBE0E3BBE0E3 -BBE0E3BBE0E3BBE0E3B7DCDF788687EAE9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFB8B8B8262626262626B9B9B9FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E76B6B6B0B0B0B4C4C4CD3D3D3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F6F6F6FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF1F1F1869091ACCED1BBE1E4BADFE2BBE0E3BBE0E3BADFE2BCE1E4A4C5C8 -8D9495F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB6B6B6 -2121212A2A2AC1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF3F3F39191911616162E2E2EB8B8B8FDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5D5D5D5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFC1C1 -8BA2A4BBE1E4BBE0E3BADFE2BADFE2BBE0E3B8DDE184989ACCCDCDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEADADAD1E1E1E2E2E2EC2C2C2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFCB1B1B1282828181818999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFA6A6A6D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB585D5E799294B3D7DABADFE2 -BADFE2B0D4D789A0A2ABAEAFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFDAAAAAA1B1B1B323232CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE454545 -0C0C0C747474EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEAF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9F9F9F1110105A5D5D818E8F8093947F9293818C8DC0C2C2FAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA3A3A3161616393939CDCDCD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5656565090909525252D9D9D9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDF4F4F4FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1272727 -3D3D3DE2E2E2EDECECD3D3D3D5D5D4EFEEEEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA9D9D9D1616163B3B3BD2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF1F1F1888888121212353535BEBEBEFDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF969696DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F25B5B5B161616B8B8B8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA989898121212 -444444D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFBFBFBAAAAAA2424241C1C1C9F9F9FF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B2B2B2E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF9797970D0D0D7E7E7EFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F88F8F8F111111464646D9D9D9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC6C6C6 -3C3C3C0F0F0F7D7D7DEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD222222424242E6E6E6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -8D8D8D0F0F0F4E4E4EDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5E5E5E0A0A0A595959 -DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDBEBEBEEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF0F0F0545454191919BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F58484840F0F0F515151E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE7D7D7D1010103C3C3CC5C5C5FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -959595E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE929292 -0C0C0C848484FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF3F3F38080800D0D0D575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF8F8F8A2A2A21F1F1F232323A6A6A6FAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED0D0D0F2F2F2FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C81E1E1E484848EAEAEAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F37878780B0B0B5E5E5E -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -C0C0C0353535101010868686F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEF2F2F2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEDEDED4F4F4F1B1B1BC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEFEFEF7575750B0B0B616161EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D95555550B0B0B -636363E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 -A4A4A4EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE8B8B8B0B0B0B8B8B8B -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF6D6D6D -0A0A0A6B6B6BEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED7777770B0B0B414141CDCDCDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A0A0A0E9E9E9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFC4C4C41B1B1B4D4D4DEDEDEDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC6666660B0B0B6D6D6DEFEFEFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6F6F6999999191919282828B0B0B0FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDEDEDEDFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB -4949491F1F1FC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEA6262620A0A0A767676F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FDFDFDBBBBBB3131311313138D8D8DF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA -D9D9D9F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8484840C0C0C929292FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E65959590D0D0D7A7A7AF3F3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D54B4B4B -0909096B6B6BE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2979797EBEBEBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFBEBEBE181818545454F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE3E3E35757570C0C0C828282F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E87070700D0D0D494949D0D0D0 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6F6F6B8B8B8F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6424242232323 -CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E04D4D4D0F0F0F -888888F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF5F5F59191911515152B2B2BB5B5B5FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBFBFB7E7E7E0D0D0D989898FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDADADA4A4A4A1010108D8D8DF8F8F8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFCFCFCB2B2B22B2B2B181818959595F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3B9B9B9F5F5F5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -B8B8B81616165C5C5CF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0 -AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9 -444444131313959595F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF -4545450C0C0C717171E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEDEDED979797F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E13B3B3B272727D1D1D1FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9797970D0D0D848484FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D33F3F3F141414989898FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E36666660B0B0B515151 -D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 -D6D6D6F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF9F9F97777770E0E0E9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFA0A0A03F3F3F242424D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD1D1D13B3B3B161616A1A1A1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F28B8B8B131313323232BCBCBCFDFDFDFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEFEFEFFDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1141414 -626262F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF525252949494343434 -E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB3535351A1A1AA4A4A4 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFAAAAAAA2323231C1C1C9E9E9EF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEAEAEAA2A2A2F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3636362C2C2CD6D6D6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE7E7E7585858AEAEAEACACAC525252F0F0F0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC6C6C63333331B1B1BACACACFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -C8C8C83F3F3F0D0D0D7C7C7CECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F6CFCFCFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA -A4A4A4F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F7F7F76E6E6E0E0E0EA5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE949494 -5F5F5FFDFDFD6C6C6C7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C32B2B2B -1F1F1FAFAFAFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5C5C5C090909 -595959DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA8585855E5E5E -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF0F0F0FDFDFDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB111111696969F6F6F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2A2A25F5F5FE3E3E3FDFDFD6969697B7B7B -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBE2A2A2A202020B6B6B6FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F08181810F0F0F3A3A3AC4C4C4FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDCDCDC7878780D0D0DACACACFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF3F3F3D4D4D4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDBDBDB303030323232DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE9E9E93636362727274040403E3E3E181818262626BBBBBBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -BABABA242424262626BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFAFAFAA5A5A51E1E1E202020A4A4A4FAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2 -383838363636161616C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2 -979797F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6686868 -0F0F0FACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECBDBDBDB9B9B9 -BABABA9B9B9B252525B0B0B0F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB1B1B1212121292929BFBFBFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEC1C1C1383838111111848484EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACA5A5A5CECECE404040D3D3D3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBEBEBEFBFBFBFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A40E0E0E707070F8F8F8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8474747EEEEEE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDAFAFAF1E1E1E2E2E2EC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB575757 -0909095E5E5EE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDFFFFFF959595585858FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD6D6D62B2B2B383838E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF868686A0A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A61B1B1B333333 -C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC7878780E0E0E3F3F3FCACACA -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFF939393595959FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7 -B6B6B6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4606060111111B3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F9F9FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBA2A2A2181818383838CFCFCFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF7F7F79C9C9C1C1C1C252525ACACACFAFAFAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F65A5A5A9E9E9EFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9B9B9BFEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFF9E9E9E0D0D0D767676FAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9B9B9B -1414143F3F3FD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDBBBBBB3131311212128A8A8AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEDEDED343434CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF3F3F3DCDCDCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 -2828283D3D3DE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9959595131313424242D6D6D6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5 -5050500B0B0B696969E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E2E2E2393939D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1595959141414B7B7B7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F9F9F99191911010104A4A4AD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E97070700B0B0B474747 -CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9E6A6A6AFCFCFCFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A3A3A3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFE9999990B0B0B7D7D7DFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F78989891010104D4D4DDDDDDD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F59393931616162C2C2CB5B5B5FBFBFBFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD8D8D8B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE232323424242 -E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF6F6F68686860D0D0D545454E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFBFBFBB5B5B52A2A2A181818939393F5F5F5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9 -F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE555555181818BDBDBDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F47D7D7D0C0C0C -575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CFCFCF4646460A0A0A727272E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4D8D8D8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD -9292920B0B0B838383FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF1F1F17B7B7B0B0B0B5D5D5DE8E8E8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E46868680A0A0A -4F4F4FD5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFC5C5C5ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8202020474747EAEAEAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 -7272720A0A0A646464E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38A8A8A131313303030BBBBBBFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE -CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFECECEC4E4E4E1C1C1CC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC6D6D6D0A0A0A676767EEEEEEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFBFBFBACACAC2525251A1A1A9C9C9CF8F8F8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFAFAFAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8989890A0A0A -8A8A8AFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFEBEBEB6666660A0A0A707070EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFECBCBCB3F3F3F0D0D0D767676ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCDCDCDC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C21B1B1B4F4F4FEDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E75E5E5E0C0C0C747474 -F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0616161 -080808565656DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF -B8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E9E9E9464646202020C9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE5E5E55B5B5B0C0C0C7D7D7DF3F3F3FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F18484840F0F0F363636C1C1C1 -FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECE9E9E9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB8181810B0B0B929292FDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1525252 -0E0E0E808080F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A5A5A52121211E1E1EA4A4A4F8F8F8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEDEDEDEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBCBCBC171717555555EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD4F4F4F0E0E0E898989F6F6F6FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFDC4C4C43A3A3A101010818181F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 -C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6404040 -242424CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DCDCDC4747471111118F8F8FF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC -5757570909095D5D5DDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3CBCBCBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7A7A7A0C0C0C999999FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6444444111111949494F9F9F9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB7A7A7A0E0E0E404040 -C8C8C8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF8F8F8F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFB6B6B61414145B5B5BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD5D5D53E3E3E1414149A9A9AF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F89C9C9C1B1B1B242424AAAAAAFAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 -E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E43B3B3B292929D3D3D3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF393939161616 -9F9F9FFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFCBBBBBB3232321313138B8B8BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF9F9F97474740C0C0C9E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCCCCCC363636171717A8A8A8FBFBFBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D7D7D75050500A0A0A666666E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD2D2D2E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 -111111626262F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6 -2F2F2F1A1A1AAAAAAAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E87171710A0A0A -434343CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E03636362C2C2CD7D7D7FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC2C2C22E2E2E1D1D1DB2B2B2FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F59696961818182A2A2AB2B2B2FCFCFC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5DADADAFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF7F7F76F6F6F0E0E0EA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFEBDBDBD272727232323B5B5B5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFCFCFCB6B6B62B2B2B131313909090F5F5F5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFA8A8A8D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA0E0E0E686868 -F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB5B5B5252525242424BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD2D2D24A4A4A0B0B0B6F6F6FE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 -F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFDADADA313131313131DCDCDCFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFDFDFDB2B2B22020202B2B2BC0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7696969 -0909094B4B4BD2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2F4F4F4FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 -686868111111ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDAAAAAA1D1D1D -2E2E2EC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38D8D8D1414142F2F2FBABABA -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A40D0D0D6F6F6FF8F8F8FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA7A7A7191919343434CBCBCBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBAFAFAF2727271A1A1A989898F5F5F5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 -E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD6D6D62C2C2C373737DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB -9F9F9F151515393939CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFEFEFECACACA4141410C0C0C757575ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7FCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3606060141414 -B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9A9A9A1414143D3D3DD3D3D3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2 -6262620A0A0A545454D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9D0D0D0D757575F9F9F9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFAFAFA959595101010444444D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF838383111111363636 -BEBEBEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF929292 -E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -D0D0D02626263B3B3BE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88F8F8F0F0F0F474747 -DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A6A6A62222221E1E1EA2A2A2F9F9F9FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAF1F1F1FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F25A5A5A161616B7B7B7FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF7F7F78B8B8B0C0C0C4E4E4EDDDDDDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEC5C5C53939390E0E0E7E7E7EEEEEEEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEF3F3F3FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFF9696960C0C0C7C7C7CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5828282 -0B0B0B515151E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -DCDCDC5959590909095B5B5BE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA4A4A4 -EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC212121 -424242E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38080800A0A0A595959E5E5E5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7D7D7D0C0C0C -3C3C3CC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9B9B9BE9E9E9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0525252181818BDBDBDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1F1F17777770909095C5C5CE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79E9E9E1C1C1C222222A9A9A9FAFAFA -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFEFEFEE9E9E9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFEFE8E8E8E0B0B0B848484FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE727272090909646464ECECEC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFDFDFDBFBFBF343434111111878787F0F0F0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBDCDCDC -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C71C1C1C484848E9E9E9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEDEDED6A6A6A0909096A6A6AEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD7D7D7515151090909636363E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3969696EDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFECECEC4B4B4B1B1B1BC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8636363090909 -6F6F6FF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB747474 -0D0D0D434343CCCCCCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF4F4F4B4B4B4F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD898989 -0B0B0B8A8A8AFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFE7E7E75E5E5E0A0A0A777777F0F0F0FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6979797171717282828AEAEAE -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C21818184E4E4EEDEDEDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3 -5757570C0C0C7B7B7BF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB6B6B62F2F2F1414148D8D8DF3F3F3FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5BDBDBDF5F5F5FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE8E8E84646461E1E1EC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E05353530C0C0C848484F4F4F4FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD2D2D24A4A4A0B0B0B6C6C6CE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFEBEBEB979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8383830B0B0B919191 -FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDEDEDE4B4B4B0E0E0E878787F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5 -6B6B6B0B0B0B484848D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5D3D3D3 -FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFBCBCBC171717545454EFEFEFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA4848480E0E0E8F8F8F -F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F39090901414142F2F2F -B7B7B7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1FEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 -414141212121CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD8D8D8414141111111939393F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBAFAFAF272727181818979797F6F6F6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE7E7E7A6A6A6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7B7B7B0C0C0C979797FEFEFEFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D13E3E3E -1111119B9B9BFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFCDCDCD4242420A0A0A747474EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6A4A4A4 -F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFB6B6B6151515595959F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0383838151515A1A1A1FAFAFAFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E2E2E2616161090909535353D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAEEEEEEFDFDFDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1393939272727 -D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -CACACA323232171717A5A5A5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2868686101010 -333333BEBEBEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF2F2F2D9D9D9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF9F9F97474740D0D0D9D9D9DFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC6C6C62F2F2F1A1A1AADADADFDFDFD -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA9A9A92121211D1D1D9F9F9FF8F8F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9B9B9B -FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -AFAFAF121212616161F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC0C0C02929291E1E1EB0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEC5C5C53C3C3C0E0E0E7A7A7AEDEDEDFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9BCBCBCFCFCFCFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD3434342C2C2CD6D6D6FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEBABABA272727222222 -B8B8B8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFDEDEDE5D5D5D0808085A5A5ADCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFCFCFCF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F76B6B6B0E0E0EA5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFEB6B6B6212121282828BBBBBBFEFEFEFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE7D7D7D -101010393939C3C3C3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4BCBCBC -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9101010 -696969F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDAEAEAE -202020292929C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A2A2A21E1E1E202020A5A5A5 -FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D89E9E9EFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D92F2F2F323232DBDBDBFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCABABAB1B1B1B303030C5C5C5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBF353535101010848484F0F0F0FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF0F0F0DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F5F5F5646464101010ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FCFCFCA3A3A3181818333333C9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD8D8D8545454090909606060E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7EEEEEE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A40E0E0E6F6F6FF8F8F8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA0A0A0151515393939D0D0D0 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB -7676760B0B0B424242CBCBCBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A7A7A7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD6D6D62A2A2A373737E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFAFAFA9999991212123D3D3DD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7979797181818262626 -ACACACFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD8D8D8ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F35F5F5F -101010B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9959595111111 -424242D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB9B9B92E2E2E1414148E8E8EF3F3F3FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9D0C0C0C767676F9F9F9FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFF8F8F88F8F8F0D0D0D484848D9D9D9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFD2D2D24A4A4A090909696969E5E5E5FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8D9D9D9FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFD0D0D02626263B3B3BE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 -8787870C0C0C4C4C4CDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E7E7E76D6D6D0A0A0A484848D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC9C9C9A7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1595959131313B8B8B8 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F58484840A0A0A535353E0E0E0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F58E8E8E161616 -2C2C2CB5B5B5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEC9C9C9 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFEFEFE9595950B0B0B7C7C7CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF3F3F37A7A7A0A0A0A575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB2B2B2292929161616929292F6F6F6 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB -222222404040E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0777777090909606060 -E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFCFCFCF4545450C0C0C717171E9E9E9FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFD1D1D1C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE515151181818BDBDBDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFEEEEEE6E6E6E080808636363EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE2E2E26666660909094E4E4ED5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B3B3B3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFDFDFD8E8E8E0A0A0A838383FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA696969 -0909096C6C6CEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2898989 -111111303030BCBCBCFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBE6E6E6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C51E1E1E484848 -E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFEAEAEA636363090909717171EEEEEEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA9A9A92323231B1B1B9B9B9B -F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF0F0F0F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFEAEAEA4C4C4C1C1C1CC2C2C2FFFFFFFFFFFFFFFFFFFFFFFF -E5E5E55D5D5D090909777777F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC8C8C83E3E3E0D0D0D7A7A7AEDEDEDFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDBFBFBF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC -8787870A0A0A8A8A8AFCFCFCFFFFFFFFFFFFFFFFFFE4E4E45858580B0B0B7D7D7DF2F2F2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFDFDFDF5B5B5B090909585858DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4C6C6C6FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C01B1B1B4D4D4DECECECFFFFFF -FFFFFFFFFFFFE0E0E05050500B0B0B818181F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE -7F7F7F0F0F0F383838C1C1C1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFF7F7F7F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE8E8E8444444202020C8C8C8FFFFFFFFFFFFFFFFFFDEDEDE4E4E4E0D0D0D -8A8A8AF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A1A1A11D1D1D202020 -A5A5A5F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8E2E2E2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB8080800A0A0A -909090FDFDFDFFFFFFFFFFFFDADADA4646460F0F0F8D8D8DF8F8F8FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBF363636111111818181EFEFEFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC161616545454EFEFEFFFFFFFFFFFFFD5D5D5 -434343101010959595F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFDADADA555555080808606060E1E1E1FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFCDCDCDE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -E5E5E53E3E3E242424CDCDCDFFFFFFFFFFFFD4D4D43B3B3B141414999999FAFAFAFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -EAEAEA7676760C0C0C3E3E3EC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7979790B0B0B989898FEFEFE -FFFFFFCCCCCC363636151515A1A1A1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79B9B9B1B1B1B -232323ABABABFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAD8D8D8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFB4B4B41313135C5C5CF1F1F1FFFFFFCACACA3232321A1A1AA8A8A8 -FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBABABA2F2F2F1111118A8A8AF3F3F3 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFA5A5A5D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E23A3A3A -272727D3D3D3FFFFFFC3C3C32C2C2C1C1C1CACACACFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFD6D6D64E4E4E0A0A0A656565E3E3E3FFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5F4F4F4 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F97272720C0C0CA0A0A0FFFFFFBFBFBF2A2A2A -212121B3B3B3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFE9E9E96E6E6E0A0A0A464646CFCFCFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFAEAEAE101010606060F4F4F4BABABA242424242424B6B6B6FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4929292 -1616162A2A2AB2B2B2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFF9A9A9AE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFDEDEDE3434342C2C2CD8D8D8 -B6B6B6232323282828BEBEBEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB3B3B32A2A2A151515929292 -F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADE6E6E6 -FFFFFFFFFFFFFFFFFFF7F7F76B6B6B0E0E0EA5A5A5B2B2B21D1D1D2C2C2CC0C0C0FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFEFEFECDCDCD4545450C0C0C6F6F6FE8E8E8FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6FCFCFCFFFFFFFFFFFFFFFFFFA8A8A8 -0E0E0E666666A1A1A11C1C1C2E2E2EC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFE4E4E46868680909094D4D4DD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFC1C1C1F3F3F3FFFFFFFFFFFFD8D8D83030302E2E2E8282821B1B1B353535 -CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 -888888131313313131BABABAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E8E8EE8E8E8 -FFFFFFF5F5F56666660E0E0E4A4A4A181818363636CECECEFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAABABAB252525191919 -999999F7F7F7FFFFFFFFFFFFFCFBFBEAEAEAA5A5A5DEDDDDFCFBFBA2A2A20D0D0D191919 -1010103F3F3FD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC7C7C73D3D3D0C0C0C787878EDEDEDECECEC -A0A5A57B88897E8D8E7C898A8A90902B2B2B010101050505434343D5D5D5FFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFE0E0E05F5F5F0A0A0A4F4F4F85909199B7B9B6DBDEB9DEE1B7DCDF -95B3B63743440303034A4A4ADBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -F1F1F17F7E7E2A30319BBBBDBDE2E5BBE0E3BADFE2BBE0E3BDE3E6A0C0C34F5757D2D2D2 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C77D9294BBE0E3 -BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3879D9FC6C7C8FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A8A895B2B4BDE2E5BBE0E3BBE0E3BBE0E3BBE0E3 -BADFE2BCE1E49AB9BB9A9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FEFDFD9CA0A09BBABCBCE2E5BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE1E4A2C3C68D9293 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A8A894B1B3BDE2E6 -BADFE2BBE0E3BBE0E3BBE0E3BADFE2BCE1E49BB9BC9A9E9EFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB83989ABAE0E3BBE0E3BBE0E3BBE0E3BBDFE2 -BBE0E3BBE0E3869C9EC5C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFF9F8F8969C9D9EBDBFBCE2E5BBE0E3BBE0E3BBE0E3BCE2E5A1C1C492999AF5F5F5 -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E3E38D9798 -98B5B7B4D8DBB8DDE0B4D9DB9AB8BA8A9596DDDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA2A6A77F8D8E7B8E8F7E8D8E -9FA4A4E9E9E9FFFFFFFFFFFFFFFFFFFAFAFAF0F0F0EFEFEFF3F3F3FEFEFEFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE6E6E6DBDBDBE5E5E5FBFBFBFFFFFFFFFFFFFFFFFF -FAFAFA898989303030343434444444D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC858585272727ACACACCACACA -777777525252D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF6F6F6707070BBBBBBFFFFFFFFFFFFFFFFFF555555989898FFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE -FEFEFEFEFEFEFEFEFEFDFDFDCECECE4D4D4DB2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C94A4A4A -151515666666FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A8A8A88E8E8E282828A0A0A0FEFEFE -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C9C9C343434F0F0F0FFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDEDEDEF5F5F5FFFFFFFFFFFF -FFFFFFC9C9C9353535F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFF5F5F54B4B4B7A7A7AF8F8F8FFFFFFF9F9F97C7C7C6D6D6DFBFBFB -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -C3C3C3363636636363777777646464363636CBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE6E6E68F8F8F717171 -8D8D8DE5E5E5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - -end -%%PageTrailer -%%Trailer -%%EOF diff --git a/medtool/doc/user/doxygen/figures/polyhedron_connectivity_small.png b/medtool/doc/user/doxygen/figures/polyhedron_connectivity_small.png deleted file mode 100644 index fa59ed5c0..000000000 Binary files a/medtool/doc/user/doxygen/figures/polyhedron_connectivity_small.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/projectionHQ.png b/medtool/doc/user/doxygen/figures/projectionHQ.png deleted file mode 100755 index 26cb913c1..000000000 Binary files a/medtool/doc/user/doxygen/figures/projectionHQ.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/projectionHQ_600.png b/medtool/doc/user/doxygen/figures/projectionHQ_600.png deleted file mode 100644 index d28a93c1e..000000000 Binary files a/medtool/doc/user/doxygen/figures/projectionHQ_600.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/source_field.png b/medtool/doc/user/doxygen/figures/source_field.png deleted file mode 100755 index d3e90df26..000000000 Binary files a/medtool/doc/user/doxygen/figures/source_field.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/source_mesh.png b/medtool/doc/user/doxygen/figures/source_mesh.png deleted file mode 100755 index e10ba3d90..000000000 Binary files a/medtool/doc/user/doxygen/figures/source_mesh.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/target_field.png b/medtool/doc/user/doxygen/figures/target_field.png deleted file mode 100755 index 5fc892926..000000000 Binary files a/medtool/doc/user/doxygen/figures/target_field.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/target_mesh.png b/medtool/doc/user/doxygen/figures/target_mesh.png deleted file mode 100755 index 67b2d343c..000000000 Binary files a/medtool/doc/user/doxygen/figures/target_mesh.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/tetra_simplexize_24_48.jpg b/medtool/doc/user/doxygen/figures/tetra_simplexize_24_48.jpg deleted file mode 100644 index a3933c142..000000000 Binary files a/medtool/doc/user/doxygen/figures/tetra_simplexize_24_48.jpg and /dev/null differ diff --git a/medtool/doc/user/doxygen/figures/tetra_simplexize_5_6.jpg b/medtool/doc/user/doxygen/figures/tetra_simplexize_5_6.jpg deleted file mode 100644 index a6786485e..000000000 Binary files a/medtool/doc/user/doxygen/figures/tetra_simplexize_5_6.jpg and /dev/null differ diff --git a/medtool/doc/user/doxygen/images/head.png b/medtool/doc/user/doxygen/images/head.png deleted file mode 100755 index 307d9ef9a..000000000 Binary files a/medtool/doc/user/doxygen/images/head.png and /dev/null differ diff --git a/medtool/doc/user/doxygen/static/footer.html b/medtool/doc/user/doxygen/static/footer.html deleted file mode 100755 index affd43d84..000000000 --- a/medtool/doc/user/doxygen/static/footer.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/medtool/doc/user/doxygen/static/header.html.in b/medtool/doc/user/doxygen/static/header.html.in deleted file mode 100755 index 1d6c7c358..000000000 --- a/medtool/doc/user/doxygen/static/header.html.in +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - -$projectname: $title -$title - - - -$treeview -$search -$mathjax - -$extrastylesheet - - -
- -
Version: @MEDCOUPLING_VERSION@
- diff --git a/medtool/doc/user/doxygen/static/medcoupling_extra.css b/medtool/doc/user/doxygen/static/medcoupling_extra.css deleted file mode 100644 index 3e8b838a6..000000000 --- a/medtool/doc/user/doxygen/static/medcoupling_extra.css +++ /dev/null @@ -1,29 +0,0 @@ -/* The extra CSS for doxygen 1.8.3.1 */ - -#titlearea { - background-image:url('head.png'); - background-color: #175783; - border: 1px solid; - height: 80px; - background-repeat: no-repeat; - padding: 0px; - margin: 0px; - width: 99.9%; - border-bottom: 1px solid #5373B4; -} - -div.version { - border:1px solid #0000FF; - color: #CCCCCC; - font-family: Arial, Helvetica, sans-serif; - font-size: 9pt; - text-align: center; - width:100px; - -moz-border-radius: 8px; - margin: 5px; -} - -.navpath li.footer { - line-height:15px; - text-align: right; -} \ No newline at end of file diff --git a/medtool/resources/BDC-714.sauv b/medtool/resources/BDC-714.sauv deleted file mode 100644 index fe8063076..000000000 Binary files a/medtool/resources/BDC-714.sauv and /dev/null differ diff --git a/medtool/resources/Box1.med b/medtool/resources/Box1.med deleted file mode 100644 index d1687755a..000000000 Binary files a/medtool/resources/Box1.med and /dev/null differ diff --git a/medtool/resources/Box1Moderate.med b/medtool/resources/Box1Moderate.med deleted file mode 100644 index 28d53d567..000000000 Binary files a/medtool/resources/Box1Moderate.med and /dev/null differ diff --git a/medtool/resources/Box2.med b/medtool/resources/Box2.med deleted file mode 100644 index a7c9e049f..000000000 Binary files a/medtool/resources/Box2.med and /dev/null differ diff --git a/medtool/resources/Box2Moderate.med b/medtool/resources/Box2Moderate.med deleted file mode 100644 index c68570b46..000000000 Binary files a/medtool/resources/Box2Moderate.med and /dev/null differ diff --git a/medtool/resources/Box3.med b/medtool/resources/Box3.med deleted file mode 100644 index d9158ff61..000000000 Binary files a/medtool/resources/Box3.med and /dev/null differ diff --git a/medtool/resources/BoxEvenSmaller1.med b/medtool/resources/BoxEvenSmaller1.med deleted file mode 100644 index 79a495abc..000000000 Binary files a/medtool/resources/BoxEvenSmaller1.med and /dev/null differ diff --git a/medtool/resources/BoxHexa1.med b/medtool/resources/BoxHexa1.med deleted file mode 100644 index da4ba0ebe..000000000 Binary files a/medtool/resources/BoxHexa1.med and /dev/null differ diff --git a/medtool/resources/BoxHexa2.med b/medtool/resources/BoxHexa2.med deleted file mode 100644 index f76852e74..000000000 Binary files a/medtool/resources/BoxHexa2.med and /dev/null differ diff --git a/medtool/resources/BoxModSmall1.med b/medtool/resources/BoxModSmall1.med deleted file mode 100644 index 7b0ebc77b..000000000 Binary files a/medtool/resources/BoxModSmall1.med and /dev/null differ diff --git a/medtool/resources/BoxModSmall2.med b/medtool/resources/BoxModSmall2.med deleted file mode 100644 index 4d2e505ac..000000000 Binary files a/medtool/resources/BoxModSmall2.med and /dev/null differ diff --git a/medtool/resources/BoxTetra2.med b/medtool/resources/BoxTetra2.med deleted file mode 100644 index 3d21669bf..000000000 Binary files a/medtool/resources/BoxTetra2.med and /dev/null differ diff --git a/medtool/resources/CMakeLists.txt b/medtool/resources/CMakeLists.txt deleted file mode 100644 index 3fe42f071..000000000 --- a/medtool/resources/CMakeLists.txt +++ /dev/null @@ -1,239 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -SET(MED_RESOURCES_FILES - #boitenew.cnc - #boitenew.inp - #boitenew.xyz - #Case1.cnc - #Case1.inp - #Case1.xyz - #cube.cnc - #cube.inp - #cube.xyz - #test3.cnc - #test3.inp - #test3.xyz - #titi.cnc - #titi.inp - #titi.xyz - #carre_en_quad4.med - #carre_en_quad4_seg2.med - #cas_defaut_domaine_fluide.med - #ChampsDarcy.med - #cube_hexa8.med - #cube_hexa8_quad4.med - #darcy_1.1_res.med - #darcy_1.3_resCASTEM.med - #darcy_1.3_resPORFLOW.med - #darcy_1.3_resTRACES.med - #darcy2_Castem_EFMH.med - #darcy2_Castem_qua_EFMH.med - #darcy2_Castem_qua_VF.med - #Darcy3_3D_H_10x10x10_2.med - #Darcy3_3D_H_10x10x10.sauve - #dx200_dy1_avec_2couches.sauve - #elle_2D_QT_10x10.sauve - #elle_2D_QT_2x2.sauve - #elle_2D_QT_40x40.sauve - #elle_2D_QT_4x4.sauve - #elle_3D_HPr_10x10x10_2.med - #elle_3D_HPr_10x10x10.sauve - #elle_3D_HPr_2x2x2_2.med - #elle_3D_HPr_2x2x2.sauve - #elle_3D_HPr_4x4x4_2.med - #elle_3D_HPr_4x4x4.sauve - #extendedtransport53_triangles.med - #geomMesh_nomorereadable21.med - #geomMesh22.med - #H_CastCast_EFMH_I129_COUPLEX1.med - #H_CastCast_VF_I129_COUPLEX1.med - #H_CastCast_VF_Se79_COUPLEX1.med - #H_CastPorf_I129_COUPLEX1.med - #H_CastPorf_Se79_COUPLEX1.med - #H_PorfCast_EFMH_I129_COUPLEX1.med - #H_PorfCast_EFMH_Se79_COUPLEX1.med - #H_PorfPorf_I129_COUPLEX1.med - #H_Traces_I129_COUPLEX1.med - #H_Traces_Se79_COUPLEX1.med - # inclusion_2d_raf.sauve - # inclusion_2d.sauve - # mail_ktest1-3-hexa.sauve - # mail_ktest1-3-tetra.sauve - # mail_ktest3-1.sauve - # mail_ktest3-2.sauve - # maill.00.med - # maill.00_nofield.med - # maill.00_nomesh.med - # maill.00_without_seg2.med - # maill.0.med - # maillage_5_5_5.med - # maillage_andra2_100elts.sauve - # maillage_cas2_2d.sauve - # maillage_cas4_234elts.sauve - # maillage_CHEMVAL_100elts.sauve - # maillage_CHEMVAL_40elts.sauve - # maillage_chemvalIV_cas1_100elts.sauve - # maillage_chemvalIV_cas1_40elts.med - # maillage_chemvalIV_cas1_40elts.sauve - # maillage_UniSegFam.med - # mail_test1-1-qua.sauve - # mail_test1-1-tri.sauve - # mail_test1-2-qua.sauve - # mail_test1-2-tri.sauve - # mail-test1-4-1.sauve - # mail-test1-4-2.sauve - # mesh_nomorereadable21.med - # mesh.med - # Mistrat.med - #Old_ChampsDarcy.med - #Old_darcy_1.1_res.med - #Old_darcy_1.3_resCASTEM.med - #Old_darcy_1.3_resPORFLOW.med - #Old_darcy_1.3_resTRACES.med - #Old_darcy2_Castem_EFMH.med - #Old_darcy2_Castem_qua_EFMH.med - #Old_darcy2_Castem_qua_VF.med - #Old_H_CastCast_EFMH_I129_COUPLEX1.med - #Old_H_CastCast_VF_I129_COUPLEX1.med - #Old_H_CastCast_VF_Se79_COUPLEX1.med - #Old_H_CastPorf_I129_COUPLEX1.med - #Old_H_CastPorf_Se79_COUPLEX1.med - #Old_H_PorfCast_EFMH_I129_COUPLEX1.med - #Old_H_PorfCast_EFMH_Se79_COUPLEX1.med - #Old_H_PorfPorf_I129_COUPLEX1.med - #Old_H_PorfPorf_Se79_COUPLEX1.med - #Old_H_Traces_I129_COUPLEX1.med - #Old_H_Traces_Se79_COUPLEX1.med - #Old_maillage_chemvalIV_cas1_40elts.med - #pointe_nomorereadable21.med - pointe.med - poly3D.med - #polyedres.med - polygones.med - #recoll_bord.med - #test19.med - # test_2D.med - # trio_2D.med - # TimeStamps.med - # zzzz121b.med - # zzzz121b_without_tr6.med - UnitTetra.med - GeneralTetra.med - NudgedSimpler.med - NudgedTetra.med - CornerTetra.med - SimpleIncludedTetra.med - SimpleIncludingTetra.med - Test2D.med - Test2Dpoly.med - Test3D.med - Test3Dpoly.med - UnitTetraDegenT.med - DegenEdgeXY.med - DegenFaceXYZ.med - DegenTranslatedInPlane.med - ComplexIncludedTetra.med - ComplexIncludingTetra.med - HalfstripOnly.med - HalfstripOnly2.med - SimpleHalfstripOnly.med - GenTetra1.med - GenTetra2.med - TrickyTetra1.med - LargeUnitTetra.med - # LargeInconsistentTetra.med - DividedUnitTetraSimpler.med - DividedUnitTetra.med - NudgedDividedUnitTetra.med - NudgedDividedUnitTetraSimpler.med - DividedGenTetra1.med - DividedGenTetra2.med - Box1.med - Box2.med - Box3.med - Box1Moderate.med - Box2Moderate.med - BoxModSmall1.med - BoxModSmall2.med - BoxEvenSmaller1.med - TinyBox.med - BoxHexa1.med - BoxHexa2.med - MovedHexaBox1.med - MovedHexaBox2.med - BoxTetra2.med - square1.med - square1_split - square1_split1.med - square1_split2.med - square1_split3.med - square2.med - square2_split - square2_split1.med - square2_split2.med - # testStructCart3D.med - Mesh3D_10_2d1.med - Mesh3D_10_2d2.med - Mesh3D_11.med - Pol1.fig - Pol2.fig - Pol3.fig - Pol4.fig - # blow5_ascii.case - # blow5_ascii.geo - # blow5_ascii_cd_displacement - # blow5_ascii_cd_thickness - # blow5_ascii_pd_displacement - # blow5_ascii_pd_thickness - #test_2D.sauve - allPillesTest.sauv - BDC-714.sauv - portico_3subs.sauv - agitateur.med - ) - -# IF(MED_ENABLE_GUI) -# FILE(GLOB MED_RESOURCES_PNG "${CMAKE_CURRENT_SOURCE_DIR}/*.png") -# SET(MED_RESOURCES_FILES -# ${MED_RESOURCES_FILES} -# ModuleMed.png -# Data.png -# Infos.png -# Structure.png -# explore_med_file.png -# field_selection.png -# med_mesh.png -# med_field.png -# mesh_selection.png -# ) -# ENDIF(MED_ENABLE_GUI) - -FOREACH(resfile ${MED_RESOURCES_FILES}) - CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/${resfile}" "${CMAKE_CURRENT_BINARY_DIR}/${resfile}" COPYONLY) -ENDFOREACH(resfile) - -INSTALL(FILES ${MED_RESOURCES_FILES} DESTINATION ${MEDCOUPLING_INSTALL_RES_DATA}) - -#MESSAGE(STATUS "Creation of ${CMAKE_CURRENT_BINARY_DIR}/MEDCatalog.xml") -#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/MEDCatalog.xml.in ${CMAKE_CURRENT_BINARY_DIR}/MEDCatalog.xml @ONLY) -#MESSAGE(STATUS "Creation of ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml") -#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/SalomeApp.xml.in ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml @ONLY) - -#INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDCatalog.xml ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml DESTINATION ${SALOME_MED_INSTALL_RES_DATA}) diff --git a/medtool/resources/ComplexIncludedTetra.med b/medtool/resources/ComplexIncludedTetra.med deleted file mode 100644 index 09a59279c..000000000 Binary files a/medtool/resources/ComplexIncludedTetra.med and /dev/null differ diff --git a/medtool/resources/ComplexIncludingTetra.med b/medtool/resources/ComplexIncludingTetra.med deleted file mode 100644 index e6aedf5aa..000000000 Binary files a/medtool/resources/ComplexIncludingTetra.med and /dev/null differ diff --git a/medtool/resources/CornerTetra.med b/medtool/resources/CornerTetra.med deleted file mode 100644 index f006c1756..000000000 Binary files a/medtool/resources/CornerTetra.med and /dev/null differ diff --git a/medtool/resources/DegenEdgeXY.med b/medtool/resources/DegenEdgeXY.med deleted file mode 100644 index bd42d14f0..000000000 Binary files a/medtool/resources/DegenEdgeXY.med and /dev/null differ diff --git a/medtool/resources/DegenFaceXYZ.med b/medtool/resources/DegenFaceXYZ.med deleted file mode 100644 index f0ecdd61e..000000000 Binary files a/medtool/resources/DegenFaceXYZ.med and /dev/null differ diff --git a/medtool/resources/DegenTranslatedInPlane.med b/medtool/resources/DegenTranslatedInPlane.med deleted file mode 100644 index d83f96c6d..000000000 Binary files a/medtool/resources/DegenTranslatedInPlane.med and /dev/null differ diff --git a/medtool/resources/DividedGenTetra1.med b/medtool/resources/DividedGenTetra1.med deleted file mode 100644 index 71274ea70..000000000 Binary files a/medtool/resources/DividedGenTetra1.med and /dev/null differ diff --git a/medtool/resources/DividedGenTetra2.med b/medtool/resources/DividedGenTetra2.med deleted file mode 100644 index 14f63cd5f..000000000 Binary files a/medtool/resources/DividedGenTetra2.med and /dev/null differ diff --git a/medtool/resources/DividedUnitTetra.med b/medtool/resources/DividedUnitTetra.med deleted file mode 100644 index 320bdfa3d..000000000 Binary files a/medtool/resources/DividedUnitTetra.med and /dev/null differ diff --git a/medtool/resources/DividedUnitTetraSimpler.med b/medtool/resources/DividedUnitTetraSimpler.med deleted file mode 100644 index a826cfbeb..000000000 Binary files a/medtool/resources/DividedUnitTetraSimpler.med and /dev/null differ diff --git a/medtool/resources/GenTetra1.med b/medtool/resources/GenTetra1.med deleted file mode 100644 index 629b29928..000000000 Binary files a/medtool/resources/GenTetra1.med and /dev/null differ diff --git a/medtool/resources/GenTetra2.med b/medtool/resources/GenTetra2.med deleted file mode 100644 index 32e3bb51e..000000000 Binary files a/medtool/resources/GenTetra2.med and /dev/null differ diff --git a/medtool/resources/GeneralTetra.med b/medtool/resources/GeneralTetra.med deleted file mode 100644 index 11b2e2785..000000000 Binary files a/medtool/resources/GeneralTetra.med and /dev/null differ diff --git a/medtool/resources/HalfstripOnly.med b/medtool/resources/HalfstripOnly.med deleted file mode 100644 index 11dee6434..000000000 Binary files a/medtool/resources/HalfstripOnly.med and /dev/null differ diff --git a/medtool/resources/HalfstripOnly2.med b/medtool/resources/HalfstripOnly2.med deleted file mode 100644 index 67bca2377..000000000 Binary files a/medtool/resources/HalfstripOnly2.med and /dev/null differ diff --git a/medtool/resources/LargeUnitTetra.med b/medtool/resources/LargeUnitTetra.med deleted file mode 100644 index 99ad8003b..000000000 Binary files a/medtool/resources/LargeUnitTetra.med and /dev/null differ diff --git a/medtool/resources/Mesh3D_10_2d1.med b/medtool/resources/Mesh3D_10_2d1.med deleted file mode 100644 index 508781d32..000000000 Binary files a/medtool/resources/Mesh3D_10_2d1.med and /dev/null differ diff --git a/medtool/resources/Mesh3D_10_2d2.med b/medtool/resources/Mesh3D_10_2d2.med deleted file mode 100644 index 071d4a3dc..000000000 Binary files a/medtool/resources/Mesh3D_10_2d2.med and /dev/null differ diff --git a/medtool/resources/Mesh3D_11.med b/medtool/resources/Mesh3D_11.med deleted file mode 100644 index 5088b55b3..000000000 Binary files a/medtool/resources/Mesh3D_11.med and /dev/null differ diff --git a/medtool/resources/MovedHexaBox1.med b/medtool/resources/MovedHexaBox1.med deleted file mode 100644 index 6d826aef1..000000000 Binary files a/medtool/resources/MovedHexaBox1.med and /dev/null differ diff --git a/medtool/resources/MovedHexaBox2.med b/medtool/resources/MovedHexaBox2.med deleted file mode 100644 index c0bdb6d7a..000000000 Binary files a/medtool/resources/MovedHexaBox2.med and /dev/null differ diff --git a/medtool/resources/NudgedDividedUnitTetra.med b/medtool/resources/NudgedDividedUnitTetra.med deleted file mode 100644 index 67aabde0b..000000000 Binary files a/medtool/resources/NudgedDividedUnitTetra.med and /dev/null differ diff --git a/medtool/resources/NudgedDividedUnitTetraSimpler.med b/medtool/resources/NudgedDividedUnitTetraSimpler.med deleted file mode 100644 index 2eb145e5e..000000000 Binary files a/medtool/resources/NudgedDividedUnitTetraSimpler.med and /dev/null differ diff --git a/medtool/resources/NudgedSimpler.med b/medtool/resources/NudgedSimpler.med deleted file mode 100644 index a0fb4ea20..000000000 Binary files a/medtool/resources/NudgedSimpler.med and /dev/null differ diff --git a/medtool/resources/NudgedTetra.med b/medtool/resources/NudgedTetra.med deleted file mode 100644 index 0672d1a7a..000000000 Binary files a/medtool/resources/NudgedTetra.med and /dev/null differ diff --git a/medtool/resources/Pol1.fig b/medtool/resources/Pol1.fig deleted file mode 100644 index cee7eb792..000000000 --- a/medtool/resources/Pol1.fig +++ /dev/null @@ -1,15 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Metric -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2700.000 4800.000 3600 6000 4200 4800 3600 3600 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5400.000 1200.000 3600 3600 5400 4200 7200 3600 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5100.000 6300.000 7200 3600 7800 4200 8400 5400 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 8400.000 6000.000 8400 5400 7800 6000 8400 6600 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 9128.571 9642.857 8400 6600 6600 7800 6000 9600 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2820.000 9120.000 6000 9600 5400 7200 3600 6000 diff --git a/medtool/resources/Pol2.fig b/medtool/resources/Pol2.fig deleted file mode 100644 index 4778e6735..000000000 --- a/medtool/resources/Pol2.fig +++ /dev/null @@ -1,13 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 13000.000 7200.000 6600 9000 6600 5400 8400 2400 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 10500.000 -900.000 8400 2400 10800 3000 12600 2400 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 16242.857 6471.429 12600 2400 10800 6000 11400 9000 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 9000.000 13500.000 6600 9000 9000 8400 11400 9000 diff --git a/medtool/resources/Pol3.fig b/medtool/resources/Pol3.fig deleted file mode 100644 index 4bad14493..000000000 --- a/medtool/resources/Pol3.fig +++ /dev/null @@ -1,11 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 -3000 7200 6600 3600 diff --git a/medtool/resources/Pol4.fig b/medtool/resources/Pol4.fig deleted file mode 100644 index 1c6cd7924..000000000 --- a/medtool/resources/Pol4.fig +++ /dev/null @@ -1,10 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 4800.000 4837.500 4200 7200 4800 2400 5400 7200 diff --git a/medtool/resources/SimpleHalfstripOnly.med b/medtool/resources/SimpleHalfstripOnly.med deleted file mode 100644 index f15aedb63..000000000 Binary files a/medtool/resources/SimpleHalfstripOnly.med and /dev/null differ diff --git a/medtool/resources/SimpleIncludedTetra.med b/medtool/resources/SimpleIncludedTetra.med deleted file mode 100644 index 9ac90ee1b..000000000 Binary files a/medtool/resources/SimpleIncludedTetra.med and /dev/null differ diff --git a/medtool/resources/SimpleIncludingTetra.med b/medtool/resources/SimpleIncludingTetra.med deleted file mode 100644 index e0d6066d0..000000000 Binary files a/medtool/resources/SimpleIncludingTetra.med and /dev/null differ diff --git a/medtool/resources/Test2D.med b/medtool/resources/Test2D.med deleted file mode 100644 index 8f651af39..000000000 Binary files a/medtool/resources/Test2D.med and /dev/null differ diff --git a/medtool/resources/Test2Dpoly.med b/medtool/resources/Test2Dpoly.med deleted file mode 100644 index 7d56fed90..000000000 Binary files a/medtool/resources/Test2Dpoly.med and /dev/null differ diff --git a/medtool/resources/Test3D.med b/medtool/resources/Test3D.med deleted file mode 100644 index 48eccd7a6..000000000 Binary files a/medtool/resources/Test3D.med and /dev/null differ diff --git a/medtool/resources/Test3Dpoly.med b/medtool/resources/Test3Dpoly.med deleted file mode 100644 index 621709411..000000000 Binary files a/medtool/resources/Test3Dpoly.med and /dev/null differ diff --git a/medtool/resources/TinyBox.med b/medtool/resources/TinyBox.med deleted file mode 100644 index 2ae80ef4f..000000000 Binary files a/medtool/resources/TinyBox.med and /dev/null differ diff --git a/medtool/resources/TrickyTetra1.med b/medtool/resources/TrickyTetra1.med deleted file mode 100644 index 50c0aa98a..000000000 Binary files a/medtool/resources/TrickyTetra1.med and /dev/null differ diff --git a/medtool/resources/UnitTetra.med b/medtool/resources/UnitTetra.med deleted file mode 100644 index d4548f23c..000000000 Binary files a/medtool/resources/UnitTetra.med and /dev/null differ diff --git a/medtool/resources/UnitTetraDegenT.med b/medtool/resources/UnitTetraDegenT.med deleted file mode 100644 index 5a0800615..000000000 Binary files a/medtool/resources/UnitTetraDegenT.med and /dev/null differ diff --git a/medtool/resources/agitateur.med b/medtool/resources/agitateur.med deleted file mode 100644 index 73c62e127..000000000 Binary files a/medtool/resources/agitateur.med and /dev/null differ diff --git a/medtool/resources/allPillesTest.sauv b/medtool/resources/allPillesTest.sauv deleted file mode 100644 index 99efda1a5..000000000 --- a/medtool/resources/allPillesTest.sauv +++ /dev/null @@ -1,11246 +0,0 @@ - ENREGISTREMENT DE TYPE 4 - NIVEAU 16 NIVEAU ERREUR 0 DIMENSION 2 - DENSITE 0.00000E+00 - ENREGISTREMENT DE TYPE 7 - NOMBRE INFO CASTEM2000 8 - IFOUR -1 NIFOUR 0 IFOMOD -1 IECHO 0 IIMPI 0 IOSPI 0 ISOTYP 1 - NSDPGE 0 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 1NBRE OBJETS NOMMES 17NBRE OBJETS 43 - BOTTOM C_3D C_5F C_6 C_65 C_6F C_75 FAM_LEFT - FAM_STOT FAM_TOP GE_1 GE_3 LEFT RIGHT TOP C_5 - C_9 - 1 2 3 4 5 6 7 8 9 10 - 11 12 13 14 15 4 16 - 2 0 0 2 1 - 0 - 11 12 - 8 0 0 4 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 14 11 14 13 15 16 16 15 - 17 18 18 17 19 20 20 19 21 22 - 22 21 23 24 24 23 25 26 26 25 - 27 28 28 27 29 30 30 29 31 32 - 32 31 33 34 34 33 35 36 36 35 - 37 38 38 37 39 40 40 39 41 42 - 42 41 43 44 44 43 45 46 46 45 - 47 48 48 47 49 50 50 49 51 52 - 52 51 53 54 54 53 55 56 56 55 - 57 58 58 57 59 60 60 59 61 62 - 62 61 63 64 64 63 65 66 66 65 - 67 68 68 67 69 70 70 69 71 72 - 72 71 73 74 74 73 75 76 76 75 - 77 78 78 77 79 80 79 81 82 80 - 81 83 84 82 83 85 86 84 85 87 - 88 86 87 89 90 88 89 91 92 90 - 91 93 94 92 93 95 96 94 95 97 - 98 96 97 99 100 98 99 101 102 100 - 101 103 104 102 103 105 106 104 105 107 - 108 106 107 109 110 108 109 111 112 110 - 111 113 114 112 113 115 116 114 115 117 - 118 116 117 119 120 118 119 121 122 120 - 121 123 124 122 123 125 126 124 125 127 - 128 126 127 129 130 128 129 131 132 130 - 131 133 134 132 133 135 136 134 135 137 - 138 136 137 139 140 138 139 141 142 140 - 141 143 144 142 143 145 146 144 145 147 - 148 146 147 149 150 148 149 151 152 150 - 151 153 154 152 153 155 156 154 155 157 - 158 156 157 159 160 158 159 161 162 160 - 161 163 164 162 163 165 166 164 165 167 - 168 166 167 169 170 168 169 171 172 170 - 171 173 174 172 173 175 176 174 175 177 - 178 176 177 179 180 178 179 181 182 180 - 181 183 184 182 183 185 186 184 185 187 - 188 186 187 189 190 188 189 191 192 190 - 191 193 194 192 193 195 196 194 195 197 - 198 196 197 199 200 198 199 201 202 200 - 201 203 204 202 203 205 206 204 205 207 - 208 206 207 209 210 208 209 211 212 210 - 2 0 0 2 1 - 0 - 11 12 - 8 0 0 4 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 14 11 14 13 15 16 16 15 - 17 18 18 17 19 20 20 19 21 22 - 22 21 23 24 24 23 25 26 26 25 - 27 28 28 27 29 30 30 29 31 32 - 32 31 33 34 34 33 35 36 36 35 - 37 38 38 37 39 40 40 39 41 42 - 42 41 43 44 44 43 45 46 46 45 - 47 48 48 47 49 50 50 49 51 52 - 52 51 53 54 54 53 55 56 56 55 - 57 58 58 57 59 60 60 59 61 62 - 62 61 63 64 64 63 65 66 66 65 - 67 68 68 67 69 70 70 69 71 72 - 72 71 73 74 74 73 75 76 76 75 - 77 78 78 77 79 80 79 81 82 80 - 81 83 84 82 83 85 86 84 85 87 - 88 86 87 89 90 88 89 91 92 90 - 91 93 94 92 93 95 96 94 95 97 - 98 96 97 99 100 98 99 101 102 100 - 101 103 104 102 103 105 106 104 105 107 - 108 106 107 109 110 108 109 111 112 110 - 111 113 114 112 113 115 116 114 115 117 - 118 116 117 119 120 118 119 121 122 120 - 121 123 124 122 123 125 126 124 125 127 - 128 126 127 129 130 128 129 131 132 130 - 131 133 134 132 133 135 136 134 135 137 - 138 136 137 139 140 138 139 141 142 140 - 141 143 144 142 143 145 146 144 145 147 - 148 146 147 149 150 148 149 151 152 150 - 151 153 154 152 153 155 156 154 155 157 - 158 156 157 159 160 158 159 161 162 160 - 161 163 164 162 163 165 166 164 165 167 - 168 166 167 169 170 168 169 171 172 170 - 171 173 174 172 173 175 176 174 175 177 - 178 176 177 179 180 178 179 181 182 180 - 181 183 184 182 183 185 186 184 185 187 - 188 186 187 189 190 188 189 191 192 190 - 191 193 194 192 193 195 196 194 195 197 - 198 196 197 199 200 198 199 201 202 200 - 201 203 204 202 203 205 206 204 205 207 - 208 206 207 209 210 208 209 211 212 210 - 2 0 0 2 1 - 0 - 211 212 - 2 0 0 2 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 13 15 15 17 17 19 19 21 - 21 23 23 25 25 27 27 29 29 31 - 31 33 33 35 35 37 37 39 39 41 - 41 43 43 45 45 47 47 49 49 51 - 51 53 53 55 55 57 57 59 59 61 - 61 63 63 65 65 67 67 69 69 71 - 71 73 73 75 75 77 77 79 79 81 - 81 83 83 85 85 87 87 89 89 91 - 91 93 93 95 95 97 97 99 99 101 - 101 103 103 105 105 107 107 109 109 111 - 111 113 113 115 115 117 117 119 119 121 - 121 123 123 125 125 127 127 129 129 131 - 131 133 133 135 135 137 137 139 139 141 - 141 143 143 145 145 147 147 149 149 151 - 151 153 153 155 155 157 157 159 159 161 - 161 163 163 165 165 167 167 169 169 171 - 171 173 173 175 175 177 177 179 179 181 - 181 183 183 185 185 187 187 189 189 191 - 191 193 193 195 195 197 197 199 199 201 - 201 203 203 205 205 207 207 209 209 211 - 2 0 0 2 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 14 11 16 14 18 16 20 18 22 20 - 24 22 26 24 28 26 30 28 32 30 - 34 32 36 34 38 36 40 38 42 40 - 44 42 46 44 48 46 50 48 52 50 - 54 52 56 54 58 56 60 58 62 60 - 64 62 66 64 68 66 70 68 72 70 - 74 72 76 74 78 76 80 78 82 80 - 84 82 86 84 88 86 90 88 92 90 - 94 92 96 94 98 96 100 98 102 100 - 104 102 106 104 108 106 110 108 112 110 - 114 112 116 114 118 116 120 118 122 120 - 124 122 126 124 128 126 130 128 132 130 - 134 132 136 134 138 136 140 138 142 140 - 144 142 146 144 148 146 150 148 152 150 - 154 152 156 154 158 156 160 158 162 160 - 164 162 166 164 168 166 170 168 172 170 - 174 172 176 174 178 176 180 178 182 180 - 184 182 186 184 188 186 190 188 192 190 - 194 192 196 194 198 196 200 198 202 200 - 204 202 206 204 208 206 210 208 212 210 - 2 0 0 2 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 13 15 15 17 17 19 19 21 - 21 23 23 25 25 27 27 29 29 31 - 31 33 33 35 35 37 37 39 39 41 - 41 43 43 45 45 47 47 49 49 51 - 51 53 53 55 55 57 57 59 59 61 - 61 63 63 65 65 67 67 69 69 71 - 71 73 73 75 75 77 77 79 79 81 - 81 83 83 85 85 87 87 89 89 91 - 91 93 93 95 95 97 97 99 99 101 - 101 103 103 105 105 107 107 109 109 111 - 111 113 113 115 115 117 117 119 119 121 - 121 123 123 125 125 127 127 129 129 131 - 131 133 133 135 135 137 137 139 139 141 - 141 143 143 145 145 147 147 149 149 151 - 151 153 153 155 155 157 157 159 159 161 - 161 163 163 165 165 167 167 169 169 171 - 171 173 173 175 175 177 177 179 179 181 - 181 183 183 185 185 187 187 189 189 191 - 191 193 193 195 195 197 197 199 199 201 - 201 203 203 205 205 207 207 209 209 211 - 8 0 0 4 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 14 11 14 13 15 16 16 15 - 17 18 18 17 19 20 20 19 21 22 - 22 21 23 24 24 23 25 26 26 25 - 27 28 28 27 29 30 30 29 31 32 - 32 31 33 34 34 33 35 36 36 35 - 37 38 38 37 39 40 40 39 41 42 - 42 41 43 44 44 43 45 46 46 45 - 47 48 48 47 49 50 50 49 51 52 - 52 51 53 54 54 53 55 56 56 55 - 57 58 58 57 59 60 60 59 61 62 - 62 61 63 64 64 63 65 66 66 65 - 67 68 68 67 69 70 70 69 71 72 - 72 71 73 74 74 73 75 76 76 75 - 77 78 78 77 79 80 79 81 82 80 - 81 83 84 82 83 85 86 84 85 87 - 88 86 87 89 90 88 89 91 92 90 - 91 93 94 92 93 95 96 94 95 97 - 98 96 97 99 100 98 99 101 102 100 - 101 103 104 102 103 105 106 104 105 107 - 108 106 107 109 110 108 109 111 112 110 - 111 113 114 112 113 115 116 114 115 117 - 118 116 117 119 120 118 119 121 122 120 - 121 123 124 122 123 125 126 124 125 127 - 128 126 127 129 130 128 129 131 132 130 - 131 133 134 132 133 135 136 134 135 137 - 138 136 137 139 140 138 139 141 142 140 - 141 143 144 142 143 145 146 144 145 147 - 148 146 147 149 150 148 149 151 152 150 - 151 153 154 152 153 155 156 154 155 157 - 158 156 157 159 160 158 159 161 162 160 - 161 163 164 162 163 165 166 164 165 167 - 168 166 167 169 170 168 169 171 172 170 - 171 173 174 172 173 175 176 174 175 177 - 178 176 177 179 180 178 179 181 182 180 - 181 183 184 182 183 185 186 184 185 187 - 188 186 187 189 190 188 189 191 192 190 - 191 193 194 192 193 195 196 194 195 197 - 198 196 197 199 200 198 199 201 202 200 - 201 203 204 202 203 205 206 204 205 207 - 208 206 207 209 210 208 209 211 212 210 - 2 0 0 2 1 - 0 - 211 212 - 2 0 0 2 1 - 0 - 11 12 - 2 0 0 2 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 14 11 16 14 18 16 20 18 22 20 - 24 22 26 24 28 26 30 28 32 30 - 34 32 36 34 38 36 40 38 42 40 - 44 42 46 44 48 46 50 48 52 50 - 54 52 56 54 58 56 60 58 62 60 - 64 62 66 64 68 66 70 68 72 70 - 74 72 76 74 78 76 80 78 82 80 - 84 82 86 84 88 86 90 88 92 90 - 94 92 96 94 98 96 100 98 102 100 - 104 102 106 104 108 106 110 108 112 110 - 114 112 116 114 118 116 120 118 122 120 - 124 122 126 124 128 126 130 128 132 130 - 134 132 136 134 138 136 140 138 142 140 - 144 142 146 144 148 146 150 148 152 150 - 154 152 156 154 158 156 160 158 162 160 - 164 162 166 164 168 166 170 168 172 170 - 174 172 176 174 178 176 180 178 182 180 - 184 182 186 184 188 186 190 188 192 190 - 194 192 196 194 198 196 200 198 202 200 - 204 202 206 204 208 206 210 208 212 210 - 2 0 0 2 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 13 15 15 17 17 19 19 21 - 21 23 23 25 25 27 27 29 29 31 - 31 33 33 35 35 37 37 39 39 41 - 41 43 43 45 45 47 47 49 49 51 - 51 53 53 55 55 57 57 59 59 61 - 61 63 63 65 65 67 67 69 69 71 - 71 73 73 75 75 77 77 79 79 81 - 81 83 83 85 85 87 87 89 89 91 - 91 93 93 95 95 97 97 99 99 101 - 101 103 103 105 105 107 107 109 109 111 - 111 113 113 115 115 117 117 119 119 121 - 121 123 123 125 125 127 127 129 129 131 - 131 133 133 135 135 137 137 139 139 141 - 141 143 143 145 145 147 147 149 149 151 - 151 153 153 155 155 157 157 159 159 161 - 161 163 163 165 165 167 167 169 169 171 - 171 173 173 175 175 177 177 179 179 181 - 181 183 183 185 185 187 187 189 189 191 - 191 193 193 195 195 197 197 199 199 201 - 201 203 203 205 205 207 207 209 209 211 - 2 0 0 2 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 14 11 16 14 18 16 20 18 22 20 - 24 22 26 24 28 26 30 28 32 30 - 34 32 36 34 38 36 40 38 42 40 - 44 42 46 44 48 46 50 48 52 50 - 54 52 56 54 58 56 60 58 62 60 - 64 62 66 64 68 66 70 68 72 70 - 74 72 76 74 78 76 80 78 82 80 - 84 82 86 84 88 86 90 88 92 90 - 94 92 96 94 98 96 100 98 102 100 - 104 102 106 104 108 106 110 108 112 110 - 114 112 116 114 118 116 120 118 122 120 - 124 122 126 124 128 126 130 128 132 130 - 134 132 136 134 138 136 140 138 142 140 - 144 142 146 144 148 146 150 148 152 150 - 154 152 156 154 158 156 160 158 162 160 - 164 162 166 164 168 166 170 168 172 170 - 174 172 176 174 178 176 180 178 182 180 - 184 182 186 184 188 186 190 188 192 190 - 194 192 196 194 198 196 200 198 202 200 - 204 202 206 204 208 206 210 208 212 210 - 2 0 0 2 1 - 0 - 211 212 - 1 0 0 1 202 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 - 11 12 211 212 13 15 17 19 21 23 - 25 27 29 31 33 35 37 39 41 43 - 45 47 49 51 53 55 57 59 61 63 - 65 67 69 71 73 75 77 79 81 83 - 85 87 89 91 93 95 97 99 101 103 - 105 107 109 111 113 115 117 119 121 123 - 125 127 129 131 133 135 137 139 141 143 - 145 147 149 151 153 155 157 159 161 163 - 165 167 169 171 173 175 177 179 181 183 - 185 187 189 191 193 195 197 199 201 203 - 205 207 209 210 208 206 204 202 200 198 - 196 194 192 190 188 186 184 182 180 178 - 176 174 172 170 168 166 164 162 160 158 - 156 154 152 150 148 146 144 142 140 138 - 136 134 132 130 128 126 124 122 120 118 - 116 114 112 110 108 106 104 102 100 98 - 96 94 92 90 88 86 84 82 80 78 - 76 74 72 70 68 66 64 62 60 58 - 56 54 52 50 48 46 44 42 40 38 - 36 34 32 30 28 26 24 22 20 18 - 16 14 - 11 0 0 9 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 213 13 214 14 215 11 216 217 14 - 214 13 218 15 219 16 220 221 16 219 - 15 222 17 223 18 224 225 18 223 17 - 226 19 227 20 228 229 20 227 19 230 - 21 231 22 232 233 22 231 21 234 23 - 235 24 236 237 24 235 23 238 25 239 - 26 240 241 26 239 25 242 27 243 28 - 244 245 28 243 27 246 29 247 30 248 - 249 30 247 29 250 31 251 32 252 253 - 32 251 31 254 33 255 34 256 257 34 - 255 33 258 35 259 36 260 261 36 259 - 35 262 37 263 38 264 265 38 263 37 - 266 39 267 40 268 269 40 267 39 270 - 41 271 42 272 273 42 271 41 274 43 - 275 44 276 277 44 275 43 278 45 279 - 46 280 281 46 279 45 282 47 283 48 - 284 285 48 283 47 286 49 287 50 288 - 289 50 287 49 290 51 291 52 292 293 - 52 291 51 294 53 295 54 296 297 54 - 295 53 298 55 299 56 300 301 56 299 - 55 302 57 303 58 304 305 58 303 57 - 306 59 307 60 308 309 60 307 59 310 - 61 311 62 312 313 62 311 61 314 63 - 315 64 316 317 64 315 63 318 65 319 - 66 320 321 66 319 65 322 67 323 68 - 324 325 68 323 67 326 69 327 70 328 - 329 70 327 69 330 71 331 72 332 333 - 72 331 71 334 73 335 74 336 337 74 - 335 73 338 75 339 76 340 341 76 339 - 75 342 77 343 78 344 345 78 343 77 - 346 79 347 80 348 349 79 350 81 351 - 82 352 80 347 353 81 354 83 355 84 - 356 82 351 357 83 358 85 359 86 360 - 84 355 361 85 362 87 363 88 364 86 - 359 365 87 366 89 367 90 368 88 363 - 369 89 370 91 371 92 372 90 367 373 - 91 374 93 375 94 376 92 371 377 93 - 378 95 379 96 380 94 375 381 95 382 - 97 383 98 384 96 379 385 97 386 99 - 387 100 388 98 383 389 99 390 101 391 - 102 392 100 387 393 101 394 103 395 104 - 396 102 391 397 103 398 105 399 106 400 - 104 395 401 105 402 107 403 108 404 106 - 399 405 107 406 109 407 110 408 108 403 - 409 109 410 111 411 112 412 110 407 413 - 111 414 113 415 114 416 112 411 417 113 - 418 115 419 116 420 114 415 421 115 422 - 117 423 118 424 116 419 425 117 426 119 - 427 120 428 118 423 429 119 430 121 431 - 122 432 120 427 433 121 434 123 435 124 - 436 122 431 437 123 438 125 439 126 440 - 124 435 441 125 442 127 443 128 444 126 - 439 445 127 446 129 447 130 448 128 443 - 449 129 450 131 451 132 452 130 447 453 - 131 454 133 455 134 456 132 451 457 133 - 458 135 459 136 460 134 455 461 135 462 - 137 463 138 464 136 459 465 137 466 139 - 467 140 468 138 463 469 139 470 141 471 - 142 472 140 467 473 141 474 143 475 144 - 476 142 471 477 143 478 145 479 146 480 - 144 475 481 145 482 147 483 148 484 146 - 479 485 147 486 149 487 150 488 148 483 - 489 149 490 151 491 152 492 150 487 493 - 151 494 153 495 154 496 152 491 497 153 - 498 155 499 156 500 154 495 501 155 502 - 157 503 158 504 156 499 505 157 506 159 - 507 160 508 158 503 509 159 510 161 511 - 162 512 160 507 513 161 514 163 515 164 - 516 162 511 517 163 518 165 519 166 520 - 164 515 521 165 522 167 523 168 524 166 - 519 525 167 526 169 527 170 528 168 523 - 529 169 530 171 531 172 532 170 527 533 - 171 534 173 535 174 536 172 531 537 173 - 538 175 539 176 540 174 535 541 175 542 - 177 543 178 544 176 539 545 177 546 179 - 547 180 548 178 543 549 179 550 181 551 - 182 552 180 547 553 181 554 183 555 184 - 556 182 551 557 183 558 185 559 186 560 - 184 555 561 185 562 187 563 188 564 186 - 559 565 187 566 189 567 190 568 188 563 - 569 189 570 191 571 192 572 190 567 573 - 191 574 193 575 194 576 192 571 577 193 - 578 195 579 196 580 194 575 581 195 582 - 197 583 198 584 196 579 585 197 586 199 - 587 200 588 198 583 589 199 590 201 591 - 202 592 200 587 593 201 594 203 595 204 - 596 202 591 597 203 598 205 599 206 600 - 204 595 601 205 602 207 603 208 604 206 - 599 605 207 606 209 607 210 608 208 603 - 609 209 610 211 611 212 612 210 607 613 - 11 0 0 9 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 213 13 214 14 215 11 216 217 14 - 214 13 218 15 219 16 220 221 16 219 - 15 222 17 223 18 224 225 18 223 17 - 226 19 227 20 228 229 20 227 19 230 - 21 231 22 232 233 22 231 21 234 23 - 235 24 236 237 24 235 23 238 25 239 - 26 240 241 26 239 25 242 27 243 28 - 244 245 28 243 27 246 29 247 30 248 - 249 30 247 29 250 31 251 32 252 253 - 32 251 31 254 33 255 34 256 257 34 - 255 33 258 35 259 36 260 261 36 259 - 35 262 37 263 38 264 265 38 263 37 - 266 39 267 40 268 269 40 267 39 270 - 41 271 42 272 273 42 271 41 274 43 - 275 44 276 277 44 275 43 278 45 279 - 46 280 281 46 279 45 282 47 283 48 - 284 285 48 283 47 286 49 287 50 288 - 289 50 287 49 290 51 291 52 292 293 - 52 291 51 294 53 295 54 296 297 54 - 295 53 298 55 299 56 300 301 56 299 - 55 302 57 303 58 304 305 58 303 57 - 306 59 307 60 308 309 60 307 59 310 - 61 311 62 312 313 62 311 61 314 63 - 315 64 316 317 64 315 63 318 65 319 - 66 320 321 66 319 65 322 67 323 68 - 324 325 68 323 67 326 69 327 70 328 - 329 70 327 69 330 71 331 72 332 333 - 72 331 71 334 73 335 74 336 337 74 - 335 73 338 75 339 76 340 341 76 339 - 75 342 77 343 78 344 345 78 343 77 - 346 79 347 80 348 349 79 350 81 351 - 82 352 80 347 353 81 354 83 355 84 - 356 82 351 357 83 358 85 359 86 360 - 84 355 361 85 362 87 363 88 364 86 - 359 365 87 366 89 367 90 368 88 363 - 369 89 370 91 371 92 372 90 367 373 - 91 374 93 375 94 376 92 371 377 93 - 378 95 379 96 380 94 375 381 95 382 - 97 383 98 384 96 379 385 97 386 99 - 387 100 388 98 383 389 99 390 101 391 - 102 392 100 387 393 101 394 103 395 104 - 396 102 391 397 103 398 105 399 106 400 - 104 395 401 105 402 107 403 108 404 106 - 399 405 107 406 109 407 110 408 108 403 - 409 109 410 111 411 112 412 110 407 413 - 111 414 113 415 114 416 112 411 417 113 - 418 115 419 116 420 114 415 421 115 422 - 117 423 118 424 116 419 425 117 426 119 - 427 120 428 118 423 429 119 430 121 431 - 122 432 120 427 433 121 434 123 435 124 - 436 122 431 437 123 438 125 439 126 440 - 124 435 441 125 442 127 443 128 444 126 - 439 445 127 446 129 447 130 448 128 443 - 449 129 450 131 451 132 452 130 447 453 - 131 454 133 455 134 456 132 451 457 133 - 458 135 459 136 460 134 455 461 135 462 - 137 463 138 464 136 459 465 137 466 139 - 467 140 468 138 463 469 139 470 141 471 - 142 472 140 467 473 141 474 143 475 144 - 476 142 471 477 143 478 145 479 146 480 - 144 475 481 145 482 147 483 148 484 146 - 479 485 147 486 149 487 150 488 148 483 - 489 149 490 151 491 152 492 150 487 493 - 151 494 153 495 154 496 152 491 497 153 - 498 155 499 156 500 154 495 501 155 502 - 157 503 158 504 156 499 505 157 506 159 - 507 160 508 158 503 509 159 510 161 511 - 162 512 160 507 513 161 514 163 515 164 - 516 162 511 517 163 518 165 519 166 520 - 164 515 521 165 522 167 523 168 524 166 - 519 525 167 526 169 527 170 528 168 523 - 529 169 530 171 531 172 532 170 527 533 - 171 534 173 535 174 536 172 531 537 173 - 538 175 539 176 540 174 535 541 175 542 - 177 543 178 544 176 539 545 177 546 179 - 547 180 548 178 543 549 179 550 181 551 - 182 552 180 547 553 181 554 183 555 184 - 556 182 551 557 183 558 185 559 186 560 - 184 555 561 185 562 187 563 188 564 186 - 559 565 187 566 189 567 190 568 188 563 - 569 189 570 191 571 192 572 190 567 573 - 191 574 193 575 194 576 192 571 577 193 - 578 195 579 196 580 194 575 581 195 582 - 197 583 198 584 196 579 585 197 586 199 - 587 200 588 198 583 589 199 590 201 591 - 202 592 200 587 593 201 594 203 595 204 - 596 202 591 597 203 598 205 599 206 600 - 204 595 601 205 602 207 603 208 604 206 - 599 605 207 606 209 607 210 608 208 603 - 609 209 610 211 611 212 612 210 607 613 - 8 0 0 4 100 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 213 214 215 216 214 218 219 220 219 222 - 223 224 223 226 227 228 227 230 231 232 - 231 234 235 236 235 238 239 240 239 242 - 243 244 243 246 247 248 247 250 251 252 - 251 254 255 256 255 258 259 260 259 262 - 263 264 263 266 267 268 267 270 271 272 - 271 274 275 276 275 278 279 280 279 282 - 283 284 283 286 287 288 287 290 291 292 - 291 294 295 296 295 298 299 300 299 302 - 303 304 303 306 307 308 307 310 311 312 - 311 314 315 316 315 318 319 320 319 322 - 323 324 323 326 327 328 327 330 331 332 - 331 334 335 336 335 338 339 340 339 342 - 343 344 343 346 347 348 350 351 352 347 - 354 355 356 351 358 359 360 355 362 363 - 364 359 366 367 368 363 370 371 372 367 - 374 375 376 371 378 379 380 375 382 383 - 384 379 386 387 388 383 390 391 392 387 - 394 395 396 391 398 399 400 395 402 403 - 404 399 406 407 408 403 410 411 412 407 - 414 415 416 411 418 419 420 415 422 423 - 424 419 426 427 428 423 430 431 432 427 - 434 435 436 431 438 439 440 435 442 443 - 444 439 446 447 448 443 450 451 452 447 - 454 455 456 451 458 459 460 455 462 463 - 464 459 466 467 468 463 470 471 472 467 - 474 475 476 471 478 479 480 475 482 483 - 484 479 486 487 488 483 490 491 492 487 - 494 495 496 491 498 499 500 495 502 503 - 504 499 506 507 508 503 510 511 512 507 - 514 515 516 511 518 519 520 515 522 523 - 524 519 526 527 528 523 530 531 532 527 - 534 535 536 531 538 539 540 535 542 543 - 544 539 546 547 548 543 550 551 552 547 - 554 555 556 551 558 559 560 555 562 563 - 564 559 566 567 568 563 570 571 572 567 - 574 575 576 571 578 579 580 575 582 583 - 584 579 586 587 588 583 590 591 592 587 - 594 595 596 591 598 599 600 595 602 603 - 604 599 606 607 608 603 610 611 612 607 - 8 0 0 4 100 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 - 213 214 215 216 214 218 219 220 219 222 - 223 224 223 226 227 228 227 230 231 232 - 231 234 235 236 235 238 239 240 239 242 - 243 244 243 246 247 248 247 250 251 252 - 251 254 255 256 255 258 259 260 259 262 - 263 264 263 266 267 268 267 270 271 272 - 271 274 275 276 275 278 279 280 279 282 - 283 284 283 286 287 288 287 290 291 292 - 291 294 295 296 295 298 299 300 299 302 - 303 304 303 306 307 308 307 310 311 312 - 311 314 315 316 315 318 319 320 319 322 - 323 324 323 326 327 328 327 330 331 332 - 331 334 335 336 335 338 339 340 339 342 - 343 344 343 346 347 348 350 351 352 347 - 354 355 356 351 358 359 360 355 362 363 - 364 359 366 367 368 363 370 371 372 367 - 374 375 376 371 378 379 380 375 382 383 - 384 379 386 387 388 383 390 391 392 387 - 394 395 396 391 398 399 400 395 402 403 - 404 399 406 407 408 403 410 411 412 407 - 414 415 416 411 418 419 420 415 422 423 - 424 419 426 427 428 423 430 431 432 427 - 434 435 436 431 438 439 440 435 442 443 - 444 439 446 447 448 443 450 451 452 447 - 454 455 456 451 458 459 460 455 462 463 - 464 459 466 467 468 463 470 471 472 467 - 474 475 476 471 478 479 480 475 482 483 - 484 479 486 487 488 483 490 491 492 487 - 494 495 496 491 498 499 500 495 502 503 - 504 499 506 507 508 503 510 511 512 507 - 514 515 516 511 518 519 520 515 522 523 - 524 519 526 527 528 523 530 531 532 527 - 534 535 536 531 538 539 540 535 542 543 - 544 539 546 547 548 543 550 551 552 547 - 554 555 556 551 558 559 560 555 562 563 - 564 559 566 567 568 563 570 571 572 567 - 574 575 576 571 578 579 580 575 582 583 - 584 579 586 587 588 583 590 591 592 587 - 594 595 596 591 598 599 600 595 602 603 - 604 599 606 607 608 603 610 611 612 607 - 8 0 0 4 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 14 11 14 13 15 16 16 15 - 17 18 18 17 19 20 20 19 21 22 - 22 21 23 24 24 23 25 26 26 25 - 27 28 28 27 29 30 30 29 31 32 - 32 31 33 34 34 33 35 36 36 35 - 37 38 38 37 39 40 40 39 41 42 - 42 41 43 44 44 43 45 46 46 45 - 47 48 48 47 49 50 50 49 51 52 - 52 51 53 54 54 53 55 56 56 55 - 57 58 58 57 59 60 60 59 61 62 - 62 61 63 64 64 63 65 66 66 65 - 67 68 68 67 69 70 70 69 71 72 - 72 71 73 74 74 73 75 76 76 75 - 77 78 78 77 79 80 79 81 82 80 - 81 83 84 82 83 85 86 84 85 87 - 88 86 87 89 90 88 89 91 92 90 - 91 93 94 92 93 95 96 94 95 97 - 98 96 97 99 100 98 99 101 102 100 - 101 103 104 102 103 105 106 104 105 107 - 108 106 107 109 110 108 109 111 112 110 - 111 113 114 112 113 115 116 114 115 117 - 118 116 117 119 120 118 119 121 122 120 - 121 123 124 122 123 125 126 124 125 127 - 128 126 127 129 130 128 129 131 132 130 - 131 133 134 132 133 135 136 134 135 137 - 138 136 137 139 140 138 139 141 142 140 - 141 143 144 142 143 145 146 144 145 147 - 148 146 147 149 150 148 149 151 152 150 - 151 153 154 152 153 155 156 154 155 157 - 158 156 157 159 160 158 159 161 162 160 - 161 163 164 162 163 165 166 164 165 167 - 168 166 167 169 170 168 169 171 172 170 - 171 173 174 172 173 175 176 174 175 177 - 178 176 177 179 180 178 179 181 182 180 - 181 183 184 182 183 185 186 184 185 187 - 188 186 187 189 190 188 189 191 192 190 - 191 193 194 192 193 195 196 194 195 197 - 198 196 197 199 200 198 199 201 202 200 - 201 203 204 202 203 205 206 204 205 207 - 208 206 207 209 210 208 209 211 212 210 - 2 0 0 2 301 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 - 12 13 13 14 14 11 11 12 13 15 - 15 16 16 14 15 17 17 18 18 16 - 17 19 19 20 20 18 19 21 21 22 - 22 20 21 23 23 24 24 22 23 25 - 25 26 26 24 25 27 27 28 28 26 - 27 29 29 30 30 28 29 31 31 32 - 32 30 31 33 33 34 34 32 33 35 - 35 36 36 34 35 37 37 38 38 36 - 37 39 39 40 40 38 39 41 41 42 - 42 40 41 43 43 44 44 42 43 45 - 45 46 46 44 45 47 47 48 48 46 - 47 49 49 50 50 48 49 51 51 52 - 52 50 51 53 53 54 54 52 53 55 - 55 56 56 54 55 57 57 58 58 56 - 57 59 59 60 60 58 59 61 61 62 - 62 60 61 63 63 64 64 62 63 65 - 65 66 66 64 65 67 67 68 68 66 - 67 69 69 70 70 68 69 71 71 72 - 72 70 71 73 73 74 74 72 73 75 - 75 76 76 74 75 77 77 78 78 76 - 77 79 79 80 80 78 79 81 81 82 - 82 80 81 83 83 84 84 82 83 85 - 85 86 86 84 85 87 87 88 88 86 - 87 89 89 90 90 88 89 91 91 92 - 92 90 91 93 93 94 94 92 93 95 - 95 96 96 94 95 97 97 98 98 96 - 97 99 99 100 100 98 99 101 101 102 - 102 100 101 103 103 104 104 102 103 105 - 105 106 106 104 105 107 107 108 108 106 - 107 109 109 110 110 108 109 111 111 112 - 112 110 111 113 113 114 114 112 113 115 - 115 116 116 114 115 117 117 118 118 116 - 117 119 119 120 120 118 119 121 121 122 - 122 120 121 123 123 124 124 122 123 125 - 125 126 126 124 125 127 127 128 128 126 - 127 129 129 130 130 128 129 131 131 132 - 132 130 131 133 133 134 134 132 133 135 - 135 136 136 134 135 137 137 138 138 136 - 137 139 139 140 140 138 139 141 141 142 - 142 140 141 143 143 144 144 142 143 145 - 145 146 146 144 145 147 147 148 148 146 - 147 149 149 150 150 148 149 151 151 152 - 152 150 151 153 153 154 154 152 153 155 - 155 156 156 154 155 157 157 158 158 156 - 157 159 159 160 160 158 159 161 161 162 - 162 160 161 163 163 164 164 162 163 165 - 165 166 166 164 165 167 167 168 168 166 - 167 169 169 170 170 168 169 171 171 172 - 172 170 171 173 173 174 174 172 173 175 - 175 176 176 174 175 177 177 178 178 176 - 177 179 179 180 180 178 179 181 181 182 - 182 180 181 183 183 184 184 182 183 185 - 185 186 186 184 185 187 187 188 188 186 - 187 189 189 190 190 188 189 191 191 192 - 192 190 191 193 193 194 194 192 193 195 - 195 196 196 194 195 197 197 198 198 196 - 197 199 199 200 200 198 199 201 201 202 - 202 200 201 203 203 204 204 202 203 205 - 205 206 206 204 205 207 207 208 208 206 - 207 209 209 210 210 208 209 211 211 212 - 212 210 - 1 0 0 1 100 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 217 221 225 229 233 237 241 245 249 253 - 257 261 265 269 273 277 281 285 289 293 - 297 301 305 309 313 317 321 325 329 333 - 337 341 345 349 353 357 361 365 369 373 - 377 381 385 389 393 397 401 405 409 413 - 417 421 425 429 433 437 441 445 449 453 - 457 461 465 469 473 477 481 485 489 493 - 497 501 505 509 513 517 521 525 529 533 - 537 541 545 549 553 557 561 565 569 573 - 577 581 585 589 593 597 601 605 609 613 - 1 0 0 1 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 217 221 225 229 233 237 241 245 249 253 - 257 261 265 269 273 277 281 285 289 293 - 297 301 305 309 313 317 321 325 329 333 - 337 341 345 349 353 357 361 365 369 373 - 377 381 385 389 393 397 401 405 409 413 - 417 421 425 429 433 437 441 445 449 453 - 457 461 465 469 473 477 481 485 489 493 - 497 501 505 509 513 517 521 525 529 533 - 537 541 545 549 553 557 561 565 569 573 - 577 581 585 589 593 597 601 605 609 613 - 1 0 0 1 100 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 6 6 6 6 6 6 6 6 6 6 - 217 221 225 229 233 237 241 245 249 253 - 257 261 265 269 273 277 281 285 289 293 - 297 301 305 309 313 317 321 325 329 333 - 337 341 345 349 353 357 361 365 369 373 - 377 381 385 389 393 397 401 405 409 413 - 417 421 425 429 433 437 441 445 449 453 - 457 461 465 469 473 477 481 485 489 493 - 497 501 505 509 513 517 521 525 529 533 - 537 541 545 549 553 557 561 565 569 573 - 577 581 585 589 593 597 601 605 609 613 - 8 0 0 4 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 14 11 14 13 15 16 16 15 - 17 18 18 17 19 20 20 19 21 22 - 22 21 23 24 24 23 25 26 26 25 - 27 28 28 27 29 30 30 29 31 32 - 32 31 33 34 34 33 35 36 36 35 - 37 38 38 37 39 40 40 39 41 42 - 42 41 43 44 44 43 45 46 46 45 - 47 48 48 47 49 50 50 49 51 52 - 52 51 53 54 54 53 55 56 56 55 - 57 58 58 57 59 60 60 59 61 62 - 62 61 63 64 64 63 65 66 66 65 - 67 68 68 67 69 70 70 69 71 72 - 72 71 73 74 74 73 75 76 76 75 - 77 78 78 77 79 80 79 81 82 80 - 81 83 84 82 83 85 86 84 85 87 - 88 86 87 89 90 88 89 91 92 90 - 91 93 94 92 93 95 96 94 95 97 - 98 96 97 99 100 98 99 101 102 100 - 101 103 104 102 103 105 106 104 105 107 - 108 106 107 109 110 108 109 111 112 110 - 111 113 114 112 113 115 116 114 115 117 - 118 116 117 119 120 118 119 121 122 120 - 121 123 124 122 123 125 126 124 125 127 - 128 126 127 129 130 128 129 131 132 130 - 131 133 134 132 133 135 136 134 135 137 - 138 136 137 139 140 138 139 141 142 140 - 141 143 144 142 143 145 146 144 145 147 - 148 146 147 149 150 148 149 151 152 150 - 151 153 154 152 153 155 156 154 155 157 - 158 156 157 159 160 158 159 161 162 160 - 161 163 164 162 163 165 166 164 165 167 - 168 166 167 169 170 168 169 171 172 170 - 171 173 174 172 173 175 176 174 175 177 - 178 176 177 179 180 178 179 181 182 180 - 181 183 184 182 183 185 186 184 185 187 - 188 186 187 189 190 188 189 191 192 190 - 191 193 194 192 193 195 196 194 195 197 - 198 196 197 199 200 198 199 201 202 200 - 201 203 204 202 203 205 206 204 205 207 - 208 206 207 209 210 208 209 211 212 210 - 1 0 0 1 301 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 - 213 214 215 216 218 219 220 222 223 224 - 226 227 228 230 231 232 234 235 236 238 - 239 240 242 243 244 246 247 248 250 251 - 252 254 255 256 258 259 260 262 263 264 - 266 267 268 270 271 272 274 275 276 278 - 279 280 282 283 284 286 287 288 290 291 - 292 294 295 296 298 299 300 302 303 304 - 306 307 308 310 311 312 314 315 316 318 - 319 320 322 323 324 326 327 328 330 331 - 332 334 335 336 338 339 340 342 343 344 - 346 347 348 350 351 352 354 355 356 358 - 359 360 362 363 364 366 367 368 370 371 - 372 374 375 376 378 379 380 382 383 384 - 386 387 388 390 391 392 394 395 396 398 - 399 400 402 403 404 406 407 408 410 411 - 412 414 415 416 418 419 420 422 423 424 - 426 427 428 430 431 432 434 435 436 438 - 439 440 442 443 444 446 447 448 450 451 - 452 454 455 456 458 459 460 462 463 464 - 466 467 468 470 471 472 474 475 476 478 - 479 480 482 483 484 486 487 488 490 491 - 492 494 495 496 498 499 500 502 503 504 - 506 507 508 510 511 512 514 515 516 518 - 519 520 522 523 524 526 527 528 530 531 - 532 534 535 536 538 539 540 542 543 544 - 546 547 548 550 551 552 554 555 556 558 - 559 560 562 563 564 566 567 568 570 571 - 572 574 575 576 578 579 580 582 583 584 - 586 587 588 590 591 592 594 595 596 598 - 599 600 602 603 604 606 607 608 610 611 - 612 - 3 0 0 3 301 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 - 217 213 217 217 214 221 217 215 217 217 - 216 217 221 218 221 221 219 225 221 220 - 221 225 222 225 225 223 229 225 224 225 - 229 226 229 229 227 233 229 228 229 233 - 230 233 233 231 237 233 232 233 237 234 - 237 237 235 241 237 236 237 241 238 241 - 241 239 245 241 240 241 245 242 245 245 - 243 249 245 244 245 249 246 249 249 247 - 253 249 248 249 253 250 253 253 251 257 - 253 252 253 257 254 257 257 255 261 257 - 256 257 261 258 261 261 259 265 261 260 - 261 265 262 265 265 263 269 265 264 265 - 269 266 269 269 267 273 269 268 269 273 - 270 273 273 271 277 273 272 273 277 274 - 277 277 275 281 277 276 277 281 278 281 - 281 279 285 281 280 281 285 282 285 285 - 283 289 285 284 285 289 286 289 289 287 - 293 289 288 289 293 290 293 293 291 297 - 293 292 293 297 294 297 297 295 301 297 - 296 297 301 298 301 301 299 305 301 300 - 301 305 302 305 305 303 309 305 304 305 - 309 306 309 309 307 313 309 308 309 313 - 310 313 313 311 317 313 312 313 317 314 - 317 317 315 321 317 316 317 321 318 321 - 321 319 325 321 320 321 325 322 325 325 - 323 329 325 324 325 329 326 329 329 327 - 333 329 328 329 333 330 333 333 331 337 - 333 332 333 337 334 337 337 335 341 337 - 336 337 341 338 341 341 339 345 341 340 - 341 345 342 345 345 343 349 345 344 345 - 349 346 349 349 347 353 349 348 349 353 - 350 353 353 351 357 353 352 353 357 354 - 357 357 355 361 357 356 357 361 358 361 - 361 359 365 361 360 361 365 362 365 365 - 363 369 365 364 365 369 366 369 369 367 - 373 369 368 369 373 370 373 373 371 377 - 373 372 373 377 374 377 377 375 381 377 - 376 377 381 378 381 381 379 385 381 380 - 381 385 382 385 385 383 389 385 384 385 - 389 386 389 389 387 393 389 388 389 393 - 390 393 393 391 397 393 392 393 397 394 - 397 397 395 401 397 396 397 401 398 401 - 401 399 405 401 400 401 405 402 405 405 - 403 409 405 404 405 409 406 409 409 407 - 413 409 408 409 413 410 413 413 411 417 - 413 412 413 417 414 417 417 415 421 417 - 416 417 421 418 421 421 419 425 421 420 - 421 425 422 425 425 423 429 425 424 425 - 429 426 429 429 427 433 429 428 429 433 - 430 433 433 431 437 433 432 433 437 434 - 437 437 435 441 437 436 437 441 438 441 - 441 439 445 441 440 441 445 442 445 445 - 443 449 445 444 445 449 446 449 449 447 - 453 449 448 449 453 450 453 453 451 457 - 453 452 453 457 454 457 457 455 461 457 - 456 457 461 458 461 461 459 465 461 460 - 461 465 462 465 465 463 469 465 464 465 - 469 466 469 469 467 473 469 468 469 473 - 470 473 473 471 477 473 472 473 477 474 - 477 477 475 481 477 476 477 481 478 481 - 481 479 485 481 480 481 485 482 485 485 - 483 489 485 484 485 489 486 489 489 487 - 493 489 488 489 493 490 493 493 491 497 - 493 492 493 497 494 497 497 495 501 497 - 496 497 501 498 501 501 499 505 501 500 - 501 505 502 505 505 503 509 505 504 505 - 509 506 509 509 507 513 509 508 509 513 - 510 513 513 511 517 513 512 513 517 514 - 517 517 515 521 517 516 517 521 518 521 - 521 519 525 521 520 521 525 522 525 525 - 523 529 525 524 525 529 526 529 529 527 - 533 529 528 529 533 530 533 533 531 537 - 533 532 533 537 534 537 537 535 541 537 - 536 537 541 538 541 541 539 545 541 540 - 541 545 542 545 545 543 549 545 544 545 - 549 546 549 549 547 553 549 548 549 553 - 550 553 553 551 557 553 552 553 557 554 - 557 557 555 561 557 556 557 561 558 561 - 561 559 565 561 560 561 565 562 565 565 - 563 569 565 564 565 569 566 569 569 567 - 573 569 568 569 573 570 573 573 571 577 - 573 572 573 577 574 577 577 575 581 577 - 576 577 581 578 581 581 579 585 581 580 - 581 585 582 585 585 583 589 585 584 585 - 589 586 589 589 587 593 589 588 589 593 - 590 593 593 591 597 593 592 593 597 594 - 597 597 595 601 597 596 597 601 598 601 - 601 599 605 601 600 601 605 602 605 605 - 603 609 605 604 605 609 606 609 609 607 - 613 609 608 609 613 610 613 613 611 613 - 613 612 613 - 3 0 0 3 301 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 - 12 13 213 13 14 214 14 11 215 11 - 12 216 13 15 218 15 16 219 16 14 - 220 15 17 222 17 18 223 18 16 224 - 17 19 226 19 20 227 20 18 228 19 - 21 230 21 22 231 22 20 232 21 23 - 234 23 24 235 24 22 236 23 25 238 - 25 26 239 26 24 240 25 27 242 27 - 28 243 28 26 244 27 29 246 29 30 - 247 30 28 248 29 31 250 31 32 251 - 32 30 252 31 33 254 33 34 255 34 - 32 256 33 35 258 35 36 259 36 34 - 260 35 37 262 37 38 263 38 36 264 - 37 39 266 39 40 267 40 38 268 39 - 41 270 41 42 271 42 40 272 41 43 - 274 43 44 275 44 42 276 43 45 278 - 45 46 279 46 44 280 45 47 282 47 - 48 283 48 46 284 47 49 286 49 50 - 287 50 48 288 49 51 290 51 52 291 - 52 50 292 51 53 294 53 54 295 54 - 52 296 53 55 298 55 56 299 56 54 - 300 55 57 302 57 58 303 58 56 304 - 57 59 306 59 60 307 60 58 308 59 - 61 310 61 62 311 62 60 312 61 63 - 314 63 64 315 64 62 316 63 65 318 - 65 66 319 66 64 320 65 67 322 67 - 68 323 68 66 324 67 69 326 69 70 - 327 70 68 328 69 71 330 71 72 331 - 72 70 332 71 73 334 73 74 335 74 - 72 336 73 75 338 75 76 339 76 74 - 340 75 77 342 77 78 343 78 76 344 - 77 79 346 79 80 347 80 78 348 79 - 81 350 81 82 351 82 80 352 81 83 - 354 83 84 355 84 82 356 83 85 358 - 85 86 359 86 84 360 85 87 362 87 - 88 363 88 86 364 87 89 366 89 90 - 367 90 88 368 89 91 370 91 92 371 - 92 90 372 91 93 374 93 94 375 94 - 92 376 93 95 378 95 96 379 96 94 - 380 95 97 382 97 98 383 98 96 384 - 97 99 386 99 100 387 100 98 388 99 - 101 390 101 102 391 102 100 392 101 103 - 394 103 104 395 104 102 396 103 105 398 - 105 106 399 106 104 400 105 107 402 107 - 108 403 108 106 404 107 109 406 109 110 - 407 110 108 408 109 111 410 111 112 411 - 112 110 412 111 113 414 113 114 415 114 - 112 416 113 115 418 115 116 419 116 114 - 420 115 117 422 117 118 423 118 116 424 - 117 119 426 119 120 427 120 118 428 119 - 121 430 121 122 431 122 120 432 121 123 - 434 123 124 435 124 122 436 123 125 438 - 125 126 439 126 124 440 125 127 442 127 - 128 443 128 126 444 127 129 446 129 130 - 447 130 128 448 129 131 450 131 132 451 - 132 130 452 131 133 454 133 134 455 134 - 132 456 133 135 458 135 136 459 136 134 - 460 135 137 462 137 138 463 138 136 464 - 137 139 466 139 140 467 140 138 468 139 - 141 470 141 142 471 142 140 472 141 143 - 474 143 144 475 144 142 476 143 145 478 - 145 146 479 146 144 480 145 147 482 147 - 148 483 148 146 484 147 149 486 149 150 - 487 150 148 488 149 151 490 151 152 491 - 152 150 492 151 153 494 153 154 495 154 - 152 496 153 155 498 155 156 499 156 154 - 500 155 157 502 157 158 503 158 156 504 - 157 159 506 159 160 507 160 158 508 159 - 161 510 161 162 511 162 160 512 161 163 - 514 163 164 515 164 162 516 163 165 518 - 165 166 519 166 164 520 165 167 522 167 - 168 523 168 166 524 167 169 526 169 170 - 527 170 168 528 169 171 530 171 172 531 - 172 170 532 171 173 534 173 174 535 174 - 172 536 173 175 538 175 176 539 176 174 - 540 175 177 542 177 178 543 178 176 544 - 177 179 546 179 180 547 180 178 548 179 - 181 550 181 182 551 182 180 552 181 183 - 554 183 184 555 184 182 556 183 185 558 - 185 186 559 186 184 560 185 187 562 187 - 188 563 188 186 564 187 189 566 189 190 - 567 190 188 568 189 191 570 191 192 571 - 192 190 572 191 193 574 193 194 575 194 - 192 576 193 195 578 195 196 579 196 194 - 580 195 197 582 197 198 583 198 196 584 - 197 199 586 199 200 587 200 198 588 199 - 201 590 201 202 591 202 200 592 201 203 - 594 203 204 595 204 202 596 203 205 598 - 205 206 599 206 204 600 205 207 602 207 - 208 603 208 206 604 207 209 606 209 210 - 607 210 208 608 209 211 610 211 212 611 - 212 210 612 - 0 2 0 0 0 - 40 41 - 3 0 0 3 301 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 - 12 213 13 13 214 14 14 215 11 11 - 216 12 13 218 15 15 219 16 16 220 - 14 15 222 17 17 223 18 18 224 16 - 17 226 19 19 227 20 20 228 18 19 - 230 21 21 231 22 22 232 20 21 234 - 23 23 235 24 24 236 22 23 238 25 - 25 239 26 26 240 24 25 242 27 27 - 243 28 28 244 26 27 246 29 29 247 - 30 30 248 28 29 250 31 31 251 32 - 32 252 30 31 254 33 33 255 34 34 - 256 32 33 258 35 35 259 36 36 260 - 34 35 262 37 37 263 38 38 264 36 - 37 266 39 39 267 40 40 268 38 39 - 270 41 41 271 42 42 272 40 41 274 - 43 43 275 44 44 276 42 43 278 45 - 45 279 46 46 280 44 45 282 47 47 - 283 48 48 284 46 47 286 49 49 287 - 50 50 288 48 49 290 51 51 291 52 - 52 292 50 51 294 53 53 295 54 54 - 296 52 53 298 55 55 299 56 56 300 - 54 55 302 57 57 303 58 58 304 56 - 57 306 59 59 307 60 60 308 58 59 - 310 61 61 311 62 62 312 60 61 314 - 63 63 315 64 64 316 62 63 318 65 - 65 319 66 66 320 64 65 322 67 67 - 323 68 68 324 66 67 326 69 69 327 - 70 70 328 68 69 330 71 71 331 72 - 72 332 70 71 334 73 73 335 74 74 - 336 72 73 338 75 75 339 76 76 340 - 74 75 342 77 77 343 78 78 344 76 - 77 346 79 79 347 80 80 348 78 79 - 350 81 81 351 82 82 352 80 81 354 - 83 83 355 84 84 356 82 83 358 85 - 85 359 86 86 360 84 85 362 87 87 - 363 88 88 364 86 87 366 89 89 367 - 90 90 368 88 89 370 91 91 371 92 - 92 372 90 91 374 93 93 375 94 94 - 376 92 93 378 95 95 379 96 96 380 - 94 95 382 97 97 383 98 98 384 96 - 97 386 99 99 387 100 100 388 98 99 - 390 101 101 391 102 102 392 100 101 394 - 103 103 395 104 104 396 102 103 398 105 - 105 399 106 106 400 104 105 402 107 107 - 403 108 108 404 106 107 406 109 109 407 - 110 110 408 108 109 410 111 111 411 112 - 112 412 110 111 414 113 113 415 114 114 - 416 112 113 418 115 115 419 116 116 420 - 114 115 422 117 117 423 118 118 424 116 - 117 426 119 119 427 120 120 428 118 119 - 430 121 121 431 122 122 432 120 121 434 - 123 123 435 124 124 436 122 123 438 125 - 125 439 126 126 440 124 125 442 127 127 - 443 128 128 444 126 127 446 129 129 447 - 130 130 448 128 129 450 131 131 451 132 - 132 452 130 131 454 133 133 455 134 134 - 456 132 133 458 135 135 459 136 136 460 - 134 135 462 137 137 463 138 138 464 136 - 137 466 139 139 467 140 140 468 138 139 - 470 141 141 471 142 142 472 140 141 474 - 143 143 475 144 144 476 142 143 478 145 - 145 479 146 146 480 144 145 482 147 147 - 483 148 148 484 146 147 486 149 149 487 - 150 150 488 148 149 490 151 151 491 152 - 152 492 150 151 494 153 153 495 154 154 - 496 152 153 498 155 155 499 156 156 500 - 154 155 502 157 157 503 158 158 504 156 - 157 506 159 159 507 160 160 508 158 159 - 510 161 161 511 162 162 512 160 161 514 - 163 163 515 164 164 516 162 163 518 165 - 165 519 166 166 520 164 165 522 167 167 - 523 168 168 524 166 167 526 169 169 527 - 170 170 528 168 169 530 171 171 531 172 - 172 532 170 171 534 173 173 535 174 174 - 536 172 173 538 175 175 539 176 176 540 - 174 175 542 177 177 543 178 178 544 176 - 177 546 179 179 547 180 180 548 178 179 - 550 181 181 551 182 182 552 180 181 554 - 183 183 555 184 184 556 182 183 558 185 - 185 559 186 186 560 184 185 562 187 187 - 563 188 188 564 186 187 566 189 189 567 - 190 190 568 188 189 570 191 191 571 192 - 192 572 190 191 574 193 193 575 194 194 - 576 192 193 578 195 195 579 196 196 580 - 194 195 582 197 197 583 198 198 584 196 - 197 586 199 199 587 200 200 588 198 199 - 590 201 201 591 202 202 592 200 201 594 - 203 203 595 204 204 596 202 203 598 205 - 205 599 206 206 600 204 205 602 207 207 - 603 208 208 604 206 207 606 209 209 607 - 210 210 608 208 209 610 211 211 611 212 - 212 612 210 - 1 0 0 1 202 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 - 12 14 16 18 20 22 24 26 28 30 - 32 34 36 38 40 42 44 46 48 50 - 52 54 56 58 60 62 64 66 68 70 - 72 74 76 78 79 81 83 85 87 89 - 91 93 95 97 99 101 103 105 107 109 - 111 113 115 117 119 121 123 125 127 129 - 131 133 135 137 139 141 143 145 147 149 - 151 153 155 157 159 161 163 165 167 169 - 171 173 175 177 179 181 183 185 187 189 - 191 193 195 197 199 201 203 205 207 209 - 13 15 17 19 21 23 25 27 29 31 - 33 35 37 39 41 43 45 47 49 51 - 53 55 57 59 61 63 65 67 69 71 - 73 75 77 211 82 84 86 88 90 92 - 94 96 98 100 102 104 106 108 110 112 - 114 116 118 120 122 124 126 128 130 132 - 134 136 138 140 142 144 146 148 150 152 - 154 156 158 160 162 164 166 168 170 172 - 174 176 178 180 182 184 186 188 190 192 - 194 196 198 200 202 204 206 208 210 212 - 11 80 - 8 0 0 4 100 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 12 13 14 11 14 13 15 16 16 15 - 17 18 18 17 19 20 20 19 21 22 - 22 21 23 24 24 23 25 26 26 25 - 27 28 28 27 29 30 30 29 31 32 - 32 31 33 34 34 33 35 36 36 35 - 37 38 38 37 39 40 40 39 41 42 - 42 41 43 44 44 43 45 46 46 45 - 47 48 48 47 49 50 50 49 51 52 - 52 51 53 54 54 53 55 56 56 55 - 57 58 58 57 59 60 60 59 61 62 - 62 61 63 64 64 63 65 66 66 65 - 67 68 68 67 69 70 70 69 71 72 - 72 71 73 74 74 73 75 76 76 75 - 77 78 78 77 79 80 79 81 82 80 - 81 83 84 82 83 85 86 84 85 87 - 88 86 87 89 90 88 89 91 92 90 - 91 93 94 92 93 95 96 94 95 97 - 98 96 97 99 100 98 99 101 102 100 - 101 103 104 102 103 105 106 104 105 107 - 108 106 107 109 110 108 109 111 112 110 - 111 113 114 112 113 115 116 114 115 117 - 118 116 117 119 120 118 119 121 122 120 - 121 123 124 122 123 125 126 124 125 127 - 128 126 127 129 130 128 129 131 132 130 - 131 133 134 132 133 135 136 134 135 137 - 138 136 137 139 140 138 139 141 142 140 - 141 143 144 142 143 145 146 144 145 147 - 148 146 147 149 150 148 149 151 152 150 - 151 153 154 152 153 155 156 154 155 157 - 158 156 157 159 160 158 159 161 162 160 - 161 163 164 162 163 165 166 164 165 167 - 168 166 167 169 170 168 169 171 172 170 - 171 173 174 172 173 175 176 174 175 177 - 178 176 177 179 180 178 179 181 182 180 - 181 183 184 182 183 185 186 184 185 187 - 188 186 187 189 190 188 189 191 192 190 - 191 193 194 192 193 195 196 194 195 197 - 198 196 197 199 200 198 199 201 202 200 - 201 203 204 202 203 205 206 204 205 207 - 208 206 207 209 210 208 209 211 212 210 - 1 0 0 1 301 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 4 4 4 4 4 4 4 4 4 - 4 - 213 214 215 216 218 219 220 222 223 224 - 226 227 228 230 231 232 234 235 236 238 - 239 240 242 243 244 246 247 248 250 251 - 252 254 255 256 258 259 260 262 263 264 - 266 267 268 270 271 272 274 275 276 278 - 279 280 282 283 284 286 287 288 290 291 - 292 294 295 296 298 299 300 302 303 304 - 306 307 308 310 311 312 314 315 316 318 - 319 320 322 323 324 326 327 328 330 331 - 332 334 335 336 338 339 340 342 343 344 - 346 347 348 350 351 352 354 355 356 358 - 359 360 362 363 364 366 367 368 370 371 - 372 374 375 376 378 379 380 382 383 384 - 386 387 388 390 391 392 394 395 396 398 - 399 400 402 403 404 406 407 408 410 411 - 412 414 415 416 418 419 420 422 423 424 - 426 427 428 430 431 432 434 435 436 438 - 439 440 442 443 444 446 447 448 450 451 - 452 454 455 456 458 459 460 462 463 464 - 466 467 468 470 471 472 474 475 476 478 - 479 480 482 483 484 486 487 488 490 491 - 492 494 495 496 498 499 500 502 503 504 - 506 507 508 510 511 512 514 515 516 518 - 519 520 522 523 524 526 527 528 530 531 - 532 534 535 536 538 539 540 542 543 544 - 546 547 548 550 551 552 554 555 556 558 - 559 560 562 563 564 566 567 568 570 571 - 572 574 575 576 578 579 580 582 583 584 - 586 587 588 590 591 592 594 595 596 598 - 599 600 602 603 604 606 607 608 610 611 - 612 - 3 0 0 3 301 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 2 2 - 2 - 217 213 217 217 214 221 217 215 217 217 - 216 217 221 218 221 221 219 225 221 220 - 221 225 222 225 225 223 229 225 224 225 - 229 226 229 229 227 233 229 228 229 233 - 230 233 233 231 237 233 232 233 237 234 - 237 237 235 241 237 236 237 241 238 241 - 241 239 245 241 240 241 245 242 245 245 - 243 249 245 244 245 249 246 249 249 247 - 253 249 248 249 253 250 253 253 251 257 - 253 252 253 257 254 257 257 255 261 257 - 256 257 261 258 261 261 259 265 261 260 - 261 265 262 265 265 263 269 265 264 265 - 269 266 269 269 267 273 269 268 269 273 - 270 273 273 271 277 273 272 273 277 274 - 277 277 275 281 277 276 277 281 278 281 - 281 279 285 281 280 281 285 282 285 285 - 283 289 285 284 285 289 286 289 289 287 - 293 289 288 289 293 290 293 293 291 297 - 293 292 293 297 294 297 297 295 301 297 - 296 297 301 298 301 301 299 305 301 300 - 301 305 302 305 305 303 309 305 304 305 - 309 306 309 309 307 313 309 308 309 313 - 310 313 313 311 317 313 312 313 317 314 - 317 317 315 321 317 316 317 321 318 321 - 321 319 325 321 320 321 325 322 325 325 - 323 329 325 324 325 329 326 329 329 327 - 333 329 328 329 333 330 333 333 331 337 - 333 332 333 337 334 337 337 335 341 337 - 336 337 341 338 341 341 339 345 341 340 - 341 345 342 345 345 343 349 345 344 345 - 349 346 349 349 347 353 349 348 349 353 - 350 353 353 351 357 353 352 353 357 354 - 357 357 355 361 357 356 357 361 358 361 - 361 359 365 361 360 361 365 362 365 365 - 363 369 365 364 365 369 366 369 369 367 - 373 369 368 369 373 370 373 373 371 377 - 373 372 373 377 374 377 377 375 381 377 - 376 377 381 378 381 381 379 385 381 380 - 381 385 382 385 385 383 389 385 384 385 - 389 386 389 389 387 393 389 388 389 393 - 390 393 393 391 397 393 392 393 397 394 - 397 397 395 401 397 396 397 401 398 401 - 401 399 405 401 400 401 405 402 405 405 - 403 409 405 404 405 409 406 409 409 407 - 413 409 408 409 413 410 413 413 411 417 - 413 412 413 417 414 417 417 415 421 417 - 416 417 421 418 421 421 419 425 421 420 - 421 425 422 425 425 423 429 425 424 425 - 429 426 429 429 427 433 429 428 429 433 - 430 433 433 431 437 433 432 433 437 434 - 437 437 435 441 437 436 437 441 438 441 - 441 439 445 441 440 441 445 442 445 445 - 443 449 445 444 445 449 446 449 449 447 - 453 449 448 449 453 450 453 453 451 457 - 453 452 453 457 454 457 457 455 461 457 - 456 457 461 458 461 461 459 465 461 460 - 461 465 462 465 465 463 469 465 464 465 - 469 466 469 469 467 473 469 468 469 473 - 470 473 473 471 477 473 472 473 477 474 - 477 477 475 481 477 476 477 481 478 481 - 481 479 485 481 480 481 485 482 485 485 - 483 489 485 484 485 489 486 489 489 487 - 493 489 488 489 493 490 493 493 491 497 - 493 492 493 497 494 497 497 495 501 497 - 496 497 501 498 501 501 499 505 501 500 - 501 505 502 505 505 503 509 505 504 505 - 509 506 509 509 507 513 509 508 509 513 - 510 513 513 511 517 513 512 513 517 514 - 517 517 515 521 517 516 517 521 518 521 - 521 519 525 521 520 521 525 522 525 525 - 523 529 525 524 525 529 526 529 529 527 - 533 529 528 529 533 530 533 533 531 537 - 533 532 533 537 534 537 537 535 541 537 - 536 537 541 538 541 541 539 545 541 540 - 541 545 542 545 545 543 549 545 544 545 - 549 546 549 549 547 553 549 548 549 553 - 550 553 553 551 557 553 552 553 557 554 - 557 557 555 561 557 556 557 561 558 561 - 561 559 565 561 560 561 565 562 565 565 - 563 569 565 564 565 569 566 569 569 567 - 573 569 568 569 573 570 573 573 571 577 - 573 572 573 577 574 577 577 575 581 577 - 576 577 581 578 581 581 579 585 581 580 - 581 585 582 585 585 583 589 585 584 585 - 589 586 589 589 587 593 589 588 589 593 - 590 593 593 591 597 593 592 593 597 594 - 597 597 595 601 597 596 597 601 598 601 - 601 599 605 601 600 601 605 602 605 605 - 603 609 605 604 605 609 606 609 609 607 - 613 609 608 609 613 610 613 613 611 613 - 613 612 613 - 3 0 0 3 301 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 - 12 13 213 13 14 214 14 11 215 11 - 12 216 13 15 218 15 16 219 16 14 - 220 15 17 222 17 18 223 18 16 224 - 17 19 226 19 20 227 20 18 228 19 - 21 230 21 22 231 22 20 232 21 23 - 234 23 24 235 24 22 236 23 25 238 - 25 26 239 26 24 240 25 27 242 27 - 28 243 28 26 244 27 29 246 29 30 - 247 30 28 248 29 31 250 31 32 251 - 32 30 252 31 33 254 33 34 255 34 - 32 256 33 35 258 35 36 259 36 34 - 260 35 37 262 37 38 263 38 36 264 - 37 39 266 39 40 267 40 38 268 39 - 41 270 41 42 271 42 40 272 41 43 - 274 43 44 275 44 42 276 43 45 278 - 45 46 279 46 44 280 45 47 282 47 - 48 283 48 46 284 47 49 286 49 50 - 287 50 48 288 49 51 290 51 52 291 - 52 50 292 51 53 294 53 54 295 54 - 52 296 53 55 298 55 56 299 56 54 - 300 55 57 302 57 58 303 58 56 304 - 57 59 306 59 60 307 60 58 308 59 - 61 310 61 62 311 62 60 312 61 63 - 314 63 64 315 64 62 316 63 65 318 - 65 66 319 66 64 320 65 67 322 67 - 68 323 68 66 324 67 69 326 69 70 - 327 70 68 328 69 71 330 71 72 331 - 72 70 332 71 73 334 73 74 335 74 - 72 336 73 75 338 75 76 339 76 74 - 340 75 77 342 77 78 343 78 76 344 - 77 79 346 79 80 347 80 78 348 79 - 81 350 81 82 351 82 80 352 81 83 - 354 83 84 355 84 82 356 83 85 358 - 85 86 359 86 84 360 85 87 362 87 - 88 363 88 86 364 87 89 366 89 90 - 367 90 88 368 89 91 370 91 92 371 - 92 90 372 91 93 374 93 94 375 94 - 92 376 93 95 378 95 96 379 96 94 - 380 95 97 382 97 98 383 98 96 384 - 97 99 386 99 100 387 100 98 388 99 - 101 390 101 102 391 102 100 392 101 103 - 394 103 104 395 104 102 396 103 105 398 - 105 106 399 106 104 400 105 107 402 107 - 108 403 108 106 404 107 109 406 109 110 - 407 110 108 408 109 111 410 111 112 411 - 112 110 412 111 113 414 113 114 415 114 - 112 416 113 115 418 115 116 419 116 114 - 420 115 117 422 117 118 423 118 116 424 - 117 119 426 119 120 427 120 118 428 119 - 121 430 121 122 431 122 120 432 121 123 - 434 123 124 435 124 122 436 123 125 438 - 125 126 439 126 124 440 125 127 442 127 - 128 443 128 126 444 127 129 446 129 130 - 447 130 128 448 129 131 450 131 132 451 - 132 130 452 131 133 454 133 134 455 134 - 132 456 133 135 458 135 136 459 136 134 - 460 135 137 462 137 138 463 138 136 464 - 137 139 466 139 140 467 140 138 468 139 - 141 470 141 142 471 142 140 472 141 143 - 474 143 144 475 144 142 476 143 145 478 - 145 146 479 146 144 480 145 147 482 147 - 148 483 148 146 484 147 149 486 149 150 - 487 150 148 488 149 151 490 151 152 491 - 152 150 492 151 153 494 153 154 495 154 - 152 496 153 155 498 155 156 499 156 154 - 500 155 157 502 157 158 503 158 156 504 - 157 159 506 159 160 507 160 158 508 159 - 161 510 161 162 511 162 160 512 161 163 - 514 163 164 515 164 162 516 163 165 518 - 165 166 519 166 164 520 165 167 522 167 - 168 523 168 166 524 167 169 526 169 170 - 527 170 168 528 169 171 530 171 172 531 - 172 170 532 171 173 534 173 174 535 174 - 172 536 173 175 538 175 176 539 176 174 - 540 175 177 542 177 178 543 178 176 544 - 177 179 546 179 180 547 180 178 548 179 - 181 550 181 182 551 182 180 552 181 183 - 554 183 184 555 184 182 556 183 185 558 - 185 186 559 186 184 560 185 187 562 187 - 188 563 188 186 564 187 189 566 189 190 - 567 190 188 568 189 191 570 191 192 571 - 192 190 572 191 193 574 193 194 575 194 - 192 576 193 195 578 195 196 579 196 194 - 580 195 197 582 197 198 583 198 196 584 - 197 199 586 199 200 587 200 198 588 199 - 201 590 201 202 591 202 200 592 201 203 - 594 203 204 595 204 202 596 203 205 598 - 205 206 599 206 204 600 205 207 602 207 - 208 603 208 206 604 207 209 606 209 210 - 607 210 208 608 209 211 610 211 212 611 - 212 210 612 - 0 2 0 0 0 - 42 43 - 3 0 0 3 301 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 - 5 - 12 213 13 13 214 14 14 215 11 11 - 216 12 13 218 15 15 219 16 16 220 - 14 15 222 17 17 223 18 18 224 16 - 17 226 19 19 227 20 20 228 18 19 - 230 21 21 231 22 22 232 20 21 234 - 23 23 235 24 24 236 22 23 238 25 - 25 239 26 26 240 24 25 242 27 27 - 243 28 28 244 26 27 246 29 29 247 - 30 30 248 28 29 250 31 31 251 32 - 32 252 30 31 254 33 33 255 34 34 - 256 32 33 258 35 35 259 36 36 260 - 34 35 262 37 37 263 38 38 264 36 - 37 266 39 39 267 40 40 268 38 39 - 270 41 41 271 42 42 272 40 41 274 - 43 43 275 44 44 276 42 43 278 45 - 45 279 46 46 280 44 45 282 47 47 - 283 48 48 284 46 47 286 49 49 287 - 50 50 288 48 49 290 51 51 291 52 - 52 292 50 51 294 53 53 295 54 54 - 296 52 53 298 55 55 299 56 56 300 - 54 55 302 57 57 303 58 58 304 56 - 57 306 59 59 307 60 60 308 58 59 - 310 61 61 311 62 62 312 60 61 314 - 63 63 315 64 64 316 62 63 318 65 - 65 319 66 66 320 64 65 322 67 67 - 323 68 68 324 66 67 326 69 69 327 - 70 70 328 68 69 330 71 71 331 72 - 72 332 70 71 334 73 73 335 74 74 - 336 72 73 338 75 75 339 76 76 340 - 74 75 342 77 77 343 78 78 344 76 - 77 346 79 79 347 80 80 348 78 79 - 350 81 81 351 82 82 352 80 81 354 - 83 83 355 84 84 356 82 83 358 85 - 85 359 86 86 360 84 85 362 87 87 - 363 88 88 364 86 87 366 89 89 367 - 90 90 368 88 89 370 91 91 371 92 - 92 372 90 91 374 93 93 375 94 94 - 376 92 93 378 95 95 379 96 96 380 - 94 95 382 97 97 383 98 98 384 96 - 97 386 99 99 387 100 100 388 98 99 - 390 101 101 391 102 102 392 100 101 394 - 103 103 395 104 104 396 102 103 398 105 - 105 399 106 106 400 104 105 402 107 107 - 403 108 108 404 106 107 406 109 109 407 - 110 110 408 108 109 410 111 111 411 112 - 112 412 110 111 414 113 113 415 114 114 - 416 112 113 418 115 115 419 116 116 420 - 114 115 422 117 117 423 118 118 424 116 - 117 426 119 119 427 120 120 428 118 119 - 430 121 121 431 122 122 432 120 121 434 - 123 123 435 124 124 436 122 123 438 125 - 125 439 126 126 440 124 125 442 127 127 - 443 128 128 444 126 127 446 129 129 447 - 130 130 448 128 129 450 131 131 451 132 - 132 452 130 131 454 133 133 455 134 134 - 456 132 133 458 135 135 459 136 136 460 - 134 135 462 137 137 463 138 138 464 136 - 137 466 139 139 467 140 140 468 138 139 - 470 141 141 471 142 142 472 140 141 474 - 143 143 475 144 144 476 142 143 478 145 - 145 479 146 146 480 144 145 482 147 147 - 483 148 148 484 146 147 486 149 149 487 - 150 150 488 148 149 490 151 151 491 152 - 152 492 150 151 494 153 153 495 154 154 - 496 152 153 498 155 155 499 156 156 500 - 154 155 502 157 157 503 158 158 504 156 - 157 506 159 159 507 160 160 508 158 159 - 510 161 161 511 162 162 512 160 161 514 - 163 163 515 164 164 516 162 163 518 165 - 165 519 166 166 520 164 165 522 167 167 - 523 168 168 524 166 167 526 169 169 527 - 170 170 528 168 169 530 171 171 531 172 - 172 532 170 171 534 173 173 535 174 174 - 536 172 173 538 175 175 539 176 176 540 - 174 175 542 177 177 543 178 178 544 176 - 177 546 179 179 547 180 180 548 178 179 - 550 181 181 551 182 182 552 180 181 554 - 183 183 555 184 184 556 182 183 558 185 - 185 559 186 186 560 184 185 562 187 187 - 563 188 188 564 186 187 566 189 189 567 - 190 190 568 188 189 570 191 191 571 192 - 192 572 190 191 574 193 193 575 194 194 - 576 192 193 578 195 195 579 196 196 580 - 194 195 582 197 197 583 198 198 584 196 - 197 586 199 199 587 200 200 588 198 199 - 590 201 201 591 202 202 592 200 201 594 - 203 203 595 204 204 596 202 203 598 205 - 205 599 206 206 600 204 205 602 207 207 - 603 208 208 604 206 207 606 209 209 607 - 210 210 608 208 209 610 211 211 611 212 - 212 612 210 - 1 0 0 1 202 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 - 0 0 - 12 14 16 18 20 22 24 26 28 30 - 32 34 36 38 40 42 44 46 48 50 - 52 54 56 58 60 62 64 66 68 70 - 72 74 76 78 79 81 83 85 87 89 - 91 93 95 97 99 101 103 105 107 109 - 111 113 115 117 119 121 123 125 127 129 - 131 133 135 137 139 141 143 145 147 149 - 151 153 155 157 159 161 163 165 167 169 - 171 173 175 177 179 181 183 185 187 189 - 191 193 195 197 199 201 203 205 207 209 - 13 15 17 19 21 23 25 27 29 31 - 33 35 37 39 41 43 45 47 49 51 - 53 55 57 59 61 63 65 67 69 71 - 73 75 77 211 82 84 86 88 90 92 - 94 96 98 100 102 104 106 108 110 112 - 114 116 118 120 122 124 126 128 130 132 - 134 136 138 140 142 144 146 148 150 152 - 154 156 158 160 162 164 166 168 170 172 - 174 176 178 180 182 184 186 188 190 192 - 194 196 198 200 202 204 206 208 210 212 - 11 80 - 3 0 0 3 99 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 - 217 214 221 221 219 225 225 223 229 229 - 227 233 233 231 237 237 235 241 241 239 - 245 245 243 249 249 247 253 253 251 257 - 257 255 261 261 259 265 265 263 269 269 - 267 273 273 271 277 277 275 281 281 279 - 285 285 283 289 289 287 293 293 291 297 - 297 295 301 301 299 305 305 303 309 309 - 307 313 313 311 317 317 315 321 321 319 - 325 325 323 329 329 327 333 333 331 337 - 337 335 341 341 339 345 345 343 349 349 - 347 353 353 351 357 357 355 361 361 359 - 365 365 363 369 369 367 373 373 371 377 - 377 375 381 381 379 385 385 383 389 389 - 387 393 393 391 397 397 395 401 401 399 - 405 405 403 409 409 407 413 413 411 417 - 417 415 421 421 419 425 425 423 429 429 - 427 433 433 431 437 437 435 441 441 439 - 445 445 443 449 449 447 453 453 451 457 - 457 455 461 461 459 465 465 463 469 469 - 467 473 473 471 477 477 475 481 481 479 - 485 485 483 489 489 487 493 493 491 497 - 497 495 501 501 499 505 505 503 509 509 - 507 513 513 511 517 517 515 521 521 519 - 525 525 523 529 529 527 533 533 531 537 - 537 535 541 541 539 545 545 543 549 549 - 547 553 553 551 557 557 555 561 561 559 - 565 565 563 569 569 567 573 573 571 577 - 577 575 581 581 579 585 585 583 589 589 - 587 593 593 591 597 597 595 601 601 599 - 605 605 603 609 609 607 613 - 2 0 0 2 202 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 - 217 213 217 215 217 216 221 218 221 220 - 225 222 225 224 229 226 229 228 233 230 - 233 232 237 234 237 236 241 238 241 240 - 245 242 245 244 249 246 249 248 253 250 - 253 252 257 254 257 256 261 258 261 260 - 265 262 265 264 269 266 269 268 273 270 - 273 272 277 274 277 276 281 278 281 280 - 285 282 285 284 289 286 289 288 293 290 - 293 292 297 294 297 296 301 298 301 300 - 305 302 305 304 309 306 309 308 313 310 - 313 312 317 314 317 316 321 318 321 320 - 325 322 325 324 329 326 329 328 333 330 - 333 332 337 334 337 336 341 338 341 340 - 345 342 345 344 349 346 349 348 353 350 - 353 352 357 354 357 356 361 358 361 360 - 365 362 365 364 369 366 369 368 373 370 - 373 372 377 374 377 376 381 378 381 380 - 385 382 385 384 389 386 389 388 393 390 - 393 392 397 394 397 396 401 398 401 400 - 405 402 405 404 409 406 409 408 413 410 - 413 412 417 414 417 416 421 418 421 420 - 425 422 425 424 429 426 429 428 433 430 - 433 432 437 434 437 436 441 438 441 440 - 445 442 445 444 449 446 449 448 453 450 - 453 452 457 454 457 456 461 458 461 460 - 465 462 465 464 469 466 469 468 473 470 - 473 472 477 474 477 476 481 478 481 480 - 485 482 485 484 489 486 489 488 493 490 - 493 492 497 494 497 496 501 498 501 500 - 505 502 505 504 509 506 509 508 513 510 - 513 512 517 514 517 516 521 518 521 520 - 525 522 525 524 529 526 529 528 533 530 - 533 532 537 534 537 536 541 538 541 540 - 545 542 545 544 549 546 549 548 553 550 - 553 552 557 554 557 556 561 558 561 560 - 565 562 565 564 569 566 569 568 573 570 - 573 572 577 574 577 576 581 578 581 580 - 585 582 585 584 589 586 589 588 593 590 - 593 592 597 594 597 596 601 598 601 600 - 605 602 605 604 609 606 609 608 613 610 - 613 611 613 612 - 3 0 0 3 99 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 - 217 214 221 221 219 225 225 223 229 229 - 227 233 233 231 237 237 235 241 241 239 - 245 245 243 249 249 247 253 253 251 257 - 257 255 261 261 259 265 265 263 269 269 - 267 273 273 271 277 277 275 281 281 279 - 285 285 283 289 289 287 293 293 291 297 - 297 295 301 301 299 305 305 303 309 309 - 307 313 313 311 317 317 315 321 321 319 - 325 325 323 329 329 327 333 333 331 337 - 337 335 341 341 339 345 345 343 349 349 - 347 353 353 351 357 357 355 361 361 359 - 365 365 363 369 369 367 373 373 371 377 - 377 375 381 381 379 385 385 383 389 389 - 387 393 393 391 397 397 395 401 401 399 - 405 405 403 409 409 407 413 413 411 417 - 417 415 421 421 419 425 425 423 429 429 - 427 433 433 431 437 437 435 441 441 439 - 445 445 443 449 449 447 453 453 451 457 - 457 455 461 461 459 465 465 463 469 469 - 467 473 473 471 477 477 475 481 481 479 - 485 485 483 489 489 487 493 493 491 497 - 497 495 501 501 499 505 505 503 509 509 - 507 513 513 511 517 517 515 521 521 519 - 525 525 523 529 529 527 533 533 531 537 - 537 535 541 541 539 545 545 543 549 549 - 547 553 553 551 557 557 555 561 561 559 - 565 565 563 569 569 567 573 573 571 577 - 577 575 581 581 579 585 585 583 589 589 - 587 593 593 591 597 597 595 601 601 599 - 605 605 603 609 609 607 613 - 2 0 0 2 202 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 3 3 3 3 3 3 3 3 - 3 3 - 217 213 217 215 217 216 221 218 221 220 - 225 222 225 224 229 226 229 228 233 230 - 233 232 237 234 237 236 241 238 241 240 - 245 242 245 244 249 246 249 248 253 250 - 253 252 257 254 257 256 261 258 261 260 - 265 262 265 264 269 266 269 268 273 270 - 273 272 277 274 277 276 281 278 281 280 - 285 282 285 284 289 286 289 288 293 290 - 293 292 297 294 297 296 301 298 301 300 - 305 302 305 304 309 306 309 308 313 310 - 313 312 317 314 317 316 321 318 321 320 - 325 322 325 324 329 326 329 328 333 330 - 333 332 337 334 337 336 341 338 341 340 - 345 342 345 344 349 346 349 348 353 350 - 353 352 357 354 357 356 361 358 361 360 - 365 362 365 364 369 366 369 368 373 370 - 373 372 377 374 377 376 381 378 381 380 - 385 382 385 384 389 386 389 388 393 390 - 393 392 397 394 397 396 401 398 401 400 - 405 402 405 404 409 406 409 408 413 410 - 413 412 417 414 417 416 421 418 421 420 - 425 422 425 424 429 426 429 428 433 430 - 433 432 437 434 437 436 441 438 441 440 - 445 442 445 444 449 446 449 448 453 450 - 453 452 457 454 457 456 461 458 461 460 - 465 462 465 464 469 466 469 468 473 470 - 473 472 477 474 477 476 481 478 481 480 - 485 482 485 484 489 486 489 488 493 490 - 493 492 497 494 497 496 501 498 501 500 - 505 502 505 504 509 506 509 508 513 510 - 513 512 517 514 517 516 521 518 521 520 - 525 522 525 524 529 526 529 528 533 530 - 533 532 537 534 537 536 541 538 541 540 - 545 542 545 544 549 546 549 548 553 550 - 553 552 557 554 557 556 561 558 561 560 - 565 562 565 564 569 566 569 568 573 570 - 573 572 577 574 577 576 581 578 581 580 - 585 582 585 584 589 586 589 588 593 590 - 593 592 597 594 597 596 601 598 601 600 - 605 602 605 604 609 606 609 608 613 610 - 613 611 613 612 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 2NBRE OBJETS NOMMES 0NBRE OBJETS 8 - 1 1 -1 1 - -23 100 1 - SCAL - 0 - - - 1 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 - 1 1 -1 2 - -24 100 1 - SCAL - 0 - CENT RE GIBI FEC IT - - 2 0 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 - 1 1 -1 2 - -24 100 1 - SCAL - 0 - CENT RE GIBI FEC IT - - 2 0 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 5.49990000000000E-02 5.49990000000000E-02 - 5.49990000000000E-02 - 1 1 -1 1 - -25 100 1 - SCAL - 0 - - - 1 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 4.00000000000000E+00 4.00000000000000E+00 - 4.00000000000000E+00 - 1 1 -1 1 - -27 301 1 - SCAL - 0 - FACE - - 2 - 3.00000000000000E-02 1.00000000000000E+00 2.99999999999980E-02 - 1.00000000000000E+00 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000001E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 3.00000000000009E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000010E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 - 1 2 -1 1 - -27 301 2 - UX UY - 0 0 - FACE - - 2 - -1.00000000000000E+00 1.99840144432528E-15 1.00000000000000E+00 - 0.00000000000000E+00 -1.00000000000000E+00 1.89431803576667E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.90125692967058E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 - 1 1 -1 1 - -34 301 1 - SCAL - 0 - FACE - - 2 - 3.00000000000000E-02 1.00000000000000E+00 2.99999999999980E-02 - 1.00000000000000E+00 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000001E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 3.00000000000009E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999999E-02 1.00000000000000E+00 - 2.99999999999999E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000010E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 3.00000000000000E-02 1.00000000000000E+00 - 3.00000000000000E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 3.00000000000002E-02 1.00000000000000E+00 - 3.00000000000002E-02 2.99999999999998E-02 1.00000000000000E+00 - 2.99999999999998E-02 - 1 2 -1 1 - -34 301 2 - UX UY - 0 0 - FACE - - 2 - -1.00000000000000E+00 1.99840144432528E-15 1.00000000000000E+00 - 0.00000000000000E+00 -1.00000000000000E+00 1.89431803576667E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.90125692967058E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 1.99840144432528E-15 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 9.99200722162641E-16 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 10NBRE OBJETS NOMMES 36NBRE OBJETS 40 - C_2 C_3 C_4 C_E C_F C_10 C_11 C_12 - C_13 C_14 C_18 C_1C C_20 C_24 C_28 C_2C - C_30 C_34 C_38 C_3C C_3E C_43 C_45 C_5C - C_5D C_5E C_6B C_6C C_6D C_6E C_8B C_8C - C_8D C_8E C_8F C_90 - 1 2 3 4 5 6 7 8 9 10 - 11 12 13 14 15 16 17 18 19 20 - 21 22 23 24 25 26 27 28 29 30 - 31 32 33 34 35 36 - 64 - 27 80 27 81 27 82 27 57 27 83 - 25 8 27 84 25 9 27 85 27 58 - 27 86 25 10 27 87 27 59 27 88 - 27 60 27 89 25 11 27 90 27 61 - 27 91 27 62 27 92 26 11 27 93 - 26 12 27 94 25 12 27 95 18 1 - 27 96 18 2 - 4 - 27 97 10 9 - 0 - 40 - 26 1 10 10 26 2 10 11 26 3 - 10 12 26 4 10 13 26 5 10 14 - 26 6 10 15 26 7 10 16 26 8 - 10 17 26 9 10 18 26 10 10 19 - 0 - 0 - 0 - 0 - 40 - 26 1 32 1 26 2 32 2 26 3 - 32 3 26 4 32 4 26 5 32 5 - 26 6 32 6 26 7 32 7 26 8 - 32 8 26 9 32 9 26 10 32 10 - 12 - 27 97 26 1 27 98 27 44 27 99 - 18 3 - 12 - 27 97 26 2 27 98 27 45 27 99 - 18 4 - 12 - 27 97 26 3 27 98 27 46 27 99 - 18 5 - 12 - 27 97 26 4 27 98 27 47 27 99 - 18 6 - 12 - 27 97 26 5 27 98 27 48 27 99 - 18 7 - 12 - 27 97 26 6 27 98 27 49 27 99 - 18 8 - 12 - 27 97 26 7 27 98 27 50 27 99 - 18 9 - 12 - 27 97 26 8 27 98 27 51 27 99 - 18 10 - 12 - 27 97 26 9 27 98 27 52 27 99 - 18 11 - 12 - 27 97 26 10 27 98 27 53 27 99 - 18 12 - 12 - 27 80 27 100 26 1 10 21 27 101 - 10 37 - 36 - 27 102 1 2 27 80 27 54 27 103 - 25 2 27 104 25 3 27 105 25 4 - 27 106 38 1 27 107 27 108 27 109 - 39 10 27 110 2 1 - 12 - 27 80 27 100 26 1 10 23 27 101 - 10 38 - 48 - 27 102 1 2 27 80 27 56 27 111 - 25 5 27 112 25 6 27 113 25 7 - 27 106 38 2 27 107 27 108 27 114 - 2 2 27 115 2 3 27 116 25 13 - 27 109 39 11 27 110 2 4 - 8 - 27 117 10 25 27 118 10 26 - 8 - 26 1 39 2 26 2 39 3 - 8 - 26 1 22 1 26 2 22 2 - 0 - 8 - 27 117 10 29 27 118 10 30 - 8 - 26 1 39 4 26 2 39 5 - 8 - 26 1 22 3 26 2 22 4 - 0 - 0 - 84 - 26 13 39 12 26 1 39 13 26 2 - 39 14 26 3 39 15 26 4 39 16 - 26 5 39 17 26 6 39 18 26 7 - 39 19 26 8 39 20 26 9 39 21 - 26 10 39 22 26 14 39 23 26 15 - 39 24 26 16 39 25 26 17 39 26 - 26 18 39 27 26 19 39 28 26 20 - 39 29 26 21 39 30 26 22 39 31 - 26 23 39 32 - 84 - 26 13 39 33 26 1 39 34 26 2 - 39 35 26 3 39 36 26 4 39 37 - 26 5 39 38 26 6 39 39 26 7 - 39 40 26 8 39 41 26 9 39 42 - 26 10 39 43 26 14 39 44 26 15 - 39 45 26 16 39 46 26 17 39 47 - 26 18 39 48 26 19 39 49 26 20 - 39 50 26 21 39 51 26 22 39 52 - 26 23 39 53 - 84 - 26 13 39 54 26 1 39 55 26 2 - 39 56 26 3 39 57 26 4 39 58 - 26 5 39 59 26 6 39 60 26 7 - 39 61 26 8 39 62 26 9 39 63 - 26 10 39 64 26 14 39 65 26 15 - 39 66 26 16 39 67 26 17 39 68 - 26 18 39 69 26 19 39 70 26 20 - 39 71 26 21 39 72 26 22 39 73 - 26 23 39 74 - 84 - 26 13 39 75 26 1 39 76 26 2 - 39 77 26 3 39 78 26 4 39 79 - 26 5 39 80 26 6 39 81 26 7 - 39 82 26 8 39 83 26 9 39 84 - 26 10 39 85 26 14 39 86 26 15 - 39 87 26 16 39 88 26 17 39 89 - 26 18 39 90 26 19 39 91 26 20 - 39 92 26 21 39 93 26 22 39 94 - 26 23 39 95 - 4 - 26 1 26 1 - 4 - 26 1 26 1 - 88 - 27 80 27 119 27 120 26 1 27 121 - 1 17 27 122 27 123 27 102 1 26 - 27 124 26 1 27 125 1 27 27 126 - 1 28 27 127 1 29 27 128 1 23 - 27 129 1 19 27 130 1 30 27 131 - 1 31 27 132 25 8 27 133 1 32 - 27 134 26 24 27 135 26 25 27 136 - 26 26 27 137 29 1 27 138 39 96 - 27 139 2 5 27 140 2 6 - 88 - 27 80 27 119 27 120 26 1 27 121 - 1 18 27 122 27 123 27 102 1 33 - 27 124 26 1 27 125 1 34 27 126 - 1 35 27 127 1 36 27 128 1 25 - 27 129 1 20 27 130 1 37 27 131 - 1 38 27 132 25 8 27 133 1 39 - 27 134 26 24 27 135 26 25 27 136 - 26 26 27 137 29 2 27 138 39 97 - 27 139 2 7 27 140 2 8 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 18NBRE OBJETS NOMMES 2NBRE OBJETS 20 - C_57 C_58 - 1 2 - 21 - 0.00000000000000E+00 1.80000000000000E+02 3.60000000000000E+02 - 5.40000000000000E+02 7.20000000000000E+02 9.00000000000000E+02 - 1.08000000000000E+03 1.26000000000000E+03 1.44000000000000E+03 - 1.62000000000000E+03 1.80000000000000E+03 1.98000000000000E+03 - 2.16000000000000E+03 2.34000000000000E+03 2.52000000000000E+03 - 2.70000000000000E+03 2.88000000000000E+03 3.06000000000000E+03 - 3.24000000000000E+03 3.42000000000000E+03 3.60000000000000E+03 - 21 - 0.00000000000000E+00 1.80000000000000E+02 3.60000000000000E+02 - 5.40000000000000E+02 7.20000000000000E+02 9.00000000000000E+02 - 1.08000000000000E+03 1.26000000000000E+03 1.44000000000000E+03 - 1.62000000000000E+03 1.80000000000000E+03 1.98000000000000E+03 - 2.16000000000000E+03 2.34000000000000E+03 2.52000000000000E+03 - 2.70000000000000E+03 2.88000000000000E+03 3.06000000000000E+03 - 3.24000000000000E+03 3.42000000000000E+03 3.60000000000000E+03 - 21 - -1.15000000000000E+00 -2.16540006497621E-01 -8.41397770009844E-02 - -4.85976677678687E-02 -3.37455570371690E-02 -2.52459832108218E-02 - -1.97690425436327E-02 -1.59409962757219E-02 -1.31888625377558E-02 - -1.09119860531204E-02 -9.19290101181534E-03 -7.84294096039159E-03 - -6.74365940030929E-03 -5.82979435469586E-03 -5.06740412419820E-03 - -4.41975400584346E-03 -3.86658567110400E-03 -3.39449654285649E-03 - -2.98504207216772E-03 -2.53776152358996E-03 -2.31476016363927E-03 - 21 - -1.15000000000000E+00 -9.30397404678052E-01 -3.99006393092861E-01 - -2.07168724171530E-01 -1.29350727394083E-01 -9.03551366564161E-02 - -6.76129559558960E-02 -5.28388160049688E-02 -4.26312674227759E-02 - -3.45377273330808E-02 -2.86788164188325E-02 -2.41927361441432E-02 - -2.06123089316590E-02 -1.76887851915472E-02 -1.52792695565113E-02 - -1.32536610116376E-02 -1.15427250669061E-02 -1.00903141297685E-02 - -8.84056690841387E-03 -7.48544137316366E-03 -6.80674510584511E-03 - 21 - -1.15000000000000E+00 -1.15060872024149E+00 -1.13499905693040E+00 - -7.95394822100051E-01 -4.30905323840183E-01 -2.64917049285670E-01 - -1.81256800501063E-01 -1.32961427219939E-01 -1.02231526111713E-01 - -8.01552310619662E-02 -6.48410172548005E-02 -5.35915529885089E-02 - -4.49298823577743E-02 -3.80662136598705E-02 -3.25312588159042E-02 - -2.79676615199501E-02 -2.41759217163720E-02 -2.09930359371299E-02 - -1.82881621622230E-02 -1.55047223983316E-02 -1.39381228920544E-02 - 21 - -1.15000000000000E+00 -1.15003050279579E+00 -1.14945324999156E+00 - -1.15216622941086E+00 -1.14194776513999E+00 -9.31257334949404E-01 - -5.67940566609100E-01 -3.60643458507160E-01 -2.50817800828769E-01 - -1.84496520865302E-01 -1.41808693317095E-01 -1.12656876351951E-01 - -9.16244319997735E-02 -7.58227570362588E-02 -6.35890561852581E-02 - -5.38457707225434E-02 -4.59685747877699E-02 -3.94954594598532E-02 - -3.41018315130958E-02 -2.89695162340258E-02 -2.56219655982434E-02 - 21 - -1.15000000000000E+00 -1.15000151469562E+00 -1.14997228758946E+00 - -1.15012078743789E+00 -1.14964997086609E+00 -1.15034594794479E+00 - -1.15242834219045E+00 -1.10346040120499E+00 -8.26415561949390E-01 - -5.30787359698162E-01 -3.58863584011360E-01 -2.60114236348006E-01 - -1.97855922317559E-01 -1.55882626060270E-01 -1.25947669247034E-01 - -1.03629896223960E-01 -8.64832401557986E-02 -7.29512134106926E-02 - -6.20519737259673E-02 -5.25659618901367E-02 -4.56082435019248E-02 - 21 - -1.15000000000000E+00 -1.15000007516150E+00 -1.14999858497049E+00 - -1.15000648601938E+00 -1.14998091221237E+00 -1.15002201148601E+00 - -1.15012292571263E+00 -1.14916546120541E+00 -1.15151945793081E+00 - -1.15140124164690E+00 -1.09441898963168E+00 -8.38270772945895E-01 - -5.54048026462153E-01 -3.82909893086666E-01 -2.82442837703037E-01 - -2.17561993419072E-01 -1.72968908719407E-01 -1.40614485535019E-01 - -1.16224003093473E-01 -9.70000399779595E-02 -8.21272011753830E-02 - 21 - -1.15000000000000E+00 -1.15000000372952E+00 -1.14999992775752E+00 - -1.15000034647027E+00 -1.14999895267042E+00 -1.15000134148075E+00 - -1.15000601799045E+00 -1.14995662642460E+00 -1.15009096148427E+00 - -1.15006229202357E+00 -1.14914889879884E+00 -1.15134713449563E+00 - -1.15235921190085E+00 -1.11260787601159E+00 -8.99467334965939E-01 - -6.13129474211469E-01 -4.25293436586229E-01 -3.14332083383740E-01 - -2.42570221057817E-01 -1.93671486405551E-01 -1.57261914282897E-01 - 21 - -1.15000000000000E+00 -1.15000000018511E+00 -1.14999999631362E+00 - -1.15000001845649E+00 -1.14999994261664E+00 -1.15000008029727E+00 - -1.15000029118890E+00 -1.14999771852574E+00 -1.15000518273646E+00 - -1.15000241369967E+00 -1.14995590195655E+00 -1.15008167585997E+00 - -1.15011240661199E+00 -1.14920280894521E+00 -1.15048413637776E+00 - -1.15355271999449E+00 -1.13489684822653E+00 -9.88079014600367E-01 - -7.06575620556291E-01 -4.89547416771393E-01 -3.57755578976403E-01 - 21 - -1.15000000000000E+00 -1.15000000000919E+00 -1.14999999981198E+00 - -1.15000000098080E+00 -1.14999999686222E+00 -1.15000000474282E+00 - -1.15000001391583E+00 -1.14999988021859E+00 -1.15000029238419E+00 - -1.15000007693173E+00 -1.14999769428415E+00 -1.15000469239171E+00 - -1.15000502071806E+00 -1.14995808942615E+00 -1.15003535574102E+00 - -1.15018676578197E+00 -1.14948762713892E+00 -1.14955847860536E+00 - -1.15335609441927E+00 -1.14777221562769E+00 -1.07288169976893E+00 - 21 - -1.15000000000000E+00 -1.15000000000046E+00 -1.14999999999041E+00 - -1.15000000005201E+00 -1.14999999982878E+00 -1.15000000027714E+00 - -1.15000000065495E+00 -1.14999999372727E+00 -1.15000001638543E+00 - -1.15000000121241E+00 -1.14999987981461E+00 -1.15000026657349E+00 - -1.15000021282329E+00 -1.14999777671329E+00 -1.15000230040975E+00 - -1.15000939152630E+00 -1.14997173675939E+00 -1.14998304877008E+00 - -1.15018720080803E+00 -1.14987984887642E+00 -1.14909664847054E+00 - 2 - 0.00000000000000E+00 3.60000000000000E+03 - 2 - 1.00000000000000E+00 1.00000000000000E+00 - 2 - 0.00000000000000E+00 3.60000000000000E+03 - 2 - 1.00000000000000E+00 1.00000000000000E+00 - 2 - 0.00000000000000E+00 3.60000000000000E+03 - 2 - 1.00000000000000E+00 1.00000000000000E+00 - 2 - 0.00000000000000E+00 3.60000000000000E+03 - 2 - 1.00000000000000E+00 1.00000000000000E+00 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 22NBRE OBJETS NOMMES 4NBRE OBJETS 4 - C_62 C_68 C_72 C_78 - 1 2 3 4 - 1 - REEL GIBI FEC IT - - -13 -14 0 - PROG _X PROG _Y REEL LIST REEL LIST REEL - GIBI FEC IT - - 1 - REEL GIBI FEC IT - - -15 -16 0 - PROG _X PROG _Y REEL LIST REEL LIST REEL - GIBI FEC IT - - 1 - REEL GIBI FEC IT - - -17 -18 0 - PROG _X PROG _Y REEL LIST REEL LIST REEL - GIBI FEC IT - - 1 - REEL GIBI FEC IT - - -19 -20 0 - PROG _X PROG _Y REEL LIST REEL LIST REEL - GIBI FEC IT - - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 25NBRE OBJETS NOMMES 12NBRE OBJETS 13 - PI C_40 C_41 C_42 C_47 C_48 C_49 C_4B - C_4C C_4E C_51 C_56 - 1 2 3 4 5 6 7 8 9 10 - 11 12 - 13 - 3.14159265358979E+00 -1.00000000000000E+00 7.30000000000000E+00 - 1.00000000000000E+00 2.92270000000000E+00 2.03040000000000E+00 - 5.07500000000000E-01 0.00000000000000E+00 3.00000000000000E+00 - 8.00000000000000E-01 1.00000000000000E-14 5.00000000000000E-04 - 3.42149382420365E-05 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 26NBRE OBJETS NOMMES 13NBRE OBJETS 26 - C_16 C_1A C_1E C_22 C_26 C_2A C_2E C_32 - C_36 C_3A C_54 C_55 C_8A - 1 2 3 4 5 6 7 8 9 10 - 11 12 1 - 26 - 1 2 3 4 5 6 7 - 8 9 10 1000 40 0 11 - 12 13 14 15 16 17 18 - 19 20 202 100 301 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 27NBRE OBJETS NOMMES 79NBRE OBJETS 140 - #2 #3 #4 D C GRAV * DENS - MESH0 TROPIC PARAMET PERMEA POROSITY SRESIDU MCOMPRES SATLAW - PERMLAW SOURCE BC_DIRI BC_NEUMA HINI MODD FIELD MOTC - / DEUXINDI LOI PW SAT SATUR H_TFIELD OUTPUTS - OUT_SUP TABLE OUBL OPTI MODE PLAN DEFO TASS - C_A MOT DIME C_17 C_1B C_1F C_23 C_27 - C_2B C_2F C_33 C_37 C_3B C_3F CHAIN C_46 - C_4A C_4D C_4F C_50 C_52 C_53 PROG PROG_Y - ALL X N INDIC CHP1 NIV MODARCY TRANS1 - TRANS2 QELEM OPTRESOL TYPDI MASSEFMH MATTR MATTM - 1 2 3 4 5 6 7 8 9 10 - 11 12 13 14 15 16 17 18 19 20 - 21 22 23 24 25 26 27 28 29 30 - 31 32 33 34 35 36 37 38 39 40 - 41 42 43 44 45 46 47 48 49 50 - 51 52 53 54 55 56 57 58 59 60 - 61 62 63 64 65 66 67 68 69 70 - 71 72 73 74 75 76 77 78 79 - 807 140 - #2#3#4DROICERCGRAV*DENSMESH0TROPICPARAMETPERMEAPOROSITYSRESIDUMCOMPRESS - ATLAWPERMLAWSOURCEBC_DIRIBC_NEUMAHINIMODDFIELDMOTC/DEUXINDILOIPWSATSATU - RH_TFIELDOUTPUTSOUT_SUPTABLEOUBLOPTIMODEPLANDEFOTASSISOTROPEMOTDIMEOUT2 - .955OUT2.895OUT2.835OUT2.775OUT2.715OUT2.655OUT2.595OUT2.535OUT2.475OUT - 2.415EXPONENTIELLECHAINVAN_GENUCHTENLUYESDECENTRENOEFMHILU0PROGPROG_YAL - LXNINDICCHP1NIVMODARCYTRANS1TRANS2QELEMOPTRESOLTYPDIMASSEFMHMATTRMATTMS - OUSTYPEDARCYSATURSOLVERPREFZREFMASSLUMPSOUS_RELAXATIONHOMOGENEISATIONLT - RACEEPSILONSSCHEMEPRECONDMAXITERITMAXRESIDU_MAXTEMPS_CALCULESTEMPS_SAUV - ESCPOINTNAMEVALUEMULTIZONEINDEXMAILLAGECOEF_NALPHACOEF_CMODELENOMZONE1A - BMCNFBHETANEXPMEXPPOROTERESIDUPRECCHAMPEVOLDOMAINEPRECONDIQUAFNOMDOMINE - FMDFACEFACELFACEPCENTREELTFAFACEL2MAILFACETOLERSOMMETNPTDNELDNBFDOBJINC - LUXXNORMAEXXSURFACXXNORMAF - 2 4 6 10 14 18 19 23 28 34 - 41 47 55 62 70 76 83 89 96 104 - 108 112 117 121 122 130 133 135 138 143 - 151 158 165 170 174 178 182 186 190 194 - 202 205 209 217 225 233 241 249 257 265 - 273 281 289 302 307 320 322 325 333 335 - 339 343 347 353 356 357 358 363 367 370 - 377 383 389 394 402 407 415 420 425 433 - 443 449 453 457 465 480 495 501 508 515 - 522 529 534 544 558 570 576 580 585 594 - 599 607 613 618 624 630 637 638 642 644 - 649 653 657 661 669 673 678 682 689 697 - 701 707 707 713 717 722 727 733 738 744 - 752 757 763 767 771 775 783 791 799 807 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 29NBRE OBJETS NOMMES 0NBRE OBJETS 2 - 8 18 - C_9 C_5 TOP RIGHT LEFT GE_3 GE_1 FAM_TOP FAM_STO - TFAM_LEFTC_75 C_6F C_65 C_6 C_5F C_3D BOTTOM MESH0 - - 8 18 - C_9 C_5 TOP RIGHT LEFT GE_3 GE_1 FAM_TOP FAM_STO - TFAM_LEFTC_75 C_6F C_65 C_6 C_5F C_3D BOTTOM MESH0 - - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 32NBRE OBJETS NOMMES 10NBRE OBJETS 613 - C_15 C_19 C_1D C_21 C_25 C_29 C_2D C_31 - C_35 C_39 - 1 2 3 4 5 6 7 8 9 10 - 613 - 604 605 606 607 608 609 610 611 612 613 - 201 1 101 2 102 3 103 4 104 5 - 105 6 106 7 107 8 108 9 109 10 - 110 11 111 12 112 13 113 14 114 15 - 115 16 116 17 117 18 118 19 119 20 - 120 21 121 22 122 23 123 24 124 25 - 125 26 126 27 127 28 128 29 129 30 - 130 31 131 32 132 33 133 34 35 202 - 36 135 37 136 38 137 39 138 40 139 - 41 140 42 141 43 142 44 143 45 144 - 46 145 47 146 48 147 49 148 50 149 - 51 150 52 151 53 152 54 153 55 154 - 56 155 57 156 58 157 59 158 60 159 - 61 160 62 161 63 162 64 163 65 164 - 66 165 67 166 68 167 69 168 70 169 - 71 170 72 171 73 172 74 173 75 174 - 76 175 77 176 78 177 79 178 80 179 - 81 180 82 181 83 182 84 183 85 184 - 86 185 87 186 88 187 89 188 90 189 - 91 190 92 191 93 192 94 193 95 194 - 96 195 97 196 98 197 99 198 100 199 - 134 200 203 204 205 206 207 208 209 210 - 211 212 213 214 215 216 217 218 219 220 - 221 222 223 224 225 226 227 228 229 230 - 231 232 233 234 235 236 237 238 239 240 - 241 242 243 244 245 246 247 248 249 250 - 251 252 253 254 255 256 257 258 259 260 - 261 262 263 264 265 266 267 268 269 270 - 271 272 273 274 275 276 277 278 279 280 - 281 282 283 284 285 286 287 288 289 290 - 291 292 293 294 295 296 297 298 299 300 - 301 302 303 304 305 306 307 308 309 310 - 311 312 313 314 315 316 317 318 319 320 - 321 322 323 324 325 326 327 328 329 330 - 331 332 333 334 335 336 337 338 339 340 - 341 342 343 344 345 346 347 348 349 350 - 351 352 353 354 355 356 357 358 359 360 - 361 362 363 364 365 366 367 368 369 370 - 371 372 373 374 375 376 377 378 379 380 - 381 382 383 384 385 386 387 388 389 390 - 391 392 393 394 395 396 397 398 399 400 - 401 402 403 404 405 406 407 408 409 410 - 411 412 413 414 415 416 417 418 419 420 - 421 422 423 424 425 426 427 428 429 430 - 431 432 433 434 435 436 437 438 439 440 - 441 442 443 444 445 446 447 448 449 450 - 451 452 453 454 455 456 457 458 459 460 - 461 462 463 464 465 466 467 468 469 470 - 471 472 473 474 475 476 477 478 479 480 - 481 482 483 484 485 486 487 488 489 490 - 491 492 493 494 495 496 497 498 499 500 - 501 502 503 504 505 506 507 508 509 510 - 511 512 513 514 515 516 517 518 519 520 - 521 522 523 524 525 526 527 528 529 530 - 531 532 533 534 535 536 537 538 539 540 - 541 542 543 544 545 546 547 548 549 550 - 551 552 553 554 555 556 557 558 559 560 - 561 562 563 564 565 566 567 568 569 570 - 571 572 573 574 575 576 577 578 579 580 - 581 582 583 584 585 586 587 588 589 590 - 591 592 593 594 595 596 597 598 599 600 - 601 602 603 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1 - 3042 - -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.99999999999980E-02 0.00000000000000E+00 - 5.00000000000000E-01 5.99999999999981E-02 0.00000000000000E+00 - 5.00000000000000E-01 8.99999999999981E-02 0.00000000000000E+00 - 5.00000000000000E-01 1.19999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.49999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.79999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.09999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.39999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.69999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.99999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.29999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.59999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.89999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.19999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.49999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.79999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.09999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.39999999999998E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.59999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.89999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.19999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.49999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.79999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.09999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.59999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.89999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.02000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.05000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.08000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.11000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.14000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.17000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.20000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.23000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.26000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.29000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.32000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.35000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.38000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.41000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.44000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.47000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.50000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.53000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.56000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.59000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.62000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.65000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.68000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.71000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.74000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.77000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.80000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.83000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.86000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.89000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.92000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.95000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.98000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.01000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.04000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.07000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.10000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.13000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.16000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.19000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.22000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.25000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.28000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.31000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.34000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.37000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.40000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.43000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.46000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.49000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.52000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.55000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.58000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.61000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.64000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.67000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.70000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.73000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.76000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.79000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.82000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.85000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.88000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.91000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.94000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.97000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 3.00000000000000E-02 0.00000000000000E+00 - -5.00000000000000E-01 6.00000000000000E-02 0.00000000000000E+00 - -5.00000000000000E-01 9.00000000000000E-02 0.00000000000000E+00 - -5.00000000000000E-01 1.20000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.50000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.80000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.10000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.40000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.70000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.00000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.30000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.60000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.90000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.20000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.50000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.80000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.10000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.40000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.70000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.00000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.30000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.60000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.90000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.20000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.50000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.80000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.10000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.40000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.70000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.00000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.30000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.60000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.90000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.05000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.08000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.11000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.14000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.17000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.20000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.23000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.26000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.29000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.32000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.35000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.38000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.41000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.44000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.47000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.50000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.53000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.56000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.59000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.62000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.65000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.68000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.71000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.74000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.77000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.80000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.83000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.86000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.89000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.92000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.95000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.98000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.01000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.04000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.07000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.10000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.13000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.16000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.19000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.22000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.25000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.28000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.31000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.34000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.37000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.40000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.43000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.46000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.49000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.52000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.55000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.58000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.61000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.64000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.67000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.70000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.73000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.76000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.79000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.82000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.85000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.88000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.91000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.94000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.97000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 3.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.02000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.50000000000000E-02 0.00000000000000E+00 - 0.00000000000000E+00 2.99999999999990E-02 0.00000000000000E+00 - 5.00000000000000E-01 1.49999999999990E-02 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.49999999999995E-02 0.00000000000000E+00 - -5.00000000000000E-01 4.50000000000000E-02 0.00000000000000E+00 - 0.00000000000000E+00 5.99999999999991E-02 0.00000000000000E+00 - 5.00000000000000E-01 4.49999999999981E-02 0.00000000000000E+00 - 0.00000000000000E+00 4.49999999999990E-02 0.00000000000000E+00 - -5.00000000000000E-01 7.50000000000000E-02 0.00000000000000E+00 - 0.00000000000000E+00 8.99999999999991E-02 0.00000000000000E+00 - 5.00000000000000E-01 7.49999999999981E-02 0.00000000000000E+00 - 0.00000000000000E+00 7.49999999999991E-02 0.00000000000000E+00 - -5.00000000000000E-01 1.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.19999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.04999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.04999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.49999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.34999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.34999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.79999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.64999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.64999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.09999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.94999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.94999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.24999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.24999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.55000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.54999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.54999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.85000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.84999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.84999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.15000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.14999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.14999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.59999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.44999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.44999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.89999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.74999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.74999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.19999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.04999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.04999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.49999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.34999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.34999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.79999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.64999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.64999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.09999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.94999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.94999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.24999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.24999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.55000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.54999999999998E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.54999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.85000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.84999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.84999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.15000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.14999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.14999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.59999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.44999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.44999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.90000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.74999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.74999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.20000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.04999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.05000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.50000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.34999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.35000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.80000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.64999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.65000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.10000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.94999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.95000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.24999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.25000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.55000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.54999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.54999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.85000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.84999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.84999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.15000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.14999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.14999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.60000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.44999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.45000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.90000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.74999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.75000000000000E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.00500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.02000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.00500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.03500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.05000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.03500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.03500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.06500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.08000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.06500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.06500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.09500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.11000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.09500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.09500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.12500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.14000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.12500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.12500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.15500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.17000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.15500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.15500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.18500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.20000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.18500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.18500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.21500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.23000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.21500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.21500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.24500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.26000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.24500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.24500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.27500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.29000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.27500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.27500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.30500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.32000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.30500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.30500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.33500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.35000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.33500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.33500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.36500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.38000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.36500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.36500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.39500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.41000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.39500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.39500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.42500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.44000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.42500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.42500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.45500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.47000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.45500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.45500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.48500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.50000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.48500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.48500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.51500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.53000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.51500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.51500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.54500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.56000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.54500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.54500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.57500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.59000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.57500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.57500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.60500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.62000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.60500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.60500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.63500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.65000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.63500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.63500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.66500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.68000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.66500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.66500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.69500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.71000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.69500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.69500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.72500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.74000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.72500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.72500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.75500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.77000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.75500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.75500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.78500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.80000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.78500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.78500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.81500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.83000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.81500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.81500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.84500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.86000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.84500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.84500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.87500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.89000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.87500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.87500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.90500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.92000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.90500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.90500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.93500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.95000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.93500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.93500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.96500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.98000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.96500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.96500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.99500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.01000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.99500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.99500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.02500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.04000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.02500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.02500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.05500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.07000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.05500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.05500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.08500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.10000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.08500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.08500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.11500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.13000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.11500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.11500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.14500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.16000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.14500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.14500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.17500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.19000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.17500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.17500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.20500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.22000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.20500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.20500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.23500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.25000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.23500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.23500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.26500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.28000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.26500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.26500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.29500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.31000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.29500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.29500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.32500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.34000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.32500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.32500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.35500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.37000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.35500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.35500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.38500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.40000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.38500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.38500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.41500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.43000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.41500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.41500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.44500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.46000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.44500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.44500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.47500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.49000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.47500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.47500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.50500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.52000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.50500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.53500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.55000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.53500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.53500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.56500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.58000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.56500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.56500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.59500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.61000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.59500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.59500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.62500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.64000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.62500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.62500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.65500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.67000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.65500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.65500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.68500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.70000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.68500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.68500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.71500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.73000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.71500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.71500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.74500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.76000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.74500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.74500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.77500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.79000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.77500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.77500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.80500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.82000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.80500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.80500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.83500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.85000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.83500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.83500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.86500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.88000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.86500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.86500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.89500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.91000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.89500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.89500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.92500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.94000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.92500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.92500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.95500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.97000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.95500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.95500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.98500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 3.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.98500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.98500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.95500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.89500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.83500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.77500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.71500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.65500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.59500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.53500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.47500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.41500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.50000000000000E-02 0.00000000000000E+00 - 0.00000000000000E+00 2.99999999999990E-02 0.00000000000000E+00 - 5.00000000000000E-01 1.49999999999990E-02 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 4.50000000000000E-02 0.00000000000000E+00 - 0.00000000000000E+00 5.99999999999991E-02 0.00000000000000E+00 - 5.00000000000000E-01 4.49999999999981E-02 0.00000000000000E+00 - -5.00000000000000E-01 7.50000000000000E-02 0.00000000000000E+00 - 0.00000000000000E+00 8.99999999999991E-02 0.00000000000000E+00 - 5.00000000000000E-01 7.49999999999981E-02 0.00000000000000E+00 - -5.00000000000000E-01 1.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.19999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.04999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.49999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.34999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.79999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.64999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.09999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 1.94999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.24999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.55000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.54999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 2.85000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 2.84999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.15000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.14999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.59999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.44999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 3.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.89999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 3.74999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.19999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.04999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.49999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.34999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.79999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.64999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 4.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.09999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 4.94999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.24999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.55000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.54999999999998E-01 0.00000000000000E+00 - -5.00000000000000E-01 5.85000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 5.84999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.15000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.14999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.59999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.44999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 6.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.90000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 6.74999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.20000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.04999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.50000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.34999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.80000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.64999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 7.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.10000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 7.94999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.39999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.24999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.55000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.69999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.54999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 8.85000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.99999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 8.84999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.15000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.29999999999999E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.14999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.60000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.44999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 9.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.90000000000000E-01 0.00000000000000E+00 - 5.00000000000000E-01 9.74999999999999E-01 0.00000000000000E+00 - -5.00000000000000E-01 1.00500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.02000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.00500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.03500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.05000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.03500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.06500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.08000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.06500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.09500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.11000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.09500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.12500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.14000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.12500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.15500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.17000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.15500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.18500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.20000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.18500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.21500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.23000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.21500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.24500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.26000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.24500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.27500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.29000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.27500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.30500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.32000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.30500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.33500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.35000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.33500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.36500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.38000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.36500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.39500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.41000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.39500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.42500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.44000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.42500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.45500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.47000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.45500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.48500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.50000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.48500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.51500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.53000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.51500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.54500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.56000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.54500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.57500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.59000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.57500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.60500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.62000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.60500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.63500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.65000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.63500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.66500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.68000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.66500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.69500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.71000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.69500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.72500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.74000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.72500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.75500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.77000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.75500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.78500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.80000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.78500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.81500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.83000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.81500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.84500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.86000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.84500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.87500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.89000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.87500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.90500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.92000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.90500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.93500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.95000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.93500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.96500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.98000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.96500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 1.99500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.01000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 1.99500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.02500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.04000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.02500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.05500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.07000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.05500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.08500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.10000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.08500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.11500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.13000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.11500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.14500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.16000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.14500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.17500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.19000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.17500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.20500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.22000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.20500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.23500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.25000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.23500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.26500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.28000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.26500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.29500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.31000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.29500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.32500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.34000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.32500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.35500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.37000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.35500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.38500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.40000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.38500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.41500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.43000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.41500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.44500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.46000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.44500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.47500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.49000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.47500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.50500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.52000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.50500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.53500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.55000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.53500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.56500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.58000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.56500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.59500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.61000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.59500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.62500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.64000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.62500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.65500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.67000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.65500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.68500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.70000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.68500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.71500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.73000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.71500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.74500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.76000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.74500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.77500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.79000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.77500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.80500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.82000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.80500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.83500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.85000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.83500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.86500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.88000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.86500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.89500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.91000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.89500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.92500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.94000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.92500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.95500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.97000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.95500000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 2.98500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 3.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 2.98500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.49999999999995E-02 0.00000000000000E+00 - 0.00000000000000E+00 4.49999999999990E-02 0.00000000000000E+00 - 0.00000000000000E+00 7.49999999999991E-02 0.00000000000000E+00 - 0.00000000000000E+00 1.04999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.34999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.64999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.94999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.24999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.54999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 2.84999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.14999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.44999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 3.74999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.04999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.34999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.64999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 4.94999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.24999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.54999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 5.84999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.14999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.44999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 6.74999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.05000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.35000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.65000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 7.95000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.25000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.54999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 8.84999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.14999999999999E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.45000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 9.75000000000000E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.00500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.03500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.06500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.09500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.12500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.15500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.18500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.21500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.24500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.27500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.30500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.33500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.36500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.39500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.42500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.45500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.48500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.51500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.54500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.57500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.60500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.63500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.66500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.69500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.72500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.75500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.78500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.81500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.84500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.87500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.90500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.93500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.96500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.99500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.02500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.05500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.08500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.11500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.14500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.17500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.20500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.23500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.26500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.29500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.32500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.35500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.38500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.41500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.44500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.47500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.53500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.56500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.59500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.62500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.65500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.68500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.71500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.74500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.77500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.80500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.83500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.86500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.89500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.92500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.95500000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.98500000000000E+00 0.00000000000000E+00 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 38NBRE OBJETS NOMMES 0NBRE OBJETS 2 - 1 2 2 2 3 11 1 0 0 0 - -17 100 1 1 2 0 0 1 0 0 - 0 - 318745 - DARCY - ISOTROPE - 0 -39 - K - 1 2 2 2 3 11 1 0 0 0 - -18 100 1 1 2 0 0 1 0 0 - 0 - 318877 - DARCY - ISOTROPE - 0 -40 - K - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 39NBRE OBJETS NOMMES 9NBRE OBJETS 97 - C_5B C_61 C_67 C_71 C_77 C_7D C_80 C_83 - C_D - 1 2 3 4 5 6 7 8 9 - 1 -1 6 72 - Field - - -4 317635 1 0 0 0 0 0 2 - - - 317623 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94500000000000E+00 -1.91500000000000E+00 - -1.88500000000000E+00 -1.85500000000000E+00 -1.82500000000000E+00 - -1.79500000000000E+00 -1.76500000000000E+00 -1.73500000000000E+00 - -1.70500000000000E+00 -1.67500000000000E+00 -1.64500000000000E+00 - -1.61500000000000E+00 -1.58500000000000E+00 -1.55500000000000E+00 - -1.52500000000000E+00 -1.49500000000000E+00 -1.46500000000000E+00 - -1.43500000000000E+00 -1.40500000000000E+00 -1.37500000000000E+00 - -1.34500000000000E+00 -1.31500000000000E+00 -1.28500000000000E+00 - -1.25500000000000E+00 -1.22500000000000E+00 -1.19500000000000E+00 - -1.16500000000000E+00 - 1 -1 6 72 - Field - - -3 317653 1 0 0 0 0 0 2 - - - 317641 - TH - REAL*8 - 1 1 0 0 - -4.15000000000000E+00 - 1 -1 6 72 - Field - - -5 317671 1 0 0 0 0 0 2 - - - 317659 - TH - REAL*8 - 1 1 0 0 - 0.00000000000000E+00 - 1 -1 6 72 - Field - - -6 317689 1 0 0 0 0 0 2 - - - 317677 - FLUX - REAL*8 - 1 100 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 1 -1 6 72 - Field - - -7 317707 1 0 0 0 0 0 2 - - - 317695 - FLUX - REAL*8 - 1 100 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 1 -1 6 72 - Field - - -4 317725 1 0 0 0 0 0 2 - - - 317713 - SCAL - REAL*8 - 1 100 0 0 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 1.62500000000000E-05 1.62500000000000E-05 - 1.62500000000000E-05 - 1 -1 6 72 - Field - - -4 317761 1 0 0 0 0 0 2 - - - 317749 - SCAL - REAL*8 - 1 100 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 1 -1 6 72 - Field - - -4 317779 1 0 0 0 0 0 2 - - - 317767 - SCAL - REAL*8 - 1 100 0 0 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 3.00000000000000E-01 3.00000000000000E-01 - 3.00000000000000E-01 - 1 -1 6 72 - Field - - -4 317797 1 0 0 0 0 0 2 - - - 317785 - SCAL - REAL*8 - 1 100 0 0 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 1.83330000000000E-01 1.83330000000000E-01 - 1.83330000000000E-01 - 1 -1 6 0 - -19 323917 1 0 0 0 0 0 0 - - - 323911 - SCAL - REAL*8 - 4 100 0 0 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 - 1 -1 6 0 - -20 322831 1 0 0 0 0 0 0 - - - 322825 - SCAL - REAL*8 - 4 100 0 0 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 - 1 -1 6 8 - SCALAIRE - -21 324895 1 0 0 0 -1 0 2 - - - 324913 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94500000000000E+00 -1.91500000000000E+00 - -1.88500000000000E+00 -1.85500000000000E+00 -1.82500000000000E+00 - -1.79500000000000E+00 -1.76500000000000E+00 -1.73500000000000E+00 - -1.70500000000000E+00 -1.67500000000000E+00 -1.64500000000000E+00 - -1.61500000000000E+00 -1.58500000000000E+00 -1.55500000000000E+00 - -1.52500000000000E+00 -1.49500000000000E+00 -1.46500000000000E+00 - -1.43500000000000E+00 -1.40500000000000E+00 -1.37500000000000E+00 - -1.34500000000000E+00 -1.31500000000000E+00 -1.28500000000000E+00 - -1.25500000000000E+00 -1.22500000000000E+00 -1.19500000000000E+00 - -1.16500000000000E+00 - 1 -1 6 8 - SCALAIRE - -21 325177 1 0 0 0 -2 0 2 - - - 325189 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94500000000000E+00 -1.91500000000000E+00 - -1.88500000000000E+00 -1.85500000000000E+00 -1.82499999999999E+00 - -1.79500000000002E+00 -1.76499999999990E+00 -1.73500000000046E+00 - -1.70499999999795E+00 -1.67500000000919E+00 -1.64499999995875E+00 - -1.61500000018511E+00 -1.58499999916916E+00 -1.55500000372952E+00 - -1.52499998325759E+00 -1.49500007516150E+00 -1.46499966257587E+00 - -1.43500151469562E+00 -1.40499319973773E+00 -1.37503050279579E+00 - -1.34486272161241E+00 -1.31560872024149E+00 -1.28208143964912E+00 - -1.03539740467805E+00 -5.49145954159549E-01 -2.61540006497621E-01 - -7.90437383301150E-02 - 1 -1 6 8 - SCALAIRE - -21 326443 1 0 0 0 -3 0 2 - - - 326491 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94500000000000E+00 -1.91500000000000E+00 - -1.88500000000001E+00 -1.85499999999998E+00 -1.82500000000011E+00 - -1.79499999999951E+00 -1.76500000000216E+00 -1.73499999999041E+00 - -1.70500000004245E+00 -1.67499999981198E+00 -1.64500000083258E+00 - -1.61499999631362E+00 -1.58500001632013E+00 -1.55499992775752E+00 - -1.52500031974302E+00 -1.49499858497048E+00 -1.46500626037860E+00 - -1.43497228758946E+00 -1.40512229123405E+00 -1.37445324999156E+00 - -1.34732398415236E+00 -1.29999905693040E+00 -9.39039023392856E-01 - -5.04006393092861E-01 -2.68247218769097E-01 -1.29139777000984E-01 - -3.75078673593804E-02 - 1 -1 6 8 - SCALAIRE - -21 324649 1 0 0 0 -4 0 2 - - - 324637 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94500000000000E+00 -1.91500000000001E+00 - -1.88499999999997E+00 -1.85500000000015E+00 -1.82499999999937E+00 - -1.79500000000275E+00 -1.76499999998803E+00 -1.73500000005201E+00 - -1.70499999977409E+00 -1.67500000098080E+00 -1.64499999574411E+00 - -1.61500001845649E+00 -1.58499992000793E+00 -1.55500034647027E+00 - -1.52499850024683E+00 -1.49500648601938E+00 -1.46497194543986E+00 - -1.43512078743789E+00 -1.40447123268857E+00 -1.37716622941086E+00 - -1.32999410273643E+00 -9.60394822100051E-01 -5.35159666296827E-01 - -3.12168724171530E-01 -1.81111056228492E-01 -9.35976677678686E-02 - -2.85937362206644E-02 - 1 -1 6 8 - SCALAIRE - -21 324409 1 0 0 0 -5 0 2 - - - 324397 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94500000000001E+00 -1.91499999999997E+00 - -1.88500000000012E+00 -1.85499999999949E+00 -1.82500000000217E+00 - -1.79499999999068E+00 -1.76500000003996E+00 -1.73499999982878E+00 - -1.70500000073316E+00 -1.67499999686222E+00 -1.64500001342196E+00 - -1.61499994261664E+00 -1.58500024520669E+00 -1.55499895267043E+00 - -1.52500447046912E+00 -1.49498091221237E+00 -1.46508121144364E+00 - -1.43464997086609E+00 -1.40643115235774E+00 -1.36694776513999E+00 - -1.04002512536374E+00 -5.95905323840183E-01 -3.67098547585758E-01 - -2.34350727394083E-01 -1.45267147117089E-01 -7.87455570371689E-02 - -2.47231504493155E-02 - 1 -1 6 8 - SCALAIRE - -21 324169 1 0 0 0 -6 0 2 - - - 324133 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94499999999999E+00 -1.91500000000005E+00 - -1.88499999999978E+00 -1.85500000000092E+00 -1.82499999999615E+00 - -1.79500000001605E+00 -1.76499999993324E+00 -1.73500000027714E+00 - -1.70499999885212E+00 -1.67500000474282E+00 -1.64499998045600E+00 - -1.61500008029727E+00 -1.58499967117228E+00 -1.55500134148075E+00 - -1.52499454751231E+00 -1.49502201148601E+00 -1.46491087912687E+00 - -1.43534594794479E+00 -1.40343758225318E+00 -1.15625733494940E+00 - -6.81591577109316E-01 -4.29917049285670E-01 -2.88797648041618E-01 - -1.95355136656416E-01 -1.26089220082132E-01 -7.02459832108218E-02 - -2.23956508279002E-02 - 1 -1 6 8 - SCALAIRE - -21 323839 1 0 0 0 -7 0 2 - - - 323827 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000000E+00 - -1.97500000000000E+00 -1.94499999999999E+00 -1.91500000000006E+00 - -1.88499999999972E+00 -1.85500000000136E+00 -1.82499999999356E+00 - -1.79500000003023E+00 -1.76499999985890E+00 -1.73500000065495E+00 - -1.70499999697457E+00 -1.67500001391583E+00 -1.64499993623505E+00 - -1.61500029118890E+00 -1.58499867429844E+00 -1.55500601799045E+00 - -1.52497273589662E+00 -1.49512292571263E+00 -1.46444078115727E+00 - -1.43742834219045E+00 -1.28263638756659E+00 -7.92940566609100E-01 - -5.01859648381398E-01 -3.46256800501063E-01 -2.45860445229598E-01 - -1.72612955955896E-01 -1.14269489149970E-01 -6.47690425436326E-02 - -2.08541229081103E-02 - 1 -1 6 8 - SCALAIRE - -21 323587 1 0 0 0 -8 0 2 - - - 323575 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000000E+00 -2.00500000000001E+00 - -1.97499999999995E+00 -1.94500000000020E+00 -1.91499999999911E+00 - -1.88500000000389E+00 -1.85499999998293E+00 -1.82500000007480E+00 - -1.79499999967238E+00 -1.76500000143404E+00 -1.73499999372727E+00 - -1.70500002741978E+00 -1.67499988021859E+00 -1.64500052291084E+00 - -1.61499771852574E+00 -1.58500994501613E+00 -1.55495662642460E+00 - -1.52518809456395E+00 -1.49416546120541E+00 -1.46840898382644E+00 - -1.38846040120499E+00 -9.35682918089455E-01 -5.85643458507160E-01 - -4.08184793116873E-01 -2.97961427219939E-01 -2.19395918470747E-01 - -1.57838816004969E-01 -1.06260677206624E-01 -6.09409962757218E-02 - -1.97564413836509E-02 - 1 -1 6 8 - SCALAIRE - -21 323413 1 0 0 0 -9 0 2 - - - 323395 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03500000000001E+00 -2.00499999999996E+00 - -1.97500000000015E+00 -1.94499999999935E+00 -1.91500000000279E+00 - -1.88499999998811E+00 -1.85500000005060E+00 -1.82499999978494E+00 - -1.79500000091293E+00 -1.76499999612968E+00 -1.73500001638543E+00 - -1.70499993073060E+00 -1.67500029238419E+00 -1.64499876778899E+00 - -1.61500518273646E+00 -1.58497821846118E+00 -1.55509096148427E+00 - -1.52461371682233E+00 -1.49651945793081E+00 -1.45550522404072E+00 - -1.11141556194939E+00 -6.85617467062108E-01 -4.75817800828769E-01 - -3.52493664636066E-01 -2.67231526111714E-01 -2.01735043236646E-01 - -1.47631267422776E-01 -1.00592612668865E-01 -5.81888625377557E-02 - -1.89603860496890E-02 - 1 -1 6 8 - SCALAIRE - -21 323221 1 0 0 0 -10 0 2 - - - 323209 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000000E+00 -2.03499999999999E+00 -2.00500000000002E+00 - -1.97499999999991E+00 -1.94500000000034E+00 -1.91499999999878E+00 - -1.88500000000425E+00 -1.85499999998610E+00 -1.82500000004098E+00 - -1.79499999990457E+00 -1.76500000006362E+00 -1.73500000121241E+00 - -1.70499998842712E+00 -1.67500007693173E+00 -1.64499955319541E+00 - -1.61500241369967E+00 -1.58498749940464E+00 -1.55506229202357E+00 - -1.52468781009987E+00 -1.49640124164690E+00 -1.29828539904695E+00 - -8.15787359698163E-01 -5.52564260334102E-01 -4.09496520865303E-01 - -3.15342837430113E-01 -2.45155231061966E-01 -1.88306354219557E-01 - -1.39537727333081E-01 -9.59717936652752E-02 -5.59119860531203E-02 - -1.82986686913840E-02 - 1 -1 6 8 - SCALAIRE - -21 323059 1 0 0 0 -11 0 2 - - - 323047 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000001E+00 -2.03499999999996E+00 -2.00500000000019E+00 - -1.97499999999915E+00 -1.94500000000375E+00 -1.91499999998343E+00 - -1.88500000007314E+00 -1.85499999967763E+00 -1.82500000141909E+00 - -1.79499999376094E+00 -1.76500002739826E+00 -1.73499987981461E+00 - -1.70500052665675E+00 -1.67499769428415E+00 -1.64501008296745E+00 - -1.61495590195655E+00 -1.58519189020477E+00 -1.55414889879884E+00 - -1.52851191983636E+00 -1.43941898963168E+00 -9.81842080685448E-01 - -6.43863584011360E-01 -4.73139086315934E-01 -3.66808693317095E-01 - -2.90338102902997E-01 -2.29841017254800E-01 -1.78775092857409E-01 - -1.33678816418832E-01 -9.25593652683946E-02 -5.41929010118153E-02 - -1.77895189025899E-02 - 1 -1 6 8 - SCALAIRE - -21 322561 1 0 0 0 -12 0 2 - - - 322471 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000001E+00 - -2.06499999999997E+00 -2.03500000000014E+00 -2.00499999999939E+00 - -1.97500000000260E+00 -1.94499999998894E+00 -1.91500000004693E+00 - -1.88499999980106E+00 -1.85500000084225E+00 -1.82499999643920E+00 - -1.79500001503169E+00 -1.76499993664479E+00 -1.73500026657349E+00 - -1.70499888033726E+00 -1.67500469239171E+00 -1.64498035522495E+00 - -1.61508167585997E+00 -1.58465446764326E+00 -1.55634713449563E+00 - -1.51635524464944E+00 -1.18327077294589E+00 -7.55733803743065E-01 - -5.45114236348007E-01 -4.22306189906336E-01 -3.37656876351951E-01 - -2.72525392337286E-01 -2.18591552988509E-01 -1.71608240957917E-01 - -1.29192736144143E-01 -8.99091049467646E-02 -5.28429409603915E-02 - -1.73868596837357E-02 - 1 -1 6 8 - SCALAIRE - -21 322099 1 0 0 0 -13 0 2 - - - 322087 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000000E+00 -2.09500000000000E+00 - -2.06500000000001E+00 -2.03499999999996E+00 -2.00500000000010E+00 - -1.97499999999980E+00 -1.94499999999978E+00 -1.91500000000559E+00 - -1.88499999995589E+00 -1.85500000027617E+00 -1.82499999843995E+00 - -1.79500000831078E+00 -1.76499995737749E+00 -1.73500021282329E+00 - -1.70499895816906E+00 -1.67500502071806E+00 -1.64497607675388E+00 - -1.61511240661199E+00 -1.58446815158855E+00 -1.55735921190085E+00 - -1.38188676739605E+00 -8.99048026462153E-01 -6.28308879412534E-01 - -4.82855922317560E-01 -3.87568689490143E-01 -3.16624431999774E-01 - -2.59181507666836E-01 -2.09929882357774E-01 -1.65975829802754E-01 - -1.25612308931659E-01 -8.77692139374181E-02 -5.17436594003092E-02 - -1.70572940941870E-02 - 1 -1 6 8 - SCALAIRE - -21 321907 1 0 0 0 -14 0 2 - - - 321895 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12500000000001E+00 -2.09499999999996E+00 - -2.06500000000020E+00 -2.03499999999913E+00 -2.00500000000383E+00 - -1.97499999998318E+00 -1.94500000007378E+00 -1.91499999967679E+00 - -1.88500000141394E+00 -1.85499999382253E+00 -1.82500002695510E+00 - -1.79499988252698E+00 -1.76500051133874E+00 -1.73499777671329E+00 - -1.70500965323825E+00 -1.67495808942615E+00 -1.64518091197089E+00 - -1.61420280894521E+00 -1.58824697663436E+00 -1.51760787601159E+00 - -1.08543736306801E+00 -7.27909893086666E-01 -5.50321650130748E-01 - -4.40882626060270E-01 -3.62575415113305E-01 -3.00822757036259E-01 - -2.48843364845485E-01 -2.03066213659871E-01 -1.61436270837271E-01 - -1.22688785191547E-01 -8.60041424118693E-02 -5.08297943546958E-02 - -1.67819474408829E-02 - 1 -1 6 8 - SCALAIRE - -21 321691 1 0 0 0 -15 0 2 - - - 321679 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000001E+00 -2.12499999999998E+00 -2.09500000000010E+00 - -2.06499999999957E+00 -2.03500000000177E+00 -2.00499999999262E+00 - -1.97500000003061E+00 -1.94499999987343E+00 -1.91500000052155E+00 - -1.88499999785939E+00 -1.85500000874691E+00 -1.82499996443679E+00 - -1.79500014376692E+00 -1.76499942260985E+00 -1.73500230040975E+00 - -1.70499090918539E+00 -1.67503535574102E+00 -1.64486149739304E+00 - -1.61548413637776E+00 -1.58236356215296E+00 -1.30446733496594E+00 - -8.53144609758120E-01 -6.27442837703036E-01 -4.98709850686808E-01 - -4.10947669247034E-01 -3.43861516019437E-01 -2.88589056185258E-01 - -2.40647818875179E-01 -1.97531258815904E-01 -1.57729398777222E-01 - -1.20279269556511E-01 -8.45392657922977E-02 -5.00674041241981E-02 - -1.65514929378359E-02 - 1 -1 6 8 - SCALAIRE - -21 321469 1 0 0 0 -16 0 2 - - - 321445 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000000E+00 - -2.15500000000000E+00 -2.12499999999998E+00 -2.09500000000010E+00 - -2.06499999999951E+00 -2.03500000000233E+00 -2.00499999998904E+00 - -1.97500000005111E+00 -1.94499999976330E+00 -1.91500000108945E+00 - -1.88499999501316E+00 -1.85500002271558E+00 -1.82499989698235E+00 - -1.79500046532613E+00 -1.76499790577032E+00 -1.73500939152630E+00 - -1.70495798442831E+00 -1.67518676578197E+00 -1.64415923729329E+00 - -1.61855271999449E+00 -1.49449212288334E+00 -1.01812947421147E+00 - -7.18323423488807E-01 -5.62561993419072E-01 -4.62394581843326E-01 - -3.88629896223960E-01 -3.29358866942754E-01 -2.78845770722544E-01 - -2.33989572297653E-01 -1.92967661519950E-01 -1.54638985801121E-01 - -1.18253661011638E-01 -8.33001983139831E-02 -4.94197540058434E-02 - -1.63552445631558E-02 - 1 -1 6 8 - SCALAIRE - -21 320965 1 0 0 0 -17 0 2 - - - 320425 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18500000000001E+00 - -2.15499999999996E+00 -2.12500000000017E+00 -2.09499999999925E+00 - -2.06500000000325E+00 -2.03499999998600E+00 -2.00500000006021E+00 - -1.97499999974149E+00 -1.94500000110828E+00 -1.91499999525586E+00 - -1.88500002027688E+00 -1.85499991346874E+00 -1.82500036868679E+00 - -1.79499843153118E+00 -1.76500666007237E+00 -1.73497173675939E+00 - -1.70511918852121E+00 -1.67448762713892E+00 -1.64703246136924E+00 - -1.59989684822653E+00 -1.23068537872209E+00 -8.30293436586229E-01 - -6.34936848362107E-01 -5.17968908719407E-01 -4.35677384763109E-01 - -3.71483240155799E-01 -3.17879990570377E-01 -2.70968574787770E-01 - -2.28522077526631E-01 -1.89175921716372E-01 -1.52047710788681E-01 - -1.16542725066906E-01 -8.22472559032441E-02 -4.88665856711039E-02 - -1.61870424730015E-02 - 1 -1 6 8 - SCALAIRE - -21 320281 1 0 0 0 -18 0 2 - - - 320269 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000000E+00 -2.18499999999999E+00 - -2.15500000000003E+00 -2.12499999999987E+00 -2.09500000000049E+00 - -2.06499999999818E+00 -2.03500000000650E+00 -2.00499999997787E+00 - -1.97500000006975E+00 -1.94499999981103E+00 -1.91500000032912E+00 - -1.88500000068871E+00 -1.85499998789205E+00 -1.82500009177635E+00 - -1.79499943295436E+00 -1.76500318344073E+00 -1.73498304877008E+00 - -1.70508638477966E+00 -1.67455847860536E+00 -1.64702131434164E+00 - -1.45307901460037E+00 -9.76343132097054E-01 -7.19332083383740E-01 - -5.78992719586475E-01 -4.85614485535019E-01 -4.15290953068750E-01 - -3.57951213410693E-01 -3.08605124448837E-01 -2.64495459459853E-01 - -2.23973592811258E-01 -1.85993035937130E-01 -1.49858247317575E-01 - -1.15090314129768E-01 -8.13505236277189E-02 -4.83944965428564E-02 - -1.60433356194304E-02 - 1 -1 6 8 - SCALAIRE - -21 320101 1 0 0 0 -19 0 2 - - - 320089 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21500000000001E+00 -2.18499999999996E+00 - -2.15500000000019E+00 -2.12499999999915E+00 -2.09500000000376E+00 - -2.06499999998335E+00 -2.03500000007360E+00 -2.00499999967542E+00 - -1.97500000142846E+00 -1.94499999372593E+00 -1.91500002750383E+00 - -1.88499987965708E+00 -1.85500052558087E+00 -1.82499770865601E+00 - -1.79500996887489E+00 -1.76495666210619E+00 -1.73518720080803E+00 - -1.70417535842507E+00 -1.67835609441927E+00 -1.60565784801097E+00 - -1.17157562055629E+00 -8.21560351878633E-01 -6.47570221057817E-01 - -5.39323223872264E-01 -4.61224003093473E-01 -3.99308541774042E-01 - -3.47051973725967E-01 -3.00987993886565E-01 -2.59101831513096E-01 - -2.20141499462282E-01 -1.83288162162223E-01 -1.47984729132786E-01 - -1.13840566908414E-01 -8.05754656628490E-02 -4.79850420721677E-02 - -1.59184235380158E-02 - 1 -1 6 8 - SCALAIRE - -21 319939 1 0 0 0 -20 0 2 - - - 319927 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000001E+00 -2.21499999999998E+00 -2.18500000000010E+00 - -2.15499999999959E+00 -2.12500000000171E+00 -2.09499999999288E+00 - -2.06500000002950E+00 -2.03499999987831E+00 -2.00500000049984E+00 - -1.97499999795685E+00 -1.94500000830635E+00 -1.91499996643941E+00 - -1.88500013462757E+00 -1.85499946442300E+00 -1.82500210889192E+00 - -1.79499178635361E+00 -1.76503134459040E+00 -1.73487984887641E+00 - -1.70540159991715E+00 -1.67277221562769E+00 -1.40162620326480E+00 - -9.54547416771393E-01 -7.28488147764493E-01 -5.98671486405551E-01 - -5.09923046753073E-01 -4.42000039977959E-01 -3.86043009820908E-01 - -3.37565961890137E-01 -2.94050371875220E-01 -2.53969516234026E-01 - -2.16341488218916E-01 -1.80504722398332E-01 -1.45996856626893E-01 - -1.12485441373164E-01 -7.97263482747270E-02 -4.75377615235899E-02 - -1.57833121775161E-02 - 1 -1 6 8 - SCALAIRE - -21 319063 1 0 0 0 -21 0 2 - - - 319051 - H - REAL*8 - 1 100 0 0 - -4.13500000000000E+00 -4.10500000000000E+00 -4.07500000000000E+00 - -4.04500000000000E+00 -4.01500000000000E+00 -3.98500000000000E+00 - -3.95500000000000E+00 -3.92500000000000E+00 -3.89500000000000E+00 - -3.86500000000000E+00 -3.83500000000000E+00 -3.80500000000000E+00 - -3.77500000000000E+00 -3.74500000000000E+00 -3.71500000000000E+00 - -3.68500000000000E+00 -3.65500000000000E+00 -3.62500000000000E+00 - -3.59500000000000E+00 -3.56500000000000E+00 -3.53500000000000E+00 - -3.50500000000000E+00 -3.47500000000000E+00 -3.44500000000000E+00 - -3.41500000000000E+00 -3.38500000000000E+00 -3.35500000000000E+00 - -3.32500000000000E+00 -3.29500000000000E+00 -3.26500000000000E+00 - -3.23500000000000E+00 -3.20500000000000E+00 -3.17500000000000E+00 - -3.14500000000000E+00 -3.11500000000000E+00 -3.08500000000000E+00 - -3.05500000000000E+00 -3.02500000000000E+00 -2.99500000000000E+00 - -2.96500000000000E+00 -2.93500000000000E+00 -2.90500000000000E+00 - -2.87500000000000E+00 -2.84500000000000E+00 -2.81500000000000E+00 - -2.78500000000000E+00 -2.75500000000000E+00 -2.72500000000000E+00 - -2.69500000000000E+00 -2.66500000000000E+00 -2.63500000000000E+00 - -2.60500000000000E+00 -2.57500000000000E+00 -2.54500000000000E+00 - -2.51500000000000E+00 -2.48500000000000E+00 -2.45500000000000E+00 - -2.42500000000000E+00 -2.39500000000000E+00 -2.36500000000000E+00 - -2.33500000000000E+00 -2.30500000000000E+00 -2.27500000000000E+00 - -2.24500000000000E+00 -2.21499999999998E+00 -2.18500000000012E+00 - -2.15499999999944E+00 -2.12500000000263E+00 -2.09499999998770E+00 - -2.06500000005700E+00 -2.03499999973747E+00 -2.00500000120243E+00 - -1.97499999451969E+00 -1.94500002486672E+00 -1.91499988762354E+00 - -1.88500050595717E+00 -1.85499772973232E+00 -1.82501015222710E+00 - -1.79495469916735E+00 -1.76520080678885E+00 -1.73409664847054E+00 - -1.70879144835943E+00 -1.59788169976893E+00 -1.12953755674489E+00 - -8.22755578976403E-01 -6.64153880913141E-01 -5.62261914282898E-01 - -4.87285649346261E-01 -4.27127201175383E-01 -3.75955278447332E-01 - -3.30608243501925E-01 -2.89221144244088E-01 -2.50621965598243E-01 - -2.14037478711910E-01 -1.78938122892054E-01 -1.44950743646838E-01 - -1.11806745105845E-01 -7.93097828201385E-02 -4.73147601636392E-02 - -1.57136364979199E-02 - 1 -1 6 8 - SCALAIRE - -21 324955 1 0 0 0 -22 0 2 - - - 324967 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 - 1 -1 6 8 - SCALAIRE - -21 325309 1 0 0 0 -23 0 2 - - - 325381 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000002E+00 -1.14999999999990E+00 -1.15000000000046E+00 - -1.14999999999795E+00 -1.15000000000919E+00 -1.14999999995875E+00 - -1.15000000018511E+00 -1.14999999916916E+00 -1.15000000372952E+00 - -1.14999998325759E+00 -1.15000007516150E+00 -1.14999966257587E+00 - -1.15000151469562E+00 -1.14999319973773E+00 -1.15003050279579E+00 - -1.14986272161241E+00 -1.15060872024149E+00 -1.14708143964912E+00 - -9.30397404678052E-01 -4.74145954159549E-01 -2.16540006497621E-01 - -6.40437383301153E-02 - 1 -1 6 8 - SCALAIRE - -21 326617 1 0 0 0 -24 0 2 - - - 324799 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000001E+00 -1.14999999999998E+00 -1.15000000000011E+00 - -1.14999999999951E+00 -1.15000000000216E+00 -1.14999999999041E+00 - -1.15000000004245E+00 -1.14999999981198E+00 -1.15000000083258E+00 - -1.14999999631362E+00 -1.15000001632013E+00 -1.14999992775752E+00 - -1.15000031974302E+00 -1.14999858497049E+00 -1.15000626037860E+00 - -1.14997228758946E+00 -1.15012229123405E+00 -1.14945324999156E+00 - -1.15232398415236E+00 -1.13499905693040E+00 -8.04039023392856E-01 - -3.99006393092861E-01 -1.93247218769097E-01 -8.41397770009844E-02 - -2.25078673593807E-02 - 1 -1 6 8 - SCALAIRE - -21 324595 1 0 0 0 -25 0 2 - - - 324511 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000001E+00 - -1.14999999999997E+00 -1.15000000000015E+00 -1.14999999999937E+00 - -1.15000000000275E+00 -1.14999999998803E+00 -1.15000000005201E+00 - -1.14999999977409E+00 -1.15000000098080E+00 -1.14999999574411E+00 - -1.15000001845649E+00 -1.14999992000793E+00 -1.15000034647027E+00 - -1.14999850024683E+00 -1.15000648601938E+00 -1.14997194543986E+00 - -1.15012078743789E+00 -1.14947123268857E+00 -1.15216622941086E+00 - -1.13499410273643E+00 -7.95394822100051E-01 -4.00159666296827E-01 - -2.07168724171530E-01 -1.06111056228492E-01 -4.85976677678687E-02 - -1.35937362206647E-02 - 1 -1 6 8 - SCALAIRE - -21 324373 1 0 0 0 -26 0 2 - - - 324319 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000001E+00 -1.14999999999997E+00 - -1.15000000000012E+00 -1.14999999999949E+00 -1.15000000000217E+00 - -1.14999999999068E+00 -1.15000000003996E+00 -1.14999999982878E+00 - -1.15000000073316E+00 -1.14999999686222E+00 -1.15000001342196E+00 - -1.14999994261664E+00 -1.15000024520669E+00 -1.14999895267042E+00 - -1.15000447046912E+00 -1.14998091221237E+00 -1.15008121144364E+00 - -1.14964997086609E+00 -1.15143115235774E+00 -1.14194776513999E+00 - -8.45025125363738E-01 -4.30905323840183E-01 -2.32098547585758E-01 - -1.29350727394083E-01 -7.02671471170892E-02 -3.37455570371690E-02 - -9.72315044931582E-03 - 1 -1 6 8 - SCALAIRE - -21 324109 1 0 0 0 -27 0 2 - - - 324031 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.14999999999999E+00 -1.15000000000005E+00 - -1.14999999999978E+00 -1.15000000000092E+00 -1.14999999999615E+00 - -1.15000000001605E+00 -1.14999999993324E+00 -1.15000000027714E+00 - -1.14999999885212E+00 -1.15000000474282E+00 -1.14999998045600E+00 - -1.15000008029727E+00 -1.14999967117228E+00 -1.15000134148075E+00 - -1.14999454751231E+00 -1.15002201148601E+00 -1.14991087912687E+00 - -1.15034594794479E+00 -1.14843758225318E+00 -9.31257334949404E-01 - -4.86591577109316E-01 -2.64917049285670E-01 -1.53797648041618E-01 - -9.03551366564161E-02 -5.10892200821322E-02 -2.52459832108218E-02 - -7.39565082790055E-03 - 1 -1 6 8 - SCALAIRE - -21 323797 1 0 0 0 -28 0 2 - - - 323773 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.14999999999999E+00 -1.15000000000006E+00 - -1.14999999999971E+00 -1.15000000000136E+00 -1.14999999999357E+00 - -1.15000000003023E+00 -1.14999999985890E+00 -1.15000000065495E+00 - -1.14999999697457E+00 -1.15000001391583E+00 -1.14999993623505E+00 - -1.15000029118890E+00 -1.14999867429844E+00 -1.15000601799045E+00 - -1.14997273589662E+00 -1.15012292571263E+00 -1.14944078115727E+00 - -1.15242834219045E+00 -1.02763638756659E+00 -5.67940566609100E-01 - -3.06859648381398E-01 -1.81256800501063E-01 -1.10860445229599E-01 - -6.76129559558960E-02 -3.92694891499696E-02 -1.97690425436327E-02 - -5.85412290811059E-03 - 1 -1 6 8 - SCALAIRE - -21 323551 1 0 0 0 -29 0 2 - - - 323539 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000001E+00 - -1.14999999999995E+00 -1.15000000000020E+00 -1.14999999999911E+00 - -1.15000000000389E+00 -1.14999999998293E+00 -1.15000000007480E+00 - -1.14999999967238E+00 -1.15000000143404E+00 -1.14999999372727E+00 - -1.15000002741979E+00 -1.14999988021859E+00 -1.15000052291084E+00 - -1.14999771852574E+00 -1.15000994501613E+00 -1.14995662642460E+00 - -1.15018809456395E+00 -1.14916546120541E+00 -1.15340898382644E+00 - -1.10346040120499E+00 -6.80682918089455E-01 -3.60643458507160E-01 - -2.13184793116873E-01 -1.32961427219939E-01 -8.43959184707471E-02 - -5.28388160049688E-02 -3.12606772066239E-02 -1.59409962757219E-02 - -4.75644138365122E-03 - 1 -1 6 8 - SCALAIRE - -21 323371 1 0 0 0 -30 0 2 - - - 323359 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000001E+00 -1.14999999999996E+00 - -1.15000000000015E+00 -1.14999999999935E+00 -1.15000000000279E+00 - -1.14999999998811E+00 -1.15000000005060E+00 -1.14999999978494E+00 - -1.15000000091293E+00 -1.14999999612968E+00 -1.15000001638543E+00 - -1.14999993073060E+00 -1.15000029238419E+00 -1.14999876778899E+00 - -1.15000518273646E+00 -1.14997821846118E+00 -1.15009096148427E+00 - -1.14961371682233E+00 -1.15151945793081E+00 -1.14050522404072E+00 - -8.26415561949390E-01 -4.30617467062108E-01 -2.50817800828769E-01 - -1.57493664636066E-01 -1.02231526111713E-01 -6.67350432366463E-02 - -4.26312674227759E-02 -2.55926126688644E-02 -1.31888625377558E-02 - -3.96038604968927E-03 - 1 -1 6 8 - SCALAIRE - -21 323185 1 0 0 0 -31 0 2 - - - 323173 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.14999999999999E+00 -1.15000000000002E+00 - -1.14999999999991E+00 -1.15000000000034E+00 -1.14999999999878E+00 - -1.15000000000425E+00 -1.14999999998610E+00 -1.15000000004098E+00 - -1.14999999990457E+00 -1.15000000006362E+00 -1.15000000121241E+00 - -1.14999998842712E+00 -1.15000007693173E+00 -1.14999955319541E+00 - -1.15000241369967E+00 -1.14998749940464E+00 -1.15006229202357E+00 - -1.14968781009987E+00 -1.15140124164690E+00 -9.83285399046954E-01 - -5.30787359698162E-01 -2.97564260334102E-01 -1.84496520865302E-01 - -1.20342837430113E-01 -8.01552310619662E-02 -5.33063542195572E-02 - -3.45377273330808E-02 -2.09717936652750E-02 -1.09119860531204E-02 - -3.29866869138428E-03 - 1 -1 6 8 - SCALAIRE - -21 323023 1 0 0 0 -32 0 2 - - - 323011 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000001E+00 -1.14999999999996E+00 -1.15000000000019E+00 - -1.14999999999915E+00 -1.15000000000375E+00 -1.14999999998343E+00 - -1.15000000007314E+00 -1.14999999967763E+00 -1.15000000141909E+00 - -1.14999999376094E+00 -1.15000002739826E+00 -1.14999987981461E+00 - -1.15000052665675E+00 -1.14999769428415E+00 -1.15001008296745E+00 - -1.14995590195655E+00 -1.15019189020477E+00 -1.14914889879884E+00 - -1.15351191983636E+00 -1.09441898963168E+00 -6.66842080685448E-01 - -3.58863584011360E-01 -2.18139086315934E-01 -1.41808693317095E-01 - -9.53381029029966E-02 -6.48410172548005E-02 -4.37750928574093E-02 - -2.86788164188325E-02 -1.75593652683945E-02 -9.19290101181534E-03 - -2.78951890259027E-03 - 1 -1 6 8 - SCALAIRE - -21 322333 1 0 0 0 -33 0 2 - - - 322315 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000001E+00 - -1.14999999999997E+00 -1.15000000000014E+00 -1.14999999999939E+00 - -1.15000000000260E+00 -1.14999999998894E+00 -1.15000000004693E+00 - -1.14999999980106E+00 -1.15000000084225E+00 -1.14999999643920E+00 - -1.15000001503169E+00 -1.14999993664479E+00 -1.15000026657349E+00 - -1.14999888033726E+00 -1.15000469239171E+00 -1.14998035522495E+00 - -1.15008167585997E+00 -1.14965446764326E+00 -1.15134713449563E+00 - -1.14135524464944E+00 -8.38270772945895E-01 -4.40733803743065E-01 - -2.60114236348006E-01 -1.67306189906336E-01 -1.12656876351951E-01 - -7.75253923372858E-02 -5.35915529885089E-02 -3.66082409579170E-02 - -2.41927361441432E-02 -1.49091049467644E-02 -7.84294096039159E-03 - -2.38685968373603E-03 - 1 -1 6 8 - SCALAIRE - -21 322063 1 0 0 0 -34 0 2 - - - 322051 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000001E+00 -1.14999999999996E+00 -1.15000000000010E+00 - -1.14999999999980E+00 -1.14999999999978E+00 -1.15000000000559E+00 - -1.14999999995589E+00 -1.15000000027617E+00 -1.14999999843995E+00 - -1.15000000831078E+00 -1.14999995737749E+00 -1.15000021282329E+00 - -1.14999895816906E+00 -1.15000502071806E+00 -1.14997607675388E+00 - -1.15011240661199E+00 -1.14946815158854E+00 -1.15235921190085E+00 - -1.00688676739605E+00 -5.54048026462153E-01 -3.13308879412534E-01 - -1.97855922317559E-01 -1.32568689490143E-01 -9.16244319997735E-02 - -6.41815076668359E-02 -4.49298823577743E-02 -3.09758298027547E-02 - -2.06123089316590E-02 -1.27692139374180E-02 -6.74365940030929E-03 - -2.05729409418735E-03 - 1 -1 6 8 - SCALAIRE - -21 321805 1 0 0 0 -35 0 2 - - - 321793 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000001E+00 -1.14999999999996E+00 - -1.15000000000020E+00 -1.14999999999913E+00 -1.15000000000383E+00 - -1.14999999998318E+00 -1.15000000007378E+00 -1.14999999967679E+00 - -1.15000000141394E+00 -1.14999999382253E+00 -1.15000002695510E+00 - -1.14999988252698E+00 -1.15000051133873E+00 -1.14999777671329E+00 - -1.15000965323825E+00 -1.14995808942615E+00 -1.15018091197089E+00 - -1.14920280894521E+00 -1.15324697663436E+00 -1.11260787601159E+00 - -7.10437363068010E-01 -3.82909893086666E-01 -2.35321650130748E-01 - -1.55882626060270E-01 -1.07575415113305E-01 -7.58227570362588E-02 - -5.38433648454849E-02 -3.80662136598705E-02 -2.64362708372711E-02 - -1.76887851915472E-02 -1.10041424118691E-02 -5.82979435469586E-03 - -1.78194744088324E-03 - 1 -1 6 8 - SCALAIRE - -21 321655 1 0 0 0 -36 0 2 - - - 321643 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000001E+00 -1.14999999999998E+00 -1.15000000000010E+00 - -1.14999999999957E+00 -1.15000000000177E+00 -1.14999999999262E+00 - -1.15000000003061E+00 -1.14999999987343E+00 -1.15000000052155E+00 - -1.14999999785939E+00 -1.15000000874691E+00 -1.14999996443679E+00 - -1.15000014376692E+00 -1.14999942260984E+00 -1.15000230040975E+00 - -1.14999090918539E+00 -1.15003535574102E+00 -1.14986149739304E+00 - -1.15048413637776E+00 -1.14736356215296E+00 -8.99467334965939E-01 - -4.78144609758120E-01 -2.82442837703037E-01 -1.83709850686808E-01 - -1.25947669247034E-01 -8.88615160194366E-02 -6.35890561852581E-02 - -4.56478188751788E-02 -3.25312588159042E-02 -2.27293987772218E-02 - -1.52792695565113E-02 -9.53926579229748E-03 -5.06740412419820E-03 - -1.55149293783622E-03 - 1 -1 6 8 - SCALAIRE - -21 321325 1 0 0 0 -37 0 2 - - - 321307 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.14999999999998E+00 -1.15000000000010E+00 - -1.14999999999951E+00 -1.15000000000233E+00 -1.14999999998904E+00 - -1.15000000005111E+00 -1.14999999976330E+00 -1.15000000108945E+00 - -1.14999999501315E+00 -1.15000002271558E+00 -1.14999989698235E+00 - -1.15000046532613E+00 -1.14999790577032E+00 -1.15000939152630E+00 - -1.14995798442831E+00 -1.15018676578197E+00 -1.14915923729329E+00 - -1.15355271999449E+00 -1.05949212288334E+00 -6.13129474211469E-01 - -3.43323423488807E-01 -2.17561993419072E-01 -1.47394581843326E-01 - -1.03629896223960E-01 -7.43588669427536E-02 -5.38457707225434E-02 - -3.89895722976527E-02 -2.79676615199501E-02 -1.96389858011214E-02 - -1.32536610116376E-02 -8.30019831398295E-03 -4.41975400584346E-03 - -1.35524456315610E-03 - 1 -1 6 8 - SCALAIRE - -21 320395 1 0 0 0 -38 0 2 - - - 320383 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000001E+00 - -1.14999999999996E+00 -1.15000000000017E+00 -1.14999999999925E+00 - -1.15000000000325E+00 -1.14999999998600E+00 -1.15000000006021E+00 - -1.14999999974149E+00 -1.15000000110828E+00 -1.14999999525586E+00 - -1.15000002027688E+00 -1.14999991346874E+00 -1.15000036868679E+00 - -1.14999843153118E+00 -1.15000666007237E+00 -1.14997173675939E+00 - -1.15011918852121E+00 -1.14948762713892E+00 -1.15203246136924E+00 - -1.13489684822653E+00 -7.95685378722091E-01 -4.25293436586229E-01 - -2.59936848362107E-01 -1.72968908719407E-01 -1.20677384763109E-01 - -8.64832401557986E-02 -6.28799905703766E-02 -4.59685747877699E-02 - -3.35220775266305E-02 -2.41759217163720E-02 -1.70477107886816E-02 - -1.15427250669061E-02 -7.24725590324395E-03 -3.86658567110400E-03 - -1.18704247300186E-03 - 1 -1 6 8 - SCALAIRE - -21 320245 1 0 0 0 -39 0 2 - - - 320233 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.14999999999999E+00 - -1.15000000000003E+00 -1.14999999999987E+00 -1.15000000000049E+00 - -1.14999999999818E+00 -1.15000000000650E+00 -1.14999999997787E+00 - -1.15000000006975E+00 -1.14999999981103E+00 -1.15000000032912E+00 - -1.15000000068871E+00 -1.14999998789205E+00 -1.15000009177635E+00 - -1.14999943295436E+00 -1.15000318344073E+00 -1.14998304877008E+00 - -1.15008638477966E+00 -1.14955847860536E+00 -1.15202131434164E+00 - -9.88079014600367E-01 -5.41343132097054E-01 -3.14332083383740E-01 - -2.03992719586475E-01 -1.40614485535019E-01 -1.00290953068750E-01 - -7.29512134106926E-02 -5.36051244488369E-02 -3.94954594598532E-02 - -2.89735928112576E-02 -2.09930359371299E-02 -1.48582473175757E-02 - -1.00903141297685E-02 -6.35052362771876E-03 -3.39449654285649E-03 - -1.04333561943075E-03 - 1 -1 6 8 - SCALAIRE - -21 320065 1 0 0 0 -40 0 2 - - - 320053 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000001E+00 -1.14999999999996E+00 - -1.15000000000019E+00 -1.14999999999915E+00 -1.15000000000376E+00 - -1.14999999998335E+00 -1.15000000007360E+00 -1.14999999967542E+00 - -1.15000000142846E+00 -1.14999999372593E+00 -1.15000002750383E+00 - -1.14999987965708E+00 -1.15000052558087E+00 -1.14999770865601E+00 - -1.15000996887489E+00 -1.14995666210619E+00 -1.15018720080803E+00 - -1.14917535842507E+00 -1.15335609441927E+00 -1.11065784801097E+00 - -7.06575620556291E-01 -3.86560351878633E-01 -2.42570221057817E-01 - -1.64323223872264E-01 -1.16224003093473E-01 -8.43085417740423E-02 - -6.20519737259673E-02 -4.59879938865652E-02 -3.41018315130958E-02 - -2.51414994622821E-02 -1.82881621622230E-02 -1.29847291327866E-02 - -8.84056690841387E-03 -5.57546566284878E-03 -2.98504207216772E-03 - -9.18423538016081E-04 - 1 -1 6 8 - SCALAIRE - -21 319867 1 0 0 0 -41 0 2 - - - 319177 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000001E+00 -1.14999999999998E+00 -1.15000000000010E+00 - -1.14999999999959E+00 -1.15000000000171E+00 -1.14999999999288E+00 - -1.15000000002950E+00 -1.14999999987831E+00 -1.15000000049984E+00 - -1.14999999795685E+00 -1.15000000830635E+00 -1.14999996643941E+00 - -1.15000013462757E+00 -1.14999946442300E+00 -1.15000210889192E+00 - -1.14999178635361E+00 -1.15003134459040E+00 -1.14987984887642E+00 - -1.15040159991715E+00 -1.14777221562769E+00 -9.06626203264796E-01 - -4.89547416771393E-01 -2.93488147764493E-01 -1.93671486405551E-01 - -1.34923046753073E-01 -9.70000399779595E-02 -7.10430098209084E-02 - -5.25659618901367E-02 -3.90503718752204E-02 -2.89695162340258E-02 - -2.13414882189154E-02 -1.55047223983316E-02 -1.09968566268930E-02 - -7.48544137316366E-03 -4.72634827472679E-03 -2.53776152358996E-03 - -7.83312177516423E-04 - 1 -1 6 8 - SCALAIRE - -21 318895 1 0 0 0 -42 0 2 - - - 318805 - SCAL - REAL*8 - 1 100 0 0 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.15000000000000E+00 -1.15000000000000E+00 - -1.15000000000000E+00 -1.14999999999998E+00 -1.15000000000012E+00 - -1.14999999999944E+00 -1.15000000000263E+00 -1.14999999998770E+00 - -1.15000000005700E+00 -1.14999999973747E+00 -1.15000000120243E+00 - -1.14999999451969E+00 -1.15000002486672E+00 -1.14999988762354E+00 - -1.15000050595717E+00 -1.14999772973232E+00 -1.15001015222710E+00 - -1.14995469916735E+00 -1.15020080678885E+00 -1.14909664847054E+00 - -1.15379144835943E+00 -1.07288169976893E+00 -6.34537556744892E-01 - -3.57755578976403E-01 -2.29153880913141E-01 -1.57261914282897E-01 - -1.12285649346261E-01 -8.21272011753830E-02 -6.09552784473316E-02 - -4.56082435019248E-02 -3.42211442440880E-02 -2.56219655982434E-02 - -1.90374787119092E-02 -1.39381228920544E-02 -9.95074364683848E-03 - -6.80674510584511E-03 -4.30978282013827E-03 -2.31476016363927E-03 - -7.13636497920257E-04 - 1 -1 6 8 - SCALAIRE - -21 324991 1 0 0 0 -43 0 2 - - - 325003 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 - 1 -1 6 8 - SCALAIRE - -21 325603 1 0 0 0 -44 0 2 - - - 325723 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243884E-01 - 2.75076403243878E-01 2.75076403243906E-01 2.75076403243779E-01 - 2.75076403244348E-01 2.75076403241795E-01 2.75076403253250E-01 - 2.75076403201845E-01 2.75076403432567E-01 2.75076402396908E-01 - 2.75076407046083E-01 2.75076386174716E-01 2.75076479872885E-01 - 2.75076059257084E-01 2.75077947590852E-01 2.75069476226816E-01 - 2.75107582481038E-01 2.74938228399967E-01 2.75740716552630E-01 - 3.35088285191157E-01 5.78559124771428E-01 8.44554067695688E-01 - 9.83514651550140E-01 - 1 -1 6 8 - SCALAIRE - -21 324757 1 0 0 0 -45 0 2 - - - 324745 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243882E-01 2.75076403243888E-01 2.75076403243858E-01 - 2.75076403243994E-01 2.75076403243391E-01 2.75076403246060E-01 - 2.75076403234241E-01 2.75076403286582E-01 2.75076403054805E-01 - 2.75076404081059E-01 2.75076399537584E-01 2.75076419650144E-01 - 2.75076330630297E-01 2.75076724597280E-01 2.75074981519534E-01 - 2.75082696864921E-01 2.75048633561102E-01 2.75200622959918E-01 - 2.74549579549443E-01 2.78523327342428E-01 3.81798147501242E-01 - 6.45886388339689E-01 8.70752849056533E-01 9.71815912108816E-01 - 9.97984223966455E-01 - 1 -1 6 8 - SCALAIRE - -21 324481 1 0 0 0 -46 0 2 - - - 324469 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243881E-01 - 2.75076403243891E-01 2.75076403243850E-01 2.75076403244027E-01 - 2.75076403243258E-01 2.75076403246600E-01 2.75076403232072E-01 - 2.75076403295187E-01 2.75076403021142E-01 2.75076404210396E-01 - 2.75076399052417E-01 2.75076421410073E-01 2.75076324560545E-01 - 2.75076743838056E-01 2.75074930277047E-01 2.75082774570429E-01 - 2.75048975008449E-01 2.75196535671437E-01 2.74585280759558E-01 - 2.78524479152279E-01 3.85423995339201E-01 6.44776844558968E-01 - 8.55175906606314E-01 9.55953899835618E-01 9.90487419249991E-01 - 9.99274516744765E-01 - 1 -1 6 8 - SCALAIRE - -21 324295 1 0 0 0 -47 0 2 - - - 324277 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243881E-01 2.75076403243889E-01 - 2.75076403243856E-01 2.75076403243998E-01 2.75076403243389E-01 - 2.75076403246000E-01 2.75076403234807E-01 2.75076403282766E-01 - 2.75076403077382E-01 2.75076403956472E-01 2.75076400195756E-01 - 2.75076416275639E-01 2.75076347557482E-01 2.75076641092505E-01 - 2.75075388004380E-01 2.75080738142696E-01 2.75057961299655E-01 - 2.75155916478797E-01 2.74751750291351E-01 2.76916591719028E-01 - 3.65410829911533E-01 6.16074043280492E-01 8.26765266988173E-01 - 9.36182856971901E-01 9.80198909919764E-01 9.95430171969058E-01 - 9.99632404189964E-01 - 1 -1 6 8 - SCALAIRE - -21 323995 1 0 0 0 -48 0 2 - - - 323959 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243882E-01 2.75076403243886E-01 2.75076403243871E-01 - 2.75076403243933E-01 2.75076403243673E-01 2.75076403244757E-01 - 2.75076403240238E-01 2.75076403259044E-01 2.75076403180945E-01 - 2.75076403504566E-01 2.75076402166788E-01 2.75076407682324E-01 - 2.75076385008383E-01 2.75076477920641E-01 2.75076098594074E-01 - 2.75077641508478E-01 2.75071404523509E-01 2.75096643987876E-01 - 2.74997859649614E-01 2.75431660046904E-01 3.34806381021184E-01 - 5.68367466392874E-01 7.89076430871077E-01 9.12704213645399E-01 - 9.67636599287993E-01 9.89486842677331E-01 9.97457078703781E-01 - 9.99789041049580E-01 - 1 -1 6 8 - SCALAIRE - -21 323743 1 0 0 0 -49 0 2 - - - 323677 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243882E-01 2.75076403243886E-01 2.75076403243869E-01 - 2.75076403243948E-01 2.75076403243574E-01 2.75076403245344E-01 - 2.75076403237018E-01 2.75076403275927E-01 2.75076403095143E-01 - 2.75076403930959E-01 2.75076400083600E-01 2.75076417724897E-01 - 2.75076337114932E-01 2.75076704310868E-01 2.75075036565330E-01 - 2.75082595050061E-01 2.75048489498580E-01 2.75203457069334E-01 - 2.74525967266966E-01 3.05771180228018E-01 5.08006685133833E-01 - 7.41722364815973E-01 8.83905415084670E-01 9.52145467738794E-01 - 9.81647655265086E-01 9.93798177210084E-01 9.98449995669623E-01 - 9.99868739454027E-01 - 1 -1 6 8 - SCALAIRE - -21 323497 1 0 0 0 -50 0 2 - - - 323485 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243880E-01 - 2.75076403243893E-01 2.75076403243837E-01 2.75076403244084E-01 - 2.75076403242999E-01 2.75076403247758E-01 2.75076403226896E-01 - 2.75076403318286E-01 2.75076402918213E-01 2.75076404668418E-01 - 2.75076397016853E-01 2.75076430446229E-01 2.75076284490938E-01 - 2.75076921367351E-01 2.75074144749317E-01 2.75086253710453E-01 - 2.75033693241166E-01 2.75266050066841E-01 2.74304272012834E-01 - 2.86041854807574E-01 4.39999467546227E-01 6.84122227688821E-01 - 8.48367183610111E-01 9.32871929985208E-01 9.71648712251219E-01 - 9.88755311025829E-01 9.96083688701043E-01 9.98997913961015E-01 - 9.99913888234155E-01 - 1 -1 6 8 - SCALAIRE - -21 323323 1 0 0 0 -51 0 2 - - - 323299 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243881E-01 2.75076403243891E-01 - 2.75076403243848E-01 2.75076403244031E-01 2.75076403243249E-01 - 2.75076403246583E-01 2.75076403232392E-01 2.75076403292723E-01 - 2.75076403036556E-01 2.75076404122832E-01 2.75076399522752E-01 - 2.75076418974956E-01 2.75076336843481E-01 2.75076683079132E-01 - 2.75075226249762E-01 2.75081349912743E-01 2.75055747363164E-01 - 2.75164154487523E-01 2.74731742077390E-01 2.77248709718158E-01 - 3.72691065982872E-01 6.16334916531130E-01 8.05254012427773E-01 - 9.08958218909807E-01 9.58969219685787E-01 9.82115560135372E-01 - 9.92684804027684E-01 9.97385963671390E-01 9.99317672207359E-01 - 9.99940629277427E-01 - 1 -1 6 8 - SCALAIRE - -21 323149 1 0 0 0 -52 0 2 - - - 323137 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243884E-01 2.75076403243877E-01 - 2.75076403243904E-01 2.75076403243806E-01 2.75076403244161E-01 - 2.75076403242918E-01 2.75076403247040E-01 2.75076403234576E-01 - 2.75076403265555E-01 2.75076403229435E-01 2.75076402968544E-01 - 2.75076405872082E-01 2.75076385772696E-01 2.75076504713190E-01 - 2.75075855093989E-01 2.75079242155298E-01 2.75062257418054E-01 - 2.75147318763092E-01 2.74758528061837E-01 3.18528679762045E-01 - 5.34271958706114E-01 7.52074179273654E-01 8.80380047313657E-01 - 9.44175445405613E-01 9.74359982893834E-01 9.88555807346621E-01 - 9.95211289778203E-01 9.98253030755661E-01 9.99535458491857E-01 - 9.99959038784235E-01 - 1 -1 6 8 - SCALAIRE - -21 322951 1 0 0 0 -53 0 2 - - - 322939 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243881E-01 2.75076403243892E-01 2.75076403243839E-01 - 2.75076403244075E-01 2.75076403243032E-01 2.75076403247646E-01 - 2.75076403227273E-01 2.75076403317094E-01 2.75076402921608E-01 - 2.75076404660773E-01 2.75076397021741E-01 2.75076430537973E-01 - 2.75076283640243E-01 2.75076926872633E-01 2.75074113421077E-01 - 2.75086418248265E-01 2.75032831506396E-01 2.75269816325956E-01 - 2.74281020677927E-01 2.88268002535811E-01 4.47498099617187E-01 - 6.85957263065727E-01 8.42733266340498E-01 9.24518929653974E-01 - 9.64106210414430E-01 9.83105754143116E-01 9.92285401972344E-01 - 9.96709437690328E-01 9.98780931315179E-01 9.99671944858330E-01 - 9.99970856059199E-01 - 1 -1 6 8 - SCALAIRE - -21 322261 1 0 0 0 -54 0 2 - - - 322201 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243881E-01 - 2.75076403243891E-01 2.75076403243850E-01 2.75076403244022E-01 - 2.75076403243292E-01 2.75076403246393E-01 2.75076403233226E-01 - 2.75076403289062E-01 2.75076403052608E-01 2.75076404052540E-01 - 2.75076399830189E-01 2.75076417631844E-01 2.75076342705086E-01 - 2.75076657519386E-01 2.75075337606145E-01 2.75080864638288E-01 - 2.75057855844128E-01 2.75154894708238E-01 2.74770789549403E-01 - 2.77052917690813E-01 3.68023253039494E-01 6.07255829957364E-01 - 7.94579662623554E-01 8.98802294939202E-01 9.50672320596031E-01 - 9.75979733567630E-01 9.88433279849384E-01 9.94615186713931E-01 - 9.97667124480411E-01 9.99125064985235E-01 9.99762337260503E-01 - 9.99978763136121E-01 - 1 -1 6 8 - SCALAIRE - -21 322027 1 0 0 0 -55 0 2 - - - 322015 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243884E-01 - 2.75076403243880E-01 2.75076403243891E-01 2.75076403243859E-01 - 2.75076403243928E-01 2.75076403243933E-01 2.75076403242613E-01 - 2.75076403253900E-01 2.75076403181165E-01 2.75076403598169E-01 - 2.75076401356505E-01 2.75076412923451E-01 2.75076354911745E-01 - 2.75076639843763E-01 2.75075263043832E-01 2.75081836311531E-01 - 2.75050877947728E-01 2.75197235966756E-01 2.74541608412357E-01 - 3.11619295542107E-01 5.17582681532861E-01 7.34600300746943E-01 - 8.65627865400592E-01 9.33234910320546E-01 9.66752249413485E-01 - 9.83444330892054E-01 9.91871618014800E-01 9.96155393041772E-01 - 9.98313144143876E-01 9.99360989853670E-01 9.99825079299029E-01 - 9.99984293797073E-01 - 1 -1 6 8 - SCALAIRE - -21 321769 1 0 0 0 -56 0 2 - - - 321757 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243881E-01 2.75076403243893E-01 - 2.75076403243838E-01 2.75076403244080E-01 2.75076403243013E-01 - 2.75076403247703E-01 2.75076403227127E-01 2.75076403317284E-01 - 2.75076402922777E-01 2.75076404646786E-01 2.75076397122384E-01 - 2.75076429921994E-01 2.75076287118960E-01 2.75076908152918E-01 - 2.75074211011031E-01 2.75085921440915E-01 2.75035323938940E-01 - 2.75257557619757E-01 2.74340873960896E-01 2.83822219078321E-01 - 4.24593815142912E-01 6.61618294691164E-01 8.23065282704934E-01 - 9.10596678590429E-01 9.54793200102124E-01 9.77002838064811E-01 - 9.88324573827211E-01 9.94174651925386E-01 9.97208765652739E-01 - 9.98762652430626E-01 9.99527463675546E-01 9.99869844436761E-01 - 9.99988267953268E-01 - 1 -1 6 8 - SCALAIRE - -21 321619 1 0 0 0 -57 0 2 - - - 321589 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243881E-01 2.75076403243888E-01 2.75076403243860E-01 - 2.75076403243979E-01 2.75076403243480E-01 2.75076403245558E-01 - 2.75076403236932E-01 2.75076403272627E-01 2.75076403125439E-01 - 2.75076403730014E-01 2.75076401257460E-01 2.75076411320285E-01 - 2.75076370594436E-01 2.75076534369181E-01 2.75075880822022E-01 - 2.75078467781463E-01 2.75068374179981E-01 2.75107860560792E-01 - 2.74966497334450E-01 2.75676368750234E-01 3.45525648600928E-01 - 5.75255619914131E-01 7.69105886950918E-01 8.81238135868439E-01 - 9.39248300942959E-01 9.68663976127688E-01 9.83745732173656E-01 - 9.91609035405005E-01 9.95755801640328E-01 9.97943859954538E-01 - 9.99080455341518E-01 9.99646374660908E-01 9.99902074057537E-01 - 9.99991143603448E-01 - 1 -1 6 8 - SCALAIRE - -21 321277 1 0 0 0 -58 0 2 - - - 321031 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243882E-01 2.75076403243888E-01 2.75076403243860E-01 - 2.75076403243994E-01 2.75076403243354E-01 2.75076403246371E-01 - 2.75076403232276E-01 2.75076403297638E-01 2.75076402996470E-01 - 2.75076404376395E-01 2.75076398085178E-01 2.75076426639182E-01 - 2.75076297568409E-01 2.75076878843983E-01 2.75074270444905E-01 - 2.75085945287469E-01 2.75033994919394E-01 2.75267465360987E-01 - 2.74271805707605E-01 2.97181172385417E-01 4.78768164364373E-01 - 7.02197815355443E-01 8.43390621444724E-01 9.19081051771557E-01 - 9.57892452985096E-01 9.77866244245520E-01 9.88323532860446E-01 - 9.93886795585721E-01 9.96872236776175E-01 9.98470583008462E-01 - 9.99310855330837E-01 9.99733369648950E-01 9.99925812145758E-01 - 9.99993270098462E-01 - 1 -1 6 8 - SCALAIRE - -21 320359 1 0 0 0 -59 0 2 - - - 320347 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243881E-01 - 2.75076403243892E-01 2.75076403243843E-01 2.75076403244054E-01 - 2.75076403243145E-01 2.75076403247063E-01 2.75076403230209E-01 - 2.75076403302591E-01 2.75076402992193E-01 2.75076404321277E-01 - 2.75076398639007E-01 2.75076422895124E-01 2.75076319515179E-01 - 2.75076759443410E-01 2.75074890750035E-01 2.75082821963817E-01 - 2.75049338054446E-01 2.75192809475366E-01 2.74615560438652E-01 - 2.78547091851997E-01 3.85301119135236E-01 6.21186648249266E-01 - 7.94783100461535E-01 8.92814917870383E-01 9.43885719287350E-01 - 9.70269922021216E-01 9.84103028781021E-01 9.91490401464924E-01 - 9.95491000100106E-01 9.97670404002984E-01 9.98851851465030E-01 - 9.99479357861243E-01 9.99797544195274E-01 9.99943449308032E-01 - 9.99994857700813E-01 - 1 -1 6 8 - SCALAIRE - -21 320191 1 0 0 0 -60 0 2 - - - 320179 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243882E-01 2.75076403243885E-01 - 2.75076403243875E-01 2.75076403243913E-01 2.75076403243771E-01 - 2.75076403244297E-01 2.75076403242406E-01 2.75076403248910E-01 - 2.75076403228043E-01 2.75076403286797E-01 2.75076403169140E-01 - 2.75076403087476E-01 2.75076405993597E-01 2.75076382401485E-01 - 2.75076532019941E-01 2.75075680286642E-01 2.75080252917071E-01 - 2.75056786588840E-01 2.75176707165086E-01 2.74618083959426E-01 - 3.17102445319390E-01 5.26594655048742E-01 7.33475146296911E-01 - 8.58753498126137E-01 9.25665515370157E-01 9.60444341881162E-01 - 9.78682208281852E-01 9.88427433595326E-01 9.93726178404508E-01 - 9.96640745510548E-01 9.98249445428024E-01 9.99131106382427E-01 - 9.99603688428033E-01 9.99845157931926E-01 9.99956586712335E-01 - 9.99996042964252E-01 - 1 -1 6 8 - SCALAIRE - -21 320023 1 0 0 0 -61 0 2 - - - 320011 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243881E-01 2.75076403243893E-01 - 2.75076403243840E-01 2.75076403244075E-01 2.75076403243029E-01 - 2.75076403247665E-01 2.75076403227168E-01 2.75076403317595E-01 - 2.75076402919480E-01 2.75076404668724E-01 2.75076396997765E-01 - 2.75076430573749E-01 2.75076283884574E-01 2.75076923608774E-01 - 2.75074139331080E-01 2.75086245606620E-01 2.75033896153769E-01 - 2.75263799504664E-01 2.74316220194198E-01 2.84292674912493E-01 - 4.26540022790520E-01 6.58010510863171E-01 8.14735482565288E-01 - 9.01920389609861E-01 9.47695560123662E-01 9.71705797830911E-01 - 9.84515519404856E-01 9.91483193046957E-01 9.95332360678094E-01 - 9.97478321699428E-01 9.98676207458368E-01 9.99338923161316E-01 - 9.99696958512170E-01 9.99881112303148E-01 9.99966558773075E-01 - 9.99996945607005E-01 - 1 -1 6 8 - SCALAIRE - -21 319147 1 0 0 0 -62 0 2 - - - 319135 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243882E-01 2.75076403243888E-01 2.75076403243861E-01 - 2.75076403243976E-01 2.75076403243494E-01 2.75076403245501E-01 - 2.75076403237183E-01 2.75076403271519E-01 2.75076403130370E-01 - 2.75076403707882E-01 2.75076401357512E-01 2.75076410865489E-01 - 2.75076372669981E-01 2.75076524873409E-01 2.75075924315552E-01 - 2.75078268573976E-01 2.75069285064556E-01 2.75103692102007E-01 - 2.74985228442121E-01 2.75583211354218E-01 3.43057286145631E-01 - 5.65985865759580E-01 7.56643364380001E-01 8.70282521264471E-01 - 9.31048736801026E-01 9.62894182038538E-01 9.79765795602946E-01 - 9.88870958864737E-01 9.93867600695666E-01 9.96641700320888E-01 - 9.98190104312052E-01 9.99052735814466E-01 9.99528098252560E-01 - 9.99783809832887E-01 9.99914990677645E-01 9.99975948300227E-01 - 9.99997788900343E-01 - 1 -1 6 8 - SCALAIRE - -21 318721 1 0 0 0 -63 0 2 - - - 318673 - SCAL - REAL*8 - 1 100 0 0 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243883E-01 2.75076403243883E-01 2.75076403243883E-01 - 2.75076403243882E-01 2.75076403243888E-01 2.75076403243856E-01 - 2.75076403244010E-01 2.75076403243284E-01 2.75076403246676E-01 - 2.75076403230938E-01 2.75076403303503E-01 2.75076402970810E-01 - 2.75076404488461E-01 2.75076397596653E-01 2.75076428764566E-01 - 2.75076288341111E-01 2.75076918822328E-01 2.75074097692465E-01 - 2.75086691420561E-01 2.75030807169828E-01 2.75281698585845E-01 - 2.74217899115999E-01 2.93703945394787E-01 4.65875386319161E-01 - 6.87102250960072E-01 8.30142339263955E-01 9.09194441577445E-01 - 9.50978184442015E-01 9.73114334153185E-01 9.85053957900761E-01 - 9.91623616241485E-01 9.95299374491461E-01 9.97379896381979E-01 - 9.98563993772111E-01 9.99236754546396E-01 9.99614733108286E-01 - 9.99821741720774E-01 9.99929511687589E-01 9.99980045333358E-01 - 9.99998169949833E-01 - 1 -1 6 8 - SCALAIRE - -22 325111 1 0 0 0 -64 0 2 - - - 325147 - FLUX - REAL*8 - 1 301 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 1 -1 6 8 - SCALAIRE - -22 326071 1 0 0 0 -65 0 2 - - - 326209 - FLUX - REAL*8 - 1 301 0 0 - 1.07234596012123E-25 -3.67241024039310E-09 1.06830699228650E-25 - 3.67241024039376E-09 -3.08981039356966E-25 -3.67241024039319E-09 - -4.90330695136414E-25 1.95687991592745E-25 -3.67241024039276E-09 - 2.25576353569759E-25 7.83559759937927E-26 -3.67241024039276E-09 - 1.31064506237040E-25 -5.14968398928277E-26 -3.67241024039320E-09 - -3.27964188180204E-25 -7.29033694169050E-26 -3.67241024039320E-09 - -1.47422325967703E-26 1.08850183146016E-25 -3.67241024039287E-09 - 6.66429692730711E-27 -7.89618211690024E-26 -3.67241024039332E-09 - -3.05547916697444E-25 2.50214057361621E-25 -3.67241024039331E-09 - -3.42504472385238E-25 2.14671140415984E-25 -3.67241024039266E-09 - 3.72594782753988E-25 3.64920743867998E-25 -3.67241024039329E-09 - 6.11095833394888E-25 1.42575564566025E-25 -3.67241024039342E-09 - -1.42575564566025E-25 -4.48325429655205E-26 -3.67241024039285E-09 - -5.35163238101934E-26 -2.73640070803065E-25 -3.67241024039277E-09 - 1.79936017037292E-25 -2.01140598169633E-25 -3.67241024039332E-09 - -1.93668507675379E-25 1.50047655060278E-25 -3.67241024039335E-09 - -6.28059498300761E-26 3.95818847803695E-26 -3.67241024039290E-09 - -2.28403631054071E-25 6.70468660565442E-26 -3.67241024039288E-09 - -3.60679827641530E-25 -3.23723271953736E-25 -3.67241024039336E-09 - -4.49335171613888E-25 1.58327539121478E-25 -3.67241024039338E-09 - 6.03825691292371E-26 -2.30827011754910E-25 -3.67241024039330E-09 - -7.60537643279957E-25 2.62532909257553E-27 -3.67241024039267E-09 - -2.62532909257553E-27 -6.32098466135492E-26 -3.67241024039364E-09 - -2.30625063363173E-25 2.96864135852771E-26 -3.67241024039305E-09 - -2.96864135852771E-26 1.13494996155957E-25 -3.67241024039328E-09 - -1.13494996155957E-25 -2.98277774594927E-25 -3.67241024039359E-09 - 1.79734068645555E-25 1.83167191305077E-25 -3.67241024039301E-09 - 5.23854128164686E-25 -1.88417849490228E-25 -3.67241024039304E-09 - 2.38904947424373E-25 1.34497628896562E-25 -3.67241024039350E-09 - 1.58933384296688E-25 7.95676663442121E-26 -3.67241024039301E-09 - 2.13661398457301E-25 -7.47209049425342E-26 -3.67241024039329E-09 - 7.47209049425342E-26 1.39344390298240E-26 -3.67241024039291E-09 - -3.45533698261287E-25 -2.63138754432762E-25 -3.67241024039352E-09 - -1.59943126255371E-25 -5.13554760186120E-25 -3.67241024039318E-09 - -4.98004734022404E-25 5.04870979341448E-26 -3.67241024039333E-09 - 1.10465770279909E-25 6.60371240978613E-26 -3.67241024039257E-09 - 2.01948391736579E-25 9.89547119509237E-26 -3.67241024039312E-09 - -7.67403888599000E-26 -2.06189307963047E-25 -3.67241024039342E-09 - -2.43751708826051E-25 -2.71216690102226E-25 -3.67241024039295E-09 - -1.77108739552980E-25 6.82585564069637E-26 -3.67241024039308E-09 - -6.82585564069637E-26 6.84605047987003E-26 -3.67241024039339E-09 - 7.35092145921148E-26 -5.55358077275592E-26 -3.67241024039344E-09 - -9.47137957244556E-26 1.11273563846855E-25 -3.67241024039318E-09 - 1.82359397738131E-25 -1.22582673784103E-25 -3.67241024039329E-09 - -1.70848339409146E-25 -1.31266454628776E-27 -3.67241024039349E-09 - 3.83701944299500E-27 6.01806207375005E-26 -3.67241024039345E-09 - -6.01806207375005E-26 8.69387826425973E-26 -3.67241024039303E-09 - 5.54348335316909E-26 -1.60548971430580E-26 -3.67241024039354E-09 - 1.56913900379322E-25 1.30458661061830E-25 -3.67241024039286E-09 - -1.45200893658600E-25 -2.70610844927016E-26 -3.67241024039375E-09 - 2.69601102968333E-26 3.17260923418166E-25 -3.67241024039307E-09 - 4.27221822718733E-25 2.02352288520052E-25 -3.67241024039317E-09 - 4.08945493266573E-25 9.61274344666116E-26 -3.67241024039324E-09 - -9.61274344666116E-26 2.44357554001261E-26 -3.67241024039336E-09 - 1.07133621816255E-25 1.43484332328839E-25 -3.67241024039331E-09 - 1.99928907819213E-26 -7.38121371797196E-26 -3.67241024039303E-09 - -5.46270399647446E-26 1.37223932185005E-25 -3.67241024039319E-09 - 1.56510003595849E-25 -4.01877299555792E-26 -3.67241024039309E-09 - 1.65698655419863E-25 2.65562135133601E-26 -3.67241024039328E-09 - -2.64552393174919E-26 2.32240650497066E-26 -3.67241024039348E-09 - -2.32240650497066E-26 3.23117426778526E-26 -3.67241024039283E-09 - 8.83524213847533E-26 -6.40176401804956E-26 -3.67241024039304E-09 - 6.41186143763638E-26 -2.63542651216236E-26 -3.67241024039296E-09 - 1.43686280720576E-25 -9.22904150236166E-26 -3.67241024039328E-09 - 3.85721428216866E-25 5.46270399647446E-26 -3.67241024039307E-09 - 5.98776981498957E-26 8.96650859310411E-26 -3.67241024039318E-09 - 3.16857026634692E-25 -1.10263821888172E-25 -3.67241024039353E-09 - -3.65425614847340E-25 -6.45225111598370E-26 -3.67241024039358E-09 - -4.53374139448620E-26 2.78688780596479E-26 -3.67241024039309E-09 - 2.65663109329470E-25 7.81540276020561E-26 -3.67241024039303E-09 - 2.85756974307259E-26 1.04003421744338E-26 -3.67241024039319E-09 - -9.34011311781678E-26 2.15377959787062E-25 -3.67241024039314E-09 - 7.81540276020561E-26 4.73568978622278E-26 -3.67241024039311E-09 - -4.73568978622278E-26 -1.20462215670869E-25 -3.67241024039352E-09 - -2.63542651216236E-26 1.48432067926386E-25 -3.67241024039259E-09 - 9.74400990128994E-26 -7.16916790664856E-27 -3.67241024039531E-09 - -2.37087411898744E-25 1.14403763918772E-25 -3.67241024038472E-09 - 2.75053709545221E-25 -8.27988406119974E-27 -3.67241024043177E-09 - -4.41257235944425E-26 -2.86766716265942E-26 -3.67241024022065E-09 - -2.53445231629407E-26 -5.11939173052228E-26 -3.67241024116607E-09 - -9.55215892914019E-26 -9.59254860748750E-27 -3.67241023692872E-09 - -8.01735115194219E-26 -1.67617165141361E-26 -3.67241025593145E-09 - 7.54277243136123E-26 1.11071615455118E-27 -3.67241017068603E-09 - 2.32139676301198E-25 -2.47386779877309E-26 -3.67241055317633E-09 - 8.64339116632558E-26 -1.57519745554532E-26 -3.67240883665447E-09 - 9.91566603426603E-26 -7.77501308185829E-27 -3.67241654107518E-09 - -7.41150597673245E-26 -2.07300024117598E-25 -3.67238195705987E-09 - -2.33149418259880E-25 -1.17533963990689E-25 -3.67253721004644E-09 - -1.86903236552204E-25 -2.06997101529993E-26 -3.67184023473504E-09 - -4.87705366043838E-26 9.00689827145142E-26 -3.67496918095292E-09 - 1.27732357773386E-25 7.77501308185829E-26 -3.66092335343000E-09 - 1.41666796803210E-25 -6.46234853557053E-27 -3.72398243270705E-09 - 6.46234853557053E-27 6.00796465416323E-27 -3.44112923141631E-09 - 6.95207338553173E-26 -7.83559759937927E-26 -4.71430921074279E-09 - -6.07359788147761E-26 -1.25712873856020E-26 9.27421964195406E-10 - -6.32098466135492E-26 -8.11832534781048E-26 -2.62092929521969E-08 - -2.16185753354008E-25 -5.94536065272489E-25 -2.48955785161512E-06 - -4.51556603922991E-25 5.64809262008864E-24 -1.48867407977123E-05 - -5.64809262008864E-24 -8.24207932226665E-23 -3.81233169248468E-05 - -8.74614250804115E-23 -1.17924936077091E-22 -6.70527946976353E-05 - -1.06060064165784E-22 - 1 -1 6 8 - SCALAIRE - -22 324721 1 0 0 0 -66 0 2 - - - 324673 - FLUX - REAL*8 - 1 301 0 0 - 8.90592407558313E-26 -3.67241024039288E-09 -8.88572923640948E-26 - 3.67241024039353E-09 -7.06819371078027E-27 -3.67241024039253E-09 - 2.19517901817661E-25 -2.01948391736579E-28 -3.67241024039320E-09 - -3.76633750588720E-25 -3.97838331721061E-26 -3.67241024039298E-09 - -1.69232752275253E-25 4.03896783473158E-26 -3.67241024039233E-09 - 1.67011319966151E-25 2.10228275797779E-25 -3.67241024039354E-09 - 1.70848339409146E-25 -8.68378084467290E-26 -3.67241024039333E-09 - -5.89285407087338E-25 -3.75825957021774E-25 -3.67241024039342E-09 - -4.13994203059987E-25 2.47386779877309E-25 -3.67241024039320E-09 - -4.60442333159400E-26 -1.74685358852141E-25 -3.67241024039333E-09 - -2.12449708106881E-25 6.86624531904369E-26 -3.67241024039320E-09 - 2.17296469508559E-25 1.42777512957761E-25 -3.67241024039375E-09 - 5.41221689854032E-26 -4.44286461820474E-26 -3.67241024039307E-09 - -1.50855448627225E-25 -7.99715631276853E-26 -3.67241024039344E-09 - 7.99715631276853E-26 -2.97268032636244E-25 -3.67241024039290E-09 - 3.63507105125842E-27 1.57923642338005E-25 -3.67241024039320E-09 - 1.35507370855245E-25 3.93799363886329E-26 -3.67241024039333E-09 - 6.52293305309150E-26 1.60750919822317E-25 -3.67241024039306E-09 - -1.60750919822317E-25 -1.47624274359439E-25 -3.67241024039303E-09 - 3.97838331721061E-26 1.40959977432132E-25 -3.67241024039348E-09 - -1.40959977432132E-25 -1.13696944547694E-25 -3.67241024039361E-09 - -6.90663499739100E-26 9.89547119509237E-27 -3.67241024039296E-09 - -1.91245126974540E-25 -6.30078982218127E-26 -3.67241024039386E-09 - -2.30221166579700E-25 -1.57115848771058E-25 -3.67241024039359E-09 - -2.08006843488676E-26 -1.51259345410698E-25 -3.67241024039328E-09 - -3.18674562160322E-25 8.27988406119974E-26 -3.67241024039290E-09 - -2.01342546561369E-25 -2.94844651935405E-25 -3.67241024039308E-09 - -1.72261978151302E-25 -3.10192729707385E-25 -3.67241024039331E-09 - -2.26788043920178E-25 -3.03932329563551E-25 -3.67241024039308E-09 - -4.53374139448620E-25 -3.15039491109063E-26 -3.67241024039391E-09 - 2.00332804602686E-25 1.06628750836914E-25 -3.67241024039308E-09 - -6.58351757061248E-26 -6.86624531904369E-26 -3.67241024039323E-09 - 3.24329117128946E-25 -6.72488144482808E-26 -3.67241024039318E-09 - -6.22001046548663E-26 5.69494464697153E-26 -3.67241024039301E-09 - 2.68187464226177E-25 -1.45200893658600E-25 -3.67241024039377E-09 - -2.80910212905581E-25 9.14826214566703E-26 -3.67241024039300E-09 - 3.61487621208476E-25 -7.77501308185829E-26 -3.67241024039317E-09 - 7.77501308185829E-26 -2.06189307963047E-25 -3.67241024039310E-09 - -2.43751708826051E-25 -3.89760396051598E-26 -3.67241024039290E-09 - 5.51319109440861E-26 -1.27429435185781E-25 -3.67241024039354E-09 - -1.27227486794045E-26 2.46377037918626E-26 -3.67241024039328E-09 - -1.66203526399205E-25 1.70040545842200E-25 -3.67241024039333E-09 - 1.23794364134523E-25 -1.08042389579070E-25 -3.67241024039339E-09 - -3.69565556877940E-26 4.84676140167790E-26 -3.67241024039361E-09 - -3.42100575601765E-25 -7.65384404681634E-26 -3.67241024039317E-09 - -6.88644015821734E-26 -2.13055553282091E-25 -3.67241024039331E-09 - -8.04764341070267E-26 2.11439966148198E-25 -3.67241024039343E-09 - 2.33250392455749E-25 6.62390724895979E-26 -3.67241024039318E-09 - 2.27393889095388E-25 -1.34901525680035E-25 -3.67241024039311E-09 - 1.34901525680035E-25 8.18900728491828E-26 -3.67241024039357E-09 - 1.93668507675379E-25 3.23117426778526E-26 -3.67241024039314E-09 - -5.34153496143252E-26 -5.43241173771398E-26 -3.67241024039307E-09 - 5.44250915730080E-26 1.62669429543814E-25 -3.67241024039284E-09 - 1.30761583649435E-25 -4.12984461101304E-26 -3.67241024039350E-09 - -9.02709311062508E-26 2.08612688663886E-25 -3.67241024039307E-09 - -4.51354655531254E-26 2.39308844207846E-26 -3.67241024039306E-09 - 1.40959977432132E-25 -9.28962601988264E-26 -3.67241024039349E-09 - 9.28962601988264E-26 -5.14968398928277E-27 -3.67241024039352E-09 - 1.30458661061830E-25 -9.73391248170311E-26 -3.67241024039339E-09 - 2.67177722267494E-25 2.32240650497066E-26 -3.67241024039338E-09 - 9.90556861467920E-26 -1.02892705589787E-25 -3.67241024039340E-09 - 1.02993679785655E-25 -1.61962610172736E-25 -3.67241024039337E-09 - -3.06052787676786E-25 1.10768692867514E-25 -3.67241024039322E-09 - 6.52293305309150E-26 -9.20884666318800E-26 -3.67241024039350E-09 - -8.54241697045729E-26 -1.41060951628000E-25 -3.67241024039317E-09 - -3.80672718423451E-26 -2.34260134414432E-26 -3.67241024039306E-09 - 2.03866901458077E-25 4.33179300274962E-26 -3.67241024039341E-09 - -4.32169558316279E-26 -6.45225111598370E-26 -3.67241024039337E-09 - -4.53374139448620E-26 8.19910470450511E-26 -3.67241024039320E-09 - -8.20920212409194E-26 7.81540276020561E-26 -3.67241024039314E-09 - 2.85756974307259E-26 -4.22072138729450E-26 -3.67241024039330E-09 - -4.39641648810533E-25 2.15377959787062E-25 -3.67241024039292E-09 - 7.81540276020561E-26 -5.04870979341448E-26 -3.67241024039388E-09 - -5.15978140886959E-26 1.75897049202560E-25 -3.67241024039071E-09 - 3.18876510552058E-25 -4.73568978622278E-26 -3.67241024040324E-09 - -2.93935884172591E-25 9.04728794979874E-26 -3.67241024034861E-09 - 3.00499206904030E-25 -8.03754599111585E-26 -3.67241024059032E-09 - -1.62265532760341E-25 -3.02922587604869E-27 -3.67241023952035E-09 - 5.54348335316909E-26 -1.21471957629552E-25 -3.67241024426136E-09 - 1.21370983433684E-25 1.47826222751176E-25 -3.67241022324977E-09 - 5.45260657688763E-26 -5.45260657688763E-27 -3.67241031637190E-09 - -8.42124793541535E-26 3.69565556877940E-26 -3.67240990368664E-09 - -6.65419950772028E-26 -3.08981039356966E-26 -3.67241173242214E-09 - 9.10787246731971E-26 6.68449176648077E-26 -3.67240362942430E-09 - -6.67439434689394E-26 1.80036991233160E-25 -3.67243952988475E-09 - 1.13494996155957E-25 9.79449699922408E-26 -3.67228048833603E-09 - 4.87705366043838E-26 -1.09355054125358E-25 -3.67298497952106E-09 - 4.30150074398913E-26 -4.81646914291741E-26 -3.66986473778849E-09 - 4.82656656250424E-26 -8.99680085186460E-26 -3.68368333162175E-09 - -2.03563978870472E-25 -1.43383358132971E-25 -3.62250163492353E-09 - -2.25879276157364E-25 1.02791731393919E-25 -3.89352501416930E-09 - 1.92456817324960E-25 -4.20557525791426E-26 -2.69653362574500E-09 - -1.04205370136075E-25 1.51158371214829E-25 -8.05177318462775E-09 - 6.93692725615149E-26 1.16978605913413E-25 1.47323925086573E-08 - 8.82009600909509E-26 -4.58422849242034E-26 -1.31703887083274E-07 - 1.71858081367829E-25 3.72877510502420E-24 -4.47711692554017E-06 - 4.30230853755608E-24 7.67727006025779E-24 -1.71768467880227E-05 - 1.62851183096377E-23 -1.30280946477102E-23 -2.91071220692787E-05 - -1.52511425439464E-24 -9.88739325942291E-24 -3.43072691406396E-05 - 9.90031795649405E-24 8.91157863055176E-24 -3.48986932858369E-05 - 8.42690249038397E-24 - 1 -1 6 8 - SCALAIRE - -22 324445 1 0 0 0 -67 0 2 - - - 324433 - FLUX - REAL*8 - 1 301 0 0 - 4.03896783473158E-28 -3.67241024039266E-09 -2.01948391736579E-28 - 3.67241024039396E-09 -7.06819371078027E-27 -3.67241024039318E-09 - 2.19517901817661E-25 3.91375983185490E-25 -3.67241024039363E-09 - 2.98883619770137E-26 2.74043967586538E-25 -3.67241024039320E-09 - 3.13423903975171E-25 1.32276196587459E-25 -3.67241024039321E-09 - -3.39879143292662E-25 2.20527643776344E-25 -3.67241024039299E-09 - 7.31053178086416E-26 9.99644539096066E-26 -3.67241024039332E-09 - -1.89225643057175E-25 -7.51248017260074E-26 -3.67241024039353E-09 - -1.55500261637166E-26 3.50986304838174E-25 -3.67241024039341E-09 - -1.49643758276805E-25 -3.76633750588720E-25 -3.67241024039375E-09 - -6.10086091436205E-25 1.69232752275253E-25 -3.67241024039374E-09 - 1.24602157701469E-25 -5.25065818515105E-26 -3.67241024039331E-09 - -1.41161925823869E-25 5.31124270267203E-26 -3.67241024039318E-09 - -5.31124270267203E-26 -1.77916533119926E-25 -3.67241024039374E-09 - -3.09182987748702E-25 1.84580830047233E-25 -3.67241024039299E-09 - 1.99525011035740E-25 -1.40758029040396E-25 -3.67241024039320E-09 - -1.52672984152854E-25 2.35067927981378E-25 -3.67241024039331E-09 - 1.62972352131419E-25 1.60750919822317E-25 -3.67241024039360E-09 - -1.60750919822317E-25 -4.48325429655205E-26 -3.67241024039337E-09 - -2.48800418619465E-25 -3.73604524712671E-26 -3.67241024039337E-09 - -3.73604524712671E-26 -2.86766716265942E-26 -3.67241024039351E-09 - -2.64754341566655E-25 1.22380725392367E-25 -3.67241024039318E-09 - -1.22380725392367E-25 1.40556080648659E-25 -3.67241024039309E-09 - 3.89760396051598E-26 2.08006843488676E-26 -3.67241024039337E-09 - 2.72630328844382E-25 1.55500261637166E-26 -3.67241024039361E-09 - -1.57519745554532E-26 2.01342546561369E-25 -3.67241024039340E-09 - 9.20884666318800E-26 -3.47351233786916E-26 -3.67241024039318E-09 - 8.80494987971485E-26 9.30982085905629E-26 -3.67241024039379E-09 - -4.28130590481548E-26 6.19981562631298E-26 -3.67241024039318E-09 - 2.31432856930120E-25 5.27085302432471E-26 -3.67241024039297E-09 - -1.77714584728190E-25 -6.07864659127103E-26 -3.67241024039335E-09 - -2.33250392455749E-25 1.11879409022065E-25 -3.67241024039297E-09 - 1.43787254916444E-25 -8.30007890037340E-26 -3.67241024039325E-09 - -4.69328062395810E-25 -1.05820957269967E-25 -3.67241024039351E-09 - 2.68389412617914E-25 2.46175089526890E-25 -3.67241024039333E-09 - -1.13696944547694E-25 2.25576353569759E-25 -3.67241024039290E-09 - 6.80566080152271E-26 8.01735115194219E-26 -3.67241024039355E-09 - -5.79591884283982E-26 -1.27833331969255E-25 -3.67241024039304E-09 - 1.27833331969255E-25 -1.36719061205664E-25 -3.67241024039327E-09 - -1.40758029040396E-25 -5.06890463258813E-26 -3.67241024039312E-09 - 3.57448653373745E-25 1.66203526399205E-25 -3.67241024039318E-09 - 2.69197206184860E-25 -1.23592415742786E-25 -3.67241024039355E-09 - -1.97909423901847E-26 -1.08042389579070E-25 -3.67241024039300E-09 - 1.08042389579070E-25 2.36279618331797E-26 -3.67241024039322E-09 - -2.44357554001261E-26 -2.64552393174919E-26 -3.67241024039334E-09 - 3.22410607407448E-25 6.00796465416323E-26 -3.67241024039345E-09 - -2.04169824045681E-25 -1.09052131537753E-26 -3.67241024039340E-09 - 1.10061873496436E-26 -1.29448919103147E-25 -3.67241024039350E-09 - -1.14100841331167E-26 -2.04573720829155E-25 -3.67241024039329E-09 - -8.89582665599631E-26 5.28095044391154E-26 -3.67241024039303E-09 - 2.22749076085447E-25 -1.72060029759565E-25 -3.67241024039339E-09 - -1.21471957629552E-25 -1.15413505877455E-25 -3.67241024039314E-09 - -1.78118481511663E-25 2.32240650497066E-27 -3.67241024039357E-09 - -2.96864135852771E-26 8.85543697764899E-26 -3.67241024039315E-09 - 7.35092145921148E-26 1.10768692867514E-25 -3.67241024039331E-09 - 1.82763294521604E-25 -1.71656132976092E-25 -3.67241024039292E-09 - -2.50416005753358E-25 6.83595306028320E-26 -3.67241024039372E-09 - 5.86660077994762E-26 2.24162714827603E-26 -3.67241024039316E-09 - -2.24162714827603E-26 -7.14897306747490E-26 -3.67241024039341E-09 - -9.82478925798457E-26 2.31331882734251E-25 -3.67241024039326E-09 - 2.33654289239222E-25 -1.02892705589787E-25 -3.67241024039318E-09 - 1.02993679785655E-25 1.25208002876679E-26 -3.67241024039314E-09 - -1.31771325608118E-25 9.13816472608020E-26 -3.67241024039318E-09 - 2.62532909257553E-26 -1.68424958708307E-25 -3.67241024039326E-09 - -6.37147175928907E-26 3.79662976464769E-26 -3.67241024039306E-09 - 1.41161925823869E-25 -1.21169035041947E-25 -3.67241024039328E-09 - 1.21169035041947E-25 -1.65900603811600E-25 -3.67241024039341E-09 - -2.39005921620241E-25 3.33214846365355E-26 -3.67241024039337E-09 - -1.43080435545366E-25 -1.24198260917996E-25 -3.67241024039298E-09 - 1.58529487513215E-26 1.59539229471897E-26 -3.67241024039336E-09 - -1.22683647979972E-25 1.08244337970806E-25 -3.67241024039254E-09 - -1.91346101170409E-25 -1.75998023398429E-25 -3.67241024039370E-09 - -1.17533963990689E-25 -1.61558713389263E-27 -3.67241024038972E-09 - 1.93062662500170E-25 -1.69333726471122E-25 -3.67241024040869E-09 - -7.79520792103195E-26 1.00974195868290E-27 -3.67241024032582E-09 - -1.00974195868290E-27 9.00689827145142E-26 -3.67241024068759E-09 - 7.27014210251684E-27 6.54312789226516E-26 -3.67241023910895E-09 - -1.16322273640270E-25 -1.06224854053441E-25 -3.67241024599752E-09 - 5.36172980060617E-26 -2.86766716265942E-26 -3.67241021594828E-09 - 1.21471957629552E-25 -2.32240650497066E-27 -3.67241034697880E-09 - -1.44494074287522E-25 -1.56308055204112E-25 -3.67240977583599E-09 - 9.59254860748750E-27 -6.57342015102565E-26 -3.67241226438450E-09 - 6.58351757061248E-26 1.59135332688424E-25 -3.67240142586568E-09 - 4.77607946457009E-26 -2.26788043920178E-25 -3.67244861142530E-09 - 7.99715631276853E-26 -1.57519745554532E-26 -3.67224327981185E-09 - 9.91566603426603E-26 2.01948391736579E-28 -3.67313638625655E-09 - 6.48254337474419E-26 -1.75897049202560E-25 -3.66925364726284E-09 - -1.17634938186557E-25 4.02887041514475E-26 -3.68612589317128E-09 - -1.87004210748072E-25 -1.78017507315794E-25 -3.61285901818769E-09 - -1.15514480073323E-25 1.39344390298240E-26 -3.93107607298909E-09 - -1.39344390298240E-26 2.99893361728820E-26 -2.55409793676906E-09 - 1.16221299444401E-25 1.72665874934775E-26 -8.59351902682153E-09 - 5.54348335316909E-26 -2.57989070443480E-26 1.65320211216982E-08 - 2.04977617612628E-26 2.05078591808496E-25 -1.45795184154468E-07 - 6.69458918606759E-26 -4.74982617364434E-25 -4.52527430267040E-06 - -2.39914689383056E-24 9.19592196611686E-24 -1.52793802463874E-05 - 4.96308367531817E-24 -2.01625274309800E-24 -2.38252364893103E-05 - 7.35415263347926E-24 -1.25886549472914E-23 -2.73069401262468E-05 - -6.35895095900140E-24 1.18777966083786E-23 -2.80706164505380E-05 - 1.67374827071277E-23 -1.19488824422699E-23 -2.81234131669965E-05 - -9.61597462092895E-24 - 1 -1 6 8 - SCALAIRE - -22 324223 1 0 0 0 -68 0 2 - - - 324211 - FLUX - REAL*8 - 1 301 0 0 - 2.01948391736579E-28 -3.67241024039310E-09 2.13459450065564E-25 - 3.67241024039375E-09 -1.29852815886620E-25 -3.67241024039340E-09 - -4.57211158891615E-25 0.00000000000000E+00 -3.67241024039319E-09 - 0.00000000000000E+00 -1.44191151699917E-25 -3.67241024039299E-09 - -6.46234853557053E-26 1.32276196587459E-25 -3.67241024039342E-09 - 2.47184831485573E-25 2.04977617612628E-25 -3.67241024039354E-09 - 2.63542651216236E-25 1.04407318527811E-25 -3.67241024039330E-09 - 9.99644539096066E-26 -1.76704842769507E-25 -3.67241024039288E-09 - -2.62532909257553E-26 -1.38334648339557E-25 -3.67241024039373E-09 - -4.60442333159400E-26 1.20765138258474E-25 -3.67241024039331E-09 - -2.14267243632510E-25 7.39131113755879E-26 -3.67241024039286E-09 - -1.69030803883517E-25 1.42777512957761E-25 -3.67241024039321E-09 - 1.51057397018961E-25 2.48396521835992E-25 -3.67241024039243E-09 - 4.50344913572571E-26 2.14671140415984E-25 -3.67241024039339E-09 - -2.14469192024247E-25 -1.07032647620387E-25 -3.67241024039277E-09 - -2.88180355008098E-25 3.53611633930750E-25 -3.67241024039329E-09 - 2.33452340847485E-25 2.31634805321856E-25 -3.67241024039308E-09 - -3.36446020633141E-25 -2.14065295240774E-25 -3.67241024039309E-09 - -1.60750919822317E-25 -4.96793043671984E-26 -3.67241024039306E-09 - -3.51592150013384E-25 -1.46816480792493E-25 -3.67241024039350E-09 - -3.30993414056253E-25 -1.26621641618835E-25 -3.67241024039329E-09 - -2.77477090246060E-25 -2.61725115690606E-25 -3.67241024039340E-09 - -1.00368350693080E-25 4.26111106564182E-26 -3.67241024039331E-09 - 1.36921009597401E-25 2.08006843488676E-26 -3.67241024039294E-09 - 2.72630328844382E-25 1.51865190585907E-25 -3.67241024039278E-09 - 8.21929954367877E-26 1.03397576569128E-25 -3.67241024039362E-09 - 1.89831488232384E-25 -2.36279618331797E-26 -3.67241024039302E-09 - 1.97101630334901E-25 -2.98277774594927E-25 -3.67241024039341E-09 - 5.49299625523495E-26 -1.08244337970806E-25 -3.67241024039318E-09 - -3.55631117848116E-25 -1.29448919103147E-25 -3.67241024039325E-09 - -3.33012897973619E-25 5.14968398928277E-26 -3.67241024039315E-09 - 7.47209049425342E-26 -9.87527635591871E-26 -3.67241024039352E-09 - -6.68449176648077E-26 -1.64991836048785E-25 -3.67241024039297E-09 - -2.57888096247611E-25 7.33072662003782E-26 -3.67241024039350E-09 - -7.35092145921148E-26 -2.08410740272150E-25 -3.67241024039349E-09 - -2.46377037918626E-25 9.14826214566703E-26 -3.67241024039333E-09 - 3.61487621208476E-25 1.77916533119926E-25 -3.67241024039312E-09 - -2.01948391736579E-26 2.82929696822947E-25 -3.67241024039357E-09 - 1.47624274359439E-25 1.77310687944716E-25 -3.67241024039305E-09 - 1.16322273640270E-25 1.23794364134523E-25 -3.67241024039307E-09 - -1.10667718671645E-25 -1.49441809885068E-25 -3.67241024039355E-09 - -1.44191151699917E-25 -4.84676140167790E-26 -3.67241024039329E-09 - -9.47137957244556E-26 -1.08042389579070E-25 -3.67241024039318E-09 - -1.81753552562921E-25 -6.05845175209737E-28 -3.67241024039329E-09 - 6.05845175209737E-28 2.11036069364725E-26 -3.67241024039364E-09 - -2.13055553282091E-26 -2.13055553282091E-25 -3.67241024039352E-09 - -8.04764341070267E-26 4.24091622646816E-26 -3.67241024039343E-09 - 2.51223799320304E-25 -1.56812926183454E-25 -3.67241024039339E-09 - -1.36719061205664E-25 -1.34901525680035E-25 -3.67241024039315E-09 - -3.12818058799961E-25 7.08838854995392E-26 -3.67241024039374E-09 - 2.22850050281315E-25 -7.41150597673245E-26 -3.67241024039331E-09 - -6.19981562631298E-26 -1.21673906021289E-25 -3.67241024039314E-09 - -1.31266454628776E-26 -1.97404552922506E-25 -3.67241024039317E-09 - 6.41186143763638E-26 1.88114926902623E-25 -3.67241024039347E-09 - 3.99150996267348E-25 1.75796075006692E-25 -3.67241024039363E-09 - -4.58422849242034E-26 1.89124668861306E-25 -3.67241024039306E-09 - -2.40318586166529E-26 1.66203526399205E-25 -3.67241024039351E-09 - -3.92789621927646E-26 1.20260267279133E-25 -3.67241024039339E-09 - 5.14968398928277E-27 3.65526589043208E-26 -3.67241024039286E-09 - 4.26817925935260E-25 -3.78653234506086E-26 -3.67241024039349E-09 - 3.78653234506086E-26 6.98741435408563E-26 -3.67241024039294E-09 - 1.02993679785655E-25 -8.54241697045729E-26 -3.67241024039304E-09 - -3.38263556158770E-26 1.30458661061830E-25 -3.67241024039321E-09 - -1.28237228752728E-26 2.41227353929344E-25 -3.67241024039295E-09 - 5.24056076556423E-26 -4.32169558316279E-26 -3.67241024039306E-09 - 1.57721693946268E-25 -1.21169035041947E-25 -3.67241024039339E-09 - 1.21169035041947E-25 -5.45260657688763E-26 -3.67241024039331E-09 - 5.46270399647446E-26 3.32205104406672E-26 -3.67241024039326E-09 - -2.16993546920954E-25 2.78688780596479E-26 -3.67241024039330E-09 - 2.65663109329470E-25 7.81540276020561E-26 -3.67241024039303E-09 - 2.85756974307259E-26 -4.95783301713301E-26 -3.67241024039386E-09 - -1.38738545123030E-25 7.14897306747490E-26 -3.67241024038983E-09 - -7.14897306747490E-26 9.84498409715823E-26 -3.67241024040755E-09 - 4.84676140167790E-26 2.62532909257553E-26 -3.67241024033189E-09 - -7.24994726334319E-26 -9.62284086624799E-26 -3.67241024065768E-09 - 1.95284094809272E-25 4.13994203059987E-26 -3.67241023925444E-09 - 1.05417060486494E-25 2.14166269436642E-25 -3.67241024529885E-09 - 2.77073193462586E-25 -4.84676140167790E-27 -3.67241021927662E-09 - 5.72523690573202E-26 -8.01735115194219E-26 -3.67241033124529E-09 - 1.72968797522380E-25 4.00867557597109E-26 -3.67240984970189E-09 - 1.42474590370157E-25 -5.44250915730080E-26 -3.67241191965898E-09 - -9.24923634153532E-26 2.72630328844382E-26 -3.67240302615240E-09 - 1.19452473712186E-25 1.64789887657048E-25 -3.67244121793013E-09 - -1.04609266919548E-25 -2.13964321044905E-25 -3.67227729050905E-09 - -1.78724326686872E-26 -2.28201682662334E-26 -3.67298055619205E-09 - 1.06426802445177E-25 -7.77501308185829E-27 -3.66996497593654E-09 - 1.54692468070220E-25 -7.78511050144512E-26 -3.68288972557482E-09 - -5.49299625523495E-26 -1.06830699228650E-25 -3.62752750801944E-09 - -2.54555947783958E-25 2.94844651935405E-26 -3.86467195985321E-09 - 2.64249470587314E-25 -3.33214846365355E-26 -2.85145474916674E-09 - -1.88619797881965E-25 -3.68555814919257E-26 -7.21816146023862E-09 - -3.77643492547403E-26 -1.37476367674676E-25 1.09455213600853E-08 - -1.42474590370157E-25 -2.09824379014306E-25 -8.41961845613521E-08 - -2.02251314324184E-25 -4.02765872479433E-24 -3.61381822391411E-06 - -4.64804418420910E-24 -2.27927032849573E-23 -1.30446904442429E-05 - -2.28508644217774E-23 -4.00665609205373E-25 -2.04805546634357E-05 - 3.87740912134232E-25 -5.82128356084193E-23 -2.37828557507934E-05 - -3.93169284904111E-23 -1.23043116117263E-23 -2.47708212411996E-05 - 1.23043116117263E-23 4.96308367531817E-24 -2.49723748419041E-05 - -4.95015897824702E-24 -6.91471293306047E-25 -2.49869805498920E-05 - -3.53490464895708E-24 - 1 -1 6 8 - SCALAIRE - -22 323905 1 0 0 0 -69 0 2 - - - 323893 - FLUX - REAL*8 - 1 301 0 0 - 7.08838854995392E-26 -3.67241024039375E-09 -2.84747232348576E-25 - 3.67241024039331E-09 8.23949438285242E-26 -3.67241024039275E-09 - 1.29852815886620E-25 9.02709311062508E-26 -3.67241024039362E-09 - 4.96793043671984E-25 -3.97838331721061E-26 -3.67241024039363E-09 - -1.69232752275253E-25 -1.43383358132971E-25 -3.67241024039299E-09 - -2.36077669940061E-25 2.20527643776344E-25 -3.67241024039397E-09 - -2.20527643776344E-25 1.55500261637166E-26 -3.67241024039321E-09 - 9.99644539096066E-26 -7.87598727772658E-26 -3.67241024039322E-09 - 1.69232752275253E-25 -4.32169558316279E-26 -3.67241024039331E-09 - 4.32169558316279E-26 -7.89618211690024E-26 -3.67241024039373E-09 - -2.14267243632510E-25 3.66132434218418E-25 -3.67241024039362E-09 - 2.28201682662334E-26 -1.51865190585907E-25 -3.67241024039332E-09 - -4.35198784192328E-25 1.50855448627225E-25 -3.67241024039288E-09 - -2.49204315402939E-25 -1.78926275078609E-25 -3.67241024039330E-09 - -5.08102153609233E-25 9.04728794979874E-26 -3.67241024039334E-09 - -9.04728794979874E-26 -3.33820691540565E-25 -3.67241024039332E-09 - -8.40105309624169E-25 1.33891783721352E-25 -3.67241024039319E-09 - 1.59741177863634E-25 -2.30625063363173E-25 -3.67241024039297E-09 - -6.30078982218127E-26 -4.26515003347655E-25 -3.67241024039357E-09 - 1.32680093370932E-25 -2.38904947424373E-25 -3.67241024039348E-09 - -2.38904947424373E-25 -1.39546338689976E-25 -3.67241024039327E-09 - -3.75624008630037E-25 2.42338070083895E-26 -3.67241024039276E-09 - 2.00130856210950E-25 -7.12877822830124E-26 -3.67241024039360E-09 - -4.28130590481548E-26 -1.66001578007468E-25 -3.67241024039344E-09 - -1.27429435185781E-25 4.44286461820474E-26 -3.67241024039325E-09 - -2.20931540559817E-25 1.91043178582804E-25 -3.67241024039308E-09 - 1.02589783002182E-25 -1.85792520397653E-25 -3.67241024039344E-09 - -2.81314109689055E-25 -7.89618211690024E-26 -3.67241024039330E-09 - -2.14873088807720E-25 8.76456020136753E-26 -3.67241024039292E-09 - 1.58933384296688E-25 -1.42979461349498E-25 -3.67241024039301E-09 - -5.69090567913680E-25 1.06628750836914E-25 -3.67241024039286E-09 - -6.58351757061248E-26 1.79734068645555E-25 -3.67241024039320E-09 - 2.41732224908685E-25 1.47422325967703E-26 -3.67241024039286E-09 - 1.49239861493332E-25 5.69494464697153E-26 -3.67241024039355E-09 - 2.68187464226177E-25 -1.10667718671645E-25 -3.67241024039343E-09 - -3.44120059519131E-25 1.45806738833810E-25 -3.67241024039322E-09 - 1.47624274359439E-25 8.01735115194219E-26 -3.67241024039388E-09 - -5.79591884283982E-26 -3.62901259950633E-25 -3.67241024039331E-09 - 6.94702467573832E-26 -1.16322273640270E-25 -3.67241024039306E-09 - -2.24162714827603E-26 4.70539752746229E-26 -3.67241024039339E-09 - -4.70539752746229E-26 -1.05417060486494E-25 -3.67241024039343E-09 - -1.88215901098492E-25 -4.84676140167790E-26 -3.67241024039339E-09 - -9.47137957244556E-26 -1.35103474071771E-25 -3.67241024039343E-09 - 1.35305422463508E-25 2.36279618331797E-26 -3.67241024039350E-09 - -1.70646391017409E-25 -1.49441809885068E-25 -3.67241024039354E-09 - 3.93799363886329E-27 -6.35127692011541E-26 -3.67241024039335E-09 - -8.03754599111585E-26 2.11439966148198E-25 -3.67241024039310E-09 - 2.33250392455749E-25 -2.27393889095388E-25 -3.67241024039292E-09 - 8.64339116632558E-26 1.30458661061830E-25 -3.67241024039311E-09 - 8.78475504054119E-27 -2.70610844927016E-26 -3.67241024039364E-09 - 2.69601102968333E-26 2.37289360290480E-26 -3.67241024039318E-09 - 1.33790809525484E-25 -1.15413505877455E-25 -3.67241024039350E-09 - 1.15312531681587E-25 -6.42195885722321E-26 -3.67241024039357E-09 - -9.62284086624799E-26 8.85543697764899E-26 -3.67241024039304E-09 - 7.35092145921148E-26 7.79520792103195E-26 -3.67241024039331E-09 - -2.41530276516949E-25 -6.66429692730711E-27 -3.67241024039336E-09 - 1.71656132976092E-25 -9.28962601988264E-26 -3.67241024039339E-09 - 9.28962601988264E-26 -4.01877299555792E-26 -3.67241024039320E-09 - 1.65698655419863E-25 -7.13887564788807E-26 -3.67241024039328E-09 - 7.14897306747490E-26 2.32240650497066E-26 -3.67241024039348E-09 - -2.32240650497066E-26 -1.25914822247757E-25 -3.67241024039305E-09 - -1.67718139337229E-25 1.25208002876679E-26 -3.67241024039314E-09 - -1.31771325608118E-25 9.13816472608020E-26 -3.67241024039297E-09 - -9.14826214566703E-26 -7.05809629119344E-26 -3.67241024039318E-09 - -4.54383881407303E-26 -2.39005921620241E-25 -3.67241024039338E-09 - -2.33755263435090E-25 -3.83701944299500E-26 -3.67241024039339E-09 - 3.83701944299500E-26 -5.45260657688763E-26 -3.67241024039319E-09 - -1.27530409381650E-25 -1.50350577647883E-25 -3.67241024039325E-09 - -3.32205104406672E-26 -2.22042256714369E-25 -3.67241024039298E-09 - 5.45260657688763E-27 -2.84747232348576E-26 -3.67241024039369E-09 - -1.58226564925610E-25 1.00873221672421E-25 -3.67241024039133E-09 - 1.92759739912565E-25 -1.75897049202560E-25 -3.67241024040141E-09 - -4.11166925575675E-25 5.14968398928277E-26 -3.67241024035965E-09 - 2.42035147496290E-25 2.36279618331797E-26 -3.67241024053529E-09 - 1.23188518959313E-25 -4.73568978622278E-26 -3.67241023979269E-09 - 4.73568978622278E-26 -7.37111629838513E-27 -3.67241024293143E-09 - -1.88720772077833E-25 6.35127692011541E-26 -3.67241022968243E-09 - -2.61119270515397E-25 -2.00534752994423E-25 -3.67241028554567E-09 - 1.21169035041947E-27 -7.26004468293002E-26 -3.67241005027592E-09 - -7.43170081590611E-26 9.56225634872702E-26 -3.67241103992250E-09 - 1.42474590370157E-25 -1.76704842769507E-26 -3.67240688233238E-09 - 1.76704842769507E-26 -6.08874401085786E-26 -3.67242432529182E-09 - -1.15413505877455E-25 -1.51259345410698E-25 -3.67235124816126E-09 - -2.02453262715920E-25 -1.28944048123806E-25 -3.67265694278546E-09 - -1.78724326686872E-26 -8.48183245293632E-27 -3.67138022513029E-09 - -5.48289883564812E-26 -7.87598727772658E-27 -3.67670326507487E-09 - 7.87598727772658E-27 -6.93692725615149E-26 -3.65455170399297E-09 - -1.43787254916444E-25 -3.84711686258183E-26 -3.74656700307015E-09 - 3.83701944299500E-26 -4.27120848522865E-26 -3.36544160750021E-09 - 4.27120848522865E-26 -7.01770661284612E-26 -4.94496986160892E-09 - 7.00760919325929E-26 4.94773559754619E-26 1.50941977348801E-09 - -4.55393623365986E-26 2.10026327406042E-26 -2.62460699675534E-08 - -2.10026327406042E-26 -1.40394521935270E-24 -2.38137905264311E-06 - -1.99848128462519E-24 1.58973773975035E-24 -1.06758299602607E-05 - 7.42523846737054E-24 -6.96641172134503E-24 -1.77464553400661E-05 - 6.96641172134503E-24 -1.98523347012727E-23 -2.12523037521504E-05 - -4.16175245690742E-24 -9.64699389389969E-23 -2.25349190595267E-05 - -7.33605805757966E-23 3.02696405406124E-23 -2.29138857114356E-05 - 2.58752435364244E-23 3.45089411799466E-23 -2.29966672954561E-05 - 3.31001491991922E-23 -3.98080669791145E-24 -2.30030697359713E-05 - 3.98080669791145E-24 - 1 -1 6 8 - SCALAIRE - -22 323653 1 0 0 0 -70 0 2 - - - 323635 - FLUX - REAL*8 - 1 301 0 0 - -3.91174034793754E-25 -3.67241024039354E-09 1.77714584728190E-26 - 3.67241024039354E-09 2.78082935421269E-25 -3.67241024039319E-09 - 9.69352280335579E-26 3.01105052079239E-25 -3.67241024039363E-09 - -9.02709311062508E-26 -1.30862557845303E-25 -3.67241024039343E-09 - -7.81540276020561E-26 -1.43383358132971E-25 -3.67241024039299E-09 - -2.36077669940061E-25 2.20527643776344E-25 -3.67241024039353E-09 - 7.31053178086416E-26 1.11071615455118E-26 -3.67241024039385E-09 - 1.04407318527811E-25 -7.51248017260074E-26 -3.67241024039353E-09 - -1.55500261637166E-26 -4.32169558316279E-26 -3.67241024039278E-09 - 1.52269087369381E-25 -7.89618211690024E-26 -3.67241024039384E-09 - -2.14267243632510E-25 -2.64552393174919E-26 -3.67241024039374E-09 - -2.66975773875757E-25 1.42979461349498E-25 -3.67241024039352E-09 - 3.47149285395179E-25 5.29104786349837E-26 -3.67241024039286E-09 - -5.29104786349837E-26 -7.89618211690024E-26 -3.67241024039384E-09 - 1.78926275078609E-25 -3.95213002628485E-25 -3.67241024039334E-09 - -4.85483933734736E-25 3.50986304838174E-25 -3.67241024039320E-09 - 3.39071349725716E-25 -6.17962078713932E-26 -3.67241024039341E-09 - -4.28130590481548E-26 -1.24400209309733E-25 -3.67241024039331E-09 - 1.24400209309733E-25 -2.30625063363173E-25 -3.67241024039322E-09 - 1.52672984152854E-25 4.88715108002521E-26 -3.67241024039322E-09 - 6.03825691292371E-26 -3.53409685539013E-26 -3.67241024039351E-09 - -3.69161660094466E-25 1.15110583289850E-25 -3.67241024039307E-09 - -2.62532909257553E-27 -2.51021850928568E-25 -3.67241024039330E-09 - -3.36244072241404E-25 2.96864135852771E-26 -3.67241024039305E-09 - -2.96864135852771E-26 1.13494996155957E-25 -3.67241024039296E-09 - -1.13494996155957E-25 -4.64481300994132E-27 -3.67241024039314E-09 - -2.88988148575045E-25 -1.96899681943165E-25 -3.67241024039370E-09 - -9.65313312500848E-26 -7.87598727772658E-26 -3.67241024039331E-09 - -3.36446020633141E-25 -1.33689835329615E-25 -3.67241024039293E-09 - 1.02993679785655E-26 5.27085302432471E-26 -3.67241024039302E-09 - 1.15918376856796E-25 4.14398099843460E-25 -3.67241024039286E-09 - 3.39879143292662E-25 -9.89547119509237E-26 -3.67241024039314E-09 - -2.32644547280539E-25 1.47422325967703E-26 -3.67241024039297E-09 - 1.49239861493332E-25 -1.05820957269967E-25 -3.67241024039346E-09 - 1.05619008878231E-25 -1.10667718671645E-25 -3.67241024039354E-09 - -3.44120059519131E-25 6.60371240978613E-26 -3.67241024039300E-09 - 2.01948391736579E-25 1.36921009597401E-25 -3.67241024039366E-09 - 2.12045811323408E-26 -1.27833331969255E-25 -3.67241024039365E-09 - -1.65597681223995E-25 -1.36719061205664E-25 -3.67241024039328E-09 - -1.40556080648659E-25 -5.08909947176179E-26 -3.67241024039339E-09 - -2.29817269796227E-25 2.42338070083895E-27 -3.67241024039329E-09 - 1.49239861493332E-25 -2.21537385735027E-25 -3.67241024039339E-09 - -7.20955758499587E-26 1.85590572005916E-25 -3.67241024039334E-09 - 2.56676405897192E-25 9.73391248170311E-26 -3.67241024039339E-09 - 4.92754075837253E-26 1.69232752275253E-25 -3.67241024039342E-09 - 2.72327406256777E-25 -6.36137433970224E-26 -3.67241024039349E-09 - -8.03754599111585E-26 1.57519745554532E-26 -3.67241024039310E-09 - -1.58226564925610E-25 -1.59539229471897E-26 -3.67241024039340E-09 - -1.36618087009796E-25 -1.48331093730517E-25 -3.67241024039297E-09 - -2.84646258152708E-25 2.77477090246060E-25 -3.67241024039361E-09 - 1.53783700307405E-25 2.19214979230057E-25 -3.67241024039328E-09 - 2.31533831125988E-25 1.41262900019737E-25 -3.67241024039314E-09 - 1.52269087369381E-25 9.62284086624799E-26 -3.67241024039352E-09 - -9.62284086624799E-26 -1.05518034682363E-25 -3.67241024039336E-09 - 1.05619008878231E-25 1.10061873496436E-25 -3.67241024039344E-09 - -1.43585306524708E-25 9.12806730649337E-26 -3.67241024039304E-09 - 7.39131113755879E-26 3.92789621927646E-26 -3.67241024039341E-09 - 2.54253025196353E-25 -5.14968398928277E-27 -3.67241024039341E-09 - 1.30458661061830E-25 -9.73391248170311E-26 -3.67241024039339E-09 - 2.67177722267494E-25 2.33250392455749E-26 -3.67241024039373E-09 - -2.32240650497066E-26 5.51319109440861E-26 -3.67241024039308E-09 - 6.55322531185199E-26 3.37253814200087E-26 -3.67241024039282E-09 - 2.59806605969109E-25 1.30458661061830E-25 -3.67241024039342E-09 - -1.28237228752728E-26 -1.90033436624121E-25 -3.67241024039306E-09 - -1.03599524960865E-25 -8.38085825706803E-26 -3.67241024039328E-09 - 8.37076083748120E-26 -1.06022905661704E-25 -3.67241024039340E-09 - 2.19013030838320E-25 7.19946016540904E-26 -3.67241024039353E-09 - -1.21169035041947E-27 -6.45225111598370E-26 -3.67241024039358E-09 - -4.53374139448620E-26 1.25712873856020E-25 -3.67241024039309E-09 - 1.67920087728965E-25 -7.30043436127733E-26 -3.67241024039282E-09 - 2.86564767874206E-25 9.35021053740361E-26 -3.67241024039386E-09 - -9.35021053740361E-26 -1.30054764278357E-25 -3.67241024039184E-09 - 2.62532909257553E-26 1.00570299084816E-25 -3.67241024039684E-09 - 4.63471559035449E-26 2.36279618331797E-26 -3.67241024039191E-09 - 1.23087544763445E-25 1.00974195868290E-27 -3.67241024033383E-09 - -1.00974195868290E-27 -7.57306469012171E-27 -3.67241024092811E-09 - -1.39243416102371E-25 -3.33214846365355E-26 -3.67241023687463E-09 - -3.11000523274332E-25 9.13816472608020E-26 -3.67241026083658E-09 - -9.13816472608020E-26 -1.78017507315794E-25 -3.67241012933954E-09 - 3.12010265233015E-26 -1.03498550764997E-25 -3.67241081869888E-09 - 4.79627430374375E-26 3.53409685539013E-26 -3.67240731517883E-09 - 1.11475512238592E-25 -6.57342015102565E-26 -3.67242472581844E-09 - -8.10822792822365E-26 5.56367819234275E-26 -3.67233966420491E-09 - 3.08981039356966E-26 3.06961555439600E-26 -3.67274972667956E-09 - -5.40211947895349E-26 -1.06325828249309E-25 -3.67079412118892E-09 - -4.03896783473158E-26 9.79449699922408E-26 -3.68003817324006E-09 - 4.89724849961204E-26 1.93870456067116E-26 -3.63667281930962E-09 - 6.09884143044469E-26 2.09016585447359E-26 -3.83893444180349E-09 - -2.09016585447359E-26 -5.69494464697153E-26 -2.90324120563540E-09 - 5.69494464697153E-26 -1.14605712310509E-25 -7.26494328943760E-09 - -1.08143363774938E-25 -2.05987359571311E-26 1.20013250860920E-08 - -4.28130590481548E-26 -8.32835167521652E-25 -1.22383101138835E-06 - 8.32835167521652E-25 7.27014210251684E-24 -8.29640894066741E-06 - 6.48819792971281E-24 2.14032983498096E-23 -1.53829689953952E-05 - 1.76292868050364E-23 4.32977351883225E-23 -1.92533983599839E-05 - 9.97528119950667E-23 -1.76034374108941E-23 -2.08622916601194E-05 - 1.75775880167518E-23 -2.58493941422821E-24 -2.14340684376363E-05 - 6.56316117272543E-23 4.00665609205373E-24 -2.16101573362036E-05 - 2.32644547280539E-24 3.13294657004459E-23 -2.16507499071785E-05 - 2.52677827740808E-23 1.00941884125612E-23 -2.16540105355530E-05 - 8.46567658159739E-24 - 1 -1 6 8 - SCALAIRE - -22 323455 1 0 0 0 -71 0 2 - - - 323443 - FLUX - REAL*8 - 1 301 0 0 - 1.07234596012123E-25 -3.67241024039310E-09 1.06830699228650E-25 - 3.67241024039376E-09 6.58351757061248E-26 -3.67241024039340E-09 - -6.58351757061248E-26 -1.49441809885068E-26 -3.67241024039320E-09 - 1.49441809885068E-26 -2.21941282518500E-25 -3.67241024039321E-09 - -1.55904158420639E-25 4.05916267390524E-26 -3.67241024039343E-09 - -4.05916267390524E-26 1.12485254197275E-25 -3.67241024039364E-09 - -4.06118215782260E-25 -1.89023694665438E-25 -3.67241024039342E-09 - -1.04407318527811E-25 1.17130067207216E-26 -3.67241024039333E-09 - -1.24198260917996E-25 -2.41934173300422E-25 -3.67241024039309E-09 - -3.45331749869550E-25 -1.74685358852141E-25 -3.67241024039344E-09 - -2.12449708106881E-25 -1.21774880217157E-25 -3.67241024039351E-09 - -1.71656132976092E-25 2.40924431341739E-25 -3.67241024039311E-09 - -4.42266977903108E-26 -4.46305945737840E-26 -3.67241024039350E-09 - -5.37182722019300E-26 1.15716428465060E-25 -3.67241024039363E-09 - -1.15716428465060E-25 -1.11071615455118E-26 -3.67241024039321E-09 - -1.91850972149750E-25 5.73533432531884E-26 -3.67241024039352E-09 - -5.75552916449250E-26 3.93799363886329E-26 -3.67241024039277E-09 - -3.93799363886329E-26 -3.06961555439600E-26 -3.67241024039289E-09 - -1.56711951987585E-25 1.55702210028902E-25 -3.67241024039335E-09 - -1.55904158420639E-25 2.61725115690606E-25 -3.67241024039307E-09 - 2.50416005753358E-25 2.77679038637796E-25 -3.67241024039326E-09 - -1.66809371574414E-25 -3.66940227785364E-25 -3.67241024039340E-09 - -2.20123746992871E-25 4.26111106564182E-26 -3.67241024039374E-09 - 2.51021850928568E-25 2.07602946705203E-25 -3.67241024039317E-09 - 8.58280664880461E-26 -1.51259345410698E-25 -3.67241024039295E-09 - -3.18674562160322E-25 7.24994726334319E-26 -3.67241024039345E-09 - 1.02387834610446E-25 9.65313312500848E-26 -3.67241024039340E-09 - 2.36279618331797E-26 9.30982085905629E-26 -3.67241024039330E-09 - 2.50819902536831E-25 -1.33689835329615E-25 -3.67241024039326E-09 - 1.02993679785655E-26 -3.38869401333980E-25 -3.67241024039326E-09 - -5.42231431812715E-25 -7.49228533342708E-26 -3.67241024039296E-09 - -1.77714584728190E-25 1.11879409022065E-25 -3.67241024039331E-09 - -2.77679038637796E-25 -1.65193784440522E-25 -3.67241024039352E-09 - -2.57888096247611E-25 -7.87598727772658E-27 -3.67241024039383E-09 - 1.70444442625673E-25 6.78546596234906E-26 -3.67241024039311E-09 - -6.78546596234906E-26 4.78617688415692E-26 -3.67241024039295E-09 - -4.80637172333058E-26 -2.54656921979826E-25 -3.67241024039327E-09 - -1.74685358852141E-25 2.82929696822947E-25 -3.67241024039324E-09 - 1.47624274359439E-25 -2.71216690102226E-25 -3.67241024039328E-09 - -1.77108739552980E-25 1.66001578007468E-25 -3.67241024039350E-09 - 1.27631383577518E-25 1.44191151699917E-25 -3.67241024039306E-09 - 1.49239861493332E-25 9.49157441161921E-26 -3.67241024039312E-09 - 1.98717217468794E-25 -1.08042389579070E-25 -3.67241024039306E-09 - -3.69565556877940E-26 -6.05845175209737E-28 -3.67241024039362E-09 - 6.05845175209737E-28 7.13887564788807E-26 -3.67241024039357E-09 - 7.66394146640317E-26 -2.39005921620241E-25 -3.67241024039337E-09 - -2.04169824045681E-25 -5.55358077275592E-26 -3.67241024039350E-09 - 6.42195885722321E-26 -1.29448919103147E-25 -3.67241024039350E-09 - -1.14100841331167E-26 -2.04573720829155E-25 -3.67241024039329E-09 - -8.89582665599631E-26 8.18900728491828E-26 -3.67241024039368E-09 - 1.93668507675379E-25 -2.31533831125988E-25 -3.67241024039328E-09 - 7.42160339631928E-26 8.02744857152902E-26 -3.67241024039314E-09 - -8.03754599111585E-26 -1.97404552922506E-25 -3.67241024039338E-09 - 6.41186143763638E-26 9.01699569103825E-26 -3.67241024039314E-09 - 2.03463004674603E-25 -5.28095044391154E-26 -3.67241024039349E-09 - 1.92860714108433E-26 -1.71656132976092E-25 -3.67241024039282E-09 - -2.50416005753358E-25 2.00635727190291E-25 -3.67241024039375E-09 - 9.29972343946946E-26 -1.65698655419863E-25 -3.67241024039359E-09 - 1.65698655419863E-25 4.03896783473158E-28 -3.67241024039306E-09 - 1.69232752275253E-25 -3.78653234506086E-26 -3.67241024039347E-09 - -1.33386912742010E-25 3.24127168737209E-26 -3.67241024039315E-09 - 2.61119270515397E-25 -1.61962610172736E-25 -3.67241024039340E-09 - -1.31670351412250E-25 9.13816472608020E-26 -3.67241024039297E-09 - 2.62532909257553E-26 1.43383358132971E-25 -3.67241024039338E-09 - 1.50249603452015E-25 9.52186667037970E-26 -3.67241024039340E-09 - 1.98212346489452E-25 -3.83701944299500E-26 -3.67241024039306E-09 - 3.83701944299500E-26 -1.10263821888172E-25 -3.67241024039353E-09 - -3.65425614847340E-25 2.42338070083895E-27 -3.67241024039304E-09 - 1.07537518599728E-25 -3.19886252510741E-25 -3.67241024039429E-09 - -2.67278696463362E-25 2.20527643776344E-25 -3.67241024038884E-09 - 1.79734068645555E-25 -3.35840175457931E-25 -3.67241024041174E-09 - -1.46109661421415E-25 -1.29953790082489E-25 -3.67241024031090E-09 - -1.63578197306629E-25 -1.61558713389263E-27 -3.67241024075875E-09 - 2.37693257073954E-25 2.76669296679113E-26 -3.67241023877604E-09 - 1.19048576928713E-25 4.87705366043838E-26 -3.67241024754211E-09 - 1.45806738833810E-25 -5.65455496862421E-26 -3.67241020882449E-09 - 5.65455496862421E-26 -1.30357686865962E-25 -3.67241037967676E-09 - -1.63174300523156E-25 4.24091622646816E-26 -3.67240962639660E-09 - 1.04306344331943E-25 -2.61523167298870E-26 -3.67241294477900E-09 - -2.13459450065564E-25 1.11071615455118E-27 -3.67239833845266E-09 - -9.22904150236166E-26 1.78017507315794E-25 -3.67246257907850E-09 - 2.05280540200233E-25 -1.58731435904951E-25 -3.67218025945504E-09 - -1.75695100810824E-26 -1.02286860414577E-25 -3.67342003876045E-09 - -1.80743810604238E-26 -1.71454184584356E-25 -3.66797977224315E-09 - -4.15609790193880E-25 2.62532909257553E-26 -3.69183616047043E-09 - 5.72523690573202E-26 4.17023428936036E-26 -3.58732216990726E-09 - 2.30221166579700E-26 -4.74578720580961E-26 -4.04535763371071E-09 - -1.79936017037292E-25 -1.14403763918772E-25 -2.04852851387296E-09 - -9.84498409715823E-26 1.54086622895010E-25 -1.09323357115035E-08 - 1.48230119534649E-25 4.18538041874060E-26 2.57837085903936E-08 - -4.18033170894719E-26 1.14908634898113E-25 -4.43951352575007E-07 - -1.14706686506377E-25 8.17487089749672E-25 -5.91945509373330E-06 - -2.45569244351680E-24 1.59749255799303E-23 -1.31189825371438E-05 - 1.15417544845290E-23 -3.12260681238768E-23 -1.74735215059716E-05 - -7.66434536318665E-23 -6.20902447297616E-23 -1.94715448771937E-05 - -3.20790981305721E-23 -3.85155972720004E-24 -2.02675213940120E-05 - -4.02992054678178E-23 -7.52217369540410E-23 -2.05577972547547E-05 - -9.07572228335525E-23 3.49742302745077E-23 -2.06512160672106E-05 - 3.94720248552648E-23 1.16322273640270E-23 -2.06736310268074E-05 - 2.45052256468834E-23 -5.79349546213898E-24 -2.06754791963205E-05 - -9.63213049226787E-24 - 1 -1 6 8 - SCALAIRE - -22 323275 1 0 0 0 -72 0 2 - - - 323245 - FLUX - REAL*8 - 1 301 0 0 - -3.91174034793754E-25 -3.67241024039265E-09 -5.69292516305416E-25 - 3.67241024039396E-09 1.72060029759565E-25 -3.67241024039275E-09 - -1.71858081367829E-25 3.91375983185490E-25 -3.67241024039320E-09 - 4.06320164173997E-25 -2.21941282518500E-25 -3.67241024039277E-09 - -1.55904158420639E-25 -6.34117950052858E-26 -3.67241024039276E-09 - -5.23854128164686E-25 1.12485254197275E-25 -3.67241024039311E-09 - 2.68591361009650E-25 -8.68378084467290E-26 -3.67241024039398E-09 - -9.12806730649337E-26 1.06224854053441E-25 -3.67241024039364E-09 - 2.77880987029533E-25 -1.40959977432132E-25 -3.67241024039319E-09 - -1.52471035761117E-25 -7.91637695607390E-26 -3.67241024039331E-09 - -3.08173245790020E-25 2.64552393174919E-25 -3.67241024039265E-09 - 2.19921798601135E-25 -2.48800418619465E-25 -3.67241024039398E-09 - -3.38263556158770E-25 -1.41969719390815E-25 -3.67241024039318E-09 - -3.46745388611706E-25 4.11368873967411E-25 -3.67241024039322E-09 - 3.75624008630037E-25 -1.99525011035740E-25 -3.67241024039312E-09 - -9.41079505492458E-26 6.01806207375005E-26 -3.67241024039288E-09 - -2.50416005753358E-25 3.22915478386790E-25 -3.67241024039350E-09 - 5.49299625523495E-26 -1.20361241475001E-25 -3.67241024039268E-09 - -6.70468660565442E-26 5.29104786349837E-26 -3.67241024039306E-09 - 5.33951547751515E-25 1.41161925823869E-25 -3.67241024039322E-09 - -4.34592939017118E-25 -1.26621641618835E-25 -3.67241024039384E-09 - -1.66809371574414E-25 -2.83737490389894E-25 -3.67241024039308E-09 - -1.91043178582804E-25 2.46377037918626E-25 -3.67241024039302E-09 - 1.60952868214053E-25 -7.71442856433732E-26 -3.67241024039304E-09 - -3.83701944299500E-26 -2.58897838206294E-25 -3.67241024039316E-09 - -3.49370717704282E-26 -1.90033436624121E-25 -3.67241024039352E-09 - -2.78486832204742E-25 -1.96899681943165E-25 -3.67241024039283E-09 - -9.65313312500848E-26 -2.74447864370011E-25 -3.67241024039320E-09 - -1.40758029040396E-25 1.47220377575966E-25 -3.67241024039302E-09 - -1.47220377575966E-25 -3.38869401333980E-25 -3.67241024039347E-09 - -5.42231431812715E-25 -8.90592407558313E-26 -3.67241024039303E-09 - -4.57211158891615E-25 -1.81551604171185E-25 -3.67241024039341E-09 - -1.49845706668542E-25 -1.49441809885068E-25 -3.67241024039335E-09 - -1.44191151699917E-25 -3.34426536715775E-25 -3.67241024039367E-09 - -3.83499995907764E-25 6.78546596234906E-26 -3.67241024039366E-09 - -6.78546596234906E-26 9.14826214566703E-26 -3.67241024039365E-09 - 3.61487621208476E-25 1.99928907819213E-26 -3.67241024039339E-09 - -1.55702210028902E-25 3.02720639213132E-25 -3.67241024039358E-09 - 2.65158238350128E-25 -1.16322273640270E-25 -3.67241024039306E-09 - -2.24162714827603E-26 8.94631375393045E-26 -3.67241024039328E-09 - 5.08909947176179E-26 -5.14968398928277E-26 -3.67241024039328E-09 - -1.00368350693080E-25 -4.84676140167790E-26 -3.67241024039367E-09 - -9.47137957244556E-26 -1.35103474071771E-25 -3.67241024039365E-09 - -1.58327539121478E-25 9.73391248170311E-26 -3.67241024039351E-09 - -9.71371764252945E-26 -1.49441809885068E-25 -3.67241024039361E-09 - 3.83701944299500E-27 -8.94631375393045E-26 -3.67241024039331E-09 - -5.45260657688763E-26 1.13595970351826E-25 -3.67241024039354E-09 - 3.75624008630037E-26 -1.29448919103147E-25 -3.67241024039329E-09 - -1.14100841331167E-26 1.92860714108433E-26 -3.67241024039319E-09 - -1.93870456067116E-26 8.18900728491828E-26 -3.67241024039346E-09 - 1.93668507675379E-25 -6.05845175209737E-27 -3.67241024039326E-09 - 1.42373616174288E-25 -1.15413505877455E-25 -3.67241024039339E-09 - 1.15312531681587E-25 -1.97404552922506E-25 -3.67241024039338E-09 - 6.41186143763638E-26 9.01699569103825E-26 -3.67241024039336E-09 - 2.03463004674603E-25 2.08612688663886E-25 -3.67241024039361E-09 - -4.51354655531254E-26 1.21875854413025E-25 -3.67241024039308E-09 - 1.71656132976092E-25 1.37223932185005E-25 -3.67241024039319E-09 - 1.56510003595849E-25 -4.02887041514475E-26 -3.67241024039329E-09 - 4.03896783473158E-26 3.65526589043208E-26 -3.67241024039351E-09 - 4.26817925935260E-25 1.21068060846079E-25 -3.67241024039338E-09 - 1.21169035041947E-27 1.53076880936327E-25 -3.67241024039297E-09 - -3.23117426778526E-26 -4.44286461820474E-27 -3.67241024039295E-09 - 1.23592415742786E-25 1.30458661061830E-25 -3.67241024039308E-09 - -1.29246970711411E-26 -2.48093599248387E-25 -3.67241024039327E-09 - -1.61558713389263E-25 -2.96258290677561E-25 -3.67241024039328E-09 - -2.90906658296542E-25 -2.19013030838320E-25 -3.67241024039339E-09 - -7.45189565507977E-26 -1.94476301242326E-25 -3.67241024039308E-09 - 1.24198260917996E-26 4.53374139448620E-26 -3.67241024039425E-09 - -1.19048576928713E-25 3.82692202340817E-26 -3.67241024038944E-09 - 2.55262767155036E-25 1.75998023398429E-25 -3.67241024041189E-09 - 3.74614266671354E-26 -4.95783301713301E-26 -3.67241024031195E-09 - -1.38738545123030E-25 1.38334648339557E-26 -3.67241024074168E-09 - -2.21234463147422E-25 -4.62461817076766E-26 -3.67241023889439E-09 - 1.93163636696038E-25 2.36279618331797E-26 -3.67241024683450E-09 - -7.79520792103195E-26 1.00974195868290E-27 -3.67241021273262E-09 - 1.93567533479511E-25 -5.67474980779787E-26 -3.67241035907448E-09 - -2.36885463507007E-25 6.44215369639687E-26 -3.67240973161857E-09 - -1.66203526399205E-25 -4.74578720580961E-27 -3.67241241950008E-09 - -4.76598204498326E-26 7.16916790664856E-26 -3.67240091578795E-09 - 2.21840308322632E-25 1.00974195868290E-27 -3.67245010328658E-09 - -1.47725248555308E-25 -7.06819371078027E-26 -3.67223999333808E-09 - -4.35198784192328E-26 -5.60406787069007E-26 -3.67313659561857E-09 - -1.20260267279133E-25 9.89547119509237E-26 -3.66931456831474E-09 - 1.34396654700693E-25 -3.74614266671354E-26 -3.68558986379105E-09 - -1.71050287800882E-25 -6.50273821391784E-26 -3.61637372058597E-09 - -1.44897971070995E-25 -5.83630852118713E-26 -3.91057079186339E-09 - -2.36279618331797E-26 -2.19114005034188E-26 -2.66488595451117E-09 - -1.24299235113864E-25 -5.60406787069007E-26 -7.99200438801827E-09 - -1.71858081367829E-25 3.58458395332428E-26 1.38268645244581E-08 - -3.59468137291111E-26 1.70242494233936E-25 -1.06378433713651E-07 - -1.70242494233936E-25 -5.39444544006750E-24 -3.63018616491496E-06 - -3.69646336234634E-24 8.59492355230880E-25 -1.08242147884387E-05 - -4.32977351883225E-25 -1.61946454301397E-23 -1.57718481429636E-05 - -1.15934532728135E-23 1.90510034828619E-23 -1.82435119926449E-05 - 1.82496722644512E-23 6.69757802226530E-23 -1.93068569886447E-05 - 8.88702170611659E-23 -4.99927282711736E-23 -1.97331217072005E-05 - -5.78767934845697E-23 -3.71714287766017E-23 -1.98931622614145E-05 - -2.24889729037854E-23 5.14402943431414E-23 -1.99462274840331E-05 - 6.21419435180462E-23 -2.74003577908190E-24 -1.99592671714597E-05 - 2.75296047615305E-24 -5.96151652406381E-24 -1.99603584460771E-05 - 1.13091099372484E-25 - 1 -1 6 8 - SCALAIRE - -22 323095 1 0 0 0 -73 0 2 - - - 323083 - FLUX - REAL*8 - 1 301 0 0 - -1.06628750836914E-25 -3.67241024039288E-09 1.06628750836914E-25 - 3.67241024039353E-09 2.78082935421269E-25 -3.67241024039296E-09 - 5.21228799072110E-25 -1.05417060486494E-25 -3.67241024039340E-09 - 1.05215112094758E-25 7.83559759937927E-26 -3.67241024039277E-09 - -7.81540276020561E-26 -6.34117950052858E-26 -3.67241024039298E-09 - -1.44191151699917E-25 -7.79520792103195E-26 -3.67241024039311E-09 - -2.15276985591193E-25 1.09052131537753E-26 -3.67241024039298E-09 - -1.89023694665438E-25 -1.73069771718248E-25 -3.67241024039352E-09 - -2.11238017756462E-25 2.53041334845934E-25 -3.67241024039297E-09 - -5.16987882845642E-26 -2.72630328844382E-25 -3.67241024039340E-09 - -1.14504738114640E-25 -2.19517901817661E-25 -3.67241024039405E-09 - -7.37111629838513E-26 -1.49845706668542E-25 -3.67241024039342E-09 - -3.37253814200087E-25 2.48396521835992E-25 -3.67241024039254E-09 - 4.50344913572571E-26 2.15680882374666E-25 -3.67241024039333E-09 - -1.57519745554532E-26 -7.27014210251684E-27 -3.67241024039288E-09 - -9.41079505492458E-26 -3.77643492547403E-26 -3.67241024039332E-09 - 3.77643492547403E-26 3.93799363886329E-26 -3.67241024039320E-09 - -3.93799363886329E-26 -1.28439177144464E-25 -3.67241024039330E-09 - -6.45830956773580E-25 1.55702210028902E-25 -3.67241024039314E-09 - -1.55904158420639E-25 1.58327539121478E-25 -3.67241024039337E-09 - 6.03825691292371E-26 2.77679038637796E-25 -3.67241024039315E-09 - -1.66809371574414E-25 -1.92860714108433E-25 -3.67241024039309E-09 - 8.05774083028950E-26 -3.91779879968963E-26 -3.67241024039317E-09 - 3.32810949581882E-25 2.08006843488676E-26 -3.67241024039348E-09 - 2.72630328844382E-25 -5.52328851399544E-25 -3.67241024039310E-09 - -7.98503940926433E-25 -1.02589783002182E-25 -3.67241024039362E-09 - -1.59539229471897E-26 -1.96899681943165E-25 -3.67241024039359E-09 - -9.65313312500848E-26 1.89831488232384E-26 -3.67241024039326E-09 - -3.12616110408224E-25 -3.03730381171815E-25 -3.67241024039258E-09 - -2.83333593606420E-25 -1.42979461349498E-25 -3.67241024039301E-09 - -5.69090567913680E-25 1.06628750836914E-25 -3.67241024039308E-09 - -6.58351757061248E-26 -3.11000523274332E-26 -3.67241024039330E-09 - -9.69352280335579E-26 -1.49441809885068E-25 -3.67241024039309E-09 - -1.44191151699917E-25 -2.20123746992871E-25 -3.67241024039329E-09 - -2.04371772437418E-25 -1.45200893658600E-25 -3.67241024039355E-09 - -2.80910212905581E-25 -1.66001578007468E-25 -3.67241024039295E-09 - 3.17058975026429E-26 2.34664031197905E-25 -3.67241024039333E-09 - 5.10323585918335E-25 -1.08446286362543E-25 -3.67241024039309E-09 - -4.82656656250424E-26 -1.36921009597401E-25 -3.67241024039321E-09 - 1.36719061205664E-25 -5.08909947176179E-26 -3.67241024039339E-09 - -2.29817269796227E-25 6.84605047987003E-26 -3.67241024039329E-09 - 2.25172456786286E-25 -1.23592415742786E-25 -3.67241024039367E-09 - -1.95889939984482E-26 -8.44144277458900E-26 -3.67241024039350E-09 - 2.33048444064012E-25 9.73391248170311E-26 -3.67241024039335E-09 - -9.71371764252945E-26 2.42035147496290E-25 -3.67241024039338E-09 - 3.45129801477814E-25 -8.94631375393045E-26 -3.67241024039342E-09 - -5.45260657688763E-26 1.13595970351826E-25 -3.67241024039307E-09 - 3.75624008630037E-26 3.88750654092915E-26 -3.67241024039328E-09 - 2.54858870371563E-25 -1.34901525680035E-25 -3.67241024039315E-09 - -3.12818058799961E-25 8.18900728491828E-26 -3.67241024039368E-09 - 1.93668507675379E-25 -6.05845175209737E-27 -3.67241024039342E-09 - 6.05845175209737E-27 -1.15413505877455E-25 -3.67241024039328E-09 - 1.15312531681587E-25 -1.97404552922506E-25 -3.67241024039338E-09 - -9.62284086624799E-26 -1.05518034682363E-25 -3.67241024039358E-09 - 1.05619008878231E-25 2.08612688663886E-25 -3.67241024039372E-09 - -4.51354655531254E-26 -1.71656132976092E-25 -3.67241024039303E-09 - -2.50416005753358E-25 1.66203526399205E-25 -3.67241024039351E-09 - -3.92789621927646E-26 -5.14968398928277E-27 -3.67241024039352E-09 - 1.30458661061830E-25 2.64552393174919E-26 -3.67241024039318E-09 - -1.96192862572087E-25 -9.89547119509237E-26 -3.67241024039371E-09 - -2.32240650497066E-26 6.98741435408563E-26 -3.67241024039294E-09 - 1.02993679785655E-25 1.25208002876679E-26 -3.67241024039304E-09 - -1.31771325608118E-25 1.30458661061830E-25 -3.67241024039309E-09 - -1.28237228752728E-26 -9.22904150236166E-26 -3.67241024039328E-09 - 3.85721428216866E-25 5.46270399647446E-26 -3.67241024039307E-09 - 5.98776981498957E-26 -2.33250392455749E-26 -3.67241024039285E-09 - 2.33250392455749E-26 1.41161925823869E-25 -3.67241024039374E-09 - 1.52471035761117E-25 1.86095442985258E-25 -3.67241024039183E-09 - 2.17397443704427E-25 -5.35163238101934E-27 -3.67241024040013E-09 - 1.13696944547694E-25 2.20527643776344E-25 -3.67241024036626E-09 - 7.30043436127733E-26 2.43953657217787E-25 -3.67241024050241E-09 - 4.96793043671984E-26 1.11677460630328E-25 -3.67241023994561E-09 - 2.67985515834440E-25 1.47321351771834E-25 -3.67241024221549E-09 - -5.04870979341448E-28 -2.18205237271374E-25 -3.67241023300174E-09 - -2.22042256714369E-25 1.61558713389263E-27 -3.67241027023173E-09 - -1.48331093730517E-25 1.39647312885844E-25 -3.67241012057040E-09 - 2.03261056282867E-25 -1.29347944907279E-25 -3.67241071869039E-09 - -1.64285016677707E-25 1.89124668861306E-25 -3.67240834440596E-09 - 2.51122825124436E-25 -2.19315953425925E-25 -3.67241769497842E-09 - -1.67011319966151E-25 5.33143754184569E-26 -3.67238121542601E-09 - 2.32240650497066E-27 -6.66429692730711E-26 -3.67252191540260E-09 - -1.37324906380874E-25 -2.07703920901072E-25 -3.67198689341817E-09 - -1.15413505877455E-25 -1.34396654700693E-25 -3.67398479101008E-09 - -9.89547119509237E-26 -6.09884143044469E-26 -3.66670167477851E-09 - 3.76633750588720E-26 1.38637570927161E-25 -3.69237884649335E-09 - 9.17855440442752E-26 7.06819371078027E-28 -3.60631339505549E-09 - -7.06819371078027E-28 4.12984461101304E-26 -3.87214898067419E-09 - 2.54454973588090E-26 -1.81551604171185E-25 -3.18477037194116E-09 - -1.89528565644779E-25 3.16049233067746E-26 -4.27913275502452E-09 - 4.00867557597109E-26 -1.09698366391310E-24 -1.70308071332777E-06 - 1.09617587034615E-24 2.71418638493962E-24 -8.28937201405086E-06 - -2.71418638493962E-24 1.16968508493827E-23 -1.38170743729813E-05 - 2.93390623514902E-24 6.85008944770476E-24 -1.68883280063703E-05 - -4.89070537171978E-23 -1.25886549472914E-23 -1.83295843332460E-05 - 4.59343733908353E-23 -1.73449434694713E-23 -1.89586559438941E-05 - -2.79690444619492E-23 -2.66507253606929E-23 -1.92212312789595E-05 - 1.13220346343196E-23 -5.70754622661589E-23 -1.93239142361664E-05 - -6.95607196368812E-23 5.96604016803871E-23 -1.93590336395289E-05 - 6.54765153624006E-23 -1.88829824209371E-23 -1.93678253171371E-05 - -2.56296742920727E-23 -3.78047389330876E-24 -1.93685666714608E-05 - 1.61235595962485E-24 - 1 -1 6 8 - SCALAIRE - -22 322915 1 0 0 0 -74 0 2 - - - 322897 - FLUX - REAL*8 - 1 301 0 0 - -2.13459450065564E-25 -3.67241024039266E-09 -2.01948391736579E-28 - 3.67241024039396E-09 -2.92421271234566E-25 -3.67241024039341E-09 - -2.94642703543669E-25 1.95687991592745E-25 -3.67241024039320E-09 - 1.47422325967703E-26 7.81540276020561E-26 -3.67241024039341E-09 - 1.30862557845303E-25 -1.55298313245429E-25 -3.67241024039320E-09 - -2.24364663219339E-25 2.20527643776344E-25 -3.67241024039397E-09 - -2.20527643776344E-25 -1.80339913820765E-25 -3.67241024039343E-09 - -2.91411529275884E-25 -1.73069771718248E-25 -3.67241024039330E-09 - -2.11238017756462E-25 1.52471035761117E-25 -3.67241024039232E-09 - -1.52269087369381E-25 1.16928118815479E-25 -3.67241024039351E-09 - -1.16524222032006E-25 -2.19517901817661E-25 -3.67241024039351E-09 - -7.37111629838513E-26 -1.51057397018961E-25 -3.67241024039356E-09 - -1.42575564566025E-25 4.44690358603947E-25 -3.67241024039286E-09 - 2.40520534558266E-25 2.12449708106881E-25 -3.67241024039374E-09 - 8.11832534781048E-26 2.86160871090732E-25 -3.67241024039364E-09 - -1.95687991592745E-25 -1.40959977432132E-25 -3.67241024039321E-09 - 1.40556080648659E-25 1.30660609453567E-25 -3.67241024039320E-09 - 5.83630852118713E-26 6.70468660565442E-26 -3.67241024039298E-09 - -3.60679827641530E-25 -2.25576353569759E-25 -3.67241024039382E-09 - -2.53647180021143E-25 1.52471035761117E-25 -3.67241024039326E-09 - 4.34592939017118E-25 1.79734068645555E-25 -3.67241024039310E-09 - -6.90663499739100E-26 2.12853604890354E-25 -3.67241024039297E-09 - 8.05774083028950E-26 -3.91779879968963E-26 -3.67241024039299E-09 - 1.52874932544590E-25 3.14231697542117E-25 -3.67241024039315E-09 - 4.50950758747781E-25 -2.68389412617914E-25 -3.67241024039329E-09 - -3.18876510552058E-25 -1.49441809885068E-26 -3.67241024039308E-09 - 1.49441809885068E-26 -2.08006843488676E-25 -3.67241024039346E-09 - -8.56261180963095E-26 9.30982085905629E-26 -3.67241024039298E-09 - -2.14873088807720E-25 1.34497628896562E-25 -3.67241024039285E-09 - 1.58933384296688E-25 -1.15918376856796E-25 -3.67241024039356E-09 - 1.16120325248533E-25 1.06628750836914E-25 -3.67241024039304E-09 - -6.58351757061248E-26 -1.00974195868290E-27 -3.67241024039287E-09 - -2.92623219626303E-25 4.64481300994132E-26 -3.67241024039345E-09 - -4.62461817076766E-26 -2.20325695384608E-25 -3.67241024039339E-09 - -2.04371772437418E-25 2.46175089526890E-25 -3.67241024039312E-09 - -1.13696944547694E-25 -6.80566080152271E-26 -3.67241024039284E-09 - 2.02150340128316E-25 3.89760396051598E-26 -3.67241024039350E-09 - 3.90164292835071E-25 -1.08244337970806E-25 -3.67241024039341E-09 - 2.45367295959944E-25 -3.89760396051598E-26 -3.67241024039301E-09 - 5.51319109440861E-26 6.82585564069637E-26 -3.67241024039312E-09 - 3.78653234506086E-25 -5.14968398928277E-26 -3.67241024039313E-09 - -9.04728794979874E-26 1.17533963990689E-25 -3.67241024039322E-09 - 1.76098997594297E-25 1.11273563846855E-25 -3.67241024039307E-09 - 3.30993414056253E-25 -4.92754075837253E-26 -3.67241024039314E-09 - -3.90770138010280E-25 9.39060021575092E-26 -3.67241024039300E-09 - 1.99625985231608E-25 6.00796465416323E-26 -3.67241024039357E-09 - 2.38904947424373E-25 4.23081880688133E-26 -3.67241024039340E-09 - 1.08749208950148E-25 -1.56913900379322E-25 -3.67241024039339E-09 - -1.36618087009796E-25 4.74578720580961E-26 -3.67241024039271E-09 - 1.06729725032782E-25 3.35537252870326E-25 -3.67241024039339E-09 - 2.51728670299646E-25 3.23117426778526E-26 -3.67241024039325E-09 - -5.34153496143252E-26 1.04609266919548E-25 -3.67241024039339E-09 - -8.03754599111585E-26 -1.62164558564473E-25 -3.67241024039316E-09 - -1.31468403020513E-25 -7.57306469012171E-27 -3.67241024039347E-09 - 7.77501308185829E-27 -8.56261180963095E-26 -3.67241024039329E-09 - -7.78511050144512E-26 -1.04407318527811E-25 -3.67241024039331E-09 - -2.40318586166529E-26 -9.28962601988264E-26 -3.67241024039328E-09 - 9.28962601988264E-26 -1.73271720109985E-25 -3.67241024039328E-09 - 5.14968398928277E-27 -9.73391248170311E-26 -3.67241024039317E-09 - 2.67177722267494E-25 1.82157449346394E-25 -3.67241024039337E-09 - 2.33654289239222E-25 6.98741435408563E-26 -3.67241024039283E-09 - 1.02993679785655E-25 1.31569377216381E-25 -3.67241024039304E-09 - -1.31771325608118E-25 9.13816472608020E-26 -3.67241024039318E-09 - 2.62532909257553E-26 -2.66268954504679E-25 -3.67241024039327E-09 - -1.43383358132971E-25 -3.12818058799961E-25 -3.67241024039350E-09 - -2.74245915978274E-25 -1.62568455347946E-25 -3.67241024039328E-09 - -1.80743810604238E-26 -1.23794364134523E-25 -3.67241024039418E-09 - -2.81112161297318E-25 -9.59254860748750E-27 -3.67241024039017E-09 - -1.74079513676931E-25 -6.99751177367246E-26 -3.67241024040621E-09 - -2.23556869652393E-25 1.58529487513215E-26 -3.67241024033184E-09 - -1.59539229471897E-26 -2.00029882015082E-25 -3.67241024067214E-09 - -3.87034092763154E-25 6.56332273143882E-26 -3.67241023912656E-09 - 1.24198260917996E-25 4.72559236663595E-26 -3.67241024612763E-09 - -2.52435489670724E-27 2.49406263794675E-26 -3.67241021451625E-09 - -1.25510925464284E-25 1.48936938905727E-25 -3.67241035681707E-09 - -9.76420474046360E-26 -5.64445754903738E-26 -3.67240971801033E-09 - -1.39647312885844E-25 -8.13852018698413E-26 -3.67241257848886E-09 - -6.54312789226516E-26 -1.02690757198050E-25 -3.67239979925296E-09 - -1.90942204386935E-25 2.28201682662334E-26 -3.67245676938233E-09 - -2.28201682662334E-26 4.33179300274962E-26 -3.67220329428053E-09 - -4.33179300274962E-26 7.61345436846903E-26 -3.67332902047773E-09 - -1.33184964350274E-25 -7.16916790664856E-27 -3.66833799748444E-09 - -1.69131778079385E-25 9.34011311781678E-26 -3.69043237250492E-09 - 2.86665742070074E-25 -1.89831488232384E-26 -3.59278934569882E-09 - 8.05774083028950E-26 -1.24198260917996E-26 -4.02411894015268E-09 - 9.58245118790067E-26 -9.48147699203239E-26 -2.12899188816421E-09 - -1.15110583289850E-25 1.64587939265312E-26 -1.06040100329596E-08 - 6.39166659846273E-26 1.15766915562994E-25 2.47757728731998E-08 - 7.42160339631928E-26 -8.27988406119974E-25 -5.29319265901949E-07 - -4.76598204498326E-25 4.68520268828863E-24 -5.80759890841139E-06 - -4.68520268828863E-24 -1.77973078669612E-23 -1.19788991956802E-05 - -1.82625969615223E-23 4.03250548619601E-24 -1.56808927965243E-05 - -1.27179019180028E-23 -5.97121004686717E-24 -1.74868094137154E-05 - 5.99705944100945E-24 -7.33605805757966E-23 -1.83017529352925E-05 - -8.90253134260196E-23 3.48449833037963E-23 -1.86586083909881E-05 - 6.66138887046610E-23 -6.71825753757912E-23 -1.88103486194971E-05 - -1.33382873774176E-23 2.85635805272217E-23 -1.88711001879951E-05 - 3.75333202945936E-23 -5.87556728854072E-23 -1.88924337160956E-05 - -8.45275188452625E-23 -1.04431552334820E-23 -1.88979314879779E-05 - 1.04560799305531E-23 3.48320586067251E-24 -1.88984064073565E-05 - 6.46557970983831E-24 - 1 -1 6 8 - SCALAIRE - -22 322171 1 0 0 0 -75 0 2 - - - 322123 - FLUX - REAL*8 - 1 301 0 0 - -3.91174034793754E-25 -3.67241024039309E-09 -5.69292516305416E-25 - 3.67241024039374E-09 -9.69352280335579E-26 -3.67241024039296E-09 - -6.58351757061248E-26 9.04728794979874E-26 -3.67241024039342E-09 - -9.02709311062508E-26 -3.95818847803695E-26 -3.67241024039407E-09 - 3.97838331721061E-26 -6.34117950052858E-26 -3.67241024039342E-09 - -1.44191151699917E-25 -2.68591361009650E-25 -3.67241024039384E-09 - -1.12283305805538E-25 2.22143230910237E-27 -3.67241024039376E-09 - -2.22143230910237E-27 -1.76704842769507E-25 -3.67241024039343E-09 - -1.16928118815479E-25 -1.38334648339557E-25 -3.67241024039297E-09 - -4.60442333159400E-26 1.16928118815479E-25 -3.67241024039351E-09 - -1.16524222032006E-25 -2.19517901817661E-25 -3.67241024039383E-09 - -7.37111629838513E-26 4.35602680975801E-25 -3.67241024039353E-09 - 4.45094255387420E-25 1.51057397018961E-25 -3.67241024039329E-09 - 1.42373616174288E-25 1.16726170423743E-25 -3.67241024039375E-09 - -1.16726170423743E-25 -1.11071615455118E-26 -3.67241024039353E-09 - -1.91850972149750E-25 5.73533432531884E-26 -3.67241024039344E-09 - -3.50986304838174E-25 3.93799363886329E-26 -3.67241024039277E-09 - -3.93799363886329E-26 -3.06961555439600E-26 -3.67241024039289E-09 - -1.56711951987585E-25 -2.30625063363173E-25 -3.67241024039355E-09 - 1.52672984152854E-25 -3.75624008630037E-26 -3.67241024039332E-09 - -3.75624008630037E-26 1.66809371574414E-25 -3.67241024039348E-09 - 1.57519745554532E-26 -2.61927064082343E-25 -3.67241024039316E-09 - -2.12853604890354E-25 3.47351233786916E-26 -3.67241024039331E-09 - -3.28166136571941E-25 2.08006843488676E-26 -3.67241024039304E-09 - 2.72630328844382E-25 2.40116637774792E-25 -3.67241024039292E-09 - 1.70444442625673E-25 -2.87776458224625E-25 -3.67241024039308E-09 - -2.99287516553610E-25 -2.34260134414432E-26 -3.67241024039363E-09 - -3.90164292835071E-25 1.89831488232384E-26 -3.67241024039348E-09 - -3.12616110408224E-25 6.19981562631298E-26 -3.67241024039274E-09 - 1.08244337970806E-25 7.95676663442121E-26 -3.67241024039341E-09 - -7.97696147359487E-26 2.30221166579700E-26 -3.67241024039320E-09 - -1.49441809885068E-25 -1.00974195868290E-27 -3.67241024039287E-09 - -2.92623219626303E-25 -1.49441809885068E-25 -3.67241024039352E-09 - -1.44191151699917E-25 -8.92611891475679E-26 -3.67241024039339E-09 - -2.04371772437418E-25 1.65597681223995E-25 -3.67241024039377E-09 - 1.27833331969255E-25 -1.66001578007468E-25 -3.67241024039274E-09 - 3.17058975026429E-26 -1.75695100810824E-26 -3.67241024039323E-09 - 3.33416794757092E-25 -3.00903103687503E-26 -3.67241024039331E-09 - 3.00903103687503E-26 -1.57317797162795E-25 -3.67241024039322E-09 - 3.12010265233015E-25 2.63744599607972E-25 -3.67241024039328E-09 - 2.96864135852771E-26 2.42136121692158E-25 -3.67241024039317E-09 - 5.12948915010911E-26 9.49157441161921E-26 -3.67241024039375E-09 - 1.98919165860530E-25 -1.35103474071771E-25 -3.67241024039332E-09 - 1.35305422463508E-25 -6.05845175209737E-28 -3.67241024039318E-09 - 6.05845175209737E-28 1.69232752275253E-25 -3.67241024039342E-09 - 2.72327406256777E-25 -8.94631375393045E-26 -3.67241024039363E-09 - -5.45260657688763E-26 4.23081880688133E-26 -3.67241024039361E-09 - 1.08749208950148E-25 -5.90699045829494E-26 -3.67241024039349E-09 - -8.17890986533145E-26 1.17130067207216E-25 -3.67241024039264E-09 - 3.30690491468648E-25 1.29246970711411E-26 -3.67241024039329E-09 - 1.24804106093206E-25 -1.72060029759565E-25 -3.67241024039317E-09 - -1.21471957629552E-25 -1.74685358852141E-26 -3.67241024039314E-09 - 1.74685358852141E-26 -1.66102552203336E-25 -3.67241024039339E-09 - 3.29175878530624E-26 -4.12984461101304E-26 -3.67241024039371E-09 - -9.01699569103825E-26 -8.56261180963095E-26 -3.67241024039329E-09 - -7.78511050144512E-26 9.12806730649337E-26 -3.67241024039304E-09 - 7.39131113755879E-26 -1.90841230191067E-25 -3.67241024039362E-09 - 1.90841230191067E-25 -1.30357686865962E-25 -3.67241024039326E-09 - -1.20159293083265E-25 4.03896783473158E-28 -3.67241024039339E-09 - 1.69232752275253E-25 2.80203393534503E-25 -3.67241024039360E-09 - -3.54419427497696E-26 1.53076880936327E-25 -3.67241024039286E-09 - -3.23117426778526E-26 9.34011311781678E-26 -3.67241024039306E-09 - 2.57484199464138E-26 -6.52293305309150E-26 -3.67241024039321E-09 - 1.82864268717472E-25 1.43383358132971E-25 -3.67241024039316E-09 - 1.50249603452015E-25 -1.17130067207216E-25 -3.67241024039294E-09 - 2.62532909257553E-27 -2.34058186022695E-25 -3.67241024039429E-09 - -3.52904814559672E-25 1.41161925823869E-25 -3.67241024038932E-09 - -2.97873877811454E-26 -9.55215892914019E-26 -3.67241024041112E-09 - -3.81783434578003E-25 9.24923634153532E-26 -3.67241024031789E-09 - -9.23913892194849E-26 -2.85756974307259E-26 -3.67241024071875E-09 - -1.58226564925610E-25 -8.74436536219387E-26 -3.67241023898999E-09 - 4.34189042233645E-27 7.14897306747490E-26 -3.67241024642919E-09 - 1.18341757557635E-25 -4.62461817076766E-26 -3.67241021445703E-09 - 4.62461817076766E-26 2.22042256714369E-25 -3.67241035173176E-09 - 1.17735912382426E-25 -9.57235376831385E-26 -3.67240976292330E-09 - 2.01948391736579E-28 1.88720772077833E-25 -3.67241228591498E-09 - -9.00689827145142E-26 6.64410208813345E-26 -3.67240148630648E-09 - 8.03754599111585E-26 8.77465762095436E-26 -3.67244766498289E-09 - 6.46234853557053E-27 -2.61523167298870E-26 -3.67225042056438E-09 - -2.78688780596479E-26 -2.53546205825275E-25 -3.67309198072820E-09 - -1.51057397018961E-25 9.23913892194849E-26 -3.66950555093795E-09 - 5.44250915730080E-26 1.34901525680035E-25 -3.68477191885339E-09 - 1.58630461709083E-25 -4.25101364605499E-26 -3.61987798016023E-09 - 4.25101364605499E-26 -3.59468137291111E-26 -3.89554067850580E-09 - -1.10970641259250E-25 -5.98776981498957E-26 -2.72924382412303E-09 - 5.99786723457640E-26 -3.73604524712671E-26 -7.71363301018465E-09 - -2.60917322123660E-25 -5.96757497581591E-26 1.26613011808582E-08 - -1.59438255276029E-25 8.60300148797827E-26 -1.00650861534201E-07 - 7.06819371078027E-26 -3.95818847803695E-25 -3.37618415512387E-06 - -1.56227275847418E-24 -9.94555439624304E-24 -9.87864129022174E-06 - -6.17154285146985E-24 -3.19498511598607E-23 -1.43085331856003E-05 - -1.86115637824431E-23 1.69313531631948E-23 -1.66011565380491E-05 - -1.69055037690525E-23 -9.15844034461055E-23 -1.76706025932332E-05 - -1.58198292150767E-23 -5.54986492234797E-23 -1.81553546586637E-05 - 5.54727998293374E-23 4.34528315531762E-23 -1.83723150365528E-05 - 1.16580767581692E-23 -6.36153589841563E-23 -1.84669084631304E-05 - -2.48929665590177E-23 5.24742701088327E-24 -1.85056653765262E-05 - 8.34935430795712E-24 -8.40105309624169E-25 -1.85195466602756E-05 - -7.23783035983899E-25 -2.10801809230311E-23 -1.85231818848799E-05 - -1.29246970711411E-24 2.07247517535747E-23 -1.85234992186534E-05 - 1.91964063249123E-23 - 1 -1 6 8 - SCALAIRE - -22 321949 1 0 0 0 -76 0 2 - - - 321937 - FLUX - REAL*8 - 1 301 0 0 - -8.86553439723582E-26 -3.67241024039332E-09 8.86553439723582E-26 - 3.67241024039397E-09 3.67748021352310E-25 -3.67241024039297E-09 - 2.19517901817661E-25 2.86160871090732E-25 -3.67241024039319E-09 - 3.01105052079239E-25 7.81540276020561E-26 -3.67241024039320E-09 - 1.30862557845303E-25 -1.55298313245429E-25 -3.67241024039320E-09 - -2.24364663219339E-25 1.45402842050337E-26 -3.67241024039342E-09 - 3.66536331001891E-25 3.04538174738761E-25 -3.67241024039299E-09 - 1.04407318527811E-25 -7.87598727772658E-26 -3.67241024039354E-09 - 1.69232752275253E-25 4.88715108002521E-26 -3.67241024039309E-09 - -3.42504472385238E-25 -1.74685358852141E-25 -3.67241024039333E-09 - -2.12449708106881E-25 -1.21774880217157E-25 -3.67241024039329E-09 - -1.71656132976092E-25 4.56403365324669E-26 -3.67241024039321E-09 - 1.50855448627225E-25 5.35163238101934E-26 -3.67241024039329E-09 - -3.47149285395179E-25 -2.73640070803065E-25 -3.67241024039372E-09 - -3.13423903975171E-25 -9.08767762814606E-27 -3.67241024039320E-09 - -1.93668507675379E-25 3.53611633930750E-25 -3.67241024039329E-09 - 2.33452340847485E-25 3.33012897973619E-25 -3.67241024039254E-09 - 6.50273821391784E-26 -1.28439177144464E-25 -3.67241024039243E-09 - -6.45830956773580E-25 6.78546596234906E-26 -3.67241024039365E-09 - 3.99857815638426E-26 -2.44761450784734E-25 -3.67241024039266E-09 - -2.33250392455749E-25 -1.26621641618835E-25 -3.67241024039353E-09 - -4.60644281551137E-25 -2.61725115690606E-25 -3.67241024039361E-09 - -1.00368350693080E-25 -3.48764872529072E-25 -3.67241024039364E-09 - -5.89689303870811E-26 -7.69423372516366E-26 -3.67241024039319E-09 - -2.16488675941613E-25 4.44286461820474E-26 -3.67241024039303E-09 - -2.20931540559817E-25 7.24994726334319E-26 -3.67241024039334E-09 - 1.02387834610446E-25 1.07638492795597E-25 -3.67241024039341E-09 - -1.60952868214053E-25 9.30982085905629E-26 -3.67241024039314E-09 - -4.28130590481548E-26 -1.33487886937879E-25 -3.67241024039334E-09 - -1.59943126255371E-25 -1.42979461349498E-25 -3.67241024039352E-09 - 1.81753552562921E-26 3.71585040795305E-26 -3.67241024039290E-09 - 2.56070560721982E-25 -9.89547119509237E-26 -3.67241024039347E-09 - -2.32644547280539E-25 -8.30007890037340E-26 -3.67241024039304E-09 - -4.69328062395810E-25 -3.01307000470976E-25 -3.67241024039361E-09 - -2.85756974307259E-25 -1.45200893658600E-25 -3.67241024039333E-09 - 1.25208002876679E-26 2.96864135852771E-26 -3.67241024039274E-09 - 1.29650867494884E-25 2.15680882374666E-25 -3.67241024039355E-09 - 7.77501308185829E-26 -2.25778301961495E-25 -3.67241024039326E-09 - -5.17795676412589E-25 -3.89760396051598E-26 -3.67241024039323E-09 - 5.51319109440861E-26 2.21537385735027E-25 -3.67241024039329E-09 - 3.78451286114349E-25 2.46377037918626E-26 -3.67241024039339E-09 - -1.66203526399205E-25 1.95889939984482E-26 -3.67241024039349E-09 - 2.73842019194801E-25 8.78475504054119E-26 -3.67241024039350E-09 - 6.09884143044469E-26 -9.83488667757140E-26 -3.67241024039333E-09 - -1.95082146417535E-25 1.69232752275253E-25 -3.67241024039332E-09 - 2.72327406256777E-25 -1.15312531681587E-25 -3.67241024039320E-09 - -1.78219455707531E-25 2.82525800039474E-25 -3.67241024039280E-09 - 4.46911790913049E-25 6.61380982937296E-26 -3.67241024039350E-09 - 2.27292914899520E-25 1.58630461709083E-25 -3.67241024039290E-09 - -1.58630461709083E-25 -1.13797918743562E-25 -3.67241024039343E-09 - 9.59254860748750E-26 6.19981562631298E-26 -3.67241024039317E-09 - -6.19981562631298E-26 1.41262900019737E-25 -3.67241024039292E-09 - 1.52269087369381E-25 -1.93365585087774E-25 -3.67241024039327E-09 - -1.00065428105475E-25 -7.67403888599000E-27 -3.67241024039350E-09 - 7.67403888599000E-27 -8.56261180963095E-26 -3.67241024039318E-09 - -7.78511050144512E-26 1.86196417181126E-25 -3.67241024039283E-09 - 2.35976695744193E-25 3.92789621927646E-26 -3.67241024039339E-09 - 8.76456020136753E-26 -5.14968398928277E-27 -3.67241024039330E-09 - 1.30458661061830E-25 9.83488667757140E-26 -3.67241024039306E-09 - 7.14897306747490E-26 -1.35305422463508E-26 -3.67241024039349E-09 - -1.57822668142137E-25 -5.14968398928277E-27 -3.67241024039329E-09 - 5.25065818515105E-27 -4.71549494704912E-26 -3.67241024039315E-09 - 2.21537385735027E-25 -1.23996312526260E-25 -3.67241024039374E-09 - -5.19007366763008E-26 -2.08309766076281E-25 -3.67241024039317E-09 - -2.01241572365501E-25 1.11879409022065E-25 -3.67241024039319E-09 - 2.52435489670724E-27 1.16019351052665E-25 -3.67241024039184E-09 - 3.58357421136559E-25 -1.10263821888172E-25 -3.67241024039837E-09 - -1.83369139696814E-25 3.33214846365355E-26 -3.67241024037210E-09 - 2.60311476948450E-25 1.25712873856020E-25 -3.67241024047737E-09 - 1.67920087728965E-25 -1.35305422463508E-25 -3.67241024005577E-09 - -1.58226564925610E-25 4.82656656250424E-26 -3.67241024173497E-09 - 2.45367295959944E-25 6.57342015102565E-26 -3.67241023510011E-09 - 1.24097286722128E-25 -5.04870979341448E-26 -3.67241026106876E-09 - -2.42943915259105E-25 -2.39308844207846E-26 -3.67241016058758E-09 - 7.01770661284612E-26 -4.79627430374375E-26 -3.67241054388886E-09 - -5.10929431093545E-26 9.01699569103825E-26 -3.67240910812809E-09 - 1.54086622895010E-25 -8.04764341070267E-26 -3.67241435744275E-09 - -2.13257501673827E-25 -5.72523690573202E-26 -3.67239580438676E-09 - -8.95641117351728E-26 -7.76491566227146E-26 -3.67245812754514E-09 - -1.23188518959313E-25 -1.42474590370157E-25 -3.67226587249112E-09 - -4.24091622646816E-27 -1.15514480073323E-25 -3.67276429984079E-09 - -8.83524213847533E-26 -6.08874401085786E-26 -3.67204256148415E-09 - 3.14029749150380E-26 -9.66323054459531E-26 -3.66899800156275E-09 - -5.00832011506716E-26 -3.73604524712671E-26 -3.70867363661401E-09 - -2.44357554001261E-26 2.43347812042578E-26 -3.42374203898481E-09 - -1.50552526039620E-25 8.98670343227777E-26 -5.15252803383940E-09 - 1.23188518959313E-25 -2.26182198744969E-26 4.20938191100619E-09 - 2.26182198744969E-26 5.17795676412589E-25 -1.41564736595331E-06 - 1.46372194330672E-24 5.53823269498394E-24 -7.51502709705433E-06 - 4.07127957740943E-25 -1.34546096510578E-23 -1.27022004617453E-05 - -3.86448442427118E-23 3.28545799548406E-23 -1.56051647397627E-05 - 6.04875822929401E-24 -7.97195315347980E-23 -1.70132529917506E-05 - -8.52771512753887E-23 3.98597657673990E-23 -1.76701491577021E-05 - 5.99964438042368E-23 -9.59012522678666E-24 -1.79744532224153E-05 - -4.53139879314205E-23 -3.83088021188621E-23 -1.81142387519693E-05 - -3.47157363330849E-23 -1.85857143883008E-23 -1.81766611461520E-05 - 5.37667398159468E-23 1.98523347012727E-23 -1.82027577838721E-05 - 5.02253728184541E-23 -3.19627758569318E-23 -1.82122577438387E-05 - -6.07073021431495E-23 -2.28637891188485E-23 -1.82147769293799E-05 - -4.89846018996246E-24 4.95015897824702E-24 -1.82149985647079E-05 - 5.05355655481615E-24 - 1 -1 6 8 - SCALAIRE - -22 321727 1 0 0 0 -77 0 2 - - - 321715 - FLUX - REAL*8 - 1 301 0 0 - 8.90592407558313E-26 -3.67241024039331E-09 1.24602157701469E-25 - 3.67241024039331E-09 -1.13494996155957E-25 -3.67241024039296E-09 - 1.13494996155957E-25 -1.20361241475001E-25 -3.67241024039364E-09 - -9.02709311062508E-26 -1.30862557845303E-25 -3.67241024039299E-09 - -7.81540276020561E-26 -5.14968398928277E-26 -3.67241024039276E-09 - -3.27964188180204E-25 -2.63340702824499E-25 -3.67241024039354E-09 - 8.84533955806216E-26 -2.22143230910237E-27 -3.67241024039331E-09 - 9.12806730649337E-26 -7.87598727772658E-26 -3.67241024039311E-09 - 1.69232752275253E-25 -2.36077669940061E-25 -3.67241024039331E-09 - -2.41732224908685E-25 2.16488675941613E-25 -3.67241024039355E-09 - 2.76871245070850E-25 -2.76669296679113E-26 -3.67241024039353E-09 - -3.68555814919257E-25 -1.50855448627225E-25 -3.67241024039366E-09 - 5.41221689854032E-26 5.29104786349837E-26 -3.67241024039285E-09 - 1.42373616174288E-25 1.87812004315018E-26 -3.67241024039318E-09 - -2.12449708106881E-25 9.04728794979874E-26 -3.67241024039353E-09 - -1.92052920541487E-25 1.55500261637166E-25 -3.67241024039310E-09 - -1.55298313245429E-25 2.25172456786286E-25 -3.67241024039307E-09 - 2.57282251072402E-25 6.70468660565442E-26 -3.67241024039266E-09 - -3.60679827641530E-25 -2.35673773156588E-25 -3.67241024039346E-09 - -2.43953657217787E-25 -3.75624008630037E-26 -3.67241024039375E-09 - -3.75624008630037E-26 -1.59539229471897E-26 -3.67241024039342E-09 - -4.60442333159400E-25 9.89547119509237E-27 -3.67241024039329E-09 - -1.91245126974540E-25 -1.44998945266864E-25 -3.67241024039316E-09 - -3.28368084963677E-25 -1.66001578007468E-25 -3.67241024039372E-09 - 1.66203526399205E-25 -3.46947337003443E-25 -3.67241024039328E-09 - -7.10252493737548E-25 -1.90235385015857E-25 -3.67241024039311E-09 - 4.83464449817370E-25 9.65313312500848E-26 -3.67241024039308E-09 - 2.36279618331797E-26 -2.12247759715145E-25 -3.67241024039320E-09 - -3.24531065520682E-25 -1.46210635617283E-25 -3.67241024039334E-09 - -1.47220377575966E-25 -4.50344913572571E-26 -3.67241024039369E-09 - 3.38465504550506E-25 -8.90592407558313E-26 -3.67241024039325E-09 - -1.63780145698366E-25 -6.86624531904369E-26 -3.67241024039313E-09 - 3.24329117128946E-25 -1.64991836048785E-25 -3.67241024039352E-09 - -2.57888096247611E-25 -1.05820957269967E-25 -3.67241024039324E-09 - -1.87812004315018E-25 -2.77679038637796E-25 -3.67241024039289E-09 - -4.42065029511371E-25 -1.65799629615731E-25 -3.67241024039360E-09 - -2.87170613049415E-25 1.99928907819213E-26 -3.67241024039339E-09 - -1.55702210028902E-25 3.02720639213132E-25 -3.67241024039358E-09 - 2.65158238350128E-25 9.99644539096066E-26 -3.67241024039306E-09 - 3.48764872529072E-25 4.70539752746229E-26 -3.67241024039306E-09 - 2.59503683381504E-25 -1.49441809885068E-25 -3.67241024039355E-09 - -1.44191151699917E-25 -4.84676140167790E-26 -3.67241024039307E-09 - -9.47137957244556E-26 -2.05785411179574E-25 -3.67241024039322E-09 - -3.81278563598661E-25 2.36279618331797E-26 -3.67241024039350E-09 - -1.70646391017409E-25 -1.49441809885068E-25 -3.67241024039332E-09 - 3.93799363886329E-27 8.38085825706803E-27 -3.67241024039331E-09 - 1.41161925823869E-25 4.24091622646816E-26 -3.67241024039343E-09 - 2.51223799320304E-25 -1.29549893299015E-25 -3.67241024039310E-09 - -1.64184042481839E-25 -6.52293305309150E-26 -3.67241024039323E-09 - 5.03861237382765E-26 4.19042912853401E-26 -3.67241024039340E-09 - -4.19042912853401E-26 -6.05845175209737E-27 -3.67241024039315E-09 - 1.42373616174288E-25 -1.21673906021289E-25 -3.67241024039347E-09 - -1.31266454628776E-26 6.49264079433102E-26 -3.67241024039305E-09 - -6.49264079433102E-26 2.44357554001261E-26 -3.67241024039314E-09 - 1.07133621816255E-25 -5.21026850680374E-26 -3.67241024039352E-09 - -7.79520792103195E-26 1.21875854413025E-25 -3.67241024039297E-09 - 1.71656132976092E-25 -2.94844651935405E-26 -3.67241024039341E-09 - -1.00974195868290E-26 -5.14968398928277E-27 -3.67241024039352E-09 - 1.30458661061830E-25 -1.59135332688424E-25 -3.67241024039304E-09 - -1.34295680504825E-25 3.55429169456379E-26 -3.67241024039306E-09 - -3.56438911415062E-26 1.07234596012123E-25 -3.67241024039261E-09 - 6.55322531185199E-26 1.31670351412250E-25 -3.67241024039304E-09 - 1.61962610172736E-25 3.26146652654575E-26 -3.67241024039353E-09 - -2.08612688663886E-25 -1.26217744835362E-26 -3.67241024039306E-09 - -1.03599524960865E-25 -8.38085825706803E-26 -3.67241024039416E-09 - 1.92860714108433E-26 1.80743810604238E-26 -3.67241024038976E-09 - -1.79734068645555E-26 -1.52370061565249E-25 -3.67241024040874E-09 - -3.23319375170263E-25 -6.45225111598370E-26 -3.67241024032398E-09 - -4.52364397489937E-26 -1.57418771358663E-25 -3.67241024070688E-09 - -2.78688780596479E-26 1.22683647979972E-25 -3.67241023898450E-09 - 1.70949313605014E-25 1.46210635617283E-25 -3.67241024670657E-09 - 4.22072138729450E-26 1.96899681943165E-26 -3.67241021216743E-09 - -1.96899681943165E-26 1.00469324888948E-25 -3.67241036629365E-09 - 4.62461817076766E-26 2.50416005753358E-26 -3.67240968006121E-09 - 2.12045811323408E-26 -9.80459441881091E-26 -3.67241272907087E-09 - -1.47725248555308E-25 1.39344390298240E-25 -3.67239920851796E-09 - 5.66465238821104E-26 -3.24127168737209E-26 -3.67245905333379E-09 - -1.14302789722904E-25 -5.72523690573202E-26 -3.67219463136957E-09 - 4.74578720580961E-27 -2.11036069364725E-26 -3.67336102911222E-09 - -7.16916790664856E-26 -5.12948915010911E-26 -3.66822412598072E-09 - -1.51057397018961E-25 8.83524213847533E-26 -3.69081425509343E-09 - 1.15514480073323E-25 -6.67439434689394E-26 -3.59163832889835E-09 - -7.99715631276853E-26 6.36137433970224E-26 -4.02685766887640E-09 - -3.33214846365355E-27 3.70575298836623E-26 -2.12758930404420E-09 - 4.80637172333058E-26 -1.26722615814703E-25 -1.05669531351905E-08 - -1.07537518599728E-25 -3.72594782753988E-26 2.44028666277002E-08 - -9.71371764252945E-26 1.43787254916444E-25 -3.55567622349283E-07 - -1.43787254916444E-25 -1.88054342385102E-24 -4.98138494292076E-06 - -1.70929118765840E-24 -2.36263462460459E-23 -1.08450822193204E-05 - -2.18039639590150E-23 -2.34970992753344E-23 -1.44560557198934E-05 - -7.23783035983899E-24 7.02586532787228E-23 -1.62947009153702E-05 - 1.39379933215185E-22 2.38848401874687E-23 -1.71758381229689E-05 - 5.04063185774501E-23 5.33531495096703E-23 -1.75941360872711E-05 - 1.04069660816828E-22 4.10488378979440E-23 -1.77928203206775E-05 - 7.12926290444141E-23 2.66248759665506E-23 -1.78863175128531E-05 - 3.51293266393614E-23 4.49262470192863E-23 -1.79289491078582E-05 - 2.22821777506472E-23 -4.90363006879092E-23 -1.79470832766236E-05 - -2.25665210862123E-23 -1.54320883029424E-23 -1.79537785986010E-05 - -4.03638289531735E-23 1.23301610058686E-23 -1.79555741694020E-05 - 7.14735748034100E-24 5.87750599310140E-24 -1.79557332960063E-05 - 1.12541799746961E-23 - 1 -1 6 8 - SCALAIRE - -22 321541 1 0 0 0 -78 0 2 - - - 321511 - FLUX - REAL*8 - 1 301 0 0 - -3.91174034793754E-25 -3.67241024039354E-09 1.77714584728190E-26 - 3.67241024039354E-09 -2.38299102249163E-26 -3.67241024039318E-09 - 2.38299102249163E-26 1.95687991592745E-25 -3.67241024039298E-09 - 1.47422325967703E-26 -3.97838331721061E-26 -3.67241024039320E-09 - 3.97838331721061E-26 -5.14968398928277E-26 -3.67241024039343E-09 - 5.14968398928277E-26 1.47422325967703E-26 -3.67241024039354E-09 - -1.47422325967703E-26 9.99644539096066E-26 -3.67241024039310E-09 - -1.89225643057175E-25 -1.83974984872023E-25 -3.67241024039300E-09 - -4.03290938297948E-25 -2.36077669940061E-25 -3.67241024039321E-09 - -2.41732224908685E-25 2.18710108250715E-25 -3.67241024039332E-09 - 2.74851761153484E-25 7.00760919325929E-26 -3.67241024039319E-09 - -1.73069771718248E-25 4.48325429655205E-26 -3.67241024039334E-09 - -3.38263556158770E-25 1.51057397018961E-25 -3.67241024039253E-09 - -1.51057397018961E-25 1.16726170423743E-25 -3.67241024039351E-09 - -3.10192729707385E-25 9.04728794979874E-26 -3.67241024039288E-09 - -1.92052920541487E-25 1.55500261637166E-25 -3.67241024039310E-09 - -1.55298313245429E-25 -1.59539229471897E-25 -3.67241024039330E-09 - 1.59741177863634E-25 -1.20159293083265E-25 -3.67241024039320E-09 - 3.91779879968963E-26 -2.30625063363173E-25 -3.67241024039344E-09 - 1.52672984152854E-25 1.58125590729741E-25 -3.67241024039330E-09 - -4.90734591919887E-26 -1.13696944547694E-25 -3.67241024039296E-09 - -6.90663499739100E-26 4.15811738585616E-25 -3.67241024039306E-09 - -9.89547119509237E-27 -3.91779879968963E-26 -3.67241024039339E-09 - 3.32810949581882E-25 -7.71442856433732E-26 -3.67241024039337E-09 - -3.83701944299500E-26 -3.66132434218418E-25 -3.67241024039316E-09 - -3.97636383329324E-25 -1.51461293802434E-26 -3.67241024039320E-09 - -1.03801473352602E-25 -1.21169035041947E-27 -3.67241024039318E-09 - -1.72261978151302E-25 1.16928118815479E-25 -3.67241024039331E-09 - -2.38702999032636E-25 -4.01675351164056E-25 -3.67241024039334E-09 - -3.55833066239852E-25 -1.29448919103147E-25 -3.67241024039351E-09 - -1.64184042481839E-25 2.18710108250715E-25 -3.67241024039286E-09 - -5.14968398928277E-26 -6.86624531904369E-26 -3.67241024039323E-09 - 3.24329117128946E-25 1.44191151699917E-25 -3.67241024039302E-09 - -1.44191151699917E-25 -2.44357554001261E-26 -3.67241024039319E-09 - -2.68995257793123E-25 -2.77679038637796E-25 -3.67241024039332E-09 - -4.42065029511371E-25 1.63982094090102E-25 -3.67241024039312E-09 - 1.29650867494884E-25 -7.77501308185829E-26 -3.67241024039339E-09 - 7.77501308185829E-26 -8.86553439723582E-26 -3.67241024039341E-09 - -6.78546596234906E-26 -1.36719061205664E-25 -3.67241024039338E-09 - -1.40758029040396E-25 1.29246970711411E-26 -3.67241024039329E-09 - -1.66001578007468E-25 2.46377037918626E-26 -3.67241024039317E-09 - -1.66203526399205E-25 7.20955758499587E-26 -3.67241024039339E-09 - 3.71786989187042E-25 -1.00974195868290E-26 -3.67241024039350E-09 - -2.79698522555162E-25 -2.44963399176470E-25 -3.67241024039303E-09 - -1.95082146417535E-25 7.12877822830124E-26 -3.67241024039339E-09 - 2.24667585806944E-25 8.04764341070267E-26 -3.67241024039359E-09 - 2.13156527477959E-25 1.57519745554532E-26 -3.67241024039332E-09 - -1.58226564925610E-25 -1.29448919103147E-25 -3.67241024039307E-09 - -1.14100841331167E-26 -1.34901525680035E-25 -3.67241024039289E-09 - 1.34901525680035E-25 7.08838854995392E-26 -3.67241024039339E-09 - 8.49192987252315E-26 -2.31533831125988E-25 -3.67241024039317E-09 - 7.42160339631928E-26 8.02744857152902E-26 -3.67241024039314E-09 - -8.03754599111585E-26 -1.71656132976092E-27 -3.67241024039360E-09 - 1.61558713389263E-27 2.44357554001261E-26 -3.67241024039317E-09 - -2.44357554001261E-26 1.10061873496436E-25 -3.67241024039365E-09 - -1.43585306524708E-25 1.21875854413025E-25 -3.67241024039352E-09 - 1.71656132976092E-25 4.94773559754619E-27 -3.67241024039340E-09 - 2.88685225987440E-25 1.55500261637166E-25 -3.67241024039341E-09 - 1.38132699947820E-25 5.04870979341448E-28 -3.67241024039317E-09 - 1.69232752275253E-25 -3.78653234506086E-26 -3.67241024039305E-09 - 3.78653234506086E-26 1.07234596012123E-25 -3.67241024039282E-09 - 6.55322531185199E-26 1.25208002876679E-26 -3.67241024039314E-09 - -1.31771325608118E-25 -6.52293305309150E-26 -3.67241024039299E-09 - -1.10667718671645E-25 -3.06052787676786E-25 -3.67241024039406E-09 - -2.19618876013530E-25 -5.98776981498957E-26 -3.67241024038965E-09 - 5.98776981498957E-26 -3.83701944299500E-26 -3.67241024040750E-09 - -7.45189565507977E-26 1.69838597450463E-25 -3.67241024033254E-09 - 1.24198260917996E-26 -1.50350577647883E-25 -3.67241024065134E-09 - 7.66394146640317E-26 2.78688780596479E-26 -3.67241023929447E-09 - 1.57418771358663E-25 1.13797918743562E-25 -3.67241024506611E-09 - 1.79734068645555E-25 2.06088333767179E-25 -3.67241022055434E-09 - 1.92658765716696E-25 1.39344390298240E-26 -3.67241032447343E-09 - -2.21234463147422E-25 4.72559236663595E-26 -3.67240988467279E-09 - 9.95605571261335E-26 -7.14897306747490E-26 -3.67241174257651E-09 - -1.21471957629552E-25 -4.79627430374375E-26 -3.67240390907499E-09 - 4.79627430374375E-26 9.06748278897240E-26 -3.67243687051309E-09 - -2.37592282878085E-25 -3.04942071522234E-26 -3.67229847617418E-09 - 3.04942071522234E-26 -8.38085825706803E-27 -3.67287821070506E-09 - 1.96899681943165E-25 -2.86766716265942E-26 -3.67045572285493E-09 - 2.86766716265942E-26 5.00832011506716E-26 -3.68055153739757E-09 - 1.52168113173512E-25 -1.36315164422191E-26 -3.63860299048642E-09 - 7.07829113036709E-26 -5.35163238101934E-27 -3.81241466280927E-09 - 6.40176401804956E-26 -1.48634016318122E-25 -3.09590192026221E-09 - -5.76562658407933E-26 -1.48129145338781E-25 -6.05788840844362E-09 - -1.70141520038068E-25 1.00974195868290E-28 5.82604926563694E-09 - 0.00000000000000E+00 -5.20017108721691E-26 -4.87380196349415E-08 - 2.32745521476407E-25 7.51248017260074E-25 -2.58132668003456E-06 - 1.40717639362048E-24 9.31224423975713E-24 -8.71919391713703E-06 - 3.55429169456379E-24 6.43649914142825E-24 -1.31019766382739E-05 - -6.43649914142825E-24 1.03914564451974E-23 -1.54793032716819E-05 - -4.35820785238876E-23 9.46087825607525E-23 -1.66505032150849E-05 - 1.44136221737365E-22 -3.65510433171869E-23 -1.72168609640783E-05 - -3.62408505874795E-23 1.05155335370804E-22 -1.74916386198471E-05 - 9.97786613892090E-23 1.37311981683803E-22 -1.76251455312477E-05 - 3.05022850878929E-23 1.05982515983357E-24 -1.76892303828135E-05 - -4.28582954879037E-23 -6.57867080921080E-23 -1.77189319913074E-05 - -7.23007554159631E-23 -8.03916157824974E-24 -1.77317330604970E-05 - 2.25665210862123E-23 -3.28287305606983E-24 -1.77365089130635E-05 - 2.33290782134096E-23 -6.46234853557053E-24 -1.77378002342758E-05 - 6.47527323264167E-24 -4.29746177615440E-25 -1.77379152761724E-05 - 4.32977351883225E-25 - 1 -1 6 8 - SCALAIRE - -22 321007 1 0 0 0 -79 0 2 - - - 320989 - FLUX - REAL*8 - 1 301 0 0 - 7.10858338912758E-26 -3.67241024039287E-09 8.86553439723582E-26 - 3.67241024039352E-09 3.67546072960574E-25 -3.67241024039317E-09 - 5.94334116880752E-25 -1.95687991592745E-25 -3.67241024039319E-09 - -1.80743810604238E-25 -1.17533963990689E-25 -3.67241024039320E-09 - 1.17533963990689E-25 3.27964188180204E-25 -3.67241024039321E-09 - 5.14968398928277E-26 1.47422325967703E-26 -3.67241024039332E-09 - -1.47422325967703E-26 -4.73770927014014E-25 -3.67241024039364E-09 - -3.80470770031715E-25 -1.73069771718248E-25 -3.67241024039309E-09 - -2.11238017756462E-25 1.55298313245429E-25 -3.67241024039342E-09 - -4.62461817076766E-26 -3.70373350444886E-25 -3.67241024039375E-09 - -3.10192729707385E-25 6.86624531904369E-26 -3.67241024039320E-09 - 2.17296469508559E-25 4.52364397489937E-26 -3.67241024039330E-09 - 1.51461293802434E-25 2.48598470227729E-25 -3.67241024039275E-09 - -5.35163238101934E-26 1.15716428465060E-25 -3.67241024039342E-09 - -1.55500261637166E-26 -1.07032647620387E-25 -3.67241024039322E-09 - -3.89558447659861E-25 5.49299625523495E-26 -3.67241024039311E-09 - 1.35507370855245E-25 1.40556080648659E-25 -3.67241024039333E-09 - -2.24970508394549E-25 7.95676663442121E-26 -3.67241024039309E-09 - 2.66571877092284E-26 -4.21668241945977E-25 -3.67241024039293E-09 - 4.96793043671984E-26 -1.52471035761117E-25 -3.67241024039317E-09 - -3.19078458943795E-26 -3.53409685539013E-26 -3.67241024039372E-09 - -3.69161660094466E-25 2.05785411179574E-25 -3.67241024039285E-09 - 8.78475504054119E-26 -7.12877822830124E-26 -3.67241024039349E-09 - -4.28130590481548E-26 -4.50748810356044E-25 -3.67241024039362E-09 - -6.07864659127103E-25 -2.68187464226177E-25 -3.67241024039329E-09 - -4.35804629367538E-25 -2.98277774594927E-25 -3.67241024039338E-09 - 1.79734068645555E-25 3.79057131289559E-25 -3.67241024039323E-09 - 3.28368084963677E-25 1.16928118815479E-25 -3.67241024039320E-09 - -2.38702999032636E-25 1.72665874934775E-25 -3.67241024039336E-09 - 2.44155605609524E-25 -4.50142965180835E-25 -3.67241024039345E-09 - -2.62129012474080E-25 5.14968398928277E-26 -3.67241024039336E-09 - 7.47209049425342E-26 1.11879409022065E-25 -3.67241024039286E-09 - 1.43787254916444E-25 -1.80945758995975E-25 -3.67241024039330E-09 - -3.71383092403569E-25 -2.20123746992871E-25 -3.67241024039319E-09 - -3.66940227785364E-25 1.65597681223995E-25 -3.67241024039377E-09 - 1.27833331969255E-25 9.14826214566703E-26 -3.67241024039268E-09 - 3.61487621208476E-25 3.32609001190146E-25 -3.67241024039322E-09 - 4.12580564317831E-25 4.80637172333058E-26 -3.67241024039324E-09 - 2.45569244351680E-25 -2.71216690102226E-25 -3.67241024039306E-09 - -1.77108739552980E-25 -1.27429435185781E-25 -3.67241024039334E-09 - -1.29246970711411E-26 4.66500784911498E-26 -3.67241024039317E-09 - -1.88215901098492E-25 -1.23592415742786E-25 -3.67241024039296E-09 - -1.95889939984482E-26 1.35305422463508E-26 -3.67241024039307E-09 - -1.58327539121478E-25 -9.83488667757140E-26 -3.67241024039344E-09 - -1.95082146417535E-25 2.11036069364725E-26 -3.67241024039299E-09 - -2.13055553282091E-26 -6.36137433970224E-26 -3.67241024039327E-09 - -8.03754599111585E-26 4.23081880688133E-26 -3.67241024039318E-09 - 1.08749208950148E-25 -1.60548971430580E-26 -3.67241024039321E-09 - 1.56913900379322E-25 -1.48331093730517E-25 -3.67241024039318E-09 - -2.84646258152708E-25 -4.50344913572571E-26 -3.67241024039382E-09 - 2.71620586885699E-26 2.19416927621793E-25 -3.67241024039306E-09 - 7.41150597673245E-26 -1.15413505877455E-25 -3.67241024039361E-09 - 1.15312531681587E-25 -6.42195885722321E-26 -3.67241024039309E-09 - -2.29312398816885E-25 -7.67403888599000E-27 -3.67241024039283E-09 - 1.39344390298240E-25 1.28237228752728E-26 -3.67241024039364E-09 - -1.29246970711411E-26 -1.71656132976092E-25 -3.67241024039303E-09 - -2.50416005753358E-25 -9.28962601988264E-26 -3.67241024039386E-09 - 9.29972343946946E-26 2.24162714827603E-26 -3.67241024039316E-09 - -2.24162714827603E-26 2.64552393174919E-26 -3.67241024039306E-09 - -2.64552393174919E-26 -9.89547119509237E-26 -3.67241024039349E-09 - -2.32240650497066E-26 -1.63376248914892E-25 -3.67241024039317E-09 - -2.51021850928568E-25 1.31569377216381E-25 -3.67241024039295E-09 - -1.31670351412250E-25 -6.53303047267833E-26 -3.67241024039322E-09 - -1.10768692867514E-25 -1.50148629256147E-25 -3.67241024039327E-09 - 3.42302523993501E-26 3.07567400614810E-25 -3.67241024039438E-09 - 2.79496574163425E-25 1.87509081727414E-25 -3.67241024038987E-09 - -7.44179823549294E-26 1.27732357773386E-25 -3.67241024040381E-09 - -1.27732357773386E-25 7.62355178805586E-26 -3.67241024037322E-09 - -7.61345436846903E-26 -1.57418771358663E-25 -3.67241024036949E-09 - -3.21400865448766E-25 2.65057264154260E-25 -3.67241024097486E-09 - 1.35204448267640E-25 2.43953657217787E-25 -3.67241023581727E-09 - 2.37895205465690E-25 -3.21097942861161E-26 -3.67241026900556E-09 - 3.21097942861161E-26 -1.01479066847631E-25 -3.67241007889590E-09 - -1.47321351771834E-25 2.77679038637796E-26 -3.67241110014965E-09 - -2.75659554720430E-26 1.48331093730517E-25 -3.67240583402067E-09 - 1.45301867854469E-25 4.18033170894719E-26 -3.67243222729908E-09 - 7.57306469012171E-27 1.65597681223995E-26 -3.67230269536434E-09 - -6.73497886441491E-26 2.88685225987440E-25 -3.67292820288685E-09 - 1.51562267998303E-25 -7.76491566227146E-26 -3.66994637327746E-09 - -2.15983804962271E-25 4.67510526870180E-26 -3.68401209400644E-09 - -4.67510526870180E-26 7.59325952929537E-26 -3.61825614792585E-09 - 1.37324906380874E-26 8.91602149516996E-26 -3.92357309176902E-09 - 5.76562658407933E-26 -2.38198128053295E-25 -2.51973002858363E-09 - -1.40657054844527E-25 7.57306469012171E-27 -9.03659666759729E-09 - -7.57306469012171E-27 -6.47244595515736E-26 1.93364806333660E-08 - -1.54995390657824E-25 -1.13091099372484E-25 -8.62449047588266E-07 - 7.31457074869889E-25 6.24262868536113E-24 -6.30426733966067E-06 - 6.15861815439871E-24 3.15362608535842E-24 -1.14752219114733E-05 - -3.14070138828728E-24 3.67319890761829E-23 -1.45088873074069E-05 - 3.09934235765963E-23 8.07535073004893E-23 -1.60559227018534E-05 - 1.91052872105607E-22 -5.17504870728488E-23 -1.68176487092601E-05 - -6.58642562745348E-23 -1.05930817195072E-22 -1.71930230383733E-05 - -5.85230283381267E-23 -1.03397576569128E-23 -1.73793423962185E-05 - 2.32644547280539E-24 -3.67578384703252E-23 -1.74717988743411E-05 - -9.77107098578264E-23 -5.23708725322636E-23 -1.75169794511500E-05 - -1.06163461742353E-22 3.76884166594473E-23 -1.75382275855495E-05 - -3.76625672653050E-23 2.30059607866311E-23 -1.75474928523005E-05 - -1.10635406928967E-23 -3.94203260669802E-24 -1.75509812426694E-05 - 2.15842441088056E-23 -4.56241806611279E-24 -1.75519308993191E-05 - 4.54949336904165E-24 3.41858237531681E-24 -1.75520158509334E-05 - -3.41858237531681E-24 - 1 -1 6 8 - SCALAIRE - -22 320323 1 0 0 0 -80 0 2 - - - 320311 - FLUX - REAL*8 - 1 301 0 0 - -2.13459450065564E-25 -3.67241024039309E-09 -2.01948391736579E-28 - 3.67241024039374E-09 -2.92421271234566E-25 -3.67241024039319E-09 - -2.94642703543669E-25 2.86160871090732E-25 -3.67241024039364E-09 - 3.01105052079239E-25 6.48254337474419E-26 -3.67241024039385E-09 - -2.73842019194801E-25 -5.14968398928277E-26 -3.67241024039342E-09 - 5.12948915010911E-26 1.17533963990689E-25 -3.67241024039278E-09 - 1.76098997594297E-25 9.99644539096066E-26 -3.67241024039321E-09 - -1.89225643057175E-25 1.20563189866738E-25 -3.67241024039363E-09 - 1.72867823326512E-25 1.46816480792493E-25 -3.67241024039298E-09 - 1.46614532400756E-25 1.67617165141361E-26 -3.67241024039320E-09 - -2.16690624333349E-25 -2.20931540559817E-25 -3.67241024039350E-09 - -3.66132434218418E-25 -1.51865190585907E-25 -3.67241024039387E-09 - -4.35198784192328E-25 -4.46305945737840E-26 -3.67241024039273E-09 - 3.38263556158770E-25 2.11439966148198E-25 -3.67241024039333E-09 - -1.79734068645555E-26 -3.95213002628485E-25 -3.67241024039323E-09 - -4.85483933734736E-25 2.55868612330246E-25 -3.67241024039329E-09 - -2.55868612330246E-25 2.92825168018040E-26 -3.67241024039340E-09 - -1.34093732113088E-25 7.95676663442121E-26 -3.67241024039320E-09 - 2.66571877092284E-26 -2.45569244351680E-25 -3.67241024039263E-09 - -4.49537120005625E-25 -3.48360975745599E-25 -3.67241024039310E-09 - -2.38904947424373E-25 -1.33083990154406E-25 -3.67241024039350E-09 - -2.71216690102226E-25 -2.76467348287377E-25 -3.67241024039354E-09 - 3.88750654092915E-25 -4.72559236663595E-26 -3.67241024039368E-09 - 4.72559236663595E-26 4.72559236663595E-26 -3.67241024039257E-09 - -2.25374405178022E-25 4.44286461820474E-26 -3.67241024039325E-09 - -2.20931540559817E-25 8.27988406119974E-26 -3.67241024039327E-09 - -8.27988406119974E-26 3.79057131289559E-25 -3.67241024039268E-09 - 3.28368084963677E-25 1.16928118815479E-25 -3.67241024039320E-09 - -2.38702999032636E-25 1.85186675222443E-25 -3.67241024039330E-09 - 2.31432856930120E-25 -5.87669819953445E-26 -3.67241024039384E-09 - -2.35067927981378E-25 8.68378084467290E-27 -3.67241024039324E-09 - 1.58327539121478E-25 1.39344390298240E-26 -3.67241024039292E-09 - -5.21026850680374E-26 1.47422325967703E-26 -3.67241024039329E-09 - 1.49239861493332E-25 -8.92611891475679E-26 -3.67241024039350E-09 - -2.04371772437418E-25 -6.48254337474419E-26 -3.67241024039371E-09 - 2.25778301961495E-25 -1.66001578007468E-25 -3.67241024039274E-09 - 3.17058975026429E-26 2.15680882374666E-25 -3.67241024039345E-09 - 7.77501308185829E-26 -2.06189307963047E-25 -3.67241024039321E-09 - -2.43751708826051E-25 -1.57317797162795E-25 -3.67241024039311E-09 - 3.12010265233015E-25 -1.27429435185781E-25 -3.67241024039334E-09 - 1.27429435185781E-25 4.66500784911498E-26 -3.67241024039350E-09 - -1.88215901098492E-25 1.95889939984482E-26 -3.67241024039349E-09 - 2.73842019194801E-25 -8.44144277458900E-26 -3.67241024039307E-09 - 2.33048444064012E-25 2.36279618331797E-26 -3.67241024039333E-09 - -2.44357554001261E-26 -1.31266454628776E-27 -3.67241024039328E-09 - 3.83701944299500E-27 -2.85151129132050E-25 -3.67241024039370E-09 - -3.01912845646186E-25 -1.35507370855245E-25 -3.67241024039350E-09 - -1.58125590729741E-25 -1.13797918743562E-25 -3.67241024039310E-09 - 2.54757896175694E-25 1.92860714108433E-26 -3.67241024039329E-09 - 4.28433513069152E-25 -1.13797918743562E-25 -3.67241024039357E-09 - 9.59254860748750E-26 2.19416927621793E-25 -3.67241024039317E-09 - 7.41150597673245E-26 -1.74685358852141E-26 -3.67241024039328E-09 - 1.52168113173512E-25 -1.97404552922506E-25 -3.67241024039338E-09 - 6.41186143763638E-26 9.01699569103825E-26 -3.67241024039336E-09 - 2.03463004674603E-25 2.08612688663886E-25 -3.67241024039361E-09 - -4.51354655531254E-26 -1.71656132976092E-25 -3.67241024039325E-09 - -2.50416005753358E-25 4.94773559754619E-27 -3.67241024039340E-09 - 2.88685225987440E-25 -6.78546596234906E-26 -3.67241024039328E-09 - 6.78546596234906E-26 -2.31028960146646E-25 -3.67241024039304E-09 - 6.13923110879200E-26 2.33250392455749E-26 -3.67241024039340E-09 - -2.32240650497066E-26 -6.54312789226516E-26 -3.67241024039315E-09 - -1.07335570207992E-25 3.37253814200087E-26 -3.67241024039294E-09 - 8.54241697045729E-26 7.16916790664856E-26 -3.67241024039398E-09 - 4.59432591200717E-26 8.53231955087046E-26 -3.67241024038919E-09 - 9.21894408277483E-26 -2.39005921620241E-25 -3.67241024041104E-09 - -5.46270399647446E-26 1.87509081727414E-25 -3.67241024031642E-09 - 1.06022905661704E-25 -3.05951813480917E-25 -3.67241024072959E-09 - -1.69838597450463E-25 1.74180487872799E-25 -3.67241023891744E-09 - 1.19452473712186E-25 8.20920212409194E-26 -3.67241024685356E-09 - 2.63542651216236E-26 2.73942993390669E-25 -3.67241021215777E-09 - 2.33149418259880E-25 -3.43110317560448E-25 -3.67241036359670E-09 - -2.43953657217787E-25 2.61422193103002E-25 -3.67240970367814E-09 - 3.21097942861161E-26 -1.61558713389263E-27 -3.67241257480795E-09 - 4.63471559035449E-26 -2.12045811323408E-26 -3.67240010274169E-09 - -1.71757107171960E-25 4.92754075837253E-26 -3.67245419782431E-09 - 1.45200893658600E-25 -1.05417060486494E-25 -3.67221992641354E-09 - 5.60406787069007E-26 2.11238017756462E-25 -3.67323297628686E-09 - 1.27328460989913E-25 -5.72523690573202E-26 -3.66885884315946E-09 - 1.51562267998303E-25 1.20664164062606E-25 -3.68771828403649E-09 - 1.72867823326512E-25 -1.07436544403860E-25 -3.60653905820639E-09 - -3.53409685539013E-27 -1.72665874934775E-26 -3.95572769114796E-09 - -4.00867557597109E-26 1.69636649058726E-26 -2.46093046140696E-09 - 4.09955235225255E-26 2.40318586166529E-26 -8.94597395804359E-09 - -1.73978539481063E-25 -1.91850972149750E-26 1.76720761351751E-08 - 1.90841230191067E-26 1.00772247476553E-25 -1.57101478830654E-07 - -1.00772247476553E-25 4.36531643577789E-24 -3.76874819374065E-06 - 4.79344702625944E-24 7.90991460753833E-24 -9.56990432756230E-06 - 3.07607790293157E-24 -6.30208229188838E-23 -1.33474547521495E-05 - -3.80761575715816E-23 7.13443278326986E-24 -1.53673825057499E-05 - -7.13443278326986E-24 6.01773895632328E-23 -1.63810943817335E-05 - -3.87223924251386E-23 -5.73856549958663E-23 -1.68863543377959E-05 - -2.93132129573479E-23 -3.12260681238768E-23 -1.71404709690535E-05 - -4.44609579247252E-24 -8.91287110025887E-23 -1.72691960877876E-05 - -8.65954703766451E-23 -1.03397576569128E-25 -1.73342214396680E-05 - 1.03397576569128E-25 -3.70163324117480E-23 -1.73664762356253E-05 - -5.95828534979603E-23 -1.52511425439464E-24 -1.73818355972555E-05 - -3.82054045422930E-23 -7.90991460753833E-24 -1.73886031515654E-05 - 2.06278165255411E-23 2.27733162393505E-23 -1.73911737238040E-05 - -2.27603915422794E-23 1.57422810326498E-23 -1.73918787514344E-05 - 1.34158355598444E-23 3.91618321255574E-24 -1.73919421406017E-05 - 2.93713740941681E-24 - 1 -1 6 8 - SCALAIRE - -22 320137 1 0 0 0 -81 0 2 - - - 320125 - FLUX - REAL*8 - 1 301 0 0 - -3.91174034793754E-25 -3.67241024039310E-09 1.77714584728190E-26 - 3.67241024039375E-09 2.94642703543669E-25 -3.67241024039318E-09 - -8.23949438285242E-26 2.85958922698996E-25 -3.67241024039340E-09 - 3.01105052079239E-25 7.83559759937927E-26 -3.67241024039298E-09 - 1.31064506237040E-25 1.32276196587459E-25 -3.67241024039320E-09 - 2.47184831485573E-25 1.45402842050337E-26 -3.67241024039321E-09 - -2.20527643776344E-25 -8.68378084467290E-26 -3.67241024039311E-09 - -5.89285407087338E-25 1.53480777719800E-26 -3.67241024039308E-09 - -1.55500261637166E-26 2.47386779877309E-25 -3.67241024039320E-09 - -3.39677194900926E-25 1.67617165141361E-26 -3.67241024039287E-09 - 7.69423372516366E-26 7.12877822830124E-26 -3.67241024039361E-09 - 6.11095833394888E-25 1.42575564566025E-25 -3.67241024039364E-09 - -1.42575564566025E-25 2.48396521835992E-25 -3.67241024039264E-09 - 4.50344913572571E-26 2.13459450065564E-25 -3.67241024039309E-09 - 5.67273032388050E-25 9.04728794979874E-26 -3.67241024039290E-09 - -9.04728794979874E-26 -3.77643492547403E-26 -3.67241024039354E-09 - -2.55868612330246E-25 3.93799363886329E-26 -3.67241024039277E-09 - -3.93799363886329E-26 -3.06961555439600E-26 -3.67241024039311E-09 - -1.56711951987585E-25 -1.28035280360991E-25 -3.67241024039304E-09 - 4.96793043671984E-26 -4.32169558316279E-26 -3.67241024039326E-09 - -1.41161925823869E-25 -1.13696944547694E-25 -3.67241024039318E-09 - -6.90663499739100E-26 1.71656132976092E-26 -3.67241024039294E-09 - 3.88548705701178E-25 4.26111106564182E-26 -3.67241024039341E-09 - 1.36921009597401E-25 -4.50748810356044E-25 -3.67241024039318E-09 - -6.07864659127103E-25 -1.70444442625673E-25 -3.67241024039325E-09 - -5.33547650968042E-25 2.88786200183308E-25 -3.67241024039316E-09 - 4.16821480544299E-25 1.83167191305077E-25 -3.67241024039312E-09 - 5.23854128164686E-25 -9.06748278897240E-26 -3.67241024039319E-09 - -3.24531065520682E-25 1.34497628896562E-25 -3.67241024039296E-09 - 1.58933384296688E-25 -3.38869401333980E-25 -3.67241024039347E-09 - -5.42231431812715E-25 -8.90592407558313E-26 -3.67241024039281E-09 - -4.57211158891615E-25 -1.00974195868290E-27 -3.67241024039347E-09 - -3.30589517272780E-25 -2.47184831485573E-25 -3.67241024039357E-09 - -6.33512104877648E-25 -1.05820957269967E-25 -3.67241024039333E-09 - -1.87812004315018E-25 -2.08410740272150E-25 -3.67241024039360E-09 - -2.46377037918626E-25 1.45806738833810E-25 -3.67241024039301E-09 - 1.47826222751176E-25 9.89547119509237E-26 -3.67241024039355E-09 - 3.52399943580330E-25 -1.08446286362543E-25 -3.67241024039309E-09 - -4.82656656250424E-26 -1.36719061205664E-25 -3.67241024039317E-09 - -1.40758029040396E-25 1.10667718671645E-25 -3.67241024039307E-09 - -2.64148496391445E-25 -5.14968398928277E-26 -3.67241024039313E-09 - -9.04728794979874E-26 -3.02922587604869E-27 -3.67241024039365E-09 - 1.46412584009020E-25 8.78475504054119E-26 -3.67241024039306E-09 - 6.09884143044469E-26 9.73391248170311E-26 -3.67241024039324E-09 - -9.71371764252945E-26 1.69232752275253E-25 -3.67241024039310E-09 - 2.72327406256777E-25 -1.35608345051113E-25 -3.67241024039378E-09 - 1.41060951628000E-25 -2.77981961225401E-25 -3.67241024039335E-09 - -1.58024616533873E-25 -1.29448919103147E-25 -3.67241024039361E-09 - -1.14100841331167E-26 -8.88572923640948E-27 -3.67241024039326E-09 - 8.88572923640948E-27 1.50653500235488E-25 -3.67241024039369E-09 - 1.24804106093206E-25 -7.41150597673245E-26 -3.67241024039342E-09 - -6.19981562631298E-26 1.41464848411474E-25 -3.67241024039292E-09 - 1.52168113173512E-25 -1.93365585087774E-25 -3.67241024039305E-09 - -1.00065428105475E-25 -4.12984461101304E-26 -3.67241024039361E-09 - -9.02709311062508E-26 2.08612688663886E-25 -3.67241024039350E-09 - -4.51354655531254E-26 2.40318586166529E-26 -3.67241024039306E-09 - 1.41060951628000E-25 4.94773559754619E-27 -3.67241024039329E-09 - 2.88685225987440E-25 1.27934306165123E-25 -3.67241024039306E-09 - 1.65597681223995E-25 5.04870979341448E-28 -3.67241024039328E-09 - 1.69232752275253E-25 3.55429169456379E-26 -3.67241024039361E-09 - -3.55429169456379E-26 -2.98681671378400E-25 -3.67241024039295E-09 - -1.67718139337229E-25 -1.23693389938655E-25 -3.67241024039403E-09 - -1.69939571646331E-25 -2.22042256714369E-25 -3.67241024039131E-09 - 4.59432591200717E-26 5.65455496862421E-27 -3.67241024040122E-09 - -1.21774880217157E-25 2.50214057361621E-25 -3.67241024036101E-09 - 1.57620719750400E-25 -6.47244595515736E-26 -3.67241024052816E-09 - 6.46234853557053E-26 -1.23188518959313E-26 -3.67241023983736E-09 - 1.23794364134523E-25 7.63364920764269E-26 -3.67241024267130E-09 - 1.07436544403860E-25 -6.99751177367246E-26 -3.67241023109740E-09 - -3.83701944299500E-26 -8.19910470450511E-26 -3.67241027813751E-09 - 8.18900728491828E-26 1.91346101170409E-25 -3.67241008800946E-09 - 1.02185886218709E-25 1.11778434826196E-25 -3.67241085158396E-09 - -2.54454973588090E-26 9.83488667757140E-26 -3.67240780761044E-09 - 9.30982085905629E-26 2.76669296679113E-26 -3.67241983701927E-09 - -2.76669296679113E-26 -2.01948391736579E-28 -3.67237279248025E-09 - 1.94678249634062E-25 -5.62426270986373E-26 -3.67255443421343E-09 - -9.05738536938557E-26 -3.04942071522234E-26 -3.67186430405844E-09 - -6.54312789226516E-26 -2.00534752994423E-25 -3.67443210311541E-09 - -9.30982085905629E-26 2.28201682662334E-26 -3.66514584687697E-09 - 6.99751177367246E-26 9.91566603426603E-26 -3.69738444431288E-09 - 2.50012108969885E-25 -1.37324906380874E-26 -3.59248313420328E-09 - -4.32169558316279E-26 8.83524213847533E-26 -3.89663772383702E-09 - -2.95854393894088E-26 1.02993679785655E-25 -3.23917083348685E-09 - -1.63578197306629E-26 -1.26217744835362E-25 -3.34224756146355E-09 - -2.02958133695262E-26 -5.65455496862421E-25 -1.58487825807655E-06 - 5.65455496862421E-27 1.26209666899692E-23 -7.34757047487880E-06 - 1.38940493514766E-24 3.31130738962634E-23 -1.19246462832618E-05 - 1.97747865188458E-24 -7.36707733055040E-24 -1.45377675536451E-05 - -3.64993445289023E-23 -2.48671171648754E-23 -1.58804450984939E-05 - -3.37076099615359E-23 -1.03397576569128E-23 -1.65567383079266E-05 - 8.87151206963122E-23 -6.26072326126073E-23 -1.68997832054134E-05 - -1.48634016318122E-22 1.24697477342369E-22 -1.70757506132719E-05 - 2.06019671313988E-22 -5.19572822259871E-23 -1.71664911720159E-05 - -7.02586532787228E-23 5.94536065272489E-23 -1.72130164990172E-05 - 6.56574611213966E-24 -6.96899666075926E-23 -1.72363736891111E-05 - -3.08124778176003E-23 1.60783231564995E-23 -1.72476021977859E-05 - -1.61041725506418E-23 -3.25702366192755E-24 -1.72525863793049E-05 - -1.02105106862014E-23 1.06241009924779E-23 -1.72544902576826E-05 - 6.59159550628194E-24 -1.31056428301370E-23 -1.72550146062442E-05 - -2.65473277841237E-23 -5.90012421297589E-24 -1.72550618687095E-05 - -8.95035272176518E-25 - 1 -1 6 8 - SCALAIRE - -22 319987 1 0 0 0 -82 0 2 - - - 319969 - FLUX - REAL*8 - 1 301 0 0 - 7.08838854995392E-26 -3.67241024039375E-09 8.86553439723582E-26 - 3.67241024039375E-09 -3.08981039356966E-25 -3.67241024039363E-09 - -6.58351757061248E-26 3.01105052079239E-25 -3.67241024039341E-09 - -9.02709311062508E-26 -2.21941282518500E-25 -3.67241024039299E-09 - -1.55904158420639E-25 1.32276196587459E-25 -3.67241024039298E-09 - 2.47184831485573E-25 2.20527643776344E-25 -3.67241024039397E-09 - -2.20527643776344E-25 1.04407318527811E-25 -3.67241024039385E-09 - 9.99644539096066E-26 -1.83773036480287E-25 -3.67241024039331E-09 - -1.09859925104699E-25 2.47386779877309E-25 -3.67241024039321E-09 - 2.47386779877309E-25 -2.72630328844382E-25 -3.67241024039311E-09 - -1.14504738114640E-25 -3.18876510552058E-25 -3.67241024039242E-09 - 2.54454973588090E-26 2.40924431341739E-25 -3.67241024039355E-09 - -4.42266977903108E-26 -2.40520534558266E-25 -3.67241024039289E-09 - -4.44892306995684E-25 -7.79520792103195E-26 -3.67241024039373E-09 - -1.15514480073323E-25 -2.02958133695262E-25 -3.67241024039290E-09 - -9.04728794979874E-26 5.73533432531884E-26 -3.67241024039341E-09 - -5.75552916449250E-26 3.93799363886329E-26 -3.67241024039387E-09 - 6.52293305309150E-26 -1.28439177144464E-25 -3.67241024039330E-09 - -6.45830956773580E-25 -2.30625063363173E-25 -3.67241024039355E-09 - 1.52672984152854E-25 1.40959977432132E-25 -3.67241024039380E-09 - -1.40959977432132E-25 -1.26621641618835E-25 -3.67241024039329E-09 - -4.60442333159400E-25 -8.78475504054119E-26 -3.67241024039319E-09 - -4.99216424372823E-25 -3.91779879968963E-26 -3.67241024039317E-09 - 3.32810949581882E-25 2.08006843488676E-26 -3.67241024039283E-09 - 2.72630328844382E-25 2.52435489670724E-26 -3.67241024039314E-09 - -2.52435489670724E-26 5.65455496862421E-27 -3.67241024039338E-09 - 1.12687202589011E-25 -2.36279618331797E-26 -3.67241024039280E-09 - 1.97101630334901E-25 -2.98277774594927E-25 -3.67241024039324E-09 - -1.16928118815479E-25 1.34497628896562E-25 -3.67241024039274E-09 - 1.58933384296688E-25 -3.15039491109063E-26 -3.67241024039348E-09 - 2.00332804602686E-25 -8.90592407558313E-26 -3.67241024039336E-09 - -4.57211158891615E-25 -1.81551604171185E-25 -3.67241024039330E-09 - -1.49845706668542E-25 -1.64991836048785E-25 -3.67241024039308E-09 - -2.57888096247611E-25 -5.13554760186120E-25 -3.67241024039329E-09 - -4.98004734022404E-25 -2.08410740272150E-25 -3.67241024039371E-09 - -2.46377037918626E-25 5.00832011506716E-25 -3.67241024039300E-09 - 3.79662976464769E-25 1.17937860774162E-25 -3.67241024039371E-09 - -1.17937860774162E-25 -1.08446286362543E-25 -3.67241024039331E-09 - -4.82656656250424E-26 1.97707475510111E-25 -3.67241024039322E-09 - 3.89558447659861E-25 4.70539752746229E-26 -3.67241024039323E-09 - -3.39273298117453E-26 1.88215901098492E-25 -3.67241024039329E-09 - 1.05215112094758E-25 9.47137957244556E-26 -3.67241024039340E-09 - 5.55358077275592E-26 1.34699577288298E-25 -3.67241024039314E-09 - 3.07365452223073E-25 -4.92754075837253E-26 -3.67241024039358E-09 - -9.71371764252945E-26 4.62461817076766E-26 -3.67241024039350E-09 - -4.63471559035449E-26 -8.94631375393045E-26 -3.67241024039342E-09 - -5.45260657688763E-26 2.11439966148198E-25 -3.67241024039343E-09 - 2.33250392455749E-25 -1.29448919103147E-25 -3.67241024039339E-09 - -1.14100841331167E-26 -8.88572923640948E-27 -3.67241024039294E-09 - 8.88572923640948E-27 3.35537252870326E-25 -3.67241024039328E-09 - 2.51728670299646E-25 1.89629539840648E-25 -3.67241024039321E-09 - 1.03902447548470E-25 -3.11101497470200E-25 -3.67241024039335E-09 - -2.76063451503904E-25 -6.42195885722321E-26 -3.67241024039336E-09 - -9.62284086624799E-26 -7.34082403962465E-26 -3.67241024039372E-09 - 7.35092145921148E-26 2.08612688663886E-25 -3.67241024039350E-09 - -4.51354655531254E-26 2.19820824405266E-25 -3.67241024039319E-09 - 3.67344124568837E-25 3.92789621927646E-26 -3.67241024039330E-09 - 2.54253025196353E-25 -4.01877299555792E-26 -3.67241024039342E-09 - 1.65698655419863E-25 2.65562135133601E-26 -3.67241024039339E-09 - -2.64552393174919E-26 -1.35305422463508E-26 -3.67241024039338E-09 - -1.57822668142137E-25 1.90538307603462E-25 -3.67241024039319E-09 - 1.02993679785655E-25 -2.57484199464138E-26 -3.67241024039371E-09 - 2.57484199464138E-26 -6.52293305309150E-26 -3.67241024039053E-09 - -2.28403631054071E-25 1.03599524960865E-25 -3.67241024040508E-09 - 1.90134410819989E-25 2.33553315043354E-25 -3.67241024033732E-09 - 3.53409685539013E-25 -1.21270009237816E-25 -3.67241024065173E-09 - -1.72362952347170E-25 4.34189042233645E-26 -3.67241023920345E-09 - -2.25475379373890E-25 1.86095442985258E-25 -3.67241024584230E-09 - -7.62355178805586E-26 7.15907048706173E-26 -3.67241021555809E-09 - -7.14897306747490E-26 2.48396521835992E-26 -3.67241035310348E-09 - 1.88619797881965E-25 1.04003421744338E-26 -3.67240973087812E-09 - -9.35021053740361E-26 1.95889939984482E-26 -3.67241253548250E-09 - 1.70141520038068E-25 -4.62461817076766E-26 -3.67239993610636E-09 - -1.00469324888948E-25 2.76669296679113E-26 -3.67245636348669E-09 - -2.76669296679113E-26 2.01948391736579E-27 -3.67220437136776E-09 - 2.43751708826051E-25 -1.05013163703021E-25 -3.67332670213141E-09 - -4.17023428936036E-26 -3.35234330282721E-26 -3.66834069401166E-09 - 1.80339913820765E-25 1.40455106452791E-25 -3.69043945245977E-09 - 6.36137433970224E-27 -7.49228533342708E-26 -3.59273939212511E-09 - -7.17926532623538E-26 9.29972343946946E-26 -4.02415810440273E-09 - 8.95641117351728E-26 -2.05987359571311E-26 -2.13124439066565E-09 - 2.05987359571311E-26 3.63507105125842E-26 -1.05842241240242E-08 - 2.63542651216236E-26 5.43241173771398E-26 2.45538906686823E-08 - -1.41060951628000E-25 1.39748287081713E-25 -3.71339668052768E-07 - -1.39546338689976E-25 4.45578931527588E-24 -4.84934751541688E-06 - 7.16674452594772E-24 5.23450231381213E-24 -1.02029946298330E-05 - 1.68150308895545E-23 2.85377311330795E-23 -1.35198853655860E-05 - -2.85377311330795E-23 -8.47860127866853E-24 -1.52841049549540E-05 - 8.47860127866853E-24 7.85304594042531E-23 -1.61842703320657E-05 - -8.73709522009135E-24 -3.99114645556836E-23 -1.66438853440873E-05 - -4.81315718929293E-23 -4.60119215732622E-24 -1.68815258698557E-05 - 4.60119215732622E-24 -1.08205563879593E-22 -1.70057202381540E-05 - -1.88648878450375E-22 -4.63738130912541E-23 -1.70708183521222E-05 - -6.33827144368757E-23 -6.82940993239093E-23 -1.71046598950915E-05 - -1.14047526955749E-22 -1.06757997807625E-23 -1.71218466010197E-05 - -1.31961157096350E-22 -9.43502886193297E-24 -1.71301886836876E-05 - 7.20939602628248E-23 -1.19682694878766E-23 -1.71339215111459E-05 - -2.61854362661318E-23 -2.30059607866311E-24 -1.71353569402940E-05 - -1.47600040552431E-23 -2.68833699079734E-24 -1.71357544042738E-05 - -1.71898471046176E-23 -2.19073615355841E-24 -1.71357903542904E-05 - 2.19073615355841E-24 - 1 -1 6 8 - SCALAIRE - -22 319099 1 0 0 0 -83 0 2 - - - 319087 - FLUX - REAL*8 - 1 301 0 0 - 7.08838854995392E-26 -3.67241024039331E-09 -2.84747232348576E-25 - 3.67241024039352E-09 6.58351757061248E-26 -3.67241024039340E-09 - -6.58351757061248E-26 -1.49441809885068E-26 -3.67241024039320E-09 - 1.49441809885068E-26 -2.62532909257553E-26 -3.67241024039233E-09 - 2.64552393174919E-26 3.27964188180204E-25 -3.67241024039299E-09 - 5.14968398928277E-26 -2.68591361009650E-25 -3.67241024039384E-09 - -1.12283305805538E-25 1.93668507675379E-25 -3.67241024039364E-09 - 1.89023694665438E-25 -7.51248017260074E-26 -3.67241024039288E-09 - -1.55500261637166E-26 -3.31195362447990E-25 -3.67241024039339E-09 - -1.46816480792493E-25 -7.49228533342708E-26 -3.67241024039298E-09 - 2.74851761153484E-25 2.68389412617914E-25 -3.67241024039300E-09 - 1.20563189866738E-25 -1.49845706668542E-25 -3.67241024039331E-09 - -3.37253814200087E-25 5.29104786349837E-26 -3.67241024039340E-09 - 1.42373616174288E-25 1.15716428465060E-25 -3.67241024039342E-09 - 1.77916533119926E-25 1.86398365572862E-25 -3.67241024039352E-09 - -9.59254860748750E-26 1.57923642338005E-25 -3.67241024039331E-09 - 1.35507370855245E-25 2.28403631054071E-25 -3.67241024039296E-09 - -2.28403631054071E-25 -1.28439177144464E-25 -3.67241024039342E-09 - -1.64991836048785E-25 -4.48325429655205E-26 -3.67241024039261E-09 - -2.48800418619465E-25 1.46816480792493E-25 -3.67241024039363E-09 - -1.46816480792493E-25 -1.13696944547694E-25 -3.67241024039348E-09 - 2.24566611611076E-25 1.22380725392367E-25 -3.67241024039327E-09 - -9.89547119509237E-27 -4.72559236663595E-26 -3.67241024039346E-09 - 4.72559236663595E-26 -1.66001578007468E-25 -3.67241024039366E-09 - -1.27429435185781E-25 1.32680093370932E-25 -3.67241024039338E-09 - -1.32680093370932E-25 2.78486832204742E-25 -3.67241024039323E-09 - -1.03599524960865E-25 1.83167191305077E-25 -3.67241024039334E-09 - 5.23854128164686E-25 1.16928118815479E-25 -3.67241024039341E-09 - -2.38702999032636E-25 -3.54621375889433E-25 -3.67241024039329E-09 - -6.22001046548663E-26 -1.42979461349498E-25 -3.67241024039362E-09 - 1.81753552562921E-26 5.14968398928277E-26 -3.67241024039336E-09 - 7.47209049425342E-26 1.94880198025799E-25 -3.67241024039309E-09 - -6.68449176648077E-26 1.47422325967703E-26 -3.67241024039341E-09 - 1.49239861493332E-25 5.69494464697153E-26 -3.67241024039366E-09 - 2.68187464226177E-25 -1.10667718671645E-25 -3.67241024039354E-09 - -3.44120059519131E-25 1.63982094090102E-25 -3.67241024039333E-09 - 1.29650867494884E-25 3.89760396051598E-26 -3.67241024039291E-09 - -1.96899681943165E-25 -1.27833331969255E-25 -3.67241024039299E-09 - -1.65597681223995E-25 5.87669819953445E-26 -3.67241024039327E-09 - -4.28130590481548E-26 -2.03967875653945E-25 -3.67241024039356E-09 - 2.04169824045681E-25 -2.94844651935405E-26 -3.67241024039317E-09 - 1.71252236192619E-25 1.95889939984482E-26 -3.67241024039349E-09 - 2.73842019194801E-25 1.35305422463508E-26 -3.67241024039332E-09 - 1.35305422463508E-25 2.20123746992871E-25 -3.67241024039333E-09 - 2.20527643776344E-25 -2.64552393174919E-26 -3.67241024039334E-09 - 3.22410607407448E-25 8.04764341070267E-26 -3.67241024039359E-09 - 2.13156527477959E-25 -8.21929954367877E-26 -3.67241024039354E-09 - -6.02815949333688E-26 8.17890986533145E-26 -3.67241024039317E-09 - 5.90699045829494E-26 6.06854917168420E-26 -3.67241024039325E-09 - 7.85579243855292E-26 7.08838854995392E-26 -3.67241024039350E-09 - 8.49192987252315E-26 -2.31533831125988E-25 -3.67241024039328E-09 - 7.42160339631928E-26 4.35198784192328E-26 -3.67241024039346E-09 - -4.34189042233645E-26 6.49264079433102E-26 -3.67241024039327E-09 - -6.49264079433102E-26 2.44357554001261E-26 -3.67241024039325E-09 - 1.07133621816255E-25 7.79520792103195E-26 -3.67241024039344E-09 - 5.21026850680374E-26 1.21875854413025E-25 -3.67241024039330E-09 - 1.71656132976092E-25 6.83595306028320E-26 -3.67241024039383E-09 - 5.86660077994762E-26 -1.30357686865962E-25 -3.67241024039337E-09 - -1.20159293083265E-25 -1.59236306884293E-25 -3.67241024039317E-09 - -8.83524213847533E-26 -1.11273563846855E-25 -3.67241024039327E-09 - -5.99786723457640E-26 1.53177855132195E-25 -3.67241024039372E-09 - 1.40556080648659E-25 -4.44286461820474E-27 -3.67241024038987E-09 - -5.06890463258813E-26 1.69434700666990E-25 -3.67241024040675E-09 - -2.87170613049415E-25 1.43282383937103E-25 -3.67241024033535E-09 - 3.41292782034819E-26 -8.39095567665486E-26 -3.67241024064094E-09 - -9.53196408996653E-26 1.30963532041171E-25 -3.67241023933420E-09 - 2.75457606328694E-25 -9.66323054459531E-26 -3.67241024491125E-09 - -8.54241697045729E-26 8.83524213847533E-26 -3.67241022116221E-09 - 2.17094521116822E-26 -1.58529487513215E-26 -3.67241032208835E-09 - 1.58529487513215E-26 6.92682983656466E-26 -3.67240989409041E-09 - -6.92682983656466E-26 -2.37895205465690E-25 -3.67241170507284E-09 - -1.38738545123030E-25 1.96899681943165E-26 -3.67240406019146E-09 - -1.96899681943165E-26 -9.30982085905629E-26 -3.67243625254478E-09 - -9.83488667757140E-26 -7.00760919325929E-26 -3.67230104777980E-09 - -7.65384404681634E-26 -4.79627430374375E-26 -3.67286730035930E-09 - -9.88537377550554E-26 9.08767762814606E-26 -3.67050294932171E-09 - 7.67403888599000E-27 1.64587939265312E-26 -3.68034309677901E-09 - 7.93657179524756E-26 -6.86624531904369E-27 -3.63953940370348E-09 - 1.01176144260026E-25 6.90663499739100E-26 -3.80814396863972E-09 - 2.38299102249163E-26 -5.76562658407933E-26 -3.11559076103677E-09 - -3.36244072241404E-26 4.08945493266573E-26 -5.96568804190029E-09 - 1.07335570207992E-25 5.20017108721691E-26 5.40793843461567E-09 - -5.20017108721691E-26 4.11974719142621E-26 -4.63554694216671E-08 - -2.21032514755686E-25 5.23450231381213E-25 -2.46859301522864E-06 - -5.25065818515105E-25 -1.31314922242793E-23 -8.17994673947346E-06 - -1.11087771326457E-23 -3.99890127381104E-23 -1.22031078427885E-05 - -8.24595673138799E-23 1.99557322778418E-23 -1.44736911737957E-05 - 5.94794559213911E-23 -6.99484605490154E-23 -1.56675841684025E-05 - -5.06648125188729E-23 8.01331218410746E-24 -1.62916910416744E-05 - 3.87740912134232E-23 3.68095372586097E-23 -1.66229696591420E-05 - -1.18597020324790E-22 -1.47289847822723E-22 -1.68019811749265E-05 - -7.29469902695201E-23 2.74003577908190E-24 -1.68998767144953E-05 - 5.95570041038180E-23 7.02586532787228E-23 -1.69535115578035E-05 - 6.09528713875012E-23 2.65214783899814E-23 -1.69825628902453E-05 - -2.64697796016969E-23 9.83569447113834E-23 -1.69978525747682E-05 - 4.68132527916729E-23 5.97637992569562E-23 -1.70054836021629E-05 - 1.53028413322310E-23 5.86781247029804E-24 -1.70089587961893E-05 - 7.12150808619872E-23 1.10506159958256E-23 -1.70103018167796E-05 - 1.13608087255330E-23 8.01331218410746E-25 -1.70106703692447E-05 - -7.88406521339605E-25 -1.19585759650733E-23 -1.70107032160216E-05 - -8.23626320858464E-24 - 1 -1 6 8 - SCALAIRE - -22 318379 1 0 0 0 -84 0 2 - - - 318289 - FLUX - REAL*8 - 1 301 0 0 - 8.90592407558313E-26 -3.67241024039287E-09 1.24602157701469E-25 - 3.67241024039352E-09 -1.30054764278357E-25 -3.67241024039383E-09 - 1.29852815886620E-25 1.95687991592745E-25 -3.67241024039298E-09 - 2.25576353569759E-25 -3.97838331721061E-26 -3.67241024039320E-09 - -1.69232752275253E-25 2.24162714827603E-25 -3.67241024039320E-09 - -5.25065818515105E-26 2.05179566004364E-25 -3.67241024039267E-09 - 8.84533955806216E-26 2.22143230910237E-27 -3.67241024039330E-09 - -9.12806730649337E-26 1.91850972149750E-26 -3.67241024039277E-09 - -4.03290938297948E-25 5.45260657688763E-26 -3.67241024039310E-09 - -2.39106895816110E-25 -7.89618211690024E-26 -3.67241024039373E-09 - -2.14267243632510E-25 3.63709053517579E-25 -3.67241024039288E-09 - 1.20563189866738E-25 2.40924431341739E-25 -3.67241024039387E-09 - 2.49406263794675E-25 1.50653500235488E-25 -3.67241024039341E-09 - -5.37182722019300E-26 -7.77501308185829E-26 -3.67241024039329E-09 - 7.79520792103195E-26 -3.95213002628485E-25 -3.67241024039297E-09 - -9.04728794979874E-26 2.50617954145095E-25 -3.67241024039234E-09 - 2.33654289239222E-25 2.94844651935405E-26 -3.67241024039329E-09 - -2.92825168018040E-26 1.64991836048785E-25 -3.67241024039319E-09 - -1.64991836048785E-25 -2.25576353569759E-25 -3.67241024039360E-09 - -2.53647180021143E-25 1.40959977432132E-25 -3.67241024039358E-09 - -1.40959977432132E-25 -1.26621641618835E-25 -3.67241024039332E-09 - -4.60644281551137E-25 1.00570299084816E-25 -3.67241024039293E-09 - 8.07793566946316E-26 4.26111106564182E-26 -3.67241024039334E-09 - -2.22547127693710E-25 -8.58280664880461E-26 -3.67241024039349E-09 - -2.94844651935405E-26 -2.68389412617914E-25 -3.67241024039350E-09 - -3.18876510552058E-25 -1.90033436624121E-25 -3.67241024039338E-09 - -2.78688780596479E-25 -1.21169035041947E-27 -3.67241024039329E-09 - -1.72261978151302E-25 9.30982085905629E-26 -3.67241024039341E-09 - -2.14873088807720E-25 -3.03932329563551E-25 -3.67241024039308E-09 - -4.53374139448620E-25 -3.17058975026429E-26 -3.67241024039331E-09 - -2.61927064082343E-25 5.14968398928277E-26 -3.67241024039304E-09 - 7.47209049425342E-26 1.79734068645555E-25 -3.67241024039341E-09 - 2.41732224908685E-25 -1.64991836048785E-25 -3.67241024039319E-09 - -2.57888096247611E-25 -1.38738545123030E-25 -3.67241024039307E-09 - -1.23188518959313E-25 6.78546596234906E-26 -3.67241024039344E-09 - -6.78546596234906E-26 -4.98812527589350E-26 -3.67241024039295E-09 - 4.98812527589350E-26 -5.87669819953445E-26 -3.67241024039360E-09 - -9.91566603426603E-26 -3.00903103687503E-26 -3.67241024039315E-09 - 3.00903103687503E-26 -3.89760396051598E-26 -3.67241024039290E-09 - 5.51319109440861E-26 1.66001578007468E-25 -3.67241024039339E-09 - 1.27631383577518E-25 -1.93264610891906E-25 -3.67241024039355E-09 - 5.12948915010911E-26 -1.23592415742786E-25 -3.67241024039355E-09 - -1.97909423901847E-26 1.35305422463508E-26 -3.67241024039339E-09 - 1.35305422463508E-25 4.86695624085155E-26 -3.67241024039317E-09 - -4.86695624085155E-26 1.69232752275253E-25 -3.67241024039288E-09 - 2.72327406256777E-25 5.44250915730080E-26 -3.67241024039341E-09 - -2.04068849849813E-25 4.24091622646816E-26 -3.67241024039332E-09 - 2.51223799320304E-25 -1.29549893299015E-25 -3.67241024039321E-09 - -1.64184042481839E-25 1.30559635257698E-25 -3.67241024039296E-09 - 3.02417716625527E-25 2.77477090246060E-25 -3.67241024039350E-09 - 1.53783700307405E-25 3.17159949222297E-25 -3.67241024039317E-09 - 1.33790809525484E-25 8.02744857152902E-26 -3.67241024039314E-09 - -8.03754599111585E-26 -1.71656132976092E-27 -3.67241024039273E-09 - 1.62063584368605E-25 -7.67403888599000E-27 -3.67241024039326E-09 - 1.39344390298240E-25 1.29246970711411E-26 -3.67241024039364E-09 - -1.42979461349498E-25 -7.38121371797196E-26 -3.67241024039292E-09 - -5.46270399647446E-26 2.00635727190291E-25 -3.67241024039364E-09 - 9.29972343946946E-26 -5.14968398928277E-27 -3.67241024039352E-09 - 1.30458661061830E-25 -7.14897306747490E-26 -3.67241024039330E-09 - -9.82478925798457E-26 -9.89547119509237E-26 -3.67241024039371E-09 - -2.32240650497066E-26 5.51319109440861E-26 -3.67241024039262E-09 - 6.56332273143882E-26 -1.61861635976868E-25 -3.67241024039337E-09 - -1.31670351412250E-25 -6.36137433970224E-27 -3.67241024039123E-09 - 6.46234853557053E-27 5.65455496862421E-27 -3.67241024039619E-09 - -5.75552916449250E-27 -1.81652578367053E-25 -3.67241024040573E-09 - -2.90906658296542E-25 1.57317797162795E-25 -3.67241024022561E-09 - 2.33250392455749E-26 -6.80566080152271E-26 -3.67241024160476E-09 - 6.80566080152271E-26 7.63364920764269E-26 -3.67241023306524E-09 - -7.61345436846903E-26 -1.67920087728965E-25 -3.67241028106278E-09 - 5.95747755622908E-26 6.03825691292371E-26 -3.67241002603596E-09 - -6.03825691292371E-26 -4.22072138729450E-26 -3.67241133200713E-09 - 1.47523300163571E-25 1.38334648339557E-26 -3.67240481681615E-09 - -1.17533963990689E-25 -1.97404552922506E-25 -3.67243668973012E-09 - -1.53682726111537E-25 1.70444442625673E-25 -3.67228312479706E-09 - 2.25172456786286E-26 -2.43044889454973E-25 -3.67301398726464E-09 - -2.45064373372339E-25 -2.02655211107657E-25 -3.66957063503093E-09 - -4.16013686977353E-26 1.84782778438970E-26 -3.68565649821336E-09 - -1.14403763918772E-25 -1.53783700307405E-25 -3.61107060340678E-09 - -1.39647312885844E-25 1.97909423901847E-26 -3.95500079421264E-09 - 1.27126512598176E-25 1.35103474071771E-25 -2.38380011125780E-09 - 6.58351757061248E-26 9.99644539096066E-26 -9.65215721567542E-09 - 2.00736701386160E-25 -8.27988406119974E-27 2.16853787387587E-08 - -7.99715631276853E-26 -3.78855182897822E-25 -7.20589351035437E-07 - -2.81919954864264E-25 3.16655078242956E-24 -5.73897194747979E-06 - 7.77097411402356E-24 -1.29246970711411E-25 -1.06742920457331E-05 - 1.42171667782552E-25 -3.77918142360165E-23 -1.36752360237257E-05 - -5.97896486510985E-23 -2.52290086828673E-23 -1.52655577613042E-05 - -3.43279954209506E-23 8.30799527732947E-23 -1.60797779363244E-05 - 6.05392810812247E-23 8.11153988184813E-23 -1.64968021832648E-05 - 8.32350491381484E-24 6.04358835046556E-23 -1.67121660879859E-05 - 4.39956688301642E-23 -1.11410888753236E-22 -1.68239894520389E-05 - -1.22422730657848E-22 -1.78360819581747E-23 -1.68819784812890E-05 - -1.75000398343250E-22 1.56440533349091E-22 -1.69117743413299E-05 - 1.67297278888850E-22 -1.81979734761666E-23 -1.69268098587926E-05 - 1.82496722644512E-23 5.40510831515119E-23 -1.69341821237591E-05 - 1.95679913657076E-23 -3.01662429640432E-23 -1.69376405790826E-05 - 3.01920923581855E-23 -5.73856549958663E-24 -1.69391502063646E-05 - 2.94166105339170E-23 3.08771013029560E-23 -1.69397268550251E-05 - -3.08771013029560E-23 3.75462449916648E-23 -1.69398893856616E-05 - 2.23985000242875E-23 1.72221588472955E-24 -1.69399044986060E-05 - -8.37843487636719E-24 - 1 -1 6 0 - -19 323929 1 0 0 0 0 0 0 - - - 323923 - SCAL - REAL*8 - 4 100 0 0 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 - 1 -1 6 0 - -20 322843 1 0 0 0 0 0 0 - - - 322837 - SCAL - REAL*8 - 4 100 0 0 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 -1.00000000000000E+00 1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 -1.00000000000000E+00 - 1.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - -1.00000000000000E+00 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 40NBRE OBJETS NOMMES 0NBRE OBJETS 84 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 4 1 - 4.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - -2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 2.50000000000000E-01 -2.50000000000000E-01 - 2.50000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - 2 1 - 2.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 5.00000000000000E-01 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 5.00000000000000E-01 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 - ENREGISTREMENT DE TYPE 5 -LABEL AUTOMATIQUE : 1 diff --git a/medtool/resources/pointe.med b/medtool/resources/pointe.med deleted file mode 100644 index 73844dfa6..000000000 Binary files a/medtool/resources/pointe.med and /dev/null differ diff --git a/medtool/resources/poly3D.med b/medtool/resources/poly3D.med deleted file mode 100644 index 5a42c3ff9..000000000 Binary files a/medtool/resources/poly3D.med and /dev/null differ diff --git a/medtool/resources/polygones.med b/medtool/resources/polygones.med deleted file mode 100644 index 0782b0098..000000000 Binary files a/medtool/resources/polygones.med and /dev/null differ diff --git a/medtool/resources/portico_3subs.sauv b/medtool/resources/portico_3subs.sauv deleted file mode 100644 index d672a118f..000000000 --- a/medtool/resources/portico_3subs.sauv +++ /dev/null @@ -1,182 +0,0 @@ - ENREGISTREMENT DE TYPE 4 - NIVEAU 18 NIVEAU ERREUR 0 DIMENSION 3 - DENSITE 0.00000E+00 - ENREGISTREMENT DE TYPE 7 - NOMBRE INFO CASTEM2000 8 - IFOUR 2 NIFOUR 0 IFOMOD 2 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1 - NSDPGE 0 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 1NBRE OBJETS NOMMES 6NBRE OBJETS 6 - PBAS POT1 POT2 POUTL STOT EL1 - 4 1 2 3 5 6 - 2 0 0 2 2 - 0 0 - 1 2 2 3 - 2 0 0 2 3 - 0 0 0 - 4 5 5 6 6 7 - 2 0 0 2 1 - 0 - 3 7 - 1 0 0 1 2 - 0 0 - 1 4 - 2 0 0 2 6 - 0 0 0 0 0 0 - 1 2 2 3 4 5 5 6 6 7 - 3 7 - 1 0 0 1 7 - 0 0 0 0 0 0 0 - 1 2 4 5 6 3 7 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 32NBRE OBJETS NOMMES 4NBRE OBJETS 7 - 0P0 0P1 1P0 1P1 - 1 4 3 7 - 7 - 1 2 6 3 4 5 7 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1 - 96 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 5.00000000000000E-01 5.00000000000000E-01 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 3.33333333333333E-01 - 3.33333333333333E-01 1.00000000000000E+00 0.00000000000000E+00 - 6.66666666666667E-01 3.33333333333333E-01 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 3.00000000000000E+03 -2.00000000000000E+04 - 6.00000000000000E+03 0.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 -1.00000000000000E+03 - -1.00000000000000E+03 1.00000000000000E+03 0.00000000000000E+00 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 39NBRE OBJETS NOMMES 1NBRE OBJETS 1 - CHAM1D - 1 - 3 2 6 11 - CONTRAINTES - -1 27665 6 0 0 0 -1 0 5 -2 - 27882 6 0 0 0 -2 0 5 -3 27931 - 6 0 0 0 -3 0 5 - 19363 19664 19888 - - 27833 27840 27847 27854 27861 27868 - EFFX EFFY EFFZ MOMX MOMY MOMZ - REAL*8 REAL*8 REAL*8 REAL*8 - REAL*8 REAL*8 - 2 2 0 0 - -7.68749999999959E-03 -7.68749999999959E-03 -4.56249999999959E-03 - -4.56249999999959E-03 - 2 2 0 0 - -6.11141334691317E-07 -6.11141334691317E-07 -6.11141334690612E-07 - -6.11141334690612E-07 - 2 2 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 2 2 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 2 2 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 - 2 2 0 0 - 1.32422443924838E-04 1.32728014592183E-04 1.32728014592184E-04 - 1.33033585259529E-04 - 27826 27903 27889 27917 27910 27896 - EFFX EFFY EFFZ MOMX MOMY MOMZ - REAL*8 REAL*8 REAL*8 REAL*8 - REAL*8 REAL*8 - 2 3 0 0 - -8.20833333333293E-03 -8.20833333333293E-03 -6.12499999999960E-03 - -6.12499999999960E-03 -4.04166666666627E-03 -4.04166666666627E-03 - 2 3 0 0 - 6.11141334689149E-07 6.11141334689149E-07 6.11141334689393E-07 - 6.11141334689393E-07 6.11141334688905E-07 6.11141334688905E-07 - 2 3 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 2 3 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 2 3 0 0 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 2 3 0 0 - -1.32422443922787E-04 -1.32626157701017E-04 -1.32626157701017E-04 - -1.32829871479247E-04 -1.32829871479247E-04 -1.33033585257476E-04 - 27651 27952 27938 27966 27959 27945 - EFFX EFFY EFFZ MOMX MOMY MOMZ - REAL*8 REAL*8 REAL*8 REAL*8 - REAL*8 REAL*8 - 2 1 0 0 - -6.11141334691013E-07 -6.11141334691013E-07 - 2 1 0 0 - 0.00000000000000E+00 0.00000000000000E+00 - 2 1 0 0 - -5.81088996365331E-15 -5.81088996365331E-15 - 2 1 0 0 - 0.00000000000000E+00 0.00000000000000E+00 - 2 1 0 0 - -3.66966414738893E-04 -3.66966414744704E-04 - 2 1 0 0 - 0.00000000000000E+00 0.00000000000000E+00 - ENREGISTREMENT DE TYPE 2 - PILE NUMERO 40NBRE OBJETS NOMMES 0NBRE OBJETS 3 - 2 2 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 - 2 2 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 - 2 2 - 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 -5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 1.00000000000000E+00 0.00000000000000E+00 5.00000000000000E-01 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 - -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 - 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 - 0.00000000000000E+00 1.00000000000000E+00 - ENREGISTREMENT DE TYPE 5 -LABEL_AUTOMATIQUE_2 diff --git a/medtool/resources/square1.med b/medtool/resources/square1.med deleted file mode 100644 index 3fd7c4111..000000000 Binary files a/medtool/resources/square1.med and /dev/null differ diff --git a/medtool/resources/square1_split b/medtool/resources/square1_split deleted file mode 100644 index c6a1bce25..000000000 --- a/medtool/resources/square1_split +++ /dev/null @@ -1,6 +0,0 @@ -#MED Fichier V 2.3 -# -3 -Mesh_2 1 Mesh_2_1 localhost /home/vb144235/resources/square1_split1.med -Mesh_2 2 Mesh_2_2 localhost /home/vb144235/resources/square1_split2.med -Mesh_2 3 Mesh_2_3 localhost /home/vb144235/resources/square1_split3.med diff --git a/medtool/resources/square1_split1.med b/medtool/resources/square1_split1.med deleted file mode 100644 index c3ec2b8f5..000000000 Binary files a/medtool/resources/square1_split1.med and /dev/null differ diff --git a/medtool/resources/square1_split2.med b/medtool/resources/square1_split2.med deleted file mode 100644 index 42e0777a1..000000000 Binary files a/medtool/resources/square1_split2.med and /dev/null differ diff --git a/medtool/resources/square1_split3.med b/medtool/resources/square1_split3.med deleted file mode 100644 index c77d0688c..000000000 Binary files a/medtool/resources/square1_split3.med and /dev/null differ diff --git a/medtool/resources/square2.med b/medtool/resources/square2.med deleted file mode 100644 index 9b9d0a40e..000000000 Binary files a/medtool/resources/square2.med and /dev/null differ diff --git a/medtool/resources/square2_split b/medtool/resources/square2_split deleted file mode 100644 index bad1d1a8f..000000000 --- a/medtool/resources/square2_split +++ /dev/null @@ -1,5 +0,0 @@ -#MED Fichier V 2.3 -# -2 -Mesh_3 1 Mesh_3_1 localhost /home/vb144235/resources/square2_split1.med -Mesh_3 2 Mesh_3_2 localhost /home/vb144235/resources/square2_split2.med diff --git a/medtool/resources/square2_split1.med b/medtool/resources/square2_split1.med deleted file mode 100644 index 497957256..000000000 Binary files a/medtool/resources/square2_split1.med and /dev/null differ diff --git a/medtool/resources/square2_split2.med b/medtool/resources/square2_split2.med deleted file mode 100644 index 109f2500f..000000000 Binary files a/medtool/resources/square2_split2.med and /dev/null differ diff --git a/medtool/src/CMakeLists.txt b/medtool/src/CMakeLists.txt deleted file mode 100644 index c360b4a7c..000000000 --- a/medtool/src/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -SET(MED_ENABLE_MICROMED ${MEDCOUPLING_MED_MICROMED}) - -ADD_SUBDIRECTORY(INTERP_KERNEL) -IF(MEDCOUPLING_BUILD_TESTS) - ADD_SUBDIRECTORY(INTERP_KERNELTest) -ENDIF(MEDCOUPLING_BUILD_TESTS) -ADD_SUBDIRECTORY(MEDCoupling) - -IF(MEDCOUPLING_MED_ENABLE_PYTHON) - ADD_SUBDIRECTORY(MEDCoupling_Swig) -ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - -IF(NOT MEDCOUPLING_MED_MICROMED) - ADD_SUBDIRECTORY(MEDLoader) - IF(MEDCOUPLING_MED_ENABLE_RENUMBER) - ADD_SUBDIRECTORY(RENUMBER) - IF(MEDCOUPLING_MED_ENABLE_PYTHON) - ADD_SUBDIRECTORY(RENUMBER_Swig) - ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - ENDIF(MEDCOUPLING_MED_ENABLE_RENUMBER) - IF(MEDCOUPLING_MED_ENABLE_PARTITIONER) - ADD_SUBDIRECTORY(MEDPartitioner) - IF(MEDCOUPLING_MED_ENABLE_PYTHON) - ADD_SUBDIRECTORY(MEDPartitioner_Swig) - ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - ENDIF(MEDCOUPLING_MED_ENABLE_PARTITIONER) -ENDIF(NOT MEDCOUPLING_MED_MICROMED) - -IF(MEDCOUPLING_USE_MPI) - ADD_SUBDIRECTORY(ParaMEDMEM) - IF(NOT MEDCOUPLING_MED_MICROMED) - ADD_SUBDIRECTORY(ParaMEDLoader) - ENDIF(NOT MEDCOUPLING_MED_MICROMED) - IF(MEDCOUPLING_MED_ENABLE_PYTHON) - ADD_SUBDIRECTORY(ParaMEDMEM_Swig) - ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - IF(MEDCOUPLING_BUILD_TESTS) - IF(NOT MEDCOUPLING_MED_MICROMED) - ADD_SUBDIRECTORY(ParaMEDMEMTest) - ENDIF(NOT MEDCOUPLING_MED_MICROMED) - ENDIF(MEDCOUPLING_BUILD_TESTS) -ENDIF(MEDCOUPLING_USE_MPI) - -# Application tests -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${MEDCOUPLING_INSTALL_TESTS} - RENAME CTestTestfile.cmake) - -INSTALL(FILES CTestTestfileInstallMEDCoupling.cmake - DESTINATION ${MEDCOUPLING_INSTALL_TESTS}/MEDCoupling - RENAME CTestTestfile.cmake) diff --git a/medtool/src/CTestTestfileInstall.cmake b/medtool/src/CTestTestfileInstall.cmake deleted file mode 100644 index e9b04a1f6..000000000 --- a/medtool/src/CTestTestfileInstall.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -SUBDIRS(MEDCoupling) diff --git a/medtool/src/CTestTestfileInstallMEDCoupling.cmake b/medtool/src/CTestTestfileInstallMEDCoupling.cmake deleted file mode 100644 index b1a8785b6..000000000 --- a/medtool/src/CTestTestfileInstallMEDCoupling.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -SET(COMPONENT_NAME MEDCOUPLING) - -#SUBDIRS(INTERP_KERNELTest) -SUBDIRS(MEDCoupling) -#SUBDIRS(MEDCoupling_Swig) -#SUBDIRS(MEDLoader) -#SUBDIRS(MEDLoader/Swig) -#SUBDIRS(MEDPartitioner) -#SUBDIRS(ParaMEDMEM_Swig) -#SUBDIRS(ParaMEDMEMTest) -#SUBDIRS(MEDPartitioner_Swig) -#SUBDIRS(RENUMBER_Swig) diff --git a/medtool/src/INTERP_KERNEL/BBTree.txx b/medtool/src/INTERP_KERNEL/BBTree.txx deleted file mode 100644 index 5694fa4bc..000000000 --- a/medtool/src/INTERP_KERNEL/BBTree.txx +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __BBTREE_TXX__ -#define __BBTREE_TXX__ - -#include -#include - -#include -#include -#include - -template -class BBTree -{ - -private: - BBTree* _left; - BBTree* _right; - int _level; - double _max_left; - double _min_right; - const double *_bb; - typename std::vector _elems; - bool _terminal; - ConnType _nbelems; - double _epsilon; - - static const int MIN_NB_ELEMS=15; - static const int MAX_LEVEL=20; -public: - - /*! - Constructor of the bounding box tree - \param bbs pointer to the [xmin1 xmax1 ymin1 ymax1 xmin2 xmax2 ...] array containing the bounding boxes that are to be indexed. - \param elems array to the indices of the elements contained in the BBTree - \param level level in the BBTree recursive structure - \param nbelems nb of elements in the BBTree - \param epsilon precision to which points are decided to be coincident. Epsilon can be positive or negative. - If \a epsilon is positive the request method will enlarge the computed bounding box (more matching elems return). - If negative the given bounding box will be tighten (less matching elems return). - - Parameters \a elems and \a level are used only by BBTree itself for creating trees recursively. A typical use is therefore : - \code - int nbelems=... - double* bbs= new double[2*2*nbelems]; - // filling bbs ... - ... - BBTree<2> tree = new BBTree<2>(elems,0,0,nbelems,1e-12); - \endcode - */ - - BBTree(const double* bbs, ConnType* elems, int level, ConnType nbelems, double epsilon=1e-12): - _left(0), _right(0), _level(level), _bb(bbs), _terminal(false),_nbelems(nbelems),_epsilon(epsilon) - { - if (nbelems < MIN_NB_ELEMS || level> MAX_LEVEL) - { - _terminal=true; - - } - double* nodes=new double [nbelems]; - _elems.resize(nbelems); - for (ConnType i=0; i(nodes, nodes+nbelems/2, nodes+nbelems); - double median = *(nodes+nbelems/2); - delete[] nodes; - // std:: cout << *median < new_elems_left; - std::vector new_elems_right; - - new_elems_left.reserve(nbelems/2+1); - new_elems_right.reserve(nbelems/2+1); - double max_left = -std::numeric_limits::max(); - double min_right= std::numeric_limits::max(); - for (int i=0; imedian) - { - new_elems_right.push_back(elem); - if (minmax_left) max_left = max; - } - - - } - _max_left=max_left+std::abs(_epsilon); - _min_right=min_right-std::abs(_epsilon); - ConnType *tmp; - tmp=0; - if(!new_elems_left.empty()) - tmp=&(new_elems_left[0]); - _left=new BBTree(bbs, tmp, level+1, (int)new_elems_left.size(),_epsilon); - tmp=0; - if(!new_elems_right.empty()) - tmp=&(new_elems_right[0]); - _right=new BBTree(bbs, tmp, level+1, (int)new_elems_right.size(),_epsilon); - - } - - - - ~BBTree() - { - if (_left!=0) delete _left; - if (_right!=0) delete _right; - - } - - - /*! returns in \a elems the list of elements potentially intersecting the bounding box pointed to by \a bb - - \param bb pointer to query bounding box - \param elems list of elements (given in 0-indexing that is to say in \b C \b mode) intersecting the bounding box - */ - - void getIntersectingElems(const double* bb, std::vector& elems) const - { - // terminal node : return list of elements intersecting bb - if (_terminal) - { - for (int i=0; i<_nbelems; i++) - { - const double* const bb_ptr=_bb+_elems[i]*2*dim; - bool intersects = true; - for (int idim=0; idim-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) - intersects=false; - } - if (intersects) - { - elems.push_back(_elems[i]); - } - } - return; - } - - //non terminal node - double min = bb[(_level%dim)*2]; - double max = bb[(_level%dim)*2+1]; - if (max < _min_right) - { - _left->getIntersectingElems(bb, elems); - return; - } - if (min> _max_left) - { - _right->getIntersectingElems(bb,elems); - return; - } - _left->getIntersectingElems(bb,elems); - _right->getIntersectingElems(bb,elems); - } - - /*! - * This method is very close to getIntersectingElems except that it returns number of elems instead of elems themselves. - */ - int getNbOfIntersectingElems(const double* bb) - { - // terminal node : return list of elements intersecting bb - int ret(0); - if (_terminal) - { - for (int i=0; i<_nbelems; i++) - { - const double* const bb_ptr=_bb+_elems[i]*2*dim; - bool intersects = true; - for (int idim=0; idim-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) - intersects=false; - } - if (intersects) - ret++; - } - return ret; - } - //non terminal node - double min = bb[(_level%dim)*2]; - double max = bb[(_level%dim)*2+1]; - if (max < _min_right) - return _left->getNbOfIntersectingElems(bb); - if (min> _max_left) - return _right->getNbOfIntersectingElems(bb); - return _left->getNbOfIntersectingElems(bb)+_right->getNbOfIntersectingElems(bb); - } - - - /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx - \param xx pointer to query point coords - \param elems list of elements (given in 0-indexing) intersecting the bounding box - */ - - void getElementsAroundPoint(const double* xx, std::vector& elems) const - { - // terminal node : return list of elements intersecting bb - if (_terminal) - { - for (ConnType i=0; i<_nbelems; i++) - { - const double* const bb_ptr=_bb+_elems[i]*2*dim; - bool intersects = true; - for (int idim=0; idim_epsilon|| bb_ptr[idim*2+1]-xx[idim]<-_epsilon) - intersects=false; - } - if (intersects) - { - elems.push_back(_elems[i]); - } - } - return; - } - - //non terminal node - if (xx[_level%dim] < _min_right) - { - _left->getElementsAroundPoint(xx, elems); - return; - } - if (xx[_level%dim]> _max_left) - { - _right->getElementsAroundPoint(xx,elems); - return; - } - _left->getElementsAroundPoint(xx,elems); - _right->getElementsAroundPoint(xx,elems); - } - - - - int size() - { - if (_terminal) return _nbelems; - return _left->size()+_right->size(); - } -}; -#endif diff --git a/medtool/src/INTERP_KERNEL/BBTreeDst.txx b/medtool/src/INTERP_KERNEL/BBTreeDst.txx deleted file mode 100644 index a5cbfb43d..000000000 --- a/medtool/src/INTERP_KERNEL/BBTreeDst.txx +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __BBTREEDST_TXX__ -#define __BBTREEDST_TXX__ - -#include -#include - -#include -#include -#include - -template -class BBTreeDst -{ -private: - BBTreeDst* _left; - BBTreeDst* _right; - int _level; - double _max_left; - double _min_right; - const double *_bb; - std::vector _elems; - double *_terminal; - int _nbelems; - - static const int MIN_NB_ELEMS=15; - static const int MAX_LEVEL=20; -public: - BBTreeDst(const double* bbs, int* elems, int level, int nbelems): - _left(0),_right(0),_level(level),_bb(bbs),_terminal(0),_nbelems(nbelems) - { - if((nbelems < MIN_NB_ELEMS || level> MAX_LEVEL)) - _terminal=new double[2*dim]; - _elems.resize(nbelems); - for (int i=0; i(nodes, nodes+nbelems/2, nodes+nbelems); - double median = *(nodes+nbelems/2); - delete [] nodes; - std::vector new_elems_left; - std::vector new_elems_right; - - new_elems_left.reserve(nbelems/2+1); - new_elems_right.reserve(nbelems/2+1); - double max_left = -std::numeric_limits::max(); - double min_right= std::numeric_limits::max(); - for(int i=0; imedian) - { - new_elems_right.push_back(elem); - if (minmax_left) max_left = max; - } - } - _max_left=max_left; - _min_right=min_right; - int *tmp; - tmp=0; - if(!new_elems_left.empty()) - tmp=&(new_elems_left[0]); - _left=new BBTreeDst(bbs, tmp, level+1, (int)new_elems_left.size()); - tmp=0; - if(!new_elems_right.empty()) - tmp=&(new_elems_right[0]); - _right=new BBTreeDst(bbs, tmp, level+1, (int)new_elems_right.size()); - } - - ~BBTreeDst() - { - delete _left; - delete _right; - delete [] _terminal; - } - - void getElemsWhoseMinDistanceToPtSmallerThan(const double *pt, double minOfMaxDstsSq, std::vector& elems) const - { - if(_terminal) - { - for(int i=0; i<_nbelems; i++) - { - if(GetMinDistanceFromBBoxToPt(_bb+_elems[i]*2*dim,pt)minOfMaxDsts) - { _left->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); return ; } - if(pt[_level%dim]-_max_left>minOfMaxDsts) - { _right->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); return ; } - _left->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); - _right->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); - } - } - - void getMinDistanceOfMax(const double *pt, double& minOfMaxDstsSq) const - { - if(_terminal) - { - if(GetMinDistanceFromBBoxToPt(_terminal,pt)>minOfMaxDstsSq)//min it is not a bug - return ; - for(int i=0; i<_nbelems; i++) - { - minOfMaxDstsSq=std::min(minOfMaxDstsSq,GetMaxDistanceFromBBoxToPt(_bb+_elems[i]*2*dim,pt)); - } - } - else - { - double minOfMaxDsts=sqrt(minOfMaxDstsSq); - if(_min_right-pt[_level%dim]>minOfMaxDsts) - { _left->getMinDistanceOfMax(pt,minOfMaxDstsSq); return ; } - if(pt[_level%dim]-_max_left>minOfMaxDsts) - { _right->getMinDistanceOfMax(pt,minOfMaxDstsSq); return ; } - _left->getMinDistanceOfMax(pt,minOfMaxDstsSq); - _right->getMinDistanceOfMax(pt,minOfMaxDstsSq); - } - } - - void fillBBoxTerminal(const double* bbs) - { - for(int j=0;j::max(); - _terminal[2*j+1]=-std::numeric_limits::max(); - } - for(int i=0;i<_nbelems;i++) - { - for(int j=0;jmax -> no cells in this - return std::numeric_limits::max(); - - } - - static double GetMinDistanceFromBBoxToPt(const double *bbox, const double *pt) - { - if(bbox[0]<=bbox[1]) - { - double zeRes=0.; - for (int idim=0; idimmax -> no cells in this - return std::numeric_limits::max(); - } -}; - -#endif diff --git a/medtool/src/INTERP_KERNEL/BBTreePts.txx b/medtool/src/INTERP_KERNEL/BBTreePts.txx deleted file mode 100644 index 6c4378a79..000000000 --- a/medtool/src/INTERP_KERNEL/BBTreePts.txx +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __BBTREEPTS_TXX__ -#define __BBTREEPTS_TXX__ - -#include -#include - -#include -#include -#include - -template -class BBTreePts -{ - -private: - BBTreePts* _left; - BBTreePts* _right; - int _level; - double _max_left; - double _min_right; - const double *_pts; - typename std::vector _elems; - bool _terminal; - ConnType _nbelems; - double _epsilon; - - static const int MIN_NB_ELEMS=15; - static const int MAX_LEVEL=20; -public: - - /*! - Constructor of the bounding box tree - \param [in] pts pointer to the array containing the points that are to be indexed. - \param [in] elems array to the indices of the elements contained in the BBTreePts - \param [in] level level in the BBTreePts recursive structure - \param [in] nbelems nb of elements in the BBTreePts - \param [in] epsilon precision to which points are decided to be coincident. Contrary to BBTree, the absolute epsilon is computed. So the internal epsilon is always positive. - - Parameters \a elems and \a level are used only by BBTreePts itself for creating trees recursively. A typical use is therefore : - \code - int nbelems=... - double* pts= new double[dim*nbelems]; - // filling pts ... - ... - BBTreePts<2> tree = new BBTreePts<2>(elems,0,0,nbelems,1e-12); - \endcode - */ - BBTreePts(const double *pts, const ConnType *elems, int level, ConnType nbelems, double epsilon=1e-12): - _left(0),_right(0),_level(level),_pts(pts),_terminal(nbelems < MIN_NB_ELEMS || level> MAX_LEVEL),_nbelems(nbelems),_epsilon(std::abs(epsilon)) - { - double *nodes=new double[nbelems]; - _elems.resize(nbelems); - for (ConnType i=0;i(nodes, nodes+nbelems/2, nodes+nbelems); - double median=*(nodes+nbelems/2); - delete [] nodes; - std::vector new_elems_left,new_elems_right; - - new_elems_left.reserve(nbelems/2+1); - new_elems_right.reserve(nbelems/2+1); - double max_left = -std::numeric_limits::max(); - double min_right= std::numeric_limits::max(); - for(int i=0;imedian) - { - new_elems_right.push_back(elem); - if(mxmax_left) max_left=mx; - } - } - _max_left=max_left+_epsilon; - _min_right=min_right-_epsilon; - ConnType *tmp; - tmp=0; - if(!new_elems_left.empty()) - tmp=&(new_elems_left[0]); - _left=new BBTreePts(pts, tmp, level+1, (int)new_elems_left.size(),_epsilon); - tmp=0; - if(!new_elems_right.empty()) - tmp=&(new_elems_right[0]); - _right=new BBTreePts(pts, tmp, level+1, (int)new_elems_right.size(),_epsilon); - } - - - - ~BBTreePts() - { - delete _left; - delete _right; - } - - /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx - Contrary to BBTreePts::getElementsAroundPoint the norm 2 is used here. - - \param [in] xx pointer to query point coords - \param [in] threshold - \param elems list of elements (given in 0-indexing) intersecting the bounding box - \sa BBTreePts::getElementsAroundPoint - */ - double getElementsAroundPoint2(const double *xx, double threshold, ConnType& elem) const - { - // terminal node : return list of elements intersecting bb - if(_terminal) - { - double ret=std::numeric_limits::max(); - for(ConnType i=0;i<_nbelems;i++) - { - const double* const bb_ptr=_pts+_elems[i]*dim; - double tmp=0.; - for(int idim=0;idimgetElementsAroundPoint2(xx,threshold,elem); - if(xx[_level%dim]-s>_max_left) - return _right->getElementsAroundPoint2(xx,threshold,elem); - int eleml,elemr; - double retl=_left->getElementsAroundPoint2(xx,threshold,eleml); - double retr=_right->getElementsAroundPoint2(xx,threshold,elemr); - if(retl& elems) const - { - // terminal node : return list of elements intersecting bb - if(_terminal) - { - for(ConnType i=0;i<_nbelems;i++) - { - const double* const bb_ptr=_pts+_elems[i]*dim; - bool intersects = true; - for(int idim=0;idimgetElementsAroundPoint(xx,elems); - return; - } - if(xx[_level%dim]>_max_left) - { - _right->getElementsAroundPoint(xx,elems); - return; - } - _left->getElementsAroundPoint(xx,elems); - _right->getElementsAroundPoint(xx,elems); - } - - int size() const - { - if(_terminal) - return _nbelems; - return _left->size()+_right->size(); - } -}; - -#endif diff --git a/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx b/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx deleted file mode 100644 index 33746d4c4..000000000 --- a/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __BARYCENTRIC3DINTERSECTORP1P1_HXX__ -#define __BARYCENTRIC3DINTERSECTORP1P1_HXX__ - -#include "Intersector3DP1P1.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class Barycentric3DIntersectorP1P1 : public Intersector3DP1P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - Barycentric3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~Barycentric3DIntersectorP1P1(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx b/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx deleted file mode 100644 index 7009c7c36..000000000 --- a/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __BARYCENTRIC3DINTERSECTORP1P1_TXX__ -#define __BARYCENTRIC3DINTERSECTORP1P1_TXX__ - -#include "Barycentric3DIntersectorP1P1.hxx" -#include "Intersector3DP1P1.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - Barycentric3DIntersectorP1P1::Barycentric3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP1P1(targetMesh,srcMesh),_precision(precision) - { - } - - template - Barycentric3DIntersectorP1P1::~Barycentric3DIntersectorP1P1() - { - } - - /** - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void Barycentric3DIntersectorP1P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - const ConnType *startOfCellNodeConnT=Intersector3DP1P1::getStartConnOfTargetCell(targetCell); - Intersector3DP1P1::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - int nbOfNodesT=CoordsT.size()/SPACEDIM; - const double *coordsS=Intersector3DP1P1::_src_mesh.getCoordinatesPtr(); - for(int nodeIdT=0;nodeIdT::ind2C(startOfCellNodeConnT[nodeIdT])]; - if(!resRow.empty()) - continue; - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP1P1::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - if(tS!=NORM_TETRA4) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - // - std::vector connOfCurCellS; - Intersector3DP1P1::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if( PointLocatorAlgos::isElementContainsPointAlg3D(&CoordsT[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) - { - double resLoc[4]; - std::vector localCoordsS; - Intersector3DP1P1::getRealSourceCoordinates(OTT::indFC(*iterCellS),localCoordsS); - std::vector eap(4); - eap[0]=&localCoordsS[0]; eap[1]=&localCoordsS[3]; eap[2]=&localCoordsS[6]; eap[3]=&localCoordsS[9]; - barycentric_coords(eap,&CoordsT[nodeIdT*SPACEDIM],resLoc); - const ConnType *startOfCellNodeConnS=Intersector3DP1P1::getStartConnOfSourceCell(*iterCellS); - for(int nodeIdS=0;nodeIdS<4;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - } - } - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx deleted file mode 100644 index 1e28d1e61..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELAUTOPTR_HXX__ -#define __INTERPKERNELAUTOPTR_HXX__ - -namespace INTERP_KERNEL -{ - template - class AutoPtr - { - public: - AutoPtr(T *ptr=0):_ptr(ptr) { } - ~AutoPtr() { destroyPtr(); } - AutoPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; } - T *operator->() { return _ptr ; } - const T *operator->() const { return _ptr; } - T& operator*() { return *_ptr; } - const T& operator*() const { return *_ptr; } - operator T *() { return _ptr; } - operator const T *() const { return _ptr; } - private: - void destroyPtr() { delete [] _ptr; } - private: - T *_ptr; - }; - - template - class AutoCppPtr - { - public: - AutoCppPtr(T *ptr=0):_ptr(ptr) { } - ~AutoCppPtr() { destroyPtr(); } - AutoCppPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; } - T *operator->() { return _ptr ; } - const T *operator->() const { return _ptr; } - T& operator*() { return *_ptr; } - const T& operator*() const { return *_ptr; } - operator T *() { return _ptr; } - operator const T *() const { return _ptr; } - private: - void destroyPtr() { delete _ptr; } - private: - T *_ptr; - }; - - template - class AutoCPtr - { - public: - AutoCPtr(T *ptr=0):_ptr(ptr) { } - ~AutoCPtr() { destroyPtr(); } - AutoCPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; } - T *operator->() { return _ptr ; } - const T *operator->() const { return _ptr; } - T& operator*() { return *_ptr; } - const T& operator*() const { return *_ptr; } - operator T *() { return _ptr; } - operator const T *() const { return _ptr; } - private: - void destroyPtr() { free(_ptr); } - private: - T *_ptr; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.cxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.cxx deleted file mode 100644 index dae549346..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.cxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelException.hxx" - -INTERP_KERNEL::Exception::Exception(const char *reason):_reason(reason) -{ -} - -INTERP_KERNEL::Exception::Exception(const char *reason, const char *file, int line):_reason(reason) -{ -} - -INTERP_KERNEL::Exception::~Exception() throw () -{ -} - -const char *INTERP_KERNEL::Exception::what() const throw() -{ - return _reason.c_str(); -} diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.hxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.hxx deleted file mode 100644 index 86fe0cc96..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELEXCEPTION_HXX__ -#define __INTERPKERNELEXCEPTION_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class Exception : public std::exception - { - public: - INTERPKERNEL_EXPORT Exception(const char *reason); - INTERPKERNEL_EXPORT Exception(const char *reason, const char *file, int line); - INTERPKERNEL_EXPORT ~Exception() throw (); - INTERPKERNEL_EXPORT const char *what() const throw(); - protected: - std::string _reason; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx deleted file mode 100644 index 3fcc84ee6..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (C) 2001-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/* - * Copyright (c) 1996-1998 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef __INTERPKERNELHASHFUN_HXX__ -#define __INTERPKERNELHASHFUN_HXX__ - -#include - -namespace INTERP_KERNEL -{ - template - struct hash { }; - - inline std::size_t __stl_hash_string(const char* __s) - { - unsigned long __h = 0; - for ( ; *__s; ++__s) - __h = 5 * __h + *__s; - return std::size_t(__h); - } - - template<> - struct hash - { - std::size_t operator()(const char* __s) const - { return __stl_hash_string(__s); } - }; - - template<> - struct hash - { - std::size_t operator()(const char* __s) const - { return __stl_hash_string(__s); } - }; - - template<> - struct hash - { - std::size_t operator()(char __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned char __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned char __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(short __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned short __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(int __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned int __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(long __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned long __x) const { return __x; } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx deleted file mode 100644 index f4ff608b0..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright (C) 2001-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/* - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef __INTERPKERNELHASHMAP__ -#define __INTERPKERNELHASHMAP__ - -#include "InterpKernelStlExt.hxx" -#include "InterpKernelHashTable.hxx" - -namespace INTERP_KERNEL -{ - template, - class _EqualKey = std::equal_to<_Key>, class _Alloc = std::allocator<_Tp> > - class HashMap - { - private: - typedef hashtable,_Key, _HashFn, - STLEXT::Select1st >, - _EqualKey, _Alloc> _Ht; - - _Ht _M_ht; - - public: - typedef typename _Ht::key_type key_type; - typedef _Tp data_type; - typedef _Tp mapped_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - - key_equal key_eq() const { return _M_ht.key_eq(); } - - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - - HashMap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} - - explicit HashMap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} - - HashMap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} - - HashMap(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} - - template - HashMap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - - template - HashMap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - - template - HashMap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - - template - HashMap(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) - { _M_ht.insert_unique(__f, __l); } - - size_type size() const { return _M_ht.size(); } - - size_type max_size() const { return _M_ht.max_size(); } - - bool empty() const { return _M_ht.empty(); } - - void swap(HashMap& __hs) { _M_ht.swap(__hs._M_ht); } - - template - friend bool operator== (const HashMap<_K1, _T1, _HF, _EqK, _Al>&, - const HashMap<_K1, _T1, _HF, _EqK, _Al>&); - - iterator begin() { return _M_ht.begin(); } - - iterator end() { return _M_ht.end(); } - - const_iterator begin() const { return _M_ht.begin(); } - - const_iterator end() const { return _M_ht.end(); } - - std::pair insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); } - - template - void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } - - std::pair - insert_noresize(const value_type& __obj) { return _M_ht.insert_unique_noresize(__obj); } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - - const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - _Tp& operator[](const key_type& __key) { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } - - std::pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - - void erase(iterator __it) { _M_ht.erase(__it); } - - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - - void clear() { _M_ht.clear(); } - - void resize(size_type __hint) { _M_ht.resize(__hint); } - - size_type bucket_count() const { return _M_ht.bucket_count(); } - - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - - size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } - }; - - template - inline bool operator==(const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { return __hm1._M_ht == __hm2._M_ht; } - - template - inline bool operator!=(const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { return !(__hm1 == __hm2); } - - template - inline void swap(HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { __hm1.swap(__hm2); } - - template, - class _EqualKey = std::equal_to<_Key>, - class _Alloc = std::allocator<_Tp> > - class HashMultiMap - { - private: - typedef hashtable, _Key, _HashFn, - STLEXT::Select1st >, _EqualKey, _Alloc> - _Ht; - _Ht _M_ht; - public: - typedef typename _Ht::key_type key_type; - typedef _Tp data_type; - typedef _Tp mapped_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - - key_equal key_eq() const { return _M_ht.key_eq(); } - - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - - HashMultiMap() : _M_ht(100, hasher(), key_equal(), allocator_type()) { } - - explicit HashMultiMap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} - - HashMultiMap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} - - HashMultiMap(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} - - template - HashMultiMap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - - template - HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - - template - HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - - template - HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { _M_ht.insert_equal(__f, __l); } - - size_type size() const { return _M_ht.size(); } - - size_type max_size() const { return _M_ht.max_size(); } - - bool empty() const { return _M_ht.empty(); } - - void swap(HashMultiMap& __hs) { _M_ht.swap(__hs._M_ht); } - - template - friend bool operator==(const HashMultiMap<_K1, _T1, _HF, _EqK, _Al>&, - const HashMultiMap<_K1, _T1, _HF, _EqK, _Al>&); - - iterator begin() { return _M_ht.begin(); } - - iterator end() { return _M_ht.end(); } - - const_iterator begin() const { return _M_ht.begin(); } - - const_iterator end() const { return _M_ht.end(); } - - iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } - - template - void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } - - iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - - const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } - - std::pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - - void erase(iterator __it) { _M_ht.erase(__it); } - - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - - void clear() { _M_ht.clear(); } - - void resize(size_type __hint) { _M_ht.resize(__hint); } - - size_type bucket_count() const { return _M_ht.bucket_count(); } - - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - - size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } - }; - - template - inline bool operator==(const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) - { return __hm1._M_ht == __hm2._M_ht; } - - template - inline bool operator!=(const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) - { return !(__hm1 == __hm2); } - - template - inline void swap(HashMultiMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - HashMultiMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { __hm1.swap(__hm2); } - -} - -namespace std -{ - // Specialization of insert_iterator so that it will work for HashMap - // and HashMultiMap. - template - class insert_iterator > - { - protected: - typedef INTERP_KERNEL::HashMap<_Key, _Tp, _HashFn, _EqKey, _Alloc> - _Container; - _Container* container; - public: - typedef _Container container_type; - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; - - insert_iterator(_Container& __x) : container(&__x) {} - - insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} - - insert_iterator<_Container>& operator=(const typename _Container::value_type& __value__) - { - container->insert(__value__); - return *this; - } - - insert_iterator<_Container>& operator*() { return *this; } - - insert_iterator<_Container>& operator++() { return *this; } - - insert_iterator<_Container>& operator++(int) { return *this; } - }; - - template - class insert_iterator > - { - protected: - typedef INTERP_KERNEL::HashMultiMap<_Key, _Tp, _HashFn, _EqKey, _Alloc> - _Container; - _Container* container; - typename _Container::iterator iter; - - public: - typedef _Container container_type; - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; - - insert_iterator(_Container& __x) : container(&__x) {} - - insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} - - insert_iterator<_Container>& operator=(const typename _Container::value_type& __value__) - { - container->insert(__value__); - return *this; - } - - insert_iterator<_Container>& operator*() { return *this; } - - insert_iterator<_Container>& operator++() { return *this; } - - insert_iterator<_Container>& operator++(int) { return *this; } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx deleted file mode 100644 index 6caa116b9..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx +++ /dev/null @@ -1,1005 +0,0 @@ -// Copyright (C) 2001-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/* - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef __INTERPKERNELHASHTABLE_HXX__ -#define __INTERPKERNELHASHTABLE_HXX__ - -#include "InterpKernelStlExt.hxx" -#include "InterpKernelHashFun.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - struct _Hashtable_node - { - _Hashtable_node* _M_next; - _Val _M_val; - }; - - template > - class hashtable; - - template - struct _Hashtable_iterator; - - template - struct _Hashtable_const_iterator; - - template - struct _Hashtable_iterator - { - typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> - _Hashtable; - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - typedef std::forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef std::ptrdiff_t difference_type; - typedef std::size_t size_type; - typedef _Val& reference; - typedef _Val* pointer; - - _Node* _M_cur; - _Hashtable* _M_ht; - - _Hashtable_iterator(_Node* __n, _Hashtable* __tab) - : _M_cur(__n), _M_ht(__tab) { } - - _Hashtable_iterator() { } - - reference - operator*() const - { return _M_cur->_M_val; } - - pointer - operator->() const - { return &(operator*()); } - - iterator& - operator++(); - - iterator - operator++(int); - - bool - operator==(const iterator& __it) const - { return _M_cur == __it._M_cur; } - - bool - operator!=(const iterator& __it) const - { return _M_cur != __it._M_cur; } - }; - - template - struct _Hashtable_const_iterator - { - typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> - _Hashtable; - typedef _Hashtable_iterator<_Val,_Key,_HashFcn, - _ExtractKey,_EqualKey,_Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - - typedef std::forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef std::ptrdiff_t difference_type; - typedef std::size_t size_type; - typedef const _Val& reference; - typedef const _Val* pointer; - - const _Node* _M_cur; - const _Hashtable* _M_ht; - - _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) - : _M_cur(__n), _M_ht(__tab) { } - - _Hashtable_const_iterator() { } - - _Hashtable_const_iterator(const iterator& __it) - : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { } - - reference operator*() const { return _M_cur->_M_val; } - - pointer operator->() const { return &(operator*()); } - - const_iterator& operator++(); - - const_iterator operator++(int); - - bool operator==(const const_iterator& __it) const { return _M_cur == __it._M_cur; } - - bool operator!=(const const_iterator& __it) const { return _M_cur != __it._M_cur; } - }; - - // Note: assumes long is at least 32 bits. - enum { _S_num_primes = 28 }; - - static const unsigned long __stl_prime_list[_S_num_primes] = - { - 53ul, 97ul, 193ul, 389ul, 769ul, - 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, - 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, - 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, - 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, - 1610612741ul, 3221225473ul, 4294967291ul - }; - - inline unsigned long - __stl_next_prime(unsigned long __n) - { - const unsigned long* __first = __stl_prime_list; - const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; - const unsigned long* pos = std::lower_bound(__first, __last, __n); - return pos == __last ? *(__last - 1) : *pos; - } - - // Forward declaration of operator==. - template - class hashtable; - - template - bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); - - // Hashtables handle allocators a bit differently than other - // containers do. If we're using standard-conforming allocators, then - // a hashtable unconditionally has a member variable to hold its - // allocator, even if it so happens that all instances of the - // allocator type are identical. This is because, for hashtables, - // this extra storage is negligible. Additionally, a base class - // wouldn't serve any other purposes; it wouldn't, for example, - // simplify the exception-handling code. - template - class hashtable - { - public: - typedef _Key key_type; - typedef _Val value_type; - typedef _HashFcn hasher; - typedef _EqualKey key_equal; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - - hasher hash_funct() const { return _M_hash; } - - key_equal key_eq() const { return _M_equals; } - - private: - typedef _Hashtable_node<_Val> _Node; - - public: - typedef typename _Alloc::template rebind::other allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } - - private: - typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; - typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; - typedef std::vector<_Node*, _Nodeptr_Alloc> _Vector_type; - - _Node_Alloc _M_node_allocator; - - _Node *_M_get_node() { return _M_node_allocator.allocate(1); } - - void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } - - private: - hasher _M_hash; - key_equal _M_equals; - _ExtractKey _M_get_key; - _Vector_type _M_buckets; - size_type _M_num_elements; - - public: - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - const_iterator; - - friend struct - _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; - - friend struct - _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc>; - - public: - hashtable(size_type __n, const _HashFcn& __hf, - const _EqualKey& __eql, const _ExtractKey& __ext, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), - _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) - { _M_initialize_buckets(__n); } - - hashtable(size_type __n, const _HashFcn& __hf, - const _EqualKey& __eql, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), - _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) - { _M_initialize_buckets(__n); } - - hashtable(const hashtable& __ht) - : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash), - _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), - _M_buckets(__ht.get_allocator()), _M_num_elements(0) - { _M_copy_from(__ht); } - - hashtable& operator= (const hashtable& __ht) - { - if (&__ht != this) - { - clear(); - _M_hash = __ht._M_hash; - _M_equals = __ht._M_equals; - _M_get_key = __ht._M_get_key; - _M_copy_from(__ht); - } - return *this; - } - - ~hashtable() - { clear(); } - - size_type size() const { return _M_num_elements; } - - size_type max_size() const { return size_type(-1); } - - bool empty() const { return size() == 0; } - - void swap(hashtable& __ht) - { - std::swap(_M_hash, __ht._M_hash); - std::swap(_M_equals, __ht._M_equals); - std::swap(_M_get_key, __ht._M_get_key); - _M_buckets.swap(__ht._M_buckets); - std::swap(_M_num_elements, __ht._M_num_elements); - } - - iterator begin() - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return iterator(_M_buckets[__n], this); - return end(); - } - - iterator end() { return iterator(0, this); } - - const_iterator begin() const - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return const_iterator(_M_buckets[__n], this); - return end(); - } - - const_iterator end() const { return const_iterator(0, this); } - - template - friend bool operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, - const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); - - public: - size_type bucket_count() const { return _M_buckets.size(); } - - size_type max_bucket_count() const { return __stl_prime_list[(int)_S_num_primes - 1]; } - - size_type elems_in_bucket(size_type __bucket) const - { - size_type __result = 0; - for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) - __result += 1; - return __result; - } - - std::pair insert_unique(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_unique_noresize(__obj); - } - - iterator insert_equal(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_equal_noresize(__obj); - } - - std::pair insert_unique_noresize(const value_type& __obj); - - iterator insert_equal_noresize(const value_type& __obj); - - template - void insert_unique(_InputIterator __f, _InputIterator __l) - { insert_unique(__f, __l, __iterator_category(__f)); } - - template - void insert_equal(_InputIterator __f, _InputIterator __l) - { insert_equal(__f, __l, __iterator_category(__f)); } - - template - void insert_unique(_InputIterator __f, _InputIterator __l, - std::input_iterator_tag) - { - for ( ; __f != __l; ++__f) - insert_unique(*__f); - } - - template - void insert_equal(_InputIterator __f, _InputIterator __l, - std::input_iterator_tag) - { - for ( ; __f != __l; ++__f) - insert_equal(*__f); - } - - template - void insert_unique(_ForwardIterator __f, _ForwardIterator __l, - std::forward_iterator_tag) - { - size_type __n = std::distance(__f, __l); - resize(_M_num_elements + __n); - for ( ; __n > 0; --__n, ++__f) - insert_unique_noresize(*__f); - } - - template - void - insert_equal(_ForwardIterator __f, _ForwardIterator __l, - std::forward_iterator_tag) - { - size_type __n = std::distance(__f, __l); - resize(_M_num_elements + __n); - for ( ; __n > 0; --__n, ++__f) - insert_equal_noresize(*__f); - } - - reference find_or_insert(const value_type& __obj); - - iterator find(const key_type& __key) - { - size_type __n = _M_bkt_num_key(__key); - _Node* __first; - for (__first = _M_buckets[__n]; - __first && !_M_equals(_M_get_key(__first->_M_val), __key); - __first = __first->_M_next) - { } - return iterator(__first, this); - } - - const_iterator find(const key_type& __key) const - { - size_type __n = _M_bkt_num_key(__key); - const _Node* __first; - for (__first = _M_buckets[__n]; - __first && !_M_equals(_M_get_key(__first->_M_val), __key); - __first = __first->_M_next) - { } - return const_iterator(__first, this); - } - - size_type count(const key_type& __key) const - { - const size_type __n = _M_bkt_num_key(__key); - size_type __result = 0; - for (const _Node* __cur = _M_buckets[__n]; __cur; - __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), __key)) - ++__result; - return __result; - } - - std::pair equal_range(const key_type& __key); - - std::pair equal_range(const key_type& __key) const; - - size_type erase(const key_type& __key); - - void erase(const iterator& __it); - - void erase(iterator __first, iterator __last); - - void erase(const const_iterator& __it); - - void erase(const_iterator __first, const_iterator __last); - - void resize(size_type __num_elements_hint); - - void clear(); - - private: - size_type _M_next_size(size_type __n) const { return __stl_next_prime(__n); } - - void _M_initialize_buckets(size_type __n) - { - const size_type __n_buckets = _M_next_size(__n); - _M_buckets.reserve(__n_buckets); - _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); - _M_num_elements = 0; - } - - size_type _M_bkt_num_key(const key_type& __key) const - { return _M_bkt_num_key(__key, _M_buckets.size()); } - - size_type _M_bkt_num(const value_type& __obj) const - { return _M_bkt_num_key(_M_get_key(__obj)); } - - size_type _M_bkt_num_key(const key_type& __key, std::size_t __n) const - { return _M_hash(__key) % __n; } - - size_type _M_bkt_num(const value_type& __obj, std::size_t __n) const - { return _M_bkt_num_key(_M_get_key(__obj), __n); } - - _Node* _M_new_node(const value_type& __obj) - { - _Node* __n = _M_get_node(); - __n->_M_next = 0; - try - { - this->get_allocator().construct(&__n->_M_val, __obj); - return __n; - } - catch(...) - { - _M_put_node(__n); - throw; - } - } - - void _M_delete_node(_Node* __n) - { - this->get_allocator().destroy(&__n->_M_val); - _M_put_node(__n); - } - - void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); - - void _M_erase_bucket(const size_type __n, _Node* __last); - - void _M_copy_from(const hashtable& __ht); - }; - - template - _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& - _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++() - { - const _Node* __old = _M_cur; - _M_cur = _M_cur->_M_next; - if (!_M_cur) - { - size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); - while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) - _M_cur = _M_ht->_M_buckets[__bucket]; - } - return *this; - } - - template - inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> - _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++(int) - { - iterator __tmp = *this; - ++*this; - return __tmp; - } - - template - _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& - _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++() - { - const _Node* __old = _M_cur; - _M_cur = _M_cur->_M_next; - if (!_M_cur) - { - size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); - while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) - _M_cur = _M_ht->_M_buckets[__bucket]; - } - return *this; - } - - template - inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> - _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++(int) - { - const_iterator __tmp = *this; - ++*this; - return __tmp; - } - - template - bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) - { - typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; - - if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) - return false; - - for (std::size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) - { - _Node* __cur1 = __ht1._M_buckets[__n]; - _Node* __cur2 = __ht2._M_buckets[__n]; - // Check same length of lists - for (; __cur1 && __cur2; - __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) - { } - if (__cur1 || __cur2) - return false; - // Now check one's elements are in the other - for (__cur1 = __ht1._M_buckets[__n] ; __cur1; - __cur1 = __cur1->_M_next) - { - bool _found__cur1 = false; - for (__cur2 = __ht2._M_buckets[__n]; - __cur2; __cur2 = __cur2->_M_next) - { - if (__cur1->_M_val == __cur2->_M_val) - { - _found__cur1 = true; - break; - } - } - if (!_found__cur1) - return false; - } - } - return true; - } - - template - inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) - { return !(__ht1 == __ht2); } - - template - inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, - hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) - { __ht1.swap(__ht2); } - - template - std::pair::iterator, bool> - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - insert_unique_noresize(const value_type& __obj) - { - const size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - return std::pair(iterator(__cur, this), false); - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return std::pair(iterator(__tmp, this), true); - } - - template - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - insert_equal_noresize(const value_type& __obj) - { - const size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - { - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __cur->_M_next; - __cur->_M_next = __tmp; - ++_M_num_elements; - return iterator(__tmp, this); - } - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return iterator(__tmp, this); - } - - template - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - find_or_insert(const value_type& __obj) - { - resize(_M_num_elements + 1); - - size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - return __cur->_M_val; - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return __tmp->_M_val; - } - - template - std::pair::iterator, - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) - { - typedef std::pair _Pii; - const size_type __n = _M_bkt_num_key(__key); - - for (_Node* __first = _M_buckets[__n]; __first; - __first = __first->_M_next) - if (_M_equals(_M_get_key(__first->_M_val), __key)) - { - for (_Node* __cur = __first->_M_next; __cur; - __cur = __cur->_M_next) - if (!_M_equals(_M_get_key(__cur->_M_val), __key)) - return _Pii(iterator(__first, this), iterator(__cur, this)); - for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) - if (_M_buckets[__m]) - return _Pii(iterator(__first, this), - iterator(_M_buckets[__m], this)); - return _Pii(iterator(__first, this), end()); - } - return _Pii(end(), end()); - } - - template - std::pair::const_iterator, - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) const - { - typedef std::pair _Pii; - const size_type __n = _M_bkt_num_key(__key); - - for (const _Node* __first = _M_buckets[__n]; __first; - __first = __first->_M_next) - { - if (_M_equals(_M_get_key(__first->_M_val), __key)) - { - for (const _Node* __cur = __first->_M_next; __cur; - __cur = __cur->_M_next) - if (!_M_equals(_M_get_key(__cur->_M_val), __key)) - return _Pii(const_iterator(__first, this), - const_iterator(__cur, this)); - for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) - if (_M_buckets[__m]) - return _Pii(const_iterator(__first, this), - const_iterator(_M_buckets[__m], this)); - return _Pii(const_iterator(__first, this), end()); - } - } - return _Pii(end(), end()); - } - - template - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key) - { - const size_type __n = _M_bkt_num_key(__key); - _Node* __first = _M_buckets[__n]; - size_type __erased = 0; - - if (__first) - { - _Node* __cur = __first; - _Node* __next = __cur->_M_next; - while (__next) - { - if (_M_equals(_M_get_key(__next->_M_val), __key)) - { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - ++__erased; - --_M_num_elements; - } - else - { - __cur = __next; - __next = __cur->_M_next; - } - } - if (_M_equals(_M_get_key(__first->_M_val), __key)) - { - _M_buckets[__n] = __first->_M_next; - _M_delete_node(__first); - ++__erased; - --_M_num_elements; - } - } - return __erased; - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it) - { - _Node* __p = __it._M_cur; - if (__p) - { - const size_type __n = _M_bkt_num(__p->_M_val); - _Node* __cur = _M_buckets[__n]; - if (__cur == __p) - { - _M_buckets[__n] = __cur->_M_next; - _M_delete_node(__cur); - --_M_num_elements; - } - else - { - _Node* __next = __cur->_M_next; - while (__next) - { - if (__next == __p) - { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - --_M_num_elements; - break; - } - else - { - __cur = __next; - __next = __cur->_M_next; - } - } - } - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first, iterator __last) - { - size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); - - size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); - - if (__first._M_cur == __last._M_cur) - return; - else if (__f_bucket == __l_bucket) - _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); - else - { - _M_erase_bucket(__f_bucket, __first._M_cur, 0); - for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) - _M_erase_bucket(__n, 0); - if (__l_bucket != _M_buckets.size()) - _M_erase_bucket(__l_bucket, __last._M_cur); - } - } - - template - inline void - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - erase(const_iterator __first, const_iterator __last) - { - erase(iterator(const_cast<_Node*>(__first._M_cur), - const_cast(__first._M_ht)), - iterator(const_cast<_Node*>(__last._M_cur), - const_cast(__last._M_ht))); - } - - template - inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const const_iterator& __it) - { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast(__it._M_ht))); } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(size_type __num_elements_hint) - { - const size_type __old_n = _M_buckets.size(); - if (__num_elements_hint > __old_n) - { - const size_type __n = _M_next_size(__num_elements_hint); - if (__n > __old_n) - { - _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); - try - { - for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) - { - _Node* __first = _M_buckets[__bucket]; - while (__first) - { - size_type __new_bucket = _M_bkt_num(__first->_M_val,__n); - _M_buckets[__bucket] = __first->_M_next; - __first->_M_next = __tmp[__new_bucket]; - __tmp[__new_bucket] = __first; - __first = _M_buckets[__bucket]; - } - } - _M_buckets.swap(__tmp); - } - catch(...) - { - for (size_type __bucket = 0; __bucket < __tmp.size();++__bucket) - { - while (__tmp[__bucket]) - { - _Node* __next = __tmp[__bucket]->_M_next; - _M_delete_node(__tmp[__bucket]); - __tmp[__bucket] = __next; - } - } - throw; - } - } - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) - { - _Node* __cur = _M_buckets[__n]; - if (__cur == __first) - _M_erase_bucket(__n, __last); - else - { - _Node* __next; - for (__next = __cur->_M_next; - __next != __first; - __cur = __next, __next = __cur->_M_next) - ; - while (__next != __last) - { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - --_M_num_elements; - } - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(const size_type __n, _Node* __last) - { - _Node* __cur = _M_buckets[__n]; - while (__cur != __last) - { - _Node* __next = __cur->_M_next; - _M_delete_node(__cur); - __cur = __next; - _M_buckets[__n] = __cur; - --_M_num_elements; - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear() - { - for (size_type __i = 0; __i < _M_buckets.size(); ++__i) - { - _Node* __cur = _M_buckets[__i]; - while (__cur != 0) - { - _Node* __next = __cur->_M_next; - _M_delete_node(__cur); - __cur = __next; - } - _M_buckets[__i] = 0; - } - _M_num_elements = 0; - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(const hashtable& __ht) - { - _M_buckets.clear(); - _M_buckets.reserve(__ht._M_buckets.size()); - _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); - try - { - for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { - const _Node* __cur = __ht._M_buckets[__i]; - if (__cur) - { - _Node* __local_copy = _M_new_node(__cur->_M_val); - _M_buckets[__i] = __local_copy; - for (_Node* __next = __cur->_M_next; - __next; - __cur = __next, __next = __cur->_M_next) - { - __local_copy->_M_next = _M_new_node(__next->_M_val); - __local_copy = __local_copy->_M_next; - } - } - } - _M_num_elements = __ht._M_num_elements; - } - catch(...) - { - clear(); - throw; - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx b/medtool/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx deleted file mode 100644 index 162cc7871..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPKERNELSTLEXT_HXX__ -#define __INTERPKERNELSTLEXT_HXX__ - -#include - -namespace INTERP_KERNEL -{ - namespace STLEXT - { - template - struct Select1st : public std::unary_function<_Pair, typename _Pair::first_type> - { - typename _Pair::first_type& operator()(_Pair& __x) const { return __x.first; } - const typename _Pair::first_type&operator()(const _Pair& __x) const { return __x.first; } - }; - - template - inline void Construct(_T1* __p, const _T2& __value__) { ::new(static_cast(__p)) _T1(__value__); } - - template inline void Destroy(_Tp* __pointer) { __pointer->~_Tp(); } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes b/medtool/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes deleted file mode 100644 index b02d2cb72..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __NORMALIZEDGEOMETRICTYPES__ -#define __NORMALIZEDGEOMETRICTYPES__ - -namespace INTERP_KERNEL -{ - typedef enum - { - NORM_POINT1 = 0, - NORM_SEG2 = 1, - NORM_SEG3 = 2, - NORM_SEG4 = 10, - NORM_POLYL = 33, - NORM_TRI3 = 3, - NORM_QUAD4 = 4, - NORM_POLYGON = 5, - NORM_TRI6 = 6, - NORM_TRI7 = 7, - NORM_QUAD8 = 8, - NORM_QUAD9 = 9, - NORM_QPOLYG = 32, - // - NORM_TETRA4 = 14, - NORM_PYRA5 = 15, - NORM_PENTA6 = 16, - NORM_HEXA8 = 18, - NORM_TETRA10 = 20, - NORM_HEXGP12 = 22, - NORM_PYRA13 = 23, - NORM_PENTA15 = 25, - NORM_HEXA20 = 30, - NORM_HEXA27 = 27, - NORM_POLYHED = 31, - NORM_ERROR = 40, - NORM_MAXTYPE = 33 - } NormalizedCellType; - - /*! Type describing the different ways in which the hexahedron can be split into tetrahedra. - * The PLANAR_* policies persume that each face is to be considered planar, while the general - * policies make no such hypothesis. The integer at the end gives the number of tetrahedra - * that result from the split. - * - * The images below illustrates the policies in their respective order. - * - * \image html tetra_simplexize_5_6.jpg - * \image html tetra_simplexize_24_48.jpg - */ - typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx b/medtool/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx deleted file mode 100644 index 26732f94b..000000000 --- a/medtool/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __NORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __NORMALIZEDUNSTRUCTUREDMESH_HXX__ - -#include "NormalizedGeometricTypes" - -namespace INTERP_KERNEL -{ - typedef enum - { - ALL_C_MODE , - ALL_FORTRAN_MODE - } NumberingPolicy; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/BoundingBox.cxx b/medtool/src/INTERP_KERNEL/BoundingBox.cxx deleted file mode 100644 index de2748b7a..000000000 --- a/medtool/src/INTERP_KERNEL/BoundingBox.cxx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "BoundingBox.hxx" - -#include -#include -#include - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating box from an array of the points corresponding - * to the vertices of the element. - * Each point is represented by an array of three doubles. - * - * @param pts array of points - * @param numPts number of vertices - * - */ - BoundingBox::BoundingBox(const double** pts, const unsigned numPts) - :_coords(new double[6]) - { - assert(numPts > 1); - - // initialize with first two points - const double* pt1 = pts[0]; - const double* pt2 = pts[1]; - - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - _coords[c] = std::min(pt1[c], pt2[c]); - _coords[c + 3] = std::max(pt1[c], pt2[c]); - } - - for(unsigned i = 2 ; i < numPts ; ++i) - { - updateWithPoint(pts[i]); - } - - assert(isValid()); - } - - /** - * Constructor creating box from union of two boxes, resulting in a box that encloses both of them - * - * @param box1 the first box - * @param box2 the second box - */ - BoundingBox::BoundingBox(const BoundingBox& box1, const BoundingBox& box2) - : _coords(new double[6]) - { - assert(_coords != 0); - - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - _coords[c] = std::min(box1._coords[c], box2._coords[c]); - _coords[c + 3] = std::max(box1._coords[c + 3], box2._coords[c + 3]); - } - - assert(isValid()); - } - - /** - * Destructor - * - */ - BoundingBox::~BoundingBox() - { - delete[] _coords; - } - - /** - * Determines if the intersection with a given box is empty - * - * @param box BoundingBox with which intersection is tested - * @return true if intersection between boxes is empty, false if not - */ - bool BoundingBox::isDisjointWith(const BoundingBox& box) const - { - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - const double otherMinCoord = box.getCoordinate(c); - const double otherMaxCoord = box.getCoordinate(BoxCoord(c + 3)); - - // boxes are disjoint if there exists a direction in which the - // minimum coordinate of one is greater than the maximum coordinate of the other - - // more stable version ? - // const double tol = 1.0e-2*_coords[c]; - // if(_coords[c] > otherMaxCoord + tol - // || _coords[c + 3] < otherMinCoord - tol) - - - if(_coords[c] > otherMaxCoord - || _coords[c + 3] < otherMinCoord) - - { - return true; - } - - } - return false; - } - - - - /** - * Updates the bounding box to include a given point - * - * @param pt point to be included - * - */ - void BoundingBox::updateWithPoint(const double* pt) - { - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - const double ptVal = pt[c]; - - // update min and max coordinates - _coords[c] = std::min(_coords[c], ptVal); - _coords[c + 3] = std::max(_coords[c + 3], ptVal); - - } - } - - /** - * Checks if the box is valid, which it is if its minimum coordinates are - * smaller than its maximum coordinates in all directions. - * - * @return true if the box is valid, false if not - */ - bool BoundingBox::isValid() const - { - bool valid = true; - for(BoxCoord c = XMIN ; c < ZMIN ; c = BoxCoord(c + 1)) - { - if(_coords[c] > _coords[c + 3]) - { - std::cout << "+++ Error in BoundingBox |: coordinate " << c << " is invalid : " - <<_coords[c] << " > " << _coords[c+3] << std::endl; - valid = false; - } - } - return valid; - } - -} diff --git a/medtool/src/INTERP_KERNEL/BoundingBox.hxx b/medtool/src/INTERP_KERNEL/BoundingBox.hxx deleted file mode 100644 index 02c2ce9a1..000000000 --- a/medtool/src/INTERP_KERNEL/BoundingBox.hxx +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __BOUNDINGBOX_HXX__ -#define __BOUNDINGBOX_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing the bounding box of a number of points. - * - */ - class INTERPKERNEL_EXPORT BoundingBox - { - public: - - /// Enumeration representing the six coordinates that define the bounding box - enum BoxCoord { XMIN = 0, YMIN = 1, ZMIN = 2, XMAX = 3, YMAX = 4, ZMAX = 5 }; - - BoundingBox(const double** pts, const unsigned numPts); - - BoundingBox(const BoundingBox& box1, const BoundingBox& box2); - - ~BoundingBox(); - - bool isDisjointWith(const BoundingBox& box) const; - - inline void setCoordinate(const BoxCoord coord, double value); - - inline double getCoordinate(const BoxCoord coord) const; - - void updateWithPoint(const double* pt); - - inline void dumpCoords() const; - - private: - - bool isValid() const; - - /// disallow copying - BoundingBox(const BoundingBox& box); - - /// disallow assignment - BoundingBox& operator=(const BoundingBox& box); - - /// Vector containing the coordinates of the box - /// interlaced in the order XMIN, YMIN, ZMIN, XMAX, YMAX, ZMAX - double* _coords; - - }; - - /** - * Sets a coordinate of the box to a given value. - * - * @param coord coordinate to set - * @param value new value for coordinate - * - */ - inline void BoundingBox::setCoordinate(const BoxCoord coord, double value) - { - _coords[coord] = value; - } - - /** - * Gets a coordinate of the box - * - * @param coord coordinate to get - * @return value of coordinate - * - */ - inline double BoundingBox::getCoordinate(const BoxCoord coord) const - { - return _coords[coord]; - } - - /** - * Prints the coordinates of the box to std::cout - * - */ - inline void BoundingBox::dumpCoords() const - { - std::cout << "[xmin, xmax] = [" << _coords[XMIN] << ", " << _coords[XMAX] << "]" << " | "; - std::cout << "[ymin, ymax] = [" << _coords[YMIN] << ", " << _coords[YMAX] << "]" << " | "; - std::cout << "[zmin, zmax] = [" << _coords[ZMIN] << ", " << _coords[ZMAX] << "]"; - std::cout << std::endl; - } - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/BoxSplittingOptions.cxx b/medtool/src/INTERP_KERNEL/BoxSplittingOptions.cxx deleted file mode 100644 index a23a6b7e3..000000000 --- a/medtool/src/INTERP_KERNEL/BoxSplittingOptions.cxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#include "BoxSplittingOptions.hxx" - -#include - -const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFICIENCY_GOAL=0.5; - -const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFICIENCY_THRESHOLD=0.7; - -void INTERP_KERNEL::BoxSplittingOptions::init() -{ - _efficiency_goal=DFT_EFFICIENCY_GOAL; - _efficiency_threshold=DFT_EFFICIENCY_THRESHOLD; - _min_patch_length=DFT_MIN_PATCH_LENGTH; - _max_patch_length=DFT_MAX_PATCH_LENGTH; - _max_nb_cells_in_patch=DFT_MAX_PATCH_MEASURE; -} - -std::string INTERP_KERNEL::BoxSplittingOptions::printOptions() const -{ - std::ostringstream oss; - oss << "Efficiency goal: " << 100*_efficiency_goal << "%" << std::endl; - oss << "Efficiency threshold: " << 100*_efficiency_threshold << "%" << std::endl; - oss << "Min. patch side length: " << _min_patch_length << std::endl; - oss << "Max. patch side length: " << _max_patch_length << std::endl; - oss << "Max. patch measure: " << _max_nb_cells_in_patch << std::endl; - return oss.str(); -} diff --git a/medtool/src/INTERP_KERNEL/BoxSplittingOptions.hxx b/medtool/src/INTERP_KERNEL/BoxSplittingOptions.hxx deleted file mode 100644 index 0834430ef..000000000 --- a/medtool/src/INTERP_KERNEL/BoxSplittingOptions.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#ifndef __BOXSPLITTINGOPTIONS_HXX__ -#define __BOXSPLITTINGOPTIONS_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - /*! - * \class BoxSplittingOptions - * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion. - */ - class INTERPKERNEL_EXPORT BoxSplittingOptions - { - private: - double _efficiency_goal; - double _efficiency_threshold; - int _min_patch_length; - int _max_patch_length; - int _max_nb_cells_in_patch; - public: - BoxSplittingOptions() { init(); } - void init(); - double getEfficiencyGoal() const { return _efficiency_goal; } - void setEfficiencyGoal(double efficiency) { _efficiency_goal=efficiency; } - double getEfficiencyThreshold() const { return _efficiency_threshold; } - void setEfficiencyThreshold(double efficiencyThreshold) { _efficiency_threshold=efficiencyThreshold; } - int getMinimumPatchLength() const { return _min_patch_length; } - void setMinimumPatchLength(int minPatchLength) { _min_patch_length=minPatchLength; } - int getMaximumPatchLength() const { return _max_patch_length; } - void setMaximumPatchLength(int maxNbCellPatch) { _max_patch_length=maxNbCellPatch; } - int getMaximumNbOfCellsInPatch() const { return _max_nb_cells_in_patch; } - void setMaximumNbOfCellsInPatch(int maxNbCellsInPatch) { _max_nb_cells_in_patch=maxNbCellsInPatch; } - void copyOptions(const BoxSplittingOptions & other) { *this=other; } - std::string printOptions() const; - private: - static const int DFT_MIN_PATCH_LENGTH=1; - static const int DFT_MAX_PATCH_LENGTH=2147483647; - static const int DFT_MAX_PATCH_MEASURE=2147483647; - static const double DFT_EFFICIENCY_GOAL; - static const double DFT_EFFICIENCY_THRESHOLD; - public: - static const char PRECISION_STR[]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CMakeLists.txt b/medtool/src/INTERP_KERNEL/CMakeLists.txt deleted file mode 100644 index 2f2124db5..000000000 --- a/medtool/src/INTERP_KERNEL/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -SET(interpkernel_SOURCES - TransformedTriangle.cxx - TransformedTriangleIntersect.cxx - TransformedTriangleMath.cxx - BoundingBox.cxx - TranslationRotationMatrix.cxx - TetraAffineTransform.cxx - CellModel.cxx - DiameterCalculator.cxx - UnitTetraIntersectionBary.cxx - InterpolationOptions.cxx - BoxSplittingOptions.cxx - DirectedBoundingBox.cxx - Interpolation2DCurve.cxx - Interpolation3DSurf.cxx - Interpolation3D.cxx - Interpolation3D2D.cxx - MeshElement.cxx - InterpKernelMeshQuality.cxx - InterpKernelCellSimplify.cxx - InterpKernelMatrixTools.cxx - VolSurfUser.cxx - SplitterTetra.cxx - Bases/InterpKernelException.cxx - Geometric2D/InterpKernelGeo2DAbstractEdge.cxx - Geometric2D/InterpKernelGeo2DBounds.cxx - Geometric2D/InterpKernelGeo2DPrecision.cxx - Geometric2D/InterpKernelGeo2DComposedEdge.cxx - Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx - Geometric2D/InterpKernelGeo2DEdge.cxx - Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx - Geometric2D/InterpKernelGeo2DEdgeLin.cxx - Geometric2D/InterpKernelGeo2DElementaryEdge.cxx - Geometric2D/InterpKernelGeo2DNode.cxx - Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx - ExprEval/InterpKernelExprParser.cxx - ExprEval/InterpKernelFunction.cxx - ExprEval/InterpKernelUnit.cxx - ExprEval/InterpKernelValue.cxx - ExprEval/InterpKernelAsmX86.cxx - GaussPoints/InterpKernelGaussCoords.cxx - ) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/GaussPoints - ) - -SET(PLATFORM_MMAP) -IF(NOT WIN32) - SET(PLATFORM_MMAP "-D_POSIX_MAPPED_FILES") -ENDIF(NOT WIN32) - -ADD_LIBRARY(interpkernel SHARED ${interpkernel_SOURCES}) -SET_TARGET_PROPERTIES(interpkernel PROPERTIES COMPILE_FLAGS "${PLATFORM_MMAP}") -TARGET_LINK_LIBRARIES(interpkernel ${PLATFORM_LIBS}) -INSTALL(TARGETS interpkernel EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -FILE(GLOB_RECURSE interpkernel_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") -FILE(GLOB_RECURSE interpkernel_HEADERS_TXX "${CMAKE_CURRENT_SOURCE_DIR}/*.txx") -INSTALL(FILES ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX} Bases/NormalizedGeometricTypes DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -# Will be used for SWIG dependencies: -SET (interpkernel_HEADERS_HXX PARENT_SCOPE) -SET (interpkernel_HEADERS_TXX PARENT_SCOPE) diff --git a/medtool/src/INTERP_KERNEL/CellModel.cxx b/medtool/src/INTERP_KERNEL/CellModel.cxx deleted file mode 100644 index d3e364196..000000000 --- a/medtool/src/INTERP_KERNEL/CellModel.cxx +++ /dev/null @@ -1,889 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "CellModel.hxx" - -#include "InterpKernelException.hxx" -#include "DiameterCalculator.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT1", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4 - "NORM_POLYGON", "NORM_TRI6", "NORM_TRI7" , "NORM_QUAD8", "NORM_QUAD9",//5->9 - "NORM_SEG4", "", "", "", "NORM_TETRA4",//10->14 - "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19 - "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24 - "NORM_PENTA15", "", "NORM_HEXA27", "", "",//25->29 - "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "NORM_POLYL", "",//30->34 - "", "", "", "", "",//35->39 - "NORM_ERROR"}; - - std::map CellModel::_map_of_unique_instance; - - const CellModel& CellModel::GetCellModel(NormalizedCellType type) - { - if(_map_of_unique_instance.empty()) - buildUniqueInstance(); - const std::map::iterator iter=_map_of_unique_instance.find(type); - if(iter==_map_of_unique_instance.end()) - { - std::ostringstream stream; stream << "no cellmodel for normalized type " << type; - throw Exception(stream.str().c_str()); - } - return (*iter).second; - } - - const char *CellModel::getRepr() const - { - return CELL_TYPES_REPR[(int)_type]; - } - - /*! - * This method is compatible with all types including dynamic one. - */ - bool CellModel::isCompatibleWith(NormalizedCellType type) const - { - if(_type==type) - return true; - const CellModel& other=GetCellModel(type); - if(_dim!=other.getDimension()) - return false; - bool b1=isQuadratic(); - bool b2=other.isQuadratic(); - if((b1 && !b2) || (!b1 && b2)) - return false; - b1=isDynamic(); - b2=other.isDynamic(); - return b1 || b2; - } - - void CellModel::buildUniqueInstance() - { - _map_of_unique_instance.insert(std::make_pair(NORM_POINT1,CellModel(NORM_POINT1))); - _map_of_unique_instance.insert(std::make_pair(NORM_SEG2,CellModel(NORM_SEG2))); - _map_of_unique_instance.insert(std::make_pair(NORM_SEG3,CellModel(NORM_SEG3))); - _map_of_unique_instance.insert(std::make_pair(NORM_SEG4,CellModel(NORM_SEG4))); - _map_of_unique_instance.insert(std::make_pair(NORM_TRI3,CellModel(NORM_TRI3))); - _map_of_unique_instance.insert(std::make_pair(NORM_QUAD4,CellModel(NORM_QUAD4))); - _map_of_unique_instance.insert(std::make_pair(NORM_TRI6,CellModel(NORM_TRI6))); - _map_of_unique_instance.insert(std::make_pair(NORM_TRI7,CellModel(NORM_TRI7))); - _map_of_unique_instance.insert(std::make_pair(NORM_QUAD8,CellModel(NORM_QUAD8))); - _map_of_unique_instance.insert(std::make_pair(NORM_QUAD9,CellModel(NORM_QUAD9))); - _map_of_unique_instance.insert(std::make_pair(NORM_TETRA4,CellModel(NORM_TETRA4))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXA8,CellModel(NORM_HEXA8))); - _map_of_unique_instance.insert(std::make_pair(NORM_PYRA5,CellModel(NORM_PYRA5))); - _map_of_unique_instance.insert(std::make_pair(NORM_PENTA6,CellModel(NORM_PENTA6))); - _map_of_unique_instance.insert(std::make_pair(NORM_TETRA10,CellModel(NORM_TETRA10))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXGP12,CellModel(NORM_HEXGP12))); - _map_of_unique_instance.insert(std::make_pair(NORM_PYRA13,CellModel(NORM_PYRA13))); - _map_of_unique_instance.insert(std::make_pair(NORM_PENTA15,CellModel(NORM_PENTA15))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXA27,CellModel(NORM_HEXA27))); - _map_of_unique_instance.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON))); - _map_of_unique_instance.insert(std::make_pair(NORM_POLYHED,CellModel(NORM_POLYHED))); - _map_of_unique_instance.insert(std::make_pair(NORM_QPOLYG,CellModel(NORM_QPOLYG))); - _map_of_unique_instance.insert(std::make_pair(NORM_POLYL,CellModel(NORM_POLYL))); - _map_of_unique_instance.insert(std::make_pair(NORM_ERROR,CellModel(NORM_ERROR))); - } - - CellModel::CellModel(NormalizedCellType type):_type(type) - { - _is_extruded=false; - _quadratic=false; - _dyn=false; - _extruded_type=NORM_ERROR; - _reverse_extruded_type=NORM_ERROR; - _linear_type=NORM_ERROR; - _quadratic_type=NORM_ERROR; - _quadratic_type2=NORM_ERROR; - _nb_of_little_sons=std::numeric_limits::max(); - switch(type) - { - case NORM_POINT1: - { - _nb_of_pts=1; _nb_of_sons=0; _dim=0; _extruded_type=NORM_SEG2; _is_simplex=true; - } - break; - case NORM_SEG2: - { - _nb_of_pts=2; _nb_of_sons=2; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; _quadratic_type2=NORM_SEG3; _is_simplex=true; _is_extruded=true; _reverse_extruded_type=NORM_POINT1; - _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; - _sons_con[0][0]=0; _nb_of_sons_con[0]=1; - _sons_con[1][0]=1; _nb_of_sons_con[1]=1; - } - break; - case NORM_SEG3: - { - _nb_of_pts=3; _nb_of_sons=3; _dim=1; _extruded_type=NORM_QUAD8; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; - _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; - _sons_con[0][0]=0; _nb_of_sons_con[0]=1; - _sons_con[1][0]=1; _nb_of_sons_con[1]=1; - _sons_con[2][0]=2; _nb_of_sons_con[2]=1; - } - break; - case NORM_SEG4: - { - _nb_of_pts=4; _nb_of_sons=4; _dim=1; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; // no _extruded_type because no cubic 2D cell - _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; _sons_type[3]=NORM_POINT1; - _sons_con[0][0]=0; _nb_of_sons_con[0]=1; - _sons_con[1][0]=1; _nb_of_sons_con[1]=1; - _sons_con[2][0]=2; _nb_of_sons_con[2]=1; - _sons_con[3][0]=3; _nb_of_sons_con[3]=1; - } - break; - case NORM_TETRA4: - { - _nb_of_pts=4; _nb_of_sons=4; _dim=3; _quadratic_type=NORM_TETRA10; _is_simplex=true; - _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; - _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; - _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _nb_of_sons_con[2]=3; - _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _nb_of_sons_con[3]=3; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=6; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; - _little_sons_con[3][0]=0; _little_sons_con[3][1]=3; - _little_sons_con[4][0]=1; _little_sons_con[4][1]=3; - _little_sons_con[5][0]=2; _little_sons_con[5][1]=3; - } - break; - case NORM_HEXA8: - { - _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _quadratic_type2=NORM_HEXA27; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_QUAD4; - _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; - _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4; - _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; - _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; - _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _nb_of_sons_con[4]=4; - _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _nb_of_sons_con[5]=4; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=12; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; - _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; - _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; - _little_sons_con[5][0]=5; _little_sons_con[5][1]=6; - _little_sons_con[6][0]=6; _little_sons_con[6][1]=7; - _little_sons_con[7][0]=7; _little_sons_con[7][1]=4; - _little_sons_con[8][0]=0; _little_sons_con[8][1]=4; - _little_sons_con[9][0]=1; _little_sons_con[9][1]=5; - _little_sons_con[10][0]=2; _little_sons_con[10][1]=6; - _little_sons_con[11][0]=3; _little_sons_con[11][1]=7; - } - break; - case NORM_QUAD4: - { - _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _quadratic_type2=NORM_QUAD9; _is_simplex=false; _is_extruded=true; - _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2; - _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; - _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; - _sons_con[2][0]=2; _sons_con[2][1]=3; _nb_of_sons_con[2]=2; - _sons_con[3][0]=3; _sons_con[3][1]=0; _nb_of_sons_con[3]=2; _extruded_type=NORM_HEXA8; - } - break; - case NORM_TRI3: - { - _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _quadratic_type2=NORM_TRI7; _is_simplex=true; - _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; - _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; - _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; - _sons_con[2][0]=2; _sons_con[2][1]=0; _nb_of_sons_con[2]=2; _extruded_type=NORM_PENTA6; - } - break; - case NORM_TRI6: - { - _nb_of_pts=6; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; _extruded_type=NORM_PENTA15; - } - break; - case NORM_TRI7: - { - _nb_of_pts=7; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; //no extruded type because no penta20 - } - break; - case NORM_QUAD8: - { - _nb_of_pts=8; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; - _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA20; - } - break; - case NORM_QUAD9: - { - _nb_of_pts=9; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; - _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA27; - } - break; - case NORM_PYRA5: - { - _nb_of_pts=5; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PYRA13; _is_simplex=false; - _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; - _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; - _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _nb_of_sons_con[2]=3; - _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _nb_of_sons_con[3]=3; - _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _nb_of_sons_con[4]=3; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=8; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; - _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; - _little_sons_con[4][0]=0; _little_sons_con[4][1]=4; - _little_sons_con[5][0]=1; _little_sons_con[5][1]=4; - _little_sons_con[6][0]=2; _little_sons_con[6][1]=4; - _little_sons_con[7][0]=3; _little_sons_con[7][1]=4; - } - break; - case NORM_PENTA6: - { - _nb_of_pts=6; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PENTA15; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_TRI3; - _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; - _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; - _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; - _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; - _sons_con[4][0]=2; _sons_con[4][1]=5; _sons_con[4][2]=3; _sons_con[4][3]=0; _nb_of_sons_con[4]=4; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=9; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; - _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; - _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; - _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; - _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; - _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; - _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; - } - break; - case NORM_TETRA10: - { - _nb_of_pts=10; _nb_of_sons=4; _dim=3; _linear_type=NORM_TETRA4; _is_simplex=false; - _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6; - _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6; - _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _sons_con[2][3]=8; _sons_con[2][4]=9; _sons_con[2][5]=5; _nb_of_sons_con[2]=6; - _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _sons_con[3][3]=9; _sons_con[3][4]=7; _sons_con[3][5]=6; _nb_of_sons_con[3]=6; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=4; _nb_of_little_sons=6; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=5; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=6; - _little_sons_con[3][0]=0; _little_sons_con[3][1]=3; _little_sons_con[3][2]=7; - _little_sons_con[4][0]=1; _little_sons_con[4][1]=3; _little_sons_con[4][2]=8; - _little_sons_con[5][0]=2; _little_sons_con[5][1]=3; _little_sons_con[5][2]=9; - } - break; - case NORM_HEXGP12: - { - _nb_of_pts=12; _nb_of_sons=8; _dim=3; _is_simplex=false; _is_extruded=true; - _sons_type[0]=NORM_POLYGON; _sons_type[1]=NORM_POLYGON; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; - _sons_type[6]=NORM_QUAD4; _sons_type[7]=NORM_QUAD4; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=4; _sons_con[0][5]=5; _nb_of_sons_con[0]=6; - _sons_con[1][0]=6; _sons_con[1][1]=11; _sons_con[1][2]=10; _sons_con[1][3]=9; _sons_con[1][4]=8; _sons_con[1][5]=7; _nb_of_sons_con[1]=6; - _sons_con[2][0]=0; _sons_con[2][1]=6; _sons_con[2][2]=7; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; - _sons_con[3][0]=1; _sons_con[3][1]=7; _sons_con[3][2]=8; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; - _sons_con[4][0]=2; _sons_con[4][1]=8; _sons_con[4][2]=9; _sons_con[4][3]=3; _nb_of_sons_con[4]=4; - _sons_con[5][0]=3; _sons_con[5][1]=9; _sons_con[5][2]=10; _sons_con[5][3]=4; _nb_of_sons_con[5]=4; - _sons_con[6][0]=4; _sons_con[6][1]=10; _sons_con[6][2]=11; _sons_con[6][3]=5; _nb_of_sons_con[6]=4; - _sons_con[7][0]=5; _sons_con[7][1]=11; _sons_con[7][2]=6; _sons_con[7][3]=0; _nb_of_sons_con[7]=4; - } - break; - case NORM_PYRA13: - { - _nb_of_pts=13; _nb_of_sons=5; _dim=3; _linear_type=NORM_PYRA5; _is_simplex=false; - _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8; - _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6; - _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _sons_con[2][3]=10; _sons_con[2][4]=11; _sons_con[2][5]=6; _nb_of_sons_con[2]=6; - _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _sons_con[3][3]=11; _sons_con[3][4]=12; _sons_con[3][5]=7; _nb_of_sons_con[3]=6; - _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _sons_con[4][3]=12; _sons_con[4][4]=9; _sons_con[4][5]=8; _nb_of_sons_con[4]=6; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=5; _nb_of_little_sons=8; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=6; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=7; - _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=8; - _little_sons_con[4][0]=0; _little_sons_con[4][1]=4; _little_sons_con[4][2]=9; - _little_sons_con[5][0]=1; _little_sons_con[5][1]=4; _little_sons_con[5][2]=10; - _little_sons_con[6][0]=2; _little_sons_con[6][1]=4; _little_sons_con[6][2]=11; - _little_sons_con[7][0]=3; _little_sons_con[7][1]=4; _little_sons_con[7][2]=12; - } - break; - case NORM_PENTA15: - { - _nb_of_pts=15; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false; - _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6; - _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6; - _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _sons_con[2][4]=12; _sons_con[2][5]=9; _sons_con[2][6]=13; _sons_con[2][7]=6; _nb_of_sons_con[2]=8; - _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _sons_con[3][4]=13; _sons_con[3][5]=10; _sons_con[3][6]=14; _sons_con[3][7]=7; _nb_of_sons_con[3]=8; - _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _sons_con[4][4]=14; _sons_con[4][5]=11; _sons_con[4][6]=12; _sons_con[4][7]=8; _nb_of_sons_con[4]=8; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6; _nb_of_little_sons=9; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8; - _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9; - _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=10; - _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; _little_sons_con[5][2]=11; - _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; _little_sons_con[6][2]=12; - _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; _little_sons_con[7][2]=13; - _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14; - } - break; - case NORM_HEXA20: - { - _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; - _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _nb_of_sons_con[0]=8; - _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _nb_of_sons_con[1]=8; - _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _nb_of_sons_con[2]=8; - _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8; - _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8; - _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=8; _nb_of_little_sons=12; - _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=9; - _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=10; - _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=11; - _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=12; - _little_sons_con[5][0]=5; _little_sons_con[5][1]=6; _little_sons_con[5][2]=13; - _little_sons_con[6][0]=6; _little_sons_con[6][1]=7; _little_sons_con[6][2]=14; - _little_sons_con[7][0]=7; _little_sons_con[7][1]=4; _little_sons_con[7][2]=15; - _little_sons_con[8][0]=0; _little_sons_con[8][1]=4; _little_sons_con[8][2]=16; - _little_sons_con[9][0]=1; _little_sons_con[9][1]=5; _little_sons_con[9][2]=17; - _little_sons_con[10][0]=2; _little_sons_con[10][1]=6; _little_sons_con[10][2]=18; - _little_sons_con[11][0]=3; _little_sons_con[11][1]=7; _little_sons_con[11][2]=19; - } - break; - case NORM_HEXA27: - { - _nb_of_pts=27; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; - _sons_type[0]=NORM_QUAD9; _sons_type[1]=NORM_QUAD9; _sons_type[2]=NORM_QUAD9; _sons_type[3]=NORM_QUAD9; _sons_type[4]=NORM_QUAD9; _sons_type[5]=NORM_QUAD9; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _sons_con[0][8]=20; _nb_of_sons_con[0]=9; - _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _sons_con[1][8]=25; _nb_of_sons_con[1]=9; - _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _sons_con[2][8]=21; _nb_of_sons_con[2]=9; - _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9; _sons_con[3][8]=22; _nb_of_sons_con[3]=9; - _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _sons_con[4][8]=23; _nb_of_sons_con[4]=9; - _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _sons_con[5][8]=24; _nb_of_sons_con[5]=9; - _quadratic=true; - } - break; - case NORM_POLYGON: - { - _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _extruded_type=NORM_POLYHED; _is_simplex=false; _quadratic_type=NORM_QPOLYG; - } - break; - case NORM_POLYHED: - { - _nb_of_pts=0; _nb_of_sons=0; _dim=3; _dyn=true; _is_simplex=false; - } - break; - case NORM_QPOLYG: - { - _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false; _quadratic=true; _linear_type=NORM_POLYGON; - } - break; - case NORM_POLYL: - { - _nb_of_pts=0; _nb_of_sons=0; _dim=1; _dyn=true; _extruded_type=NORM_POLYGON; _is_simplex=false; - } - break; - case NORM_ERROR: - { - _nb_of_pts=std::numeric_limits::max(); _nb_of_sons=std::numeric_limits::max(); _dim=std::numeric_limits::max(); - } - break; - } - } - - /*! - * Equivalent to getNumberOfSons except that this method deals with dynamic type. - */ - unsigned CellModel::getNumberOfSons2(const int *conn, int lgth) const - { - if(!isDynamic()) - return getNumberOfSons(); - if(_dim==2) - { - if(_type==NORM_POLYGON) - return lgth; - else - return lgth/2; - } - else if(_dim==1) - return lgth;//NORM_POLYL - else - return std::count(conn,conn+lgth,-1)+1; - } - - unsigned CellModel::getNumberOfEdgesIn3D(const int *conn, int lgth) const - { - if(!isDynamic()) - return _nb_of_little_sons; - else//polyhedron - return (lgth-std::count(conn,conn+lgth,-1))/2; - } - - NormalizedCellType CellModel::getCorrespondingPolyType() const - { - switch(getDimension()) - { - case 0: - return NORM_POINT1; - case 1: - { - if(!isQuadratic()) - return NORM_POLYL; - throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 1D !"); - } - case 2: - { - if(!isQuadratic()) - return NORM_POLYGON; - else - return NORM_QPOLYG; - } - case 3: - { - if(!isQuadratic()) - return NORM_POLYHED; - throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 3D !"); - } - default: - throw INTERP_KERNEL::Exception("CellModel::getPolyType : only dimension 0, 1, 2, 3 are supported !"); - } - } - - /*! - * Equivalent to getSonType except that this method deals with dynamic type. - */ - NormalizedCellType CellModel::getSonType2(unsigned sonId) const - { - if(!isDynamic()) - return getSonType(sonId); - if(_dim==2) - { - if(_type==NORM_POLYGON) - return NORM_SEG2; - else - return NORM_SEG3; - } - else if(_dim==1) - return NORM_ERROR;//NORM_POLYL - //polyedron - return NORM_POLYGON; - } - - /*! - * \b WARNING this method do not manage correctly types that return true at the call of isDynamic. Use fillSonCellNodalConnectivity2 instead. - */ - unsigned CellModel::fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const - { - unsigned nbOfTurnLoop=_nb_of_sons_con[sonId]; - const unsigned *sonConn=_sons_con[sonId]; - for(unsigned i=0;iHEXA27 - */ - unsigned CellModel::fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const - { - if(_type==NORM_HEXA8) - { - static const int permutation[6]={0,2,3,4,5,1}; - return fillSonCellNodalConnectivity2(permutation[sonId],nodalConn,lgth,sonNodalConn,typeOfSon); - } - else - return fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); - } - - unsigned CellModel::fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const - { - if(!isDynamic()) - { - if(!isQuadratic()) - { - typeOfSon=NORM_SEG2; - sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; - sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; - return 2; - } - else - { - typeOfSon=NORM_SEG3; - sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; - sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; - sonNodalConn[2]=nodalConn[_little_sons_con[sonId][2]]; - return 3; - } - } - else - throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !"); - } - - void CellModel::changeOrientationOf2D(int *nodalConn, unsigned int sz) const - { - if(sz<1) - return ; - if(!isQuadratic()) - { - std::vector tmp(sz-1); - std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); - std::copy(tmp.begin(),tmp.end(),nodalConn+1); - } - else - { - unsigned int sz2(sz/2); - std::vector tmp0(sz2-1),tmp1(sz2); - std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin()); - std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin()); - std::copy(tmp0.begin(),tmp0.end(),nodalConn+1); - std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2); - } - } - - void CellModel::changeOrientationOf1D(int *nodalConn, unsigned int sz) const - { - if(!isDynamic()) - { - if(sz==2 || sz==3) - { - std::swap(nodalConn[0],nodalConn[1]); - return ; - } - else if(sz==4) - { - std::swap(nodalConn[0],nodalConn[1]); - std::swap(nodalConn[2],nodalConn[3]); - } - else - throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !"); - } - else - { - std::vector tmp(sz-1); - std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); - std::copy(tmp.begin(),tmp.end(),nodalConn+1); - } - } - - //================================================================================ - /*! - * \brief Return number of nodes in sonId-th son of a Dynamic() cell - */ - //================================================================================ - - unsigned CellModel::getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const - { - if(!isDynamic()) - return getNumberOfNodesConstituentTheSon(sonId); - - if(_dim==2)//polygon - { - if(_type==NORM_POLYGON) - return 2; - else - return 3; - } - else if(_dim==3) - {//polyedron - const int *where=nodalConn; - for(unsigned int i=0;i tmp(2*lgth); - std::vector::iterator it=std::copy(conn1,conn1+lgth,tmp.begin()); - std::copy(conn1,conn1+lgth,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); - if(it==tmp.begin()) - return true; - if(it!=tmp.end()) - return _dim!=1; - std::vector::reverse_iterator it2=std::search(tmp.rbegin(),tmp.rend(),conn2,conn2+lgth); - if(it2!=tmp.rend()) - return false; - throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : Request of orientation status of non equal connectively cells !"); - } - else - { - if(_dim!=1) - { - std::vector tmp(lgth); - std::vector::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin()); - std::copy(conn1,conn1+lgth/2,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth/2); - int d=std::distance(tmp.begin(),it); - if(it==tmp.end()) - return false; - it=std::copy(conn1+lgth/2,conn1+lgth,tmp.begin()); - std::copy(conn1+lgth/2,conn1+lgth,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); - if(it==tmp.end()) - return false; - int d2=std::distance(tmp.begin(),it); - return d==d2; - } - else - { - int p=(lgth+1)/2; - std::vector tmp(2*p); - std::vector::iterator it=std::copy(conn1,conn1+p,tmp.begin()); - std::copy(conn1,conn1+p,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+p); - int d=std::distance(tmp.begin(),it); - if(it==tmp.end()) - return false; - tmp.resize(2*p-2); - it=std::copy(conn1+p,conn1+lgth,tmp.begin()); - std::copy(conn1+p,conn1+lgth,it); - it=std::search(tmp.begin(),tmp.end(),conn2+p,conn2+lgth); - if(it==tmp.end()) - return false; - int d2=std::distance(tmp.begin(),it); - return d==d2; - } - } - } - - DiameterCalculator *CellModel::buildInstanceOfDiameterCalulator(int spaceDim) const - { - switch(_type) - { - case NORM_TRI3: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorTRI3S2; - case 3: - return new DiameterCalulatorTRI3S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI3 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_QUAD4: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorQUAD4S2; - case 3: - return new DiameterCalulatorQUAD4S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD4 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_TRI6: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorTRI6S2; - case 3: - return new DiameterCalulatorTRI6S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI6 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_TRI7: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorTRI7S2; - case 3: - return new DiameterCalulatorTRI7S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI7 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_QUAD8: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorQUAD8S2; - case 3: - return new DiameterCalulatorQUAD8S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD8 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_QUAD9: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorQUAD9S2; - case 3: - return new DiameterCalulatorQUAD9S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD9 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_TETRA4: - { - if(spaceDim==3) - return new DiameterCalulatorTETRA4; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA4 space dimension 3 expected !"); - } - case NORM_TETRA10: - { - if(spaceDim==3) - return new DiameterCalulatorTETRA10; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA10 space dimension 3 expected !"); - } - case NORM_HEXA8: - { - if(spaceDim==3) - return new DiameterCalulatorHEXA8; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA8 space dimension 3 expected !"); - } - case NORM_HEXA20: - { - if(spaceDim==3) - return new DiameterCalulatorHEXA20; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA20 space dimension 3 expected !"); - } - case NORM_HEXA27: - { - if(spaceDim==3) - return new DiameterCalulatorHEXA27; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA27 space dimension 3 expected !"); - } - case NORM_PENTA6: - { - if(spaceDim==3) - return new DiameterCalulatorPENTA6; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA6 space dimension 3 expected !"); - } - case NORM_PENTA15: - { - if(spaceDim==3) - return new DiameterCalulatorPENTA15; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA15 space dimension 3 expected !"); - } - case NORM_PYRA5: - { - if(spaceDim==3) - return new DiameterCalulatorPYRA5; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA5 space dimension 3 expected !"); - } - case NORM_PYRA13: - { - if(spaceDim==3) - return new DiameterCalulatorPYRA13; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA13 space dimension 3 expected !"); - } - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : implemented only for TRI3, QUAD4, TETRA4, HEXA8, PENTA6, PYRA5 !"); - } - } -} diff --git a/medtool/src/INTERP_KERNEL/CellModel.hxx b/medtool/src/INTERP_KERNEL/CellModel.hxx deleted file mode 100644 index d1b5e1d95..000000000 --- a/medtool/src/INTERP_KERNEL/CellModel.hxx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __CELLMODEL_INTERP_KERNEL_HXX__ -#define __CELLMODEL_INTERP_KERNEL_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include - -namespace INTERP_KERNEL -{ - class DiameterCalculator; - - /*! - * This class descibes all static elements (different from polygons and polyhedron) 3D, 2D and 1D. - */ - class CellModel - { - public: - static const unsigned MAX_NB_OF_SONS=8; - static const unsigned MAX_NB_OF_NODES_PER_ELEM=30; - static const unsigned MAX_NB_OF_LITTLE_SONS=12; - private: - CellModel(NormalizedCellType type); - static void buildUniqueInstance(); - public: - INTERPKERNEL_EXPORT static const CellModel& GetCellModel(NormalizedCellType type); - INTERPKERNEL_EXPORT NormalizedCellType getEnum() const { return _type; } - INTERPKERNEL_EXPORT const char *getRepr() const; - INTERPKERNEL_EXPORT bool isExtruded() const { return _is_extruded; } - INTERPKERNEL_EXPORT bool isDynamic() const { return _dyn; } - INTERPKERNEL_EXPORT bool isQuadratic() const { return _quadratic; } - INTERPKERNEL_EXPORT unsigned getDimension() const { return _dim; } - INTERPKERNEL_EXPORT bool isCompatibleWith(NormalizedCellType type) const; - INTERPKERNEL_EXPORT bool isSimplex() const { return _is_simplex; } - //! sonId is in C format. - INTERPKERNEL_EXPORT const unsigned *getNodesConstituentTheSon(unsigned sonId) const { return _sons_con[sonId]; } - INTERPKERNEL_EXPORT bool getOrientationStatus(unsigned lgth, const int *conn1, const int *conn2) const; - INTERPKERNEL_EXPORT unsigned getNumberOfNodes() const { return _nb_of_pts; } - INTERPKERNEL_EXPORT unsigned getNumberOfSons() const { return _nb_of_sons; } - INTERPKERNEL_EXPORT unsigned getNumberOfSons2(const int *conn, int lgth) const; - INTERPKERNEL_EXPORT unsigned getNumberOfEdgesIn3D(const int *conn, int lgth) const; - INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon(unsigned sonId) const { return _nb_of_sons_con[sonId]; } - INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const; - INTERPKERNEL_EXPORT NormalizedCellType getExtrudedType() const { return _extruded_type; } - INTERPKERNEL_EXPORT NormalizedCellType getCorrespondingPolyType() const; - INTERPKERNEL_EXPORT NormalizedCellType getReverseExtrudedType() const { return _reverse_extruded_type; } - INTERPKERNEL_EXPORT NormalizedCellType getLinearType() const { return _linear_type; } - INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType() const { return _quadratic_type; } - INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType2() const { return _quadratic_type2; } - INTERPKERNEL_EXPORT NormalizedCellType getSonType(unsigned sonId) const { return _sons_type[sonId]; } - INTERPKERNEL_EXPORT NormalizedCellType getSonType2(unsigned sonId) const; - INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const; - INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; - INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; - INTERPKERNEL_EXPORT unsigned fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; - INTERPKERNEL_EXPORT void changeOrientationOf2D(int *nodalConn, unsigned int sz) const; - INTERPKERNEL_EXPORT void changeOrientationOf1D(int *nodalConn, unsigned int sz) const; - INTERPKERNEL_EXPORT DiameterCalculator *buildInstanceOfDiameterCalulator(int spaceDim) const; - private: - bool _dyn; - bool _quadratic; - bool _is_simplex; - bool _is_extruded; - unsigned _dim; - unsigned _nb_of_pts; - unsigned _nb_of_sons; - unsigned _nb_of_little_sons; - NormalizedCellType _type; - NormalizedCellType _extruded_type; - NormalizedCellType _reverse_extruded_type; - NormalizedCellType _linear_type; - NormalizedCellType _quadratic_type; - NormalizedCellType _quadratic_type2; - unsigned _sons_con[MAX_NB_OF_SONS][MAX_NB_OF_NODES_PER_ELEM]; - unsigned _little_sons_con[MAX_NB_OF_LITTLE_SONS][3]; - unsigned _nb_of_sons_con[MAX_NB_OF_SONS]; - NormalizedCellType _sons_type[MAX_NB_OF_SONS]; - static std::map _map_of_unique_instance; - static const char *CELL_TYPES_REPR[]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/ConvexIntersector.hxx b/medtool/src/INTERP_KERNEL/ConvexIntersector.hxx deleted file mode 100644 index 53966f530..000000000 --- a/medtool/src/INTERP_KERNEL/ConvexIntersector.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __CONVEXINTERSECTOR_HXX__ -#define __CONVEXINTERSECTOR_HXX__ - -#include "PlanarIntersectorP0P0.hxx" -#include "PlanarIntersectorP0P1.hxx" -#include "PlanarIntersectorP1P0.hxx" -#include "PlanarIntersectorP1P1.hxx" -#include "PlanarIntersectorP1P0Bary.hxx" -#include "PlanarIntersectorP0P1Bary.hxx" - -namespace INTERP_KERNEL -{ - template class InterpType > - class ConvexIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - private : - double _epsilon; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/ConvexIntersector.txx b/medtool/src/INTERP_KERNEL/ConvexIntersector.txx deleted file mode 100644 index 9ab59b197..000000000 --- a/medtool/src/INTERP_KERNEL/ConvexIntersector.txx +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __CONVEXINTERSECTOR_TXX__ -#define __CONVEXINTERSECTOR_TXX__ - -#include "ConvexIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P1.txx" -#include "PlanarIntersectorP1P0Bary.txx" -#include "PlanarIntersectorP0P1Bary.txx" - -#include "PolygonAlgorithms.txx" - -#include - -#define CONVINTERSECTOR_TEMPLATE template class InterpType> -#define CONVEX_INTERSECTOR_ ConvexIntersector - -namespace INTERP_KERNEL -{ - CONVINTERSECTOR_TEMPLATE - CONVEX_INTERSECTOR_::ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, - double medianPlane, bool doRotate , int oriantation, int printLevel) - :InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, doRotate, oriantation, printLevel), - _epsilon(precision*dimCaracteristic) - { - if(PlanarIntersector::_print_level >= 1) - { - std::cout << " - intersection type = convex " << std::endl; - if(SPACEDIM==3){ - if(PlanarIntersector::_do_rotate) std::cout << " _do_rotate = true" << std::endl; - else std::cout << " _do_rotate = false" << std::endl; - } - } - } - - CONVINTERSECTOR_TEMPLATE - double CONVEX_INTERSECTOR_::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - double result = 0; - int orientation = 1; - - /*** Obtain the coordinates of T and S ***/ - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - /*** Compute the intersection area ***/ - INTERP_KERNEL::PolygonAlgorithms P(_epsilon, PlanarIntersector::_precision); - std::deque inter = P.intersectConvexPolygons(&CoordsT[0], &CoordsS[0], - CoordsT.size()/SPACEDIM, CoordsS.size()/SPACEDIM); - double area[SPACEDIM]; - int nb_inter =((int)inter.size())/SPACEDIM; - for(int i = 1; i(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],area); - result +=0.5*norm(area); - } - - //DEBUG prints - if(PlanarIntersector::_print_level >= 3) - { - std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; - for(int i=0; i< nb_inter; i++) - {for (int idim=0; idim - class CurveIntersector : public TargetIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - CurveIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double adjustmentEpsAbs, double medianLine, int printLevel); - virtual ~CurveIntersector(); - void createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox); - void adjustBoundingBoxes(std::vector& bbox, double adjustmentEpsAbs); - static void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); - static bool ComputeBaryCoordsOf(double startOfSeg, double endOfSeg, double pt, double& startPos, double& endPos); - protected : - bool projectionThis(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const; - bool getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const; - typename MyMeshType::MyConnType getNodeIdOfTargetCellAt(ConnType icellT, ConnType nodeIdInCellT) const; - bool getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) const; - typename MyMeshType::MyConnType getNodeIdOfSourceCellAt(ConnType icellT, ConnType nodeIdInCellT) const; - double intersectSegments(const double *coordsT, const double *coordsS) const; - double intersectSegmentsInternal(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const; - - struct TDualSegment - { - std::vector _coords; - int _nodeId; // in mesh mode - }; - static void getDualSegments(ConnType icell, - const MyMeshType& mesh, - std::vector& segments); - - protected: - const ConnType *_connectT; - const ConnType *_connectS; - const double *_coordsT; - const double *_coordsS; - const ConnType *_connIndexT; - const ConnType *_connIndexS; - const MyMeshType& _meshT; - const MyMeshType& _meshS; - double _tolerance; - double _precision; - double _median_line; - int _print_level; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersector.txx b/medtool/src/INTERP_KERNEL/CurveIntersector.txx deleted file mode 100644 index c311605f7..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersector.txx +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __CURVEINTERSECTOR_TXX__ -#define __CURVEINTERSECTOR_TXX__ - -#include "CurveIntersector.hxx" -#include "InterpolationUtils.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - CurveIntersector - ::CurveIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, double medianLine, int printLevel): - _meshT(meshT), - _meshS(meshS), - _tolerance(tolerance), - _precision(precision), - _median_line(medianLine), - _print_level(printLevel) - { - if ( SPACEDIM != 1 && SPACEDIM != 2 ) - throw Exception("CurveIntersector(): space dimension of mesh must be 1 or 2"); - if ( MESHDIM != 1 ) - throw Exception("CurveIntersector(): mesh dimension must be 1"); - - _connectT = meshT.getConnectivityPtr(); - _connectS = meshS.getConnectivityPtr(); - _connIndexT = meshT.getConnectivityIndexPtr(); - _connIndexS = meshS.getConnectivityIndexPtr(); - _coordsT = meshT.getCoordinatesPtr(); - _coordsS = meshS.getCoordinatesPtr(); - } - - template - CurveIntersector::~CurveIntersector() - { - } - - //================================================================================ - /*! - \brief creates the bounding boxes for all the cells of mesh \a mesh - - \param mesh structure pointing to the mesh - \param bbox vector containing the bounding boxes - */ - //================================================================================ - - template - void CurveIntersector::createBoundingBoxes (const MyMeshType& mesh, - std::vector& bbox) - { - long nbelems = mesh.getNumberOfElements(); - bbox.resize(2*SPACEDIM* nbelems); - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - int ibox=0; - for(long icell=0; icell::max(); - bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits::max(); - } - //updating the bounding box with each node of the element - for (int j=0; j - ::coo2C(conn[OTT::conn2C(conn_index[icell]+j)]); - for(int idim=0; idim x ) ? bbox[ibox*2*SPACEDIM + 2*idim+1] : x; - } - } - ibox++; - } - } - - /*! - Computes the bouding box of a given element. iP in numPol mode. - */ - template - void CurveIntersector::getElemBB (double* bb, - const MyMeshType& mesh, - ConnType iP, - ConnType nb_nodes) - { - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - //initializing bounding box limits - for(int idim=0; idim::max(); - bb[2*idim+1] = -std::numeric_limits::max(); - } - - for (ConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); - for(int idim=0; idimbb[2*idim+1]) ? x : bb[2*idim+1]; - } - } - } - - /*! - * \param [in] startOfSeg - input coming from intersectSegments or intersectSegmentsInternal - * \param [in] endOfSeg - input coming from intersectSegments or intersectSegmentsInternal. Assume that endOfSeg>startOfSeg. - * \param [in] pt - position of point that the method computes the bary coords for. - */ - template - bool CurveIntersector::ComputeBaryCoordsOf(double startOfSeg, double endOfSeg, double pt, double& startPos, double& endPos) - { - double deno(endOfSeg-startOfSeg); - startPos=(endOfSeg-pt)/deno; - endPos=1.-startPos; - return startPos>=0. && endPos>=0.; - } - - /*! Readjusts a set of bounding boxes so that they are extended - in all dimensions for avoiding missing interesting intersections - - \param bbox vector containing the bounding boxes - */ - template - void CurveIntersector::adjustBoundingBoxes (std::vector& bbox, - double adjustmentEpsAbs) - { - long size = bbox.size()/(2*SPACEDIM); - for (int i=0; i - bool CurveIntersector::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const - { - int nbNodesT(_connIndexT[OTT::ind2C(icellT)+1] - _connIndexT[OTT::ind2C(icellT)]); - coordsT.resize(SPACEDIM*nbNodesT); - for (ConnType iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - } - } - if ( nbNodesT > 2 ) - { - for(int idim=0; idim - typename MyMeshType::MyConnType CurveIntersector::getNodeIdOfTargetCellAt(ConnType icellT, ConnType nodeIdInCellT) const - { - int nbNodesT(_connIndexT[OTT::ind2C(icellT)+1] - _connIndexT[OTT::ind2C(icellT)]); - if(nodeIdInCellT>=0 && nodeIdInCellT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+nodeIdInCellT)]); - else - throw Exception("getNodeIdOfTargetCellAt : error in nodeId in cell"); - } - - /*! - * @param icellS id in source mesh in format of MyMeshType. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - * @return true if segment is quadratic and in this case coordinates of medium node - * are placed in the middle of coordsS - */ - template - bool CurveIntersector::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) const - { - int nbNodesS = _connIndexS[OTT::ind2C(icellS)+1] - _connIndexS[OTT::ind2C(icellS)]; - coordsS.resize(SPACEDIM*nbNodesS); - for(ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - } - if ( nbNodesS > 2 ) - { - for(int idim=0; idim - typename MyMeshType::MyConnType CurveIntersector::getNodeIdOfSourceCellAt(ConnType icellS, ConnType nodeIdInCellS) const - { - int nbNodesS(_connIndexS[OTT::ind2C(icellS)+1] - _connIndexS[OTT::ind2C(icellS)]); - if(nodeIdInCellS>=0 && nodeIdInCellS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+nodeIdInCellS)]); - else - throw Exception("getNodeIdOfSourceCellAt : error in nodeId in cell"); - } - - /*! - * \brief Return dual segments of given segment - * \param icell - given segment in C mode - * \param mesh - mesh - * \param segments - dual segments - */ - template - void CurveIntersector::getDualSegments(ConnType icell, - const MyMeshType& mesh, - std::vector& segments) - { - // get coordinates of cell nodes - int nbNodes; - std::vector ncoords; - std::vector nodeIds; - { - const ConnType *connect = mesh.getConnectivityPtr(); - const ConnType *connIndex = mesh.getConnectivityIndexPtr(); - const double *coords = mesh.getCoordinatesPtr(); - - nbNodes = connIndex[icell+1] - connIndex[icell]; - - ncoords.resize(SPACEDIM*nbNodes); - nodeIds.resize(nbNodes); - - for(int i=0; i::conn2C(connIndex[OTT::ind2C(icell)]+i)]; - ncoords[SPACEDIM*i+idim] = coords[SPACEDIM*OTT::coo2C(nodeIds[i])+idim]; - } - if ( nbNodes > 2 ) // quadratic segment, put medium node in the middle - { - for(int idim=0; idim - bool CurveIntersector::projectionThis(const double *coordsT, const double *coordsS, - double& xs0, double& xs1, double& xt0, double& xt1) const - { - xt0 = coordsT[0]; xt1 = coordsT[1]; - xs0 = coordsS[0]; xs1 = coordsS[1]; - if ( SPACEDIM == 2 ) - { - // Pass 2D->1D - - enum { X=0, Y }; - - // check if two segments overlap in 2D within tolerance - - const double* t0 = coordsT; - const double* t1 = coordsT + 2; - double t01[2] = { t1[X]-t0[X], t1[Y]-t0[Y] }; // tgt segment direction - double tSize = sqrt( t01[X]*t01[X] + t01[Y]*t01[Y] ); // tgt segment size - if ( tSize < _precision ) - return false; // degenerated segment - t01[X] /= tSize, t01[Y] /= tSize; // normalize t01 - - const double* s0 = coordsS; - const double* s1 = coordsS + 2; - double t0s0[2] = { s0[X]-t0[X], s0[Y]-t0[Y] }; - double t0s1[2] = { s1[X]-t0[X], s1[Y]-t0[Y] }; - double nt01_x_t0s0 = t0s0[X] * t01[Y] - t0s0[Y] * t01[X]; // t0s0 dot norm of t01 - double nt01_x_t0s1 = t0s1[X] * t01[Y] - t0s1[Y] * t01[X]; // t0s1 dot norm of t01 - double dist_ts0 = fabs( nt01_x_t0s0 ); // dist from tgt seg to s0 - double dist_ts1 = fabs( nt01_x_t0s1 ); // dist from tgt seg to s1 - bool s0_out_of_tol = ( dist_ts0 > _tolerance ); - bool s1_out_of_tol = ( dist_ts1 > _tolerance ); - if ( nt01_x_t0s0 * nt01_x_t0s1 > 0 && ( s0_out_of_tol || s1_out_of_tol )) - return false; // tgt segment is to far from src segment - - double S0[2] = { s0[X], s0[Y] }; - double S1[2] = { s1[X], s1[Y] }; - if ( s0_out_of_tol ) // put s0 within tolerance - { - double t = _tolerance * nt01_x_t0s0 / dist_ts0; // signed tolerance - double r = ( nt01_x_t0s0 - t ) / ( nt01_x_t0s0 - nt01_x_t0s1 ); - S0[X] = s0[X] * ( 1.-r ) + s1[X] * r; - S0[Y] = s0[Y] * ( 1.-r ) + s1[Y] * r; - } - if ( s1_out_of_tol ) // put s1 within tolerance - { - double t = _tolerance * nt01_x_t0s1 / dist_ts1; // signed tolerance - double r = ( nt01_x_t0s1 - t ) / ( nt01_x_t0s1 - nt01_x_t0s0 ); - S1[X] = s1[X] * ( 1.-r ) + s0[X] * r; - S1[Y] = s1[Y] * ( 1.-r ) + s0[Y] * r; - } - - // project tgt and src segments to median line - - double s01[2] = { S1[X]-S0[X], S1[Y]-S0[Y] }; // src segment direction - double sSize = sqrt( s01[X]*s01[X] + s01[Y]*s01[Y] ); // src segment size - if ( sSize < _precision ) - return false; // degenerated segment - s01[X] /= sSize, s01[Y] /= sSize; // normalize s01 - - // make t01 and s01 codirected - double t01_x_s01 = t01[X] * s01[X] + t01[Y] * s01[Y]; // t01 dot s01 - if ( t01_x_s01 < 0 ) - s01[X] = -s01[X], s01[Y] = -s01[Y]; - - double medianDir[2] = { - t01[X] * ( 1.-_median_line) + s01[X] * _median_line, - t01[Y] * ( 1.-_median_line) + s01[Y] * _median_line - }; - double medianSize = sqrt( medianDir[X]*medianDir[X] + medianDir[Y]*medianDir[Y] ); - if ( medianSize < std::numeric_limits::min() ) - return false; // strange... - medianDir[X] /= medianSize, medianDir[Y] /= medianSize; - - xt0 = t0[X] * medianDir[X] + t0[Y] * medianDir[Y]; - xt1 = t1[X] * medianDir[X] + t1[Y] * medianDir[Y]; - xs0 = S0[X] * medianDir[X] + S0[Y] * medianDir[Y]; - xs1 = S1[X] * medianDir[X] + S1[Y] * medianDir[Y]; - - } // if ( SPACEDIM == 2 ) - return true; - } - - /*! - * \brief Return length of intersection of two segments - */ - template - double CurveIntersector::intersectSegmentsInternal(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const - { - if(!projectionThis(coordsT,coordsS,xs0,xs1,xt0,xt1)) - return 0.; - - if ( xt0 > xt1 ) std::swap( xt0, xt1 ); - if ( xs0 > xs1 ) std::swap( xs0, xs1 ); - - double x0 = std::max( xt0, xs0 ); - double x1 = std::min( xt1, xs1 ); - return ( x0 < x1 ) ? ( x1 - x0 ) : 0.; - } - - /*! - * \brief Return length of intersection of two segments - */ - template - double CurveIntersector::intersectSegments(const double *coordsT, const double *coordsS) const - { - double xs0,xs1,xt0,xt1; - return intersectSegmentsInternal(coordsT,coordsS,xs0,xs1,xt0,xt1); - } - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx b/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx deleted file mode 100644 index eabf428f6..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __CURVEINTERSECTORP0P0_HXX__ -#define __CURVEINTERSECTORP0P0_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP0P0 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType icellT, - const std::vector& icellsS, MyMatrix& res); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.txx b/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.txx deleted file mode 100644 index 61c7fd60b..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.txx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __CURVEINTERSECTORP0P0_TXX__ -#define __CURVEINTERSECTORP0P0_TXX__ - -#include "CurveIntersectorP0P0.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP0P0 - ::CurveIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR(meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP0P0 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfElements(); - } - - template - int CurveIntersectorP0P0 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfElements(); - } - - template - void CurveIntersectorP0P0 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - typename MyMatrix::value_type& resRow = res[icellT]; - std::vector coordsT; - int t, nbSegT = 1 + BASE_INTERSECTOR::getRealTargetCoordinates(icellT,coordsT); - for ( t = 0; t < nbSegT; ++t ) - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - std::vector coordsS; - int s, nbSegS = 1 + BASE_INTERSECTOR::getRealSourceCoordinates(iS,coordsS); - for ( s = 0; s < nbSegS; ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&coordsT[0] + t*SPACEDIM, - &coordsS[0] + s*SPACEDIM); - if(surf!=0.) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx b/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx deleted file mode 100644 index e8469d0f1..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __CURVEINTERSECTORP0P1_HXX__ -#define __CURVEINTERSECTORP0P1_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP0P1 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, - const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.txx b/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.txx deleted file mode 100644 index a12e41142..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __CurveIntersectorP0P1_TXX__ -#define __CurveIntersectorP0P1_TXX__ - -#include "CurveIntersectorP0P1.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP0P1 - ::CurveIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR(meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP0P1 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfNodes(); - } - - template - int CurveIntersectorP0P1 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfElements(); - } - - //================================================================================ - /*! - * \brief Project from segments to nodes - */ - //================================================================================ - - template - void CurveIntersectorP0P1 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector segmentsT; - BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); - for ( int t = 0; t < (int)segmentsT.size(); ++t ) - { - typename MyMatrix::value_type& resRow = res[ OTT::ind2C( segmentsT[t]._nodeId )]; - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - std::vector coordsS; - int s, nbSegS = 1 + BASE_INTERSECTOR::getRealSourceCoordinates(iS,coordsS); - for ( s = 0; s < nbSegS; ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], - &coordsS[0] + s*SPACEDIM); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - else - { - surf+=(*iterRes).second; - resRow.erase(OTT::indFC(iS)); - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - } - } - } - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx b/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx deleted file mode 100644 index f2d78c200..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __CURVEINTERSECTORP1P0_HXX__ -#define __CURVEINTERSECTORP1P0_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP1P0 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.txx b/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.txx deleted file mode 100644 index 7125fc8b3..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __CurveIntersectorP1P0_TXX__ -#define __CurveIntersectorP1P0_TXX__ - -#include "CurveIntersectorP1P0.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP1P0 - ::CurveIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR (meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP1P0 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfElements(); - } - - template - int CurveIntersectorP1P0 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfNodes(); - } - - //================================================================================ - /*! - * \brief Project from source nodes to target segments - */ - //================================================================================ - - template - void CurveIntersectorP1P0 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - typename MyMatrix::value_type& resRow = res[ icellT ]; - std::vector segmentsS; - std::vector coordsT; - int t, nbSegT = 1 + BASE_INTERSECTOR::getRealTargetCoordinates(icellT,coordsT); - for ( t = 0; t < nbSegT; ++t ) - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - BASE_INTERSECTOR::getDualSegments( OTT::ind2C(iS), - BASE_INTERSECTOR::_meshS, segmentsS); - for ( int s = 0; s < (int)segmentsS.size(); ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&segmentsS[s]._coords[0], - &coordsT[0] + t*SPACEDIM); - if(surf!=0.) - { - int nS = segmentsS[s]._nodeId; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(nS); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(nS,surf)); - else - { - surf+=(*iterRes).second; - resRow.erase(nS); - resRow.insert(std::make_pair(nS,surf)); - } - } - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx b/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx deleted file mode 100644 index 34678e712..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __CURVEINTERSECTORP1P1_HXX__ -#define __CURVEINTERSECTORP1P1_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP1P1 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, - const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.txx b/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.txx deleted file mode 100644 index 266c87083..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.txx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __CurveIntersectorP1P1_TXX__ -#define __CurveIntersectorP1P1_TXX__ - -#include "CurveIntersectorP1P1.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP1P1 - ::CurveIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR (meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP1P1 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfNodes(); - } - - template - int CurveIntersectorP1P1 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfNodes(); - } - - template - void CurveIntersectorP1P1 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector segmentsT, segmentsS; - BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); - for ( int t = 0; t < (int)segmentsT.size(); ++t ) - { - typename MyMatrix::value_type& resRow = res[ OTT::ind2C( segmentsT[t]._nodeId )]; - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - BASE_INTERSECTOR::getDualSegments( OTT::ind2C(iS), - BASE_INTERSECTOR::_meshS, segmentsS); - for ( int s = 0; s < (int)segmentsS.size(); ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], - &segmentsS[s]._coords[0]); - if(surf!=0.) - { - int nS = segmentsS[s]._nodeId; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(nS); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(nS,surf)); - else - { - surf+=(*iterRes).second; - resRow.erase(nS); - resRow.insert(std::make_pair(nS,surf)); - } - } - } - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx b/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx deleted file mode 100644 index d9bab059b..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __CURVEINTERSECTORP1P1PL_HXX__ -#define __CURVEINTERSECTORP1P1PL_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP1P1PL : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - private: - static void AppendValueInMatrix(MyMatrix& res, ConnType nodeIdT, ConnType nodeIdS0, double val0, ConnType nodeIdS1, double val1); - static void AppendValueInMatrix2(typename MyMatrix::value_type& resRow, ConnType nodeIdS0, double val0); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx b/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx deleted file mode 100644 index 02b09eb91..000000000 --- a/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __CURVEINTERSECTORP1P1PL_TXX__ -#define __CURVEINTERSECTORP1P1PL_TXX__ - -#include "CurveIntersectorP1P1PL.hxx" -#include "CurveIntersector.txx" - -#include - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP1P1PL::CurveIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double precision, double tolerance, double medianLine, int printLevel):CurveIntersector(meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP1P1PL::getNumberOfRowsOfResMatrix() const - { - return CurveIntersector::_meshT.getNumberOfNodes(); - } - - template - int CurveIntersectorP1P1PL::getNumberOfColsOfResMatrix() const - { - return CurveIntersector::_meshS.getNumberOfNodes(); - } - - template - void CurveIntersectorP1P1PL::AppendValueInMatrix2(typename MyMatrix::value_type& resRow, ConnType nodeIdS0, double val0) - { - typename MyMatrix::value_type::const_iterator iterRes(resRow.find(OTT::indFC(nodeIdS0))); - if(iterRes==resRow.end()) - { - resRow.insert(std::make_pair(OTT::indFC(nodeIdS0),val0)); - } - else - { - double val((*iterRes).second+val0); - resRow.erase(OTT::indFC(nodeIdS0)); - resRow.insert(std::make_pair(OTT::indFC(nodeIdS0),val)); - } - } - - template - void CurveIntersectorP1P1PL::AppendValueInMatrix(MyMatrix& res, ConnType nodeIdT, ConnType nodeIdS0, double val0, ConnType nodeIdS1, double val1) - { - typename MyMatrix::value_type& resRow(res[nodeIdT]); - AppendValueInMatrix2(resRow,nodeIdS0,val0); - AppendValueInMatrix2(resRow,nodeIdS1,val1); - } - - template - void CurveIntersectorP1P1PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector coordsT; - if(CurveIntersector::getRealTargetCoordinates(icellT,coordsT)) - throw INTERP_KERNEL::Exception("Invalid target cell detected for meshdim==1. Only SEG2 supported !"); - assert(coordsT.size()/SPACEDIM==2); - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - std::vector coordsS; - if(CurveIntersector::getRealSourceCoordinates(*iter,coordsS)) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==1. Only SEG2 supported !"); - assert(coordsS.size()/SPACEDIM==2); - double xs0,xs1,xt0,xt1; - double lgth(CurveIntersector::intersectSegmentsInternal(&coordsT[0],&coordsS[0],xs0,xs1,xt0,xt1)); - ConnType nodeIdS0(CurveIntersector::getNodeIdOfSourceCellAt(*iter,0)); - ConnType nodeIdS1(CurveIntersector::getNodeIdOfSourceCellAt(*iter,1)); - if(lgth>0.) - { - double a,b; - // for first - ConnType nodeIdT0(CurveIntersector::getNodeIdOfTargetCellAt(icellT,0)); - if(CurveIntersector::ComputeBaryCoordsOf(xs0,xs1,xt0,a,b)) - { - a*=lgth; b*=lgth; - AppendValueInMatrix(res,nodeIdT0,nodeIdS0,a,nodeIdS1,b); - } - // - ConnType nodeIdT1(CurveIntersector::getNodeIdOfTargetCellAt(icellT,1)); - typename MyMatrix::value_type& resRow1=res[nodeIdT1]; - if(CurveIntersector::ComputeBaryCoordsOf(xs0,xs1,xt1,a,b)) - { - a*=lgth; b*=lgth; - AppendValueInMatrix(res,nodeIdT1,nodeIdS0,a,nodeIdS1,b); - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/DiameterCalculator.cxx b/medtool/src/INTERP_KERNEL/DiameterCalculator.cxx deleted file mode 100644 index b89d66383..000000000 --- a/medtool/src/INTERP_KERNEL/DiameterCalculator.cxx +++ /dev/null @@ -1,745 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#include "DiameterCalculator.hxx" -#include "InterpKernelException.hxx" -#include "CellModel.hxx" - -#include -#include -#include - -using namespace INTERP_KERNEL; - -NormalizedCellType DiameterCalulatorTRI3S2::TYPE=NORM_TRI3; - -NormalizedCellType DiameterCalulatorTRI3S3::TYPE=NORM_TRI3; - -NormalizedCellType DiameterCalulatorTRI6S2::TYPE=NORM_TRI6; - -NormalizedCellType DiameterCalulatorTRI6S3::TYPE=NORM_TRI6; - -NormalizedCellType DiameterCalulatorTRI7S2::TYPE=NORM_TRI7; - -NormalizedCellType DiameterCalulatorTRI7S3::TYPE=NORM_TRI7; - -NormalizedCellType DiameterCalulatorQUAD4S2::TYPE=NORM_QUAD4; - -NormalizedCellType DiameterCalulatorQUAD4S3::TYPE=NORM_QUAD4; - -NormalizedCellType DiameterCalulatorQUAD8S2::TYPE=NORM_QUAD8; - -NormalizedCellType DiameterCalulatorQUAD8S3::TYPE=NORM_QUAD8; - -NormalizedCellType DiameterCalulatorQUAD9S2::TYPE=NORM_QUAD9; - -NormalizedCellType DiameterCalulatorQUAD9S3::TYPE=NORM_QUAD9; - -NormalizedCellType DiameterCalulatorTETRA4::TYPE=NORM_TETRA4; - -NormalizedCellType DiameterCalulatorTETRA10::TYPE=NORM_TETRA10; - -NormalizedCellType DiameterCalulatorHEXA8::TYPE=NORM_HEXA8; - -NormalizedCellType DiameterCalulatorHEXA20::TYPE=NORM_HEXA20; - -NormalizedCellType DiameterCalulatorHEXA27::TYPE=NORM_HEXA27; - -NormalizedCellType DiameterCalulatorPENTA6::TYPE=NORM_PENTA6; - -NormalizedCellType DiameterCalulatorPENTA15::TYPE=NORM_PENTA15; - -NormalizedCellType DiameterCalulatorPYRA5::TYPE=NORM_PYRA5; - -NormalizedCellType DiameterCalulatorPYRA13::TYPE=NORM_PYRA13; - -inline double SqNormV2(const double tab[2]) -{ - return tab[0]*tab[0]+tab[1]*tab[1]; -} - -inline void DiffV2(const double a[2], const double b[2], double c[2]) -{ - c[0]=a[0]-b[0]; - c[1]=a[1]-b[1]; -} - -inline double SqNormV3(const double tab[3]) -{ - return tab[0]*tab[0]+tab[1]*tab[1]+tab[2]*tab[2]; -} - -inline void DiffV3(const double a[3], const double b[3], double c[3]) -{ - c[0]=a[0]-b[0]; - c[1]=a[1]-b[1]; - c[2]=a[2]-b[2]; -} - -template -void ComputeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) -{ - Evaluator evtor; - NormalizedCellType ct(Evaluator::TYPE); - int cti((int) ct); - for(const int *it=bgIds;it!=endIds;it++) - { - int offset(indPtr[*it]); - if(connPtr[offset]==cti) - resPtr[*it]=evtor.ComputeForOneCellInternal(connPtr+offset+1,connPtr+indPtr[(*it)+1],coordsPtr); - else - { - std::ostringstream oss; oss << "DiameterCalculator::computeForListOfCellIdsUMeshFrmt : invalid nodal connectivity format at cell # " << *it << " !"; - throw Exception(oss.str().c_str()); - } - } -} - -template -void ComputeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) -{ - Evaluator evtor; - NormalizedCellType ct(Evaluator::TYPE); - int cti((int) ct); - for(int it=bgId;it -void ComputeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) -{ - Evaluator evtor; - NormalizedCellType ct(Evaluator::TYPE); - const CellModel& cm(CellModel::GetCellModel(ct)); - unsigned nbNodes(cm.getNumberOfNodes()); - const int *ptr(connPtr); - for(int i=0;i(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI3S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==3) - { - const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]); - double l0[3],l1[3],l2[3]; - DiffV3(a,b,l0); - DiffV3(a,c,l1); - DiffV3(b,c,l2); - double res(std::max(SqNormV3(l0),SqNormV3(l1))); - res=std::max(res,SqNormV3(l2)); - return std::sqrt(res); - } - else - throw Exception("DiameterCalulatorTRI3S2::ComputeForOneCellInternal : input connectivity must be of size 3 !"); -} - -void DiameterCalulatorTRI3S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI6S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==6) - return DiameterCalulatorTRI3S2::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI6S2::ComputeForOneCellInternal : input connectivity must be of size 6 !"); -} - -void DiameterCalulatorTRI6S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI6S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==6) - return DiameterCalulatorTRI3S3::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI6S3::ComputeForOneCellInternal : input connectivity must be of size 6 !"); -} - -void DiameterCalulatorTRI6S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI7S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==7) - return DiameterCalulatorTRI3S2::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI7S2::ComputeForOneCellInternal : input connectivity must be of size 7 !"); -} - -void DiameterCalulatorTRI7S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI7S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==7) - return DiameterCalulatorTRI3S3::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI7S3::ComputeForOneCellInternal : input connectivity must be of size 7 !"); -} - -void DiameterCalulatorTRI7S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==4) - { - const double *a(coordsPtr+2*bg[0]),*b(coordsPtr+2*bg[1]),*c(coordsPtr+2*bg[2]),*d(coordsPtr+2*bg[3]); - double l0[2],l1[2]; - DiffV2(a,c,l0); - DiffV2(b,d,l1); - return std::sqrt(std::max(SqNormV2(l0),SqNormV2(l1))); - } - else - throw Exception("DiameterCalulatorQUAD4S2::ComputeForOneCellInternal : input connectivity must be of size 4 !"); -} - -void DiameterCalulatorQUAD4S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==4) - { - const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]); - double l0[3],l1[3]; - DiffV3(a,c,l0); - DiffV3(b,d,l1); - return std::sqrt(std::max(SqNormV3(l0),SqNormV3(l1))); - } - else - throw Exception("DiameterCalulatorQUAD4S3::ComputeForOneCellInternal : input connectivity must be of size 4 !"); -} - -void DiameterCalulatorQUAD4S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD8S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==8) - return DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD8S2::ComputeForOneCellInternal : input connectivity must be of size 8 !"); -} - -void DiameterCalulatorQUAD8S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD8S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==8) - return DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD8S3::ComputeForOneCellInternal : input connectivity must be of size 8 !"); -} - -void DiameterCalulatorQUAD8S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD9S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==9) - return DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD9S2::ComputeForOneCellInternal : input connectivity must be of size 9 !"); -} - -void DiameterCalulatorQUAD9S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD9S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==9) - return DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD8S3::ComputeForOneCellInternal : input connectivity must be of size 9 !"); -} - -void DiameterCalulatorQUAD9S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTETRA4::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==4) - { - const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]); - double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; - DiffV3(a,b,l0); - DiffV3(a,c,l1); - DiffV3(b,c,l2); - DiffV3(a,d,l3); - DiffV3(b,d,l4); - DiffV3(c,d,l5); - double tmp[6]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); - return std::sqrt(*std::max_element(tmp,tmp+6)); - } - else - throw Exception("DiameterCalulatorTETRA4::ComputeForOneCellInternal : input connectivity must be of size 4 !"); -} - -void DiameterCalulatorTETRA4::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA4::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA4::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTETRA10::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==10) - return DiameterCalulatorTETRA4::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorTETRA10::ComputeForOneCellInternal : input connectivity must be of size 10 !"); -} - -void DiameterCalulatorTETRA10::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA10::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA10::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorHEXA8::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==8) - { - const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]),*p6(coordsPtr+3*bg[6]),*p7(coordsPtr+3*bg[7]); - double l0[3],l1[3],l2[3],l3[3]; - DiffV3(p0,p6,l0); - DiffV3(p1,p7,l1); - DiffV3(p2,p4,l2); - DiffV3(p3,p5,l3); - double tmp[4]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); - return std::sqrt(*std::max_element(tmp,tmp+4)); - } - else - throw Exception("DiameterCalulatorHEXA8::ComputeForOneCellInternal : input connectivity must be of size 8 !"); -} - -void DiameterCalulatorHEXA8::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA8::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA8::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorHEXA20::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==20) - return DiameterCalulatorHEXA8::ComputeForOneCellInternal(bg,bg+8,coordsPtr); - else - throw Exception("DiameterCalulatorHEXA20::ComputeForOneCellInternal : input connectivity must be of size 20 !"); -} - -void DiameterCalulatorHEXA20::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA20::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA20::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorHEXA27::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==27) - return DiameterCalulatorHEXA8::ComputeForOneCellInternal(bg,bg+8,coordsPtr); - else - throw Exception("DiameterCalulatorHEXA27::ComputeForOneCellInternal : input connectivity must be of size 27 !"); -} - -void DiameterCalulatorHEXA27::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA27::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA27::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPENTA6::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==6) - { - const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]); - double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; - DiffV3(p0,p4,l0); - DiffV3(p1,p3,l1); - DiffV3(p1,p5,l2); - DiffV3(p2,p4,l3); - DiffV3(p0,p5,l4); - DiffV3(p2,p3,l5); - double tmp[6]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); - return std::sqrt(*std::max_element(tmp,tmp+6)); - } - else - throw Exception("DiameterCalulatorPENTA6::ComputeForOneCellInternal : input connectivity must be of size 6 !"); -} - -void DiameterCalulatorPENTA6::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA6::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA6::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPENTA15::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==15) - return DiameterCalulatorPENTA6::ComputeForOneCellInternal(bg,bg+6,coordsPtr); - else - throw Exception("DiameterCalulatorPENTA15::ComputeForOneCellInternal : input connectivity must be of size 15 !"); -} - -void DiameterCalulatorPENTA15::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA15::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA15::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPYRA5::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==5) - { - const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]); - double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; - DiffV3(p0,p2,l0); - DiffV3(p1,p3,l1); - DiffV3(p0,p4,l2); - DiffV3(p1,p4,l3); - DiffV3(p2,p4,l4); - DiffV3(p3,p4,l5); - double tmp[6]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); - return std::sqrt(*std::max_element(tmp,tmp+6)); - } - else - throw Exception("DiameterCalulatorPYRA5::ComputeForOneCellInternal : input connectivity must be of size 5 !"); -} - -void DiameterCalulatorPYRA5::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA5::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA5::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPYRA13::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==13) - return DiameterCalulatorPYRA5::ComputeForOneCellInternal(bg,bg+5,coordsPtr); - else - throw Exception("DiameterCalulatorPYRA13::ComputeForOneCellInternal : input connectivity must be of size 13 !"); -} - -void DiameterCalulatorPYRA13::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA13::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA13::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} diff --git a/medtool/src/INTERP_KERNEL/DiameterCalculator.hxx b/medtool/src/INTERP_KERNEL/DiameterCalculator.hxx deleted file mode 100644 index a2a0a19f1..000000000 --- a/medtool/src/INTERP_KERNEL/DiameterCalculator.hxx +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __DIAMETERCALCULATOR_HXX__ -#define __DIAMETERCALCULATOR_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include "NormalizedGeometricTypes" - -namespace INTERP_KERNEL -{ - class DiameterCalculator - { - public: - INTERPKERNEL_EXPORT virtual ~DiameterCalculator() { } - INTERPKERNEL_EXPORT virtual NormalizedCellType getType() const = 0; - INTERPKERNEL_EXPORT virtual double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const = 0; - INTERPKERNEL_EXPORT virtual void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; - INTERPKERNEL_EXPORT virtual void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; - INTERPKERNEL_EXPORT virtual void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; - }; - - class DiameterCalulatorTRI3S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI3S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI6S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI6S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI7S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI7S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD4S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD4S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD8S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD8S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD9S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD9S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTETRA4 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTETRA10 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorHEXA8 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorHEXA20 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorHEXA27 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPENTA6 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPENTA15 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPYRA5 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPYRA13 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/DirectedBoundingBox.cxx b/medtool/src/INTERP_KERNEL/DirectedBoundingBox.cxx deleted file mode 100644 index 113a905f1..000000000 --- a/medtool/src/INTERP_KERNEL/DirectedBoundingBox.cxx +++ /dev/null @@ -1,757 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : DirectedBoundingBox.cxx -// Created : Mon Apr 12 14:41:22 2010 -// Author : Edward AGAPOV (eap) - -#include "DirectedBoundingBox.hxx" - -#include "InterpolationUtils.hxx" - -#define __TENSOR(i,j) tensor[(i)*_dim+(j)] -#define __AXIS(i) (&_axes[(i)*_dim]) -#define __MIN(i) _minmax[i*2] -#define __MAX(i) _minmax[i*2+1] -#define __MYID (long(this)%10000) -#define __DMP(msg) \ - // cout << msg << endl - -using namespace std; - -namespace -{ - //================================================================================ - /*! - * \brief Add point coordinates to inertia tensor in 3D space - */ - //================================================================================ - - inline void addPointToInertiaTensor3D(const double* coord, - const double* gc, - vector& tensor) - { - // we fill the upper triangle of tensor only - const int _dim = 3; - double x = coord[0] - gc[0], y = coord[1] - gc[1], z = coord[2] - gc[2]; - __TENSOR(0,0) += y*y + z*z; - __TENSOR(1,1) += x*x + z*z; - __TENSOR(2,2) += x*x + y*y; - __TENSOR(0,1) -= x*y; - __TENSOR(0,2) -= x*z; - __TENSOR(1,2) -= y*z; - } - //================================================================================ - /*! - * \brief Add point coordinates to inertia tensor in 2D space - */ - //================================================================================ - - inline void addPointToInertiaTensor2D(const double* coord, - const double* gc, - vector& tensor) - { - // we fill the upper triangle of tensor only - const int _dim = 2; - double x = coord[0] - gc[0], y = coord[1] - gc[1]; - __TENSOR(0,0) += y*y; - __TENSOR(1,1) += x*x; - __TENSOR(0,1) -= x*y; - } - - //================================================================================ - /*! - * \brief Find eigenvectors of tensor using Jacobi's method - */ - //================================================================================ - - bool JacobiEigenvectorsSearch( const int _dim, vector& tensor, vector& _axes) - { - if ( _dim == 3 ) - { - __DMP( "Tensor : {" - << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << ", "<<__TENSOR(0,2) << "} " - << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << ", "<<__TENSOR(1,2) << "} " - << "{ "<<__TENSOR(2,0) << ", "<<__TENSOR(2,1) << ", "<<__TENSOR(2,2) << "}} "); - } - else - { - __DMP( "Tensor : {" - << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << "} " - << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << "}} "); - } - - const int maxRot = 5*_dim*_dim; // limit on number of rotations - const double tol = 1e-9; - - // set _axes to identity - int i,j; - for ( i = 0; i < _dim; ++i ) - for ( j = 0; j < _dim; ++j ) - __AXIS(i)[j] = ( i==j ? 1. : 0 ); - - bool solved = false; - for ( int iRot = 0; iRot < maxRot; ++ iRot ) - { - // find max off-diagonal element of the tensor - int k = 0, l = 0; - double max = 0.; - for ( i = 0; i < _dim-1; ++i ) - for ( j = i+1; j < _dim; ++j ) - if ( fabs( __TENSOR(i,j)) > max ) - max = fabs( __TENSOR(i,j) ), k = i, l = j; - solved = ( max < tol ); - if ( solved ) - break; - - // Rotate to make __TENSOR(k,l) == 0 - - double diff = __TENSOR(l,l) - __TENSOR(k,k); - double t; // tangent of rotation angle - if ( fabs(__TENSOR(k,l)) < abs(diff)*1.0e-36) - { - t = __TENSOR(k,l)/diff; - } - else - { - double phi = diff/(2.0*__TENSOR(k,l)); - t = 1.0/(abs(phi) + sqrt(phi*phi + 1.0)); - if ( phi < 0.0) t = -t; - } - double c = 1.0/sqrt(t*t + 1.0); // cosine of rotation angle - double s = t*c; // sine of rotation angle - double tau = s/(1.0 + c); - __TENSOR(k,k) -= t*__TENSOR(k,l); - __TENSOR(l,l) += t*__TENSOR(k,l); - __TENSOR(k,l) = 0.0; - -#define __ROTATE(T,r1,c1,r2,c2) \ -{ \ -int i1 = r1*_dim+c1, i2 = r2*_dim+c2; \ -double t1 = T[i1], t2 = T[i2]; \ -T[i1] -= s * ( t2 + tau * t1);\ -T[i2] += s * ( t1 - tau * t2);\ -} - for ( i = 0; i < k; ++i ) // Case of i < k - __ROTATE(tensor, i,k,i,l); - - for ( i = k+1; i < l; ++i ) // Case of k < i < l - __ROTATE(tensor, k,i,i,l); - - for ( i = l + 1; i < _dim; ++i ) // Case of i > l - __ROTATE(tensor, k,i,l,i); - - for ( i = 0; i < _dim; ++i ) // Update transformation matrix - __ROTATE(_axes, i,k,i,l); - } - - __DMP( "Solved = " << solved ); - if ( _dim == 3 ) { - __DMP( " Eigen " << __TENSOR(0,0)<<", "<<__TENSOR(1,1)<<", "<<__TENSOR(2,2) ); - for ( int ii=0; ii <3; ++ii ) - __DMP( ii << ": " << __AXIS(ii)[0] << ", " << __AXIS(ii)[1] << ", " << __AXIS(ii)[2] ); - } - else { - __DMP( " Eigen " << __TENSOR(0,0) << ", " << __TENSOR(1,1) ); - for ( int ii=0; ii <2; ++ii ) - __DMP( ii << ": " << __AXIS(ii)[0] << ", " << __AXIS(ii)[1] ); - } - - return solved; - } - - //================================================================================ - /*! - * \brief Return true if two minmaxes do not intersect - */ - //================================================================================ - - inline bool isMinMaxOut(const double* minmax1, - const double* minmax2, - int dim) - { - for ( int i = 0; i < dim; ++i ) - { - if ( minmax1[i*2] > minmax2[i*2+1] || - minmax1[i*2+1] < minmax2[i*2] ) - return true; - } - return false; - } - -} // noname namespace - -namespace INTERP_KERNEL -{ - - //================================================================================ - /*! - * \brief Creates empty box intended to further initalization via setData() - */ - //================================================================================ - - DirectedBoundingBox::DirectedBoundingBox():_dim(0) - { - } - - //================================================================================ - /*! - * \brief Creates bounding box of a mesh - * \param pts - coordinates of points in full interlace - * \param numPts - number of points in the mesh - * \param dim - space dimension - */ - //================================================================================ - - DirectedBoundingBox::DirectedBoundingBox(const double* pts, - const unsigned numPts, - const unsigned dim) - : _dim(dim), _axes(dim*dim), _minmax(2*dim) - { - // init box extremities - for ( unsigned i = 0; i < _dim; ++i ) - _minmax[1+i*2] = -numeric_limits::max(), - _minmax[i*2] = numeric_limits::max(); - - if ( numPts < 1 ) return; - - __DMP( "DirectedBoundingBox " << __MYID ); - - const double* coord = pts; - const double* coordEnd = coord + numPts * dim; - - // compute gravity center of points - double gc[3] = {0,0,0}; - if ( dim > 1 ) - { - for ( coord = pts; coord < coordEnd; ) - for ( int i = 0; i < (int)dim; ++i ) - gc[i] += *coord++; - for ( int j = 0; j < (int)dim; ++j ) - gc[j] /= numPts; - - } - - // compute axes and box extremities - vector tensor( dim * dim, 0.); - switch ( dim ) - { - case 3: - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToInertiaTensor3D( coord, gc, tensor ); - - //computeAxes3D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToBox( coord ); - - break; - - case 2: - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToInertiaTensor2D( coord, gc, tensor ); - - //computeAxes2D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToBox( coord ); - - break; - - default: - for ( coord = pts; coord < coordEnd; coord += dim ) - { - if ( *coord < _minmax[0] ) _minmax[0] = *coord; - if ( *coord > _minmax[1] ) _minmax[1] = *coord; - } - } - } - - //================================================================================ - /*! - * \brief Creates bounding box of an element - * \param pts - coordinates of points of element - * \param numPts - number of points in the element - * \param dim - space dimension - */ - //================================================================================ - - DirectedBoundingBox::DirectedBoundingBox(const double** pts, - const unsigned numPts, - const unsigned dim) - : _dim(dim), _axes(dim*dim), _minmax(2*dim) - { - // init box extremities - for ( unsigned i = 0; i < _dim; ++i ) - _minmax[1+i*2] = -numeric_limits::max(), - _minmax[i*2] = numeric_limits::max(); - - if ( numPts < 1 ) return; - - __DMP( "DirectedBoundingBox " << __MYID ); - - // compute gravity center of points - double gc[3] = {0,0,0}; - if ( dim > 1 ) - { - for ( unsigned i = 0; i < numPts; ++i ) - for ( int j = 0; j < (int)dim; ++j ) - gc[j] += pts[i][j]; - for ( int j = 0; j < (int)dim; ++j ) - gc[j] /= numPts; - } - - // compute axes and box extremities - vector tensor( dim * dim, 0.); - switch ( dim ) - { - case 3: - for ( unsigned i = 0; i < numPts; ++i ) - addPointToInertiaTensor3D( pts[i], gc, tensor ); - - //computeAxes3D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( unsigned i = 0; i < numPts; ++i ) - addPointToBox( pts[i] ); - - break; - case 2: - for ( unsigned i = 0; i < numPts; ++i ) - addPointToInertiaTensor2D( pts[i], gc, tensor ); - - //computeAxes2D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( unsigned i = 0; i < numPts; ++i ) - addPointToBox( pts[i] ); - - break; - default: - for ( unsigned i = 0; i < numPts; ++i ) - { - if ( pts[i][0] < _minmax[0] ) _minmax[0] = pts[i][0]; - if ( pts[i][0] > _minmax[1] ) _minmax[1] = pts[i][0]; - } - _axes[0] = 1.0; - } - } - - //================================================================================ - /*! - * \brief Compute eigenvectors of inertia tensor - */ - //================================================================================ - - // void DirectedBoundingBox::computeAxes3D(const std::vector& tensor) -// { -// // compute principal moments of inertia which are eigenvalues of the tensor -// double eig[3]; -// { -// // coefficients of polynomial equation det(tensor-eig*I) = 0 -// double a = -1; -// double b = __TENSOR(0,0)+__TENSOR(1,1)+__TENSOR(2,2); -// double c = -// __TENSOR(0,1)*__TENSOR(0,1) + -// __TENSOR(0,2)*__TENSOR(0,2) + -// __TENSOR(1,2)*__TENSOR(1,2) - -// __TENSOR(0,0)*__TENSOR(1,1) - -// __TENSOR(0,0)*__TENSOR(2,2) - -// __TENSOR(1,1)*__TENSOR(2,2); -// double d = -// __TENSOR(0,0)*__TENSOR(1,1)*__TENSOR(2,2) - -// __TENSOR(0,0)*__TENSOR(1,2)*__TENSOR(1,2) - -// __TENSOR(1,1)*__TENSOR(0,2)*__TENSOR(0,2) - -// __TENSOR(2,2)*__TENSOR(0,1)*__TENSOR(0,1) + -// __TENSOR(0,1)*__TENSOR(0,2)*__TENSOR(1,2)*2; - -// // find eigenvalues which are roots of characteristic polynomial -// double x = (3*c/a - b*b/(a*a))/3; -// double y = (2*b*b*b/(a*a*a) - 9*b*c/(a*a) + 27*d/a)/27; -// double z = y*y/4 + x*x*x/27; - -// double i = sqrt(y*y/4 - z) + 1e-300; -// double j = -pow(i,1/3.); -// double y2 = -y/(2*i); -// if ( y2 > 1.0) y2 = 1.; else if ( y2 < -1.0) y2 = -1.; -// double k = acos(y2); -// double m = cos(k/3); -// double n = sqrt(3)*sin(k/3); -// double p = -b/(3*a); - -// eig[0] = -2*j*m + p; -// eig[1] = j *(m + n) + p; -// eig[2] = j *(m - n) + p; -// } -// // compute eigenvector of the tensor at each eigenvalue -// // by solving system [tensor-eig*I]*[axis] = 0 -// bool ok = true; -// __DMP( "Tensor : {" -// << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << ", "<<__TENSOR(0,2) << "} " -// << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << ", "<<__TENSOR(1,2) << "} " -// << "{ "<<__TENSOR(2,0) << ", "<<__TENSOR(2,1) << ", "<<__TENSOR(2,2) << "}} "); -// for ( int i = 0; i < 3 && ok; ++i ) // loop on 3 eigenvalues -// { -// // [tensor-eig*I] -// double T[3][3]= -// {{ __TENSOR(0,0)-eig[i],__TENSOR(0,1), __TENSOR(0,2), }, -// { __TENSOR(0,1), __TENSOR(1,1)-eig[i],__TENSOR(1,2), }, -// { __TENSOR(0,2), __TENSOR(1,2), __TENSOR(2,2)-eig[i]}}; -// // The determinant of T is zero, so that the equations are not linearly independent. -// // Therefore, we assign an arbitrary value (1.) to i-th component of eigenvector -// // and use two of the equations to compute the other two components -// double M[2][3], sol[2]; -// for ( int j = 0, c = 0; j < 3; ++j ) -// if ( i == j ) -// M[0][2] = -T[0][j], M[1][2] = -T[1][j]; -// else -// M[0][c] = T[0][j], M[1][c] = T[1][j], c++; - -// ok = solveSystemOfEquations<2>( M, sol ); - -// double* eigenVec = __AXIS(i); -// for ( int j = 0, c = 0; j < 3; ++j ) -// eigenVec[j] = ( i == j ) ? 1. : sol[c++]; - -// // normilize -// double size = sqrt(eigenVec[0]*eigenVec[0] + -// eigenVec[1]*eigenVec[1] + -// eigenVec[2]*eigenVec[2] ); -// if ((ok = (size > numeric_limits::min() ))) -// { -// eigenVec[0] /= size; -// eigenVec[1] /= size; -// eigenVec[2] /= size; -// } -// } -// if ( !ok ) -// { -// __DMP( " solve3EquationSystem() - KO " ); -// _axes = vector( _dim*_dim, 0); -// __AXIS(0)[0] = __AXIS(1)[1] = __AXIS(2)[2] = 1.; -// } -// __DMP( " Eigen " << eig[0] << ", " << eig[1] << ", " << eig[2] ); -// for ( int i=0; i <3; ++i ) -// __DMP( i << ": " << __AXIS(i)[0] << ", " << __AXIS(i)[1] << ", " << __AXIS(i)[2] ); - -// double* a0 = __AXIS(0), *a1 = __AXIS(1); -// double cross[3] = { a0[1]*a1[2]-a1[1]*a0[2], -// a0[2]*a1[0]-a1[2]*a0[0], -// a0[0]*a1[1]-a1[0]*a0[1] }; -// __DMP( " Cross a1^a2 " << cross[0] << ", " << cross[1] << ", " << cross[2] ); -// } - - //================================================================================ - /*! - * \brief Compute eigenvectors of inertia tensor - */ - //================================================================================ - - // void DirectedBoundingBox::computeAxes2D(const std::vector& tensor) -// { -// // compute principal moments of inertia which are eigenvalues of the tensor -// // by solving square equation det(tensor-eig*I) -// double X = (__TENSOR(0,0)+__TENSOR(1,1))/2; -// double Y = sqrt(4*__TENSOR(0,1)*__TENSOR(0,1) + -// (__TENSOR(0,0)-__TENSOR(1,1)) * (__TENSOR(0,0)-__TENSOR(1,1)))/2; -// double eig[2] = -// { -// X + Y, -// X - Y -// }; -// // compute eigenvector of the tensor at each eigenvalue -// // by solving system [tensor-eig*I]*[axis] = 0 -// bool ok = true; -// for ( int i = 0; i < 2 && ok; ++i ) -// { -// // [tensor-eig*I] -// double T[2][2]= -// {{ __TENSOR(0,0)-eig[i],__TENSOR(0,1) }, -// { __TENSOR(0,1), __TENSOR(1,1)-eig[i] }}; - -// // The determinant of T is zero, so that the equations are not linearly independent. -// // Therefore, we assign an arbitrary value (1.) to i-th component of eigenvector -// // and use one equation to compute the other component -// double* eigenVec = __AXIS(i); -// eigenVec[i] = 1.; -// int j = 1-i; -// if ((ok = ( fabs( T[j][j] ) > numeric_limits::min() ))) -// eigenVec[j] = -T[j][i] / T[j][j]; -// } -// if ( !ok ) -// { -// _axes = vector( _dim*_dim, 0); -// __AXIS(0)[0] = __AXIS(1)[1] = 1.; -// } -// } - - //================================================================================ - /*! - * \brief Convert point coordinates into local coordinate system of the box - */ - //================================================================================ - - void DirectedBoundingBox::toLocalCS(const double* p, double* pLoc) const - { - switch ( _dim ) - { - case 3: - pLoc[0] = dotprod<3>( p, __AXIS(0)); - pLoc[1] = dotprod<3>( p, __AXIS(1)); - pLoc[2] = dotprod<3>( p, __AXIS(2)); - break; - case 2: - pLoc[0] = dotprod<2>( p, __AXIS(0)); - pLoc[1] = dotprod<2>( p, __AXIS(1)); - break; - default: - pLoc[0] = p[0]; - } - } - - //================================================================================ - /*! - * \brief Convert point coordinates from local coordinate system of the box to global CS - */ - //================================================================================ - - void DirectedBoundingBox::fromLocalCS(const double* p, double* pGlob) const - { - switch ( _dim ) - { - case 3: - pGlob[0] = p[0] * __AXIS(0)[0] + p[1] * __AXIS(1)[0] + p[2] * __AXIS(2)[0]; - pGlob[1] = p[0] * __AXIS(0)[1] + p[1] * __AXIS(1)[1] + p[2] * __AXIS(2)[1]; - pGlob[2] = p[0] * __AXIS(0)[2] + p[1] * __AXIS(1)[2] + p[2] * __AXIS(2)[2]; - break; - case 2: - pGlob[0] = p[0] * __AXIS(0)[0] + p[1] * __AXIS(1)[0]; - pGlob[1] = p[0] * __AXIS(0)[1] + p[1] * __AXIS(1)[1]; - break; - default: - pGlob[0] = p[0]; - } - } - - //================================================================================ - /*! - * \brief Enlarge box size by given value - */ - //================================================================================ - - void DirectedBoundingBox::enlarge(const double tol) - { - for ( unsigned i = 0; i < _dim; ++i ) - __MIN(i) -= tol, __MAX(i) += tol; - } - - //================================================================================ - /*! - * \brief Return coordinates of corners of bounding box - */ - //================================================================================ - - void DirectedBoundingBox::getCorners(std::vector& corners, - const double* minmax) const - { - int iC, nbCorners = 1; - for ( int i=0;i<(int)_dim;++i ) nbCorners *= 2; - corners.resize( nbCorners * _dim ); - // each coordinate is filled with either min or max, nbSwap is number of corners - // after which min and max swap - int nbSwap = nbCorners/2; - for ( unsigned i = 0; i < _dim; ++i ) - { - iC = 0; - while ( iC < nbCorners ) - { - for (int j = 0; j < nbSwap; ++j, ++iC ) corners[iC*_dim+i] = minmax[i*2]; - for (int j = 0; j < nbSwap; ++j, ++iC ) corners[iC*_dim+i] = minmax[i*2+1]; - } - nbSwap /= 2; - } - } - - //================================================================================ - /*! - * \brief Test if this box intersects with the other - * \retval bool - true if there is no intersection - */ - //================================================================================ - - bool DirectedBoundingBox::isDisjointWith(const DirectedBoundingBox& box) const - { - if ( _dim < 1 || box._dim < 1 ) return false; // empty box includes all - if ( _dim == 1 ) - return isMinMaxOut( &box._minmax[0], &this->_minmax[0], _dim ); - - // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect - for ( int isThisCS = 0; isThisCS < 2; ++isThisCS ) - { - const DirectedBoundingBox* axisBox = isThisCS ? this : &box; - const DirectedBoundingBox* cornerBox = isThisCS ? &box : this; - - // find minmax of cornerBox in the CS of axisBox - - DirectedBoundingBox mmBox((double*)0,0,_dim); //!< empty box with CS == axisBox->_axes - mmBox._axes = axisBox->_axes; - - vector corners; - getCorners( corners, &cornerBox->_minmax[0] ); - - double globCorner[3]; - for ( int iC = 0, nC = corners.size()/_dim; iC < nC; ++iC) - { - cornerBox->fromLocalCS( &corners[iC*_dim], globCorner ); - mmBox.addPointToBox( globCorner ); - } - if ( isMinMaxOut( &mmBox._minmax[0], &axisBox->_minmax[0], _dim )) - return true; - } - return false; - } - - //================================================================================ - /*! - * \brief Test if this box intersects with an non-directed box - * \retval bool - true if there is no intersection - */ - //================================================================================ - - bool DirectedBoundingBox::isDisjointWith(const double* box) const - { - if ( _dim < 1 ) return false; // empty box includes all - if ( _dim == 1 ) - return isMinMaxOut( &_minmax[0], box, _dim ); - - // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect - - // compare minmaxes in locals CS of this directed box - { - vector cornersOther; - getCorners( cornersOther, box ); - DirectedBoundingBox mmBox((double*)0,0,_dim); //!< empty box with CS == this->_axes - mmBox._axes = this->_axes; - for ( int iC = 0, nC = cornersOther.size()/_dim; iC < nC; ++iC) - mmBox.addPointToBox( &cornersOther[iC*_dim] ); - - if ( isMinMaxOut( &mmBox._minmax[0], &this->_minmax[0], _dim )) - return true; - } - - // compare minmaxes in global CS - { - vector cornersThis; - getCorners( cornersThis, &_minmax[0] ); - DirectedBoundingBox mmBox((double*)0,0,_dim); //!< initailized _minmax - double globCorner[3]; - for ( int iC = 0, nC = cornersThis.size()/_dim; iC < nC; ++iC) - { - fromLocalCS( &cornersThis[iC*_dim], globCorner ); - for ( int i = 0; i < (int)_dim; ++i ) - { - if ( globCorner[i] < mmBox._minmax[i*2] ) mmBox._minmax[i*2] = globCorner[i]; - if ( globCorner[i] > mmBox._minmax[i*2+1] ) mmBox._minmax[i*2+1] = globCorner[i]; - } - } - if ( isMinMaxOut( &mmBox._minmax[0], box, _dim )) - return true; - } - return false; - } - - //================================================================================ - /*! - * \brief Return true if given point is out of this box - */ - //================================================================================ - - bool DirectedBoundingBox::isOut(const double* point) const - { - if ( _dim < 1 ) return false; // empty box includes all - - double pLoc[3]; - toLocalCS( point, pLoc ); - bool out = isLocalOut( pLoc ); -#ifdef _DEBUG_ - switch (_dim) - { - case 3: - __DMP(__MYID<<": "< DirectedBoundingBox::getData() const - { - vector data(1, _dim); - if ( _dim > 0 ) - { - data.insert( data.end(), &_axes[0], &_axes[0] + _axes.size()); - data.insert( data.end(), &_minmax[0], &_minmax[0] + _minmax.size()); - } - if ( data.size() < (unsigned)dataSize( _dim )) - data.resize( dataSize( _dim ), 0 ); - return data; - } - - //================================================================================ - /*! - * \brief Initializes self with data retrieved via getData() - */ - //================================================================================ - - void DirectedBoundingBox::setData(const double* data) - { - _dim = unsigned( *data++ ); - if ( _dim > 0 ) - { - _axes.assign( data, data+_dim*_dim ); data += _dim*_dim; - _minmax.assign( data, data+2*_dim ); - } - else - { - _axes.clear(); - _minmax.clear(); - } - } - - //================================================================================ - /*! - * \brief Return size of internal data returned by getData() depending on space dim - */ - //================================================================================ - - int DirectedBoundingBox::dataSize(int dim) - { - return 1 + dim*dim + 2*dim; // : _dim + _axes + _minmax - } -} diff --git a/medtool/src/INTERP_KERNEL/DirectedBoundingBox.hxx b/medtool/src/INTERP_KERNEL/DirectedBoundingBox.hxx deleted file mode 100644 index 50501cd17..000000000 --- a/medtool/src/INTERP_KERNEL/DirectedBoundingBox.hxx +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __DIRECTEDBOUNDINGBOX_HXX__ -#define __DIRECTEDBOUNDINGBOX_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing the bounding box of a number of points - * with box axes parallel to principal axes of inertia of points - */ - class DirectedBoundingBox - { - public: - - INTERPKERNEL_EXPORT DirectedBoundingBox(); - - INTERPKERNEL_EXPORT DirectedBoundingBox(const double* pts, const unsigned numPts, const unsigned dim); - - INTERPKERNEL_EXPORT DirectedBoundingBox(const double** pts, const unsigned numPts, const unsigned dim); - - //~DirectedBoundingBox(); - - INTERPKERNEL_EXPORT void enlarge(const double tol); - - INTERPKERNEL_EXPORT bool isDisjointWith(const DirectedBoundingBox& box) const; - - INTERPKERNEL_EXPORT bool isDisjointWith(const double* box) const; - - INTERPKERNEL_EXPORT bool isOut(const double* point) const; - - - // return internal data - INTERPKERNEL_EXPORT std::vector getData() const; - - // initialize with data returned by getData() - INTERPKERNEL_EXPORT void setData(const double* data); - - // return size of internal data - INTERPKERNEL_EXPORT static int dataSize(int dim); - - private: - - //void computeAxes3D(const std::vector& tensor); - - //void computeAxes2D(const std::vector& tensor); - - inline void addPointToBox(const double* coord); - - void toLocalCS(const double* p, double* pLoc) const; - - void fromLocalCS(const double* p, double* pGlob) const; - - inline bool isLocalOut(const double* pLoc) const; - - void getCorners(std::vector& corners, const double* minmax) const; - - unsigned _dim; - - std::vector _axes; //!< principal axes of inertia in full interlace - std::vector _minmax; //!< pairs of min an max coordinates along the axes - - }; - - //================================================================================ - /*! - * \brief Test point in local CS against box extremities - * - */ - //================================================================================ - - inline bool DirectedBoundingBox::isLocalOut(const double* pLoc) const - { - for ( int i = 0; i < (int)_dim; ++i ) - if ( pLoc[i] < _minmax[i*2] || pLoc[i] > _minmax[i*2+1] ) - return true; - return false; - } - - //================================================================================ - /*! - * \brief Update box extremities - */ - //================================================================================ - - inline void DirectedBoundingBox::addPointToBox(const double* coord) - { - for ( int i = 0; i < (int)_dim; ++i ) - { - double c = 0; - for ( int j = 0; j < (int)_dim; ++j ) c += coord[j]*_axes[i*_dim+j]; - if ( c < _minmax[i*2] ) _minmax[i*2] = c; - if ( c > _minmax[i*2+1] ) _minmax[i*2+1] = c; - } - } -} -#endif diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx deleted file mode 100644 index 081cab633..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx +++ /dev/null @@ -1,499 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelAsmX86.hxx" - -#include -#include -#include - -#ifdef _POSIX_MAPPED_FILES -#include -#else -#ifdef WIN32 -#include -#endif -#endif - -const char *INTERP_KERNEL::AsmX86::OPS[NB_OF_OPS]={"mov","push","pop","fld","faddp","fsubp","fmulp","fdivp","fcos","fsin","fabs","fchs","fsqrt","sub","add","ret","leave","movsd","fst"}; - -std::vector INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector& asmb) const -{ - std::vector ret; - for(std::vector::const_iterator iter=asmb.begin();iter!=asmb.end();iter++) - convertOneInstructionInML(*iter,ret); - return ret; -} - -char *INTERP_KERNEL::AsmX86::copyToExecMemZone(const std::vector& ml, unsigned& offset) const -{ - char *ret=0; - int lgth=ml.size(); -#ifdef _POSIX_MAPPED_FILES -# ifdef __APPLE__ - ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANON | MAP_PRIVATE,-1,0); -# else - ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); -# endif -#else -#ifdef WIN32 - HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL); - ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth); -#endif -#endif - if(ret) - std::copy(ml.begin(),ml.end(),ret); - return ret; -} - -void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector& ml) const -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string op; - std::string param; - if(pos!=std::string::npos) - { - op=inst.substr(0,pos); - param=inst.substr(pos+1); - } - else - op=inst; - int id=0; - for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++) - { - std::string tmp(*it); - if(op==tmp) - break; - } - switch(id) - { - case 0: - convertMov(param,ml); - break; - case 1: - convertPush(param,ml); - break; - case 2: - convertPop(param,ml); - break; - case 3: - convertFld(param,ml); - break; - case 4: - convertFaddp(param,ml); - break; - case 5: - convertFsubp(param,ml); - break; - case 6: - convertFmulp(param,ml); - break; - case 7: - convertFdivp(param,ml); - break; - case 8: - convertFcos(param,ml); - break; - case 9: - convertFsin(param,ml); - break; - case 10: - convertFabs(param,ml); - break; - case 11: - convertFchs(param,ml); - break; - case 12: - convertFsqrt(param,ml); - break; - case 13: - convertSub(param,ml); - break; - case 14: - convertAdd(param,ml); - break; - case 15: - convertRet(param,ml); - break; - case 16: - convertLeave(param,ml); - break; - case 17: - convertMovsd(param,ml); - break; - case 18: - convertFst(param,ml); - break; - default: - { - std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -#include - -void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector& ml) -{ - const char ASM1[]="ebp,esp"; - const unsigned char ML1[2]={0x89,0xe5}; - if(inst==ASM1) - { - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="rbp,rsp"; - const unsigned char ML2[3]={0x48,0x89,0xe5}; - if(inst==ASM2) - { - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - std::string::size_type pos=inst.find_first_of(' '); - if(pos==std::string::npos) - { - std::ostringstream oss; oss << "not recognized instruction mov : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string inst2=inst.substr(pos+1); - pos=inst2.find_first_of(','); - if(pos==std::string::npos) - { - std::ostringstream oss; oss << "not recognized instruction mov : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string inst3=inst2.substr(0,pos); - std::string inst4=inst2.substr(pos+1); - convertMovToEsp(inst3,inst4,ml); -} - -void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml) -{ - if(inst1[0]!='[' || inst1[inst1.length()-1]!=']') - throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !"); - std::string inst1bis=inst1.substr(1,inst1.length()-2); - const char ASM1[]="esp"; - const unsigned char ML1[3]={0xc7,0x04,0x24}; - if(inst1bis==ASM1) - {//mov dword [esp],0x3ff3c0ca - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - appendAddress(inst2,4,ml); - return ; - } - if(inst1bis.substr(0,3)==ASM1) - { - if(inst1bis[3]=='+') - {//mov dword [esp+4],0x3ff3c0ca - const unsigned char ML2[3]={0xc7,0x44,0x24}; - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - std::string::size_type pos=inst1bis.find_first_of(']'); - std::string inst1_1=inst1bis.substr(4,pos-4-1); - appendAddress(inst1_1,1,ml); - appendAddress(inst2,4,ml); - return; - } - else - throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); - } - const char ASM3[]="rsp"; - const unsigned char ML3[3]={0xc7,0x04,0x24}; - if(inst1bis==ASM3) - {//mov dword [rsp],0x3ff3c0ca - ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); - appendAddress(inst2,4,ml); - return ; - } - if(inst1bis.substr(0,3)==ASM3) - { - if(inst1bis[3]=='+') - {//mov dword [rsp+4],0x3ff3c0ca - const unsigned char ML2[3]={0xc7,0x44,0x24}; - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - std::string::size_type pos=inst1bis.find_first_of(']'); - std::string inst1_1=inst1bis.substr(4,pos-4-1); - appendAddress(inst1_1,1,ml); - appendAddress(inst2,4,ml); - return; - } - else - throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); - } - throw INTERP_KERNEL::Exception("Not recognized exp : mov"); -} - -void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector& ml) -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string inst2=inst.substr(pos+1); - const char ASM1[]="ebp"; - const unsigned char ML1[1]={0x55}; - if(inst2==ASM1) - {//push ebp - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="ebx"; - const unsigned char ML2[1]={0x53}; - if(inst2==ASM2) - {//push ebx - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - const char ASM3[]="rbp"; - const unsigned char ML3[1]={0x55}; - if(inst2==ASM3) - {//push rbp - ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized push instruction"); -} - -void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector& ml) -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string inst2=inst.substr(pos+1); - const char ASM1[]="ebp"; - const unsigned char ML1[1]={0x5d}; - if(inst2==ASM1) - {//push ebp - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="ebx"; - const unsigned char ML2[1]={0x5b}; - if(inst2==ASM2) - {//push ebx - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized pop instruction"); -} - -void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector& ml) -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string params=inst.substr(pos+1); - std::string params2=params.substr(1,params.length()-2); - if(params2.substr(0,3)=="esp") - { - const unsigned char ML1[3]={0xdd,0x04,0x24}; - if(params2.length()==3) - {//fld qword [esp] - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - pos=params2.find_first_of('+'); - if(pos!=std::string::npos) - {//fld qword [esp+@] - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - std::string params3=params2.substr(pos+1); - appendAddress(params3,1,ml); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized fld esp..."); - } - if(params2.substr(0,3)=="ebp") - { - const unsigned char ML2[2]={0xdd,0x45}; - if(params2.length()==3) - {//fld qword [ebp] - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - ml.push_back(0); - return ; - } - pos=params2.find_first_of('+'); - if(pos!=std::string::npos) - {//fld qword [esp+@] - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - std::string params3=params2.substr(pos+1); - appendAddress(params3,1,ml); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized fld ebp..."); - } - if(params2.substr(0,3)=="rsp") - { - const unsigned char ML2[3]={0xdd,0x04,0x24}; - ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed ! - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized fld instruction"); -} - -void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xc1}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xe9}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xc9}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xf9}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xff}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xfe}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xe1}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xe0}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xfa}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector& ml) -{ - if(inst.substr(0,4)=="esp,") - { - const unsigned char ML[2]={0x81,0xec}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); - std::string inst2=inst.substr(4); - appendAddress(inst2,4,ml); - return; - } - if(inst.substr(0,4)=="rsp,") - { - const unsigned char ML[4]={0x48,0x83,0xec,0x08}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! - return; - } - throw INTERP_KERNEL::Exception("Not recognized sub instruction."); -} - -void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector& ml) -{ - if(inst.substr(0,4)=="esp,") - { - const unsigned char ML[2]={0x81,0xc4}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); - std::string inst2=inst.substr(4); - appendAddress(inst2,4,ml); - return; - } - if(inst.substr(0,4)=="rsp,") - { - const unsigned char ML[4]={0x48,0x83,0xc4,0x08}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! - return; - } - throw INTERP_KERNEL::Exception("Not recognized add instruction."); -} - -void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[1]={0xc3}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[1]={0xc9}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector& ml) -{ - const char ASM1[]="[rsp],xmm0"; - const unsigned char ML1[5]={0xf2,0x0f,0x11,0x04,0x24}; - if(inst==ASM1) - { - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="xmm0,[rsp]"; - const unsigned char ML2[5]={0xf2,0x0f,0x10,0x04,0x24}; - if(inst==ASM2) - { - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - std::ostringstream oss; oss << "not recognized instruction movsd : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector& ml) -{ - const char ASM1[]="qword [rsp]"; - const unsigned char ML1[3]={0xdd,0x14,0x24}; - if(inst==ASM1) - { - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - std::ostringstream oss; oss << "not recognized instruction fst : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - //tony -} - - -void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector& ml) -{ - int i,j; - char v; - std::istringstream iss(addr); - if(addr.length()>2) - { - if(addr[0]=='0' && addr[1]=='x') - iss >> std::hex; - } - iss >> i; - for(int k=0;k>=8; - } -} diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx deleted file mode 100644 index 7620686a2..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELASMX86_HXX__ -#define __INTERPKERNELASMX86_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class AsmX86 - { - public: - std::vector convertIntoMachineLangage(const std::vector& asmb) const; - char *copyToExecMemZone(const std::vector& ml, unsigned& offset) const; - private: - void convertOneInstructionInML(const std::string& inst, std::vector& ml) const; - private: - static void convertMov(const std::string& inst, std::vector& ml); - static void convertPush(const std::string& inst, std::vector& ml); - static void convertPop(const std::string& inst, std::vector& ml); - static void convertFld(const std::string& inst, std::vector& ml); - static void convertFaddp(const std::string& inst, std::vector& ml); - static void convertFsubp(const std::string& inst, std::vector& ml); - static void convertFmulp(const std::string& inst, std::vector& ml); - static void convertFdivp(const std::string& inst, std::vector& ml); - static void convertFcos(const std::string& inst, std::vector& ml); - static void convertFsin(const std::string& inst, std::vector& ml); - static void convertFabs(const std::string& inst, std::vector& ml); - static void convertFchs(const std::string& inst, std::vector& ml); - static void convertFsqrt(const std::string& inst, std::vector& ml); - static void convertSub(const std::string& inst, std::vector& ml); - static void convertAdd(const std::string& inst, std::vector& ml); - static void convertRet(const std::string& inst, std::vector& ml); - static void convertLeave(const std::string& inst, std::vector& ml); - static void convertMovsd(const std::string& inst, std::vector& ml); - static void convertFst(const std::string& inst, std::vector& ml); - // - static void convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml); - static void appendAddress(const std::string& addr, int nbOfByte, std::vector& ml); - private: - static const int NB_OF_OPS=19; - static const char *OPS[NB_OF_OPS]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx deleted file mode 100644 index 1c213b796..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx +++ /dev/null @@ -1,1201 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelExprParser.hxx" -#include "InterpKernelValue.hxx" -#include "InterpKernelAsmX86.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec"; - -const char ExprParser::WHITE_SPACES[]=" \n"; - -const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : "; - -LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) -{ - std::istringstream stream; - stream.str(expr); - double val; - stream >> val; - if(!stream.fail()) - if(stream.eof()) - return new LeafExprVal(val); - else - { - std::ostringstream errMsg; - char MSGTYP6[]="Error following expression is not consedered as a double value : "; - errMsg << MSGTYP6 << expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - else - return new LeafExprVar(expr); -} - -LeafExpr::~LeafExpr() -{ -} - -LeafExprVal::LeafExprVal(double value):_value(value) -{ -} - -LeafExprVal::~LeafExprVal() -{ -} - -void LeafExprVal::fillValue(Value *val) const -{ - val->setDouble(_value); -} - -void LeafExprVal::replaceValues(const std::vector& valuesInExpr) -{ - int pos=(int)_value; - int lgth=(int)valuesInExpr.size(); - if(pos>=lgth || pos<0) - throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected !"); - _value=valuesInExpr[pos]; -} - -LeafExprVal *LeafExprVal::deepCpy() const -{ - return new LeafExprVal(*this); -} - -LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var),_val(0) -{ -} - -void LeafExprVar::fillValue(Value *val) const -{ - if(_val) - val->setDouble(_val[_fast_pos]); - else - val->setVarname(_fast_pos,_var_name); - -} - -void LeafExprVar::prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const -{ - std::vector::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name); - if(iter==vars.end()) - { - if(!isRecognizedKeyVar(_var_name,_fast_pos)) - { - std::ostringstream oss; oss << "Var : " << _var_name << " not in : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss,", ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { - int relPos=-7-_fast_pos; - if(relPos>=targetNbOfCompo) - { - std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos; - oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - return; - } - } - _fast_pos=(int)std::distance(vars.begin(),iter); - if(_fast_pos>=nbOfCompo) - { - std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * \param [in] vars - the sorted list of vars - * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs) - * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs) - * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters. - * \sa evaluateDouble - */ -void LeafExprVar::prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const -{ - if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd)) - throw INTERP_KERNEL::Exception("LeafExprVar::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !"); - prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); - _ref_pos=refPos; - _val=ptOfInputStart; -} - -void LeafExprVar::prepareExprEvaluationVec() const -{ - if(!isRecognizedKeyVar(_var_name,_fast_pos)) - _fast_pos=-2; -} - -bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos) -{ - if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR)) - return false; - std::string end=var.substr(1); - if(end!=END_OF_RECOGNIZED_VAR) - return false; - char first=var[0]; - if(first<'I' || first>'Z') - return false; - pos=-7-(first-'I'); - return true; -} - -LeafExprVar *LeafExprVar::deepCpy() const -{ - return new LeafExprVar(*this); -} - -/*! - * Nothing to do it is not a bug. - */ -void LeafExprVar::replaceValues(const std::vector& valuesInExpr) -{ -} - -LeafExprVar::~LeafExprVar() -{ -} - -void ExprParserOfEval::clearSortedMemory() -{ - delete _leaf; - for(std::vector::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++) - (*it).clearSortedMemory(); - for(std::vector::iterator it=_funcs.begin();it!=_funcs.end();it++) - delete *it; -} - -void ExprParserOfEval::sortMemory() -{ - for(std::vector::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++) - (*it).sortMemory(); - if(_leaf) - _leaf=_leaf->deepCpy(); - for(std::vector::iterator it=_funcs.begin();it!=_funcs.end();it++) - if(*it) - *it=(*it)->deepCpy(); -} - -ExprParser::ExprParser(const std::string& expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) -{ - _expr=deleteWhiteSpaces(_expr); -} - -//! For \b NOT null terminated strings coming from FORTRAN. -ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false) -{ - _expr=buildStringFromFortran(expr,lgth); - _expr=deleteWhiteSpaces(_expr); -} - -ExprParser::~ExprParser() -{ - delete _leaf; - _for_eval.clearSortedMemory(); - releaseFunctions(); -} - -std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket) -{ - int level=0; - for(std::size_t iter=0;iter valuesInExpr; - fillValuesInExpr(valuesInExpr); - checkBracketsParity(); - if(!simplify()) - parseDeeper(); - replaceValues(valuesInExpr); - _expr=tmp; - } - reverseThis(); - _is_parsing_ok=true; -} - -double ExprParser::evaluate() const -{ - AutoCppPtr gen(new ValueDouble); - AutoCppPtr res(static_cast(evaluateLowLev(gen))); - return res->getData(); -} - -DecompositionInUnitBase ExprParser::evaluateUnit() const -{ - Value *gen=new ValueUnit; - ValueUnit *res=0; - try - { - res=(ValueUnit *)evaluateLowLev(gen); - } - catch(INTERP_KERNEL::Exception& e) - { - delete gen; - throw e; - } - delete gen; - DecompositionInUnitBase ret=res->getData(); - delete res; - return ret; -} - -void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const -{ - AutoCppPtr gen(new ValueDoubleExpr(szOfOutParam,inParam)); - AutoCppPtr res(static_cast(evaluateLowLev(gen))); - std::copy(res->getData(),res->getData()+szOfOutParam,outParam); -} - -void ExprParser::prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const -{ - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); -} - -/*! - * \param [in] vars - the sorted list of vars - * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs) - * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs) - * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters. - * \sa evaluateDouble - */ -void ExprParser::prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const -{ - if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd)) - throw INTERP_KERNEL::Exception("ExprParser::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !"); - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - leafC->prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd); -} - -void ExprParser::prepareFastEvaluator() const -{ - _for_eval.clearSortedMemory(); - _for_eval=convertMeTo(); - _for_eval.sortMemory(); -} - -/*! - * \sa prepareExprEvaluationDouble - */ -double ExprParser::evaluateDouble() const -{ - checkForEvaluation(); - std::vector stackOfVal; - evaluateDoubleInternal(stackOfVal); - return stackOfVal.back(); -} - -void ExprParser::checkForEvaluation() const -{ - if(!_is_parsing_ok) - throw INTERP_KERNEL::Exception("checkForEvaluation : Parsing fails ! Invalid expression !"); - if(_sub_expr.empty() && !_leaf) - throw INTERP_KERNEL::Exception("checkForEvaluation : Empty expression !"); -} - -void ExprParser::prepareExprEvaluationVec() const -{ - std::set trueVars; - getTrueSetOfVars(trueVars); - if(trueVars.size()>1) - { - std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : "; - oss << "having " << trueVars.size() << " : "; - std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator(oss," ")); oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - prepareExprEvaluationVecLowLev(); -} - -void ExprParser::prepareExprEvaluationVecLowLev() const -{ - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - leafC->prepareExprEvaluationVec(); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluationVecLowLev(); -} - -Value *ExprParser::evaluateLowLev(Value *valGen) const -{ - checkForEvaluation(); - std::vector stackOfVal; - try - { - if(_leaf) - { - Value *ret=valGen->newInstance(); - try - { - _leaf->fillValue(ret); - } - catch(INTERP_KERNEL::Exception& e) - { - delete ret; - throw e; - } - stackOfVal.resize(1); - stackOfVal[0]=ret; - } - else - { - stackOfVal.resize(_sub_expr.size()); - std::vector::iterator iter2=stackOfVal.begin(); - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++) - *iter2=(*iter).evaluateLowLev(valGen); - } - for(std::vector::const_iterator iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++) - (*iter3)->operate(stackOfVal); - } - catch(INTERP_KERNEL::Exception& e) - { - for(std::vector::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++) - delete *iter4; - throw e; - } - return stackOfVal.back(); -} - -void ExprParser::reverseThis() -{ - if(_leaf) - return ; - for(std::vector::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).reverseThis(); - AutoPtr buf(new char[sizeof(ExprParser)]); - char *loc(reinterpret_cast(&_sub_expr[0])),*bufPtr(buf); - std::size_t sz(_sub_expr.size()); - std::size_t nbOfTurn(sz/2); - for(std::size_t i=0;i subExpr(sz); - for(std::size_t i=0;i& vars) const -{ - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - vars.insert(leafC->getVar()); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).getSetOfVars(vars); -} - -void ExprParser::getTrueSetOfVars(std::set& trueVars) const -{ - std::set vars; - getSetOfVars(vars); - trueVars.clear(); - for(std::set::const_iterator iter=vars.begin();iter!=vars.end();iter++) - { - int tmp; - if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp)) - trueVars.insert(*iter); - } -} - -void ExprParser::parseDeeper() -{ - for(std::vector::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - if(!(*iter).simplify()) - (*iter).parseDeeper(); -} - -/*! - * This method has the responsability to see if this->_expr can be seen as a unary function of something. - * Something defined as the contain of highest level barckets. - * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc.. - */ -void ExprParser::parseUnaryFunc() -{ - if(_expr[_expr.length()-1]!=')') - return ; - //at this level of code _expr - std::size_t pos1=_expr.find_first_of('('); - std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1); - if(pos4!=pos1) - return ; - std::string funcName=_expr.substr(0,pos1); - std::size_t pos2=funcName.find_first_of("+-*/^><",0,7); - std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7); - if(pos2!=std::string::npos && pos3!=std::string::npos) - return ;//Bracket group is not alone, can't conclude not recursively. - std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2); - std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1; - if(pos3!=std::string::npos) - _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc)); - else - { - std::size_t lgth=funcName.length(); - char tmp[2]; tmp[1]='\0'; - for(std::size_t i=0;i_expr is interpretable without any recursion. - * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level. - * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error. - */ -bool ExprParser::tryToInterpALeaf() -{ - std::size_t pos=_expr.find_first_not_of("+-",0,2); - std::string minimizedExpr=_expr.substr(pos); - std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9); - if(pos2!=std::string::npos) - return false; - delete _leaf; - _leaf=LeafExpr::buildInstanceFrom(minimizedExpr); - int nbOfNegs=0; - for(std::size_t i=0;i': - case '<': - { - isParsingSucceed=true; - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - { - std::ostringstream errMsg; - char MSGTYP1[]="Error non unary function for '"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; - std::string tmp=_expr.substr(iter-_expr.begin()); - LocateError(errMsg,tmp,0); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - break; - } - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP4[]="Error following expression finished by > / < without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::parseForAddMin() -{ - std::string::const_iterator iter; - int curLevel=0; - std::string curPart; - bool isParsingSucceed=false; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - switch(*iter) - { - case '+': - case '-': - if(curLevel!=0) - curPart+=*iter; - else - { - if(!curPart.empty()) - { - std::string::reverse_iterator accessor=curPart.rbegin(); - if(*accessor!='*' && *accessor!='/' && *accessor!='^') - { - isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - curPart+=*iter; - } - else - curPart+=*iter; - } - break; - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP4[]="Error following expression finished by +/- without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::parseForMulDiv() -{ - std::string::const_iterator iter; - int curLevel=0; - std::string curPart; - bool isParsingSucceed=false; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - switch(*iter) - { - case '/': - case '*': - if(curLevel!=0) - curPart+=*iter; - else - { - isParsingSucceed=true; - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - { - std::ostringstream errMsg; - char MSGTYP1[]="Error non unary function for '"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; - std::string tmp=_expr.substr(iter-_expr.begin()); - LocateError(errMsg,tmp,0); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } - break; - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP5[]="Error following expression finished by *// without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::parseForPow() -{ - std::string::const_iterator iter; - int curLevel=0; - std::string curPart; - bool isParsingSucceed=false; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - switch(*iter) - { - case '^': - if(curLevel!=0) - curPart+=*iter; - else - if(!curPart.empty()) - { - isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - { - std::ostringstream errMsg; - char MSGTYP1[]="Error non unary function for '"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; - std::string tmp=_expr.substr(iter-_expr.begin()); - LocateError(errMsg,tmp,0);curPart+=*iter; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - break; - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP6[]="Error following expression finished by ^ without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::releaseFunctions() -{ - for(std::vector::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++) - delete *iter; - _func_btw_sub_expr.clear(); -} - -/*! - * This method parse this->_expr at the current level. - * This method first try to see if this->_expr is a leaf, if not it try a unary function of something (see INTERP_KERNEL::ExprParser::parseUnaryFunc method) - * If true is returned, no deeper parsing needed, if false is returned for a full parsing of this->_expr INTERP_KERNEL::ExprParser::parseDeeper call needed. - */ -bool ExprParser::simplify() -{ - if(tryToInterpALeaf()) - return true; - parseUnaryFunc(); - if(!_is_parsing_ok) - { - parseForCmp(); - if(!_is_parsing_ok) - { - parseForAddMin(); - if(!_is_parsing_ok) - { - parseForMulDiv(); - if(!_is_parsing_ok) - parseForPow(); - } - } - } - if(!_is_parsing_ok) - { - std::ostringstream errMsg; - char MSGTYP3[]="Error in interpreting : "; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr; - LocateError(errMsg,_expr,0); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - return false; -} - -void ExprParser::checkBracketsParity() const -{ - std::string::const_iterator iter; - int curLevel=0; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - if(*iter=='(') - curLevel++; - else if(*iter==')') - { - if(curLevel==0) - { - std::ostringstream errMsg; - char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1; - LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter)); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - curLevel--; - } - } - if(curLevel!=0) - { - std::ostringstream errMsg; - char MSGTYP2[]="Error in brackets : not finally closed expr."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } -} - -/*! - * This method substitutes part in [bg,end) in expr by the content of (str(id)) and returns the double value representation in expr[bg,end). - * If double representation is invalid an exception is thrown. - * This method returns a delta that is the delta to operate to pos in expr after substitution. - */ -double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) -{ - static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !"; - std::istringstream stream; - std::ostringstream oss; - std::size_t end2=end!=std::string::npos?end-bg:end; - std::string tmp=expr.substr(bg,end2); - stream.str(tmp); - double ret=std::numeric_limits::max(); - stream >> ret; - if(stream.fail()) - throw INTERP_KERNEL::Exception(MSG); - if(!stream.eof()) - throw INTERP_KERNEL::Exception(MSG); - oss << id; - std::string tmp2(oss.str()); - std::size_t l1=tmp.length(); - delta=(int)tmp2.length()-(int)l1; - expr.replace(bg,l1,tmp2); - return ret; -} - -/*! - * This method makes the assumption that _expr has no white space. - * This method scans _expr finding in greedy mode the following pattern : - * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}? - */ -void ExprParser::fillValuesInExpr(std::vector& valuesInExpr) -{ - const char FIGURES[]="0123456789"; - const std::string other("+-*^/(<>,"); - std::size_t lgth=_expr.length(); - int id=0,delta; - for(std::size_t pos=0;pos!=std::string::npos;id++) - { - std::size_t pos2=_expr.find_first_of(FIGURES,pos,10); - if(pos2==std::string::npos) - break; - if(pos2>0) - {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this - if(other.find_first_of(_expr[pos2-1])==std::string::npos) - { - pos=_expr.find_first_not_of(FIGURES,pos2,10); - id--; - continue; - } - if(_expr[pos2-1]==')') - { - pos=_expr.find_first_not_of(FIGURES,pos2,10); - std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos); - oss << "\" is right after close parenthesis... ')'"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10); - if(pos3==std::string::npos) - {//"x+1223442320" - valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); - break; - } - if(_expr[pos3]=='.') - pos3++; - if(pos3=lgth) - {//"x+1223334.223e+" or "1223334.223E-" - std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\""; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10); - if(pos4==pos5) - {//"x+1223334.223e+x" or "1223334.223E-y" - std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\""; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - //OK, normal case - valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta)); - pos=pos5+delta; - continue; - } - else//"x+1223334.223e" - { - std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } - else - {//"x+1223334." - valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); - break; - } - } -} - -void ExprParser::replaceValues(const std::vector& valuesInExpr) -{ - if(_leaf) - _leaf->replaceValues(valuesInExpr); - else - { - for(std::vector::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).replaceValues(valuesInExpr); - } -} - -void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr) -{ - stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl; -} - -char *ExprParser::compileX86() const -{ - std::vector ass; - //need in stack - ass.push_back("push ebp"); - ass.push_back("mov ebp,esp"); - compileX86LowLev(ass); - ass.push_back("pop ebp"); - ass.push_back("ret"); - std::cout << std::endl; - for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) - std::cout << " " << *iter << std::endl; - AsmX86 asmb; - std::vector output=asmb.convertIntoMachineLangage(ass); - for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) - std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; - std::cout << std::endl; - unsigned offset; - return asmb.copyToExecMemZone(output,offset); -} - -char *ExprParser::compileX86_64() const -{ - std::vector ass; - //need in stack - ass.push_back("push rbp"); - ass.push_back("mov rbp,rsp"); - compileX86_64LowLev(ass); - ass.push_back("sub rsp,8"); - ass.push_back("fst qword [rsp]"); - ass.push_back("movsd xmm0,[rsp]"); - ass.push_back("add rsp,8"); - ass.push_back("leave"); - ass.push_back("ret"); - std::cout << std::endl; - for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) - std::cout << " " << *iter << std::endl; - AsmX86 asmb; - std::vector output=asmb.convertIntoMachineLangage(ass); - for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) - std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; - std::cout << std::endl; - unsigned offset; - return asmb.copyToExecMemZone(output,offset); -} - -void ExprParser::compileX86LowLev(std::vector& ass) const -{ - if(_leaf) - _leaf->compileX86(ass); - else - { - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).compileX86LowLev(ass); - } - for(std::vector::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) - (*iter2)->operateX86(ass); -} - -void ExprParser::compileX86_64LowLev(std::vector& ass) const -{ - if(_leaf) - _leaf->compileX86_64(ass); - else - { - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).compileX86_64LowLev(ass); - } - for(std::vector::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) - (*iter2)->operateX86(ass); -} - -double LeafExprVal::getDoubleValue() const -{ - return _value; -} - -void LeafExprVal::compileX86(std::vector& ass) const -{ - ass.push_back("sub esp,8"); - const int *b=reinterpret_cast(&_value),*c=reinterpret_cast(&_value); - c++; - std::ostringstream oss; - oss << std::hex; - oss << "mov dword [esp+4],0x" << *c; - ass.push_back(oss.str()); - oss.str(""); - oss << "mov dword [esp],0x" << *b; - ass.push_back(oss.str()); - ass.push_back("fld qword [esp]"); - ass.push_back("add esp,8"); -} - -void LeafExprVal::compileX86_64(std::vector& ass) const -{ - ass.push_back("sub rsp,8"); - const int *b=reinterpret_cast(&_value),*c=reinterpret_cast(&_value); - c++; - std::ostringstream oss; - oss << std::hex; - oss << "mov dword [rsp+4],0x" << *c; - ass.push_back(oss.str()); - oss.str(""); - oss << "mov dword [rsp],0x" << *b; - ass.push_back(oss.str()); - ass.push_back("fld qword [rsp]"); - ass.push_back("add rsp,8"); -} - -double LeafExprVar::getDoubleValue() const -{ - if(_fast_pos>=0) - return _val[_fast_pos]; - else - { - int pos(-7-_fast_pos); - return pos==_ref_pos?1.:0.; - } -} - -void LeafExprVar::compileX86(std::vector& ass) const -{ - ass.push_back("fld qword [ebp+8]"); -} - -void LeafExprVar::compileX86_64(std::vector& ass) const -{ - ass.push_back("sub rsp,8"); - ass.push_back("movsd [rsp],xmm0"); - ass.push_back("fld qword [rsp]"); - ass.push_back("add rsp,8"); -} - -int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const -{ - if(asker) - { - int sz=_father->getStackSizeToPlayX86(this); - int i=0; - for(std::vector::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++) - { - const ExprParser& obj=(*iter); - const ExprParser *pt=&obj; - if(pt==asker) - return sz-i; - } - throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !"); - } - else - { - if(!_father) - return MAX_X86_FP_ST; - return _father->getStackSizeToPlayX86(this); - } -} diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx deleted file mode 100644 index 0b1642a14..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELEXPRPARSER_HXX__ -#define __INTERPKERNELEXPRPARSER_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelUnit.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelFunction.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - class ValueDouble; - - class LeafExpr - { - public: - INTERPKERNEL_EXPORT virtual ~LeafExpr(); - INTERPKERNEL_EXPORT virtual double getDoubleValue() const = 0; - INTERPKERNEL_EXPORT virtual void fillValue(Value *val) const = 0; - INTERPKERNEL_EXPORT virtual void compileX86(std::vector& ass) const = 0; - INTERPKERNEL_EXPORT virtual void compileX86_64(std::vector& ass) const = 0; - INTERPKERNEL_EXPORT virtual void replaceValues(const std::vector& valuesInExpr) = 0; - INTERPKERNEL_EXPORT virtual LeafExpr *deepCpy() const = 0; - INTERPKERNEL_EXPORT static LeafExpr *buildInstanceFrom(const std::string& expr); - }; - - class LeafExprVal : public LeafExpr - { - public: - INTERPKERNEL_EXPORT LeafExprVal(double value); - INTERPKERNEL_EXPORT ~LeafExprVal(); - INTERPKERNEL_EXPORT double getDoubleValue() const; - INTERPKERNEL_EXPORT void compileX86(std::vector& ass) const; - INTERPKERNEL_EXPORT void compileX86_64(std::vector& ass) const; - INTERPKERNEL_EXPORT void fillValue(Value *val) const; - INTERPKERNEL_EXPORT void replaceValues(const std::vector& valuesInExpr); - INTERPKERNEL_EXPORT LeafExprVal *deepCpy() const; - private: - double _value; - }; - - class LeafExprVar : public LeafExpr - { - public: - INTERPKERNEL_EXPORT LeafExprVar(const LeafExprVar& other):_fast_pos(other._fast_pos),_ref_pos(other._ref_pos),_var_name(other._var_name),_val(other._val) { } - INTERPKERNEL_EXPORT LeafExprVar(const std::string& var); - INTERPKERNEL_EXPORT ~LeafExprVar(); - INTERPKERNEL_EXPORT double getDoubleValue() const; - INTERPKERNEL_EXPORT void compileX86(std::vector& ass) const; - INTERPKERNEL_EXPORT void compileX86_64(std::vector& ass) const; - INTERPKERNEL_EXPORT void fillValue(Value *val) const; - INTERPKERNEL_EXPORT std::string getVar() const { return _var_name; } - INTERPKERNEL_EXPORT void prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const; - INTERPKERNEL_EXPORT void prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const; - INTERPKERNEL_EXPORT void prepareExprEvaluationVec() const; - INTERPKERNEL_EXPORT void replaceValues(const std::vector& valuesInExpr); - INTERPKERNEL_EXPORT static bool isRecognizedKeyVar(const std::string& var, int& pos); - INTERPKERNEL_EXPORT LeafExprVar *deepCpy() const; - public: - static const char END_OF_RECOGNIZED_VAR[]; - private: - mutable int _fast_pos; - mutable int _ref_pos; - std::string _var_name; - mutable const double *_val; - }; - - class ExprParserOfEval - { - public: - ExprParserOfEval():_leaf(0) { } - ExprParserOfEval(LeafExpr *leaf, const std::vector& subParts, const std::vector& funcs):_leaf(leaf),_sub_parts(subParts),_funcs(funcs) { } - void evaluateDoubleInternal(std::vector& stck) const - { - if(_leaf) - stck.push_back(_leaf->getDoubleValue()); - else - for(std::vector::const_iterator iter=_sub_parts.begin();iter!=_sub_parts.end();iter++) - (*iter).evaluateDoubleInternal(stck); - for(std::vector::const_iterator iter3=_funcs.begin();iter3!=_funcs.end();iter3++) - (*iter3)->operateStackOfDouble(stck); - } - void evaluateDoubleInternalSafe(std::vector& stck) const - { - if(_leaf) - stck.push_back(_leaf->getDoubleValue()); - else - for(std::vector::const_iterator iter=_sub_parts.begin();iter!=_sub_parts.end();iter++) - (*iter).evaluateDoubleInternalSafe(stck); - for(std::vector::const_iterator iter3=_funcs.begin();iter3!=_funcs.end();iter3++) - (*iter3)->operateStackOfDoubleSafe(stck); - } - void clearSortedMemory(); - void sortMemory(); - private: - LeafExpr *_leaf; - std::vector _sub_parts; - std::vector _funcs; - }; - - class ExprParser - { - public: - INTERPKERNEL_EXPORT ExprParser(const std::string& expr, ExprParser *father=0); - INTERPKERNEL_EXPORT ExprParser(const char *expr, int lgth, ExprParser *father=0); - INTERPKERNEL_EXPORT ~ExprParser(); - INTERPKERNEL_EXPORT void parse(); - INTERPKERNEL_EXPORT bool isParsingSuccessfull() const { return _is_parsing_ok; } - INTERPKERNEL_EXPORT double evaluate() const; - INTERPKERNEL_EXPORT DecompositionInUnitBase evaluateUnit() const; - INTERPKERNEL_EXPORT void prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const; - INTERPKERNEL_EXPORT void prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const; - INTERPKERNEL_EXPORT void prepareFastEvaluator() const; - INTERPKERNEL_EXPORT void prepareExprEvaluationVec() const; - INTERPKERNEL_EXPORT double evaluateDouble() const; - INTERPKERNEL_EXPORT void evaluateDoubleInternal(std::vector& stck) const { _for_eval.evaluateDoubleInternal(stck); } - INTERPKERNEL_EXPORT void evaluateDoubleInternalSafe(std::vector& stck) const { _for_eval.evaluateDoubleInternalSafe(stck); } - INTERPKERNEL_EXPORT void checkForEvaluation() const; - INTERPKERNEL_EXPORT void evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const; - INTERPKERNEL_EXPORT void getSetOfVars(std::set& vars) const; - INTERPKERNEL_EXPORT void getTrueSetOfVars(std::set& vars) const; - // - INTERPKERNEL_EXPORT char *compileX86() const; - INTERPKERNEL_EXPORT char *compileX86_64() const; - INTERPKERNEL_EXPORT void compileX86LowLev(std::vector& ass) const; - INTERPKERNEL_EXPORT void compileX86_64LowLev(std::vector& ass) const; - INTERPKERNEL_EXPORT int getStackSizeToPlayX86(const ExprParser *asker) const; - // - INTERPKERNEL_EXPORT static std::string buildStringFromFortran(const char *expr, int lgth); - INTERPKERNEL_EXPORT static std::string deleteWhiteSpaces(const std::string& expr); - private: - Value *evaluateLowLev(Value *valGen) const; - void reverseThis(); - ExprParserOfEval convertMeTo() const; - private: - void prepareExprEvaluationVecLowLev() const; - bool tryToInterpALeaf(); - void parseUnaryFunc(); - void parseForCmp(); - void parseForAddMin(); - void parseForMulDiv(); - void parseForPow(); - void parseDeeper(); - bool simplify(); - void releaseFunctions(); - void checkBracketsParity() const; - void fillValuesInExpr(std::vector& valuesInExpr); - void replaceValues(const std::vector& valuesInExpr); - static double ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta); - static std::size_t FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); - static void LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); - private: - ExprParser *_father; - bool _is_parsed; - LeafExpr *_leaf; - bool _is_parsing_ok; - std::string _expr; - mutable ExprParserOfEval _for_eval; - std::vector _sub_expr; - std::vector _func_btw_sub_expr; - private: - static const int MAX_X86_FP_ST=8; - static const char WHITE_SPACES[]; - static const char EXPR_PARSE_ERR_MSG[]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx deleted file mode 100644 index 5af091240..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx +++ /dev/null @@ -1,1292 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelFunction.hxx" -#include "InterpKernelValue.hxx" - -#include -#include - -using namespace INTERP_KERNEL; - -const char IdentityFunction::REPR[]="Id"; - -const char PositiveFunction::REPR[]="+"; - -const char NegateFunction::REPR[]="-"; - -const char CosFunction::REPR[]="cos"; - -const char SinFunction::REPR[]="sin"; - -const char TanFunction::REPR[]="tan"; - -const char ACosFunction::REPR[]="acos"; - -const char ASinFunction::REPR[]="asin"; - -const char ATanFunction::REPR[]="atan"; - -const char CoshFunction::REPR[]="cosh"; - -const char SinhFunction::REPR[]="sinh"; - -const char TanhFunction::REPR[]="tanh"; - -const char SqrtFunction::REPR[]="sqrt"; - -const char AbsFunction::REPR[]="abs"; - -const char PlusFunction::REPR[]="+"; - -const char MinusFunction::REPR[]="-"; - -const char MultFunction::REPR[]="*"; - -const char DivFunction::REPR[]="/"; - -const char PowFunction::REPR[]="^"; - -const char ExpFunction::REPR[]="exp"; - -const char LnFunction::REPR[]="ln"; - -const char LogFunction::REPR[]="log"; - -const char Log10Function::REPR[]="log10"; - -const char MaxFunction::REPR[]="max"; - -const char MinFunction::REPR[]="min"; - -const char GreaterThanFunction::REPR[]=">"; - -const char LowerThanFunction::REPR[]="<"; - -const char IfFunction::REPR[]="if"; - -Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams) -{ - switch(nbOfParams) - { - case 1: - return buildUnaryFuncFromString(type); - case 2: - return buildBinaryFuncFromString(type); - case 3: - return buildTernaryFuncFromString(type); - default: - throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !"); - } -} - -Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) -{ - std::string tmp(type); - if(tmp.empty()) - return new IdentityFunction; - if(tmp==CosFunction::REPR) - return new CosFunction; - if(tmp==SinFunction::REPR) - return new SinFunction; - if(tmp==TanFunction::REPR) - return new TanFunction; - if(tmp==ACosFunction::REPR) - return new ACosFunction; - if(tmp==ASinFunction::REPR) - return new ASinFunction; - if(tmp==ATanFunction::REPR) - return new ATanFunction; - if(tmp==CoshFunction::REPR) - return new CoshFunction; - if(tmp==SinhFunction::REPR) - return new SinhFunction; - if(tmp==TanhFunction::REPR) - return new TanhFunction; - if(tmp==SqrtFunction::REPR) - return new SqrtFunction; - if(tmp==AbsFunction::REPR) - return new AbsFunction; - if(tmp==PositiveFunction::REPR) - return new PositiveFunction; - if(tmp==NegateFunction::REPR) - return new NegateFunction; - if(tmp==ExpFunction::REPR) - return new ExpFunction; - if(tmp==LnFunction::REPR) - return new LnFunction; - if(tmp==LogFunction::REPR) - return new LogFunction; - if(tmp==Log10Function::REPR) - return new Log10Function; - // - std::string msg("Invalid unary function detected : \""); - msg+=type; msg+="\""; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -Function *FunctionsFactory::buildBinaryFuncFromString(const char *type) -{ - std::string tmp(type); - if(tmp==PositiveFunction::REPR) - return new PlusFunction; - if(tmp==NegateFunction::REPR) - return new MinusFunction; - if(tmp==MultFunction::REPR) - return new MultFunction; - if(tmp==DivFunction::REPR) - return new DivFunction; - if(tmp==PowFunction::REPR) - return new PowFunction; - if(tmp==MaxFunction::REPR) - return new MaxFunction; - if(tmp==MinFunction::REPR) - return new MinFunction; - if(tmp==GreaterThanFunction::REPR) - return new GreaterThanFunction; - if(tmp==LowerThanFunction::REPR) - return new LowerThanFunction; - std::string msg("Invalid binary function detected : \""); - msg+=type; msg+="\""; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -Function *FunctionsFactory::buildTernaryFuncFromString(const char *type) -{ - std::string tmp(type); - if(tmp==IfFunction::REPR) - return new IfFunction(); - std::string msg("Invalid ternary function detected : \""); - msg+=type; msg+="\""; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -Function *FunctionsFactory::buildBinaryFuncFromString(char type) -{ - char tmp[2]; tmp[0]=type; tmp[1]='\0'; - return buildBinaryFuncFromString(tmp); -} - -Function::~Function() -{ -} - -IdentityFunction::~IdentityFunction() -{ -} - -void IdentityFunction::operate(std::vector& stck) const -{ -} - -void IdentityFunction::operateX86(std::vector& asmb) const -{ -} - -void IdentityFunction::operateStackOfDouble(std::vector& stck) const -{ -} - -const char *IdentityFunction::getRepr() const -{ - return REPR; -} - -bool IdentityFunction::isACall() const -{ - return false; -} - -PositiveFunction::~PositiveFunction() -{ -} - -int UnaryFunction::getNbInputParams() const -{ - return 1; -} - -void PositiveFunction::operate(std::vector& stck) const -{ -} - -void PositiveFunction::operateX86(std::vector& asmb) const -{ -} - -void PositiveFunction::operateStackOfDouble(std::vector& stck) const -{ -} - -const char *PositiveFunction::getRepr() const -{ - return REPR; -} - -bool PositiveFunction::isACall() const -{ - return false; -} - -NegateFunction::~NegateFunction() -{ -} - -void NegateFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->negate(); -} - -void NegateFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fchs"); -} - -void NegateFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=-v; -} - -const char *NegateFunction::getRepr() const -{ - return REPR; -} - -bool NegateFunction::isACall() const -{ - return false; -} - -CosFunction::~CosFunction() -{ -} - -void CosFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->cos(); -} - -void CosFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fcos"); -} - -void CosFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=cos(v); -} - -const char *CosFunction::getRepr() const -{ - return REPR; -} - -bool CosFunction::isACall() const -{ - return true; -} - -SinFunction::~SinFunction() -{ -} - -void SinFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->sin(); -} - -void SinFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fsin"); -} - -void SinFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=sin(v); -} - -const char *SinFunction::getRepr() const -{ - return REPR; -} - -bool SinFunction::isACall() const -{ - return true; -} - -TanFunction::~TanFunction() -{ -} - -void TanFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->tan(); -} - -void TanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void TanFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=tan(v); -} - -const char *TanFunction::getRepr() const -{ - return REPR; -} - -bool TanFunction::isACall() const -{ - return true; -} - -ACosFunction::~ACosFunction() -{ -} - -void ACosFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->acos(); -} - -void ACosFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ACosFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=acos(v); -} - -void ACosFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(fabs(v)>1.) - throw INTERP_KERNEL::Exception("acos on a value which absolute is > 1 !"); - stck.back()=acos(v); -} - -const char *ACosFunction::getRepr() const -{ - return REPR; -} - -bool ACosFunction::isACall() const -{ - return true; -} - -ASinFunction::~ASinFunction() -{ -} - -void ASinFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->asin(); -} - -void ASinFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ASinFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=asin(v); -} - -void ASinFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(fabs(v)>1.) - throw INTERP_KERNEL::Exception("asin on a value which absolute is > 1 !"); - stck.back()=asin(v); -} - -const char *ASinFunction::getRepr() const -{ - return REPR; -} - -bool ASinFunction::isACall() const -{ - return true; -} - -ATanFunction::~ATanFunction() -{ -} - -void ATanFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->atan(); -} - -void ATanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ATanFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=atan(v); -} - -const char *ATanFunction::getRepr() const -{ - return REPR; -} - -bool ATanFunction::isACall() const -{ - return true; -} - -CoshFunction::~CoshFunction() -{ -} - -void CoshFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->cosh(); -} - -void CoshFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void CoshFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=cosh(v); -} - -const char *CoshFunction::getRepr() const -{ - return REPR; -} - -bool CoshFunction::isACall() const -{ - return true; -} - -SinhFunction::~SinhFunction() -{ -} - -void SinhFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->sinh(); -} - -void SinhFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void SinhFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=sinh(v); -} - -const char *SinhFunction::getRepr() const -{ - return REPR; -} - -bool SinhFunction::isACall() const -{ - return true; -} - -TanhFunction::~TanhFunction() -{ -} - -void TanhFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->tanh(); -} - -void TanhFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void TanhFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=tanh(v); -} - -const char *TanhFunction::getRepr() const -{ - return REPR; -} - -bool TanhFunction::isACall() const -{ - return true; -} - -SqrtFunction::~SqrtFunction() -{ -} - -void SqrtFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->sqrt(); -} - -void SqrtFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fsqrt"); -} - -void SqrtFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=sqrt(v); -} - -void SqrtFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("sqrt on a value < 0. !"); - stck.back()=sqrt(v); -} - -const char *SqrtFunction::getRepr() const -{ - return REPR; -} - -bool SqrtFunction::isACall() const -{ - return true; -} - -AbsFunction::~AbsFunction() -{ -} - -void AbsFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->abs(); -} - -void AbsFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fabs"); -} - -void AbsFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=fabs(v); -} - -const char *AbsFunction::getRepr() const -{ - return REPR; -} - -bool AbsFunction::isACall() const -{ - return false; -} - -void ExpFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->exp(); -} - -void ExpFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ExpFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::exp(v); -} - -const char *ExpFunction::getRepr() const -{ - return REPR; -} - -bool ExpFunction::isACall() const -{ - return true; -} - -LnFunction::~LnFunction() -{ -} - -void LnFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->ln(); -} - -void LnFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void LnFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::log(v); -} - -void LnFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("ln on a value < 0. !"); - stck.back()=std::log(v); -} - -const char *LnFunction::getRepr() const -{ - return REPR; -} - -bool LnFunction::isACall() const -{ - return true; -} - -LogFunction::~LogFunction() -{ -} - -void LogFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->ln(); -} - -void LogFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); -} - -void LogFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::log(v); -} - -void LogFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("log on a value < 0. !"); - stck.back()=std::log(v); -} - -const char *LogFunction::getRepr() const -{ - return REPR; -} - -bool LogFunction::isACall() const -{ - return true; -} - -Log10Function::~Log10Function() -{ -} - -void Log10Function::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->log10(); -} - -void Log10Function::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); -} - -void Log10Function::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::log10(v); -} - -void Log10Function::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("log10 on a value < 0. !"); - stck.back()=std::log10(v); -} - -const char *Log10Function::getRepr() const -{ - return REPR; -} - -bool Log10Function::isACall() const -{ - return true; -} - -int BinaryFunction::getNbInputParams() const -{ - return 2; -} - -PlusFunction::~PlusFunction() -{ -} - -void PlusFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->plus(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void PlusFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("faddp st1"); -} - -void PlusFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a+stck.back(); -} - -const char *PlusFunction::getRepr() const -{ - return REPR; -} - -bool PlusFunction::isACall() const -{ - return false; -} - -MinusFunction::~MinusFunction() -{ -} - -void MinusFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->minus(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void MinusFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fsubp st1"); -} - -void MinusFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a-stck.back(); -} - -const char *MinusFunction::getRepr() const -{ - return REPR; -} - -bool MinusFunction::isACall() const -{ - return false; -} - -MultFunction::~MultFunction() -{ -} - -void MultFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3=val1->mult(val2); - delete val1; - delete val2; - val2=val3; -} - -void MultFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fmulp st1"); -} - -void MultFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a*stck.back(); -} - -const char *MultFunction::getRepr() const -{ - return REPR; -} - -bool MultFunction::isACall() const -{ - return false; -} - -DivFunction::~DivFunction() -{ -} - -void DivFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->div(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void DivFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fdivp st1"); -} - -void DivFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a/stck.back(); -} - -void DivFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - if(stck.back()==0.) - throw INTERP_KERNEL::Exception("division by 0. !"); - stck.back()=a/stck.back(); -} - -const char *DivFunction::getRepr() const -{ - return REPR; -} - -bool DivFunction::isACall() const -{ - return false; -} - -PowFunction::~PowFunction() -{ -} - -void PowFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->pow(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void PowFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void PowFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=std::pow(a,stck.back()); -} - -void PowFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - double b(stck.back()); - if(a<0.) - throw INTERP_KERNEL::Exception("pow with val < 0. !"); - stck.back()=std::pow(a,b); -} - -const char *PowFunction::getRepr() const -{ - return REPR; -} - -bool PowFunction::isACall() const -{ - return true; -} - -ExpFunction::~ExpFunction() -{ -} - -MaxFunction::~MaxFunction() -{ -} - -void MaxFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->max(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void MaxFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void MaxFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=std::max(stck.back(),a); -} - -const char *MaxFunction::getRepr() const -{ - return REPR; -} - -bool MaxFunction::isACall() const -{ - return false; -} - -MinFunction::~MinFunction() -{ -} - -void MinFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->min(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void MinFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void MinFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=std::min(stck.back(),a); -} - -const char *MinFunction::getRepr() const -{ - return REPR; -} - -bool MinFunction::isACall() const -{ - return false; -} - -GreaterThanFunction::~GreaterThanFunction() -{ -} - -void GreaterThanFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->greaterThan(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void GreaterThanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void GreaterThanFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - double b(stck.back()); - stck.back()=a>b?std::numeric_limits::max():-std::numeric_limits::max(); -} - -const char *GreaterThanFunction::getRepr() const -{ - return REPR; -} - -bool GreaterThanFunction::isACall() const -{ - return false; -} - -LowerThanFunction::~LowerThanFunction() -{ -} - -void LowerThanFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->lowerThan(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void LowerThanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void LowerThanFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - double b(stck.back()); - stck.back()=a::max():-std::numeric_limits::max(); -} - -const char *LowerThanFunction::getRepr() const -{ - return REPR; -} - -bool LowerThanFunction::isACall() const -{ - return false; -} - -int TernaryFunction::getNbInputParams() const -{ - return 3; -} - -IfFunction::~IfFunction() -{ -} - -void IfFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *val2=stck.back(); - stck.pop_back(); - Value *&val3=stck.back(); - Value *val4; - try - { - val4=val1->ifFunc(val2,val3); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - delete val2; - throw e; - } - delete val1; - delete val2; - delete val3; - val3=val4; -} - -void IfFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void IfFunction::operateStackOfDouble(std::vector& stck) const -{ - double cond(stck.back()); - stck.pop_back(); - double the(stck.back()); - stck.pop_back(); - if(cond==std::numeric_limits::max()) - stck.back()=the; -} - -void IfFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double cond(stck.back()); - stck.pop_back(); - double the(stck.back()); - stck.pop_back(); - if(cond!=std::numeric_limits::max() && cond!=-std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !"); - if(cond==std::numeric_limits::max()) - stck.back()=the; -} - -const char *IfFunction::getRepr() const -{ - return REPR; -} - -bool IfFunction::isACall() const -{ - return false; -} - diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx deleted file mode 100644 index 8f5cf489e..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx +++ /dev/null @@ -1,479 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELFUNCTION_HXX__ -#define __INTERPKERNELFUNCTION_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - class Value; - class Function; - - class INTERPKERNEL_EXPORT FunctionsFactory - { - public: - static Function *buildFuncFromString(const char *type, int nbOfParams); - static Function *buildUnaryFuncFromString(const char *type); - //static Function *buildUnaryFuncFromString(char type); - static Function *buildBinaryFuncFromString(const char *type); - static Function *buildBinaryFuncFromString(char type); - static Function *buildTernaryFuncFromString(const char *type); - }; - - class INTERPKERNEL_EXPORT Function - { - public: - virtual ~Function(); - virtual int getNbInputParams() const = 0; - virtual void operate(std::vector& stck) const = 0; - virtual void operateX86(std::vector& asmb) const = 0; - virtual void operateStackOfDouble(std::vector& stck) const = 0; - virtual void operateStackOfDoubleSafe(std::vector& stck) const { operateStackOfDouble(stck); } - virtual const char *getRepr() const = 0; - virtual bool isACall() const = 0; - virtual Function *deepCpy() const = 0; - }; - - class INTERPKERNEL_EXPORT UnaryFunction : public Function - { - public: - int getNbInputParams() const; - }; - - class INTERPKERNEL_EXPORT IdentityFunction : public UnaryFunction - { - public: - ~IdentityFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - IdentityFunction *deepCpy() const { return new IdentityFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT PositiveFunction : public UnaryFunction - { - public: - ~PositiveFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - PositiveFunction *deepCpy() const { return new PositiveFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT NegateFunction : public UnaryFunction - { - public: - ~NegateFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - NegateFunction *deepCpy() const { return new NegateFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT CosFunction : public UnaryFunction - { - public: - ~CosFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - CosFunction *deepCpy() const { return new CosFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT SinFunction : public UnaryFunction - { - public: - ~SinFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - SinFunction *deepCpy() const { return new SinFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT TanFunction : public UnaryFunction - { - public: - ~TanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - TanFunction *deepCpy() const { return new TanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ACosFunction : public UnaryFunction - { - public: - ~ACosFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ACosFunction *deepCpy() const { return new ACosFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ASinFunction : public UnaryFunction - { - public: - ~ASinFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ASinFunction *deepCpy() const { return new ASinFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ATanFunction : public UnaryFunction - { - public: - ~ATanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ATanFunction *deepCpy() const { return new ATanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT CoshFunction : public UnaryFunction - { - public: - ~CoshFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - CoshFunction *deepCpy() const { return new CoshFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT SinhFunction : public UnaryFunction - { - public: - ~SinhFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - SinhFunction *deepCpy() const { return new SinhFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT TanhFunction : public UnaryFunction - { - public: - ~TanhFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - TanhFunction *deepCpy() const { return new TanhFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT SqrtFunction : public UnaryFunction - { - public: - ~SqrtFunction(); - void operateX86(std::vector& asmb) const; - void operate(std::vector& stck) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - SqrtFunction *deepCpy() const { return new SqrtFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT AbsFunction : public UnaryFunction - { - public: - ~AbsFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - AbsFunction *deepCpy() const { return new AbsFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ExpFunction : public UnaryFunction - { - public: - ~ExpFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ExpFunction *deepCpy() const { return new ExpFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT LnFunction : public UnaryFunction - { - public: - ~LnFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - LnFunction *deepCpy() const { return new LnFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT LogFunction : public UnaryFunction - { - public: - ~LogFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - LogFunction *deepCpy() const { return new LogFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT Log10Function : public UnaryFunction - { - public: - ~Log10Function(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - Log10Function *deepCpy() const { return new Log10Function; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT BinaryFunction : public Function - { - public: - int getNbInputParams() const; - }; - - class PlusFunction : public BinaryFunction - { - public: - ~PlusFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - PlusFunction *deepCpy() const { return new PlusFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MinusFunction : public BinaryFunction - { - public: - ~MinusFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MinusFunction *deepCpy() const { return new MinusFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MultFunction : public BinaryFunction - { - public: - ~MultFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MultFunction *deepCpy() const { return new MultFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT DivFunction : public BinaryFunction - { - public: - ~DivFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - DivFunction *deepCpy() const { return new DivFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT PowFunction : public BinaryFunction - { - public: - ~PowFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - PowFunction *deepCpy() const { return new PowFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MaxFunction : public BinaryFunction - { - public: - ~MaxFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MaxFunction *deepCpy() const { return new MaxFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MinFunction : public BinaryFunction - { - public: - ~MinFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MinFunction *deepCpy() const { return new MinFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT GreaterThanFunction : public BinaryFunction - { - public: - ~GreaterThanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - GreaterThanFunction *deepCpy() const { return new GreaterThanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT LowerThanFunction : public BinaryFunction - { - public: - ~LowerThanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - LowerThanFunction *deepCpy() const { return new LowerThanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT TernaryFunction : public Function - { - public: - int getNbInputParams() const; - }; - - class INTERPKERNEL_EXPORT IfFunction : public TernaryFunction - { - public: - ~IfFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - IfFunction *deepCpy() const { return new IfFunction; } - public: - static const char REPR[]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx deleted file mode 100644 index 44e08f49f..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelUnit.hxx" -#include "InterpKernelExprParser.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -UnitDataBase UnitDataBase::_uniqueMapForExpr; - -static const char InterpKernelMuAscii[2]={-0x4B,0x0}; - -static const char InterpKernelMuUnicode[3]={-0x3E,-0x4B,0x0}; - -const char *UnitDataBase::PREF_POW10[NB_OF_PREF_POW10]={"y","z","a","f","p","n",InterpKernelMuAscii,InterpKernelMuUnicode,"u","m","c","d", - "da","h","k","M","G","T","P","E","Z","Y"}; - -const double UnitDataBase::POW10[NB_OF_PREF_POW10]={1e-24,1e-21,1e-18,1e-15,1e-12,1e-9,1e-6,1e-6,1e-6,1e-3,1e-2,1e-1, - 1e1,1e2,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24}; - -static const char InterpKernelDegreeCAscii[3]={-0x50,0x43,0x0}; - -static const char InterpKernelDegreeCUnicode[4]={-0x3E,-0x50,0x43,0x0}; - -static const char InterpKernelDegreeCUnicodeWin[3]={-0x08,0x43,0x0}; - -const char *UnitDataBase::UNITS_RECOGN[NB_OF_UNITS_RECOGN]={"g","m","s","A","K", - "W","J","Hz","V","h","min","t","N","dyn", - "eV","Pa","atm","bar",InterpKernelDegreeCAscii,"C","ohm","F","S", - "T","H","P","St",InterpKernelDegreeCUnicode,InterpKernelDegreeCUnicodeWin}; - -const short UnitDataBase::PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]= - { - {1,0,0,0,0},//g - {0,1,0,0,0},//m - {0,0,1,0,0},//s - {0,0,0,1,0},//A - {0,0,0,0,1},//K - {1,2,-3,0,0},//W - {1,2,-2,0,0},//J - {0,0,-1,0,0},//Hz - {1,2,-3,-1,0},//V - {0,0,1,0,0},//h - {0,0,1,0,0},//min - {1,0,0,0,0},//t - {1,1,-2,0,0},//N - {1,1,-2,0,0},//dyn - {1,2,-2,0,0},//eV - {1,-1,-2,0,0},//Pa - {1,-1,-2,0,0},//atm - {1,-1,-2,0,0},//bar - {0,0,0,0,1},//degree C - {0,0,1,1,0},//C - {1,2,-3,-2,0},//ohm - {-1,-2,4,2,0},//F - {-1,-2,3,2,0},//S - {1,0,-2,-1,0},//T - {1,2,-2,-2,0},//H - {1,-1,-1,0,0},//P - {0,2,-1,0,0},//St - {0,0,0,0,1},//degree C - {0,0,0,0,1}//degree C - }; - -const double UnitDataBase::MUL_COEFF[NB_OF_UNITS_RECOGN]= - { 1.,1.,1.,1.,1., - 1000.,1000.,1.,1000.,3600.,3600.,1e6,1000.,1e-2, - 1.60217733e-16,1000.,1.01325e8,1e8,1.,1.,1000.,1e-3, - 1000.,1000.,100.,1.,1.,1.,1.}; - -const double UnitDataBase::ADD_COEFF[NB_OF_UNITS_RECOGN]= - { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 273.15, 0., 0., 0., 0., 0., 0., 0., 0., 273.15 ,273.15}; - -UnitDataBase::UnitDataBase() -{ - for(int i=0;i::const_iterator iter=_units_semantic.find(work); - if(iter!=_units_semantic.end()) - { - ret=(*iter).second; - std::map::const_iterator iter2=_units_add.find(work); - addFact=(*iter2).second; - std::map::const_iterator iter3=_units_mul.find(work); - mFact=(*iter3).second; - work2=unit.substr(0,i); - } - } - if(!ret) - { - std::ostringstream os; - os << "Unit : " << unit << " not recognized !"; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(!work2.empty()) - { - std::map::const_iterator iter4=_prefix_pow_10.find(work2); - if(iter4==_prefix_pow_10.end()) - { - std::ostringstream os; - os << "Unit : " << unit << " not fully recognized : \"" << work << "\" detected as core unit and \""; - os << work2 << "\" not recognized prefix !"; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - addFact=0.; - mFact*=(*iter4).second; - } - return ret; -} - -DecompositionInUnitBase::DecompositionInUnitBase():_add_to_base(0.),_mult_fact_to_base(1.) -{ - _value[0]=0; - _value[1]=0; - _value[2]=0; - _value[3]=0; - _value[4]=0; -} - -void DecompositionInUnitBase::setInfo(const short *vals, double addFact, double mFact) -{ - _add_to_base=addFact; - _mult_fact_to_base=mFact; - _value[0]=vals[0]; - _value[1]=vals[1]; - _value[2]=vals[2]; - _value[3]=vals[3]; - _value[4]=vals[4]; -} - -bool DecompositionInUnitBase::operator==(const DecompositionInUnitBase& other) const -{ - return _value[0]==other._value[0] && _value[1]==other._value[1] && _value[2]==other._value[2] && _value[3]==other._value[3] && _value[4]==other._value[4]; -} - -void DecompositionInUnitBase::getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const -{ - if((*this)==other) - { - mul=_mult_fact_to_base/other._mult_fact_to_base; - add=_add_to_base/other._mult_fact_to_base-other._add_to_base; - } - else - { - mul=std::numeric_limits::max(); - add=std::numeric_limits::max(); - } -} - -bool DecompositionInUnitBase::isEqual(short mass, short lgth, short time, short intensity, short temp, double add, double mult) -{ - bool ret1=mass==_value[0]; - bool ret2=lgth==_value[1]; - bool ret3=time==_value[2]; - bool ret4=intensity==_value[3]; - bool ret5=temp==_value[4]; - bool ret6=areDoubleEquals(add,_add_to_base); - bool ret7=areDoubleEquals(mult,_mult_fact_to_base); - return ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7; -} - -void DecompositionInUnitBase::negate() -{ - _mult_fact_to_base=-_mult_fact_to_base; -} - -bool DecompositionInUnitBase::isAdimensional() const -{ - return _value[0]==0 && _value[1]==0 && _value[2]==0 && _value[3]==0 && _value[4]==0; -} - -bool DecompositionInUnitBase::isUnitary() const -{ - return areDoubleEquals(_add_to_base,0.) && areDoubleEquals(_mult_fact_to_base,1.); -} - -void DecompositionInUnitBase::tryToConvertInUnit(double val) -{ - int valI=(int)val; - if((val-(double)valI)!=0.) - { - std::ostringstream os; - os << "Double value " << val << " can't be considered as integer. Not admitable for units !"; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - _value[0]=0; - _value[1]=0; - _value[2]=0; - _value[3]=0; - _value[4]=0; - _add_to_base=0; - _mult_fact_to_base=valI; -} - -DecompositionInUnitBase &DecompositionInUnitBase::operator*(const DecompositionInUnitBase& other) -{ - _value[0]+=other._value[0]; _value[1]+=other._value[1]; _value[2]+=other._value[2]; _value[3]+=other._value[3]; _value[4]+=other._value[4]; - _mult_fact_to_base*=other._mult_fact_to_base; - _add_to_base=0.; - return *this; -} - -DecompositionInUnitBase &DecompositionInUnitBase::operator/(const DecompositionInUnitBase& other) -{ - _value[0]-=other._value[0]; _value[1]-=other._value[1]; _value[2]-=other._value[2]; _value[3]-=other._value[3]; _value[4]-=other._value[4]; - _mult_fact_to_base/=other._mult_fact_to_base; - _add_to_base=0.; - return *this; -} - -DecompositionInUnitBase &DecompositionInUnitBase::operator^(const DecompositionInUnitBase& other) -{ - if(!other.isAdimensional()) - throw INTERP_KERNEL::Exception("Trying to execute operator ^ with a second member not adimensionnal"); - int exp=couldItBeConsideredAsInt(other._mult_fact_to_base); - _value[0]*=exp; _value[1]*=exp; _value[2]*=exp; _value[3]*=exp; _value[4]*=exp; - _mult_fact_to_base=powInt(_mult_fact_to_base,exp); - _add_to_base=0.; - return *this; -} - -void DecompositionInUnitBase::dealWithAddFactor(const DecompositionInUnitBase& other) -{ - if(!areDoubleEquals(_add_to_base,0.)) - if(other.isAdimensional()) - if(areDoubleEquals(other._mult_fact_to_base,1.)) - return ; - if(!other.areDoubleEquals(_add_to_base,0.)) - if(isAdimensional()) - if(areDoubleEquals(_mult_fact_to_base,1.)) - return ; - _add_to_base=0.; -} - -double DecompositionInUnitBase::powInt(double val, int exp) -{ - double work=1.; - if(exp==0) - return 1.; - if(exp>0) - for(int i=0;i::max(); -} - -std::string Unit::getCoarseRepr() const -{ - return _coarse_repr; -} diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx deleted file mode 100644 index 4af8759b5..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELUNIT_HXX__ -#define __INTERPKERNELUNIT_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class UnitDataBase - { - public: - INTERPKERNEL_EXPORT UnitDataBase(); - INTERPKERNEL_EXPORT const short *getInfoForUnit(const std::string& unit, double& addFact, double& mFact) const; - INTERPKERNEL_EXPORT static UnitDataBase _uniqueMapForExpr; - INTERPKERNEL_EXPORT static const int SIZE_OF_UNIT_BASE=5; - private: - std::map _prefix_pow_10; - std::map _units_semantic; - std::map _units_mul; - std::map _units_add; - private: - static const int NB_OF_PREF_POW10=22; - static const char *PREF_POW10[NB_OF_PREF_POW10]; - static const double POW10[NB_OF_PREF_POW10]; - static const int NB_OF_UNITS_RECOGN=29; - static const char *UNITS_RECOGN[NB_OF_UNITS_RECOGN]; - static const short PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]; - static const double MUL_COEFF[NB_OF_UNITS_RECOGN]; - static const double ADD_COEFF[NB_OF_UNITS_RECOGN]; - }; - - class DecompositionInUnitBase - { - public: - INTERPKERNEL_EXPORT DecompositionInUnitBase(); - INTERPKERNEL_EXPORT void setInfo(const short *vals, double addFact, double mFact); - INTERPKERNEL_EXPORT short operator[](int i) const { return _value[i]; } - INTERPKERNEL_EXPORT bool operator==(const DecompositionInUnitBase& other) const; - INTERPKERNEL_EXPORT void getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const; - INTERPKERNEL_EXPORT bool isEqual(short mass, short lgth, short time, short intensity, short temp, - double add, double mult); - INTERPKERNEL_EXPORT bool isUnitary() const; - //! \b WARNING no test is done on the fact that unit is adimensionnal. - INTERPKERNEL_EXPORT void negate(); - INTERPKERNEL_EXPORT bool isAdimensional() const; - INTERPKERNEL_EXPORT void tryToConvertInUnit(double val); - INTERPKERNEL_EXPORT DecompositionInUnitBase &operator*(const DecompositionInUnitBase& other); - INTERPKERNEL_EXPORT DecompositionInUnitBase &operator/(const DecompositionInUnitBase& other); - INTERPKERNEL_EXPORT DecompositionInUnitBase &operator^(const DecompositionInUnitBase& other); - private: - void dealWithAddFactor(const DecompositionInUnitBase& other); - static int couldItBeConsideredAsInt(double val); - static bool areDoubleEquals(double a, double b); - static double powInt(double val, int exp); - private: - short _value[UnitDataBase::SIZE_OF_UNIT_BASE]; - double _add_to_base; - double _mult_fact_to_base; - }; - - /*! - * This class deals with units. - * This class has two main responsabilities : - * - interprete units by giving simply their representation in string type. - * - performing operations on these units. - * - * All the possible units are represented with a unique tuple with 5 elements - * representing the unique decomposition of a unit in the following base. - * - * dimension 0 stands for mass in g (\b NOT kg to simplify parsing). - * dimension 1 stands for length in m. - * dimension 2 stands for time in s. - * dimension 3 stands for elec intensity A. - * dimension 4 stands for temperature in K. - */ - class Unit - { - public: - INTERPKERNEL_EXPORT Unit(const char *reprC, bool tryToInterp=true); - INTERPKERNEL_EXPORT Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp=true); - INTERPKERNEL_EXPORT void tryToInterprate() const; - INTERPKERNEL_EXPORT bool isInterpretationOK() const; - INTERPKERNEL_EXPORT bool isCompatibleWith(const Unit& other) const; - INTERPKERNEL_EXPORT double convert(const Unit& target, double sourceVal) const; - INTERPKERNEL_EXPORT std::string getCoarseRepr() const; - private: - std::string _coarse_repr; - mutable bool _is_interpreted; - mutable bool _is_interpretation_ok; - mutable DecompositionInUnitBase _decomp_in_base; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx deleted file mode 100644 index 3006fc941..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx +++ /dev/null @@ -1,641 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelValue.hxx" -#include "InterpKernelFunction.hxx" - -#include -#include -#include - -using namespace INTERP_KERNEL; - -ValueDouble::ValueDouble():_data(std::numeric_limits::max()) -{ -} - -Value *ValueDouble::newInstance() const -{ - return new ValueDouble; -} - -ValueDouble::ValueDouble(double val):_data(val) -{ -} - -void ValueDouble::setDouble(double val) -{ - _data=val; -} - -void ValueDouble::setVarname(int fastPos, const std::string& var) -{ - std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !"; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -void ValueDouble::positive() -{ -} - -void ValueDouble::negate() -{ - _data=-_data; -} - -void ValueDouble::sqrt() -{ - _data=std::sqrt(_data); -} - -void ValueDouble::cos() -{ - _data=std::cos(_data); -} - -void ValueDouble::sin() -{ - _data=std::sin(_data); -} - -void ValueDouble::tan() -{ - _data=std::tan(_data); -} - -void ValueDouble::acos() -{ - _data=std::acos(_data); -} - -void ValueDouble::asin() -{ - _data=std::asin(_data); -} - -void ValueDouble::atan() -{ - _data=std::atan(_data); -} - -void ValueDouble::cosh() -{ - _data=std::cosh(_data); -} - -void ValueDouble::sinh() -{ - _data=std::sinh(_data); -} - -void ValueDouble::tanh() -{ - _data=std::tanh(_data); -} - -void ValueDouble::abs() -{ - if(_data<0.) - _data=-_data; -} - -void ValueDouble::exp() -{ - _data=std::exp(_data); -} - -void ValueDouble::ln() -{ - _data=std::log(_data); -} - -void ValueDouble::log10() -{ - _data=std::log10(_data); -} - -Value *ValueDouble::plus(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data+valC->_data); -} - -Value *ValueDouble::minus(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data-valC->_data); -} - -Value *ValueDouble::mult(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data*valC->_data); -} - -Value *ValueDouble::div(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data/valC->_data); -} - -Value *ValueDouble::pow(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(std::pow(_data,valC->_data)); -} - -Value *ValueDouble::max(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(std::max(_data,valC->_data)); -} - -Value *ValueDouble::min(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(std::min(_data,valC->_data)); -} - -Value *ValueDouble::greaterThan(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data>valC->_data?std::numeric_limits::max():-std::numeric_limits::max()); -} - -Value *ValueDouble::lowerThan(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data_data?std::numeric_limits::max():-std::numeric_limits::max()); -} - -Value *ValueDouble::ifFunc(const Value *the, const Value *els) const -{ - const ValueDouble *theC=checkSameType(the); - const ValueDouble *elsC=checkSameType(els); - if(_data==std::numeric_limits::max()) - return new ValueDouble(theC->_data); - if(_data==-std::numeric_limits::max()) - return new ValueDouble(elsC->_data); - throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !"); -} - -const ValueDouble *ValueDouble::checkSameType(const Value *val) -{ - const ValueDouble *valC=dynamic_cast(val); - if(!valC) - throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !"); - return valC; -} - -ValueUnit::ValueUnit() -{ -} - -Value *ValueUnit::newInstance() const -{ - return new ValueUnit; -} - -ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit) -{ -} - -void ValueUnit::setDouble(double val) -{ - _data.tryToConvertInUnit(val); -} - -void ValueUnit::setVarname(int fastPos, const std::string& var) -{ - double add,mul; - const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul); - _data.setInfo(projInBase,add,mul); -} - -void ValueUnit::positive() -{ - unsupportedOp(PositiveFunction::REPR); -} - -void ValueUnit::negate() -{ - _data.negate(); -} - -void ValueUnit::sqrt() -{ - unsupportedOp(SqrtFunction::REPR); -} - -void ValueUnit::cos() -{ - unsupportedOp(CosFunction::REPR); -} - -void ValueUnit::sin() -{ - unsupportedOp(SinFunction::REPR); -} - -void ValueUnit::tan() -{ - unsupportedOp(TanFunction::REPR); -} - -void ValueUnit::acos() -{ - unsupportedOp(ACosFunction::REPR); -} - -void ValueUnit::asin() -{ - unsupportedOp(ASinFunction::REPR); -} - -void ValueUnit::atan() -{ - unsupportedOp(ATanFunction::REPR); -} - -void ValueUnit::cosh() -{ - unsupportedOp(CoshFunction::REPR); -} - -void ValueUnit::sinh() -{ - unsupportedOp(SinhFunction::REPR); -} - -void ValueUnit::tanh() -{ - unsupportedOp(TanhFunction::REPR); -} - -void ValueUnit::abs() -{ - unsupportedOp(AbsFunction::REPR); -} - -void ValueUnit::exp() -{ - unsupportedOp(ExpFunction::REPR); -} - -void ValueUnit::ln() -{ - unsupportedOp(LnFunction::REPR); -} - -void ValueUnit::log10() -{ - unsupportedOp(Log10Function::REPR); -} - -Value *ValueUnit::plus(const Value *other) const -{ - unsupportedOp(PlusFunction::REPR); - return 0; -} - -Value *ValueUnit::minus(const Value *other) const -{ - unsupportedOp(MinusFunction::REPR); - return 0; -} - -Value *ValueUnit::greaterThan(const Value *other) const -{ - unsupportedOp(GreaterThanFunction::REPR); - return 0; -} - -Value *ValueUnit::lowerThan(const Value *other) const -{ - unsupportedOp(LowerThanFunction::REPR); - return 0; -} - -Value *ValueUnit::ifFunc(const Value *the, const Value *els) const -{ - unsupportedOp(IfFunction::REPR); - return 0; -} - -Value *ValueUnit::mult(const Value *other) const -{ - const ValueUnit *valC=checkSameType(other); - DecompositionInUnitBase tmp=_data; - tmp*valC->getData(); - return new ValueUnit(tmp); -} - -Value *ValueUnit::div(const Value *other) const -{ - const ValueUnit *valC=checkSameType(other); - DecompositionInUnitBase tmp=_data; - tmp/valC->getData(); - return new ValueUnit(tmp); -} - -Value *ValueUnit::pow(const Value *other) const -{ - const ValueUnit *valC=checkSameType(other); - DecompositionInUnitBase tmp=_data; - tmp^valC->getData(); - return new ValueUnit(tmp); -} - -Value *ValueUnit::max(const Value *other) const -{ - unsupportedOp(MaxFunction::REPR); - return 0; -} - -Value *ValueUnit::min(const Value *other) const -{ - unsupportedOp(MinFunction::REPR); - return 0; -} - -const ValueUnit *ValueUnit::checkSameType(const Value *val) -{ - const ValueUnit *valC=dynamic_cast(val); - if(!valC) - throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !"); - return valC; -} - -void ValueUnit::unsupportedOp(const char *type) -{ - const char msg[]="Unsupported operation for units :"; - std::string msgStr(msg); - msgStr+=type; - throw INTERP_KERNEL::Exception(msgStr.c_str()); -} - -ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData) -{ -} - -ValueDoubleExpr::~ValueDoubleExpr() -{ - delete [] _dest_data; -} - -Value *ValueDoubleExpr::newInstance() const -{ - return new ValueDoubleExpr(_sz_dest_data,_src_data); -} - -void ValueDoubleExpr::setDouble(double val) -{ - std::fill(_dest_data,_dest_data+_sz_dest_data,val); -} - -void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) -{ - if(fastPos==-2) - std::copy(_src_data,_src_data+_sz_dest_data,_dest_data); - else if(fastPos>-2) - std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]); - else - { - std::fill(_dest_data,_dest_data+_sz_dest_data,0.); - _dest_data[-7-fastPos]=1.; - } -} - -void ValueDoubleExpr::positive() -{ -} - -void ValueDoubleExpr::negate() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate()); -} - -void ValueDoubleExpr::sqrt() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::sqrt)); -} - -void ValueDoubleExpr::cos() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::cos)); -} - -void ValueDoubleExpr::sin() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::sin)); -} - -void ValueDoubleExpr::tan() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::tan)); -} - -void ValueDoubleExpr::acos() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),-1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !"); - it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater(),1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::acos)); -} - -void ValueDoubleExpr::asin() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),-1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !"); - it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater(),1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::asin)); -} - -void ValueDoubleExpr::atan() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::atan)); -} - -void ValueDoubleExpr::cosh() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::cosh)); -} - -void ValueDoubleExpr::sinh() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::sinh)); -} - -void ValueDoubleExpr::tanh() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::tanh)); -} - -void ValueDoubleExpr::abs() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(fabs)); -} - -void ValueDoubleExpr::exp() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::exp)); -} - -void ValueDoubleExpr::ln() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::log)); -} - -void ValueDoubleExpr::log10() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::log10)); -} - -Value *ValueDoubleExpr::plus(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus()); - return ret; -} - -Value *ValueDoubleExpr::minus(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus()); - return ret; -} - -Value *ValueDoubleExpr::mult(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies()); - return ret; -} - -Value *ValueDoubleExpr::div(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.); - if(it!=otherC->getData()+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to operate division by 0. !"); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides()); - return ret; -} - -Value *ValueDoubleExpr::pow(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - double p=otherC->getData()[0]; - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !"); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun(std::pow),p)); - return ret; -} - -Value *ValueDoubleExpr::max(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(std::max)); - return ret; -} - -Value *ValueDoubleExpr::min(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(std::min)); - return ret; -} - -Value *ValueDoubleExpr::greaterThan(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - for(int i=0;i<_sz_dest_data;i++) - if(_dest_data[i]<=otherC->getData()[i]) - { - std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits::max()); - return ret; - } - std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits::max()); - return ret; -} - -Value *ValueDoubleExpr::lowerThan(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - for(int i=0;i<_sz_dest_data;i++) - if(_dest_data[i]>=otherC->getData()[i]) - { - std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits::max()); - return ret; - } - std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits::max()); - return ret; -} - -Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const -{ - const ValueDoubleExpr *theC=static_cast(the); - const ValueDoubleExpr *elsC=static_cast(els); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - bool okmax=true; - bool okmin=true; - for(int i=0;i<_sz_dest_data && (okmax || okmin);i++) - { - okmax=_dest_data[i]==std::numeric_limits::max(); - okmin=_dest_data[i]==-std::numeric_limits::max(); - } - if(okmax || okmin) - { - if(okmax) - std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData()); - else - std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData()); - return ret; - } - else - { - throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !"); - } -} diff --git a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx b/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx deleted file mode 100644 index ecc6d1118..000000000 --- a/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELVALUE_HXX__ -#define __INTERPKERNELVALUE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelUnit.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Value - { - public: - virtual Value *newInstance() const = 0; - virtual ~Value() { } - virtual void setDouble(double val) = 0; - virtual void setVarname(int fastPos, const std::string& var) = 0; - //unary - virtual void positive() = 0; - virtual void negate() = 0; - virtual void sqrt() = 0; - virtual void cos() = 0; - virtual void sin() = 0; - virtual void tan() = 0; - virtual void acos() = 0; - virtual void asin() = 0; - virtual void atan() = 0; - virtual void cosh() = 0; - virtual void sinh() = 0; - virtual void tanh() = 0; - virtual void abs() = 0; - virtual void exp() = 0; - virtual void ln() = 0; - virtual void log10() = 0; - //binary - virtual Value *plus(const Value *other) const = 0; - virtual Value *minus(const Value *other) const = 0; - virtual Value *mult(const Value *other) const = 0; - virtual Value *div(const Value *other) const = 0; - virtual Value *pow(const Value *other) const = 0; - virtual Value *max(const Value *other) const = 0; - virtual Value *min(const Value *other) const = 0; - virtual Value *greaterThan(const Value *other) const = 0; - virtual Value *lowerThan(const Value *other) const = 0; - //ternary - virtual Value *ifFunc(const Value *the, const Value *els) const = 0; - }; - - class INTERPKERNEL_EXPORT ValueDouble : public Value - { - public: - ValueDouble(); - Value *newInstance() const; - void setDouble(double val); - void setVarname(int fastPos, const std::string& var); - // - double getData() const { return _data; } - void positive(); - void negate(); - void sqrt(); - void cos(); - void sin(); - void tan(); - void acos(); - void asin(); - void atan(); - void cosh(); - void sinh(); - void tanh(); - void abs(); - void exp(); - void ln(); - void log10(); - // - Value *plus(const Value *other) const; - Value *minus(const Value *other) const; - Value *mult(const Value *other) const; - Value *div(const Value *other) const; - Value *pow(const Value *other) const; - Value *max(const Value *other) const; - Value *min(const Value *other) const; - Value *greaterThan(const Value *other) const; - Value *lowerThan(const Value *other) const; - // - Value *ifFunc(const Value *the, const Value *els) const; - private: - ValueDouble(double val); - static const ValueDouble *checkSameType(const Value *val); - private: - double _data; - }; - - class ValueUnit : public Value - { - public: - INTERPKERNEL_EXPORT ValueUnit(); - INTERPKERNEL_EXPORT Value *newInstance() const; - INTERPKERNEL_EXPORT void setDouble(double val); - INTERPKERNEL_EXPORT void setVarname(int fastPos, const std::string& var); - // - INTERPKERNEL_EXPORT DecompositionInUnitBase getData() const { return _data; } - INTERPKERNEL_EXPORT void positive(); - INTERPKERNEL_EXPORT void negate(); - INTERPKERNEL_EXPORT void sqrt(); - INTERPKERNEL_EXPORT void cos(); - INTERPKERNEL_EXPORT void sin(); - INTERPKERNEL_EXPORT void tan(); - INTERPKERNEL_EXPORT void acos(); - INTERPKERNEL_EXPORT void asin(); - INTERPKERNEL_EXPORT void atan(); - INTERPKERNEL_EXPORT void cosh(); - INTERPKERNEL_EXPORT void sinh(); - INTERPKERNEL_EXPORT void tanh(); - INTERPKERNEL_EXPORT void abs(); - INTERPKERNEL_EXPORT void exp(); - INTERPKERNEL_EXPORT void ln(); - INTERPKERNEL_EXPORT void log10(); - // - INTERPKERNEL_EXPORT Value *plus(const Value *other) const; - INTERPKERNEL_EXPORT Value *minus(const Value *other) const; - INTERPKERNEL_EXPORT Value *mult(const Value *other) const; - INTERPKERNEL_EXPORT Value *div(const Value *other) const; - INTERPKERNEL_EXPORT Value *pow(const Value *other) const; - INTERPKERNEL_EXPORT Value *max(const Value *other) const; - INTERPKERNEL_EXPORT Value *min(const Value *other) const; - INTERPKERNEL_EXPORT Value *greaterThan(const Value *other) const; - INTERPKERNEL_EXPORT Value *lowerThan(const Value *other) const; - // - INTERPKERNEL_EXPORT Value *ifFunc(const Value *the, const Value *els) const; - private: - ValueUnit(const DecompositionInUnitBase& unit); - static void unsupportedOp(const char *type); - static const ValueUnit *checkSameType(const Value *val); - private: - DecompositionInUnitBase _data; - }; - - class INTERPKERNEL_EXPORT ValueDoubleExpr : public Value - { - public: - ValueDoubleExpr(int szDestData, const double *srcData); - ~ValueDoubleExpr(); - double *getData() const { return _dest_data; } - Value *newInstance() const; - void setDouble(double val); - void setVarname(int fastPos, const std::string& var); - // - void positive(); - void negate(); - void sqrt(); - void cos(); - void sin(); - void tan(); - void acos(); - void asin(); - void atan(); - void cosh(); - void sinh(); - void tanh(); - void abs(); - void exp(); - void ln(); - void log10(); - // - Value *plus(const Value *other) const; - Value *minus(const Value *other) const; - Value *mult(const Value *other) const; - Value *div(const Value *other) const; - Value *pow(const Value *other) const; - Value *max(const Value *other) const; - Value *min(const Value *other) const; - Value *greaterThan(const Value *other) const; - Value *lowerThan(const Value *other) const; - // - Value *ifFunc(const Value *the, const Value *els) const; - private: - int _sz_dest_data; - double *_dest_data; - const double *_src_data; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx b/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx deleted file mode 100644 index 618e9e8b8..000000000 --- a/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx +++ /dev/null @@ -1,2823 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -//Local includes -#include "InterpKernelGaussCoords.hxx" -#include "CellModel.hxx" - -//STL includes -#include -#include -#include - -using namespace INTERP_KERNEL; - -//Define common part of the code in the MACRO -//--------------------------------------------------------------- -#define LOCAL_COORD_MACRO_BEGIN \ - _my_local_reference_coord.resize( _my_local_ref_dim*_my_local_nb_ref ); \ - for( int refId = 0; refId < _my_local_nb_ref; refId++ ) \ - { \ - double* coords = &_my_local_reference_coord[ refId*_my_local_ref_dim ]; \ - switch(refId) \ - { - -//--------------------------------------------------------------- -#define LOCAL_COORD_MACRO_END \ - } \ -} - -//--------------------------------------------------------------- -#define SHAPE_FUN_MACRO_BEGIN \ - for( int gaussId = 0 ; gaussId < _my_nb_gauss ; gaussId++ ) \ - { \ - double* funValue = &_my_function_value[ gaussId * _my_nb_ref ]; \ - const double* gc = &_my_gauss_coord[ gaussId * getGaussCoordDim() ]; - -//--------------------------------------------------------------- -#define SHAPE_FUN_MACRO_END \ - } - -#define CHECK_MACRO \ - if( ! aSatify ) \ - { \ - std::ostringstream stream; \ - stream << "Error in the gauss localization for the cell with type "; \ - stream << cellModel.getRepr(); \ - stream << " !!!"; \ - throw INTERP_KERNEL::Exception(stream.str().c_str()); \ - } - - -//--------------------------------------------------------------- -static bool IsEqual(double theLeft, double theRight) -{ - static double EPS = 1.0E-3; - if(fabs(theLeft) + fabs(theRight) > EPS) - return fabs(theLeft-theRight)/(fabs(theLeft)+fabs(theRight)) < EPS; - return true; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////// -// GAUSS INFO CLASS // -//////////////////////////////////////////////////////////////////////////////////////////////// - -/*! - * Constructor of the GaussInfo - */ -GaussInfo::GaussInfo( NormalizedCellType theGeometry, - const DataVector& theGaussCoord, - int theNbGauss, - const DataVector& theReferenceCoord, - int theNbRef ) : - _my_geometry(theGeometry), - _my_nb_gauss(theNbGauss), - _my_gauss_coord(theGaussCoord), - _my_nb_ref(theNbRef), - _my_reference_coord(theReferenceCoord) -{ - - //Allocate shape function values - _my_function_value.resize( _my_nb_gauss * _my_nb_ref ); -} - -/*! - * Destructor - */ -GaussInfo::~GaussInfo() -{ -} - -/*! - * Return dimension of the gauss coordinates - */ -int GaussInfo::getGaussCoordDim() const -{ - if( _my_nb_gauss ) - { - return _my_gauss_coord.size()/_my_nb_gauss; - } - else - { - return 0; - } -} - -/*! - * Return dimension of the reference coordinates - */ -int GaussInfo::getReferenceCoordDim() const -{ - if( _my_nb_ref ) - { - return _my_reference_coord.size()/_my_nb_ref; - } - else - { - return 0; - } -} - -/*! - * Return type of the cell. - */ -NormalizedCellType GaussInfo::getCellType() const -{ - return _my_geometry; -} - -/*! - * Return Nb of the gauss points. - */ -int GaussInfo::getNbGauss() const -{ - return _my_nb_gauss; -} - -/*! - * Return Nb of the reference coordinates. - */ -int GaussInfo::getNbRef() const -{ - return _my_nb_ref; -} - -/*! - * Check coordinates - */ -bool GaussInfo::isSatisfy() -{ - - bool anIsSatisfy = ((_my_local_nb_ref == _my_nb_ref) && (_my_local_ref_dim == getReferenceCoordDim())); - //Check coordinates - if(anIsSatisfy) - { - for( int refId = 0; refId < _my_local_nb_ref; refId++ ) - { - double* refCoord = &_my_reference_coord[ refId*_my_local_ref_dim ]; - double* localRefCoord = &_my_local_reference_coord[ refId*_my_local_ref_dim ]; - bool anIsEqual = false; - for( int dimId = 0; dimId < _my_local_ref_dim; dimId++ ) - { - anIsEqual = IsEqual( localRefCoord[dimId], refCoord[dimId]); - if(!anIsEqual ) - { - return false; - } - } - } - } - return anIsSatisfy; -} - -std::vector GaussInfo::NormalizeCoordinatesIfNecessary(NormalizedCellType ct, int inputDim, const std::vector& inputArray) -{ - std::size_t sz(inputArray.size()),dim((std::size_t)inputDim); - if(dim==0) - throw INTERP_KERNEL::Exception("GaussInfo::NormalizeCoordinatesIfNecessary : invalid dimension ! Must be !=0 !"); - if(sz%dim!=0) - throw INTERP_KERNEL::Exception("GaussInfo::NormalizeCoordinatesIfNecessary : invalid input array ! Inconsistent with the given dimension !"); - const CellModel& cm(CellModel::GetCellModel(ct)); - std::size_t baseDim((std::size_t)cm.getDimension()); - if(baseDim==dim) - return inputArray; - std::size_t nbOfItems(sz/dim); - std::vector ret(nbOfItems*baseDim); - if(baseDim>dim) - { - for(std::size_t i=0;igetCellType() == theGeometry ) - { - break; - } - } - - DataVector aGaussCoord; - for(int i = 0 ; i < theNbGauss*coordDim; i++ ) - aGaussCoord.push_back(theGaussCoord[i]); - - DataVector aReferenceCoord; - for(int i = 0 ; i < theNbRef*coordDim; i++ ) - aReferenceCoord.push_back(theReferenceCoord[i]); - - - GaussInfo* info = new GaussInfo( theGeometry, aGaussCoord, theNbGauss, aReferenceCoord, theNbRef); - info->initLocalInfo(); - - //If info with cell type doesn't exist add it - if( it == _my_gauss_info.end() ) - { - _my_gauss_info.push_back(info); - - // If information exists, update it - } - else - { - int index = std::distance(_my_gauss_info.begin(),it); - delete (*it); - _my_gauss_info[index] = info; - } -} - - -/*! - * Calculate gauss points coordinates - */ -double* GaussCoords::calculateCoords( NormalizedCellType theGeometry, - const double *theNodeCoords, - const int theSpaceDim, - const int *theIndex) -{ - const GaussInfo *info = getInfoGivenCellType(theGeometry); - int nbCoords = theSpaceDim * info->getNbGauss(); - double *aCoords = new double[nbCoords]; - calculateCoordsAlg(info,theNodeCoords,theSpaceDim,theIndex,aCoords); - return aCoords; -} - - -void GaussCoords::calculateCoords( NormalizedCellType theGeometry, const double *theNodeCoords, const int theSpaceDim, const int *theIndex, double *result) -{ - const GaussInfo *info = getInfoGivenCellType(theGeometry); - calculateCoordsAlg(info,theNodeCoords,theSpaceDim,theIndex,result); -} - -void GaussCoords::calculateCoordsAlg(const GaussInfo *info, const double* theNodeCoords, const int theSpaceDim, const int *theIndex, double *result) -{ - int aConn = info->getNbRef(); - - int nbCoords = theSpaceDim * info->getNbGauss(); - std::fill(result,result+nbCoords,0.); - - for( int gaussId = 0; gaussId < info->getNbGauss(); gaussId++ ) - { - double *coord=result+gaussId*theSpaceDim; - const double *function=info->getFunctionValues(gaussId); - for ( int connId = 0; connId < aConn ; connId++ ) - { - const double* nodeCoord = theNodeCoords + (theIndex[connId]*theSpaceDim); - for( int dimId = 0; dimId < theSpaceDim; dimId++ ) - coord[dimId] += nodeCoord[dimId]*function[connId]; - } - } -} - -const GaussInfo *GaussCoords::getInfoGivenCellType(NormalizedCellType cellType) -{ - GaussInfoVector::const_iterator it = _my_gauss_info.begin(); - //Try to find gauss localization info - for( ; it != _my_gauss_info.end() ; it++ ) - if( (*it)->getCellType()==cellType) - return (*it); - throw INTERP_KERNEL::Exception("Can't find gauss localization information !"); -} diff --git a/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx b/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx deleted file mode 100644 index 12c706e82..000000000 --- a/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPKERNELGAUSSCOORDS_HXX__ -#define __INTERPKERNELGAUSSCOORDS_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - typedef std::vector DataVector; - typedef std::vector IndexVector; - - //Class to store Gauss Points information - class GaussInfo - { - public: - INTERPKERNEL_EXPORT GaussInfo( NormalizedCellType theGeometry, - const DataVector& theGaussCoord, - int theNbGauss, - const DataVector& theReferenceCoord, - int theNbRef - ); - INTERPKERNEL_EXPORT ~GaussInfo(); - - INTERPKERNEL_EXPORT NormalizedCellType getCellType() const; - - INTERPKERNEL_EXPORT int getGaussCoordDim() const; - INTERPKERNEL_EXPORT int getReferenceCoordDim() const; - - INTERPKERNEL_EXPORT int getNbGauss() const; - INTERPKERNEL_EXPORT int getNbRef() const; - - INTERPKERNEL_EXPORT const double* getFunctionValues( const int theGaussId ) const; - - INTERPKERNEL_EXPORT void initLocalInfo(); - - INTERPKERNEL_EXPORT static std::vector NormalizeCoordinatesIfNecessary(NormalizedCellType ct, int inputDim, const std::vector& inputArray); - - protected: - - bool isSatisfy(); - - void point1Init(); - - //1D - void seg2Init(); - void seg3Init(); - - //2D - void tria3aInit(); - void tria3bInit(); - void tria6aInit(); - void tria6bInit(); - void tria7aInit(); - - void quad4aInit(); - static void Quad4aInit(GaussInfo& obj) { obj.quad4aInit(); } - void quad4bInit(); - static void Quad4bInit(GaussInfo& obj) { obj.quad4bInit(); } - void quad4cInit(); - static void Quad4cInit(GaussInfo& obj) { obj.quad4cInit(); } - void quad4DegSeg2Init(); - static void Quad4DegSeg2Init(GaussInfo& obj) { obj.quad4DegSeg2Init(); } - void quad8aInit(); - void quad8bInit(); - void quad9aInit(); - - //3D - void tetra4aInit(); - void tetra4bInit(); - void tetra10aInit(); - void tetra10bInit(); - - void pyra5aInit(); - void pyra5bInit(); - void pyra13aInit(); - void pyra13bInit(); - - void penta6aInit(); - static void Penta6aInit(GaussInfo& obj) { obj.penta6aInit(); } - void penta6bInit(); - static void Penta6bInit(GaussInfo& obj) { obj.penta6bInit(); } - void penta6DegTria3aInit(); - static void Penta6DegTria3aInit(GaussInfo& obj) { obj.penta6DegTria3aInit(); } - void penta6DegTria3bInit(); - static void Penta6DegTria3bInit(GaussInfo& obj) { obj.penta6DegTria3bInit(); } - - void penta15aInit(); - static void Penta15aInit(GaussInfo& obj) { obj.penta15aInit(); } - void penta15bInit(); - static void Penta15bInit(GaussInfo& obj) { obj.penta15bInit(); } - - void hexa8aInit(); - static void Hexa8aInit(GaussInfo& obj) { obj.hexa8aInit(); } - void hexa8bInit(); - static void Hexa8bInit(GaussInfo& obj) { obj.hexa8bInit(); } - void hexa8DegQuad4aInit(); - static void Hexa8DegQuad4aInit(GaussInfo& obj) { obj.hexa8DegQuad4aInit(); } - void hexa8DegQuad4bInit(); - static void Hexa8DegQuad4bInit(GaussInfo& obj) { obj.hexa8DegQuad4bInit(); } - void hexa8DegQuad4cInit(); - static void Hexa8DegQuad4cInit(GaussInfo& obj) { obj.hexa8DegQuad4cInit(); } - void hexa20aInit(); - void hexa20bInit(); - void hexa27aInit(); - - private: - //INFORMATION from MEDMEM - NormalizedCellType _my_geometry; //Cell type - - int _my_nb_gauss; //Nb of the gauss points for element - DataVector _my_gauss_coord; //Gauss coordinates - - int _my_nb_ref; //Nb of the nodes for element: - //NORM_SEG2 - 2 - //NORM_SEG3 - 3 - //NORM_TRI3 - 3 - //............. - - DataVector _my_reference_coord; //Reference coordinates - - //LOCAL INFORMATION - DataVector _my_local_reference_coord; //Vector to store reference coordinates - int _my_local_ref_dim; //Dimension of the local reference coordinates: - // (x) - 1D case - // (x, y) - 2D case - // (x, y, z) - 3D case - int _my_local_nb_ref; //Nb of the local reference coordinates - - DataVector _my_function_value; //Shape Function values - }; - - - //Class for calculation of the coordinates of the gauss points - class GaussCoords - { - public: - - INTERPKERNEL_EXPORT GaussCoords(); - INTERPKERNEL_EXPORT ~GaussCoords(); - - INTERPKERNEL_EXPORT void addGaussInfo( NormalizedCellType theGeometry, - int coordDim, - const double* theGaussCoord, - int theNbGauss, - const double* theReferenceCoord, - int theNbRef); - - INTERPKERNEL_EXPORT double* calculateCoords( NormalizedCellType theGeometry, - const double* theNodeCoords, - const int theSpaceDim, - const int* theIndex); - - INTERPKERNEL_EXPORT void calculateCoords( NormalizedCellType theGeometry, - const double* theNodeCoords, - const int theSpaceDim, - const int* theIndex, - double *result); - private: - const GaussInfo *getInfoGivenCellType(NormalizedCellType cellType); - void calculateCoordsAlg(const GaussInfo *info, const double* theNodeCoords, const int theSpaceDim, const int *theIndex, - double *result); - private: - typedef std::vector GaussInfoVector; - GaussInfoVector _my_gauss_info; - }; -} -#endif //INTERPKERNELGAUSSCOORDS diff --git a/medtool/src/INTERP_KERNEL/GenMathFormulae.hxx b/medtool/src/INTERP_KERNEL/GenMathFormulae.hxx deleted file mode 100644 index a53aacfca..000000000 --- a/medtool/src/INTERP_KERNEL/GenMathFormulae.hxx +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __GENMATHFORMULAE_HXX__ -#define __GENMATHFORMULAE_HXX__ - -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - /*! - * This method computes eigenvalues of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: - * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, - * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz - * This method returns the 3 eigenvalues in 'eigenVals'. - */ - void computeEigenValues6(const double *matrix, double *eigenVals) - { - double tr=(matrix[0]+matrix[1]+matrix[2])/3.; - double K[6]={matrix[0]-tr,matrix[1]-tr,matrix[2]-tr,matrix[3],matrix[4],matrix[5]}; - double q=(K[0]*K[1]*K[2]+2.*K[4]*K[5]*K[3]-K[0]*K[4]*K[4]-K[2]*K[3]*K[3]-K[1]*K[5]*K[5])/2.; - double p=K[0]*K[0]+K[1]*K[1]+K[2]*K[2]+2*(K[3]*K[3]+K[4]*K[4]+K[5]*K[5]); - p/=6.; - double sqp=sqrt(p); - double tmp=p*sqp; - double phi; - if(fabs(q)<=fabs(tmp)) - phi=1./3.*acos(q/tmp); - else - phi=0.; - if(phi<0.) - phi+=M_PI/3.; - eigenVals[0]=tr+2.*sqp*cos(phi); - eigenVals[1]=tr-sqp*(cos(phi)+sqrt(3.)*sin(phi)); - eigenVals[2]=tr-sqp*(cos(phi)-sqrt(3.)*sin(phi)); - } - - /*! - * This method computes one eigenvector of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: - * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, - * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz - * This method returns the eigenvector of the corresponding eigenvalue in 'eigenVal'. The returned eigenValue is normalized. - */ - void computeEigenVectorForEigenValue6(const double *matrix, double eigenVal, double eps, double *eigenVector) - { - //if(fabs(eigenVal)>eps) - { - const double m9[9]={matrix[0]-eigenVal,matrix[3],matrix[5],matrix[3],matrix[1]-eigenVal,matrix[4],matrix[5],matrix[4],matrix[2]-eigenVal}; - for(int i=0;i<3;i++) - { - double w[9]={m9[0+3*i],m9[1+3*i],m9[2+3*i],m9[0+(3*(i+1))%6],m9[1+(3*(i+1))%6],m9[2+(3*(i+1))%6],1.,1.,1.}; - double det=w[0]*w[4]*w[8]+w[1]*w[5]*w[6]+w[2]*w[3]*w[7]-w[0]*w[5]*w[7]-w[1]*w[3]*w[8]-w[2]*w[4]*w[6]; - if(fabs(det)>eps) - { - eigenVector[0]=(w[1]*w[5]-w[4]*w[2])/det; - eigenVector[1]=(w[2]*w[3]-w[0]*w[5])/det; - eigenVector[2]=(w[0]*w[4]-w[1]*w[3])/det; - double norm=sqrt(eigenVector[0]*eigenVector[0]+eigenVector[1]*eigenVector[1]+eigenVector[2]*eigenVector[2]); - eigenVector[0]/=norm; - eigenVector[1]/=norm; - eigenVector[2]/=norm; - return; - } - } - } - //else - { - eigenVector[0]=0.; - eigenVector[1]=0.; - eigenVector[2]=0.; - return; - } - //throw INTERP_KERNEL::Exception("computeEigenVector : Do not succed in finding eigen vector !"); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx deleted file mode 100644 index af84365f3..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" - -using namespace INTERP_KERNEL; - -IteratorOnComposedEdge::IteratorOnComposedEdge():_list_handle(0) -{ -} - -IteratorOnComposedEdge::IteratorOnComposedEdge(ComposedEdge *compEdges):_list_handle(compEdges->getListBehind()) -{ - first(); -} - -void IteratorOnComposedEdge::operator=(const IteratorOnComposedEdge& other) -{ - _deep_it=other._deep_it; - _list_handle=other._list_handle; -} - -void IteratorOnComposedEdge::last() -{ - _deep_it=_list_handle->end(); - _deep_it--; -} - -void IteratorOnComposedEdge::nextLoop() -{ - _deep_it++; - if(_deep_it==_list_handle->end()) - first(); -} - -void IteratorOnComposedEdge::previousLoop() -{ - if(_deep_it!=_list_handle->begin()) - _deep_it--; - else - last(); -} - -bool IteratorOnComposedEdge::goToNextInOn(bool direction, int& i, int nbMax) -{ - TypeOfEdgeLocInPolygon loc=current()->getLoc(); - if(direction) - { - while(loc==FULL_OUT_1 && igetLoc(); - } - if(i==nbMax) - return false; - return true; - } - else - { - while(loc==FULL_OUT_1 && igetLoc(); - } - if(i==nbMax) - return false; - while(loc!=FULL_OUT_1 && igetLoc(); - } - nextLoop(); i--; - return true; - } -} - -void IteratorOnComposedEdge::assignMySelfToAllElems(ComposedEdge *elems) -{ - std::list *myList=elems->getListBehind(); - for(std::list::iterator iter=myList->begin();iter!=myList->end();iter++) - (*iter)->getIterator()=(*this); -} - -void IteratorOnComposedEdge::insertElemEdges(ComposedEdge *elems, bool changeMySelf) -{ - std::list *myListToInsert=elems->getListBehind(); - std::list::iterator iter=myListToInsert->begin(); - *_deep_it=*iter; - _deep_it++; - iter++; - int sizeOfMyList=myListToInsert->size(); - _list_handle->insert(_deep_it,iter,myListToInsert->end()); - if(!changeMySelf) - { - for(int i=0;i -#include -#include - -namespace INTERP_KERNEL -{ - class Edge; - class Node; - class Bounds; - - class ComposedEdge; - class ElementaryEdge; - - /*! - * Asumption is done with this iterator that we iterate on a container containing more than one edge. - */ - class IteratorOnComposedEdge - { - friend class ComposedEdge; - friend class ElementaryEdge; - friend class QuadraticPolygon; - public: - INTERPKERNEL_EXPORT IteratorOnComposedEdge(); - INTERPKERNEL_EXPORT IteratorOnComposedEdge(ComposedEdge *compEdges); - INTERPKERNEL_EXPORT bool isValid() const { return _list_handle!=0; } - INTERPKERNEL_EXPORT void operator=(const IteratorOnComposedEdge& other); - INTERPKERNEL_EXPORT void first() { _deep_it=_list_handle->begin(); } - INTERPKERNEL_EXPORT void next() { _deep_it++; } - INTERPKERNEL_EXPORT void last(); - INTERPKERNEL_EXPORT void nextLoop(); - INTERPKERNEL_EXPORT void previousLoop(); - INTERPKERNEL_EXPORT bool finished() const { return _deep_it==_list_handle->end(); } - INTERPKERNEL_EXPORT bool goToNextInOn(bool direction, int& i, int nbMax); - INTERPKERNEL_EXPORT ElementaryEdge *current() { return *_deep_it; } - INTERPKERNEL_EXPORT void assignMySelfToAllElems(ComposedEdge *elems); - INTERPKERNEL_EXPORT void insertElemEdges(ComposedEdge *elems, bool changeMySelf); - private: - std::list::iterator _deep_it; - std::list* _list_handle; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx deleted file mode 100644 index 72e4dec32..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DBounds.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DNode.hxx" - -using namespace INTERP_KERNEL; - -const double& Bounds::operator[](int i) const -{ - switch(i) - { - case 0: - return _x_min; - case 1: - return _x_max; - case 2: - return _y_min; - case 3: - return _y_max; - } - throw Exception("internal error occurs !"); -} - -double &Bounds::operator[](int i) -{ - switch(i) - { - case 0: - return _x_min; - case 1: - return _x_max; - case 2: - return _y_min; - case 3: - return _y_max; - } - throw Exception("internal error occurs !"); -} - -double Bounds::getDiagonal() const -{ - double a=_x_max-_x_min; - double b=_y_max-_y_min; - return sqrt(a*a+b*b); -} - -/*! - * See Node::applySimilarity to see signification of params. - */ -void Bounds::applySimilarity(double xBary, double yBary, double dimChar) -{ - _x_min=(_x_min-xBary)/dimChar; - _x_max=(_x_max-xBary)/dimChar; - _y_min=(_y_min-yBary)/dimChar; - _y_max=(_y_max-yBary)/dimChar; -} - -/*! - * See Node::unApplySimilarity to see signification of params. - */ -void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - _x_min=_x_min*dimChar+xBary; - _x_max=_x_max*dimChar+xBary; - _y_min=_y_min*dimChar+yBary; - _y_max=_y_max*dimChar+yBary; -} - -void Bounds::getBarycenter(double& xBary, double& yBary) const -{ - xBary=(_x_min+_x_max)/2.; - yBary=(_y_max+_y_min)/2.; -} - -void Bounds::prepareForAggregation() -{ - _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200; -} - -/*! - * Given an arc defined by 'center', 'radius' and 'intrcptArcDelta' in radian, returns (by outputs intrcptArcAngle0 and intrcptArcDelta) - * the intercepted angle of 'this' from 'center' point of view. - * If diagonal of 'this' is the same order of 2*radius, intrcptArcAngle0 and intrcptArcDelta remains unchanged. - * @param center IN parameter. - * @param radius IN parameter. - * @param [out] intrcptArcAngle0 OUT parameter. - * @param [out] intrcptArcDelta OUT parameter. - */ -void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const -{ - double diag=getDiagonal(); - if(diag<2.*radius) - { - double v1[2],v2[2],w1[2],w2[2]; - v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1]; - w1[0]=v1[0]; w1[1]=_y_min-center[1]; w2[0]=v2[0]; w2[1]=_y_max-center[1]; - double delta1=EdgeArcCircle::SafeAsin(v1[0]*v2[1]-v1[1]*v2[0]); - double delta2=EdgeArcCircle::SafeAsin(w1[0]*w2[1]-w1[1]*w2[0]); - double tmp; - if(fabs(delta1)>fabs(delta2)) - { - intrcptArcDelta=delta1; - intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp); - } - else - { - intrcptArcDelta=delta2; - intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp); - } - } -} - -double Bounds::fitXForXFigD(double val, int res) const -{ - double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; - double ret=val-(_x_max+_x_min)/2.+delta; - delta=11.1375*res/(2.*delta); - return ret*delta; -} - -double Bounds::fitYForXFigD(double val, int res) const -{ - double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; - double ret=(_y_max+_y_min)/2.-val+delta; - delta=11.1375*res/(2.*delta); - return ret*delta; -} - -Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const -{ - if( (other._x_min > _x_max+QUADRATIC_PLANAR::_precision) || (other._x_max < _x_min-QUADRATIC_PLANAR::_precision) || (other._y_min > _y_max+QUADRATIC_PLANAR::_precision) - || (other._y_max < _y_min-QUADRATIC_PLANAR::_precision) ) - return 0; - if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) ) - { - return new Bounds(std::max(_x_min-QUADRATIC_PLANAR::_precision,other._x_min), - std::min(_x_max+QUADRATIC_PLANAR::_precision,other._x_max), - std::max(_y_min-QUADRATIC_PLANAR::_precision,other._y_min), - std::min(_y_max+QUADRATIC_PLANAR::_precision,other._y_max));//In approx cases. - } - else - return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); -} - -Bounds *Bounds::amIIntersectingWith(const Bounds& other) const -{ - if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) ) - return 0; - return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); -} - -Position Bounds::where(double x, double y) const -{ - if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) - return IN; - else - return OUT; -} - -Position Bounds::nearlyWhere(double x, double y) const -{ - bool thinX=Node::areDoubleEquals(_x_min,_x_max); - bool thinY=Node::areDoubleEquals(_y_min,_y_max); - if(!thinX) - { - if((Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max)) && ((y<_y_max+QUADRATIC_PLANAR::_precision) && (y>_y_min-QUADRATIC_PLANAR::_precision))) - return ON_BOUNDARY_POS; - } - else - if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x)) - return OUT; - if(!thinY) - { - if((Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max)) && ((x<_x_max+QUADRATIC_PLANAR::_precision) && (x>_x_min-QUADRATIC_PLANAR::_precision))) - return ON_BOUNDARY_POS; - } - else - if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y)) - return OUT; - if(thinX && thinY) - return ON_BOUNDARY_POS; - if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) - return IN; - else - return OUT; -} - -void Bounds::aggregate(const Bounds& other) -{ - _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max); - _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max); -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx deleted file mode 100644 index 914391a9f..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DBOUNDS_HXX__ -#define __INTERPKERNELGEO2DBOUNDS_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - /*! - * Relative LOC - */ - typedef enum - { - IN = 0, - OUT = 1, - ON_BOUNDARY_POS = 2, - ON_BOUNDARY_NEG = 3 - } Position; - - class INTERPKERNEL_EXPORT Bounds - { - public: - Bounds():_x_min(0.),_x_max(0.),_y_min(0.),_y_max(0.) { } - double &operator[](int i); - const double& operator[](int i) const; - double getXMin() const { return _x_min; } - double getXMax() const { return _x_max; } - double getYMin() const { return _y_min; } - double getYMax() const { return _y_max; } - double getDiagonal() const; - void getBarycenter(double& xBary, double& yBary) const; - void applySimilarity(double xBary, double yBary, double dimChar); - void unApplySimilarity(double xBary, double yBary, double dimChar); - Bounds& operator=(const Bounds& other) { _x_min=other._x_min; _x_max=other._x_max; _y_min=other._y_min; _y_max=other._y_max; return *this; } - Bounds(double xMin, double xMax, double yMin, double yMax):_x_min(xMin),_x_max(xMax),_y_min(yMin),_y_max(yMax) { } - void setValues(double xMin, double xMax, double yMin, double yMax) { _x_min=xMin; _x_max=xMax; _y_min=yMin; _y_max=yMax; } - void prepareForAggregation(); - void getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const; - int fitXForXFig(double val, int res) const { return (int)fitXForXFigD(val,res); } - int fitYForXFig(double val, int res) const { return (int)fitYForXFigD(val,res); } - double fitXForXFigD(double val, int res) const; - double fitYForXFigD(double val, int res) const; - Bounds *nearlyAmIIntersectingWith(const Bounds& other) const; - Bounds *amIIntersectingWith(const Bounds& other) const; - //! No approximations. - Position where(double x, double y) const; - //! Idem where method but with approximations. - Position nearlyWhere(double x, double y) const; - void aggregate(const Bounds& other); - double getCaracteristicDim() const { return std::max(_x_max-_x_min,_y_max-_y_min); } - protected: - double _x_min; - double _x_max; - double _y_min; - double _y_max; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx deleted file mode 100644 index 9c310bbca..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeInfLin.hxx" -#include "InterpKernelException.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -ComposedEdge::ComposedEdge(const ComposedEdge& other) -{ - for(std::list::const_iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++) - _sub_edges.push_back((*iter)->clone()); -} - -ComposedEdge::~ComposedEdge() -{ - clearAll(_sub_edges.begin()); -} - -void ComposedEdge::setValueAt(int i, Edge *e, bool direction) -{ - std::list::iterator it=_sub_edges.begin(); - for(int j=0;jgetPtr()==_b1->getPtr();} - - ElementaryEdge *_b1; -}; -/*! \endcond */ - -double ComposedEdge::getCommonLengthWith(const ComposedEdge& other) const -{ - double ret=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - if(find_if(other._sub_edges.begin(),other._sub_edges.end(),AbsEdgeCmp(*iter))!=other._sub_edges.end()) - { - const ElementaryEdge *tmp=static_cast(*iter); - ret+=tmp->getCurveLength(); - } - } - return ret; -} - -void ComposedEdge::clear() -{ - clearAll(_sub_edges.begin()); - _sub_edges.clear(); -} - -void ComposedEdge::pushBack(Edge *edge, bool direction) -{ - _sub_edges.push_back(new ElementaryEdge(edge,direction)); -} - -void ComposedEdge::pushBack(ElementaryEdge *elem) -{ - _sub_edges.push_back(elem); -} - -void ComposedEdge::pushBack(ComposedEdge *elem) -{ - std::list *elemsOfElem=elem->getListBehind(); - _sub_edges.insert(_sub_edges.end(),elemsOfElem->begin(),elemsOfElem->end()); -} - -ElementaryEdge *ComposedEdge::operator[](int i) const -{ - std::list::const_iterator iter=_sub_edges.begin(); - for(int ii=0;ii::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->reverse(); -} - -bool ComposedEdge::presenceOfOn() const -{ - bool ret=false; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) - ret=((*iter)->getLoc()==FULL_ON_1); - return ret; -} - -bool ComposedEdge::presenceOfQuadraticEdge() const -{ - bool ret=false; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) - { - Edge *e=(*iter)->getPtr(); - if(e) - ret=dynamic_cast(e)!=0; - } - return ret; -} - -void ComposedEdge::initLocations() const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->initLocations(); -} - -/** - * Reset the status of all edges (OUT, IN, ON) because they were potentially assigned - * by the previous candidate processing. - */ -void ComposedEdge::InitLocationsWithOther(const ComposedEdge& first, const ComposedEdge& other) -{ - std::set s1,s2; - for(std::list::const_iterator it1=first._sub_edges.begin();it1!=first._sub_edges.end();it1++) - s1.insert((*it1)->getPtr()); - for(std::list::const_iterator it2=other._sub_edges.begin();it2!=other._sub_edges.end();it2++) - s2.insert((*it2)->getPtr()); - first.initLocations(); - other.initLocations(); - std::vector s3; - std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector >(s3)); - for(std::vector::const_iterator it3=s3.begin();it3!=s3.end();it3++) - (*it3)->declareOn(); -} - -ComposedEdge *ComposedEdge::clone() const -{ - return new ComposedEdge(*this); -} - -bool ComposedEdge::isNodeIn(Node *n) const -{ - bool ret=false; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) - ret=(*iter)->isNodeIn(n); - return ret; -} - -/*! - * This method computes the area of 'this'. - * By definition : - * \f[ - * Area=\int_{Polygon} dS - * \f] - * Thanks to Green's theorem we have. - * \f[ - * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}ydx=\sum_{0 \leq i < nb of edges} AreaOfZone_{Edge_{i}} - * \f] - * Where \f$ AreaOfZone_{i} \f$ is computed virtually by INTERP_KERNEL::Edge::getAreaOfZone with following formula : - * \f[ - * AreaOfZone_{i}=\int_{Edge_{i}} -ydx - * \f] - */ -double ComposedEdge::getArea() const -{ - double ret=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - ret+=(*iter)->getAreaOfZone(); - return ret; -} - -double ComposedEdge::getPerimeter() const -{ - double ret=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - ret+=(*iter)->getCurveLength(); - return ret; -} - -double ComposedEdge::getHydraulicDiameter() const -{ - return 4*fabs(getArea())/getPerimeter(); -} - -/*! - * This method computes barycenter of 'this' by returning xG in bary[0] and yG in bary[1]. - * By definition : - * \f[ - * Area \cdot x_{G}=\int_{Polygon} x \cdot dS - * \f] - * \f[ - * Area \cdot y_{G}=\int_{Polygon} y \cdot dS - * \f] - * Thanks to Green's theorem we have. - * \f[ - * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}yxdx - * \f] - * \f[ - * \int_{Polygon} y \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}\frac{y^{2}}{2}dx - * \f] - * Area is computed using the same principle than described in INTERP_KERNEL::ComposedEdge::getArea method. - * \f$ -\int_{Edge_{i}}yxdx \f$ and \f$ -\int_{Edge_{i}}\frac{y^{2}}{2}dx \f$ are computed virtually with INTERP_KERNEL::Edge::getBarycenterOfZone. - */ -void ComposedEdge::getBarycenter(double *bary) const -{ - bary[0]=0.; - bary[1]=0.; - double area=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getBarycenterOfZone(bary); - area+=(*iter)->getAreaOfZone(); - } - bary[0]/=area; - bary[1]/=area; -} - -/*! - * Idem ComposedEdge::getBarycenter except that the special case where _sub_edges==1 is dealt here. - */ -void ComposedEdge::getBarycenterGeneral(double *bary) const -{ - if(_sub_edges.empty()) - throw INTERP_KERNEL::Exception("ComposedEdge::getBarycenterGeneral called on an empty polygon !"); - if(_sub_edges.size()>2) - return getBarycenter(bary); - double w; - _sub_edges.back()->getBarycenter(bary,w); -} - -double ComposedEdge::normalizeMe(double& xBary, double& yBary) -{ - Bounds b; - b.prepareForAggregation(); - fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity(xBary,yBary,dimChar); - return dimChar; -} - -double ComposedEdge::normalize(ComposedEdge *other, double& xBary, double& yBary) -{ - Bounds b; - b.prepareForAggregation(); - fillBounds(b); - other->fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity(xBary,yBary,dimChar); - other->applyGlobalSimilarity(xBary,yBary,dimChar); - return dimChar; -} - -/*! - * This method operates the opposite operation than ComposedEdge::applyGlobalSimilarity. - */ -void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact) -{ - initNodeHitStatus(); - other.initNodeHitStatus(); - unApplySimilarityOnMyNodes(xBary,yBary,fact); - other.unApplySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,fact); - initEdgeHitStatus(); - other.initEdgeHitStatus(); - unApplySimilarityOnMyEdges(xBary,yBary,fact); - other.unApplySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,fact); -} - -double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary) -{ - Bounds b; - b.prepareForAggregation(); - fillBounds(b); - other->fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity2(other,xBary,yBary,dimChar); - return dimChar; -} - -void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - stream.precision(10); - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->dumpInXfigFile(stream,resolution,box); -} - -Node *ComposedEdge::getEndNode() const -{ - return _sub_edges.back()->getEndNode(); -} - -Node *ComposedEdge::getStartNode() const -{ - return _sub_edges.front()->getStartNode(); -} - -bool ComposedEdge::changeEndNodeWith(Node *node) const -{ - return _sub_edges.back()->changeEndNodeWith(node); -} - -bool ComposedEdge::changeStartNodeWith(Node *node) const -{ - return _sub_edges.front()->changeStartNodeWith(node); -} - -void ComposedEdge::fillBounds(Bounds& output) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->fillBounds(output); -} - -/*! - * \b WARNING : applies similarity \b ONLY on edges without any change on Nodes. To perform a global similarity call applyGlobalSimilarity. - */ -void ComposedEdge::applySimilarity(double xBary, double yBary, double dimChar) -{ - for(std::list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); -} - -/*! - * Perform Similarity transformation on all elements of this Nodes and Edges. - */ -void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimChar) -{ - std::set allNodes; - getAllNodes(allNodes); - for(std::set::iterator iter=allNodes.begin();iter!=allNodes.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); - for(std::list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); -} - -/*! - * Perform Similarity transformation on all elements of this Nodes and Edges on 'this' and 'other'. - * Nodes can be shared between 'this' and 'other'. - */ -void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar) -{ - initNodeHitStatus(); - other->initNodeHitStatus(); - applySimilarityOnMyNodes(xBary,yBary,dimChar); - other->applySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,dimChar); - initEdgeHitStatus(); - other->initEdgeHitStatus(); - applySimilarityOnMyEdges(xBary,yBary,dimChar); - other->applySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,dimChar); -} - -/*! - * This method append to param 'partConsidered' the part of length of subedges IN or ON. - * @param partConsidered INOUT param. - */ -void ComposedEdge::dispatchPerimeter(double& partConsidered) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); - if(loc==FULL_IN_1 || loc==FULL_ON_1) - partConsidered+=(*iter)->getCurveLength(); - } -} - -/*! - * Idem dispatchPerimeterExcl except that when a subedge is declared as ON this subedge is counted in commonPart. - */ -void ComposedEdge::dispatchPerimeterExcl(double& partConsidered, double& commonPart) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); - if(loc==FULL_IN_1) - partConsidered+=(*iter)->getCurveLength(); - if(loc==FULL_ON_1) - commonPart+=(*iter)->getCurveLength(); - } -} - -void ComposedEdge::getAllNodes(std::set& output) const -{ - std::list::const_iterator iter=_sub_edges.begin(); - for(;iter!=_sub_edges.end();iter++) - (*iter)->getAllNodes(output); -} - -void ComposedEdge::initNodeHitStatus() const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->initHitStatus(); - (*iter)->getEndNode()->initHitStatus(); - } -} - -void ComposedEdge::applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->hitMeAlone(xBary,yBary,dimChar); - (*iter)->getEndNode()->hitMeAlone(xBary,yBary,dimChar); - } -} - -void ComposedEdge::unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->unHitMeAlone(xBary,yBary,dimChar); - (*iter)->getEndNode()->unHitMeAlone(xBary,yBary,dimChar); - } -} - -void ComposedEdge::applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->hitMeAfter(xBary,yBary,dimChar); - (*iter)->getEndNode()->hitMeAfter(xBary,yBary,dimChar); - } -} - -void ComposedEdge::unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->unHitMeAfter(xBary,yBary,dimChar); - (*iter)->getEndNode()->unHitMeAfter(xBary,yBary,dimChar); - } -} - -void ComposedEdge::initEdgeHitStatus() const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->initHitStatus(); -} - -void ComposedEdge::applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->hitMeAlone(xBary,yBary,dimChar); -} - -void ComposedEdge::unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->unHitMeAlone(xBary,yBary,dimChar); -} - -void ComposedEdge::applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->hitMeAfter(xBary,yBary,dimChar); -} - -void ComposedEdge::unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->unHitMeAfter(xBary,yBary,dimChar); -} - -void ComposedEdge::getBarycenter(double *bary, double& weigh) const -{ - weigh=0.; bary[0]=0.; bary[1]=0.; - double tmp1,tmp2[2]; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getBarycenter(tmp2,tmp1); - weigh+=tmp1; - bary[0]+=tmp1*tmp2[0]; - bary[1]+=tmp1*tmp2[1]; - } - bary[0]/=weigh; - bary[1]/=weigh; -} - -/*! - * This method makes the hypothesis that \a nodeToTest can be either IN or OUT. - * - * \sa ComposedEdge::isInOrOut2 - */ -bool ComposedEdge::isInOrOut(Node *nodeToTest) const -{ - Bounds b; b.prepareForAggregation(); - fillBounds(b); - if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT) - return false; - std::set< IntersectElement > inOutSwitch; - double ref(isInOrOutAlg(nodeToTest,inOutSwitch)); - bool ret(false); - for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++) - { - if((*iter4).getVal1()getLoc()==ON_1) - ret=!ret; - } - else - break; - } - return ret; -} - -/*! - * This method is close to ComposedEdge::isInOrOut behaviour except that here EPSILON is taken into account to detect if it is IN or OUT. - * If \a nodeToTest is close to an edge in \a this, true will be returned even if it is outside informatically from \a this. - * - * \sa ComposedEdge::isInOrOut - */ -bool ComposedEdge::isInOrOut2(Node *nodeToTest) const -{ - std::set< IntersectElement > inOutSwitch; - double ref(isInOrOutAlg(nodeToTest,inOutSwitch)); - bool ret(false); - for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++) - { - double val((*iter4).getVal1()); - if(fabs(val-ref)>=QUADRATIC_PLANAR::_precision) - { - if(valgetLoc()==ON_1) - ret=!ret; - } - else - break; - } - else - return true; - } - return ret; -} - -double ComposedEdge::isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement >& inOutSwitch) const -{ - // searching for e1 - std::set nodes; - getAllNodes(nodes); - std::set radialDistributionOfNodes; - std::set::const_iterator iter; - for(iter=nodes.begin();iter!=nodes.end();iter++) - radialDistributionOfNodes.insert(nodeToTest->getSlope(*(*iter))); - std::vector radialDistrib(radialDistributionOfNodes.begin(),radialDistributionOfNodes.end()); - radialDistributionOfNodes.clear(); - std::vector radialDistrib2(radialDistrib.size()); - copy(radialDistrib.begin()+1,radialDistrib.end(),radialDistrib2.begin()); - radialDistrib2.back()=M_PI+radialDistrib.front(); - std::vector radialDistrib3(radialDistrib.size()); - std::transform(radialDistrib2.begin(),radialDistrib2.end(),radialDistrib.begin(),radialDistrib3.begin(),std::minus()); - std::vector::iterator iter3=max_element(radialDistrib3.begin(),radialDistrib3.end()); - int i=iter3-radialDistrib3.begin(); - // ok for e1 - Let's go. - EdgeInfLin *e1=new EdgeInfLin(nodeToTest,radialDistrib[i]+radialDistrib3[i]/2.); - double ref=e1->getCharactValue(*nodeToTest); - for(std::list::const_iterator iter4=_sub_edges.begin();iter4!=_sub_edges.end();iter4++) - { - ElementaryEdge *val=(*iter4); - if(val) - { - Edge *e=val->getPtr(); - std::auto_ptr intersc(Edge::BuildIntersectorWith(e1,e)); - bool obviousNoIntersection,areOverlapped; - intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); // first parameter never used - if(obviousNoIntersection) - { - continue; - } - if(!areOverlapped) - { - std::list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); - for(std::list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) - if((*iter2).isIncludedByBoth()) - inOutSwitch.insert(*iter2); - } - //if overlapped we can forget - } - else - throw Exception("Invalid use of ComposedEdge::isInOrOutAlg : only one level supported !"); - } - e1->decrRef(); - return ref; -} - -/*bool ComposedEdge::isInOrOut(Node *aNodeOn, Node *nodeToTest) const -{ - - EdgeInfLin *e1=new EdgeInfLin(aNodeOn,nodeToTest); - double ref=e1->getCharactValue(*nodeToTest); - set< IntersectElement > inOutSwitch; - for(vector::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - ElementaryEdge *val=dynamic_cast(*iter); - if(val) - { - Edge *e=val->getPtr(); - auto_ptr intersc(Edge::buildIntersectorWith(e1,e)); - bool obviousNoIntersection,areOverlapped; - intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); - if(obviousNoIntersection) - { - continue; - } - if(!areOverlapped) - { - list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); - for(list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) - if((*iter2).isIncludedByBoth()) - inOutSwitch.insert(*iter2); - } - //if overlapped we can forget - } - else - throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !"); - } - e1->decrRef(); - bool ret=false; - for(set< IntersectElement >::iterator iter=inOutSwitch.begin();iter!=inOutSwitch.end();iter++) - { - if((*iter).getVal1()getLoc()==ON_1) - ret=!ret; - } - else - break; - } - return ret; -}*/ - -bool ComposedEdge::getDirection() const -{ - throw Exception("ComposedEdge::getDirection : no sense"); -} - -bool ComposedEdge::intresincEqCoarse(const Edge *other) const -{ - if(_sub_edges.size()!=1) - return false; - return _sub_edges.front()->intresincEqCoarse(other); -} - -void ComposedEdge::clearAll(std::list::iterator startToDel) -{ - for(std::list::iterator iter=startToDel;iter!=_sub_edges.end();iter++) - delete (*iter); -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx deleted file mode 100644 index f4c56fbac..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DCOMPOSEDNODE_HXX__ -#define __INTERPKERNELGEO2DCOMPOSEDNODE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - class Node; - class Edge; - class Bounds; - class ElementaryEdge; - class IteratorOnComposedEdge; - - /** - * A set of quadratic or linear edges, described mainly by their connectivity - * The set is assumed to be connected, but not necessarily closed (i.e. not necessarily forming a closed polygon). - * Some methods however requires a closed form. - */ - class ComposedEdge - { - friend class IteratorOnComposedEdge; - public: - INTERPKERNEL_EXPORT ComposedEdge() { } - INTERPKERNEL_EXPORT ComposedEdge(const ComposedEdge& other); - INTERPKERNEL_EXPORT ComposedEdge(int sz):_sub_edges(sz) { } - INTERPKERNEL_EXPORT static void Delete(ComposedEdge *pt) { delete pt; } - INTERPKERNEL_EXPORT static void SoftDelete(ComposedEdge *pt) { pt->_sub_edges.clear(); delete pt; } - INTERPKERNEL_EXPORT void reverse(); - INTERPKERNEL_EXPORT int recursiveSize() const { return (int)_sub_edges.size(); } - INTERPKERNEL_EXPORT bool presenceOfOn() const; - INTERPKERNEL_EXPORT bool presenceOfQuadraticEdge() const; - INTERPKERNEL_EXPORT void initLocations() const; - INTERPKERNEL_EXPORT static void InitLocationsWithOther(const ComposedEdge& first, const ComposedEdge& other); - INTERPKERNEL_EXPORT ComposedEdge *clone() const; - INTERPKERNEL_EXPORT bool isNodeIn(Node *n) const; - INTERPKERNEL_EXPORT double getArea() const; - INTERPKERNEL_EXPORT double getPerimeter() const; - INTERPKERNEL_EXPORT double getHydraulicDiameter() const; - INTERPKERNEL_EXPORT void getBarycenter(double *bary) const; - INTERPKERNEL_EXPORT void getBarycenterGeneral(double *bary) const; - INTERPKERNEL_EXPORT double normalizeMe(double& xBary, double& yBary); - INTERPKERNEL_EXPORT double normalize(ComposedEdge *other, double& xBary, double& yBary); - INTERPKERNEL_EXPORT double normalizeExt(ComposedEdge *other, double& xBary, double& yBary); - INTERPKERNEL_EXPORT void unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact); - INTERPKERNEL_EXPORT void fillBounds(Bounds& output) const; - INTERPKERNEL_EXPORT void applySimilarity(double xBary, double yBary, double dimChar); - INTERPKERNEL_EXPORT void applyGlobalSimilarity(double xBary, double yBary, double dimChar); - INTERPKERNEL_EXPORT void applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar); - INTERPKERNEL_EXPORT void dispatchPerimeter(double& partConsidered) const; - INTERPKERNEL_EXPORT void dispatchPerimeterExcl(double& partConsidered, double& commonPart) const; - INTERPKERNEL_EXPORT double dispatchPerimeterAdv(const ComposedEdge& father, std::vector& result) const; - INTERPKERNEL_EXPORT void getAllNodes(std::set& output) const; - INTERPKERNEL_EXPORT void initNodeHitStatus() const; - INTERPKERNEL_EXPORT void applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void initEdgeHitStatus() const; - INTERPKERNEL_EXPORT void applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; - INTERPKERNEL_EXPORT bool completed() const { return getEndNode()==getStartNode(); } - INTERPKERNEL_EXPORT void setValueAt(int i, Edge *e, bool direction=true); - INTERPKERNEL_EXPORT double getCommonLengthWith(const ComposedEdge& other) const; - INTERPKERNEL_EXPORT void clear(); - INTERPKERNEL_EXPORT bool empty() const { return _sub_edges.empty(); } - INTERPKERNEL_EXPORT ElementaryEdge *front() const { return _sub_edges.front(); } - INTERPKERNEL_EXPORT ElementaryEdge *back() const { return _sub_edges.back(); } - INTERPKERNEL_EXPORT void resize(int i) { _sub_edges.resize(i); } - INTERPKERNEL_EXPORT void pushBack(Edge *edge, bool direction=true); - INTERPKERNEL_EXPORT void pushBack(ElementaryEdge *elem); - INTERPKERNEL_EXPORT void pushBack(ComposedEdge *elem); - INTERPKERNEL_EXPORT int size() const { return (int)_sub_edges.size(); } - INTERPKERNEL_EXPORT ElementaryEdge *operator[](int i) const; - INTERPKERNEL_EXPORT Node *getEndNode() const; - INTERPKERNEL_EXPORT Node *getStartNode() const; - INTERPKERNEL_EXPORT bool changeEndNodeWith(Node *node) const; - INTERPKERNEL_EXPORT bool changeStartNodeWith(Node *node) const; - INTERPKERNEL_EXPORT void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - INTERPKERNEL_EXPORT bool isInOrOut(Node *nodeToTest) const; - INTERPKERNEL_EXPORT bool isInOrOut2(Node *nodeToTest) const; - INTERPKERNEL_EXPORT bool getDirection() const; - INTERPKERNEL_EXPORT bool intresincEqCoarse(const Edge *other) const; - private: - std::list* getListBehind() { return &_sub_edges; } - double isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement >& inOutSwitch) const; - protected: - ~ComposedEdge(); - private: - void clearAll(std::list::iterator startToDel); - protected: - std::list _sub_edges; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx deleted file mode 100644 index 166252287..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx +++ /dev/null @@ -1,1032 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DEdge.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DEdgeInfLin.hxx" -//#include "EdgeParabol.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelException.hxx" - -#include - -using namespace INTERP_KERNEL; - -MergePoints::MergePoints():_ass1Start1(0),_ass1End1(0),_ass1Start2(0),_ass1End2(0), - _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0) -{ -} - -void MergePoints::start1Replaced() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - _ass1Start1=1; - else - _ass2Start1=1; -} - -void MergePoints::end1Replaced() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - _ass1End1=1; - else - _ass2End1=1; -} - -void MergePoints::start1OnStart2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1Start1=1; - _ass1Start2=1; - } - else - { - _ass2Start1=1; - _ass2Start2=1; - } -} - -void MergePoints::start1OnEnd2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1Start1=1; - _ass1End2=1; - } - else - { - _ass2Start1=1; - _ass2End2=1; - } -} - -void MergePoints::end1OnStart2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1End1=1; - _ass1Start2=1; - } - else - { - _ass2End1=1; - _ass2Start2=1; - } -} - -void MergePoints::end1OnEnd2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1End1=1; - _ass1End2=1; - } - else - { - _ass2End1=1; - _ass2End2=1; - } -} - -bool MergePoints::isStart1(unsigned rk) const -{ - if(rk==0) - return _ass1Start1; - else - return _ass2Start1; -} - -bool MergePoints::isEnd1(unsigned rk) const -{ - if(rk==0) - return _ass1End1; - else - return _ass2End1; -} - -bool MergePoints::isStart2(unsigned rk) const -{ - if(rk==0) - return _ass1Start2; - else - return _ass2Start2; -} - -bool MergePoints::isEnd2(unsigned rk) const -{ - if(rk==0) - return _ass1End2; - else - return _ass2End2; -} - -void MergePoints::clear() -{ - _ass1Start1=0;_ass1End1=0;_ass1Start2=0;_ass1End2=0; - _ass2Start1=0;_ass2End1=0;_ass2Start2=0;_ass2End2=0; -} - -unsigned MergePoints::getNumberOfAssociations() const -{ - unsigned ret=0; - unsigned subTot=_ass1Start1+_ass1End1+_ass1Start2+_ass1End2; - if(subTot!=0) - ret++; - subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; - if(subTot!=0) - ret++; - return ret; -} - -void MergePoints::PushInMap(int key, int value, std::map& mergedNodes) -{ - if(key!=-1 && value!=-1) - mergedNodes[key]=value; -} - -void MergePoints::updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map& mergedNodes) -{ - unsigned subTot(_ass1Start1+_ass1End1+_ass1Start2+_ass1End2); - if(subTot!=0) - { - if(_ass1Start1 && _ass1Start2) - PushInMap(e2Start,e1Start,mergedNodes); - if(_ass1Start1 && _ass1End2) - PushInMap(e2End,e1Start,mergedNodes); - if(_ass1End1 && _ass1Start2) - PushInMap(e2Start,e1End,mergedNodes); - if(_ass1End1 && _ass1End2) - PushInMap(e2End,e1End,mergedNodes); - } - subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; - if(subTot!=0) - { - if(_ass2Start1 && _ass2Start2) - PushInMap(e2Start,e1Start,mergedNodes); - if(_ass2Start1 && _ass2End2) - PushInMap(e2End,e1Start,mergedNodes); - if(_ass2End1 && _ass2Start2) - PushInMap(e2Start,e1End,mergedNodes); - if(_ass2End1 && _ass2End2) - PushInMap(e2End,e1End,mergedNodes); - } -} - -IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node - , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2), - _1E(keepOrder?end1:end2), - _2S(keepOrder?start2:start1), - _2E(keepOrder?end2:end1), - _chararct_val_for_e1(keepOrder?val1:val2), - _chararct_val_for_e2(keepOrder?val2:val1), - _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2), - _e2(keepOrder?e2:e1) -{ -} - -IntersectElement::IntersectElement(const IntersectElement& other):_1S(other._1S),_1E(other._1E),_2S(other._2S),_2E(other._2E), - _chararct_val_for_e1(other._chararct_val_for_e1), - _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node), - _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2) -{ - if(_node) - _node->incrRef(); -} - -IntersectElement& IntersectElement::operator=(const IntersectElement& other) -{ - _1S=other._1S;_1E=other._1E; _2S=other._2S; _2E=other._2E; - _chararct_val_for_e1=other._chararct_val_for_e1; - _chararct_val_for_e2=other._chararct_val_for_e2; - setNode(other._node); - return *this; -} - -bool IntersectElement::operator<(const IntersectElement& other) const -{ - return _e1.isLower(_chararct_val_for_e1,other._chararct_val_for_e1); -} - -IntersectElement::~IntersectElement() -{ - if(_node) - _node->decrRef(); -} - -/*! - * Returns 0 or 1. - */ -bool IntersectElement::isOnMergedExtremity() const -{ - if( (_1S && _2S) || (_1S && _2E) || (_1E && _2S) || (_1E && _2E) ) - return true; - return false; -} - -/*! - * To call if isOnMergedExtremity returned true. - */ -void IntersectElement::performMerging(MergePoints& commonNode) const -{ - if(_1S && _2S) - { - if(_e1.changeStartNodeWith(_e2.getStartNode())) - { - _e2.getStartNode()->declareOnLim(); - commonNode.start1OnStart2(); - } - } - else if(_1S && _2E) - { - if(_e1.changeStartNodeWith(_e2.getEndNode())) - { - _e2.getEndNode()->declareOnLim(); - commonNode.start1OnEnd2(); - } - } - else if(_1E && _2S) - { - if(_e1.changeEndNodeWith(_e2.getStartNode())) - { - _e2.getStartNode()->declareOnLim(); - commonNode.end1OnStart2(); - } - } - else if(_1E && _2E) - { - if(_e1.changeEndNodeWith(_e2.getEndNode())) - { - _e2.getEndNode()->declareOnLim(); - commonNode.end1OnEnd2(); - } - } -} - -/*! - * This methode is const because 'node' is supposed to be equal geomitrically to _node. - */ -void IntersectElement::setNode(Node *node) const -{ - if(node!=_node) - { - if(_node) - ((Node *)_node)->decrRef(); - (const_cast(this))->_node=node; - if(_node) - _node->incrRef(); - } -} - -bool IntersectElement::isLowerOnOther(const IntersectElement& other) const -{ - return _e2.isLower(_chararct_val_for_e2,other._chararct_val_for_e2); -} - -unsigned IntersectElement::isOnExtrForAnEdgeAndInForOtherEdge() const -{ - if(( _1S && !(_2S || _2E) ) || ( _1E && !(_2S || _2E) )) - { - if(_1S && !(_2S || _2E)) - setNode(_e1.getStartNode()); - else - setNode(_e1.getEndNode()); - if(_e2.isIn(_chararct_val_for_e2)) - return LIMIT_ON; - return LIMIT_ALONE; - } - if(( _2S && !(_1S || _1E) ) || ( _2E && !(_1S || _1E))) - { - if(_2S && !(_1S || _1E)) - setNode(_e2.getStartNode()); - else - setNode(_e2.getEndNode()); - if(_e1.isIn(_chararct_val_for_e1)) - return LIMIT_ON; - return LIMIT_ALONE; - } - return NO_LIMIT; -} - -bool IntersectElement::isIncludedByBoth() const -{ - return _e1.isIn(_chararct_val_for_e1) && _e2.isIn(_chararct_val_for_e2); -} - -bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector& newNodes, bool& order, MergePoints& commonNode) -{ - std::list< IntersectElement > listOfIntesc=getIntersectionsCharacteristicVal(); - std::list< IntersectElement >::iterator iter; - for(iter=listOfIntesc.begin();iter!=listOfIntesc.end();) - { - if((*iter).isOnMergedExtremity()) - { - (*iter).performMerging(commonNode); - iter=listOfIntesc.erase(iter); - continue; - } - unsigned tmp=(*iter).isOnExtrForAnEdgeAndInForOtherEdge(); - if(tmp==IntersectElement::LIMIT_ALONE) - { - iter=listOfIntesc.erase(iter); - continue; - } - else if(tmp==IntersectElement::LIMIT_ON) - { - (*iter).attachLoc(); - iter++; - continue; - } - if(!(*iter).isIncludedByBoth()) - { - iter=listOfIntesc.erase(iter); - continue; - } - (*iter).attachLoc(); - iter++; - } - if(listOfIntesc.size()==0) - return false; - if(listOfIntesc.size()==1) - { - order=true;//useless - newNodes.push_back(listOfIntesc.front().getNodeAndReleaseIt()); - } - else - { - std::vector vecOfIntesc(listOfIntesc.begin(),listOfIntesc.end()); - listOfIntesc.clear(); - sort(vecOfIntesc.begin(),vecOfIntesc.end()); - for(std::vector::iterator iterV=vecOfIntesc.begin();iterV!=vecOfIntesc.end();iterV++) - newNodes.push_back((*iterV).getNodeAndReleaseIt()); - order=vecOfIntesc.front().isLowerOnOther(vecOfIntesc.back()); - } - return true; -} - -/*! - * Locates 'node' regarding edge this->_e1. If node is located close to (with distant lt epsilon) start or end point of _e1, - * 'node' takes its place. In this case 'obvious' is set to true and 'commonNode' stores information of merge point and finally 'where' is set. - * Furthermore 'node' is declared as ON LIMIT to indicate in locating process that an absolute location computation will have to be done. - * If 'node' is not close to start or end point of _e1, 'obvious' is set to false and 'commonNode' and 'where' are let unchanged. - */ -void EdgeIntersector::obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const -{ - obvious=true; - if(node->isEqual(*_e1.getStartNode())) - { - where=START; - if(_e1.changeStartNodeWith(node)) - { - commonNode.start1Replaced(); - node->declareOnLim(); - } - return ; - } - if(node->isEqual(*_e1.getEndNode())) - { - where=END; - if(_e1.changeEndNodeWith(node)) - { - commonNode.end1Replaced(); - node->declareOnLim(); - } - return ; - } - obvious=false; -} - -Edge::Edge(double sX, double sY, double eX, double eY):_cnt(1),_loc(FULL_UNKNOWN),_start(new Node(sX,sY)),_end(new Node(eX,eY)) -{ -} - -Edge::~Edge() -{ - _start->decrRef(); - if(_end) - _end->decrRef(); -} - -bool Edge::decrRef() -{ - bool ret=(--_cnt==0); - if(ret) - delete this; - return ret; -} - -void Edge::declareOn() const -{ - if(_loc==FULL_UNKNOWN) - { - _loc=FULL_ON_1; - _start->declareOn(); - _end->declareOn(); - } -} - -void Edge::declareIn() const -{ - if(_loc==FULL_UNKNOWN) - { - _loc=FULL_IN_1; - _start->declareIn(); - _end->declareIn(); - } -} - -void Edge::declareOut() const -{ - if(_loc==FULL_UNKNOWN) - { - _loc=FULL_OUT_1; - _start->declareOut(); - _end->declareOut(); - } -} - -void Edge::fillXfigStreamForLoc(std::ostream& stream) const -{ - switch(_loc) - { - case FULL_IN_1: - stream << '2';//Green - break; - case FULL_OUT_1: - stream << '1';//Bleue - break; - case FULL_ON_1: - stream << '4';//Red - break; - default: - stream << '0'; - } -} - -bool Edge::changeStartNodeWith(Node *otherStartNode) const -{ - if(_start==otherStartNode) - return true; - if(_start->isEqual(*otherStartNode)) - { - ((const_cast(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. - ((const_cast(this))->_start)=otherStartNode; - _start->incrRef(); - return true; - } - return false; -} - -bool Edge::changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector& track) const -{ - if(_start==otherStartNode) - return true; - if(_start->isEqualAndKeepTrack(*otherStartNode,track)) - { - ((const_cast(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. - ((const_cast(this))->_start)=otherStartNode; - otherStartNode->incrRef(); - return true; - } - return false; -} - -bool Edge::changeEndNodeWith(Node *otherEndNode) const -{ - if(_end==otherEndNode) - return true; - if(_end->isEqual(*otherEndNode)) - { - ((const_cast(this))->_end)->decrRef(); - ((const_cast(this))->_end)=otherEndNode; - _end->incrRef(); - return true; - } - return false; -} - -bool Edge::changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector& track) const -{ - if(_end==otherEndNode) - return true; - if(_end->isEqualAndKeepTrack(*otherEndNode,track)) - { - ((const_cast(this))->_end)->decrRef(); - ((const_cast(this))->_end)=otherEndNode; - otherEndNode->incrRef(); - return true; - } - return false; -} - -/*! - * Precondition : 'start' and 'end' are lying on the same curve than 'this'. - * Add in vec the sub edge lying on this. - * If 'start' is equal (by pointer) to '_end' and 'end' is equal to '_end' too nothing is added. - * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_start' too nothing is added. - * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_end' this is added in vec. - */ -void Edge::addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const -{ - if((start==_start && end==_start) || (start==_end && end==_end)) - return ; - if(start==_start && end==_end) - { - incrRef(); - vec.pushBack(const_cast(this)); - return ; - } - vec.pushBack(buildEdgeLyingOnMe(start,end,true)); -} - -/*! - * Retrieves a vector 'vectOutput' that is normal to 'this'. 'vectOutput' is normalized. - */ -void Edge::getNormalVector(double *vectOutput) const -{ - std::copy((const double *)(*_end),(const double *)(*_end)+2,vectOutput); - std::transform(vectOutput,vectOutput+2,(const double *)(*_start),vectOutput,std::minus()); - double norm=1./Node::norm(vectOutput); - std::transform(vectOutput,vectOutput+2,vectOutput,bind2nd(std::multiplies(),norm)); - double tmp=vectOutput[0]; - vectOutput[0]=vectOutput[1]; - vectOutput[1]=-tmp; -} - -Edge *Edge::BuildEdgeFrom3Points(const double *start, const double *middle, const double *end) -{ - Node *b(new Node(start[0],start[1])),*m(new Node(middle[0],middle[1])),*e(new Node(end[0],end[1])); - EdgeLin *e1(new EdgeLin(b,m)),*e2(new EdgeLin(m,e)); - SegSegIntersector inters(*e1,*e2); bool colinearity=inters.areColinears(); delete e1; delete e2; - Edge *ret=0; - if(colinearity) - ret=new EdgeLin(b,e); - else - ret=new EdgeArcCircle(b,m,e); - b->decrRef(); m->decrRef(); e->decrRef(); - return ret; -} - -Edge *Edge::BuildEdgeFrom(Node *start, Node *end) -{ - return new EdgeLin(start,end); -} - -Edge *Edge::BuildFromXfigLine(std::istream& str) -{ - unsigned char type; - str >> type; - if(type=='2') - return new EdgeLin(str); - else if(type=='5') - return new EdgeArcCircle(str); - else - { - std::cerr << "Unknown line found..."; - return 0; - } -} - -/*! - * \param other The Edge with which we are going to intersect. - * \param commonNode Output. The common nodes found during operation of intersecting. - * \param outVal1 Output filled in case true is returned. It specifies the new or not new edges by which 'this' is replaced after intersecting op. - * \param outVal2 Output filled in case true is returned. It specifies the new or not new edges by which 'other' is replaced after intersecting op. - * return true if the intersection between this. - */ -bool Edge::intersectWith(const Edge *other, MergePoints& commonNode, - ComposedEdge& outVal1, ComposedEdge& outVal2) const -{ - bool ret=true; - Bounds *merge=_bounds.nearlyAmIIntersectingWith(other->getBounds()); - if(!merge) - return false; - delete merge; - merge=0; - EdgeIntersector *intersector=BuildIntersectorWith(this,other); - ret=Intersect(this,other,intersector,merge,commonNode,outVal1,outVal2); - delete intersector; - return ret; -} - -bool Edge::IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2) -{ - bool rev=intersector->haveTheySameDirection(); - Node *f2Start=f2->getNode(rev?START:END); - Node *f2End=f2->getNode(rev?END:START); - TypeOfLocInEdge place1, place2; - intersector->getPlacements(f2Start,f2End,place1,place2,commonNode); - int codeForIntersectionCase=CombineCodes(place1,place2); - return SplitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2); -} - -/*! - * Perform 1D linear interpolation. Warning distrib1 and distrib2 are expected to be in ascending mode. - */ -void Edge::Interpolate1DLin(const std::vector& distrib1, const std::vector& distrib2, std::map >& result) -{ - int nbOfV1=distrib1.size()-1; - int nbOfV2=distrib2.size()-1; - Node *n1=new Node(0.,0.); Node *n3=new Node(0.,0.); - Node *n2=new Node(0.,0.); Node *n4=new Node(0.,0.); - MergePoints commonNode; - for(int i=0;i::const_iterator iter=find_if(distrib2.begin()+1,distrib2.end(),bind2nd(std::greater_equal(),distrib1[i])); - if(iter!=distrib2.end()) - { - for(int j=(iter-1)-distrib2.begin();jsetNewCoords(distrib1[i],0.); n2->setNewCoords(distrib1[i+1],0.); - n3->setNewCoords(distrib2[j],0.); n4->setNewCoords(distrib2[j+1],0.); - ComposedEdge *f1=new ComposedEdge; - ComposedEdge *f2=new ComposedEdge; - SegSegIntersector inters(*e1,*e2); - bool b1,b2; - inters.areOverlappedOrOnlyColinears(0,b1,b2); - if(IntersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2)) - { - result[i][j]=f1->getCommonLengthWith(*f2)/e1->getCurveLength(); - } - ComposedEdge::Delete(f1); ComposedEdge::Delete(f2); - e1->decrRef(); e2->decrRef(); - } - } - } - } - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); -} - -EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2) -{ - EdgeIntersector *ret=0; - const EdgeLin *tmp1=0; - const EdgeArcCircle *tmp2=0; - unsigned char type1=e1->getTypeOfFunc(); - e1->dynCastFunction(tmp1,tmp2); - unsigned char type2=e2->getTypeOfFunc(); - e2->dynCastFunction(tmp1,tmp2); - type1|=type2; - switch(type1) - { - case 1:// Intersection seg/seg - ret=new SegSegIntersector((const EdgeLin &)(*e1),(const EdgeLin &)(*e2)); - break; - case 5:// Intersection seg/arc of circle - ret=new ArcCSegIntersector(*tmp2,*tmp1,tmp2==e1); - break; - case 4:// Intersection arc/arc of circle - ret=new ArcCArcCIntersector((const EdgeArcCircle &)(*e1),(const EdgeArcCircle &)(*e2)); - break; - default: - //Should never happen - throw Exception("A non managed association of edge has been detected. Go work for intersection computation implementation."); - } - return ret; -} - -/*! - * See Node::applySimilarity to see signification of params. - */ -void Edge::applySimilarity(double xBary, double yBary, double dimChar) -{ - _bounds.applySimilarity(xBary,yBary,dimChar); -} - -void Edge::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - _bounds.unApplySimilarity(xBary,yBary,dimChar); -} - -void Edge::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const -{ - return getMiddleOfPoints(p1, p2, mid); -} - -bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2) -{ - bool obviousNoIntersection; - bool areOverlapped; - intersector->areOverlappedOrOnlyColinears(whereToFind,obviousNoIntersection,areOverlapped); - if(areOverlapped) - return IntersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2); - if(obviousNoIntersection) - return false; - std::vector newNodes; - bool order; - if(intersector->intersect(whereToFind,newNodes,order,commonNode)) - { - if(newNodes.empty()) - throw Exception("Internal error occured - error in intersector implementation!");// This case should never happen - std::vector::iterator iter=newNodes.begin(); - std::vector::reverse_iterator iterR=newNodes.rbegin(); - f1->addSubEdgeInVector(f1->getStartNode(),*iter,outValForF1); - f2->addSubEdgeInVector(f2->getStartNode(),order?*iter:*iterR,outValForF2); - for(std::vector::iterator iter2=newNodes.begin();iter2!=newNodes.end();iter2++,iterR++) - { - if((iter2+1)==newNodes.end()) - { - f1->addSubEdgeInVector(*iter2,f1->getEndNode(),outValForF1); - (*iter2)->decrRef(); - f2->addSubEdgeInVector(order?*iter2:*iterR,f2->getEndNode(),outValForF2); - } - else - { - f1->addSubEdgeInVector(*iter2,*(iter2+1),outValForF1); - (*iter2)->decrRef(); - f2->addSubEdgeInVector(order?*iter2:*iterR,order?*(iter2+1):*(iterR+1),outValForF2); - } - } - return true; - } - else//no intersection inside whereToFind - return false; -} - -int Edge::CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2) -{ - int ret=(int)code1; - ret*=OFFSET_FOR_TYPEOFLOCINEDGE; - ret+=(int)code2; - return ret; -} - -/*! - * This method splits e1 and e2 into pieces as much sharable as possible. The precondition to the call of this method - * is that e1 and e2 have been declared as overlapped by corresponding intersector built from e1 and e2 type. - * - * @param nS start node of e2 with the SAME DIRECTION as e1. The pointer nS should be equal to start node of e2 or to its end node. - * @param nE end node of e2 with the SAME DIRECTION as e1. The pointer nE should be equal to start node of e2 or to its end node. - * @param direction is param that specifies if e2 and e1 have same directions (true) or opposed (false). - * @param code is the code returned by method Edge::combineCodes. - */ -bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, - ComposedEdge& outVal1, ComposedEdge& outVal2) -{ - Edge *tmp; - switch(code) - { - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // OUT_BEFORE - START - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_BEFORE: // OUT_BEFORE - OUT_BEFORE - case OUT_AFTER*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_AFTER - OUT_AFTER - case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // END - OUT_AFTER - case END*OFFSET_FOR_TYPEOFLOCINEDGE+START: // END - START - return false; - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // INSIDE - OUT_AFTER - outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); - tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); - outVal1.pushBack(tmp); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn(); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // INSIDE - INSIDE - { - if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode())))) - { - e2->incrRef(); e2->incrRef(); - outVal1.resize(3); - outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); - outVal1.setValueAt(1,const_cast(e2),direction); - outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.pushBack(const_cast(e2)); e2->declareOn(); - return true; - } - else - { - outVal1.resize(3); - outVal2.resize(3); - tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction); - outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS)); - tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction); - tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode()); - outVal2.setValueAt(1,tmp,direction); - return true; - } - } - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // OUT_BEFORE - INSIDE - { - tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); - outVal1.pushBack(tmp); - outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); - outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn(); - return true; - } - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_BEFORE - OUT_AFTER - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.resize(3); - outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); - outVal2.setValueAt(1,const_cast(e1),direction); e1->declareOn(); - outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - } - case START*OFFSET_FOR_TYPEOFLOCINEDGE+END: // START - END - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.pushBack(const_cast(e1),direction); e1->declareOn(); - return true; - } - case START*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // START - OUT_AFTER - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,const_cast(e1),direction); e1->declareOn(); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - } - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // INSIDE - END - { - e2->incrRef(); e2->incrRef(); - outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); - outVal1.pushBack(const_cast(e2),direction); - outVal2.pushBack(const_cast(e2)); e2->declareOn(); - return true; - } - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // OUT_BEFORE - END - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); - outVal2.setValueAt(direction?1:0,const_cast(e1),direction); e1->declareOn(); - return true; - } - case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // START - INSIDE - { - e2->incrRef(); e2->incrRef(); - outVal1.pushBack(const_cast(e2),direction); - outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.pushBack(const_cast(e2)); e2->declareOn(); - return true; - } - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // INSIDE - START - { - outVal1.resize(2); - outVal2.resize(2); - tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); - outVal1.setValueAt(1,tmp); - outVal2.setValueAt(direction?0:1,tmp,direction); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - } - case END*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // END - INSIDE - { - outVal1.resize(2); - outVal2.resize(2); - tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(0,tmp); - outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode(),direction)); - outVal2.setValueAt(direction?1:0,tmp,direction); - return true; - } - default: - throw Exception("Unexpected situation of overlapping edges : internal error occurs ! "); - } -} - -bool Edge::isEqual(const Edge& other) const -{ - return _start->isEqual(*other._start) && _end->isEqual(*other._end); -} - -inline bool eqpair(const std::pair& p1, const std::pair& p2) -{ - return fabs(p1.first-p2.first)& subNodes) -{ - Bounds b; - b.prepareForAggregation(); - b.aggregate(getBounds()); - double xBary,yBary; - double dimChar(b.getCaracteristicDim()); - b.getBarycenter(xBary,yBary); - applySimilarity(xBary,yBary,dimChar); - _start->applySimilarity(xBary,yBary,dimChar); - _end->applySimilarity(xBary,yBary,dimChar); - // - std::size_t sz(subNodes.size()),i(0); - std::vector< std::pair > an2(sz); - std::map m; - for(std::vector::const_iterator it=subNodes.begin();it!=subNodes.end();it++,i++) - { - Node *n(new Node(coo[2*(*it)],coo[2*(*it)+1])); - n->applySimilarity(xBary,yBary,dimChar); - m[n]=*it; - an2[i]=std::pair(getCharactValueBtw0And1(*n),n); - } - std::sort(an2.begin(),an2.end()); - // - bool ret(false); - for(i=0;i::const_iterator it2=m.begin();it2!=m.end();it2++) - (*it2).first->decrRef(); - return ret; -} - -/** - * Sort nodes so that they all lie consecutively on the edge that has been cut. - */ -void Edge::sortIdsAbs(const std::vector& addNodes, const std::map& mapp1, - const std::map& mapp2, std::vector& edgesThis) -{ - Bounds b; - b.prepareForAggregation(); - b.aggregate(getBounds()); - double xBary,yBary; - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - for(std::vector::const_iterator iter=addNodes.begin();iter!=addNodes.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); - applySimilarity(xBary,yBary,dimChar); - _start->applySimilarity(xBary,yBary,dimChar); - _end->applySimilarity(xBary,yBary,dimChar); - std::size_t sz=addNodes.size(); - std::vector< std::pair > an2(sz); - for(std::size_t i=0;i(getCharactValueBtw0And1(*addNodes[i]),addNodes[i]); - std::sort(an2.begin(),an2.end()); - int startId=(*mapp1.find(_start)).second; - int endId=(*mapp1.find(_end)).second; - std::vector tmpp; - std::vector< std::pair >::const_iterator itend=std::unique(an2.begin(),an2.end(),eqpair); - for(std::vector< std::pair >::const_iterator it=an2.begin();it!=itend;it++) - { - int idd=(*mapp2.find((*it).second)).second; - if((*it).first1-QUADRATIC_PLANAR::_precision) - { - endId=idd; - continue; - } - tmpp.push_back(idd); - } - std::vector tmpp2(tmpp.size()+2); - tmpp2[0]=startId; - std::copy(tmpp.begin(),tmpp.end(),tmpp2.begin()+1); - tmpp2[tmpp.size()+1]=endId; - std::vector::iterator itt=std::unique(tmpp2.begin(),tmpp2.end()); - tmpp2.resize(std::distance(tmpp2.begin(),itt)); - int nbOfEdges=tmpp2.size()-1; - for(int i=0;i -#include -#include -#include - -namespace INTERP_KERNEL -{ - typedef enum - { - SEG = 1, - ARC_CIRCLE = 4, - ARC_PARABOL = 8 - } TypeOfFunction; - - typedef enum - { - CIRCLE = 0 , - PARABOL = 1 - } TypeOfMod4QuadEdge; - - typedef enum - { - START = 5, - END = 1, - INSIDE = 2, - OUT_BEFORE = 3, - OUT_AFTER = 4 - } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE - - typedef enum - { - FULL_IN_1 = 1, - FULL_ON_1 = 4, - FULL_OUT_1 = 2, - FULL_UNKNOWN = 3 - } TypeOfEdgeLocInPolygon; - - class INTERPKERNEL_EXPORT MergePoints - { - public: - MergePoints(); - - //methods called during intersection edge-edge - void start1Replaced(); - void end1Replaced(); - void start1OnStart2(); - void start1OnEnd2(); - void end1OnStart2(); - void end1OnEnd2(); - //methods to be called during aggregation - bool isStart1(unsigned rk) const; - bool isEnd1(unsigned rk) const; - bool isStart2(unsigned rk) const; - bool isEnd2(unsigned rk) const; - void clear(); - unsigned getNumberOfAssociations() const; - void updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map& mergedNodes); - private: - static void PushInMap(int key, int value, std::map& mergedNodes); - private: - unsigned _ass1Start1 : 1; - unsigned _ass1End1 : 1; - unsigned _ass1Start2 : 1; - unsigned _ass1End2 : 1; - unsigned _ass2Start1 : 1; - unsigned _ass2End1 : 1; - unsigned _ass2Start2 : 1; - unsigned _ass2End2 : 1; - }; - - class Edge; - class ComposedEdge; - /*! - * This class is in charge to store an intersection point as result of \b non oververlapping edge intersection. - * This class manages the cases when intersect element is one of the extrimities of edge1 and/or edge2. - */ - class INTERPKERNEL_EXPORT IntersectElement - { - public: - IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node, const Edge& e1, const Edge& e2, bool keepOrder); - IntersectElement(const IntersectElement& other); - //! The sort operator is done on the edge 1 \b not edge 2. - bool operator<(const IntersectElement& other) const; - IntersectElement& operator=(const IntersectElement& other); - double getVal1() const { return _chararct_val_for_e1; } - double getVal2() const { return _chararct_val_for_e2; } - //! idem operator< method except that the orientation is done on edge 2 \b not edge 1. - bool isLowerOnOther(const IntersectElement& other) const; - unsigned isOnExtrForAnEdgeAndInForOtherEdge() const; - void attachLoc() { _node->setLoc(_loc_of_node); } - bool isOnMergedExtremity() const; - bool isIncludedByBoth() const; - void setNode(Node *node) const; - void performMerging(MergePoints& commonNode) const; - Node *getNodeOnly() const { return _node; } - Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; } - ~IntersectElement(); - private: - bool _1S; - bool _1E; - bool _2S; - bool _2E; - double _chararct_val_for_e1; - double _chararct_val_for_e2; - Node *_node; - TypeOfLocInPolygon _loc_of_node; - const Edge& _e1; - const Edge& _e2; - public: - static const unsigned LIMIT_ALONE = 22; - static const unsigned LIMIT_ON = 73; - static const unsigned NO_LIMIT = 19; - }; - - /*! - * This abstract interface specifies all the methods to be overloaded of all possibilities edge-intersection. - */ - class INTERPKERNEL_EXPORT EdgeIntersector - { - protected: - //! All non symetric methods are relative to 'e1'. - EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { } - public: - virtual ~EdgeIntersector() { } - virtual bool keepOrder() const = 0; - virtual bool areColinears() const = 0; - //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called - virtual bool haveTheySameDirection() const = 0; - //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called - virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0; - //! When true is returned, newNodes should contains at least 1 element. All merging nodes betw _e1 and _e2 extremities must be done. - bool intersect(const Bounds *whereToFind, std::vector& newNodes, bool& order, MergePoints& commonNode); - //! Should be called only once per association. - virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0; - //! The size of returned vector is equal to number of potential intersections point. The values are so that their are interpretable by virtual Edge::isIn method. - virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0; - protected: - void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const; - protected: - const Edge& _e1; - const Edge& _e2; - }; - - class INTERPKERNEL_EXPORT SameTypeEdgeIntersector : public EdgeIntersector - { - protected: - SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { } - bool keepOrder() const { return true; } - }; - - class INTERPKERNEL_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector - { - protected: - CrossTypeEdgeIntersector(const Edge& e1, const Edge& e2, bool reverse):EdgeIntersector(e1,e2),_reverse(reverse) { } - bool keepOrder() const { return _reverse; } - bool haveTheySameDirection() const { throw Exception("Cross type intersector is not supposed to deal with overlapped in cross type."); } - const Edge *myE1() { if(_reverse) return &_e1; else return &_e2; } - const Edge *myE2() { if(_reverse) return &_e2; else return &_e1; } - protected: - //! boolean to inform intersector that unsymetrics treatments reverse of e1 and e2 should be done. - bool _reverse; - }; - - class EdgeLin; - class EdgeInfLin; - class EdgeArcCircle; - - /*! - * Deal with an oriented edge of a polygon. - * An Edge is defined with a start node, an end node and an equation of 1D curve. - * All other attributes are mutable because they don't impact these 3 invariant attributes. - * To be exact start and end nodes can change (address) but their location remain - * the same (at precision). - */ - class INTERPKERNEL_EXPORT Edge - { - public: - Edge(Node *start, Node *end, bool direction=true):_cnt(1),_loc(FULL_UNKNOWN) { if(direction) { _start=start; _end=end; } else { _start=end; _end=start; } _start->incrRef(); _end->incrRef(); } - Edge(double sX, double sY, double eX, double eY); - TypeOfEdgeLocInPolygon getLoc() const { return _loc; } - void incrRef() const { _cnt++; } - bool decrRef(); - void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); } - void declareOn() const; - void declareIn() const; - void declareOut() const; - void initHitStatus() const { _hit=false; } - bool getHitStatus() const { return _hit; } - void hitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; applySimilarity(xBary,yBary,dimChar); } - void unHitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; unApplySimilarity(xBary,yBary,dimChar); } - void hitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) hitMeAlone(xBary,yBary,dimChar); } - void unHitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) unHitMeAlone(xBary,yBary,dimChar); } - const Bounds& getBounds() const { return _bounds; } - void fillXfigStreamForLoc(std::ostream& stream) const; - Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; } - Node *getStartNode() const { return _start; } - Node *getEndNode() const { return _end; } - void setEndNodeWithoutChange(Node *newEnd); - void setStartNodeWithoutChange(Node *newStart); - bool changeStartNodeWith(Node *otherStartNode) const; - bool changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector& track) const; - bool changeEndNodeWith(Node *otherEndNode) const; - bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector& track) const; - void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const; - void getNormalVector(double *vectOutput) const; - static EdgeIntersector *BuildIntersectorWith(const Edge *e1, const Edge *e2); - static Edge *BuildFromXfigLine(std::istream& str); - static Edge *BuildEdgeFrom(Node *start, Node *end); - template - static Edge *BuildEdgeFrom(Node *start, Node *middle, Node *end); - static Edge *BuildEdgeFrom3Points(const double *start, const double *middle, const double *end); - virtual void update(Node *m) = 0; - //! returns area between this and axe Ox delimited along Ox by _start and _end. - virtual double getAreaOfZone() const = 0; - //! apply a similiraty transformation on 'this' - virtual void applySimilarity(double xBary, double yBary, double dimChar); - //! apply the inverse similiraty transformation on 'this' - virtual void unApplySimilarity(double xBary, double yBary, double dimChar); - //! return the length of arc. Value is always > 0. ! - virtual double getCurveLength() const = 0; - virtual void getBarycenter(double *bary) const = 0; - virtual void getBarycenterOfZone(double *bary) const = 0; - //! return the middle of two points - virtual void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const = 0; - //! return the middle of two points respecting the orientation defined by this (relevant for arc of circle). By default same as getMiddleOfPoints() - virtual void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const; - //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned. - virtual Node *buildRepresentantOfMySelf() const = 0; - //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method. - virtual bool isIn(double characterVal) const = 0; - //! With the same magnitude as defined in 'isIn' method perform a compararison. Precondition : val1 and val2 are different and exactly INSIDE this. - virtual bool isLower(double val1, double val2) const = 0; - //! node is expected to lay on 'this'. It returns a characteristic magnitude usable by isIn method. - virtual double getCharactValue(const Node& node) const = 0; - //! node is expected to lay on 'this'. It returns a characteristic magnitude between 0 and 1. - virtual double getCharactValueBtw0And1(const Node& node) const = 0; - //! retrieves the distance to this : The min distance from pt and any point of this. - virtual double getDistanceToPoint(const double *pt) const = 0; - //! return if node with coords 'coordOfNode' is on this (with precision). - virtual bool isNodeLyingOn(const double *coordOfNode) const = 0; - virtual TypeOfFunction getTypeOfFunc() const = 0; - virtual void dynCastFunction(const EdgeLin * &seg, - const EdgeArcCircle * &arcSeg) const = 0; - bool intersectWith(const Edge *other, MergePoints& commonNode, - ComposedEdge& outVal1, ComposedEdge& outVal2) const; - static bool IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2); - static void Interpolate1DLin(const std::vector& distrib1, const std::vector& distrib2, - std::map >& result); - virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0; - bool isEqual(const Edge& other) const; - public: - bool sortSubNodesAbs(const double *coo, std::vector& subNodes); - void sortIdsAbs(const std::vector& addNodes, const std::map& mapp1, const std::map& mapp2, std::vector& edgesThis); - virtual void fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const = 0; - virtual void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const = 0; - virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0; - protected: - Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { } - virtual ~Edge(); - static int CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2); - static bool Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2); - //! The code 'code' is built by method combineCodes - static bool SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, - ComposedEdge& outVal1, ComposedEdge& outVal2); - protected: - mutable bool _hit; - mutable unsigned char _cnt; - mutable TypeOfEdgeLocInPolygon _loc; - Bounds _bounds; - Node *_start; - Node *_end; - protected: - //In relation with max possible value of TypeOfLocInEdge. - static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx deleted file mode 100644 index c76b18134..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERPKERNELGEO2DEDGE_TXX__ -#define __INTERPKERNELGEO2DEDGE_TXX__ - -#include "InterpKernelGeo2DEdgeArcCircle.hxx" - -template -INTERP_KERNEL::Edge *INTERP_KERNEL::Edge::BuildEdgeFrom(Node *start, Node *middle, Node *end) -{ - return new INTERP_KERNEL::EdgeArcCircle(start,middle,end); -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx deleted file mode 100644 index 491ff1578..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx +++ /dev/null @@ -1,841 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include - -using namespace INTERP_KERNEL; - -ArcCArcCIntersector::ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2):SameTypeEdgeIntersector(e1,e2),_dist(0.) -{ -} - -bool ArcCArcCIntersector::haveTheySameDirection() const -{ - return (getE1().getAngle()>0. && getE2().getAngle()>0.) || (getE1().getAngle()<0. && getE2().getAngle()<0.); -} - -bool ArcCArcCIntersector::areColinears() const -{ - double radiusL,radiusB; - double centerL[2],centerB[2]; - double tmp,cst; - return internalAreColinears(getE1(),getE2(),tmp,cst,radiusL,centerL,radiusB,centerB); -} - -/*! - * Precondition 'start' and 'end' are on the same curve than this. - */ -void ArcCArcCIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const -{ - bool obvious1,obvious2; - obviousCaseForCurvAbscisse(start,whereStart,commonNode,obvious1); - obviousCaseForCurvAbscisse(end,whereEnd,commonNode,obvious2); - if(obvious1 && obvious2) - return ; - double angleInRadStart=getAngle(start); - double angleInRadEnd=getAngle(end); - if(obvious1 || obvious2) - { - if(obvious1) - { - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) - whereEnd=INSIDE; - else - whereEnd=OUT_AFTER; - return ; - } - else - { - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) - whereStart=INSIDE; - else - whereStart=OUT_BEFORE; - return ; - } - } - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) - { - whereStart=INSIDE; - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) - whereEnd=INSIDE; - else - whereEnd=OUT_AFTER; - } - else - {//we are out in start. - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) - { - whereStart=OUT_BEFORE; - whereEnd=INSIDE; - } - else - { - if(EdgeArcCircle::IsIn2Pi(getE2().getAngle0(),getE2().getAngle(),getE1().getAngle0())) - {//_e2 contains stictly _e1 - whereStart=OUT_BEFORE; - whereEnd=OUT_AFTER; - } - else - {//_e2 is outside from _e1 - whereStart=OUT_BEFORE; - whereEnd=OUT_BEFORE; - } - } - } -} - -/*! - * Return angle between ]-Pi;Pi[ - */ -double ArcCArcCIntersector::getAngle(Node *node) const -{ - return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(((*node)[0]-getE1().getCenter()[0])/getE1().getRadius(),((*node)[1]-getE1().getCenter()[1])/getE1().getRadius()); -} - -bool ArcCArcCIntersector::internalAreColinears(const EdgeArcCircle& a1, const EdgeArcCircle& a2, double& distBetweenCenters, double& cst, - double& radiusL, double centerL[2], double& radiusB, double centerB[2]) -{ - double lgth1=fabs(a1.getAngle()*a1.getRadius()); - double lgth2=fabs(a2.getAngle()*a2.getRadius()); - if(lgth1getInterceptedArc(centerL,radiusL,angle0L,angleL); - delete merge; - // - tmp=sqrt(tmp); - if(Node::areDoubleEqualsWP(tmp,0.,1/(10*std::max(radiusL,radiusB)))) - return Node::areDoubleEquals(radiusL,radiusB); - double phi=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect((centerL[0]-centerB[0])/tmp,(centerL[1]-centerB[1])/tmp); - double cst2=2*radiusL*tmp/(radiusB*radiusB); - double cmpContainer[4]; - int sizeOfCmpContainer=2; - cmpContainer[0]=cst+cst2*cos(phi-angle0L); - cmpContainer[1]=cst+cst2*cos(phi-angle0L+angleL); - double a=EdgeArcCircle::NormalizeAngle(phi-angle0L); - if(EdgeArcCircle::IsIn2Pi(angle0L,angleL,a)) - cmpContainer[sizeOfCmpContainer++]=cst+cst2; - a=EdgeArcCircle::NormalizeAngle(phi-angle0L+M_PI); - if(EdgeArcCircle::IsIn2Pi(angle0L,angleL,a)) - cmpContainer[sizeOfCmpContainer++]=cst-cst2; - a=*std::max_element(cmpContainer,cmpContainer+sizeOfCmpContainer); - return Node::areDoubleEqualsWP(a,1.,2.); -} - -void ArcCArcCIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) -{ - _dist=Node::distanceBtw2Pt(getE1().getCenter(),getE2().getCenter()); - double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); - if(_dist>radius1+radius2+QUADRATIC_PLANAR::_precision || _dist+std::min(radius1,radius2)+QUADRATIC_PLANAR::_precision ArcCArcCIntersector::getIntersectionsCharacteristicVal() const -{ - std::list< IntersectElement > ret; - const double *center1=getE1().getCenter(); - const double *center2=getE2().getCenter(); - double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); - double d1_1=(_dist*_dist-radius2*radius2+radius1*radius1)/(2.*_dist); - double u[2];//u is normalized vector from center1 to center2. - u[0]=(center2[0]-center1[0])/_dist; u[1]=(center2[1]-center1[1])/_dist; - double d1_1y=EdgeArcCircle::SafeSqrt(radius1*radius1-d1_1*d1_1); - double angleE1=EdgeArcCircle::NormalizeAngle(getE1().getAngle0()+getE1().getAngle()); - double angleE2=EdgeArcCircle::NormalizeAngle(getE2().getAngle0()+getE2().getAngle()); - if(!Node::areDoubleEquals(d1_1y,0)) - { - //2 intersections - double v1[2],v2[2]; - v1[0]=u[0]*d1_1-u[1]*d1_1y; v1[1]=u[1]*d1_1+u[0]*d1_1y; - v2[0]=u[0]*d1_1+u[1]*d1_1y; v2[1]=u[1]*d1_1-u[0]*d1_1y; - Node *node1=new Node(center1[0]+v1[0],center1[1]+v1[1]); node1->declareOn(); - Node *node2=new Node(center1[0]+v2[0],center1[1]+v2[1]); node2->declareOn(); - double angle1_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); - double angle2_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v2[0]/radius1,v2[1]/radius1); - double v3[2],v4[2]; - v3[0]=center1[0]-center2[0]+v1[0]; v3[1]=center1[1]-center2[1]+v1[1]; - v4[0]=center1[0]-center2[0]+v2[0]; v4[1]=center1[1]-center2[1]+v2[1]; - double angle1_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v3[0]/radius2,v3[1]/radius2); - double angle2_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v4[0]/radius2,v4[1]/radius2); - // - bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); - bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); - bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); - bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); - // - bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); - bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); - bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); - bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); - ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); - ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); - } - else - { - //tangent intersection - double v1[2],v2[2]; - v1[0]=d1_1*u[0]; v1[1]=d1_1*u[1]; - v2[0]=center1[0]-center2[0]+v1[0]; v2[1]=center1[1]-center2[1]+v1[1]; - double angle0_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); - double angle0_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v2[0]/radius2,v2[1]/radius2); - bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); - bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); - bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); - bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); - Node *node=new Node(center1[0]+d1_1*u[0],center1[1]+d1_1*u[1]); node->declareOnTangent(); - ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); - } - return ret; -} -/*double angle0_2; - double signDeltaAngle2; - double d1_2; - if(u[1]<0.) - angle0_1=-angle0_1; - if(d1_1>=0.) - { - if(_dist>radius1) - { - angle0_2=angle0_1+M_PI; - signDeltaAngle2=-1.; - } - else - { - angle0_2=angle0_1; - signDeltaAngle2=1.; - } - } - else - { - angle0_1+=M_PI; - angle0_2=angle0_1; - signDeltaAngle2=1.; - } - angle0_1=NormalizeAngle(angle0_1); - angle0_2=NormalizeAngle(angle0_2); - double angleE1=NormalizeAngle(getE1().getAngle0()+getE1().getAngle()); - double angleE2=NormalizeAngle(getE2().getAngle0()+getE2().getAngle()); - if(!(Node::areDoubleEquals(d1_1,radius1) || Node::areDoubleEquals(d1_1,-radius1)) ) - { - //2 intersections - double deltaAngle1=EdgeArcCircle::SafeAcos(fabs(d1_1)/radius1); //owns to 0;Pi/2 by construction - double deltaAngle2=EdgeArcCircle::SafeAcos(fabs(d1_2)/radius2); //owns to 0;Pi/2 by construction - double angle1_1=NormalizeAngle(angle0_1+deltaAngle1);// Intersection 1 seen for _e1 - double angle2_1=NormalizeAngle(angle0_1-deltaAngle1);// Intersection 2 seen for _e1 - double angle1_2=NormalizeAngle(angle0_2+signDeltaAngle2*deltaAngle2);// Intersection 1 seen for _e2 - double angle2_2=NormalizeAngle(angle0_2-signDeltaAngle2*deltaAngle2);// Intersection 2 seen for _e2 - // - bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); - bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); - bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); - bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); - // - bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); - bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); - bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); - bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); - Node *node1=new Node(center1[0]+radius1*cos(angle1_1),center1[0]+radius1*sin(angle1_1)); node1->declareOn(); - Node *node2=new Node(center1[0]+radius1*cos(angle2_1),center1[0]+radius1*sin(angle2_1)); node2->declareOn(); - ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); - ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); - } - else - //tangent intersection - { - bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); - bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); - bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); - bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); - Node *node=new Node(center1[0]+radius1*cos(angle0_1),center1[0]+radius1*sin(angle0_1)); node->declareOnTangent(); - ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); - } - return ret;*/ - -ArcCSegIntersector::ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse):CrossTypeEdgeIntersector(e1,e2,reverse) -{ -} - -void ArcCSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) -{ - areOverlapped=false;//No overlapping by construction - const double *center=getE1().getCenter(); - _dx=(*(_e2.getEndNode()))[0]-(*(_e2.getStartNode()))[0]; - _dy=(*(_e2.getEndNode()))[1]-(*(_e2.getStartNode()))[1]; - _drSq=_dx*_dx+_dy*_dy; - _cross= - ((*(_e2.getStartNode()))[0]-center[0])*((*(_e2.getEndNode()))[1]-center[1])- - ((*(_e2.getStartNode()))[1]-center[1])*((*(_e2.getEndNode()))[0]-center[0]); - _determinant=getE1().getRadius()*getE1().getRadius()/_drSq-_cross*_cross/(_drSq*_drSq); - if(_determinant>-2*QUADRATIC_PLANAR::_precision)//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) - obviousNoIntersection=false; - else - obviousNoIntersection=true; -} - -/*! - * By construction, no chance that an arc of circle and line to be colinear. - */ -bool ArcCSegIntersector::areColinears() const -{ - return false; -} - -void ArcCSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const -{ - throw Exception("Internal error. Should never been called : no overlapping possible between arc of circle and a segment."); -} - -std::list< IntersectElement > ArcCSegIntersector::getIntersectionsCharacteristicVal() const -{ - std::list< IntersectElement > ret; - const double *center=getE1().getCenter(); - if(!(fabs(_determinant)<(2.*QUADRATIC_PLANAR::_precision)))//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) - { - double determinant=EdgeArcCircle::SafeSqrt(_determinant); - double x1=(_cross*_dy/_drSq+Node::sign(_dy)*_dx*determinant)+center[0]; - double y1=(-_cross*_dx/_drSq+fabs(_dy)*determinant)+center[1]; - Node *intersect1=new Node(x1,y1); intersect1->declareOn(); - bool i1_1S=_e1.getStartNode()->isEqual(*intersect1); - bool i1_1E=_e1.getEndNode()->isEqual(*intersect1); - bool i1_2S=_e2.getStartNode()->isEqual(*intersect1); - bool i1_2E=_e2.getEndNode()->isEqual(*intersect1); - ret.push_back(IntersectElement(getE1().getCharactValue(*intersect1),getE2().getCharactValue(*intersect1),i1_1S,i1_1E,i1_2S,i1_2E,intersect1,_e1,_e2,keepOrder())); - // - double x2=(_cross*_dy/_drSq-Node::sign(_dy)*_dx*determinant)+center[0]; - double y2=(-_cross*_dx/_drSq-fabs(_dy)*determinant)+center[1]; - Node *intersect2=new Node(x2,y2); intersect2->declareOn(); - bool i2_1S=_e1.getStartNode()->isEqual(*intersect2); - bool i2_1E=_e1.getEndNode()->isEqual(*intersect2); - bool i2_2S=_e2.getStartNode()->isEqual(*intersect2); - bool i2_2E=_e2.getEndNode()->isEqual(*intersect2); - ret.push_back(IntersectElement(getE1().getCharactValue(*intersect2),getE2().getCharactValue(*intersect2),i2_1S,i2_1E,i2_2S,i2_2E,intersect2,_e1,_e2,keepOrder())); - } - else//tangent intersection - { - double x=(_cross*_dy)/_drSq+center[0]; - double y=(-_cross*_dx)/_drSq+center[1]; - Node *intersect3=new Node(x,y); intersect3->declareOnTangent(); - bool i_1S=_e1.getStartNode()->isEqual(*intersect3); - bool i_1E=_e1.getEndNode()->isEqual(*intersect3); - bool i_2S=_e2.getStartNode()->isEqual(*intersect3); - bool i_2E=_e2.getEndNode()->isEqual(*intersect3); - ret.push_back(IntersectElement(_e1.getCharactValue(*intersect3),_e2.getCharactValue(*intersect3),i_1S,i_1E,i_2S,i_2E,intersect3,_e1,_e2,keepOrder())); - } - return ret; -} - -EdgeArcCircle::EdgeArcCircle(std::istream& lineInXfig) -{ - const unsigned NB_OF_SKIP_FIELDS=15; - std::string tmpS; - for(unsigned i=0;i> tmpS; - _start=new Node(lineInXfig); - Node *middle=new Node(lineInXfig); - _end=new Node(lineInXfig); - GetArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); - middle->decrRef(); - updateBounds(); -} - -EdgeArcCircle::EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction):Edge(start,end, direction) -{ - GetArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -EdgeArcCircle::EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY):Edge(sX,sY,eX,eY) -{ - double middle[2]; middle[0]=mX; middle[1]=mY; - GetArcOfCirclePassingThru(*_start,middle,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -/*! - * @param angle0 in ]-Pi;Pi[ - * @param deltaAngle in ]-2.*Pi;2.*Pi[ - */ -EdgeArcCircle::EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction):Edge(start,end,direction),_angle(deltaAngle), - _angle0(angle0),_radius(radius) -{ - _center[0]=center[0]; - _center[1]=center[1]; - updateBounds(); -} - -void EdgeArcCircle::changeMiddle(Node *newMiddle) -{ - GetArcOfCirclePassingThru(*_start,*newMiddle,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -Edge *EdgeArcCircle::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const -{ - double sx=((*start)[0]-_center[0])/_radius; - double sy=((*start)[1]-_center[1])/_radius; - double ex=((*end)[0]-_center[0])/_radius; - double ey=((*end)[1]-_center[1])/_radius; - double angle0=GetAbsoluteAngleOfNormalizedVect(direction?sx:ex,direction?sy:ey); - double deltaAngle=GetAbsoluteAngleOfNormalizedVect(sx*ex+sy*ey,sx*ey-sy*ex); - if(deltaAngle>0. && _angle<0.) - deltaAngle-=2.*M_PI; - else if(deltaAngle<0. && _angle>0.) - deltaAngle+=2.*M_PI; - deltaAngle=direction?deltaAngle:-deltaAngle; - return new EdgeArcCircle(start,end,_center,_radius,angle0,deltaAngle,direction); -} - -void EdgeArcCircle::applySimilarity(double xBary, double yBary, double dimChar) -{ - Edge::applySimilarity(xBary,yBary,dimChar); - _radius/=dimChar; - _center[0]=(_center[0]-xBary)/dimChar; - _center[1]=(_center[1]-yBary)/dimChar; -} - -void EdgeArcCircle::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - Edge::unApplySimilarity(xBary,yBary,dimChar); - _radius*=dimChar; - _center[0]=_center[0]*dimChar+xBary; - _center[1]=_center[1]*dimChar+yBary; -} - -/*! - * 'eps' is expected to be > 0. - * 'conn' is of size 3. conn[0] is start id, conn[1] is end id and conn[2] is middle id. - * 'offset' is typically the number of nodes already existing in global 2D curve mesh. Additionnal coords 'addCoo' ids will be put after the already existing. - */ -void EdgeArcCircle::tesselate(const int *conn, int offset, double eps, std::vector& newConn, std::vector& addCoo) const -{ - newConn.push_back(INTERP_KERNEL::NORM_POLYL); - int nbOfSubDiv=(int)(fabs(_angle)/eps); - if(nbOfSubDiv<=2) - { - newConn.push_back(conn[0]); newConn.push_back(conn[2]); newConn.push_back(conn[1]); - return ; - } - double signOfAngle=_angle>0.?1.:-1.; - int offset2=offset+((int)addCoo.size())/2; - newConn.push_back(conn[0]); - for(int i=1;idecrRef(); middle->decrRef(); end->decrRef(); - return 0; - } - else - { - EdgeArcCircle *ret=new EdgeArcCircle(start,middle,end); - start->decrRef(); middle->decrRef(); end->decrRef(); - return ret; - } -} - -/*! - * Given an \b NON normalized vector 'vect', returns its norm 'normVect' and its - * angle in ]-Pi,Pi] relative to Ox axe. - */ -double EdgeArcCircle::GetAbsoluteAngle(const double *vect, double& normVect) -{ - normVect=Node::norm(vect); - return GetAbsoluteAngleOfNormalizedVect(vect[0]/normVect,vect[1]/normVect); -} - -/*! - * Given a \b normalized vector defined by (ux,uy) returns its angle in ]-Pi;Pi]. - * So before using this method ux*ux+uy*uy should as much as possible close to 1. - * This methods is quite time consuming in order to keep as much as possible precision. - * It is NOT ALWAYS possible to do that only in one call of acos. Sometimes call to asin is necessary - * due to imperfection of acos near 0. and Pi (cos x ~ 1-x*x/2.) - */ -double EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(double ux, double uy) -{ - return atan2(uy, ux); -} - -void EdgeArcCircle::GetArcOfCirclePassingThru(const double *start, const double *middle, const double *end, - double *center, double& radius, double& angleInRad, double& angleInRad0) -{ - double delta=(middle[0]-start[0])*(end[1]-middle[1])-(end[0]-middle[0])*(middle[1]-start[1]); - double b1=(middle[1]*middle[1]+middle[0]*middle[0]-start[0]*start[0]-start[1]*start[1])/2; - double b2=(end[1]*end[1]+end[0]*end[0]-middle[0]*middle[0]-middle[1]*middle[1])/2; - center[0]=((end[1]-middle[1])*b1+(start[1]-middle[1])*b2)/delta; - center[1]=((middle[0]-end[0])*b1+(middle[0]-start[0])*b2)/delta; - radius=SafeSqrt((start[0]-center[0])*(start[0]-center[0])+(start[1]-center[1])*(start[1]-center[1])); - angleInRad0=GetAbsoluteAngleOfNormalizedVect((start[0]-center[0])/radius,(start[1]-center[1])/radius); - double angleInRadM=GetAbsoluteAngleOfNormalizedVect((middle[0]-center[0])/radius,(middle[1]-center[1])/radius); - angleInRad=GetAbsoluteAngleOfNormalizedVect(((start[0]-center[0])*(end[0]-center[0])+(start[1]-center[1])*(end[1]-center[1]))/(radius*radius), - ((start[0]-center[0])*(end[1]-center[1])-(start[1]-center[1])*(end[0]-center[0]))/(radius*radius)); - if(IsAngleNotIn(angleInRad0,angleInRad,angleInRadM)) - angleInRad=angleInRad<0?2*M_PI+angleInRad:angleInRad-2*M_PI; -} - -void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const -{ - stream << "5 1 0 1 "; - fillXfigStreamForLoc(stream); - stream << " 7 50 -1 -1 0.000 0 "; - if( (direction && (-_angle)>=0) || (!direction && (-_angle)<0)) - stream << '0';//'0' - else - stream << '1';//'1' - stream << " 1 0 "; - stream << box.fitXForXFigD(_center[0],resolution) << " " << box.fitYForXFigD(_center[1],resolution) << " "; - direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); - Node *middle=buildRepresentantOfMySelf(); - middle->dumpInXfigFile(stream,resolution,box); - middle->decrRef(); - direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); - stream << std::endl << "1 1 2.00 120.00 180.00" << std::endl; -} - -void EdgeArcCircle::update(Node *m) -{ - GetArcOfCirclePassingThru(*_start,*m,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -/*! - * This methods computes : - * \f[ - * \int_{Current Edge} -ydx - * \f] - */ -double EdgeArcCircle::getAreaOfZone() const -{ - return -_radius*_radius*(sin(_angle)-_angle)/2.+((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; -} - -double EdgeArcCircle::getCurveLength() const -{ - return fabs(_angle*_radius); -} - -void EdgeArcCircle::getBarycenter(double *bary) const -{ - bary[0]=_center[0]+_radius*cos(_angle0+_angle/2.); - bary[1]=_center[1]+_radius*sin(_angle0+_angle/2.); -} - -/*! - * \f[ - * bary[0]=\int_{Current Edge} -yxdx - * \f] - * \f[ - * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx - * \f] - * To compute these 2 expressions in this class we have : - * \f[ - * x=x_{0}+Radius \cdot cos(\theta) - * \f] - * \f[ - * y=y_{0}+Radius \cdot sin(\theta) - * \f] - * \f[ - * dx=-Radius \cdot sin(\theta) \cdot d\theta - * \f] - */ -void EdgeArcCircle::getBarycenterOfZone(double *bary) const -{ - double x0=_center[0]; - double y0=_center[1]; - double angle1=_angle0+_angle; - double tmp1=sin(angle1); - double tmp0=sin(_angle0); - double tmp2=_radius*_radius*_radius; - double tmp3=cos(angle1); - double tmp4=cos(_angle0); - bary[0]=_radius*x0*y0*(tmp4-tmp3)+_radius*_radius*(y0*(cos(2*_angle0)-cos(2*angle1))/4.+ - x0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.)) - +tmp2*(tmp1*tmp1*tmp1-tmp0*tmp0*tmp0)/3.; - bary[1]=y0*y0*_radius*(tmp4-tmp3)/2.+_radius*_radius*y0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.) - +tmp2*(tmp4-tmp3+(tmp3*tmp3*tmp3-tmp4*tmp4*tmp4)/3.)/2.; -} - -/** - * Compute the "middle" of two points on the arc of circle. - * The order (p1,p2) or (p2,p1) doesn't matter. p1 and p2 have to be localized on the edge defined by this. - * \param[out] mid the point located half-way between p1 and p2 on the arc defined by this. - * \sa getMiddleOfPointsOriented() a generalisation working also when p1 and p2 are not on the arc. - */ -void EdgeArcCircle::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const -{ - double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); - double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); - // - double myDelta1(angle1-_angle0),myDelta2(angle2-_angle0); - if(_angle>0.) - { myDelta1=myDelta1>-QUADRATIC_PLANAR::_precision?myDelta1:myDelta1+2.*M_PI; myDelta2=myDelta2>-QUADRATIC_PLANAR::_precision?myDelta2:myDelta2+2.*M_PI; } - else - { myDelta1=myDelta1_angle (i.e. by the orientation of the arc). - * This function is sensitive to the ordering of p1 and p2. - * \param[out] mid the point located half-way between p1 and p2 - * \sa getMiddleOfPoints() to be used when the order of p1 and p2 is not relevant. - */ -void EdgeArcCircle::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const -{ - double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); - double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); - - if (angle1 <= 0.0) - angle1 += 2.*M_PI; - if (angle2 <= 0.0) - angle2 += 2.*M_PI; - - double avg; - if((_angle>0. && angle1 <= angle2) || (_angle<=0. && angle1 >= angle2)) - avg = (angle1+angle2)/2.; - else - avg = (angle1+angle2)/2. - M_PI; - - mid[0]=_center[0]+_radius*cos(avg); - mid[1]=_center[1]+_radius*sin(avg); -} - - -/*! - * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. - */ -bool EdgeArcCircle::isIn(double characterVal) const -{ - return IsIn2Pi(_angle0,_angle,characterVal); -} - -Node *EdgeArcCircle::buildRepresentantOfMySelf() const -{ - return new Node(_center[0]+_radius*cos(_angle0+_angle/2.),_center[1]+_radius*sin(_angle0+_angle/2.)); -} - -/*! - * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. - * 'val1' and 'val2' have been detected previously as owning to this. - */ -bool EdgeArcCircle::isLower(double val1, double val2) const -{ - double myDelta1=val1-_angle0; - double myDelta2=val2-_angle0; - if(_angle>0.) - { - myDelta1=myDelta1>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta1:myDelta1+2.*M_PI;//in some cases val1 or val2 are so close to angle0 that myDelta is close to 0. but negative. - myDelta2=myDelta2>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta2:myDelta2+2.*M_PI; - return myDelta10.) - myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; - else - myDelta=myDelta<=0.?myDelta:myDelta-2.*M_PI; - return myDelta/_angle; -} - -double EdgeArcCircle::getDistanceToPoint(const double *pt) const -{ - double angle=Node::computeAngle(_center,pt); - if(IsIn2Pi(_angle0,_angle,angle)) - return fabs(Node::distanceBtw2Pt(_center,pt)-_radius); - else - { - double dist1=Node::distanceBtw2Pt(*_start,pt); - double dist2=Node::distanceBtw2Pt(*_end,pt); - return std::min(dist1,dist2); - } -} - -bool EdgeArcCircle::isNodeLyingOn(const double *coordOfNode) const -{ - double dist=Node::distanceBtw2Pt(_center,coordOfNode); - if(Node::areDoubleEquals(dist,_radius)) - { - double angle=Node::computeAngle(_center,coordOfNode); - return IsIn2Pi(_angle0,_angle,angle); - } - else - return false; -} - -/*! - * Idem IsAngleNotIn except that here 'start' in ]-Pi;Pi[ and delta in ]-2*Pi;2Pi[. - * @param angleIn in ]-Pi;Pi[. - */ -bool EdgeArcCircle::IsIn2Pi(double start, double delta, double angleIn) -{ - double myDelta=angleIn-start; - if(delta>0.) - { - myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; - return myDelta>0. && myDeltadelta; - } -} - -/*! - * Given the arc 'a' defined by 'start' angle and a 'delta' [-Pi;Pi] states for the angle 'angleIn' [-Pi;Pi] if it owns or not 'a'. - */ -bool EdgeArcCircle::IsAngleNotIn(double start, double delta, double angleIn) -{ - double tmp=start; - if(tmp<0.) - tmp+=2*M_PI; - double tmp2=angleIn; - if(tmp2<0.) - tmp2+=2*M_PI; - if(tmp+delta>=2.*M_PI) - return (tmp2tmp+delta-2*M_PI); - else if(tmp+delta>=0.) - return (tmp2std::max(tmp,tmp+delta)); - else - return (tmp2>tmp) && (tmp2<(tmp+delta+2.*M_PI)); -} - -void EdgeArcCircle::updateBounds() -{ - _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); - if(IsIn2Pi(_angle0,_angle,M_PI/2)) - _bounds[3]=_center[1]+_radius; - if(IsIn2Pi(_angle0,_angle,-M_PI/2)) - _bounds[2]=_center[1]-_radius; - if(IsIn2Pi(_angle0,_angle,0.)) - _bounds[1]=_center[0]+_radius; - if(IsIn2Pi(_angle0,_angle,M_PI)) - _bounds[0]=_center[0]-_radius; -} - -void EdgeArcCircle::fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const -{ - int tmp[2]; - _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp); - _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1); - if(direction) - { - edgesThis.push_back(tmp[0]); - edgesThis.push_back(tmp[1]); - } - else - { - edgesThis.push_back(tmp[1]); - edgesThis.push_back(tmp[0]); - } -} - -void EdgeArcCircle::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const -{ - _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); - _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx deleted file mode 100644 index 382077bc4..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DEDGEARCCIRCLE_HXX__ -#define __INTERPKERNELGEO2DEDGEARCCIRCLE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT ArcCArcCIntersector : public SameTypeEdgeIntersector - { - public: - ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2); - bool haveTheySameDirection() const; - bool areColinears() const; - void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; - void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); - std::list< IntersectElement > getIntersectionsCharacteristicVal() const; - private: - //! return angle in ]-Pi;Pi[ - 'node' must be on curve of '_e1' - double getAngle(Node *node) const; - static bool internalAreColinears(const EdgeArcCircle& a1, const EdgeArcCircle& a2, double& distBetweenCenters, double& cst, double& radiusL, double centerL[2], double& raduisB, double centerB[2]); - static bool areArcsOverlapped(const EdgeArcCircle& a1, const EdgeArcCircle& a2); - private: - const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } - const EdgeArcCircle& getE2() const { return (const EdgeArcCircle&)_e2; } - private: - double _dist; - }; - - class INTERPKERNEL_EXPORT ArcCSegIntersector : public CrossTypeEdgeIntersector - { - public: - ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse=true); - //virtual overloading - bool areColinears() const; - void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; - void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); - std::list< IntersectElement > getIntersectionsCharacteristicVal() const; - private: - const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } - const EdgeLin& getE2() const { return (const EdgeLin&)_e2; } - private: - double _dx; - double _dy; - double _drSq; - double _cross; - double _determinant; - }; - - class INTERPKERNEL_EXPORT EdgeArcCircle : public Edge - { - public: - EdgeArcCircle(std::istream& lineInXfig); - EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction = true); - EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY); - EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction=true); - //! for tests - void changeMiddle(Node *newMiddle); - void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; - void update(Node *m); - double getAreaOfZone() const; - double getCurveLength() const; - void getBarycenter(double *bary) const; - void getBarycenterOfZone(double *bary) const; - void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; - void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const; - bool isIn(double characterVal) const; - Node *buildRepresentantOfMySelf() const; - bool isLower(double val1, double val2) const; - double getCharactValue(const Node& node) const; - double getCharactValueBtw0And1(const Node& node) const; - double getDistanceToPoint(const double *pt) const; - bool isNodeLyingOn(const double *coordOfNode) const; - TypeOfFunction getTypeOfFunc() const { return ARC_CIRCLE; } - void dynCastFunction(const EdgeLin * &seg, - const EdgeArcCircle * &arcSeg) const { arcSeg=this; } - const double *getCenter() const { return _center; } - void getCenter(double *center) const { center[0]=_center[0]; center[1]=_center[1]; } - bool doIHaveSameDirectionAs(const Edge& other) const { return false; } - void applySimilarity(double xBary, double yBary, double dimChar); - void unApplySimilarity(double xBary, double yBary, double dimChar); - double getAngle0() const { return _angle0; } - double getRadius() const { return _radius; } - double getAngle() const { return _angle; } - void tesselate(const int *conn, int offset, double eps, std::vector& newConn, std::vector& addCoo) const; - static EdgeArcCircle *BuildFromNodes(Node *start, Node *middle, Node *end); - static double GetAbsoluteAngle(const double *vect, double& normVect); - static double GetAbsoluteAngleOfNormalizedVect(double ux, double uy); - static void GetArcOfCirclePassingThru(const double *start, const double *middle, const double *end, - double *center, double& radius, double& angleInRad, double& angleInRad0); - //! To avoid in aggressive optimizations nan. - static double SafeSqrt(double val) { double ret=std::max(val,0.); return sqrt(ret); } - static double SafeAcos(double cosAngle) { double ret=std::min(cosAngle,1.); ret=std::max(ret,-1.); return acos(ret); } - static double SafeAsin(double sinAngle) { double ret=std::min(sinAngle,1.); ret=std::max(ret,-1.); return asin(ret); } - //! @param start and @param angleIn in ]-Pi;Pi] and @param delta in ]-2*Pi,2*Pi[ - static bool IsIn2Pi(double start, double delta, double angleIn); - //! 'delta' 'start' in ]-Pi;Pi[ - static bool IsAngleNotIn(double start, double delta, double angleIn); - //! for an angle 'angle' in ]-3*Pi;3*Pi[ returns angle in ]-Pi;Pi[ - static double NormalizeAngle(double angle) { if(angle>M_PI) return angle-2.*M_PI; if(angle<-M_PI) return angle+2.*M_PI; return angle; } - protected: - void updateBounds(); - Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const; - void fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const; - void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const; - protected: - //!Value between -2Pi and 2Pi - double _angle; - //!Value between -Pi and Pi - double _angle0; - double _radius; - double _center[2]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx deleted file mode 100644 index 9f669194d..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DEdgeInfLin.hxx" - -using namespace INTERP_KERNEL; - -EdgeInfLin::EdgeInfLin(Node *pointPassingThrough, double slope) -{ - _start=pointPassingThrough; - _start->incrRef(); - _end=new Node((*_start)[0]+cos(slope),(*_start)[1]+sin(slope)); -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx deleted file mode 100644 index c4942765f..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DEDGEINFLIN_HXX__ -#define __INTERPKERNELGEO2DEDGEINFLIN_HXX__ - -#include "InterpKernelGeo2DEdgeLin.hxx" - -namespace INTERP_KERNEL -{ - class EdgeInfLin : public EdgeLin - { - public: - EdgeInfLin(Node *start, Node *end):EdgeLin(start,end,true) { } - EdgeInfLin(Node *pointPassingThrough, double slope); - bool isIn(double characterVal) const { return true; } - void dynCastFunction(const EdgeLin * &seg, - const EdgeArcCircle * &arcSeg) const { seg=this; } - protected: - ~EdgeInfLin() { } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx deleted file mode 100644 index 0ea63b722..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "InterpKernelException.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -using namespace INTERP_KERNEL; - -namespace INTERP_KERNEL -{ - extern const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; -} - -SegSegIntersector::SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2):SameTypeEdgeIntersector(e1,e2) -{ - _matrix[0]=(*(e2.getStartNode()))[0]-(*(e2.getEndNode()))[0]; - _matrix[1]=(*(e1.getEndNode()))[0]-(*(e1.getStartNode()))[0]; - _matrix[2]=(*(e2.getStartNode()))[1]-(*(e2.getEndNode()))[1]; - _matrix[3]=(*(e1.getEndNode()))[1]-(*(e1.getStartNode()))[1]; - _col[0]=_matrix[3]*(*(e1.getStartNode()))[0]-_matrix[1]*(*(e1.getStartNode()))[1]; - _col[1]=-_matrix[2]*(*(e2.getStartNode()))[0]+_matrix[0]*(*(e2.getStartNode()))[1]; - //Little trick to avoid problems if 'e1' and 'e2' are colinears and along Ox or Oy axes. - if(fabs(_matrix[3])>fabs(_matrix[1])) - _ind=0; - else - _ind=1; -} - -/*! - * Must be called when 'this' and 'other' have been detected to be at least colinear. Typically they are overlapped. - * Must be called after call of areOverlappedOrOnlyColinears. - */ -bool SegSegIntersector::haveTheySameDirection() const -{ - return (_matrix[3]*_matrix[1]+_matrix[2]*_matrix[0])>0.; - //return (_matrix[_ind?1:0]>0. && _matrix[_ind?3:2]>0.) || (_matrix[_ind?1:0]<0. && _matrix[_ind?3:2]<0.); -} - -/*! - * Precondition start and end must be so that there predecessor was in the same direction than 'e1' - */ -void SegSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const -{ - getCurveAbscisse(start,whereStart,commonNode); - getCurveAbscisse(end,whereEnd,commonNode); -} - -void SegSegIntersector::getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const -{ - bool obvious; - obviousCaseForCurvAbscisse(node,where,commonNode,obvious); - if(obvious) - return ; - double ret=((*node)[!_ind]-(*_e1.getStartNode())[!_ind])/((*_e1.getEndNode())[!_ind]-(*_e1.getStartNode())[!_ind]); - if(ret>0. && ret <1.) - where=INSIDE; - else if(ret<0.) - where=OUT_BEFORE; - else - where=OUT_AFTER; -} - -/*! - * areColinears method should be called before with a returned colinearity equal to false to avoid bad news. - */ -std::list< IntersectElement > SegSegIntersector::getIntersectionsCharacteristicVal() const -{ - std::list< IntersectElement > ret; - double x=_matrix[0]*_col[0]+_matrix[1]*_col[1]; - double y=_matrix[2]*_col[0]+_matrix[3]*_col[1]; - //Only one intersect point possible - Node *node=new Node(x,y); - node->declareOn(); - bool i_1S=_e1.getStartNode()->isEqual(*node); - bool i_1E=_e1.getEndNode()->isEqual(*node); - bool i_2S=_e2.getStartNode()->isEqual(*node); - bool i_2E=_e2.getEndNode()->isEqual(*node); - ret.push_back(IntersectElement(_e1.getCharactValue(*node), - _e2.getCharactValue(*node), - i_1S,i_1E,i_2S,i_2E,node,_e1,_e2,keepOrder())); - return ret; -} - -/*! - * retrieves if segs are colinears. - * WARNING !!! Contrary to areOverlappedOrOnlyColinears method, this method use an - * another precision to detect colinearity ! - */ -bool SegSegIntersector::areColinears() const -{ - double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2]; - return fabs(determinant)2.*QUADRATIC_PLANAR::_precision)//2*_precision due to max of offset on _start and _end - { - colinearity=false; areOverlapped=false; - _matrix[0]/=determinant; _matrix[1]/=determinant; _matrix[2]/=determinant; _matrix[3]/=determinant; - } - else - { - colinearity=true; - //retrieving initial matrix - double tmp=_matrix[0]; _matrix[0]=_matrix[3]; _matrix[3]=tmp; - _matrix[1]=-_matrix[1]; _matrix[2]=-_matrix[2]; - // - double deno=sqrt(_matrix[0]*_matrix[0]+_matrix[1]*_matrix[1]); - double x=(*(_e1.getStartNode()))[0]-(*(_e2.getStartNode()))[0]; - double y=(*(_e1.getStartNode()))[1]-(*(_e2.getStartNode()))[1]; - areOverlapped=fabs((_matrix[1]*y+_matrix[0]*x)/deno)0. && characterVal<1.; -} - -Node *EdgeLin::buildRepresentantOfMySelf() const -{ - return new Node(((*(_start))[0]+(*(_end))[0])/2.,((*(_start))[1]+(*(_end))[1])/2.); -} - -double EdgeLin::getCharactValue(const Node& node) const -{ - return getCharactValueEng(node); -} - -double EdgeLin::getCharactValueBtw0And1(const Node& node) const -{ - return getCharactValueEng(node); -} - -double EdgeLin::getDistanceToPoint(const double *pt) const -{ - double loc=getCharactValueEng(pt); - if(loc>0. && loc<1.) - { - double tmp[2]; - tmp[0]=(*_start)[0]*(1-loc)+loc*(*_end)[0]; - tmp[1]=(*_start)[1]*(1-loc)+loc*(*_end)[1]; - return Node::distanceBtw2Pt(pt,tmp); - } - else - { - double dist1=Node::distanceBtw2Pt(*_start,pt); - double dist2=Node::distanceBtw2Pt(*_end,pt); - return std::min(dist1,dist2); - } -} - -bool EdgeLin::isNodeLyingOn(const double *coordOfNode) const -{ - double dBase=sqrt(_start->distanceWithSq(*_end)); - double d1=Node::distanceBtw2Pt(*_start,coordOfNode); - d1+=Node::distanceBtw2Pt(*_end,coordOfNode); - return Node::areDoubleEquals(dBase,d1); -} - -void EdgeLin::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const -{ - stream << "2 1 0 1 "; - fillXfigStreamForLoc(stream); - stream << " 7 50 -1 -1 0.000 0 0 -1 1 0 2" << std::endl << "1 1 1.00 60.00 120.00" << std::endl; - direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); - direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); - stream << std::endl; -} - -void EdgeLin::update(Node *m) -{ - updateBounds(); -} - -double EdgeLin::getNormSq() const -{ - return _start->distanceWithSq(*_end); -} - -/*! - * This methods computes : - * \f[ - * \int_{Current Edge} -ydx - * \f] - */ -double EdgeLin::getAreaOfZone() const -{ - return ((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; -} - -void EdgeLin::getBarycenter(double *bary) const -{ - bary[0]=((*_start)[0]+(*_end)[0])/2.; - bary[1]=((*_start)[1]+(*_end)[1])/2.; -} - -/*! - * \f[ - * bary[0]=\int_{Current Edge} -yxdx - * \f] - * \f[ - * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx - * \f] - * To compute these 2 expressions in this class we have : - * \f[ - * y=y_{1}+\frac{y_{2}-y_{1}}{x_{2}-x_{1}}(x-x_{1}) - * \f] - */ -void EdgeLin::getBarycenterOfZone(double *bary) const -{ - double x1=(*_start)[0]; - double y1=(*_start)[1]; - double x2=(*_end)[0]; - double y2=(*_end)[1]; - bary[0]=(x1-x2)*(y1*(2.*x1+x2)+y2*(2.*x2+x1))/6.; - //bary[0]+=(y1-y2)*(x2*x2/3.-(x1*x2+x1*x1)/6.)+y1*(x1*x1-x2*x2)/2.; - //bary[0]+=(y1-y2)*((x2*x2+x1*x2+x1*x1)/3.-(x2+x1)*x1/2.)+y1*(x1*x1-x2*x2)/2.; - bary[1]=(x1-x2)*(y1*(y1+y2)+y2*y2)/6.; -} - -/*! - * Here \a this is not used (contrary to EdgeArcCircle class). - */ -void EdgeLin::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const -{ - mid[0]=(p1[0]+p2[0])/2.; - mid[1]=(p1[1]+p2[1])/2.; -} - -double EdgeLin::getCurveLength() const -{ - double x=(*_start)[0]-(*_end)[0]; - double y=(*_start)[1]-(*_end)[1]; - return sqrt(x*x+y*y); -} - -Edge *EdgeLin::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const -{ - return new EdgeLin(start,end,direction); -} - -/*! - * No precision should be introduced here. Just think as if precision was perfect. - */ -void EdgeLin::updateBounds() -{ - _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); -} - -double EdgeLin::getCharactValueEng(const double *node) const -{ - double car1_1x=node[0]-(*(_start))[0]; double car1_2x=(*(_end))[0]-(*(_start))[0]; - double car1_1y=node[1]-(*(_start))[1]; double car1_2y=(*(_end))[1]-(*(_start))[1]; - return (car1_1x*car1_2x+car1_1y*car1_2y)/(car1_2x*car1_2x+car1_2y*car1_2y); -} - -void EdgeLin::fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const -{ - int tmp[2]; - _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp); - _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1); - if(direction) - { - edgesThis.push_back(tmp[0]); - edgesThis.push_back(tmp[1]); - } - else - { - edgesThis.push_back(tmp[1]); - edgesThis.push_back(tmp[0]); - } -} - -void EdgeLin::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const -{ - _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); - _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx deleted file mode 100644 index fad4ada11..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DEDGELIN_HXX__ -#define __INTERPKERNELGEO2DEDGELIN_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT SegSegIntersector : SameTypeEdgeIntersector - { - friend class Edge; - public: - SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2); - bool areColinears() const; - bool haveTheySameDirection() const; - void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; - void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); - std::list< IntersectElement > getIntersectionsCharacteristicVal() const; - private: - void getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const; - private: - //! index on which all single index op will be performed. Filled in case colinearity is equal to true. - int _ind; - double _col[2]; - double _matrix[4];//SPACEDIM*SPACEDIM - }; - - class INTERPKERNEL_EXPORT EdgeLin : public Edge - { - friend class SegSegIntersector; - public: - EdgeLin(std::istream& lineInXfig); - EdgeLin(Node *start, Node *end, bool direction=true); - EdgeLin(double sX, double sY, double eX, double eY); - ~EdgeLin(); - TypeOfFunction getTypeOfFunc() const { return SEG; } - void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; - void update(Node *m); - double getNormSq() const; - double getAreaOfZone() const; - double getCurveLength() const; - void getBarycenter(double *bary) const; - void getBarycenterOfZone(double *bary) const; - void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; - bool isIn(double characterVal) const; - Node *buildRepresentantOfMySelf() const; - double getCharactValue(const Node& node) const; - double getCharactValueBtw0And1(const Node& node) const; - double getDistanceToPoint(const double *pt) const; - bool isNodeLyingOn(const double *coordOfNode) const; - bool isLower(double val1, double val2) const { return val1& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const; - void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx deleted file mode 100644 index 04089b219..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DEdge.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" - -using namespace INTERP_KERNEL; - -ElementaryEdge::ElementaryEdge(const ElementaryEdge& other):_direction(other._direction),_ptr(other._ptr) -{ - _ptr->incrRef(); -} - -ElementaryEdge::~ElementaryEdge() -{ - if(_ptr) - _ptr->decrRef(); -} - -bool ElementaryEdge::isNodeIn(Node *n) const -{ - return _ptr->getStartNode()==n || _ptr->getEndNode()==n; -} - -/*! - * \b WARNING contrary to INTERP_KERNEL::Edge::getBarycenterOfZone method called, - * this one is cumulative. - */ -void ElementaryEdge::getBarycenterOfZone(double *bary) const -{ - double tmp[2]; - _ptr->getBarycenterOfZone(tmp); - if(_direction) - { - bary[0]+=tmp[0]; - bary[1]+=tmp[1]; - } - else - { - bary[0]-=tmp[0]; - bary[1]-=tmp[1]; - } -} - -void ElementaryEdge::fillBounds(Bounds& output) const -{ - output.aggregate(_ptr->getBounds()); -} - -void ElementaryEdge::getAllNodes(std::set& output) const -{ - output.insert(_ptr->getStartNode()); - output.insert(_ptr->getEndNode()); -} - -void ElementaryEdge::getBarycenter(double *bary, double& weigh) const -{ - _ptr->getBarycenter(bary); - weigh=_ptr->getCurveLength(); -} - -ElementaryEdge *ElementaryEdge::clone() const -{ - return new ElementaryEdge(*this); -} - -void ElementaryEdge::initLocations() const -{ - _ptr->initLocs(); -} - -/*! - * WARNING use this method if and only if this is so that it is completely in/out/on of @param pol. - */ -TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const -{ - if(getLoc()!=FULL_UNKNOWN) - return getLoc(); - //obvious cases - if(precEdgeLoc==FULL_IN_1) - { - if(getStartNode()->getLoc()==ON_1) - { - declareOut(); - return getLoc(); - } - else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) - { - declareIn(); - return getLoc(); - } - } - if(precEdgeLoc==FULL_OUT_1) - { - if(getStartNode()->getLoc()==ON_1) - { - declareIn(); - return getLoc(); - } - else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) - { - declareOut(); - return getLoc(); - } - } - if(getStartNode()->getLoc()==IN_1 || getEndNode()->getLoc()==IN_1) - { - declareIn(); - return getLoc(); - } - if(getStartNode()->getLoc()==OUT_1 || getEndNode()->getLoc()==OUT_1) - { - declareOut(); - return getLoc(); - } - //a seek is requested - return locateFullyMySelfAbsolute(pol); -} - -TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelfAbsolute(const ComposedEdge& pol) const -{ - Node *node=_ptr->buildRepresentantOfMySelf(); // build barycenter used to detect if the edge is IN or OUT - if(pol.isInOrOut(node)) - declareIn(); - else - declareOut(); - node->decrRef(); - return getLoc(); -} - -Node *ElementaryEdge::getEndNode() const -{ - if(_direction) - return _ptr->getEndNode(); - else return _ptr->getStartNode(); -} - -Node *ElementaryEdge::getStartNode() const -{ - if(_direction) - return _ptr->getStartNode(); - else - return _ptr->getEndNode(); -} - -bool ElementaryEdge::changeEndNodeWith(Node *node) const -{ - if(_direction) - return _ptr->changeEndNodeWith(node); - else - return _ptr->changeStartNodeWith(node); -} - -bool ElementaryEdge::changeStartNodeWith(Node *node) const -{ - if(_direction) - return _ptr->changeStartNodeWith(node); - else - return _ptr->changeEndNodeWith(node); -} - -void ElementaryEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - _ptr->dumpInXfigFile(stream,_direction,resolution,box); -} - -bool ElementaryEdge::intresicEqual(const ElementaryEdge *other) const -{ - return _ptr==other->_ptr; -} - -bool ElementaryEdge::intresicEqualDirSensitive(const ElementaryEdge *other) const -{ - return ( _direction==other->_direction ) && (_ptr==other->_ptr); -} - -bool ElementaryEdge::intresincEqCoarse(const Edge *other) const -{ - return _ptr==other; -} - -bool ElementaryEdge::isEqual(const ElementaryEdge& other) const -{ - return _ptr->isEqual(*other._ptr); -} - -/*! - * Called by QuadraticPolygon::splitAbs method. - */ -void ElementaryEdge::fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const -{ - _ptr->fillGlobalInfoAbs(_direction,mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesThis,addCoo,mapAddCoo); -} - -/*! - * Called by QuadraticPolygon::splitAbs method. Close to ElementaryEdge::fillGlobalInfoAbs method expect that here edgesOther (that replace edgesThis) is here an in/out parameter that only contains nodes - * unsorted because the "other" mesh is not subdivided yet. - */ -void ElementaryEdge::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const -{ - _ptr->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesOther,addCoo,mapAddCoo); -} - -/*! - * This method builds from a \a start node, an \a end node and a direction a new ElementaryEdge. - */ -ElementaryEdge *ElementaryEdge::BuildEdgeFromStartEndDir(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end) -{ - Edge *ptr=Edge::BuildEdgeFrom(start,end); - return new ElementaryEdge(ptr,direction); -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx deleted file mode 100644 index 1c3cdefa9..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DELEMENTARYEDGE_HXX__ -#define __INTERPKERNELGEO2DELEMENTARYEDGE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -namespace INTERP_KERNEL -{ - class ElementaryEdge - { - public: - INTERPKERNEL_EXPORT ElementaryEdge(Edge *ptr, bool direction):_direction(direction),_ptr(ptr) { } - INTERPKERNEL_EXPORT ElementaryEdge(const ElementaryEdge& other); - INTERPKERNEL_EXPORT ~ElementaryEdge(); - INTERPKERNEL_EXPORT bool isThereStartPoint() const { return _iterator.isValid(); } - INTERPKERNEL_EXPORT IteratorOnComposedEdge& getIterator() { return _iterator; } - INTERPKERNEL_EXPORT bool completed() const { return false; } - INTERPKERNEL_EXPORT void declareOn() const { _ptr->declareOn(); } - INTERPKERNEL_EXPORT void declareIn() const { _ptr->declareIn(); } - INTERPKERNEL_EXPORT void declareOut() const { _ptr->declareOut(); } - INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon getLoc() const { return _ptr->getLoc(); } - INTERPKERNEL_EXPORT Edge *getPtr() const { return _ptr; } - INTERPKERNEL_EXPORT void reverse() { _direction=(!_direction); } - INTERPKERNEL_EXPORT bool isNodeIn(Node *n) const; - INTERPKERNEL_EXPORT double getAreaOfZone() const { double ret=_ptr->getAreaOfZone(); return _direction?ret:-ret; } - INTERPKERNEL_EXPORT void getBarycenterOfZone(double *bary) const; - INTERPKERNEL_EXPORT void fillBounds(Bounds& output) const; - INTERPKERNEL_EXPORT void applySimilarity(double xBary, double yBary, double dimChar) { _ptr->applySimilarity(xBary,yBary,dimChar); } - INTERPKERNEL_EXPORT void unApplySimilarity(double xBary, double yBary, double dimChar) { _ptr->unApplySimilarity(xBary,yBary,dimChar); } - INTERPKERNEL_EXPORT void getAllNodes(std::set& output) const; - INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; - INTERPKERNEL_EXPORT ElementaryEdge *clone() const; - INTERPKERNEL_EXPORT void initLocations() const; - INTERPKERNEL_EXPORT int size() const; - INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon locateFullyMySelfAbsolute(const ComposedEdge& pol) const; - INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const; - INTERPKERNEL_EXPORT Node *getEndNode() const; - INTERPKERNEL_EXPORT Node *getStartNode() const; - INTERPKERNEL_EXPORT double getCurveLength() const { return _ptr->getCurveLength(); } - INTERPKERNEL_EXPORT bool changeEndNodeWith(Node *node) const; - INTERPKERNEL_EXPORT bool changeStartNodeWith(Node *node) const; - INTERPKERNEL_EXPORT bool intresicEqual(const ElementaryEdge *other) const; - INTERPKERNEL_EXPORT bool intresicEqualDirSensitive(const ElementaryEdge *other) const; - INTERPKERNEL_EXPORT void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - INTERPKERNEL_EXPORT bool getDirection() const { return _direction; } - INTERPKERNEL_EXPORT bool intresincEqCoarse(const Edge *other) const; - INTERPKERNEL_EXPORT bool isEqual(const ElementaryEdge& other) const; - public: - INTERPKERNEL_EXPORT void fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const; - INTERPKERNEL_EXPORT void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const; - INTERPKERNEL_EXPORT static ElementaryEdge *BuildEdgeFromStartEndDir(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end); - private: - bool _direction; - Edge *_ptr; - IteratorOnComposedEdge _iterator; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx deleted file mode 100644 index 72072b9c2..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DNode.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" - -using namespace INTERP_KERNEL; - -Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN) -{ - _coords[0]=x; _coords[1]=y; -} - -Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN) -{ - _coords[0]=coords[0]; - _coords[1]=coords[1]; -} - -Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN) -{ - int tmp; - stream >> tmp; - _coords[0]=((double) tmp)/1e4; - stream >> tmp; - _coords[1]=((double) tmp)/1e4; -} - -Node::~Node() -{ -} - -bool Node::decrRef() -{ - bool ret=(--_cnt==0); - if(ret) - delete this; - return ret; -} - -bool Node::isEqual(const Node& other) const -{ - const unsigned SPACEDIM=2; - bool ret=true; - for(unsigned i=0;i& track) const -{ - bool ret=isEqual(other); - if(ret) - track.push_back(const_cast(&other)); - return ret; -} - -void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " "; -} - -double Node::distanceWithSq(const Node& other) const -{ - return (_coords[0]-other._coords[0])*(_coords[0]-other._coords[0])+(_coords[1]-other._coords[1])*(_coords[1]-other._coords[1]); -} - -/*! - * WARNING different from 'computeAngle' method ! The returned value are not in the same interval ! - * Here in [0; Pi). Typically this method returns the same value by exchanging pt1 and pt2. - * Use in process of detection of a point in or not in polygon. - */ -double Node::computeSlope(const double *pt1, const double *pt2) -{ - double x=pt2[0]-pt1[0]; - double y=pt2[1]-pt1[1]; - double norm=sqrt(x*x+y*y); - double ret=EdgeArcCircle::SafeAcos(fabs(x)/norm); - if( (x>=0. && y>=0.) || (x<0. && y<0.) ) - return ret; - else - return M_PI-ret; -} - -/*! - * WARNING different from 'computeSlope' method. Here angle in -Pi;Pi is returned. - * This method is anti-symetric. - */ -double Node::computeAngle(const double *pt1, const double *pt2) -{ - double x=pt2[0]-pt1[0]; - double y=pt2[1]-pt1[1]; - double norm=sqrt(x*x+y*y); - return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(x/norm,y/norm); -} - -/*! - * apply a Similarity transformation on this. - * @param xBary is the opposite of the X translation to do. - * @param yBary is the opposite of the Y translation to do. - * @param dimChar is the reduction factor. - */ -void Node::applySimilarity(double xBary, double yBary, double dimChar) -{ - _coords[0]=(_coords[0]-xBary)/dimChar; - _coords[1]=(_coords[1]-yBary)/dimChar; -} - -/*! - * apply the reverse Similarity transformation on this. - * This method is the opposite of Node::applySimilarity method to retrieve the initial state. - * @param xBary is the opposite of the X translation to do. - * @param yBary is the opposite of the Y translation to do. - * @param dimChar is the reduction factor. - */ -void Node::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - _coords[0]=_coords[0]*dimChar+xBary; - _coords[1]=_coords[1]*dimChar+yBary; -} - -/*! - * Called by QuadraticPolygon::splitAbs method. - */ -void Node::fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, int *nodeId) const -{ - std::map::const_iterator it=mapThis.find(const_cast(this)); - if(it!=mapThis.end()) - { - *nodeId=(*it).second; - return; - } - it=mapOther.find(const_cast(this)); - if(it!=mapOther.end()) - { - *nodeId=(*it).second+offset1; - return; - } - it=mapAddCoo.find(const_cast(this)); - if(it!=mapAddCoo.end()) - { - *nodeId=(*it).second; - return; - } - int id=(int)addCoo.size()/2; - addCoo.push_back(fact*_coords[0]+baryX); - addCoo.push_back(fact*_coords[1]+baryY); - *nodeId=offset2+id; - mapAddCoo[const_cast(this)]=offset2+id; -} - -/*! - * Called by QuadraticPolygon::splitAbs method. - */ -void Node::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, std::vector& pointsOther) const -{ - int tmp; - std::size_t sz1=addCoo.size(); - fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,&tmp); - if(sz1!=addCoo.size()) - { - pointsOther.push_back(tmp); - return ; - } - std::vector::const_iterator it=std::find(pointsOther.begin(),pointsOther.end(),tmp); - if(it!=pointsOther.end()) - return ; - if(tmp -#include -#include -#include - -namespace INTERP_KERNEL -{ - typedef enum - { - IN_1 = 7, - ON_1 = 8, - ON_LIM_1 = 12, - ON_TANG_1 = 9, - OUT_1 = 10, - UNKNOWN = 11 - } TypeOfLocInPolygon; - - class Bounds; - - /*! - * Representation of a 2D point, and potentially its location relative to a polygon. - * As nodes can be shared between edges it is handled with ref counting. - */ - class INTERPKERNEL_EXPORT Node - { - public: - Node(double x, double y); - Node(const double *coords); - Node(std::istream& stream); - void incrRef() const { _cnt++; } - bool decrRef(); - void initHitStatus() const { _hit=0; } - char getHitStatus() const { return _hit; } - void hitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; applySimilarity(xBary,yBary,dimChar); } } - void unHitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; unApplySimilarity(xBary,yBary,dimChar); } } - void hitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { hitMeAlone(xBary,yBary,dimChar); _hit=2; } else if(_hit==1) declareOn(); } - void unHitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { unHitMeAlone(xBary,yBary,dimChar); _hit=2; } } - void initLocs() const { _loc=UNKNOWN; } - void setLoc(TypeOfLocInPolygon loc) const { _loc=loc; } - TypeOfLocInPolygon getLoc() const { return _loc; } - void declareIn() const { if(_loc==UNKNOWN) _loc=IN_1; } - void declareOn() const { if(_loc==UNKNOWN) _loc=ON_1; } - void declareOnLim() const { if(_loc==UNKNOWN || _loc==ON_1) _loc=ON_LIM_1; } - void declareOut() { if(_loc==UNKNOWN) _loc=OUT_1; } - void declareOnTangent() { _loc=ON_TANG_1; } - operator const double*() const { return _coords; } - bool isEqual(const Node& other) const; - //returns an angle in -Pi/2;Pi/2. - double getSlope(const Node& other) const; - bool isEqualAndKeepTrack(const Node& other, std::vector& track) const; - void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - double distanceWithSq(const Node& other) const; - double operator[](int i) const { return _coords[i]; } - //! use with caution - void setNewCoords(double x, double y) { _coords[0]=x; _coords[1]=y; } - //returns an angle in -Pi/2;Pi/2. - static double computeSlope(const double *pt1, const double *pt2); - //returns an angle in -Pi;Pi - static double computeAngle(const double *pt1, const double *pt2); - void applySimilarity(double xBary, double yBary, double dimChar); - void unApplySimilarity(double xBary, double yBary, double dimChar); - static double dot(const double *vect1, const double *vect2) { return vect1[0]*vect2[0]+vect1[1]*vect2[1]; } - static double sign(double val) { if(val>=0) return 1.; else return -1.; } - static double norm(const double *vect) { return sqrt(vect[0]*vect[0]+vect[1]*vect[1]); } - static bool areDoubleEquals(double a, double b) { return fabs(a-b) < QUADRATIC_PLANAR::_precision; } - //! idem areDoubleEquals except that precision of comparison is modified. - static bool areDoubleEqualsWP(double a, double b, double k) { return fabs(a-b) < k*QUADRATIC_PLANAR::_precision; } - static double distanceBtw2Pt(const double *a, const double *b) { return sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])); } - static double distanceBtw2PtSq(const double *a, const double *b) { return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); } - // - void fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, int *nodeId) const; - void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, std::vector& pointsOther) const; - protected: - ~Node(); - protected: - mutable char _hit; - mutable unsigned char _cnt; - mutable TypeOfLocInPolygon _loc; - double _coords[2]; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx deleted file mode 100644 index 14666d9d9..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DPrecision.hxx" - -double INTERP_KERNEL::QUADRATIC_PLANAR::_precision=1e-14; - -double INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1e-14; - -void INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(double precision) -{ - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=precision; -} - -void INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(double precision) -{ - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=precision; -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx deleted file mode 100644 index 4d494abce..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DPRECISION_HXX__ -#define __INTERPKERNELGEO2DPRECISION_HXX__ - -#include "INTERPKERNELDefines.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT QUADRATIC_PLANAR - { - public: - static double _precision; - static double _arc_detection_precision; - static void setPrecision(double precision); - static void setArcDetectionPrecision(double precision); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx deleted file mode 100644 index caed9530b..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ /dev/null @@ -1,1286 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DBounds.hxx" -#include "InterpKernelGeo2DEdge.txx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_KERNEL -{ - const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; -} - -QuadraticPolygon::QuadraticPolygon(const char *file) -{ - char currentLine[MAX_SIZE_OF_LINE_XFIG_FILE]; - std::ifstream stream(file); - stream.exceptions(std::ios_base::eofbit); - try - { - do - stream.getline(currentLine,MAX_SIZE_OF_LINE_XFIG_FILE); - while(strcmp(currentLine,"1200 2")!=0); - do - { - Edge *newEdge=Edge::BuildFromXfigLine(stream); - if(!empty()) - newEdge->changeStartNodeWith(back()->getEndNode()); - pushBack(newEdge); - } - while(1); - } - catch(std::ifstream::failure&) - { - } - front()->changeStartNodeWith(back()->getEndNode()); -} - -QuadraticPolygon::~QuadraticPolygon() -{ -} - -QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector& nodes) -{ - QuadraticPolygon *ret(new QuadraticPolygon); - std::size_t size=nodes.size(); - for(std::size_t i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%size])); - nodes[i]->decrRef(); - } - return ret; -} - -QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector& nodes) -{ - QuadraticPolygon *ret(new QuadraticPolygon); - std::size_t size=nodes.size(); - for(std::size_t i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)])); - else - ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)])); - nodes[i]->decrRef(); nodes[i+size/2]->decrRef(); - } - return ret; -} - -Edge *QuadraticPolygon::BuildLinearEdge(std::vector& nodes) -{ - if(nodes.size()!=2) - throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildLinearEdge : input vector is expected to be of size 2 !"); - Edge *ret(new EdgeLin(nodes[0],nodes[1])); - nodes[0]->decrRef(); nodes[1]->decrRef(); - return ret; -} - -Edge *QuadraticPolygon::BuildArcCircleEdge(std::vector& nodes) -{ - if(nodes.size()!=3) - throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildArcCircleEdge : input vector is expected to be of size 3 !"); - EdgeLin *e1(new EdgeLin(nodes[0],nodes[2])),*e2(new EdgeLin(nodes[2],nodes[1])); - SegSegIntersector inters(*e1,*e2); - bool colinearity=inters.areColinears(); - delete e1; delete e2; - Edge *ret(0); - if(colinearity) - ret=new EdgeLin(nodes[0],nodes[1]); - else - ret=new EdgeArcCircle(nodes[0],nodes[2],nodes[1]); - nodes[0]->decrRef(); nodes[1]->decrRef(); nodes[2]->decrRef(); - return ret; -} - -void QuadraticPolygon::BuildDbgFile(const std::vector& nodes, const char *fileName) -{ - std::ofstream file(fileName); - file << std::setprecision(16); - file << " double coords[]=" << std::endl << " { "; - for(std::vector::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) - { - if(iter!=nodes.begin()) - file << "," << std::endl << " "; - file << (*(*iter))[0] << ", " << (*(*iter))[1]; - } - file << "};" << std::endl; -} - -void QuadraticPolygon::closeMe() const -{ - if(!front()->changeStartNodeWith(back()->getEndNode())) - throw(Exception("big error: not closed polygon...")); -} - -void QuadraticPolygon::circularPermute() -{ - if(_sub_edges.size()>1) - { - ElementaryEdge *first=_sub_edges.front(); - _sub_edges.pop_front(); - _sub_edges.push_back(first); - } -} - -bool QuadraticPolygon::isButterflyAbs() -{ - INTERP_KERNEL::Bounds b; - double xBary,yBary; - b.prepareForAggregation(); - fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity(xBary,yBary,dimChar); - // - return isButterfly(); -} - -bool QuadraticPolygon::isButterfly() const -{ - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) - { - Edge *e1=(*it)->getPtr(); - std::list::const_iterator it2=it; - it2++; - for(;it2!=_sub_edges.end();it2++) - { - MergePoints commonNode; - ComposedEdge *outVal1=new ComposedEdge; - ComposedEdge *outVal2=new ComposedEdge; - Edge *e2=(*it2)->getPtr(); - if(e1->intersectWith(e2,commonNode,*outVal1,*outVal2)) - { - Delete(outVal1); - Delete(outVal2); - return true; - } - Delete(outVal1); - Delete(outVal2); - } - } - return false; -} - -void QuadraticPolygon::dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const -{ - std::ofstream file(fileName); - const int resolution=1200; - Bounds box; - box.prepareForAggregation(); - fillBounds(box); - other.fillBounds(box); - dumpInXfigFile(file,resolution,box); - other.ComposedEdge::dumpInXfigFile(file,resolution,box); -} - -void QuadraticPolygon::dumpInXfigFile(const char *fileName) const -{ - std::ofstream file(fileName); - const int resolution=1200; - Bounds box; - box.prepareForAggregation(); - fillBounds(box); - dumpInXfigFile(file,resolution,box); -} - -void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - stream << "#FIG 3.2 Produced by xfig version 3.2.5-alpha5" << std::endl; - stream << "Landscape" << std::endl; - stream << "Center" << std::endl; - stream << "Metric" << std::endl; - stream << "Letter" << std::endl; - stream << "100.00" << std::endl; - stream << "Single" << std::endl; - stream << "-2" << std::endl; - stream << resolution << " 2" << std::endl; - ComposedEdge::dumpInXfigFile(stream,resolution,box); -} - -/*! - * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. - */ -double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other) -{ - double ret=0.,xBaryBB,yBaryBB; - double fact=normalize(&other,xBaryBB,yBaryBB); - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - ret+=fabs((*iter)->getArea()); - delete *iter; - } - return ret*fact*fact; -} - -/*! - * This method splits 'this' with 'other' into smaller pieces localizable. 'mapThis' is a map that gives the correspondance - * between nodes contained in 'this' and node ids in a global mesh. - * In the same way, 'mapOther' gives the correspondance between nodes contained in 'other' and node ids in a - * global mesh from wich 'other' is extracted. - * This method has 1 out paramater : 'edgesThis', After the call of this method, it contains the nodal connectivity (including type) - * of 'this' into globlal "this mesh". - * This method has 2 in/out parameters : 'subDivOther' and 'addCoo'.'otherEdgeIds' is useful to put values in - * 'edgesThis', 'subDivOther' and 'addCoo'. - * Size of 'otherEdgeIds' has to be equal to number of ElementaryEdges in 'other'. No check of that will be done. - * The term 'abs' in the name recalls that we normalize the mesh (spatially) so that node coordinates fit into [0;1]. - * @param offset1 is the number of nodes contained in global mesh from which 'this' is extracted. - * @param offset2 is the sum of nodes contained in global mesh from which 'this' is extracted and 'other' is extracted. - * @param edgesInOtherColinearWithThis will be appended at the end of the vector with colinear edge ids of other (if any) - * @param otherEdgeIds is a vector with the same size than other before calling this method. It gives in the same order - * the cell id in global other mesh. - */ -void QuadraticPolygon::splitAbs(QuadraticPolygon& other, - const std::map& mapThis, const std::map& mapOther, - int offset1, int offset2 , - const std::vector& otherEdgeIds, - std::vector& edgesThis, int cellIdThis, - std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, - std::vector& addCoo, std::map& mergedNodes) -{ - double xBaryBB, yBaryBB; - double fact=normalizeExt(&other, xBaryBB, yBaryBB); - // - IteratorOnComposedEdge it1(this),it3(&other); - MergePoints merge; - ComposedEdge *c1=new ComposedEdge; - ComposedEdge *c2=new ComposedEdge; - int i=0; - std::map mapAddCoo; - for(it3.first();!it3.finished();it3.next(),i++)//iteration over 'other' _sub_edges - { - QuadraticPolygon otherTmp; - ElementaryEdge* curE3=it3.current(); - otherTmp.pushBack(new ElementaryEdge(curE3->getPtr(),curE3->getDirection())); curE3->getPtr()->incrRef(); - IteratorOnComposedEdge it2(&otherTmp); - for(it2.first();!it2.finished();it2.next())//iteration on subedges of 'other->_sub_edge' - { - ElementaryEdge* curE2=it2.current(); - if(!curE2->isThereStartPoint()) - it1.first(); - else - it1=curE2->getIterator(); - for(;!it1.finished();)//iteration over 'this' _sub_edges - { - ElementaryEdge* curE1=it1.current(); - merge.clear(); - // - std::map::const_iterator thisStart(mapThis.find(curE1->getStartNode())),thisEnd(mapThis.find(curE1->getEndNode())),otherStart(mapOther.find(curE2->getStartNode())),otherEnd(mapOther.find(curE2->getEndNode())); - int thisStart2(thisStart==mapThis.end()?-1:(*thisStart).second),thisEnd2(thisEnd==mapThis.end()?-1:(*thisEnd).second),otherStart2(otherStart==mapOther.end()?-1:(*otherStart).second+offset1),otherEnd2(otherEnd==mapOther.end()?-1:(*otherEnd).second+offset1); - // - if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) - { - if(!curE1->getDirection()) c1->reverse(); - if(!curE2->getDirection()) c2->reverse(); - UpdateNeighbours(merge,it1,it2,c1,c2); - //Substitution of simple edge by sub-edges. - delete curE1; // <-- destroying simple edge coming from pol1 - delete curE2; // <-- destroying simple edge coming from pol2 - it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. - it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. - curE2=it2.current(); - // - it1.assignMySelfToAllElems(c2);//To avoid that others - SoftDelete(c1); - SoftDelete(c2); - c1=new ComposedEdge; - c2=new ComposedEdge; - } - else - { - UpdateNeighbours(merge,it1,it2,curE1,curE2); - it1.next(); - } - merge.updateMergedNodes(thisStart2,thisEnd2,otherStart2,otherEnd2,mergedNodes); - } - } - if(otherTmp.presenceOfOn()) - edgesInOtherColinearWithThis[otherEdgeIds[i]].push_back(cellIdThis); - if(otherTmp._sub_edges.size()>1) - { - for(std::list::const_iterator it=otherTmp._sub_edges.begin();it!=otherTmp._sub_edges.end();it++) - (*it)->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/subDivOther[otherEdgeIds[i]],addCoo,mapAddCoo); - } - } - Delete(c1); - Delete(c2); - // - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) - (*it)->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/edgesThis,addCoo,mapAddCoo); - // -} - -/*! - * This method builds 'this' from its descending conn stored in crude mode (MEDCoupling). - * Descending conn is in FORTRAN relative mode in order to give the - * orientation of edge (see buildDescendingConnectivity2() method). - * See appendEdgeFromCrudeDataArray() for params description. - */ -void QuadraticPolygon::buildFromCrudeDataArray(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges) -{ - std::size_t nbOfSeg=std::distance(descBg,descEnd); - for(std::size_t i=0;i& mapp, bool isQuad, - const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges) -{ - if(!isQuad) - { - bool direct=descBg[edgePos]>0; - int edgeId=abs(descBg[edgePos])-1; // back to C indexing mode - const std::vector& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - for(std::size_t j=0;j0; - int edgeId=abs(descBg[edgePos])-1; - const std::vector& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - if(colinearity) - { - for(std::size_t j=0;jdecrRef(); - } - st0->decrRef(); endd0->decrRef(); middle0->decrRef(); - } -} - -void QuadraticPolygon::appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector& subEdge, const std::map& mapp) -{ - std::size_t nbOfSubEdges=subEdge.size()/2; - if(!baseEdge) - {//it is not a quadratic subedge - Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second; - Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second; - ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end); - pushBack(e); - } - else - {//it is a quadratic subedge - Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second; - Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second; - Edge *ee=baseEdge->buildEdgeLyingOnMe(start,end); - ElementaryEdge *eee=new ElementaryEdge(ee,true); - pushBack(eee); - } -} - -/*! - * This method builds from descending conn of a quadratic polygon stored in crude mode (MEDCoupling). Descending conn is in FORTRAN relative mode in order to give the - * orientation of edge. - */ -void QuadraticPolygon::buildFromCrudeDataArray2(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges, - const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector >& intersectEdges1, - const std::vector< std::vector >& colinear1, - std::map >& alreadyExistingIn2) -{ - std::size_t nbOfSeg=std::distance(descBg,descEnd); - for(std::size_t i=0;i0; - int edgeId=abs(descBg[i])-1;//current edge id of pol2 - std::map >::const_iterator it1=alreadyExistingIn2.find(descBg[i]),it2=alreadyExistingIn2.find(-descBg[i]); - if(it1!=alreadyExistingIn2.end() || it2!=alreadyExistingIn2.end()) - { - bool sameDir=(it1!=alreadyExistingIn2.end()); - const std::vector& edgesAlreadyBuilt=sameDir?(*it1).second:(*it2).second; - if(sameDir) - { - for(std::vector::const_iterator it3=edgesAlreadyBuilt.begin();it3!=edgesAlreadyBuilt.end();it3++) - { - Edge *ee=(*it3)->getPtr(); ee->incrRef(); - pushBack(new ElementaryEdge(ee,(*it3)->getDirection())); - } - } - else - { - for(std::vector::const_reverse_iterator it4=edgesAlreadyBuilt.rbegin();it4!=edgesAlreadyBuilt.rend();it4++) - { - Edge *ee=(*it4)->getPtr(); ee->incrRef(); - pushBack(new ElementaryEdge(ee,!(*it4)->getDirection())); - } - } - continue; - } - bool directos=colinear1[edgeId].empty(); - std::vector > > idIns1; - int offset1=0; - if(!directos) - {// if the current edge of pol2 has one or more colinear edges part into pol1 - const std::vector& c=colinear1[edgeId]; - std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1); - for(std::size_t j=0;j >(edgeId1,std::pair(descBg1[j]>0,offset1)));// it exists an edge into pol1 given by tuple (idIn1,direct1) that is colinear at edge 'edgeId' in pol2 - //std::pair0; - } - offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2 - } - directos=idIns1.empty(); - } - if(directos) - {//no subpart of edge 'edgeId' of pol2 is in pol1 so let's operate the same thing that QuadraticPolygon::buildFromCrudeDataArray method - std::size_t oldSz=_sub_edges.size(); - appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); - std::size_t newSz=_sub_edges.size(); - std::size_t zeSz=newSz-oldSz; - alreadyExistingIn2[descBg[i]].resize(zeSz); - std::list::const_reverse_iterator it5=_sub_edges.rbegin(); - for(std::size_t p=0;p& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - for(std::size_t j=0;j > >::const_iterator it=idIns1.begin();it!=idIns1.end() && !found;it++) - { - int idIn1=(*it).first;//store if needed the cell id in 1 - direct1=(*it).second.first; - offset1=(*it).second.second; - const std::vector& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1]; - nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2; - offset2=0; - for(std::size_t k=0;k build new Edge instance - //appendEdgeFromCrudeDataArray(j,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); - Node *start=(*mapp.find(idBg)).second; - Node *end=(*mapp.find(idEnd)).second; - ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end); - pushBack(e); - alreadyExistingIn2[descBg[i]].push_back(e); - } - else - {//the current subedge of edge 'edgeId' of pol2 is part of the colinear edge 'idIn1' of pol1 -> reuse Edge instance of pol1 - ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)]; - Edge *ee=e->getPtr(); - ee->incrRef(); - ElementaryEdge *e2=new ElementaryEdge(ee,!(direct1^direction11)); - pushBack(e2); - alreadyExistingIn2[descBg[i]].push_back(e2); - } - } - } - } -} - -/*! - * Method expected to be called on pol2. Every params not suffixed by numbered are supposed to refer to pol2 (this). - * Method to find edges that are ON. - */ -void QuadraticPolygon::updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector >& intersectEdges, - const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, - const std::vector >& intersectEdges1, const std::vector< std::vector >& colinear1) const -{ - std::size_t nbOfSeg=std::distance(descBg,descEnd); - for(std::size_t i=0;i0; - int edgeId=abs(descBg[i])-1;//current edge id of pol2 - const std::vector& c=colinear1[edgeId]; - if(c.empty()) - continue; - const std::vector& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - // - std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1); - int offset1=0; - for(std::size_t j=0;j0; - const std::vector& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1]; - std::size_t nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2; - int offset2=0; - bool found=false; - for(std::size_t kk=0;kkgetPtr()->declareOn(); - } - } - } - offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2 - } - } -} - -void QuadraticPolygon::appendCrudeData(const std::map& mapp, double xBary, double yBary, double fact, int offset, std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI) const -{ - int nbOfNodesInPg=0; - bool presenceOfQuadratic=presenceOfQuadraticEdge(); - conn.push_back(presenceOfQuadratic?NORM_QPOLYG:NORM_POLYGON); - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) - { - Node *tmp=0; - tmp=(*it)->getStartNode(); - std::map::const_iterator it1=mapp.find(tmp); - conn.push_back((*it1).second); - nbOfNodesInPg++; - } - if(presenceOfQuadratic) - { - int j=0; - int off=offset+((int)addCoordsQuadratic.size())/2; - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++,j++,nbOfNodesInPg++) - { - INTERP_KERNEL::Node *node=(*it)->getPtr()->buildRepresentantOfMySelf(); - node->unApplySimilarity(xBary,yBary,fact); - addCoordsQuadratic.push_back((*node)[0]); - addCoordsQuadratic.push_back((*node)[1]); - conn.push_back(off+j); - node->decrRef(); - } - } - connI.push_back(connI.back()+nbOfNodesInPg+1); -} - -/*! - * This method make the hypothesis that \a this and \a other are split at the minimum into edges that are fully IN, OUT or ON. - * This method returns newly created polygons in \a conn and \a connI and the corresponding ids ( \a idThis, \a idOther) are stored respectively into \a nbThis and \a nbOther. - * @param [in,out] edgesThis, parameter that keep informed the caller about the edges in this not shared by the result of intersection of \a this with \a other - * @param [in,out] edgesBoundaryOther, parameter that stores all edges in result of intersection that are not - */ -void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, std::set& edgesThis, std::set& edgesBoundaryOther, const std::map& mapp, int idThis, int idOther, int offset, std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nbThis, std::vector& nbOther) -{ - double xBaryBB, yBaryBB; - double fact=normalizeExt(&other, xBaryBB, yBaryBB); - //Locate \a this relative to \a other (edges of \a this, aka \a pol1 are marked as IN or OUT) - other.performLocatingOperationSlow(*this); // without any assumption - std::vector res=buildIntersectionPolygons(other,*this); - for(std::vector::iterator it=res.begin();it!=res.end();it++) - { - (*it)->appendCrudeData(mapp,xBaryBB,yBaryBB,fact,offset,addCoordsQuadratic,conn,connI); - INTERP_KERNEL::IteratorOnComposedEdge it1(*it); - for(it1.first();!it1.finished();it1.next()) - { - Edge *e=it1.current()->getPtr(); - if(edgesThis.find(e)!=edgesThis.end()) - edgesThis.erase(e); - else - { - if(edgesBoundaryOther.find(e)!=edgesBoundaryOther.end()) - edgesBoundaryOther.erase(e); - else - edgesBoundaryOther.insert(e); - } - } - nbThis.push_back(idThis); - nbOther.push_back(idOther); - delete *it; - } - unApplyGlobalSimilarityExt(other,xBaryBB,yBaryBB,fact); -} - -/*! - * Warning This method is \b NOT const. 'this' and 'other' are modified after call of this method. - * 'other' is a QuadraticPolygon of \b non closed edges. - */ -double QuadraticPolygon::intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear) -{ - double ret = 0., xBaryBB, yBaryBB; - double fact = normalize(&other, xBaryBB, yBaryBB); - - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon cpyOfOther(other); - int nbOfSplits = 0; - SplitPolygonsEachOther(cpyOfThis, cpyOfOther, nbOfSplits); - //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. - performLocatingOperation(cpyOfOther); - isColinear = false; - for(std::list::const_iterator it=cpyOfOther._sub_edges.begin();it!=cpyOfOther._sub_edges.end();it++) - { - switch((*it)->getLoc()) - { - case FULL_IN_1: - { - ret += fabs((*it)->getPtr()->getCurveLength()); - break; - } - case FULL_ON_1: - { - isColinear=true; - ret += fabs((*it)->getPtr()->getCurveLength()); - break; - } - default: - { - } - } - } - return ret * fact; -} - -/*! - * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. - */ -double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other, double* barycenter) -{ - double ret=0.,bary[2],area,xBaryBB,yBaryBB; - barycenter[0] = barycenter[1] = 0.; - double fact=normalize(&other,xBaryBB,yBaryBB); - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - area=fabs((*iter)->getArea()); - (*iter)->getBarycenter(bary); - delete *iter; - ret+=area; - barycenter[0] += bary[0]*area; - barycenter[1] += bary[1]*area; - } - if ( ret > std::numeric_limits::min() ) - { - barycenter[0]=barycenter[0]/ret*fact+xBaryBB; - barycenter[1]=barycenter[1]/ret*fact+yBaryBB; - - } - return ret*fact*fact; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const -{ - double ret=0.; - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - ret+=fabs((*iter)->getArea()); - delete *iter; - } - return ret; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -double QuadraticPolygon::intersectWith(const QuadraticPolygon& other, double* barycenter) const -{ - double ret=0., bary[2]; - barycenter[0] = barycenter[1] = 0.; - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - double area = fabs((*iter)->getArea()); - (*iter)->getBarycenter(bary); - delete *iter; - ret+=area; - barycenter[0] += bary[0]*area; - barycenter[1] += bary[1]*area; - } - if ( ret > std::numeric_limits::min() ) - { - barycenter[0] /= ret; - barycenter[1] /= ret; - } - return ret; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -void QuadraticPolygon::intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const -{ - perimeterThisPart=0.; perimeterOtherPart=0.; perimeterCommonPart=0.; - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; - SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); - performLocatingOperation(cpyOfOther); - other.performLocatingOperation(cpyOfThis); - cpyOfThis.dispatchPerimeterExcl(perimeterThisPart,perimeterCommonPart); - cpyOfOther.dispatchPerimeterExcl(perimeterOtherPart,perimeterCommonPart); - perimeterCommonPart/=2.; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - * - * polThis.size()==this->size() and polOther.size()==other.size(). - * For each ElementaryEdge of 'this', the corresponding contribution in resulting polygon is in 'polThis'. - * For each ElementaryEdge of 'other', the corresponding contribution in resulting polygon is in 'polOther'. - * As consequence common part are counted twice (in polThis \b and in polOther). - */ -void QuadraticPolygon::intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const -{ - polThis.resize(size()); - polOther.resize(other.size()); - IteratorOnComposedEdge it1(const_cast(this)); - int edgeId=0; - for(it1.first();!it1.finished();it1.next(),edgeId++) - { - ElementaryEdge* curE1=it1.current(); - QuadraticPolygon cpyOfOther(other); - QuadraticPolygon tmp; - tmp.pushBack(curE1->clone()); - int tmp2; - SplitPolygonsEachOther(tmp,cpyOfOther,tmp2); - other.performLocatingOperation(tmp); - tmp.dispatchPerimeter(polThis[edgeId]); - } - // - IteratorOnComposedEdge it2(const_cast(&other)); - edgeId=0; - for(it2.first();!it2.finished();it2.next(),edgeId++) - { - ElementaryEdge* curE2=it2.current(); - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon tmp; - tmp.pushBack(curE2->clone()); - int tmp2; - SplitPolygonsEachOther(tmp,cpyOfThis,tmp2); - performLocatingOperation(tmp); - tmp.dispatchPerimeter(polOther[edgeId]); - } -} - - -/*! - * numberOfCreatedPointsPerEdge is resized to the number of edges of 'this'. - * This method returns in ordered maner the number of newly created points per edge. - * This method performs a split process between 'this' and 'other' that gives the result PThis. - * Then for each edges of 'this' this method counts how many edges in Pthis have the same id. - */ -void QuadraticPolygon::intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const -{ - numberOfCreatedPointsPerEdge.resize(size()); - IteratorOnComposedEdge it1(const_cast(this)); - int edgeId=0; - for(it1.first();!it1.finished();it1.next(),edgeId++) - { - ElementaryEdge* curE1=it1.current(); - QuadraticPolygon cpyOfOther(other); - QuadraticPolygon tmp; - tmp.pushBack(curE1->clone()); - int tmp2; - SplitPolygonsEachOther(tmp,cpyOfOther,tmp2); - numberOfCreatedPointsPerEdge[edgeId]=tmp.recursiveSize()-1; - } -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -std::vector QuadraticPolygon::intersectMySelfWith(const QuadraticPolygon& other) const -{ - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; - SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); - //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. - performLocatingOperation(cpyOfOther); - return other.buildIntersectionPolygons(cpyOfThis,cpyOfOther); -} - -/*! - * This method is typically the first step of boolean operations between pol1 and pol2. - * This method perform the minimal splitting so that at the end each edges constituting pol1 are fully either IN or OUT or ON. - * @param pol1 IN/OUT param that is equal to 'this' when called. - */ -void QuadraticPolygon::SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits) -{ - IteratorOnComposedEdge it1(&pol1),it2(&pol2); - MergePoints merge; - ComposedEdge *c1=new ComposedEdge; - ComposedEdge *c2=new ComposedEdge; - for(it2.first();!it2.finished();it2.next()) - { - ElementaryEdge* curE2=it2.current(); - if(!curE2->isThereStartPoint()) - it1.first(); - else - it1=curE2->getIterator(); - for(;!it1.finished();) - { - - ElementaryEdge* curE1=it1.current(); - merge.clear(); nbOfSplits++; - if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) - { - if(!curE1->getDirection()) c1->reverse(); - if(!curE2->getDirection()) c2->reverse(); - UpdateNeighbours(merge,it1,it2,c1,c2); - //Substitution of simple edge by sub-edges. - delete curE1; // <-- destroying simple edge coming from pol1 - delete curE2; // <-- destroying simple edge coming from pol2 - it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. - it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. - curE2=it2.current(); - // - it1.assignMySelfToAllElems(c2);//To avoid that others - SoftDelete(c1); - SoftDelete(c2); - c1=new ComposedEdge; - c2=new ComposedEdge; - } - else - { - UpdateNeighbours(merge,it1,it2,curE1,curE2); - it1.next(); - } - } - } - Delete(c1); - Delete(c2); -} - -void QuadraticPolygon::performLocatingOperation(QuadraticPolygon& pol1) const -{ - IteratorOnComposedEdge it(&pol1); - TypeOfEdgeLocInPolygon loc=FULL_ON_1; - for(it.first();!it.finished();it.next()) - { - ElementaryEdge *cur=it.current(); - loc=cur->locateFullyMySelf(*this,loc);//*this=pol2=other - } -} - -void QuadraticPolygon::performLocatingOperationSlow(QuadraticPolygon& pol2) const -{ - IteratorOnComposedEdge it(&pol2); - for(it.first();!it.finished();it.next()) - { - ElementaryEdge *cur=it.current(); - cur->locateFullyMySelfAbsolute(*this); - } -} - -/*! - * Given 2 polygons \a pol1 and \a pol2 (localized) the resulting polygons are returned. - * - * this : pol2 simplified. - * @param [in] pol1 pol1 split. - * @param [in] pol2 pol2 split. - */ -std::vector QuadraticPolygon::buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const -{ - std::vector ret; - std::list pol2Zip=pol2.zipConsecutiveInSegments(); - if(!pol2Zip.empty()) - ClosePolygons(pol2Zip,pol1,*this,ret); - else - {//borders of pol2 do not cross pol1,and pol2 borders are outside of pol1. That is to say, either pol2 and pol1 - //do not overlap or pol1 is fully inside pol2. So in the first case no intersection, in the other case - //the intersection is pol1. - ElementaryEdge *e1FromPol1=pol1[0]; - TypeOfEdgeLocInPolygon loc=FULL_ON_1; - loc=e1FromPol1->locateFullyMySelf(*this,loc); - if(loc==FULL_IN_1) - ret.push_back(new QuadraticPolygon(pol1)); - } - return ret; -} - -/*! - * Returns parts of potentially non closed-polygons. Each returned polygons are not mergeable. - * this : pol2 split and locallized. - */ -std::list QuadraticPolygon::zipConsecutiveInSegments() const -{ - std::list ret; - IteratorOnComposedEdge it(const_cast(this)); - int nbOfTurns=recursiveSize(); - int i=0; - if(!it.goToNextInOn(false,i,nbOfTurns)) - return ret; - i=0; - // - while(igetLoc(); - while(loc!=FULL_OUT_1 && iclone(); - tmp1->pushBack(tmp3); - it.nextLoop(); i++; - loc=it.current()->getLoc(); - } - if(tmp1->empty()) - { - delete tmp1; - continue; - } - ret.push_back(tmp1); - it.goToNextInOn(true,i,nbOfTurns); - } - return ret; -} - -/*! - * @param [in] pol2zip is a list of set of edges (=an opened polygon) coming from split polygon 2. - * @param [in] pol1 is split pol1. - * @param [in] pol2 should be considered as pol2Simplified. - * @param [out] results the resulting \b CLOSED polygons. - */ -void QuadraticPolygon::ClosePolygons(std::list& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2, - std::vector& results) -{ - bool directionKnownInPol1=false; - bool directionInPol1; - for(std::list::iterator iter=pol2Zip.begin();iter!=pol2Zip.end();) - { - if((*iter)->completed()) - { - results.push_back(*iter); - directionKnownInPol1=false; - iter=pol2Zip.erase(iter); - continue; - } - if(!directionKnownInPol1) - { - if(!(*iter)->haveIAChanceToBeCompletedBy(pol1,pol2,directionInPol1)) - { delete *iter; iter=pol2Zip.erase(iter); continue; } - else - directionKnownInPol1=true; - } - std::list::iterator iter2=iter; iter2++; - std::list::iterator iter3=(*iter)->fillAsMuchAsPossibleWith(pol1,iter2,pol2Zip.end(),directionInPol1); - if(iter3!=pol2Zip.end()) - { - (*iter)->pushBack(*iter3); - SoftDelete(*iter3); - pol2Zip.erase(iter3); - } - } -} - -/*! - * 'this' is expected to be set of edges (not closed) of pol2 split. - */ -bool QuadraticPolygon::haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted,const QuadraticPolygon& pol2NotSplitted, bool& direction) -{ - IteratorOnComposedEdge it(const_cast(&pol1Splitted)); - bool found=false; - Node *n=getEndNode(); - ElementaryEdge *cur=it.current(); - for(it.first();!it.finished() && !found;) - { - cur=it.current(); - found=(cur->getStartNode()==n); - if(!found) - it.next(); - } - if(!found) - throw Exception("Internal error: polygons incompatible with each others. Should never happen!"); - //Ok we found correspondance between this and pol1. Searching for right direction to close polygon. - ElementaryEdge *e=_sub_edges.back(); - if(e->getLoc()==FULL_ON_1) - { - if(e->getPtr()==cur->getPtr()) - { - direction=false; - it.previousLoop(); - cur=it.current(); - Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); - bool ret=pol2NotSplitted.isInOrOut(repr); - repr->decrRef(); - return ret; - } - else - { - direction=true; - Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); - bool ret=pol2NotSplitted.isInOrOut(repr); - repr->decrRef(); - return ret; - } - } - else - direction=cur->locateFullyMySelfAbsolute(pol2NotSplitted)==FULL_IN_1; - return true; -} - -/*! - * This method fills as much as possible \a this (a sub-part of pol2 split) with edges of \a pol1Splitted. - */ -std::list::iterator QuadraticPolygon::fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, - std::list::iterator iStart, - std::list::iterator iEnd, - bool direction) -{ - IteratorOnComposedEdge it(const_cast(&pol1Splitted)); - bool found=false; - Node *n=getEndNode(); - ElementaryEdge *cur; - for(it.first();!it.finished() && !found;) - { - cur=it.current(); - found=(cur->getStartNode()==n); - if(!found) - it.next(); - } - if(!direction) - it.previousLoop(); - Node *nodeToTest; - int szMax(pol1Splitted.size()+1),ii(0);// here a protection against agressive users of IntersectMeshes of invalid input meshes - std::list::iterator ret; - do - { - cur=it.current(); - ElementaryEdge *tmp=cur->clone(); - if(!direction) - tmp->reverse(); - pushBack(tmp); - nodeToTest=tmp->getEndNode(); - direction?it.nextLoop():it.previousLoop(); - ret=CheckInList(nodeToTest,iStart,iEnd); - if(completed()) - return iEnd; - ii++; - } - while(ret==iEnd && ii::iterator QuadraticPolygon::CheckInList(Node *n, std::list::iterator iStart, - std::list::iterator iEnd) -{ - for(std::list::iterator iter=iStart;iter!=iEnd;iter++) - if((*iter)->isNodeIn(n)) - return iter; - return iEnd; -} - -void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::set& notUsedInPol1, const std::set& edgesInPol2OnBoundary, const std::map& mapp, int offset, int idThis, - std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nb1, std::vector& nb2) -{ - pol1.initLocations(); - for(std::set::const_iterator it9=notUsedInPol1.begin();it9!=notUsedInPol1.end();it9++) - { (*it9)->initLocs(); (*it9)->declareOn(); } - for(std::set::const_iterator itA=edgesInPol2OnBoundary.begin();itA!=edgesInPol2OnBoundary.end();itA++) - { (*itA)->initLocs(); (*itA)->declareIn(); } - //// - std::set notUsedInPol1L(notUsedInPol1); - IteratorOnComposedEdge it(const_cast(&pol1)); - int sz=pol1.size(); - std::list pol1Zip; - if(pol1.size()==(int)notUsedInPol1.size() && edgesInPol2OnBoundary.empty()) - { - pol1.appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1); - return ; - } - while(!notUsedInPol1L.empty()) - { - for(int i=0;igetStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1);i++) - it.nextLoop(); - if(it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1) - throw INTERP_KERNEL::Exception("Presence of a target polygon fully included in source polygon ! The partition of this leads to a non simply connex cell (with hole) ! Impossible ! Such resulting cell cannot be stored in MED cell format !"); - QuadraticPolygon *tmp1=new QuadraticPolygon; - do - { - Edge *ee=it.current()->getPtr(); - if(ee->getLoc()==FULL_ON_1) - { - ee->incrRef(); notUsedInPol1L.erase(ee); - tmp1->pushBack(new ElementaryEdge(ee,it.current()->getDirection())); - } - it.nextLoop(); - } - while(it.current()->getStartNode()->getLoc()!=IN_1 && !notUsedInPol1L.empty()); - pol1Zip.push_back(tmp1); - } - //// - std::list retPolsUnderContruction; - std::list edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end()); - std::map > pol1ZipConsumed; - std::size_t maxNbOfTurn=edgesInPol2OnBoundaryL.size(),nbOfTurn=0,iiMNT=0; - for(std::list::const_iterator itMNT=pol1Zip.begin();itMNT!=pol1Zip.end();itMNT++,iiMNT++) - nbOfTurn+=(*itMNT)->size(); - maxNbOfTurn=maxNbOfTurn*nbOfTurn; maxNbOfTurn*=maxNbOfTurn; - nbOfTurn=0; - while(nbOfTurn::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();) - { - if((*it1)->getStartNode()==(*it1)->getEndNode()) - { - it1++; - continue; - } - Node *curN=(*it1)->getEndNode(); - bool smthHappened=false; - for(std::list::iterator it2=edgesInPol2OnBoundaryL.begin();it2!=edgesInPol2OnBoundaryL.end();) - { - if(curN==(*it2)->getStartNode()) - { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,true)); curN=(*it2)->getEndNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); } - else if(curN==(*it2)->getEndNode()) - { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,false)); curN=(*it2)->getStartNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); } - else - it2++; - } - if(smthHappened) - { - for(std::list::iterator it3=pol1Zip.begin();it3!=pol1Zip.end();) - { - if(curN==(*it3)->getStartNode()) - { - for(std::list::const_iterator it4=(*it3)->_sub_edges.begin();it4!=(*it3)->_sub_edges.end();it4++) - { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); (*it1)->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); } - smthHappened=true; - pol1ZipConsumed[*it1].push_back(*it3); - curN=(*it3)->getEndNode(); - it3=pol1Zip.erase(it3); - } - else - it3++; - } - } - if(!smthHappened) - { - for(std::list::const_iterator it5=(*it1)->_sub_edges.begin();it5!=(*it1)->_sub_edges.end();it5++) - { - Edge *ee=(*it5)->getPtr(); - if(edgesInPol2OnBoundary.find(ee)!=edgesInPol2OnBoundary.end()) - edgesInPol2OnBoundaryL.push_back(ee); - } - for(std::list::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) - pol1Zip.push_front(*it6); - pol1ZipConsumed.erase(*it1); - delete *it1; - it1=retPolsUnderContruction.erase(it1); - } - } - if(!pol1Zip.empty()) - { - QuadraticPolygon *tmp=new QuadraticPolygon; - QuadraticPolygon *first=*(pol1Zip.begin()); - for(std::list::const_iterator it4=first->_sub_edges.begin();it4!=first->_sub_edges.end();it4++) - { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); tmp->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); } - pol1ZipConsumed[tmp].push_back(first); - retPolsUnderContruction.push_back(tmp); - pol1Zip.erase(pol1Zip.begin()); - } - nbOfTurn++; - } - if(nbOfTurn==maxNbOfTurn) - { - std::ostringstream oss; oss << "Error during reconstruction of residual of cell ! It appears that either source or/and target mesh is/are not conform !"; - oss << " Number of turns is = " << nbOfTurn << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::list::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++) - { - if((*it1)->getStartNode()==(*it1)->getEndNode()) - { - (*it1)->appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1); - for(std::list::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) - delete *it6; - delete *it1; - } - } -} diff --git a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx deleted file mode 100644 index ee9ca5bc0..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELGEO2DQUADRATICPOLYGON_HXX__ -#define __INTERPKERNELGEO2DQUADRATICPOLYGON_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class Edge; - class MergePoints; - - /** - * A set of quadratic or linear edges, not necessarily connected to form a closed polygon. - * Some methods however requires a closed form. - * Class ComposedEdge focuses more on connectivity aspect. - */ - class QuadraticPolygon : public ComposedEdge - { - public: - INTERPKERNEL_EXPORT QuadraticPolygon() { } - INTERPKERNEL_EXPORT QuadraticPolygon(const QuadraticPolygon& other):ComposedEdge(other) { } - INTERPKERNEL_EXPORT QuadraticPolygon(const char *fileName); - INTERPKERNEL_EXPORT static QuadraticPolygon *BuildLinearPolygon(std::vector& nodes); - INTERPKERNEL_EXPORT static QuadraticPolygon *BuildArcCirclePolygon(std::vector& nodes); - INTERPKERNEL_EXPORT static Edge *BuildLinearEdge(std::vector& nodes); - INTERPKERNEL_EXPORT static Edge *BuildArcCircleEdge(std::vector& nodes); - INTERPKERNEL_EXPORT static void BuildDbgFile(const std::vector& nodes, const char *fileName); - INTERPKERNEL_EXPORT ~QuadraticPolygon(); - INTERPKERNEL_EXPORT void closeMe() const; - INTERPKERNEL_EXPORT void circularPermute(); - INTERPKERNEL_EXPORT bool isButterflyAbs(); - INTERPKERNEL_EXPORT bool isButterfly() const; - INTERPKERNEL_EXPORT void dumpInXfigFile(const char *fileName) const; - INTERPKERNEL_EXPORT void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const; - //! Before intersecting as intersectWith a normalization is done. - INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other); - INTERPKERNEL_EXPORT double intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear); - //! Before intersecting as intersectWith a normalization is done. - INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other, double* barycenter); - INTERPKERNEL_EXPORT void splitAbs(QuadraticPolygon& other, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, const std::vector& otherEdgeIds, - std::vector& edgesThis, int cellIdThis, std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, std::vector& addCoo, std::map& mergedNodes); - INTERPKERNEL_EXPORT void buildFromCrudeDataArray(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges); - INTERPKERNEL_EXPORT void buildFromCrudeDataArray2(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges, - const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector >& intersectEdges1, - const std::vector< std::vector >& colinear1, - std::map >& alreadyExistingIn2); - INTERPKERNEL_EXPORT void updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector >& intersectEdges, const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector >& intersectEdges1, const std::vector< std::vector >& colinear1) const; - INTERPKERNEL_EXPORT void appendEdgeFromCrudeDataArray(std::size_t edgeId, const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges); - INTERPKERNEL_EXPORT void appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector& subEdge, const std::map& mapp); - INTERPKERNEL_EXPORT void appendCrudeData(const std::map& mapp, double xBary, double yBary, double fact, int offset, std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI) const; - INTERPKERNEL_EXPORT void buildPartitionsAbs(QuadraticPolygon& other, std::set& edgesThis, std::set& edgesBoundaryOther, const std::map& mapp, int idThis, int idOther, int offset, - std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nb1, std::vector& nb2); - // - INTERPKERNEL_EXPORT double intersectWith(const QuadraticPolygon& other) const; - INTERPKERNEL_EXPORT double intersectWith(const QuadraticPolygon& other, double* barycenter) const; - INTERPKERNEL_EXPORT std::vector intersectMySelfWith(const QuadraticPolygon& other) const; - INTERPKERNEL_EXPORT void intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const; - INTERPKERNEL_EXPORT void intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const; - INTERPKERNEL_EXPORT void intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const; - public://Only public for tests reasons - INTERPKERNEL_EXPORT void performLocatingOperation(QuadraticPolygon& pol2) const; - INTERPKERNEL_EXPORT void performLocatingOperationSlow(QuadraticPolygon& pol2) const; - INTERPKERNEL_EXPORT static void SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits); - INTERPKERNEL_EXPORT std::vector buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const; - INTERPKERNEL_EXPORT bool haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted, const QuadraticPolygon& pol2NotSplitted, bool& direction); - INTERPKERNEL_EXPORT static void ComputeResidual(const QuadraticPolygon& pol1, const std::set& notUsedInPol1, const std::set& edgesInPol2OnBoundary, const std::map& mapp, int offset, int idThis, - std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nb1, std::vector& nb2); - protected: - std::list zipConsecutiveInSegments() const; - void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - static void ClosePolygons(std::list& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2, std::vector& results); - template - static void UpdateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, - const EDGES *e1, const EDGES *e2); - std::list::iterator fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, - std::list::iterator iStart, - std::list::iterator iEnd, - bool direction); - static std::list::iterator CheckInList(Node *n, std::list::iterator iStart, - std::list::iterator iEnd); - }; -} - -namespace INTERP_KERNEL -{ - template - void QuadraticPolygon::UpdateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, - const EDGES *e1, const EDGES *e2) - { - it1.previousLoop(); it2.previousLoop(); - ElementaryEdge *curE1=it1.current(); ElementaryEdge *curE2=it2.current(); - curE1->changeEndNodeWith(e1->getStartNode()); curE2->changeEndNodeWith(e2->getStartNode()); - it1.nextLoop(); it1.nextLoop(); it2.nextLoop(); it2.nextLoop(); - curE1->changeStartNodeWith(e1->getEndNode()); curE2->changeStartNodeWith(e2->getEndNode()); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2DIntersector.hxx b/medtool/src/INTERP_KERNEL/Geometric2DIntersector.hxx deleted file mode 100644 index 1de6c446f..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2DIntersector.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __GEOMETRIC2DINTERSECTOR_HXX__ -#define __GEOMETRIC2DINTERSECTOR_HXX__ - -#include "PlanarIntersectorP0P0.hxx" -#include "PlanarIntersectorP0P1.hxx" -#include "PlanarIntersectorP1P0.hxx" -#include "PlanarIntersectorP1P1.hxx" -#include "PlanarIntersectorP1P0Bary.hxx" -#include "PlanarIntersectorP0P1Bary.hxx" - -namespace INTERP_KERNEL -{ - class QuadraticPolygon; - - template class InterpType> - class Geometric2DIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, - bool& isColinear); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - private: - QuadraticPolygon *buildPolygonFrom(const std::vector& coords, NormalizedCellType type); - QuadraticPolygon *buildPolygonOfOneEdgeFrom(const std::vector& coords, NormalizedCellType type); - QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Geometric2DIntersector.txx b/medtool/src/INTERP_KERNEL/Geometric2DIntersector.txx deleted file mode 100644 index 81998de5e..000000000 --- a/medtool/src/INTERP_KERNEL/Geometric2DIntersector.txx +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __GEOMETRIC2DINTERSECTOR_TXX__ -#define __GEOMETRIC2DINTERSECTOR_TXX__ - -#include "Geometric2DIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "Planar2D1DIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P1.txx" -#include "PlanarIntersectorP1P0Bary.txx" -#include "PlanarIntersectorP0P1Bary.txx" -#include "CellModel.hxx" - -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DNode.hxx" - -#define GEO2D_INTERSECTOR Geometric2DIntersector -#define INTERSECTOR_TEMPLATE template class InterpType> - -namespace INTERP_KERNEL -{ - INTERSECTOR_TEMPLATE - GEO2D_INTERSECTOR::Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, - double precision, int orientation): - InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) - { - QUADRATIC_PLANAR::_precision=precision; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - int orientation = 1; - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(icellS); - QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); - QuadraticPolygon *p2=buildPolygonFrom(CoordsS,tS); - double ret=p1->intersectWithAbs(*p2); - delete p1; delete p2; - return orientation*ret; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometry1D(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS, - bool& isColinear) - { - int orientation = 1; - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(icellS); - QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); - QuadraticPolygon *p2=buildPolygonOfOneEdgeFrom(CoordsS,tS); - double ret=p1->intersectWithAbs1D(*p2, isColinear); - delete p1; delete p2; - return orientation*ret; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, - const std::vector& sourceCoords, - bool isSourceQuad) - { - std::vector nodes(4); - nodes[0]=new Node(quadrangle[0],quadrangle[1]); - nodes[1]=new Node(quadrangle[SPACEDIM],quadrangle[SPACEDIM+1]); - nodes[2]=new Node(quadrangle[2*SPACEDIM],quadrangle[2*SPACEDIM+1]); - nodes[3]=new Node(quadrangle[3*SPACEDIM],quadrangle[3*SPACEDIM+1]); - int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; - std::vector nodes2(nbOfSourceNodes); - for(int i=0;iintersectWithAbs(*p2); - delete p1; delete p2; - return ret; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometryGeneral(const std::vector& targetCoords, - const std::vector& sourceCoords) - { - int nbOfTargetNodes=targetCoords.size()/SPACEDIM; - std::vector nodes(nbOfTargetNodes); - for(int i=0;i nodes2(nbOfSourceNodes); - for(int i=0;iintersectWithAbs(*p2); - delete p1; delete p2; - return ret; - } - - //================================================================================ - /*! - * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm - * \param targetCell - list of coordinates of target polygon in full interlace - * \param targetCellQuadratic - specifies if target polygon is quadratic or not - * \param sourceTria - list of coordinates of source triangle - * \param res - coefficients a,b and c associated to nodes of sourceTria - */ - //================================================================================ - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { - std::vector nodes(3); - nodes[0]=new Node(sourceTria[0*SPACEDIM],sourceTria[0*SPACEDIM+1]); - nodes[1]=new Node(sourceTria[1*SPACEDIM],sourceTria[1*SPACEDIM+1]); - nodes[2]=new Node(sourceTria[2*SPACEDIM],sourceTria[2*SPACEDIM+1]); - int nbOfTargetNodes=targetCell.size()/SPACEDIM; - std::vector nodes2(nbOfTargetNodes); - for(int i=0;iintersectWithAbs(*p2,barycenter); - delete p1; delete p2; - if ( ret > std::numeric_limits::min() ) - { - std::vector sourceCell(3); - sourceCell[0] = &sourceTria[0]; - sourceCell[1] = &sourceTria[SPACEDIM]; - sourceCell[2] = &sourceTria[SPACEDIM*2]; - res.resize(3); - barycentric_coords( sourceCell, barycenter, &res[0]); - res[0] *= ret; - res[1] *= ret; - res[2] *= ret; - } - else - { - ret = 0; - } - return ret; - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonFrom(const std::vector& coords, NormalizedCellType type) - { - int nbNodes=coords.size()/SPACEDIM; - std::vector nodes(nbNodes); - for(int i=0;i& coords, NormalizedCellType type) - { - if(type==NORM_SEG2) - { - Node *node0=new Node(coords[0],coords[1]); - Node *node1=new Node(coords[SPACEDIM],coords[SPACEDIM+1]); - QuadraticPolygon *ret=new QuadraticPolygon; - ret->pushBack(new EdgeLin(node0,node1)); - node0->decrRef(); node1->decrRef(); - return ret; - } - else if(type==NORM_SEG3) - { - Node *nodeBg=new Node(coords[0],coords[1]); - Node *nodeEnd=new Node(coords[SPACEDIM],coords[SPACEDIM+1]); - Node *nodeMiddle=new Node(coords[2*SPACEDIM],coords[2*SPACEDIM+1]); - QuadraticPolygon *ret=new QuadraticPolygon; - ret->pushBack(new EdgeArcCircle(nodeBg,nodeMiddle,nodeEnd)); - nodeBg->decrRef(); nodeEnd->decrRef(); nodeMiddle->decrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("buildPolygonOfOneEdgeFrom : trying to build such non close QuadraticPolygon with 1D type !"); - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) - { - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsT+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - if(CellModel::GetCellModel(type).isQuadratic()) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) - { - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsS+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - const CellModel& cm=CellModel::GetCellModel(type); - if(!cm.isQuadratic()) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/INTERPKERNELDefines.hxx b/medtool/src/INTERP_KERNEL/INTERPKERNELDefines.hxx deleted file mode 100644 index 45a3e9afc..000000000 --- a/medtool/src/INTERP_KERNEL/INTERPKERNELDefines.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPKERNELDEFINES_HXX__ -#define __INTERPKERNELDEFINES_HXX__ - -//export symbols -#ifdef WIN32 -# if defined INTERPKERNEL_EXPORTS || defined interpkernel_EXPORTS -# define INTERPKERNEL_EXPORT __declspec(dllexport) -# else -# define INTERPKERNEL_EXPORT __declspec(dllimport) -# endif -#else -# define INTERPKERNEL_EXPORT -#endif - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.hxx b/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.hxx deleted file mode 100644 index 171fa99be..000000000 --- a/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.hxx +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTEGRALUNIFORMINTERSECTOR_HXX__ -#define __INTEGRALUNIFORMINTERSECTOR_HXX__ - -#include "TargetIntersector.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - class IntegralUniformIntersector : public TargetIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - IntegralUniformIntersector(const MyMeshType& mesh, bool isAbs); - double performNormalization(double val) const { if(_is_abs) return fabs(val); else return val; } - void setFromTo(bool val) { _from_to=val; } - void putValueIn(ConnType i, double val, MyMatrix& res) const; - protected: - const MyMeshType& _mesh; - //! if false means fromIntegralUniform if true means toIntegralUniform - bool _from_to; - bool _is_abs; - }; - - template - class IntegralUniformIntersectorP0 : public IntegralUniformIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - IntegralUniformIntersectorP0(const MyMeshType& mesh, bool isAbs); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - }; - - template - class IntegralUniformIntersectorP1 : public IntegralUniformIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - IntegralUniformIntersectorP1(const MyMeshType& mesh, bool isAbs); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.txx b/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.txx deleted file mode 100644 index 279776323..000000000 --- a/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.txx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTEGRALUNIFORMINTERSECTOR_TXX__ -#define __INTEGRALUNIFORMINTERSECTOR_TXX__ - -#include "IntegralUniformIntersector.hxx" -#include "VolSurfUser.txx" - -namespace INTERP_KERNEL -{ - template - IntegralUniformIntersector::IntegralUniformIntersector(const MyMeshType& mesh, bool isAbs):_mesh(mesh),_from_to(false),_is_abs(isAbs) - { - } - - template - void IntegralUniformIntersector::putValueIn(ConnType iInCMode, double val1, MyMatrix& res) const - { - static const NumberingPolicy numPol=MyMeshType::My_numPol; - double val=performNormalization(val1); - if(_from_to) - { - typename MyMatrix::value_type& resRow=res[0]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iInCMode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(iInCMode),val)); - else - { - double val2=(*iterRes).second+val; - resRow.erase(OTT::indFC(iInCMode)); - resRow.insert(std::make_pair(OTT::indFC(iInCMode),val2)); - } - } - else - { - typename MyMatrix::value_type& resRow=res[iInCMode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(0)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(0),val)); - else - { - double val2=(*iterRes).second+val; - resRow.erase(OTT::indFC(0)); - resRow.insert(std::make_pair(OTT::indFC(0),val2)); - } - } - } - - template - IntegralUniformIntersectorP0::IntegralUniformIntersectorP0(const MyMeshType& mesh, bool isAbs):IntegralUniformIntersector(mesh,isAbs) - { - } - - template - int IntegralUniformIntersectorP0::getNumberOfRowsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return 1; - else - return IntegralUniformIntersector::_mesh.getNumberOfElements(); - } - - template - int IntegralUniformIntersectorP0::getNumberOfColsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return IntegralUniformIntersector::_mesh.getNumberOfElements(); - else - return 1; - } - - template - void IntegralUniformIntersectorP0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - static const NumberingPolicy numPol=MyMeshType::My_numPol; - res.resize(getNumberOfRowsOfResMatrix()); - unsigned long nbelem=IntegralUniformIntersector::_mesh.getNumberOfElements(); - const ConnType *connIndx=IntegralUniformIntersector::_mesh.getConnectivityIndexPtr(); - const ConnType *conn=IntegralUniformIntersector::_mesh.getConnectivityPtr(); - const double *coords=IntegralUniformIntersector::_mesh.getCoordinatesPtr(); - for(unsigned long i=0;i::_mesh.getTypeOfElement(OTT::indFC(i)); - double val=computeVolSurfOfCell(t,conn+OTT::ind2C(connIndx[i]),connIndx[i+1]-connIndx[i],coords); - IntegralUniformIntersector::putValueIn(i,val,res); - } - } - - template - IntegralUniformIntersectorP1::IntegralUniformIntersectorP1(const MyMeshType& mesh, bool isAbs):IntegralUniformIntersector(mesh,isAbs) - { - } - - template - int IntegralUniformIntersectorP1::getNumberOfRowsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return 1; - else - return IntegralUniformIntersector::_mesh.getNumberOfNodes(); - } - - template - int IntegralUniformIntersectorP1::getNumberOfColsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return IntegralUniformIntersector::_mesh.getNumberOfNodes(); - else - return 1; - } - - template - void IntegralUniformIntersectorP1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - static const NumberingPolicy numPol=MyMeshType::My_numPol; - res.resize(getNumberOfRowsOfResMatrix()); - unsigned long nbelem=IntegralUniformIntersector::_mesh.getNumberOfElements(); - const ConnType *connIndx=IntegralUniformIntersector::_mesh.getConnectivityIndexPtr(); - const ConnType *conn=IntegralUniformIntersector::_mesh.getConnectivityPtr(); - const double *coords=IntegralUniformIntersector::_mesh.getCoordinatesPtr(); - for(unsigned long i=0;i::_mesh.getTypeOfElement(OTT::indFC(i)); - int lgth=connIndx[i+1]-connIndx[i]; - const ConnType *locConn=conn+OTT::ind2C(connIndx[i]); - double val=computeVolSurfOfCell(t,locConn,lgth,coords); - if(t==NORM_TRI3) - val/=3.; - else if(t==NORM_TETRA4) - val/=4.; - else - throw INTERP_KERNEL::Exception("Invalid cell type detected : must be TRI3 or TETRA4 ! "); - for(int j=0;j::putValueIn(OTT::coo2C(locConn[j]),val,res); - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx b/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx deleted file mode 100644 index dd985b501..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx +++ /dev/null @@ -1,511 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelCellSimplify.hxx" -#include "CellModel.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -/*! - * This method takes as input a cell with type 'type' and whose connectivity is defined by (conn,lgth) - * It retrieves the same cell with a potentially different type (in return) whose connectivity is defined by (retConn,retLgth) - * \b WARNING for optimization reason the arrays 'retConn' and 'conn' can overlapped ! - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, int *retConn, int& retLgth) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - std::set c(conn,conn+lgth); - c.erase(-1); - bool isObviousNonDegeneratedCell=((int)c.size()==lgth); - if(cm.isQuadratic() || isObviousNonDegeneratedCell) - {//quadratic do nothing for the moment. - retLgth=lgth; - int *tmp=new int[lgth];//no direct std::copy ! overlapping of conn and retConn ! - std::copy(conn,conn+lgth,tmp); - std::copy(tmp,tmp+lgth,retConn); - delete [] tmp; - return type; - } - if(cm.getDimension()==2) - { - int *tmp=new int[lgth]; - tmp[0]=conn[0]; - int newPos=1; - for(int i=1;i faces; - for(unsigned j=0;j nodes(conn,conn+lgth); - nodes.erase(-1); - int nbOfNodes=(int)nodes.size(); - int magicNumber=100*nbOfNodes+nbOfFaces; - switch(magicNumber) - { - case 806: - return tryToUnPolyHex8(conn,nbOfFaces,lgth,retConn,retLgth); - case 1208: - return tryToUnPolyHexp12(conn,nbOfFaces,lgth,retConn,retLgth); - case 605: - return tryToUnPolyPenta6(conn,nbOfFaces,lgth,retConn,retLgth); - case 505: - return tryToUnPolyPyra5(conn,nbOfFaces,lgth,retConn,retLgth); - case 404: - return tryToUnPolyTetra4(conn,nbOfFaces,lgth,retConn,retLgth); - default: - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; - } -} - -bool CellSimplify::orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace) -{ - std::vector tmp2; - std::set bases(baseFace,baseFace+lgthBaseFace); - std::set sides(sideFace,sideFace+4); - std::set_intersection(bases.begin(),bases.end(),sides.begin(),sides.end(),std::back_insert_iterator< std::vector >(tmp2)); - if(tmp2.size()!=2) - return false; - std::vector< std::pair > baseEdges(lgthBaseFace); - std::vector< std::pair > oppEdges(lgthBaseFace); - std::vector< std::pair > sideEdges(4); - for(int i=0;i(baseFace[i],baseFace[(i+1)%lgthBaseFace]); - oppEdges[i]=std::pair(retConn[i],retConn[(i+1)%lgthBaseFace]); - } - for(int i=0;i<4;i++) - sideEdges[i]=std::pair(sideFace[i],sideFace[(i+1)%4]); - std::vector< std::pair > tmp; - std::set< std::pair > baseEdgesS(baseEdges.begin(),baseEdges.end()); - std::set< std::pair > sideEdgesS(sideEdges.begin(),sideEdges.end()); - std::set_intersection(baseEdgesS.begin(),baseEdgesS.end(),sideEdgesS.begin(),sideEdgesS.end(),std::back_insert_iterator< std::vector< std::pair > >(tmp)); - if(tmp.empty()) - { - //reverse sideFace - for(int i=0;i<4;i++) - { - std::pair p=sideEdges[i]; - std::pair r(p.second,p.first); - sideEdges[i]=r; - } - //end reverse sideFace - std::set< std::pair > baseEdgesS2(baseEdges.begin(),baseEdges.end()); - std::set< std::pair > sideEdgesS2(sideEdges.begin(),sideEdges.end()); - std::set_intersection(baseEdgesS2.begin(),baseEdgesS2.end(),sideEdgesS2.begin(),sideEdgesS2.end(),std::back_insert_iterator< std::vector< std::pair > >(tmp)); - if(tmp.empty()) - return false; - } - if(tmp.size()!=1) - return false; - bool found=false; - std::pair pInOpp; - for(int i=0;i<4 && !found;i++) - {//finding the pair(edge) in sideFace that do not include any node of tmp[0] edge - found=(tmp[0].first!=sideEdges[i].first && tmp[0].first!=sideEdges[i].second && - tmp[0].second!=sideEdges[i].first && tmp[0].second!=sideEdges[i].second); - if(found) - {//found ! reverse it - pInOpp.first=sideEdges[i].second; - pInOpp.second=sideEdges[i].first; - } - } - if(!found) - return false; - int pos=(int)std::distance(baseEdges.begin(),std::find(baseEdges.begin(),baseEdges.end(),tmp[0])); - std::vector< std::pair >::iterator it=std::find(oppEdges.begin(),oppEdges.end(),pInOpp); - if(it==oppEdges.end())//the opposite edge of side face is not found opposite face ... maybe problem of orientation of polyhedron - return false; - int pos2=(int)std::distance(oppEdges.begin(),it); - int offset=pos-pos2; - if(offset<0) - offset+=lgthBaseFace; - //this is the end copy the result - int *tmp3=new int[lgthBaseFace]; - for(int i=0;i(),(int)INTERP_KERNEL::NORM_QUAD4))==conn+lgth+nbOfFaces) - {//6 faces are QUAD4. - int oppositeFace=-1; - std::set conn1(conn,conn+4); - for(int i=1;i<6 && oppositeFace<0;i++) - { - std::vector tmp; - std::set conn2(conn+5*i,conn+5*i+4); - std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector >(tmp)); - if(tmp.empty()) - oppositeFace=i; - } - if(oppositeFace>=1) - {//oppositeFace of face#0 found. - int tmp2[4]; - if(tryToArrangeOppositeFace(conn,lgth,4,conn,conn+5*oppositeFace,6,tmp2)) - { - std::copy(conn,conn+4,retConn); - std::copy(tmp2,tmp2+4,retConn+4); - retLgth=8; - return INTERP_KERNEL::NORM_HEXA8; - } - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - std::size_t nbOfHexagon=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); - std::size_t nbOfQuad=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); - if(nbOfQuad==6 && nbOfHexagon==2) - { - const int *hexag0=std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); - std::size_t hexg0Id=std::distance(conn+lgth,hexag0); - const int *hexag1=std::find(hexag0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); - std::size_t hexg1Id=std::distance(conn+lgth,hexag1); - const int *connHexag0=conn+5*hexg0Id; - std::size_t lgthH0=std::distance(connHexag0,std::find(connHexag0,conn+lgth,-1)); - if(lgthH0==6) - { - const int *connHexag1=conn+5*hexg0Id+7+(hexg1Id-hexg0Id-1)*5; - std::size_t lgthH1=std::distance(connHexag1,std::find(connHexag1,conn+lgth,-1)); - if(lgthH1==6) - { - std::vector tmp; - std::set conn1(connHexag0,connHexag0+6); - std::set conn2(connHexag1,connHexag1+6); - std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector >(tmp)); - if(tmp.empty()) - { - int tmp2[6]; - if(tryToArrangeOppositeFace(conn,lgth,6,connHexag0,connHexag1,8,tmp2)) - { - std::copy(connHexag0,connHexag0+6,retConn); - std::copy(tmp2,tmp2+6,retConn+6); - retLgth=12; - return INTERP_KERNEL::NORM_HEXGP12; - } - } - } - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -/*! - * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PENTA6 is returned. - * If fails a POLYHED is returned. - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - std::size_t nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3); - std::size_t nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); - if(nbOfTriFace==2 && nbOfQuadFace==3) - { - std::size_t tri3_0=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3)); - std::size_t tri3_1=std::distance(conn+lgth,std::find(conn+lgth+tri3_0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3)); - const int *tri_0=0,*tri_1=0; - const int *w=conn; - for(std::size_t i=0;i<5;i++) - { - if(i==tri3_0) - tri_0=w; - if(i==tri3_1) - tri_1=w; - w=std::find(w,conn+lgth,-1); - w++; - } - std::vector tmp; - std::set conn1(tri_0,tri_0+3); - std::set conn2(tri_1,tri_1+3); - std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector >(tmp)); - if(tmp.empty()) - { - int tmp2[3]; - if(tryToArrangeOppositeFace(conn,lgth,3,tri_0,tri_1,5,tmp2)) - { - std::copy(tri_0,tri_0+3,retConn); - std::copy(tmp2,tmp2+3,retConn+3); - retLgth=6; - return INTERP_KERNEL::NORM_PENTA6; - } - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -/*! - * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PYRA5 is returned. - * If fails a POLYHED is returned. - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - std::size_t nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3); - std::size_t nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); - if(nbOfTriFace==4 && nbOfQuadFace==1) - { - std::size_t quad4_pos=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4)); - const int *quad4=0; - const int *w=conn; - for(std::size_t i=0;i<5 && quad4==0;i++) - { - if(i==quad4_pos) - quad4=w; - w=std::find(w,conn+lgth,-1); - w++; - } - std::set quad4S(quad4,quad4+4); - w=conn; - bool ok=true; - int point=-1; - for(std::size_t i=0;i<5 && ok;i++) - { - if(i!=quad4_pos) - { - std::vector tmp; - std::set conn2(w,w+3); - std::set_intersection(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=tmp.size()==2; - tmp.clear(); - std::set_difference(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=ok && tmp.size()==1; - if(ok) - { - if(point>=0) - ok=point==tmp[0]; - else - point=tmp[0]; - } - } - w=std::find(w,conn+lgth,-1); - w++; - } - if(ok && point>=0) - { - std::copy(quad4,quad4+4,retConn); - retConn[4]=point; - retLgth=5; - return INTERP_KERNEL::NORM_PYRA5; - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -/*! - * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_TETRA4 is returned. - * If fails a POLYHED is returned. - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - if(std::find_if(conn+lgth,conn+lgth+nbOfFaces,std::bind2nd(std::not_equal_to(),(int)INTERP_KERNEL::NORM_TRI3))==conn+lgth+nbOfFaces) - { - std::set tribase(conn,conn+3); - int point=-1; - bool ok=true; - for(int i=1;i<4 && ok;i++) - { - std::vector tmp; - std::set conn2(conn+i*4,conn+4*i+3); - std::set_intersection(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=tmp.size()==2; - tmp.clear(); - std::set_difference(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=ok && tmp.size()==1; - if(ok) - { - if(point>=0) - ok=point==tmp[0]; - else - point=tmp[0]; - } - } - if(ok && point>=0) - { - std::copy(conn,conn+3,retConn); - retConn[3]=point; - retLgth=4; - return INTERP_KERNEL::NORM_TETRA4; - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} diff --git a/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx b/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx deleted file mode 100644 index 94d3163c1..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELCELLSIMPLIFY_HXX__ -#define __INTERPKERNELCELLSIMPLIFY_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT CellSimplify - { - public: - static INTERP_KERNEL::NormalizedCellType simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, int *retConn, int& retLgth); - static int *getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, - int& retNbOfFaces, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPoly2D(bool isQuad, const int *conn, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPoly3D(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyHex8(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static bool tryToArrangeOppositeFace(const int *conn, int lgth, int lgthBaseFace, const int *baseFace, const int *oppFaceId, int nbOfFaces, int *retConnOfOppFace); - static bool isWellOriented(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace); - static bool orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpKernelMatrix.hxx b/medtool/src/INTERP_KERNEL/InterpKernelMatrix.hxx deleted file mode 100755 index 6a65f8b81..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelMatrix.hxx +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPKERNELMATRIX_HXX_ -#define __INTERPKERNELMATRIX_HXX__ - -#include "InterpolationUtils.hxx" - -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - class Matrix; - - template - std::ostream& operator<<(std::ostream& in, const Matrix& m); - template - std::istream& operator>>(std::istream& in, Matrix& m); - - template - class Matrix - { - - class KeyComparator - { - public: - KeyComparator(int val):_val(val) { } - bool operator()(const typename std::pair& val) { return val.first==_val; } - protected: - int _val; - }; - - class Row : public std::vector< std::pair > - { - public: - Row():std::vector< std::pair >(){}; - Row (const Row& row) - { - this->resize(row.size()); - for (int i=0; isize(); i++) - (*this)[i]=row[i]; - } - Row& operator= (const Row& row) - { - this->resize(row.size()); - for (int i=0; isize(); i++) - (*this)[i]=row[i]; - return *this; - } - typename std::vector< std::pair >::const_iterator find(int elem) const - { - return std::find_if(std::vector< std::pair >::begin(),std::vector< std::pair >::end(),KeyComparator(elem)); - } - - void erase(int elem) { std::vector< std::pair >::erase(std::find_if(std::vector< std::pair >::begin(),std::vector< std::pair >::end(),KeyComparator(elem))); } - - void insert(const std::pair& myPair) { vector >::push_back(myPair); } - }; - - private: - unsigned int _nb_rows; - T* _coeffs; - unsigned int* _cols; - std::vector _ncols_offset; - std::vector< Row > _auxiliary_matrix; - friend std::ostream& operator<<<>(std::ostream& in, const Matrix& m); - friend std::istream& operator>><>(std::istream& in, Matrix& m); - bool _is_configured; - public: - typedef Row value_type; - public: - Matrix():_coeffs(0), _cols(0), _nb_rows(0), _is_configured(false) - { } - Matrix(int nbrows):_coeffs(0), _cols(0), _is_configured(false) - { _nb_rows=nbrows; } - Matrix(std::vector > & matrix) : - _coeffs(0), _cols(0), _is_configured(false) - { - _nb_rows=matrix.size(); - _auxiliary_matrix.resize(_nb_rows); - for (int i=0; i<_nb_rows; i++) - { - typename std::map::iterator it; - for (it=matrix[i].begin(); it != matrix[i].end(); it++) - _auxiliary_matrix[i].push_back(*it);//MN: pq push_back plutot que simple affectation? - } - } - /*!Copy constructor - */ - Matrix(const Matrix & m) - { - _is_configured=m._is_configured; - _nb_rows=m._nb_rows; - _auxiliary_matrix=m._auxiliary_matrix; - _ncols_offset=m._ncols_offset; - if (_is_configured) - { - int size=_ncols_offset[_nb_rows]; - _coeffs = new double[size]; - _cols = new unsigned int[size]; - memcpy(_coeffs, m._coeffs, size*sizeof(double)); - memcpy(_cols, m._cols, size*sizeof(int)); - } - } - - ~Matrix() - { - delete[] _coeffs; - delete[] _cols; - } - - Matrix& operator=(const Matrix& m) - { - _is_configured=m._is_configured; - _nb_rows=m._nb_rows; - _auxiliary_matrix=m._auxiliary_matrix; - _ncols_offset=m._ncols_offset; - if (_is_configured) - { - int size=_ncols_offset[_nb_rows]; - _coeffs = new double[size]; - _cols = new unsigned int[size]; - memcpy(_coeffs, m._coeffs, size*sizeof(double)); - memcpy(_cols, m._cols, size*sizeof(int)); - } - return this; - } - - /*! declares a method that specifies the number of rows */ - void resize(unsigned int nbrows) - { - _nb_rows=nbrows; - _auxiliary_matrix.resize(nbrows); - } - - /*! sets (i,j) coefficient to \a value */ - void setIJ(int irow, int icol, T value) - { - if (_is_configured) - throw Exception("filling a configured matrix"); - if (_auxiliary_matrix.empty()) - _auxiliary_matrix.resize(_nb_rows); - - for (unsigned int i=0; i< _auxiliary_matrix[OTT::ind2C(irow)].size(); i++) - if (_auxiliary_matrix[OTT::ind2C(irow)][i].first == icol) - { - _auxiliary_matrix[OTT::ind2C(irow)][i].second = value; - return; - } - _auxiliary_matrix[OTT::ind2C(irow)].push_back(std::make_pair(icol, value)); - } - - /*! - Matrix multiplies vector \a input and stores the result in - vector \a output. - The vector pointed by \a input must be dimensioned - to the number of columns while the vector pointed by output must be - dimensioned to the number of rows. - */ - void multiply(const T* const input, T* const output) - { - if (!_is_configured) - configure(); - - for (int i=0; i< _nb_rows; i++) - { - output[i]=0.; - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - output[i]+=input[icol]*_coeffs[j]; - } - } - } - - /*! - Matrix multiplies vector \a input and stores the result in - vector \a output. - input and output are supposed to represent the same field - discretised on two different on meshes. - nb_comp is the number of components of the fields input and output - The vector pointed by \a input must be dimensioned - to the number of columns times nb_comp while the vector pointed by output must be - dimensioned to the number of rows times nb_comp. - */ - void multiply(const T* const input, T* const output, int nb_comp) - { - if (!_is_configured) - configure(); - - for (int i=0; i< _nb_rows; i++) - { - for(int comp = 0; comp < nb_comp; comp++) - output[i*nb_comp+comp]=0.; - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - for(int comp = 0; comp < nb_comp; comp++) - output[i*nb_comp+comp]+=input[icol*nb_comp+comp]*_coeffs[j]; - } - } - } - /*! - Transpose-multiplies vector \a input and stores the result in - vector \a output. - nb_cols is the number of columns of the matrix, (it is not an attribute of the class) - The vector pointed by \a input must be dimensioned - to the number of lines _nb_rows while the vector pointed by output must be - dimensioned to the number of columns nb_cols. - */ - void transposeMultiply(const T* const input, T* const output, int nb_cols) - { - if (!_is_configured) - configure(); - - for (int icol=0; icol< nb_cols; icol++) - output[icol]=0.; - for (int i=0; i< _nb_rows; i++) - { - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - output[icol]+=input[i]*_coeffs[j]; - } - } - } - /*! - Transpose-multiplies vector \a input and stores the result in - vector \a output. - input and output are supposed to represent the same field - discretised on two different on meshes. - nb_comp is the number of components of the fields input and output - nb_cols is the number of columns of the matrix, (it is not an attribute of the class) - The vector pointed by \a input must be dimensioned - to _nb_rows*nb_comp while the vector pointed by output must be - dimensioned to nb_cols*nb_comp. - */ - void transposeMultiply(const T* const input, T* const output, int nb_cols, int nb_comp) - { - if (!_is_configured) - configure(); - - for (int icol=0; icol< nb_cols; icol++) - for(int comp = 0; comp < nb_comp; comp++) - output[icol*nb_comp+comp]=0.; - - for (int i=0; i< _nb_rows; i++) - { - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - for(int comp = 0; comp < nb_comp; comp++) - output[icol*nb_comp+comp]+=input[i*nb_comp+comp]*_coeffs[j]; - } - } - } - /* - Sums the coefficients of each column of the matrix - nb_cols is the number of columns of the matrix, (it is not an attribute of the class) - The vector output must be dimensioned to nb_cols - */ - void colSum(std::vector< T >& output, int nb_cols) - { - if (!_is_configured) - configure(); - for (int icol=0; icol< nb_cols; icol++) - output[icol]=0.; - for (int i=0; i< _nb_rows; i++) - { - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - output[icol]+=_coeffs[j]; - } - } - } - - /* - Sums the coefficients of each row of the matrix - The vector output must be dimensioned to _nb_rows - */ - void rowSum(std::vector< T >& output) - { - if (!_is_configured) - configure(); - for (int i=0; i< _nb_rows; i++) - { - output[i]=0; - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - output[i]+=_coeffs[j]; - } - } - - /*! This operation freezes the profile of the matrix - and puts it under a CSR form so that it becomes - efficient both in terms of memory occupation and - in terms of multiplication */ - - void configure() - { - _ncols_offset.resize(_nb_rows+1); - _ncols_offset[0]=0; - for (unsigned int i=0; i<_nb_rows; i++) - _ncols_offset[i+1]=_ncols_offset[i]+_auxiliary_matrix[i].size(); - int nbcoeffs= _ncols_offset[_nb_rows]; - _cols=new unsigned int[nbcoeffs]; - _coeffs=new T[nbcoeffs]; - unsigned int* cols_ptr=_cols; - T* coeffs_ptr=_coeffs; - for (unsigned int i=0; i<_nb_rows; i++) - { - for (unsigned int j=0; j<_auxiliary_matrix[i].size(); j++) - { - *cols_ptr++ = OTT::ind2C(_auxiliary_matrix[i][j].first); - *coeffs_ptr++ = _auxiliary_matrix[i][j].second; - } - } - _auxiliary_matrix.clear(); - _is_configured=true; - } - - /*! - * 0 <= irow < n - */ - Row &operator [] (unsigned int irow) - { - return _auxiliary_matrix[irow]; - } - - int getNbRows() - { - return _nb_rows; - } - - }; - - /*! output to an ascii file - only nonzero elements are written - - the first line contains the indexing (0 or 1) - - the second line contains the number of rows. - - for each row, a line contains: - - the number of nonzero coeffs - - and for each coeff : icol, value - - for instance, matrix - | 1.0 0.0 0.5 | - | 0.0 1.0 0.0 | - | 0.2 0.0 1.0 | - will be displayed in 0-indexing as - 0 - 3 - 2 0 1.0 2 0.5 - 1 1 1.0 - 2 0 0.2 2 1.0 - */ - - template - std::ostream& operator<<(std::ostream& out, const Matrix& m) - { - if (m._is_configured) - { - out << OTT::indFC(0) <::indFC(m._cols[j]) <<"\t"<::indFC(0) <<"\n"; - out << m._nb_rows <<"\n"; - for (unsigned int i=0; i - std::istream& operator>>(std::istream& in, Matrix& m) - { - int index_base_test; - in >> index_base_test; - if (index_base_test!=OTT::indFC(0)) - { - std::cerr << "file index is "<> m._nb_rows; - m._auxiliary_matrix.resize(m._nb_rows); - for (unsigned int i=0; i> ncols; - m._auxiliary_matrix[i].resize(ncols); - double value; - unsigned int col; - for (unsigned int j=0; j>col; - in>>value; - m._auxiliary_matrix[i].push_back(std::make_pair(col, value)); - } - } - return in; - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx b/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx deleted file mode 100644 index 59cfecaa3..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelMatrixTools.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - /* - * Computes the dot product of two vectors. - * This routine uses unrolled loops for increments equal to one. - * - * Reference: - * - * Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, - * LINPACK User's Guide, - * SIAM, 1979, - * ISBN13: 978-0-898711-72-1, - * LC: QA214.L56. - * - * Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, - * Basic Linear Algebra Subprograms for Fortran Usage, - * Algorithm 539, - * ACM Transactions on Mathematical Software, - * Volume 5, Number 3, September 1979, pages 308-323. - * - * \param [in] n the number of entries in the vectors. - * \param [in] dx the first vector. - * \param [in] incx the increment between successive entries in \a dx. - * \param [in] dy the second vector. - * \param [in] incy the increment between successive entries in \a dy. - * \return the sum of the product of the corresponding entries of \a dx and \a dy. - */ - double ddot(int n, const double *dx, int incx, const double *dy, int incy) - { - double dtemp=0.0; - int i,ix,iy,m; - if(n<=0) - return dtemp; - // Code for unequal increments or equal increments not equal to 1. - if(incx!=1 || incy!=1) - { - if (incx>=0) - ix=0; - else - ix=(-n+1)*incx; - - if(incy>=0) - iy=0; - else - iy=(-n+1)*incy; - for(i=0;i=0.0) - return x; - else - return -x; - } - - void dswap(int n, double *x, int incx, double *y, int incy) - { - int i,ix,iy,m; - double temp; - - if(n<=0) { } - else if(incx==1 && incy==1) - { - m=n%3; - for(i=0;i=0;k--) - { - for(int i=k+1;i ipvt=new int[n]; - INTERP_KERNEL::AutoPtr work=new double[n*n]; - std::copy(A,A+n*n,iA); - dgefa(iA,n,n,ipvt); - dgedi(iA,n,n,ipvt,work); - } -} diff --git a/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx b/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx deleted file mode 100644 index 95fb28f23..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELMATRIXTOOLS_HXX__ -#define __INTERPKERNELMATRIXTOOLS_HXX__ - -#include "INTERPKERNELDefines.hxx" - -namespace INTERP_KERNEL -{ - void INTERPKERNEL_EXPORT matrixProduct(const double *A, int n1, int p1, const double *B, int n2, int p2, double *C); - void INTERPKERNEL_EXPORT inverseMatrix(const double *A, int n, double *iA); - void INTERPKERNEL_EXPORT daxpy(int n, double da, const double *dx, int incx, double *dy, int incy); -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx b/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx deleted file mode 100644 index f09c0ff26..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelMeshQuality.hxx" - -#include -#include -#include -#include - -double INTERP_KERNEL::quadSkew(const double *coo) -{ - double pa0[3]={ - coo[3]+coo[6]-coo[0]-coo[9], - coo[4]+coo[7]-coo[1]-coo[10], - coo[5]+coo[8]-coo[2]-coo[11] - }; - double pa1[3]={ - coo[6]+coo[9]-coo[0]-coo[3], - coo[7]+coo[10]-coo[1]-coo[4], - coo[8]+coo[11]-coo[2]-coo[5], - }; - double l0=sqrt(pa0[0]*pa0[0]+pa0[1]*pa0[1]+pa0[2]*pa0[2]); - double l1=sqrt(pa1[0]*pa1[0]+pa1[1]*pa1[1]+pa1[2]*pa1[2]); - if(l0<1.e-15) - return 0.; - if(l1<1.e-15) - return 0.; - pa0[0]/=l0; pa0[1]/=l0; pa0[2]/=l0; - pa1[0]/=l1; pa1[1]/=l1; pa1[2]/=l1; - return pa0[0]*pa1[0]+pa0[1]*pa1[1]+pa0[2]*pa1[2]; -} - -double INTERP_KERNEL::quadEdgeRatio(const double *coo) -{ - double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); - double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); - double c2=(coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8]); - double d2=(coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11]); - double mab=a2Mcd?Mab:Mcd; - if(m2>1.e-15) - return sqrt(M2/m2); - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::quadAspectRatio(const double *coo) -{ - double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); - double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); - double c=sqrt((coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8])); - double d=sqrt((coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11])); - double ma=a>b?a:b; - double mb=c>d?c:d; - double hm=ma>mb?ma:mb; - double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), - (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), - (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; - double cd[3]={(coo[10]-coo[7])*(coo[2]-coo[11])-(coo[1]-coo[10])*(coo[11]-coo[8]), - (coo[11]-coo[8])*(coo[0]-coo[9])-(coo[9]-coo[6])*(coo[2]-coo[11]), - (coo[9]-coo[6])*(coo[1]-coo[10])-(coo[10]-coo[7])*(coo[0]-coo[9])}; - double e=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2])+sqrt(cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]); - if(d>1e-15) - return 0.5*(a+b+c+d)*hm/e; - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::quadWarp(const double *coo) -{ - double e0[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; - double e1[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; - double e2[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; - double e3[3]={coo[0]-coo[9],coo[1]-coo[10],coo[2]-coo[11]}; - - double n0[3]={e3[1]*e0[2]-e3[2]*e0[1],e3[2]*e0[0]-e3[0]*e0[2],e3[0]*e0[1]-e3[1]*e0[0]}; - double n1[3]={e0[1]*e1[2]-e0[2]*e1[1],e0[2]*e1[0]-e0[0]*e1[2],e0[0]*e1[1]-e0[1]*e1[0]}; - double n2[3]={e1[1]*e2[2]-e1[2]*e2[1],e1[2]*e2[0]-e1[0]*e2[2],e1[0]*e2[1]-e1[1]*e2[0]}; - double n3[3]={e2[1]*e3[2]-e2[2]*e3[1],e2[2]*e3[0]-e2[0]*e3[2],e2[0]*e3[1]-e2[1]*e3[0]}; - - double l0=sqrt(n0[0]*n0[0]+n0[1]*n0[1]+n0[2]*n0[2]); - double l1=sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]); - double l2=sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]); - double l3=sqrt(n3[0]*n3[0]+n3[1]*n3[1]+n3[2]*n3[2]); - - if(l0<1.e-15 || l1<1.e-15 || l2<1.e-15 || l3<1e-15) - return std::numeric_limits::min(); - - double warp=std::min(n0[0]/l0*n2[0]/l2+n0[1]/l0*n2[1]/l2+n0[2]/l0*n2[2]/l2,n1[0]/l1*n3[0]/l3+n1[1]/l1*n3[1]/l3+n1[2]/l1*n3[2]/l3); - return warp*warp*warp; -} - -double INTERP_KERNEL::triEdgeRatio(const double *coo) -{ - double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); - double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); - double c2=(coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8]); - double mab=a2mab?mab:c2; - double M2=c2>Mab?c2:Mab; - if(m2>1.e-15) - return sqrt(M2/m2); - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::triAspectRatio(const double *coo) -{ - double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); - double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); - double c=sqrt((coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8])); - - double hm=a>b?a:b; - hm=hm>c?hm:c; - - double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), - (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), - (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; - double d=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]); - static const double normalizeCoeff=sqrt(3.)/6.; - if(d>1.e-15) - return normalizeCoeff*hm*(a+b+c)/d; - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::tetraEdgeRatio(const double *coo) -{ - double a[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; - double b[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; - double c[3]={coo[0]-coo[6],coo[1]-coo[7],coo[2]-coo[8]}; - double d[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; - double e[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; - double f[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; - - double l2[6]= - {a[0]*a[0]+a[1]*a[1]+a[2]*a[2], - b[0]*b[0]+b[1]*b[1]+b[2]*b[2], - c[0]*c[0]+c[1]*c[1]+c[2]*c[2], - d[0]*d[0]+d[1]*d[1]+d[2]*d[2], - e[0]*e[0]+e[1]*e[1]+e[2]*e[2], - f[0]*f[0]+f[1]*f[1]+f[2]*f[2]}; - - double M2=*std::max_element(l2,l2+6); - double m2=*std::min_element(l2,l2+6); - if(m2>1e-15) - return sqrt(M2/m2); - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::tetraAspectRatio(const double *coo) -{ - static const double normalizeCoeff=sqrt(6.)/12.; - double ab[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; - double ac[3]={coo[6]-coo[0],coo[7]-coo[1],coo[8]-coo[2]}; - double ad[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; - double detTet=(ab[0]*(ac[1]*ad[2]-ac[2]*ad[1]))+(ab[1]*(ac[2]*ad[0]-ac[0]*ad[2]))+(ab[2]*(ac[0]*ad[1]-ac[1]*ad[0])); - //if(detTet<1.e-15) - // return std::numeric_limits::max(); - double bc[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; - double bd[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; - double cd[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; - - double ab2=ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]; - double bc2=bc[0]*bc[0]+bc[1]*bc[1]+bc[2]*bc[2]; - double ac2=ac[0]*ac[0]+ac[1]*ac[1]+ac[2]*ac[2]; - double ad2=ad[0]*ad[0]+ad[1]*ad[1]+ad[2]*ad[2]; - double bd2=bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]; - double cd2=cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]; - - double A=ab2>bc2?ab2:bc2; - double B=ac2>ad2?ac2:ad2; - double C=bd2>cd2?bd2:cd2; - double D=A>B?A:B; - double hm=D>C?sqrt(D):sqrt(C); - - bd[0]=ab[1]*bc[2]-ab[2]*bc[1]; bd[1]=ab[2]*bc[0]-ab[0]*bc[2]; bd[2]=ab[0]*bc[1]-ab[1]*bc[0]; - A=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - bd[0]=ab[1]*ad[2]-ab[2]*ad[1]; bd[1]=ab[2]*ad[0]-ab[0]*ad[2]; bd[2]=ab[0]*ad[1]-ab[1]*ad[0]; - B=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - bd[0]=ac[1]*ad[2]-ac[2]*ad[1]; bd[1]=ac[2]*ad[0]-ac[0]*ad[2]; bd[2]=ac[0]*ad[1]-ac[1]*ad[0]; - C=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - bd[0]=bc[1]*cd[2]-bc[2]*cd[1]; bd[1]=bc[2]*cd[0]-bc[0]*cd[2]; bd[2]=bc[0]*cd[1]-bc[1]*cd[0]; - D=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - return normalizeCoeff*hm*(A+B+C+D)/fabs(detTet); -} diff --git a/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx b/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx deleted file mode 100644 index 88afc15d9..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPKERNELMESHQUALITY_HXX_ -#define __INTERPKERNELMESHQUALITY_HXX__ - -#include "INTERPKERNELDefines.hxx" - -namespace INTERP_KERNEL -{ - INTERPKERNEL_EXPORT double quadSkew(const double *coo); - INTERPKERNEL_EXPORT double quadEdgeRatio(const double *coo); - INTERPKERNEL_EXPORT double quadAspectRatio(const double *coo); - INTERPKERNEL_EXPORT double quadWarp(const double *coo); - INTERPKERNEL_EXPORT double triEdgeRatio(const double *coo); - INTERPKERNEL_EXPORT double triAspectRatio(const double *coo); - INTERPKERNEL_EXPORT double tetraEdgeRatio(const double *coo); - INTERPKERNEL_EXPORT double tetraAspectRatio(const double *coo); -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpKernelUtilities.hxx b/medtool/src/INTERP_KERNEL/InterpKernelUtilities.hxx deleted file mode 100644 index 44ee02ab1..000000000 --- a/medtool/src/INTERP_KERNEL/InterpKernelUtilities.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPKERNELUTILITIES_HXX__ -#define __INTERPKERNELUTILITIES_HXX__ - -//! DON'T INCLUDE THIS FILE IN .h NOR IN .hxx FILES !!!!!!!!! -#ifdef _DEBUG_ -# define MESSAGE(chain) {HERE ; cerr << chain << endl ;} -#else -# define MESSAGE(chain) -#endif - -#ifdef _DEBUG_ -# define HERE {cout< (message) , __FILE__ , __LINE__ - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation.hxx b/medtool/src/INTERP_KERNEL/Interpolation.hxx deleted file mode 100644 index 16415593b..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION_HXX__ -#define __INTERPOLATION_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpolationOptions.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - class Interpolation : public InterpolationOptions - { - public: - Interpolation() { } - Interpolation(const InterpolationOptions& io) :InterpolationOptions(io){} - //interpolation of two triangular meshes. - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result) - { return asLeaf().interpolateMeshes(meshS,meshT,result); } - template - int fromIntegralUniform(const MyMeshType& meshT, MatrixType& result, const std::string& method) { return fromToIntegralUniform(false,meshT,result,method); } - template - int toIntegralUniform(const MyMeshType& meshS, MatrixType& result, const std::string& method) { return fromToIntegralUniform(true,meshS,result,method); } - template - static double CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel); - protected: - template - int fromToIntegralUniform(bool fromTo, const MyMeshType& mesh, MatrixType& result, const std::string& method); - protected: - TrueMainInterpolator& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation.txx b/medtool/src/INTERP_KERNEL/Interpolation.txx deleted file mode 100644 index 65a9fb4d3..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERPOLATION_TXX__ -#define __INTERPOLATION_TXX__ - -#include "Interpolation.hxx" -#include "IntegralUniformIntersector.hxx" -#include "IntegralUniformIntersector.txx" -#include "VectorUtils.hxx" - -namespace INTERP_KERNEL -{ - template - template - int Interpolation::fromToIntegralUniform(bool fromTo, const MyMeshType& mesh, MatrixType& result, const std::string& method) - { - typedef typename MyMeshType::MyConnType ConnType; - int ret=-1; - if(method=="P0") - { - IntegralUniformIntersectorP0 intersector(mesh,InterpolationOptions::getMeasureAbsStatus()); - intersector.setFromTo(fromTo); - std::vector tmp; - intersector.intersectCells(0,tmp,result); - ret=intersector.getNumberOfColsOfResMatrix(); - } - else if(method=="P1") - { - IntegralUniformIntersectorP1 intersector(mesh,InterpolationOptions::getMeasureAbsStatus()); - intersector.setFromTo(fromTo); - std::vector tmp; - intersector.intersectCells(0,tmp,result); - ret=intersector.getNumberOfColsOfResMatrix(); - } - else - throw INTERP_KERNEL::Exception("Invalid method specified in fromIntegralUniform : must be in { \"P0\", \"P1\"}"); - return ret; - } - - template - template - double Interpolation::CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - - long nbMailleS=myMeshS.getNumberOfElements(); - long nbMailleT=myMeshT.getNumberOfElements(); - - /**************************************************/ - /* Search the characteristic size of the meshes */ - /**************************************************/ - - double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); - double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); - double diagonalS,dimCaracteristicS=std::numeric_limits::max(); - if(nbMailleS!=0) - { - diagonalS=getDistanceBtw2Pts(BoxS+SPACEDIM,BoxS); - dimCaracteristicS=diagonalS/nbMailleS; - } - double diagonalT,dimCaracteristicT=std::numeric_limits::max(); - if(nbMailleT!=0) - { - diagonalT=getDistanceBtw2Pts(BoxT+SPACEDIM,BoxT); - dimCaracteristicT=diagonalT/nbMailleT; - } - if (printLevel>=1) - { - std::cout << " - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl; - std::cout << " - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl; - } - - return std::min(dimCaracteristicS, dimCaracteristicT); - - } - -} - -#endif - diff --git a/medtool/src/INTERP_KERNEL/Interpolation1D.hxx b/medtool/src/INTERP_KERNEL/Interpolation1D.hxx deleted file mode 100755 index 351cb4296..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation1D.hxx +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION1D_HXX__ -#define __INTERPOLATION1D_HXX__ - -#include "InterpolationCurve.hxx" - -namespace INTERP_KERNEL -{ - class Interpolation1D : public InterpolationCurve - { - public: - Interpolation1D() { } - Interpolation1D(const InterpolationOptions& io):InterpolationCurve(io) {} - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation1D.txx b/medtool/src/INTERP_KERNEL/Interpolation1D.txx deleted file mode 100644 index dcc4f77ff..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation1D.txx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERPOLATION1D_TXX__ -#define __INTERPOLATION1D_TXX__ - -#include "Interpolation1D.hxx" - -#include "InterpolationCurve.txx" - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation2D.hxx b/medtool/src/INTERP_KERNEL/Interpolation2D.hxx deleted file mode 100755 index 82a8980b3..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation2D.hxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION2D_HXX__ -#define __INTERPOLATION2D_HXX__ - -#include "InterpolationPlanar.hxx" - -namespace INTERP_KERNEL -{ - class Interpolation2D : public InterpolationPlanar - { - public: - Interpolation2D() { } - Interpolation2D(const InterpolationOptions& io):InterpolationPlanar(io) { } - public: - bool doRotate() const { return false; } - double medianPlane() const { return 0.; } - template - void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const { } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation2D.txx b/medtool/src/INTERP_KERNEL/Interpolation2D.txx deleted file mode 100644 index fa871e5b9..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation2D.txx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERPOLATION2D_TXX__ -#define __INTERPOLATION2D_TXX__ - -#include "Interpolation2D.hxx" - -#include "InterpolationPlanar.txx" - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation2D1D.hxx b/medtool/src/INTERP_KERNEL/Interpolation2D1D.hxx deleted file mode 100644 index 2ef88f89c..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation2D1D.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION2D1D_HXX__ -#define __INTERPOLATION2D1D_HXX__ - -#include "Interpolation.hxx" -#include "Planar2D1DIntersectorP0P0.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - /*! - * Contrary to its name this class deals with 1D mesh in source and 2D mesh in target. - * The meshdim of 'MyMeshType' in input is ignored that's why 'meshS' and 'meshT' - * have the same type. - * '_duplicate_faces' attribute stores duplicated faces in the following format. - * The key of '_duplicate_faces' represents the 1D cellId that is shared by - * more than one 2D target cell, and the value of '_duplicate_faces' - * the 2D target cells. The size of the value of '_duplicate_faces' is more than or equal to 2. - */ - class Interpolation2D1D : public Interpolation - { - public: - typedef std::map > DuplicateFacesType; - - Interpolation2D1D() { setOrientation(2); } - Interpolation2D1D(const InterpolationOptions& io):Interpolation(io) { } - public: - - // Main function to interpolate triangular and quadratic meshes - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result, const std::string& method); - DuplicateFacesType retrieveDuplicateFaces() const - { - return _duplicate_faces; - } - private: - DuplicateFacesType _duplicate_faces; - private: - double _dim_caracteristic; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation2D1D.txx b/medtool/src/INTERP_KERNEL/Interpolation2D1D.txx deleted file mode 100644 index 482a88250..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation2D1D.txx +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERPOLATION2D1D_TXX__ -#define __INTERPOLATION2D1D_TXX__ - -#include "Interpolation2D1D.hxx" - -namespace INTERP_KERNEL -{ - - /** \brief Main function to interpolate triangular or quadrangular meshes. - \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param myMeshS Planar source mesh - * @Param myMeshT Planar target mesh - * @return vector containing for each element i of the source mesh, a map giving for each element j - * of the target mesh which i intersects, the area of the intersection - * - */ - template - int Interpolation2D1D::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const std::string& method) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - long global_start =clock(); - int counter=0; - /***********************************************************/ - /* Check both meshes are made of triangles and quadrangles */ - /***********************************************************/ - - long nbMailleS=myMeshS.getNumberOfElements(); - - /**************************************************/ - /* Search the characteristic size of the meshes */ - /**************************************************/ - - int printLevel = InterpolationOptions::getPrintLevel(); - _dim_caracteristic = CalculateCharacteristicSizeOfMeshes(myMeshS, myMeshT, printLevel); - if (printLevel>=1) - { - std::cout << "Interpolation2D1D::computation of the intersections" << std::endl; - } - - PlanarIntersector* intersector=0; - std::string meth = InterpolationOptions::filterInterpolationMethod(method); - if(meth=="P0P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid intersection type ! Must be : Geometric2D"); - } - } - else - throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be : \"P0P0\""); - - /****************************************************************/ - /* Create a search tree based on the bounding boxes */ - /* Instanciate the intersector and initialise the result vector */ - /****************************************************************/ - - long start_filtering=clock(); - - std::vector bbox; - intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes - const double *bboxPtr=0; - if(nbMailleS>0) - bboxPtr=&bbox[0]; - BBTree my_tree(bboxPtr, 0, 0,nbMailleS, -getPrecision());//creating the search structure - - long end_filtering=clock(); - - result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. - - /****************************************************/ - /* Loop on the target cells - core of the algorithm */ - /****************************************************/ - long start_intersection=clock(); - long nbelem_type=myMeshT.getNumberOfElements(); - const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); - for(int iT=0; iT intersecting_elems; - double bb[2*SPACEDIM]; - intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); - my_tree.getIntersectingElems(bb, intersecting_elems); - intersector->intersectCells(iT,intersecting_elems,result); - counter+=intersecting_elems.size(); - intersecting_elems.clear(); - } - int ret=intersector->getNumberOfColsOfResMatrix(); - - const DuplicateFacesType& intersectFaces = *intersector->getIntersectFaces(); - DuplicateFacesType::const_iterator iter; - for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter) - { - if (iter->second.size() > 1) - { - _duplicate_faces.insert(std::make_pair(iter->first, iter->second)); - } - } - - delete intersector; - - if (InterpolationOptions::getPrintLevel() >=1) - { - long end_intersection=clock(); - std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; - std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; - long global_end =clock(); - std::cout << "Number of computed intersections = " << counter << std::endl; - std::cout << "Global time= " << global_end - global_start << std::endl; - } - return ret; - } - -} -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation2DCurve.cxx b/medtool/src/INTERP_KERNEL/Interpolation2DCurve.cxx deleted file mode 100644 index 0db047975..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation2DCurve.cxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "Interpolation2DCurve.hxx" -#include "InterpolationCurve.txx" - -namespace INTERP_KERNEL -{ - Interpolation2DCurve::Interpolation2DCurve() - { - // to have non-zero default thickness of target element - InterpolationOptions::setBoundingBoxAdjustmentAbs( InterpolationOptions::getPrecision() ); - } - - Interpolation2DCurve::Interpolation2DCurve - (const InterpolationOptions& io):InterpolationCurve(io) - { - // to have non-zero default thickness of target element - InterpolationOptions::setBoundingBoxAdjustmentAbs( InterpolationOptions::getPrecision() ); - } - - /** - * \brief Function used to set the options for the intersection calculation - * \details The following options can be modified: - * -# Precision: Level of precision of the computations. - * - Values: positive real number. - * - Default: 1.0E-12. - * -# Tolerance: Thickness of target element. - * - Values: positive real number. - * - Default: 1.0E-12. - * -# Median line: Position of the median line where both segments will be projected. - * - Values: real number between 0.0 and 1.0. - * - Default: 0.5 - */ - void Interpolation2DCurve::setOptions (double precision, - double tolerance, - double medianLine) - { - InterpolationOptions::setPrecision(precision); - InterpolationOptions::setBoundingBoxAdjustmentAbs(tolerance); - InterpolationOptions::setMedianPlane(medianLine); - } -} diff --git a/medtool/src/INTERP_KERNEL/Interpolation2DCurve.hxx b/medtool/src/INTERP_KERNEL/Interpolation2DCurve.hxx deleted file mode 100644 index d0348bebe..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation2DCurve.hxx +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION2DCURVE_HXX__ -#define __INTERPOLATION2DCURVE_HXX__ - -#include "InterpolationCurve.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Interpolation2DCurve : public InterpolationCurve - { - public: - Interpolation2DCurve(); - Interpolation2DCurve(const InterpolationOptions& io); - // geometric precision, intersection tolerance, coice of the median line, - void setOptions(double precision, double tolerance, double medianLine); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation3D.cxx b/medtool/src/INTERP_KERNEL/Interpolation3D.cxx deleted file mode 100644 index 16bd09cc0..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3D.cxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "Interpolation3D.hxx" -#include "Interpolation3D.txx" - -namespace INTERP_KERNEL -{ - /** - * \class Interpolation3D - * \brief Class used to calculate the volumes of intersection between the elements of two 3D meshes. - * - */ - /** - * Default constructor - * - */ - Interpolation3D::Interpolation3D() - { - } - Interpolation3D::Interpolation3D(const InterpolationOptions& io):Interpolation(io) - { - } -} diff --git a/medtool/src/INTERP_KERNEL/Interpolation3D.hxx b/medtool/src/INTERP_KERNEL/Interpolation3D.hxx deleted file mode 100644 index 828c63c76..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3D.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION3D_HXX__ -#define __INTERPOLATION3D_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "Interpolation.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Interpolation3D : public Interpolation - { - public: - Interpolation3D(); - Interpolation3D(const InterpolationOptions& io); - template - int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method); - private: - SplittingPolicy _splitting_policy; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation3D.txx b/medtool/src/INTERP_KERNEL/Interpolation3D.txx deleted file mode 100644 index bc68b525c..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3D.txx +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION3D_TXX__ -#define __INTERPOLATION3D_TXX__ - -#include "Interpolation3D.hxx" -#include "Interpolation.txx" -#include "MeshElement.txx" -#include "TransformedTriangle.hxx" -#include "PolyhedronIntersectorP0P0.txx" -#include "PointLocator3DIntersectorP0P0.txx" -#include "PolyhedronIntersectorP0P1.txx" -#include "PointLocator3DIntersectorP0P1.txx" -#include "PolyhedronIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P0Bary.txx" -#include "PointLocator3DIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P1.txx" -#include "PointLocator3DIntersectorP1P1.txx" -#include "Barycentric3DIntersectorP1P1.txx" -#include "Log.hxx" -// If defined, use recursion to traverse the binary search tree, else use the BBTree class -//#define USE_RECURSIVE_BBOX_FILTER - -#ifdef USE_RECURSIVE_BBOX_FILTER -#include "MeshRegion.txx" -#include "RegionNode.hxx" -#include - -#else // use BBTree class - -#include "BBTree.txx" - -#endif - -namespace INTERP_KERNEL -{ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh 3-dimensional source mesh - * @param targetMesh 3-dimesional target mesh, containing only tetraedra - * @param result matrix in which the result is stored - * - */ - template - int Interpolation3D::interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method) - { - typedef typename MyMeshType::MyConnType ConnType; - // create MeshElement objects corresponding to each element of the two meshes - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - const unsigned long numTargetElems = targetMesh.getNumberOfElements(); - - LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); - - std::vector*> srcElems(numSrcElems); - std::vector*> targetElems(numTargetElems); - - std::map*, int> indices; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - srcElems[i] = new MeshElement(i, srcMesh); - - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - targetElems[i] = new MeshElement(i, targetMesh); - - Intersector3D* intersector=0; - std::string methC = InterpolationOptions::filterInterpolationMethod(method); - if(methC=="P0P0") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP0P0(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP0P0(targetMesh, srcMesh, getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P0 interp specified : must be Triangle or PointLocator."); - } - } - else if(methC=="P0P1") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP0P1(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP0P1(targetMesh, srcMesh, getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P1 interp specified : must be Triangle or PointLocator."); - } - } - else if(methC=="P1P0") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP1P0(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP1P0(targetMesh, srcMesh, getPrecision()); - break; - case Barycentric: - intersector=new PolyhedronIntersectorP1P0Bary(targetMesh, srcMesh, getSplittingPolicy()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P1P0 interp specified : must be Triangle, PointLocator or Barycentric."); - } - } - else if(methC=="P1P1") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP1P1(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP1P1(targetMesh, srcMesh, getPrecision()); - break; - case Barycentric: - intersector=new Barycentric3DIntersectorP1P1(targetMesh, srcMesh, getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P1P1 interp specified : must be Triangle or PointLocator."); - } - } - else - throw Exception("Invalid method choosed must be in \"P0P0\", \"P0P1\", \"P1P0\" or \"P1P1\"."); - // create empty maps for all source elements - result.resize(intersector->getNumberOfRowsOfResMatrix()); - -#ifdef USE_RECURSIVE_BBOX_FILTER - - /* - * Performs a depth-first search over srcMesh, using bounding boxes to recursively eliminate the elements of targetMesh - * which cannot intersect smaller and smaller regions of srcMesh. At each level, each region is divided in two, forming - * a binary search tree with leaves consisting of only one element of the source mesh together with the elements of the - * target mesh that can intersect it. The recursion is implemented with a stack of RegionNodes, each one containing a - * source region and a target region. Each region has an associated bounding box and a vector of pointers to the elements - * that belong to it. Each MeshElement contains a bounding box and the global number of the corresponding element in the mesh. - */ - - // create initial RegionNode and fill up its source region with all the source mesh elements and - // its target region with all the target mesh elements whose bounding box - // intersects that of the source region - - RegionNode* firstNode = new RegionNode(); - - MeshRegion& srcRegion = firstNode->getSrcRegion(); - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - { - srcRegion.addElement(srcElems[i], srcMesh); - } - - MeshRegion& targetRegion = firstNode->getTargetRegion(); - - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - { - if(!srcRegion.isDisjointWithElementBoundingBox( *(targetElems[i]) )) - { - targetRegion.addElement(targetElems[i], targetMesh); - } - } - - // Using a stack, descend recursively, creating at each step two new RegionNodes having as source region the left and - // right part of the source region of the current node (created using MeshRegion::split()) and as target region all the - // elements of the target mesh whose bounding box intersects the corresponding part - // Continue until the source region contains only one element, at which point the intersection volumes are - // calculated with all the remaining target mesh elements and stored in the matrix if they are non-zero. - - std::stack< RegionNode* > nodes; - nodes.push(firstNode); - - while(!nodes.empty()) - { - RegionNode* currNode = nodes.top(); - nodes.pop(); - LOG(4, "Popping node "); - - if(currNode->getTargetRegion().getNumberOfElements() == 1) - { - // calculate volumes - LOG(4, " - One element"); - - MeshElement* targetElement = *(currNode->getTargetRegion().getBeginElements()); - std::vector intersectElems; - for(typename std::vector< MeshElement* >::const_iterator iter = currNode->getSrcRegion().getBeginElements();iter != currNode->getSrcRegion().getEndElements();++iter) - intersectElems.push_back((*iter)->getIndex()); - intersector->intersectCells(targetElement->getIndex(),intersectElems,result); - } - else // recursion - { - - LOG(4, " - Recursion"); - - RegionNode* leftNode = new RegionNode(); - RegionNode* rightNode = new RegionNode(); - - // split current source region - //} decide on axis - static BoundingBox::BoxCoord axis = BoundingBox::XMAX; - - currNode->getTargetRegion().split(leftNode->getTargetRegion(), rightNode->getTargetRegion(), axis, targetMesh); - - LOG(5, "After split, left target region has " << leftNode->getTargetRegion().getNumberOfElements() - << " elements and right target region has " << rightNode->getTargetRegion().getNumberOfElements() - << " elements"); - - // ugly hack to avoid problem with enum which does not start at 0 - // I guess I ought to implement ++ for it instead ... - // Anyway, it basically chooses the next axis, cyclically - axis = (axis != BoundingBox::ZMAX) ? static_cast(axis + 1) : BoundingBox::XMAX; - - // add source elements of current node that overlap the target regions of the new nodes - LOG(5, " -- Adding source elements"); - int numLeftElements = 0; - int numRightElements = 0; - for(typename std::vector*>::const_iterator iter = currNode->getSrcRegion().getBeginElements() ; - iter != currNode->getSrcRegion().getEndElements() ; ++iter) - { - LOG(6, " --- New target node"); - - if(!leftNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) - { - leftNode->getSrcRegion().addElement(*iter, srcMesh); - ++numLeftElements; - } - - if(!rightNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) - { - rightNode->getSrcRegion().addElement(*iter, srcMesh); - ++numRightElements; - } - - } - - LOG(5, "Left src region has " << numLeftElements << " elements and right src region has " - << numRightElements << " elements"); - - // push new nodes on stack - if(numLeftElements != 0) - { - nodes.push(leftNode); - } - else - { - delete leftNode; - } - - if(numRightElements != 0) - { - nodes.push(rightNode); - } - else - { - delete rightNode; - } - } - - // all nodes are deleted here - delete currNode; - - LOG(4, "Next iteration. Nodes left : " << nodes.size()); - } - -#else // Use BBTree - - // create BBTree structure - // - get bounding boxes - double* bboxes = new double[6 * numSrcElems]; - int* srcElemIdx = new int[numSrcElems]; - for(unsigned long i = 0; i < numSrcElems ; ++i) - { - // get source bboxes in right order - const BoundingBox* box = srcElems[i]->getBoundingBox(); - bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); - bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); - bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); - bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); - bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); - bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); - - // source indices have to begin with zero for BBox, I think - srcElemIdx[i] = srcElems[i]->getIndex(); - } - - BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems); - - // for each target element, get source elements with which to calculate intersection - // - calculate intersection by calling intersectCells - for(unsigned long i = 0; i < numTargetElems; ++i) - { - const BoundingBox* box = targetElems[i]->getBoundingBox(); - const int targetIdx = targetElems[i]->getIndex(); - - // get target bbox in right order - double targetBox[6]; - targetBox[0] = box->getCoordinate(BoundingBox::XMIN); - targetBox[1] = box->getCoordinate(BoundingBox::XMAX); - targetBox[2] = box->getCoordinate(BoundingBox::YMIN); - targetBox[3] = box->getCoordinate(BoundingBox::YMAX); - targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); - targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); - - std::vector intersectElems; - - tree.getIntersectingElems(targetBox, intersectElems); - - if ( !intersectElems.empty() ) - intersector->intersectCells(targetIdx,intersectElems,result); - } - - delete [] bboxes; - delete [] srcElemIdx; - -#endif - // free allocated memory - int ret=intersector->getNumberOfColsOfResMatrix(); - - delete intersector; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - { - delete srcElems[i]; - } - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - { - delete targetElems[i]; - } - return ret; - - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation3D2D.cxx b/medtool/src/INTERP_KERNEL/Interpolation3D2D.cxx deleted file mode 100644 index 4e8cee7f7..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3D2D.cxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Interpolation3D2D.hxx" - -namespace INTERP_KERNEL -{ - /** - * Default constructor - * - */ - Interpolation3D2D::Interpolation3D2D() - { - } - Interpolation3D2D::Interpolation3D2D(const InterpolationOptions& io):Interpolation(io) - { - } -} diff --git a/medtool/src/INTERP_KERNEL/Interpolation3D2D.hxx b/medtool/src/INTERP_KERNEL/Interpolation3D2D.hxx deleted file mode 100644 index 761c37f34..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3D2D.hxx +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPOLATION3D2D_HXX__ -#define __INTERPOLATION3D2D_HXX__ - -#include -#include - -#include "INTERPKERNELDefines.hxx" -#include "Interpolation.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - /*! - * Contrary to its name this class deals with 2D mesh in source and 3D mesh in target. - * The meshdim of 'MyMeshType' in input is ignored that's why 'meshS' and 'meshT' - * have the same type. - * '_duplicate_faces' attribute stores duplicated faces in the following format. - * The key of '_duplicate_faces' represents the 2D cellId that is shared by - * more than one 3D target cell, and the value of '_duplicate_faces' - * the 3D target cells. The size of the value of '_duplicate_faces' is more than or equal to 2. - */ - class Interpolation3D2D : public Interpolation - { - public: - typedef std::map > DuplicateFacesType; - - INTERPKERNEL_EXPORT Interpolation3D2D(); - INTERPKERNEL_EXPORT Interpolation3D2D(const InterpolationOptions& io); - template - int interpolateMeshes(const MyMeshType& srcMesh, - const MyMeshType& targetMesh, - MyMatrixType& matrix, - const std::string& method); - INTERPKERNEL_EXPORT DuplicateFacesType retrieveDuplicateFaces() const { return _duplicate_faces; } - private: - SplittingPolicy _splitting_policy; - DuplicateFacesType _duplicate_faces; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation3D2D.txx b/medtool/src/INTERP_KERNEL/Interpolation3D2D.txx deleted file mode 100644 index 674317e1a..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3D2D.txx +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __INTERPOLATION3D2D_TXX__ -#define __INTERPOLATION3D2D_TXX__ - -#include "Interpolation3D2D.hxx" -#include "Interpolation.txx" -#include "MeshElement.txx" -#include "TransformedTriangle.hxx" -#include "Polyhedron3D2DIntersectorP0P0.txx" -#include "PointLocator3DIntersectorP0P0.txx" -#include "PolyhedronIntersectorP0P1.txx" -#include "PointLocator3DIntersectorP0P1.txx" -#include "PolyhedronIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P0Bary.txx" -#include "PointLocator3DIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P1.txx" -#include "PointLocator3DIntersectorP1P1.txx" -#include "Log.hxx" - -#include "BBTree.txx" - -namespace INTERP_KERNEL -{ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh 3-dimensional source mesh - * @param targetMesh 3-dimesional target mesh, containing only tetraedra - * @param matrix matrix in which the result is stored - * - */ - template - int Interpolation3D2D::interpolateMeshes(const MyMeshType& srcMesh, - const MyMeshType& targetMesh, - MyMatrixType& matrix, - const std::string& method) - { - typedef typename MyMeshType::MyConnType ConnType; - // create MeshElement objects corresponding to each element of the two meshes - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - const unsigned long numTargetElems = targetMesh.getNumberOfElements(); - - LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); - - std::vector*> srcElems(numSrcElems); - std::vector*> targetElems(numTargetElems); - - std::map*, int> indices; - DuplicateFacesType intersectFaces; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - srcElems[i] = new MeshElement(i, srcMesh); - - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - targetElems[i] = new MeshElement(i, targetMesh); - - Intersector3D* intersector=0; - std::string methC = InterpolationOptions::filterInterpolationMethod(method); - const double dimCaracteristic = CalculateCharacteristicSizeOfMeshes(srcMesh, targetMesh, InterpolationOptions::getPrintLevel()); - if(methC=="P0P0") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new Polyhedron3D2DIntersectorP0P0(targetMesh, - srcMesh, - dimCaracteristic, - getPrecision(), - intersectFaces, - getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP0P0(targetMesh,srcMesh,getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D to 2D intersection type for P0P0 interp specified : must be Triangulation or PointLocator."); - } - } - else - throw Exception("Invalid method choosed must be in \"P0P0\"."); - // create empty maps for all source elements - matrix.resize(intersector->getNumberOfRowsOfResMatrix()); - - // create BBTree structure - // - get bounding boxes - double* bboxes = new double[6 * numSrcElems]; - int* srcElemIdx = new int[numSrcElems]; - for(unsigned long i = 0; i < numSrcElems ; ++i) - { - // get source bboxes in right order - const BoundingBox* box = srcElems[i]->getBoundingBox(); - bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); - bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); - bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); - bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); - bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); - bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); - - // source indices have to begin with zero for BBox, I think - srcElemIdx[i] = srcElems[i]->getIndex(); - } - - BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems, 0.); - - // for each target element, get source elements with which to calculate intersection - // - calculate intersection by calling intersectCells - for(unsigned long i = 0; i < numTargetElems; ++i) - { - const BoundingBox* box = targetElems[i]->getBoundingBox(); - const int targetIdx = targetElems[i]->getIndex(); - - // get target bbox in right order - double targetBox[6]; - targetBox[0] = box->getCoordinate(BoundingBox::XMIN); - targetBox[1] = box->getCoordinate(BoundingBox::XMAX); - targetBox[2] = box->getCoordinate(BoundingBox::YMIN); - targetBox[3] = box->getCoordinate(BoundingBox::YMAX); - targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); - targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); - - std::vector intersectElems; - - tree.getIntersectingElems(targetBox, intersectElems); - - if ( !intersectElems.empty() ) - intersector->intersectCells(targetIdx, intersectElems, matrix); - - } - - delete [] bboxes; - delete [] srcElemIdx; - - DuplicateFacesType::iterator iter; - for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter) - { - if (iter->second.size() > 1) - { - _duplicate_faces.insert(std::make_pair(iter->first, iter->second)); - } - } - - // free allocated memory - int ret=intersector->getNumberOfColsOfResMatrix(); - - delete intersector; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - { - delete srcElems[i]; - } - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - { - delete targetElems[i]; - } - return ret; - - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Interpolation3DSurf.cxx b/medtool/src/INTERP_KERNEL/Interpolation3DSurf.cxx deleted file mode 100644 index 708d11a37..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3DSurf.cxx +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "Interpolation3DSurf.hxx" -#include "InterpolationPlanar.txx" - -namespace INTERP_KERNEL -{ - Interpolation3DSurf::Interpolation3DSurf() - { - } - - Interpolation3DSurf::Interpolation3DSurf(const InterpolationOptions& io):InterpolationPlanar(io) - { - } - - - /** - \brief Function used to set the options for the intersection calculation - \details The following options can be modified: - -# intersectionType: the type of algorithm to be used in the computation of the cell-cell intersections. - - Values: Triangle, Convex. - - Default: Triangle. - -# medianPlan: Position of the median plane where both cells will be projected - - Values: between 0 and 1. - - Default: 0.5. - -# doRotat: rotate the coordinate system such that the target cell is in the Oxy plane. - - Values: true (necessarilly if Intersection_type=Triangle), false. - - Default: true (as default Intersection_type=Triangle) - -# precision: Level of precision of the computations is precision times the characteristic size of the mesh. - - Values: positive real number. - - Default: 1.0E-12. - -# printLevel: Level of verboseness during the computations. - - Values: interger between 0 and 3. - - Default: 0. - */ - void Interpolation3DSurf::setOptions(double precision, int printLevel, double medianPlan, - IntersectionType intersectionType, bool doRotat, int orientation) - { - InterpolationPlanar::setOptions(precision,printLevel,intersectionType, orientation); - InterpolationPlanar::setDoRotate(doRotat); - InterpolationPlanar::setMedianPlane(medianPlan); - } -} diff --git a/medtool/src/INTERP_KERNEL/Interpolation3DSurf.hxx b/medtool/src/INTERP_KERNEL/Interpolation3DSurf.hxx deleted file mode 100644 index fda0fdd61..000000000 --- a/medtool/src/INTERP_KERNEL/Interpolation3DSurf.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATION3DSURF_HXX__ -#define __INTERPOLATION3DSURF_HXX__ - -#include "InterpolationPlanar.txx" -#include "INTERPKERNELDefines.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Interpolation3DSurf : public InterpolationPlanar - { - public: - Interpolation3DSurf(); - Interpolation3DSurf(const InterpolationOptions& io); - void setOptions(double precision, int printLevel, double medianPlane, - IntersectionType intersectionType, bool doRotate, int orientation=0); - public: - template - void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const - { intersector->adjustBoundingBoxes(bbox,InterpolationPlanar::getBoundingBoxAdjustment(),InterpolationPlanar::getBoundingBoxAdjustmentAbs()); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationCC.hxx b/medtool/src/INTERP_KERNEL/InterpolationCC.hxx deleted file mode 100644 index 62f844b06..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationCC.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : InterpolationCC.hxx -// Created : Fri Aug 14 11:33:17 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __InterpolationCC_HXX__ -#define __InterpolationCC_HXX__ - -#include "Interpolation.hxx" - -namespace INTERP_KERNEL -{ - /*! - * \brief Interpolator of cartesian/cartesian meshes - */ - class InterpolationCC : public Interpolation - { -// static const int SPACEDIM=MyMeshType::MY_SPACEDIM; -// static const int MESHDIM=MyMeshType::MY_MESHDIM; -// typedef typename MyMeshType::MyConnType ConnType; -// static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - InterpolationCC(); - InterpolationCC(const InterpolationOptions& io); - template - int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const char *method); - - private: - }; -} - - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationCC.txx b/medtool/src/INTERP_KERNEL/InterpolationCC.txx deleted file mode 100644 index ea75faced..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationCC.txx +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : InterpolationCC.txx -// Created : Fri Aug 14 11:39:27 2009 -// Author : Edward AGAPOV (eap) -// - -#include "InterpolationCC.hxx" -#include "InterpolationUtils.hxx" - -// convert index "From Mesh Index" -#define _FMI(i) OTT::ind2C((i)) -// convert index "To Mesh Index" -#define _TMI(i) OTT::indFC((i)) - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief Constructor does nothing - */ - //================================================================================ - InterpolationCC::InterpolationCC() - { - } - - InterpolationCC::InterpolationCC(const InterpolationOptions& io):Interpolation(io) - { - } - - //================================================================================ - /*! - * \brief An 1D intersection result - */ - //================================================================================ - - struct Interference - { - int _src_index; // source cell index along an axis - int _tgt_index; // target cell index along an axis - double _length; // interference length - Interference(int is = -1, int it = -1, double l = 0):_src_index(is),_tgt_index(it),_length(l){} - }; - - //================================================================================ - /*! - * \brief Fills the matrix by precomputed cell interferences along axes - * \param inter_of_axis - cell/cell interferences along each axis - * \param result - matrix to fill in - * \param src_nb_cells[] - nb of cells along each of axes in the source mesh - * \param tgt_nb_cells[] - nb of cells along each of axes in the target mesh - * \param src_i_cell - source cell number accumulated by previous axes - * \param tgt_i_cell - target cell number accumulated by previous axes - * \param src_prev_area - factor by which this axis icreases cell number - * \param tgt_prev_area - factor by which this axis icreases cell number - * \param axis - the axis to treat - * \param prev_value - intersection size computed by previous axes - */ - //================================================================================ - - template - void fillMatrix(const std::list< Interference > inter_of_axis[dim], - MatrixType& result, - const int src_nb_cells[dim], - const int tgt_nb_cells[dim], - const int src_i_cell = 0, - const int tgt_i_cell = 0, - const int src_prev_area = 1, - const int tgt_prev_area = 1, - const int axis = 0, - const double prev_value = 1.0) - { - typedef std::list < Interference >::const_iterator TIntIterator; - - if ( axis + 1 == dim ) - { - for ( TIntIterator i = inter_of_axis[axis].begin(); i != inter_of_axis[axis].end(); ++i ) - { - double value = i->_length * prev_value; - int src_i = i->_src_index * src_prev_area + src_i_cell; - int tgt_i = i->_tgt_index * tgt_prev_area + tgt_i_cell; - - result[ tgt_i ].insert( std::make_pair( _TMI( src_i ), value )); - } - } - else - { - int src_prev_area_next = src_prev_area * src_nb_cells[ axis ]; - int tgt_prev_area_next = tgt_prev_area * tgt_nb_cells[ axis ]; - - for ( TIntIterator i = inter_of_axis[axis].begin(); i != inter_of_axis[axis].end(); ++i ) - { - double value = i->_length * prev_value; - int src_i = i->_src_index * src_prev_area + src_i_cell; - int tgt_i = i->_tgt_index * tgt_prev_area + tgt_i_cell; - - // call for the next axis - fillMatrix(inter_of_axis, result, - src_nb_cells, tgt_nb_cells, src_i, tgt_i, - src_prev_area_next, tgt_prev_area_next, - axis+1, value ); - } - } - } - - //================================================================================ - /*! - * \brief Calculates the matrix of volumes of intersection between the elements of - * src_mesh and the elements of targetMesh - * \param src_mesh - source mesh - * \param tgt_mesh - target mesh - * \param result - matrix in which the result is stored - * \param method - interpolation method, not used as only "P0P0" is implemented so far - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target - * element there is a map, regardless of whether the element intersects any source - * elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has - * indices running from 0 to (nb target elements - 1), meaning that the map for target - * element i is stored at index i - 1. In the maps, however, the indexing is more natural: - * the intersection volume of the target element i with source element j is found at matrix[i-1][j] - */ - //================================================================================ - - template - int InterpolationCC::interpolateMeshes(const MyMeshType& src_mesh, - const MyMeshType& tgt_mesh, - MatrixType& result, - const char * method) - { - if ( std::string("P0P0") != method ) - throw Exception("Only P0P0 method is implemented so far"); - - // create empty maps for all target elements - result.resize( tgt_mesh.getNumberOfElements() ); - - const int ret = src_mesh.getNumberOfElements(); - - const double eps = getPrecision(); - const int dim = MyMeshType::MY_MESHDIM; - //const NumberingPolicy numPol = MyMeshType::My_numPol; - - const double* src_coords[ dim ]; - const double* tgt_coords[ dim ]; - int src_nb_cells[ dim ]; - int tgt_nb_cells[ dim ]; - for ( int j = 0; j < dim; ++j ) - { - src_coords[ j ] = src_mesh.getCoordsAlongAxis( _TMI( j )); - tgt_coords[ j ] = tgt_mesh.getCoordsAlongAxis( _TMI( j )); - src_nb_cells[ j ] = src_mesh.nbCellsAlongAxis( _TMI( j )); - tgt_nb_cells[ j ] = tgt_mesh.nbCellsAlongAxis( _TMI( j )); - } - - // ============================================ - // Calculate cell interferences along the axes - // ============================================ - - std::list < Interference > interferences[ dim ]; - - for ( int j = 0; j < dim; ++j ) // loop on axes of castesian space - { - std::list < Interference >& axis_interferences = interferences[j]; - - int it = 0, is = 0; - double x1t, x2t, x1s, x2s; // left and right ordinates of target and source cells - - // look for the first interference - // -------------------------------- - bool intersection = false; - while ( !intersection && it < tgt_nb_cells[j] && is < src_nb_cells[j] ) - { - x1s = src_coords[ j ][ is ]; - x2t = tgt_coords[ j ][ it+1 ]; - if ( x2t < x1s+eps ) - { - it++; // source lays on the right of target - continue; - } - x1t = tgt_coords[ j ][ it ]; - x2s = src_coords[ j ][ is+1 ]; - if ( x2s < x1t+eps ) - { - is++; // source lays on the left of target - continue; - } - intersection = true; - } - if ( !intersection ) return ret; // no intersections - - // get all interferences - // ---------------------- - while ( intersection ) - { - x1s = src_coords[ j ][ is ]; - x1t = tgt_coords[ j ][ it ]; - x2t = tgt_coords[ j ][ it+1 ]; - x2s = src_coords[ j ][ is+1 ]; - - double x1 = std::max( x1s ,x1t ); - double x2 = std::min( x2s ,x2t ); - axis_interferences.push_back( Interference( is, it, x2 - x1 )); - - // to the next target and/or source cell - double diff2 = x2s - x2t; - if ( diff2 > -eps ) - intersection = ( ++it < tgt_nb_cells[j] ); - if ( diff2 < eps ) - intersection = ( ++is < src_nb_cells[j] && intersection); - } - } - - // ================ - // Fill the matrix - // ================ - - switch ( dim ) - { - case 3: - fillMatrix( interferences, result, src_nb_cells,tgt_nb_cells ); - break; - - case 2: - fillMatrix( interferences, result, src_nb_cells,tgt_nb_cells ); - break; - - case 1: - fillMatrix( interferences, result, src_nb_cells,tgt_nb_cells ); - break; - } - - return ret; - } -} diff --git a/medtool/src/INTERP_KERNEL/InterpolationCU.hxx b/medtool/src/INTERP_KERNEL/InterpolationCU.hxx deleted file mode 100644 index 1b9589777..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationCU.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : InterpolationCU.hxx -// Created : Mon Dec 14 16:52:53 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __InterpolationCU_HXX__ -#define __InterpolationCU_HXX__ - -#include "Interpolation.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - class InterpolationCU : public Interpolation< InterpolationCU > - { - public: - InterpolationCU(); - InterpolationCU(const InterpolationOptions & io); - - template - int interpolateMeshes(const MyCMeshType& meshS, const MyUMeshType& meshT, MatrixType& result, const char *method); - - template - int interpolateMeshesRev(const MyUMeshType& meshS, const MyCMeshType& meshT, MatrixType& result, const char *method); - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationCU.txx b/medtool/src/INTERP_KERNEL/InterpolationCU.txx deleted file mode 100644 index 51b30bfbd..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationCU.txx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : InterpolationCU.txx -// Created : Mon Dec 14 17:30:25 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __InterpolationCU_TXX__ -#define __InterpolationCU_TXX__ - -#include "InterpolationCU.hxx" - -#include "Interpolation.txx" -#include "IntersectorCU1D.txx" -#include "IntersectorCU2D.txx" -#include "IntersectorCU3D.txx" - -#include - -// // convert index "From Mesh Index" -#define _FMIU(i) OTT::ind2C((i)) -#define _FMIC(i) OTT::ind2C((i)) -// convert index "To Mesh Index" -#define _TMIU(i) OTT::indFC((i)) -#define _TMIC(i) OTT::indFC((i)) -// convert coord "From Mesh Coord" -#define _FMCOO(i) OTT::coo2C((i)) -// convert connectivity "From Mesh Connectivity" -#define _FMCON(i) OTT::conn2C((i)) - -namespace INTERP_KERNEL -{ - /** - * \defgroup InterpolationCU InterpolationCU - * \class InterpolationCU - * \brief Class used to calculate the volumes of intersection between the elements of a cartesian and an unstructured meshes. - * - */ - //================================================================================ - /** - * Default constructor - * - */ - //================================================================================ - - InterpolationCU::InterpolationCU() - { - } - - InterpolationCU::InterpolationCU(const InterpolationOptions & io) - :Interpolation(io) - { - } - - //================================================================================ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh cartesian source mesh - * @param targetMesh unstructured target mesh - * @param result matrix in which the result is stored - * @param method interpolation method - */ - //================================================================================ - - template - int InterpolationCU::interpolateMeshes(const MyCMeshType& src_mesh, - const MyUMeshType& tgt_mesh, - MatrixType& result, - const char * method) - { - typedef typename MyCMeshType::MyConnType CConnType; - - if ( std::string("P0P0") != method ) - throw Exception("Only P0P0 method is implemented so far"); - if ( MyCMeshType::MY_SPACEDIM != MyUMeshType::MY_SPACEDIM || - MyCMeshType::MY_SPACEDIM != MyUMeshType::MY_MESHDIM ) - throw Exception("InterpolationCU::interpolateMeshes(): dimension of meshes must be same"); - - const double eps = getPrecision(); - const int dim = MyCMeshType::MY_SPACEDIM; - - TargetIntersector* intersector = 0; - switch( dim ) - { - case 1: intersector = new IntersectorCU1D( src_mesh, tgt_mesh ); break; - case 2: intersector = new IntersectorCU2D( src_mesh, tgt_mesh ); break; - case 3: intersector = new IntersectorCU3D( src_mesh, tgt_mesh, getSplittingPolicy() ); break; - } - // create empty maps for all target elements - result.resize( intersector->getNumberOfRowsOfResMatrix() ); - const int ret = intersector->getNumberOfColsOfResMatrix(); - - const double* src_coords[ dim ]; - int src_nb_coords[ dim ]; - std::map< double, int> src_coord_to_index[ dim ]; - for ( int j = 0; j < dim; ++j ) - { - src_coords [j] = src_mesh.getCoordsAlongAxis( _TMIC( j )); - src_nb_coords[j] = src_mesh.nbCellsAlongAxis ( _TMIC( j )) + 1; - for (int i = 0; i < src_nb_coords[j]; ++i ) - src_coord_to_index[j].insert( std::make_pair( src_coords[j][i], i )); - } - - const unsigned long tgtu_nb_cells = tgt_mesh.getNumberOfElements(); - - IntersectorCU bbHelper(src_mesh, tgt_mesh); - double bb[2*dim]; - - // loop on unstructured tgt cells - - for(unsigned int iT=0; iT src_coords[j][0] + eps; - if ( !doItersect ) - continue; // no intersection - - // find structured src cells intersecting iT cell - std::vector< std::vector< CConnType > > structIndices(1); - std::map< double, int>::iterator coo_ind; - for ( int j = 0; j < dim; ++j ) - { - coo_ind = src_coord_to_index[j].lower_bound( bb[2*j+1] - eps ); - if ( coo_ind == src_coord_to_index[j].end() ) - --coo_ind; - int max_i = coo_ind->second; - - coo_ind = src_coord_to_index[j].upper_bound( bb[2*j ] + eps ); - if ( coo_ind != src_coord_to_index[j].begin() ) - --coo_ind; - int min_i = coo_ind->second; - - std::vector< std::vector< CConnType > > newStructIndices; - for ( unsigned int iInd = 0; iInd < structIndices.size(); ++iInd ) - { - for ( int i = min_i; i < max_i; ++i ) - { - std::vector< CConnType > index = structIndices[iInd]; - index.push_back( i ); - newStructIndices.push_back( index ); - } - } - structIndices.swap( newStructIndices ); - } - - // perform intersection - - for ( unsigned int iInd = 0; iInd < structIndices.size(); ++iInd ) - intersector->intersectCells( iT, structIndices[iInd], result ); - } - delete intersector; - return ret; - } - - //================================================================================ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh 2-dimesional unstructured target mesh - * @param targetMesh 2-dimensional cartesian source mesh - * @param result matrix in which the result is stored - * @param method interpolation method - */ - //================================================================================ - - template - int InterpolationCU::interpolateMeshesRev(const MyUMeshType& meshS, const MyCMeshType& meshT, MatrixType& result, const char *method) - { - MatrixType revResult; - int sizeT = interpolateMeshes( meshT, meshS, revResult, method ); - int sizeS = revResult.size(); - result.resize( sizeT ); - - for ( int iS = 0; iS < sizeS; ++iS ) - { - typename MatrixType::value_type & row = revResult[iS]; - typename MatrixType::value_type::iterator iT_surf = row.begin(); - for ( ; iT_surf != row.end(); ++iT_surf ) - result[ iT_surf->first ][ iS ] = iT_surf->second; - } - return sizeS; - } - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationCurve.hxx b/medtool/src/INTERP_KERNEL/InterpolationCurve.hxx deleted file mode 100644 index 5bdc1a9d5..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationCurve.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATIONCURVE_HXX__ -#define __INTERPOLATIONCURVE_HXX__ - -#include "Interpolation.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - template - class InterpolationCurve : public Interpolation< InterpolationCurve > - { - public: - InterpolationCurve(); - InterpolationCurve(const InterpolationOptions & io); - - // Main function to interpolate - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, - MatrixType& result, const std::string& method); - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationCurve.txx b/medtool/src/INTERP_KERNEL/InterpolationCurve.txx deleted file mode 100644 index 239370a61..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationCurve.txx +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERPOLATIONCURVE_TXX__ -#define __INTERPOLATIONCURVE_TXX__ - -#include "InterpolationCurve.hxx" -#include "InterpolationOptions.hxx" -#include "CurveIntersectorP0P0.txx" -#include "CurveIntersectorP1P0.txx" -#include "CurveIntersectorP0P1.txx" -#include "CurveIntersectorP1P1.txx" -#include "CurveIntersectorP1P1PL.txx" -#include "BBTree.txx" - -#include - -namespace INTERP_KERNEL -{ - /** - * \defgroup interpolationCurve InterpolationCurve - * - * \class InterpolationCurve - * \brief Class used to compute the coefficients of the interpolation matrix between - * two local meshes in two dimensions. - */ - template - InterpolationCurve::InterpolationCurve() - { - } - - template - InterpolationCurve::InterpolationCurve (const InterpolationOptions& io) - :Interpolation< InterpolationCurve >(io) - { - } - - /** \brief Main function to interpolate 1D meshes. - \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param myMeshS Planar source mesh - * @Param myMeshT Planar target mesh - * @return vector containing for each element i of the source mesh, a map giving for each element j - * of the target mesh which i intersects, the area of the intersection - * - */ - template - template - int InterpolationCurve::interpolateMeshes (const MyMeshType& myMeshS, - const MyMeshType& myMeshT, - MatrixType& result, - const std::string& method) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol = MyMeshType::My_numPol; - - long global_start = clock(); - int counter=0; - - long nbMailleS = myMeshS.getNumberOfElements(); - long nbMailleT = myMeshT.getNumberOfElements(); - - CurveIntersector* intersector=0; - if(method=="P0P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - { - intersector = new CurveIntersectorP0P0(myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - } - default: - throw INTERP_KERNEL::Exception("For P0P0 in 1D or 2D curve only Triangulation supported for the moment !"); - } - } - else if(method=="P0P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - { - intersector = new CurveIntersectorP0P1(myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - } - default: - throw INTERP_KERNEL::Exception("For P0P1 in 1D or 2D curve only Triangulation supported for the moment !"); - } - } - else if(method=="P1P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - { - intersector = new CurveIntersectorP1P0(myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - } - default: - throw INTERP_KERNEL::Exception("For P1P0 in 1D or 2D curve only Triangulation supported for the moment !"); - } - } - else if(method=="P1P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector = new CurveIntersectorP1P1 - (myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - case PointLocator: - intersector = new CurveIntersectorP1P1PL - (myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - default: - throw INTERP_KERNEL::Exception("For P1P1 in 1D or 2D curve only Triangulation and PointLocator supported !"); - } - } - else - throw INTERP_KERNEL::Exception("Invalid method specified ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\""); - /****************************************************************/ - /* Create a search tree based on the bounding boxes */ - /* Instanciate the intersector and initialise the result vector */ - /****************************************************************/ - - long start_filtering=clock(); - - std::vector bbox; - intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes - intersector->adjustBoundingBoxes(bbox, InterpolationOptions::getBoundingBoxAdjustmentAbs()); - BBTree my_tree(&bbox[0], 0, 0, nbMailleS);//creating the search structure - - long end_filtering = clock(); - - result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. - - /****************************************************/ - /* Loop on the target cells - core of the algorithm */ - /****************************************************/ - long start_intersection = clock(); - const ConnType *connIndxT = myMeshT.getConnectivityIndexPtr(); - for(int iT=0; iT intersecting_elems; - double bb[2*SPACEDIM]; - intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); - my_tree.getIntersectingElems(bb, intersecting_elems); - intersector->intersectCells(iT,intersecting_elems,result); - counter += intersecting_elems.size(); - } - int ret = intersector->getNumberOfColsOfResMatrix(); - delete intersector; - - if (InterpolationOptions::getPrintLevel() >= 1) - { - long end_intersection=clock(); - std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; - std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; - long global_end =clock(); - std::cout << "Number of computed intersections = " << counter << std::endl; - std::cout << "Global time= " << global_end - global_start << std::endl; - } - return ret; - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationOptions.cxx b/medtool/src/INTERP_KERNEL/InterpolationOptions.cxx deleted file mode 100644 index ae1c14e10..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationOptions.cxx +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpolationOptions.hxx" -#include "InterpKernelGeo2DPrecision.hxx" -#include "InterpKernelException.hxx" - -#include - -const double INTERP_KERNEL::InterpolationOptions::DFT_MEDIAN_PLANE=0.5; - -const double INTERP_KERNEL::InterpolationOptions::DFT_SURF3D_ADJ_EPS=1.e-4; - -const double INTERP_KERNEL::InterpolationOptions::DFT_MAX_DIST_3DSURF_INTERSECT=-1.; - -const double INTERP_KERNEL::InterpolationOptions::DFT_MIN_DOT_BTW_3DSURF_INTERSECT=-1.; - -const char INTERP_KERNEL::InterpolationOptions::PRECISION_STR[]="Precision"; - -const char INTERP_KERNEL::InterpolationOptions::ARC_DETECTION_PRECISION_STR[]="ArcDetectionPrecision"; - -const char INTERP_KERNEL::InterpolationOptions::MEDIANE_PLANE_STR[]="MedianPlane"; - -const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_STR[]="BoundingBoxAdjustment"; - -const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_ABS_STR[]="BoundingBoxAdjustmentAbs"; - -const char INTERP_KERNEL::InterpolationOptions::MAX_DISTANCE_3DSURF_INSECT_STR[]="MaxDistance3DSurfIntersect"; - -const char INTERP_KERNEL::InterpolationOptions::MIN_DOT_BTW_3DSURF_INSECT_STR[]="MinDotBetween3DSurfIntersect"; - -const char INTERP_KERNEL::InterpolationOptions::PRINT_LEV_STR[]="PrintLevel"; - -const char INTERP_KERNEL::InterpolationOptions::DO_ROTATE_STR[]="DoRotate"; - -const char INTERP_KERNEL::InterpolationOptions::ORIENTATION_STR[]="Orientation"; - -const char INTERP_KERNEL::InterpolationOptions::MEASURE_ABS_STR[]="MeasureAbs"; - -const char INTERP_KERNEL::InterpolationOptions::INTERSEC_TYPE_STR[]="IntersectionType"; - -const char INTERP_KERNEL::InterpolationOptions::SPLITTING_POLICY_STR[]="SplittingPolicy"; - -const char INTERP_KERNEL::InterpolationOptions::TRIANGULATION_INTERSECT2D_STR[]="Triangulation"; - -const char INTERP_KERNEL::InterpolationOptions::CONVEX_INTERSECT2D_STR[]="Convex"; - -const char INTERP_KERNEL::InterpolationOptions::GEOMETRIC_INTERSECT2D_STR[]="Geometric2D"; - -const char INTERP_KERNEL::InterpolationOptions::POINTLOCATOR_INTERSECT_STR[]="PointLocator"; - -const char INTERP_KERNEL::InterpolationOptions::BARYCENTRIC_INTERSECT_STR[]="Barycentric"; - -const char INTERP_KERNEL::InterpolationOptions::BARYCENTRICGEO2D_INTERSECT_STR[]="BarycentricGeo2D"; - -const char INTERP_KERNEL::InterpolationOptions::PLANAR_SPLIT_FACE_5_STR[]="PLANAR_FACE_5"; - -const char INTERP_KERNEL::InterpolationOptions::PLANAR_SPLIT_FACE_6_STR[]="PLANAR_FACE_6"; - -const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_24_STR[]="GENERAL_24"; - -const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_48_STR[]="GENERAL_48"; - -void INTERP_KERNEL::InterpolationOptions::init() -{ - _print_level=0; - _intersection_type=Triangulation; - _precision=1e-12; - _median_plane=DFT_MEDIAN_PLANE; - _do_rotate=true; - _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS; - _bounding_box_adjustment_abs=0.; - _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT; - _min_dot_btw_3Dsurf_intersect=DFT_MIN_DOT_BTW_3DSURF_INTERSECT; - _orientation=0; - _measure_abs=true; - _splitting_policy=PLANAR_FACE_5; -} - -double INTERP_KERNEL::InterpolationOptions::getArcDetectionPrecision() const -{ - return INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision; -} - -void INTERP_KERNEL::InterpolationOptions::setArcDetectionPrecision(double p) -{ - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=p; -} - -std::string INTERP_KERNEL::InterpolationOptions::getIntersectionTypeRepr() const -{ - if(_intersection_type==INTERP_KERNEL::Triangulation) - return std::string(TRIANGULATION_INTERSECT2D_STR); - else if(_intersection_type==INTERP_KERNEL::Convex) - return std::string(CONVEX_INTERSECT2D_STR); - else if(_intersection_type==INTERP_KERNEL::Geometric2D) - return std::string(GEOMETRIC_INTERSECT2D_STR); - else if(_intersection_type==INTERP_KERNEL::PointLocator) - return std::string(POINTLOCATOR_INTERSECT_STR); - else if(_intersection_type==INTERP_KERNEL::Barycentric) - return std::string(BARYCENTRIC_INTERSECT_STR); - else if(_intersection_type==INTERP_KERNEL::BarycentricGeo2D) - return std::string(BARYCENTRICGEO2D_INTERSECT_STR); - else - return std::string("UNKNOWN_INTERSECT_TYPE"); -} - -bool INTERP_KERNEL::InterpolationOptions::setOptionDouble(const std::string& key, double value) -{ - if(key==PRECISION_STR) - { - setPrecision(value); - return true; - } - if(key==ARC_DETECTION_PRECISION_STR) - { - setArcDetectionPrecision(value); - return true; - } - else if(key==MEDIANE_PLANE_STR) - { - setMedianPlane(value); - return true; - } - else if(key==BOUNDING_BOX_ADJ_STR) - { - setBoundingBoxAdjustment(value); - return true; - } - else if(key==BOUNDING_BOX_ADJ_ABS_STR) - { - setBoundingBoxAdjustmentAbs(value); - return true; - } - else if(key==MAX_DISTANCE_3DSURF_INSECT_STR) - { - setMaxDistance3DSurfIntersect(value); - return true; - } - else if(key==MIN_DOT_BTW_3DSURF_INSECT_STR) - { - setMinDotBtwPlane3DSurfIntersect(value); - return true; - } - else - return false; -} - -bool INTERP_KERNEL::InterpolationOptions::setOptionInt(const std::string& key, int value) -{ - if(key==PRINT_LEV_STR) - { - setPrintLevel(value); - return true; - } - else if(key==DO_ROTATE_STR) - { - setDoRotate(value != 0); - return true; - } - else if(key==ORIENTATION_STR) - { - setOrientation(value); - return true; - } - else if(key==MEASURE_ABS_STR) - { - bool valBool=(value!=0); - setMeasureAbsStatus(valBool); - return true; - } - else - return false; -} - -bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, const std::string& value) -{ - if(key==INTERSEC_TYPE_STR) - { - if(value==TRIANGULATION_INTERSECT2D_STR) - { - setIntersectionType(INTERP_KERNEL::Triangulation); - return true; - } - else if(value==CONVEX_INTERSECT2D_STR) - { - setIntersectionType(INTERP_KERNEL::Convex); - return true; - } - else if(value==GEOMETRIC_INTERSECT2D_STR) - { - setIntersectionType(INTERP_KERNEL::Geometric2D); - return true; - } - else if(value==POINTLOCATOR_INTERSECT_STR) - { - setIntersectionType(INTERP_KERNEL::PointLocator); - return true; - } - else if(value==BARYCENTRIC_INTERSECT_STR) - { - setIntersectionType(INTERP_KERNEL::Barycentric); - return true; - } - else if(value==BARYCENTRICGEO2D_INTERSECT_STR) - { - setIntersectionType(INTERP_KERNEL::BarycentricGeo2D); - return true; - } - } - else if(key==SPLITTING_POLICY_STR) - { - if(value==PLANAR_SPLIT_FACE_5_STR) - { - setSplittingPolicy(INTERP_KERNEL::PLANAR_FACE_5); - return true; - } - else if(value==PLANAR_SPLIT_FACE_6_STR) - { - setSplittingPolicy(INTERP_KERNEL::PLANAR_FACE_6); - return true; - } - else if(value==GENERAL_SPLIT_24_STR) - { - setSplittingPolicy(INTERP_KERNEL::GENERAL_24); - return true; - } - else if(value==GENERAL_SPLIT_48_STR) - { - setSplittingPolicy(INTERP_KERNEL::GENERAL_48); - return true; - } - else - return false; - } - return false; -} - -std::string INTERP_KERNEL::InterpolationOptions::getSplittingPolicyRepr() const -{ - if(_splitting_policy==INTERP_KERNEL::PLANAR_FACE_5) - return std::string(PLANAR_SPLIT_FACE_5_STR); - else if(_splitting_policy==INTERP_KERNEL::PLANAR_FACE_6) - return std::string(PLANAR_SPLIT_FACE_6_STR); - else if(_splitting_policy==INTERP_KERNEL::GENERAL_24) - return std::string(GENERAL_SPLIT_24_STR); - else if(_splitting_policy==INTERP_KERNEL::GENERAL_48) - return std::string(GENERAL_SPLIT_48_STR); - else - return std::string("UNKNOWN_SPLITTING_POLICY"); -} - -std::string INTERP_KERNEL::InterpolationOptions::filterInterpolationMethod(const std::string& meth) const -{ - return std::string(meth); -} - -bool INTERP_KERNEL::InterpolationOptions::setInterpolationOptions(long print_level, - std::string intersection_type, - double precision, - double median_plane, - bool do_rotate, - double bounding_box_adjustment, - double bounding_box_adjustment_abs, - double max_distance_for_3Dsurf_intersect, - long orientation, - bool measure_abs, - std::string splitting_policy) -{ - _print_level=print_level; - _precision=precision; - _median_plane=median_plane; - _do_rotate=do_rotate; - _bounding_box_adjustment=bounding_box_adjustment; - _bounding_box_adjustment_abs=bounding_box_adjustment_abs; - _max_distance_for_3Dsurf_intersect=max_distance_for_3Dsurf_intersect; - _orientation=orientation; - _measure_abs=measure_abs; - return(setOptionString(INTERSEC_TYPE_STR,intersection_type) && setOptionString(SPLITTING_POLICY_STR,splitting_policy)); -} - -std::string INTERP_KERNEL::InterpolationOptions::printOptions() const -{ - std::ostringstream oss; oss.precision(15); oss << "Interpolation Options ******" << std::endl; - oss << "Print level : " << _print_level << std::endl; - oss << "Intersection type : " << getIntersectionTypeRepr() << std::endl; - oss << "Precision : " << _precision << std::endl; - oss << "Arc Detection Precision : " << getArcDetectionPrecision() << std::endl; - oss << "Median plane : " << _median_plane << std::endl; - oss << "Do Rotate status : " << std::boolalpha << _do_rotate << std::endl; - oss << "Bounding box adj : " << _bounding_box_adjustment << std::endl; - oss << "Bounding box adj abs : " << _bounding_box_adjustment_abs << std::endl; - oss << "Max distance for 3DSurf intersect : " << _max_distance_for_3Dsurf_intersect << std::endl; - oss << "Min dot between plane for 3DSurf intersect : " << _min_dot_btw_3Dsurf_intersect << std::endl; - oss << "Orientation : " << _orientation << std::endl; - oss << "Measure abs : " << _measure_abs << std::endl; - oss << "Splitting policy : " << getSplittingPolicyRepr() << std::endl; - oss << "****************************" << std::endl; - return oss.str(); -} - -void INTERP_KERNEL::InterpolationOptions::CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth) -{ - const int NB_OF_METH_MANAGED=4; - const char *METH_MANAGED[NB_OF_METH_MANAGED]={"P0P0","P0P1","P1P0","P1P1"}; - bool found=false; - for(int i=0;i - -namespace INTERP_KERNEL -{ - typedef enum { Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D } IntersectionType; - - /*! - * Class defining the options for all interpolation algorithms used in the \ref remapper "remapper" and - * in some of the \ref para-dec "DECs". - * - * List of options, possible values and default values can be found on this page: - * \ref InterpKerIntersectors - */ - class INTERPKERNEL_EXPORT InterpolationOptions - { - private: - int _print_level ; - IntersectionType _intersection_type; - double _precision; - double _median_plane ; - bool _do_rotate ; - //! this measure is relative to the caracteristic dimension - double _bounding_box_adjustment ; - //! this measure is absolute \b not relative to the cell size - double _bounding_box_adjustment_abs ; - double _max_distance_for_3Dsurf_intersect; - double _min_dot_btw_3Dsurf_intersect; - int _orientation ; - bool _measure_abs; - SplittingPolicy _splitting_policy ; - public: - InterpolationOptions() { init(); } - int getPrintLevel() const { return _print_level; } - void setPrintLevel(int pl) { _print_level=pl; } - - IntersectionType getIntersectionType() const { return _intersection_type; } - void setIntersectionType(IntersectionType it) { _intersection_type=it; } - std::string getIntersectionTypeRepr() const; - - double getPrecision() const { return _precision; } - void setPrecision(double p) { _precision=p; } - - double getArcDetectionPrecision() const; - void setArcDetectionPrecision(double p); - - double getMedianPlane() const { return _median_plane; } - void setMedianPlane(double mp) { _median_plane=mp; } - - bool getDoRotate() const { return _do_rotate; } - void setDoRotate( bool dr) { _do_rotate = dr; } - - double getBoundingBoxAdjustment() const { return _bounding_box_adjustment; } - void setBoundingBoxAdjustment(double bba) { _bounding_box_adjustment=bba; } - - double getBoundingBoxAdjustmentAbs() const { return _bounding_box_adjustment_abs; } - void setBoundingBoxAdjustmentAbs(double bba) { _bounding_box_adjustment_abs=bba; } - - double getMaxDistance3DSurfIntersect() const { return _max_distance_for_3Dsurf_intersect; } - void setMaxDistance3DSurfIntersect(double bba) { _max_distance_for_3Dsurf_intersect=bba; } - - double getMinDotBtwPlane3DSurfIntersect() const { return _min_dot_btw_3Dsurf_intersect; } - void setMinDotBtwPlane3DSurfIntersect(double v) { _min_dot_btw_3Dsurf_intersect=v; } - - int getOrientation() const { return _orientation; } - void setOrientation(int o) { _orientation=o; } - - bool getMeasureAbsStatus() const { return _measure_abs; } - void setMeasureAbsStatus(bool newStatus) { _measure_abs=newStatus; } - - SplittingPolicy getSplittingPolicy() const { return _splitting_policy; } - void setSplittingPolicy(SplittingPolicy sp) { _splitting_policy=sp; } - std::string getSplittingPolicyRepr() const; - - std::string filterInterpolationMethod(const std::string& meth) const; - - void init(); - - bool setInterpolationOptions(long print_level, - std::string intersection_type, - double precision, - double median_plane, - bool do_rotate, - double bounding_box_adjustment, - double bounding_box_adjustment_abs, - double max_distance_for_3Dsurf_intersect, - long orientation, - bool measure_abs, - std::string splitting_policy); - void copyOptions(const InterpolationOptions & other) { *this = other; } - bool setOptionDouble(const std::string& key, double value); - bool setOptionInt(const std::string& key, int value); - bool setOptionString(const std::string& key, const std::string& value); - std::string printOptions() const; - public: - static void CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth); - private: - static const double DFT_MEDIAN_PLANE; - static const double DFT_SURF3D_ADJ_EPS; - static const double DFT_MAX_DIST_3DSURF_INTERSECT; - static const double DFT_MIN_DOT_BTW_3DSURF_INTERSECT; - public: - static const char PRECISION_STR[]; - static const char ARC_DETECTION_PRECISION_STR[]; - static const char MEDIANE_PLANE_STR[]; - static const char BOUNDING_BOX_ADJ_STR[]; - static const char BOUNDING_BOX_ADJ_ABS_STR[]; - static const char MAX_DISTANCE_3DSURF_INSECT_STR[]; - static const char MIN_DOT_BTW_3DSURF_INSECT_STR[]; - static const char PRINT_LEV_STR[]; - static const char DO_ROTATE_STR[]; - static const char ORIENTATION_STR[]; - static const char MEASURE_ABS_STR[]; - static const char INTERSEC_TYPE_STR[]; - static const char SPLITTING_POLICY_STR[]; - static const char TRIANGULATION_INTERSECT2D_STR[]; - static const char CONVEX_INTERSECT2D_STR[]; - static const char GEOMETRIC_INTERSECT2D_STR[]; - static const char POINTLOCATOR_INTERSECT_STR[]; - static const char BARYCENTRIC_INTERSECT_STR[]; - static const char BARYCENTRICGEO2D_INTERSECT_STR[]; - static const char PLANAR_SPLIT_FACE_5_STR[]; - static const char PLANAR_SPLIT_FACE_6_STR[]; - static const char GENERAL_SPLIT_24_STR[]; - static const char GENERAL_SPLIT_48_STR[]; - }; - -} -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationPlanar.hxx b/medtool/src/INTERP_KERNEL/InterpolationPlanar.hxx deleted file mode 100755 index 1505c46e4..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationPlanar.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATIONPLANAR_HXX__ -#define __INTERPOLATIONPLANAR_HXX__ - -#include "Interpolation.hxx" -#include "PlanarIntersector.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - template - class InterpolationPlanar : public Interpolation< InterpolationPlanar > - { - private: - double _dim_caracteristic; - public: - InterpolationPlanar(); - InterpolationPlanar(const InterpolationOptions & io); - - // geometric precision, debug print level, coice of the median plane, intersection etc ... - void setOptions(double precision, int printLevel, - IntersectionType intersectionType, int orientation=0); - - // Main function to interpolate triangular and quadratic meshes - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result, const std::string& method); - public: - bool doRotate() const { return asLeafInterpPlanar().doRotate(); } - double medianPlane() const { return asLeafInterpPlanar().medianPlane(); } - template - void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const - { return asLeafInterpPlanar().performAdjustmentOfBB(intersector,bbox); } - protected: - RealPlanar& asLeafInterpPlanar() { return static_cast(*this); } - const RealPlanar& asLeafInterpPlanar() const { return static_cast< const RealPlanar& >(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationPlanar.txx b/medtool/src/INTERP_KERNEL/InterpolationPlanar.txx deleted file mode 100644 index d7a1fea20..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationPlanar.txx +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATIONPLANAR_TXX__ -#define __INTERPOLATIONPLANAR_TXX__ - -#include "InterpolationPlanar.hxx" -#include "Interpolation.txx" -#include "InterpolationOptions.hxx" -#include "PlanarIntersector.hxx" -#include "PlanarIntersector.txx" -#include "TriangulationIntersector.hxx" -#include "TriangulationIntersector.txx" -#include "ConvexIntersector.hxx" -#include "ConvexIntersector.txx" -#include "Geometric2DIntersector.hxx" -#include "Geometric2DIntersector.txx" -#include "PointLocator2DIntersector.hxx" -#include "PointLocator2DIntersector.txx" -#include "PlanarIntersectorP0P1PL.hxx" -#include "PlanarIntersectorP0P1PL.txx" -#include "PlanarIntersectorP1P0PL.hxx" -#include "PlanarIntersectorP1P0PL.txx" -#include "PlanarIntersectorP1P1PL.hxx" -#include "PlanarIntersectorP1P1PL.txx" -#include "VectorUtils.hxx" -#include "BBTree.txx" - -#include -#include - -namespace INTERP_KERNEL -{ - /** - * \defgroup interpolationPlanar InterpolationPlanar - * - * \class InterpolationPlanar - * \brief Class used to compute the coefficients of the interpolation matrix between - * two local meshes in two dimensions. Meshes can contain mixed triangular and quadrangular elements. - */ - template - InterpolationPlanar::InterpolationPlanar():_dim_caracteristic(1) - - { - } - - template - InterpolationPlanar::InterpolationPlanar(const InterpolationOptions& io):Interpolation< InterpolationPlanar >(io),_dim_caracteristic(1) - - { - } - - /** - * \brief Function used to set the options for the intersection calculation - * \details The following options can be modified: - * -# Intersection_type: the type of algorithm to be used in the computation of the cell-cell intersections. - * - Values: Triangle, Convex. - * - Default: Triangle. - * -# Precision: Level of precision of the computations is precision times the characteristic size of the mesh. - * - Values: positive real number. - * - Default: 1.0E-12. - * -# PrintLevel: Level of verboseness during the computations. - * - Values: interger between 0 and 3. - * - Default: 0. - */ - template - void InterpolationPlanar::setOptions(double precision, int printLevel, IntersectionType intersectionType, int orientation) - { - InterpolationOptions::setPrecision(precision); - InterpolationOptions::setPrintLevel(printLevel); - InterpolationOptions::setIntersectionType(intersectionType); - InterpolationOptions::setOrientation(orientation); - } - - - /** \brief Main function to interpolate triangular or quadrangular meshes. - \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param myMeshS Planar source mesh - * @Param myMeshT Planar target mesh - * @return vector containing for each element i of the source mesh, a map giving for each element j - * of the target mesh which i intersects, the area of the intersection - * - */ - template - template - int InterpolationPlanar::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const std::string& method) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - long global_start =clock(); - int counter=0; - /***********************************************************/ - /* Check both meshes are made of triangles and quadrangles */ - /***********************************************************/ - - long nbMailleS=myMeshS.getNumberOfElements(); - long nbMailleT=myMeshT.getNumberOfElements(); - - /**************************************************/ - /* Search the characteristic size of the meshes */ - /**************************************************/ - - double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); - double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); - double diagonalS,dimCaracteristicS=std::numeric_limits::max(); - if(nbMailleS!=0) - { - diagonalS=getDistanceBtw2Pts(BoxS+SPACEDIM,BoxS); - dimCaracteristicS=diagonalS/nbMailleS; - } - double diagonalT,dimCaracteristicT=std::numeric_limits::max(); - if(nbMailleT!=0) - { - diagonalT=getDistanceBtw2Pts(BoxT+SPACEDIM,BoxT); - dimCaracteristicT=diagonalT/nbMailleT; - } - - _dim_caracteristic=std::min(dimCaracteristicS, dimCaracteristicT); - if (InterpolationOptions::getPrintLevel()>=1) - { - std::cout << " - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl; - std::cout << " - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl; - std::cout << "InterpolationPlanar::computation of the intersections" << std::endl; - } - - PlanarIntersector* intersector=0; - std::string meth = InterpolationOptions::filterInterpolationMethod(method); - if(meth=="P0P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PointLocator2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("For P0P0 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator !"); - } - } - else if(meth=="P0P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PlanarIntersectorP0P1PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case Barycentric: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case BarycentricGeo2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("For P0P1 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D !"); - } - } - else if(meth=="P1P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PlanarIntersectorP1P0PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case Barycentric: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case BarycentricGeo2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - } - } - else if(meth=="P1P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PlanarIntersectorP1P1PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("For P1P1 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator !"); - } - } - else - throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\""); - /****************************************************************/ - /* Create a search tree based on the bounding boxes */ - /* Instanciate the intersector and initialise the result vector */ - /****************************************************************/ - - long start_filtering=clock(); - - std::vector bbox; - intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes - performAdjustmentOfBB(intersector,bbox); - const double *bboxPtr=0; - if(nbMailleS>0) - bboxPtr=&bbox[0]; - BBTree my_tree(bboxPtr, 0, 0,nbMailleS);//creating the search structure - - long end_filtering=clock(); - - result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. - - /****************************************************/ - /* Loop on the target cells - core of the algorithm */ - /****************************************************/ - long start_intersection=clock(); - long nbelem_type=myMeshT.getNumberOfElements(); - const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); - for(int iT=0; iT intersecting_elems; - double bb[2*SPACEDIM]; - intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); - my_tree.getIntersectingElems(bb, intersecting_elems); - intersector->intersectCells(iT,intersecting_elems,result); - counter+=intersecting_elems.size(); - intersecting_elems.clear(); - } - int ret=intersector->getNumberOfColsOfResMatrix(); - delete intersector; - - if (InterpolationOptions::getPrintLevel() >=1) - { - long end_intersection=clock(); - std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; - std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; - long global_end =clock(); - std::cout << "Number of computed intersections = " << counter << std::endl; - std::cout << "Global time= " << global_end - global_start << std::endl; - } - return ret; - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/InterpolationUtils.hxx b/medtool/src/INTERP_KERNEL/InterpolationUtils.hxx deleted file mode 100644 index a96072b78..000000000 --- a/medtool/src/INTERP_KERNEL/InterpolationUtils.hxx +++ /dev/null @@ -1,1110 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERPOLATIONUTILS_HXX__ -#define __INTERPOLATIONUTILS_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - class OTT//OffsetToolTrait - { - }; - - template - class OTT - { - public: - static ConnType indFC(ConnType i) { return i; } - static ConnType ind2C(ConnType i) { return i; } - static ConnType conn2C(ConnType i) { return i; } - static ConnType coo2C(ConnType i) { return i; } - }; - - template - class OTT - { - public: - static ConnType indFC(ConnType i) { return i+1; } - static ConnType ind2C(ConnType i) { return i-1; } - static ConnType conn2C(ConnType i) { return i-1; } - static ConnType coo2C(ConnType i) { return i-1; } - }; - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul la surface d'un triangle */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline double Surf_Tri(const double* P_1,const double* P_2,const double* P_3) - { - double A=(P_3[1]-P_1[1])*(P_2[0]-P_1[0])-(P_2[1]-P_1[1])*(P_3[0]-P_1[0]); - double Surface = 0.5*fabs(A); - return Surface; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction qui calcul le determinant */ - /* de deux vecteur(cf doc CGAL). */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - //fonction qui calcul le determinant des vecteurs: P3P1 et P3P2 - //(cf doc CGAL). - - inline double mon_determinant(const double* P_1, - const double* P_2, - const double* P_3) - { - double mon_det=(P_1[0]-P_3[0])*(P_2[1]-P_3[1])-(P_2[0]-P_3[0])*(P_1[1]-P_3[1]); - return mon_det; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - //calcul la norme du vecteur P1P2 - - inline double norme_vecteur(const double* P_1,const double* P_2) - { - double X=P_1[0]-P_2[0]; - double Y=P_1[1]-P_2[1]; - double norme=sqrt(X*X+Y*Y); - return norme; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul le cos et le sin de l'angle P1P2,P1P3 */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline std::vector calcul_cos_et_sin(const double* P_1, - const double* P_2, - const double* P_3) - { - - std::vector Vect; - double P1_P2=norme_vecteur(P_1,P_2); - double P2_P3=norme_vecteur(P_2,P_3); - double P3_P1=norme_vecteur(P_3,P_1); - - double N=P1_P2*P1_P2+P3_P1*P3_P1-P2_P3*P2_P3; - double D=2.0*P1_P2*P3_P1; - double COS=N/D; - if (COS>1.0) COS=1.0; - if (COS<-1.0) COS=-1.0; - Vect.push_back(COS); - double V=mon_determinant(P_2,P_3,P_1); - double D_1=P1_P2*P3_P1; - double SIN=V/D_1; - if (SIN>1.0) SIN=1.0; - if (SIN<-1.0) SIN=-1.0; - Vect.push_back(SIN); - - return Vect; - - } - - /*! - * This method builds a quadrangle built with the first point of 'triIn' the barycenter of two edges starting or ending with - * the first point of 'triIn' and the barycenter of 'triIn'. - * - * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. - * @param quadOut is a 8 doubles array filled after the following call. - */ - template - inline void fillDualCellOfTri(const double *triIn, double *quadOut) - { - //1st point - std::copy(triIn,triIn+SPACEDIM,quadOut); - double tmp[SPACEDIM]; - std::transform(triIn,triIn+SPACEDIM,triIn+SPACEDIM,tmp,std::plus()); - //2nd point - std::transform(tmp,tmp+SPACEDIM,quadOut+SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - std::transform(tmp,tmp+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus()); - //3rd point - std::transform(tmp,tmp+SPACEDIM,quadOut+2*SPACEDIM,std::bind2nd(std::multiplies(),1/3.)); - //4th point - std::transform(triIn,triIn+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus()); - std::transform(tmp,tmp+SPACEDIM,quadOut+3*SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - } - - /*! - * This method builds a potentially non-convex polygon cell built with the first point of 'triIn' the barycenter of two edges starting or ending with - * the first point of 'triIn' and the barycenter of 'triIn'. - * - * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. - * @param quadOut is a 8 doubles array filled after the following call. - */ - template - inline void fillDualCellOfPolyg(const double *polygIn, int nPtsPolygonIn, double *polygOut) - { - //1st point - std::copy(polygIn,polygIn+SPACEDIM,polygOut); - std::transform(polygIn,polygIn+SPACEDIM,polygIn+SPACEDIM,polygOut+SPACEDIM,std::plus()); - //2nd point - std::transform(polygOut+SPACEDIM,polygOut+2*SPACEDIM,polygOut+SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - double tmp[SPACEDIM]; - // - for(int i=0;i()); - std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+3)*SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - std::transform(polygIn+(i+1)*SPACEDIM,polygIn+(i+2)*SPACEDIM,tmp,tmp,std::plus()); - std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+2)*SPACEDIM,std::bind2nd(std::multiplies(),1./3.)); - } - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul les coordonnees du barycentre d'un polygone */ - /* le vecteur en entree est constitue des coordonnees */ - /* des sommets du polygone */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline std::vector bary_poly(const std::vector& V) - { - std::vector Bary; - long taille=V.size(); - double x=0; - double y=0; - - for(long i=0;i - bool solveSystemOfEquations(double M[nbRow][nbRow+1], double* sol) - { - const int nbCol=nbRow+1; - - // make upper triangular matrix (forward elimination) - - int iR[nbRow];// = { 0, 1, 2 }; - for ( int i = 0; i < (int) nbRow; ++i ) - iR[i] = i; - for ( int i = 0; i < (int)(nbRow-1); ++i ) // nullify nbRow-1 rows - { - // swap rows to have max value of i-th column in i-th row - double max = std::fabs( M[ iR[i] ][i] ); - for ( int r = i+1; r < (int)nbRow; ++r ) - { - double m = std::fabs( M[ iR[r] ][i] ); - if ( m > max ) - { - max = m; - std::swap( iR[r], iR[i] ); - } - } - if ( max < std::numeric_limits::min() ) - { - //sol[0]=1; sol[1]=sol[2]=sol[3]=0; - return false; // no solution - } - // make 0 below M[i][i] (actually we do not modify i-th column) - double* tUpRow = M[ iR[i] ]; - for ( int r = i+1; r < (int)nbRow; ++r ) - { - double* mRow = M[ iR[r] ]; - double coef = mRow[ i ] / tUpRow[ i ]; - for ( int c = i+1; c < nbCol; ++c ) - mRow[ c ] -= tUpRow[ c ] * coef; - } - } - double* mRow = M[ iR[nbRow-1] ]; - if ( std::fabs( mRow[ nbRow-1 ] ) < std::numeric_limits::min() ) - { - //sol[0]=1; sol[1]=sol[2]=sol[3]=0; - return false; // no solution - } - mRow[ nbRow ] /= mRow[ nbRow-1 ]; - - // calculate solution (back substitution) - - sol[ nbRow-1 ] = mRow[ nbRow ]; - - for ( int i = nbRow-2; i+1; --i ) - { - mRow = M[ iR[i] ]; - sol[ i ] = mRow[ nbRow ]; - for ( int j = nbRow-1; j > i; --j ) - sol[ i ] -= sol[j]*mRow[ j ]; - sol[ i ] /= mRow[ i ]; - } - - return true; - } - - - /*! - * \brief Solve system equation in matrix form using Gaussian elimination algorithm - * \param M - N x N+NB_OF_VARS matrix - * \param sol - vector of N solutions - * \retval bool - true if succeeded - */ - template - bool solveSystemOfEquations2(const double *matrix, double *solutions, double eps) - { - unsigned k,j; - int nr,n,m,np; - double s,g; - int mb; - // - double B[SZ*(SZ+NB_OF_RES)]; - std::copy(matrix,matrix+SZ*(SZ+NB_OF_RES),B); - // - nr=SZ+NB_OF_RES; - for(k=0;keps) - {/* Rows permutation */ - for(m=0;m(),s)); - for(j=0;j - inline void barycentric_coords(const double* triaCoords, const double* p, double* bc) - { - // matrix 2x2 - double - T11 = triaCoords[0]-triaCoords[2*SPACEDIM], T12 = triaCoords[SPACEDIM]-triaCoords[2*SPACEDIM], - T21 = triaCoords[1]-triaCoords[2*SPACEDIM+1], T22 = triaCoords[SPACEDIM+1]-triaCoords[2*SPACEDIM+1]; - // matrix determinant - double Tdet = T11*T22 - T12*T21; - if ( fabs( Tdet ) < std::numeric_limits::min() ) { - bc[0]=1; bc[1]=0; bc[2]=0; - return; - } - // matrix inverse - double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; - // vector - double r11 = p[0]-triaCoords[2*SPACEDIM], r12 = p[1]-triaCoords[2*SPACEDIM+1]; - // barycentric coordinates: mutiply matrix by vector - bc[0] = (t11 * r11 + t12 * r12)/Tdet; - bc[1] = (t21 * r11 + t22 * r12)/Tdet; - bc[2] = 1. - bc[0] - bc[1]; - } - - /*! - * Calculate barycentric coordinates of a point p with respect to triangle or tetra verices. - * This method makes 2 assumptions : - * - this is a simplex - * - spacedim == meshdim. For TRI3 and TRI6 spaceDim is expected to be equal to 2 and for TETRA4 spaceDim is expected to be equal to 3. - * If not the case (3D surf for example) a previous projection should be done before. - */ - inline void barycentric_coords(const std::vector& n, const double *p, double *bc) - { - enum { _X, _Y, _Z }; - switch(n.size()) - { - case 2: - {// SEG 2 - double delta=n[0][0]-n[1][0]; - bc[0]=fabs((*p-n[1][0])/delta); - bc[1]=fabs((*p-n[0][0])/delta); - break; - } - case 3: - { // TRIA3 - // matrix 2x2 - double - T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X], - T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y]; - // matrix determinant - double Tdet = T11*T22 - T12*T21; - if ( (std::fabs( Tdet) ) < (std::numeric_limits::min()) ) - { - bc[0]=1; bc[1]=bc[2]=0; // no solution - return; - } - // matrix inverse - double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; - // vector - double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y]; - // barycentric coordinates: mutiply matrix by vector - bc[0] = (t11 * r11 + t12 * r12)/Tdet; - bc[1] = (t21 * r11 + t22 * r12)/Tdet; - bc[2] = 1. - bc[0] - bc[1]; - break; - } - case 4: - { // TETRA4 - // Find bc by solving system of 3 equations using Gaussian elimination algorithm - // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4 - // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4 - // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4 - - double T[3][4]= - {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] }, - { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] }, - { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }}; - - if ( !solveSystemOfEquations<3>( T, bc ) ) - bc[0]=1., bc[1] = bc[2] = bc[3] = 0; - else - bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2]; - break; - } - case 6: - { - // TRIA6 - double matrix2[48]={1., 0., 0., 0., 0., 0., 0., 0., - 1., 0., 0., 0., 0., 0., 1., 0., - 1., 0., 0., 0., 0., 0., 0., 1., - 1., 0., 0., 0., 0., 0., 0.5, 0., - 1., 0., 0., 0., 0., 0., 0.5, 0.5, - 1., 0., 0., 0., 0., 0., 0.,0.5}; - for(int i=0;i<6;i++) - { - matrix2[8*i+1]=n[i][0]; - matrix2[8*i+2]=n[i][1]; - matrix2[8*i+3]=n[i][0]*n[i][0]; - matrix2[8*i+4]=n[i][0]*n[i][1]; - matrix2[8*i+5]=n[i][1]*n[i][1]; - } - double res[12]; - solveSystemOfEquations2<6,2>(matrix2,res,std::numeric_limits::min()); - double refCoo[2]; - refCoo[0]=computeTria6RefBase(res,p); - refCoo[1]=computeTria6RefBase(res+6,p); - computeWeightedCoeffsInTria6FromRefBase(refCoo,bc); - break; - } - case 10: - {//TETRA10 - double matrix2[130]={1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5, 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0.5, 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0.5, - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5}; - for(int i=0;i<10;i++) - { - matrix2[13*i+1]=n[i][0]; - matrix2[13*i+2]=n[i][1]; - matrix2[13*i+3]=n[i][2]; - matrix2[13*i+4]=n[i][0]*n[i][0]; - matrix2[13*i+5]=n[i][0]*n[i][1]; - matrix2[13*i+6]=n[i][0]*n[i][2]; - matrix2[13*i+7]=n[i][1]*n[i][1]; - matrix2[13*i+8]=n[i][1]*n[i][2]; - matrix2[13*i+9]=n[i][2]*n[i][2]; - } - double res[30]; - solveSystemOfEquations2<10,3>(matrix2,res,std::numeric_limits::min()); - double refCoo[3]; - refCoo[0]=computeTetra10RefBase(res,p); - refCoo[1]=computeTetra10RefBase(res+10,p); - refCoo[2]=computeTetra10RefBase(res+20,p); - computeWeightedCoeffsInTetra10FromRefBase(refCoo,bc); - break; - } - default: - throw INTERP_KERNEL::Exception("INTERP_KERNEL::barycentric_coords : unrecognized simplex !"); - } - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul la surface d'un polygone. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline double Surf_Poly(const std::vector& Poly) - { - - double Surface=0; - for(unsigned long i=0; i<(Poly.size())/2-2; i++) - { - double Surf=Surf_Tri( &Poly[0],&Poly[2*(i+1)],&Poly[2*(i+2)] ); - Surface=Surface + Surf ; - } - return Surface ; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction qui teste si un point est dans une maille */ - /* point: P_0 */ - /* P_1, P_2, P_3 sommet des mailles */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline bool point_dans_triangle(const double* P_0,const double* P_1, - const double* P_2,const double* P_3, - double eps) - { - - bool A=false; - double det_1=mon_determinant(P_1,P_3,P_0); - double det_2=mon_determinant(P_3,P_2,P_0); - double det_3=mon_determinant(P_2,P_1,P_0); - if( (det_1>=-eps && det_2>=-eps && det_3>=-eps) || (det_1<=eps && det_2<=eps && det_3<=eps) ) - { - A=true; - } - - return A; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /*fonction pour verifier qu'un point n'a pas deja ete considerer dans */ - /* le vecteur et le rajouter au vecteur sinon. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline void verif_point_dans_vect(const double* P, std::vector& V, double absolute_precision ) - { - long taille=V.size(); - bool isPresent=false; - for(long i=0;i& V, double dim_caracteristic, double precision) - { - - double absolute_precision = precision*dim_caracteristic; - bool A_1=INTERP_KERNEL::point_dans_triangle(P_1,P_4,P_5,P_6,absolute_precision); - if(A_1) - verif_point_dans_vect(P_1,V,absolute_precision); - bool A_2=INTERP_KERNEL::point_dans_triangle(P_2,P_4,P_5,P_6,absolute_precision); - if(A_2) - verif_point_dans_vect(P_2,V,absolute_precision); - bool A_3=INTERP_KERNEL::point_dans_triangle(P_3,P_4,P_5,P_6,absolute_precision); - if(A_3) - verif_point_dans_vect(P_3,V,absolute_precision); - } - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* calcul de l'intersection de deux segments: segments P1P2 avec P3P4 */ - /* . Si l'intersection est non nulle et si celle-ci n'est */ - /* n'est pas deja contenue dans Vect on la rajoute a Vect */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - inline void inters_de_segment(const double * P_1,const double * P_2, - const double * P_3,const double * P_4, - std::vector& Vect, - double dim_caracteristic, double precision) - { - // calcul du determinant de P_1P_2 et P_3P_4. - double det=(P_2[0]-P_1[0])*(P_4[1]-P_3[1])-(P_4[0]-P_3[0])*(P_2[1]-P_1[1]); - - double absolute_precision = dim_caracteristic*precision; - if(fabs(det)>absolute_precision) - { - double k_1=-((P_3[1]-P_4[1])*(P_3[0]-P_1[0])+(P_4[0]-P_3[0])*(P_3[1]-P_1[1]))/det; - - if (k_1 >= -absolute_precision && k_1 <= 1+absolute_precision) - //if( k_1 >= -precision && k_1 <= 1+precision) - { - double k_2= ((P_1[1]-P_2[1])*(P_1[0]-P_3[0])+(P_2[0]-P_1[0])*(P_1[1]-P_3[1]))/det; - - if (k_2 >= -absolute_precision && k_2 <= 1+absolute_precision) - //if( k_2 >= -precision && k_2 <= 1+precision) - { - double P_0[2]; - P_0[0]=P_1[0]+k_1*(P_2[0]-P_1[0]); - P_0[1]=P_1[1]+k_1*(P_2[1]-P_1[1]); - verif_point_dans_vect(P_0,Vect,absolute_precision); - } - } - } - } - - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* calcul l'intersection de deux triangles */ - /* P_1, P_2, P_3: sommets du premier triangle */ - /* P_4, P_5, P_6: sommets du deuxi�me triangle */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - inline void intersec_de_triangle(const double* P_1,const double* P_2, const double* P_3, - const double* P_4,const double* P_5,const double* P_6, - std::vector& Vect, double dim_caracteristic, double precision) - { - inters_de_segment(P_1,P_2,P_4,P_5,Vect, dim_caracteristic, precision); - inters_de_segment(P_1,P_2,P_5,P_6,Vect, dim_caracteristic, precision); - inters_de_segment(P_1,P_2,P_6,P_4,Vect, dim_caracteristic, precision); - inters_de_segment(P_2,P_3,P_4,P_5,Vect, dim_caracteristic, precision); - inters_de_segment(P_2,P_3,P_5,P_6,Vect, dim_caracteristic, precision); - inters_de_segment(P_2,P_3,P_6,P_4,Vect, dim_caracteristic, precision); - inters_de_segment(P_3,P_1,P_4,P_5,Vect, dim_caracteristic, precision); - inters_de_segment(P_3,P_1,P_5,P_6,Vect, dim_caracteristic, precision); - inters_de_segment(P_3,P_1,P_6,P_4,Vect, dim_caracteristic, precision); - rajou_sommet_triangl(P_1,P_2,P_3,P_4,P_5,P_6,Vect, dim_caracteristic, precision); - rajou_sommet_triangl(P_4,P_5,P_6,P_1,P_2,P_3,Vect, dim_caracteristic, precision); - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* fonction pour verifier qu'un node maille n'a pas deja ete considerer */ - /* dans le vecteur et le rajouter au vecteur sinon. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - inline void verif_maill_dans_vect(int Num, std::vector& V) - { - long taille=V.size(); - int A=0; - for(long i=0;itheta1, std::pair theta2) const - { - double norm1 = sqrt(theta1.first*theta1.first +theta1.second*theta1.second); - double norm2 = sqrt(theta2.first*theta2.first +theta2.second*theta2.second); - - double epsilon = 1.e-12; - - if( norm1 < epsilon || norm2 < epsilon ) - std::cout << "Warning InterpolationUtils.hxx: AngleLess : Vector with zero norm, cannot define the angle !!!! " << std::endl; - - return theta1.second*(norm2 + theta2.first) < theta2.second*(norm1 + theta1.first); - - } - }; - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction pour reconstituer un polygone convexe a partir */ - /* d'un nuage de point. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline std::vector reconstruct_polygon(const std::vector& V) - { - - int taille((int)V.size()); - - //VB : why 6 ? - - if(taille<=6) - {return V;} - else - { - double *COS=new double[taille/2]; - double *SIN=new double[taille/2]; - //double *angle=new double[taille/2]; - std::vector Bary=bary_poly(V); - COS[0]=1.0; - SIN[0]=0.0; - //angle[0]=0.0; - for(int i=0; i Trigo=calcul_cos_et_sin(&Bary[0],&V[0],&V[2*(i+1)]); - COS[i+1]=Trigo[0]; - SIN[i+1]=Trigo[1]; - //if(SIN[i+1]>=0) - // {angle[i+1]=atan2(SIN[i+1],COS[i+1]);} - // else - // {angle[i+1]=-atan2(SIN[i+1],COS[i+1]);} - } - - //ensuite on ordonne les angles. - std::vector Pt_ordonne; - Pt_ordonne.reserve(taille); - // std::multimap Ordre; - std::multimap,int, AngleLess> CosSin; - for(int i=0;i::iterator mi; - std::multimap,int, AngleLess>::iterator micossin; - // for(mi=Ordre.begin();mi!=Ordre.end();mi++) - // { - // int j=(*mi).second; - // Pt_ordonne.push_back(V[2*j]); - // Pt_ordonne.push_back(V[2*j+1]); - // } - for(micossin=CosSin.begin();micossin!=CosSin.end();micossin++) - { - int j=(*micossin).second; - Pt_ordonne.push_back(V[2*j]); - Pt_ordonne.push_back(V[2*j+1]); - } - delete [] COS; - delete [] SIN; - // delete [] angle; - return Pt_ordonne; - } - } - - template - inline void getElemBB(double* bb, const double *coordsOfMesh, int iP, int nb_nodes) - { - bb[0]=std::numeric_limits::max(); - bb[1]=-std::numeric_limits::max(); - bb[2]=std::numeric_limits::max(); - bb[3]=-std::numeric_limits::max(); - bb[4]=std::numeric_limits::max(); - bb[5]=-std::numeric_limits::max(); - - for (int i=0; ibb[1])?x:bb[1]; - bb[2]=(ybb[3])?y:bb[3]; - bb[4]=(zbb[5])?z:bb[5]; - } - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Computes the dot product of a and b */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template - inline double dotprod( const double * a, const double * b) - { - double result=0; - for(int idim = 0; idim < dim ; idim++) result += a[idim]*b[idim]; - return result; - } - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Computes the norm of vector v */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template - inline double norm(const double * v) - { - double result =0; - for(int idim =0; idim - inline double distance2( const double * a, const double * b) - { - double result =0; - for(int idim =0; idim - inline double distance2( T * a, int inda, T * b, int indb) - { - double result =0; - for(int idim =0; idim inline void crossprod( const double * A, const double * B, const double * C, double * V); - - template<> inline - void crossprod<2>( const double * A, const double * B, const double * C, double * V) - { - double AB[2]; - double AC[2]; - for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A - for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - V[0]=determinant(AB,AC); - V[1]=0; - } - template<> inline - void crossprod<3>( const double * A, const double * B, const double * C, double * V) - { - double AB[3]; - double AC[3]; - for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A - for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - V[0]=AB[1]*AC[2]-AB[2]*AC[1]; - V[1]=-AB[0]*AC[2]+AB[2]*AC[0]; - V[2]=AB[0]*AC[1]-AB[1]*AC[0]; - } - template<> inline - void crossprod<1>( const double * /*A*/, const double * /*B*/, const double * /*C*/, double * /*V*/) - { - // just to be able to compile - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Checks wether point A is inside the quadrangle BCDE */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - template inline double check_inside(const double* A,const double* B,const double* C,const double* D, - const double* E,double* ABC, double* ADE) - { - crossprod(A,B,C,ABC); - crossprod(A,D,E,ADE); - return dotprod(ABC,ADE); - } - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Computes the geometric angle (in [0,Pi]) between two non zero vectors AB and AC */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template inline double angle(const double * A, const double * B, const double * C, double * n) - { - double AB[dim]; - double AC[dim]; - double orthAB[dim]; - - for(int idim =0; idim(AB); - for(int idim =0; idim(AC); - double AB_dot_AC=dotprod(AB,AC); - for(int idim =0; idim(orthAB); - - return 2*atan2(numer,denom); - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Tells whether the frame constituted of vectors AB, AC and n is direct */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template inline double direct_frame(const double * A, const double * B, const double * C, double * n); - template<> inline - double direct_frame<2>(const double * A, const double * B, const double * C, double * n) - { - double AB[2]; - double AC[2]; - for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A; - for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - return determinant(AB,AC)*n[0]; - } - template<> inline - double direct_frame<3>(const double * A, const double * B, const double * C, double * n) - { - double AB[3]; - double AC[3]; - for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A; - for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - return determinant(AB,AC,n)>0; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* calcul l'intersection de deux polygones COPLANAIRES */ - /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considere*/ - /* que les deux premieres coordonnees de chaque point */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template inline void intersec_de_polygone(const double * Coords_A, const double * Coords_B, - int nb_NodesA, int nb_NodesB, - std::vector& inter, - double dim_caracteristic, double precision) - { - for(int i_A = 1; i_A3) inter=INTERP_KERNEL::reconstruct_polygon(inter); - } - - /*_ _ _ _ _ _ _ _ _ - *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - * fonctions qui calcule l'aire d'un polygone en dimension 2 ou 3 - *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - template inline double polygon_area(std::vector& inter) - { - double result=0.; - double area[DIM]; - - for(int i = 1; i<(int)inter.size()/DIM-1; i++) - { - INTERP_KERNEL::crossprod(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); - result +=0.5*norm(area); - } - return result; - } - - template inline double polygon_area(std::deque& inter) - { - double result=0.; - double area[DIM]; - - for(int i = 1; i<(int)inter.size()/DIM-1; i++) - { - INTERP_KERNEL::crossprod(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); - result +=0.5*norm(area); - } - return result; - } - - /*! Computes the triple product (XA^XB).XC (in 3D)*/ - inline double triple_product(const double* A, const double*B, const double*C, const double*X) - { - double XA[3]; - XA[0]=A[0]-X[0]; - XA[1]=A[1]-X[1]; - XA[2]=A[2]-X[2]; - double XB[3]; - XB[0]=B[0]-X[0]; - XB[1]=B[1]-X[1]; - XB[2]=B[2]-X[2]; - double XC[3]; - XC[0]=C[0]-X[0]; - XC[1]=C[1]-X[1]; - XC[2]=C[2]-X[2]; - - return - (XA[1]*XB[2]-XA[2]*XB[1])*XC[0]+ - (XA[2]*XB[0]-XA[0]*XB[2])*XC[1]+ - (XA[0]*XB[1]-XA[1]*XB[0])*XC[2]; - } - - /*! Subroutine of checkEqualPolygins that tests if two list of nodes (not necessarily distincts) describe the same polygon, assuming they share a comon point.*/ - /*! Indexes istart1 and istart2 designate two points P1 in L1 and P2 in L2 that have identical coordinates. Generally called with istart1=0.*/ - /*! Integer sign ( 1 or -1) indicate the direction used in going all over L2. */ - template - bool checkEqualPolygonsOneDirection(T * L1, T * L2, int size1, int size2, int istart1, int istart2, double epsilon, int sign) - { - int i1 = istart1; - int i2 = istart2; - int i1next = ( i1 + 1 ) % size1; - int i2next = ( i2 + sign +size2) % size2; - - while(true) - { - while( i1next!=istart1 && distance2(L1,i1*dim, L1,i1next*dim) < epsilon ) i1next = ( i1next + 1 ) % size1; - while( i2next!=istart2 && distance2(L2,i2*dim, L2,i2next*dim) < epsilon ) i2next = ( i2next + sign +size2 ) % size2; - - if(i1next == istart1) - { - if(i2next == istart2) - return true; - else return false; - } - else - if(i2next == istart2) - return false; - else - { - if(distance2(L1,i1next*dim, L2,i2next*dim) > epsilon ) - return false; - else - { - i1 = i1next; - i2 = i2next; - i1next = ( i1 + 1 ) % size1; - i2next = ( i2 + sign + size2 ) % size2; - } - } - } - } - - /*! Tests if two list of nodes (not necessarily distincts) describe the same polygon.*/ - /*! Existence of multiple points in the list is considered.*/ - template - bool checkEqualPolygons(T * L1, T * L2, double epsilon) - { - if(L1==NULL || L2==NULL) - { - std::cout << "Warning InterpolationUtils.hxx:checkEqualPolygonsPointer: Null pointer " << std::endl; - throw(Exception("big error: not closed polygon...")); - } - - int size1 = (*L1).size()/dim; - int size2 = (*L2).size()/dim; - int istart1 = 0; - int istart2 = 0; - - while( istart2 < size2 && distance2(L1,istart1*dim, L2,istart2*dim) > epsilon ) istart2++; - - if(istart2 == size2) - { - return (size1 == 0) && (size2 == 0); - } - else - return checkEqualPolygonsOneDirection( L1, L2, size1, size2, istart1, istart2, epsilon, 1) - || checkEqualPolygonsOneDirection( L1, L2, size1, size2, istart1, istart2, epsilon, -1); - - } -} - - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3D.hxx b/medtool/src/INTERP_KERNEL/Intersector3D.hxx deleted file mode 100644 index c9b74ffe7..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3D.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERSECTOR3D_HXX__ -#define __INTERSECTOR3D_HXX__ - -#include "TargetIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3D : public TargetIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - void getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const; - void getRealSourceCoordinates(ConnType icellT, std::vector& coordsT) const; - const ConnType *getStartConnOfTargetCell(ConnType icellT) const; - const ConnType *getStartConnOfSourceCell(ConnType icellS) const; - void getConnOfSourceCell(ConnType icellS, typename std::vector& res) const; - protected: - const MyMeshType& _target_mesh; - const MyMeshType& _src_mesh; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3D.txx b/medtool/src/INTERP_KERNEL/Intersector3D.txx deleted file mode 100644 index 92ff0a56a..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3D.txx +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERSECTOR3D_TXX__ -#define __INTERSECTOR3D_TXX__ - -#include "Intersector3D.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - Intersector3D::Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh):_target_mesh(targetMesh),_src_mesh(srcMesh) - { - } - - /*! - * @param icellT in format of MyMeshType. - */ - template - void Intersector3D::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const - { - int nbNodesT=_target_mesh.getNumberOfNodesOfElement(icellT); - coordsT.resize(SPACEDIM*nbNodesT); - std::vector::iterator iter=coordsT.begin(); - for (ConnType iT=0; iT - void Intersector3D::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) const - { - int nbNodesS=_src_mesh.getNumberOfNodesOfElement(icellS); - coordsS.resize(SPACEDIM*nbNodesS); - std::vector::iterator iter=coordsS.begin(); - for (ConnType iS=0; iS - const typename MyMeshType::MyConnType *Intersector3D::getStartConnOfTargetCell(ConnType icellT) const - { - const ConnType *myConectT=_target_mesh.getConnectivityPtr(); - const ConnType *myConIndexT=_target_mesh.getConnectivityIndexPtr(); - return myConectT+OTT::conn2C(myConIndexT[icellT]); - } - - /*! - * @param icellT in C format. - * @return is in format of MyMeshType - */ - template - const typename MyMeshType::MyConnType *Intersector3D::getStartConnOfSourceCell(ConnType icellS) const - { - const ConnType *myConectS=_src_mesh.getConnectivityPtr(); - const ConnType *myConIndexS=_src_mesh.getConnectivityIndexPtr(); - return myConectS+OTT::conn2C(myConIndexS[icellS]); - } - - /*! - * @param icellS in format of MyMeshType. - * @param res ; out param in format of MyMeshType. - */ - template - void Intersector3D::getConnOfSourceCell(ConnType icellS, typename std::vector& res) const - { - const ConnType *myConectS=_src_mesh.getConnectivityPtr(); - const ConnType *myConIndexS=_src_mesh.getConnectivityIndexPtr(); - ConnType start=myConIndexS[OTT::ind2C(icellS)]; - ConnType end=myConIndexS[OTT::ind2C(icellS)+1]; - int nbNodesS=end-start; - res.resize(nbNodesS); - std::copy(myConectS+OTT::conn2C(start),myConectS+OTT::conn2C(end),res.begin()); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP0P0.hxx b/medtool/src/INTERP_KERNEL/Intersector3DP0P0.hxx deleted file mode 100644 index ede6b02ae..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP0P0.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERSECTOR3DP0P0_HXX__ -#define __INTERSECTOR3DP0P0_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP0P0 : public Intersector3D - { - public: - Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP0P0.txx b/medtool/src/INTERP_KERNEL/Intersector3DP0P0.txx deleted file mode 100644 index 86f1a17d5..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP0P0.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERSECTOR3DP0P0_TXX__ -#define __INTERSECTOR3DP0P0_TXX__ - -#include "Intersector3DP0P0.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP0P0::Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP0P0::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfElements(); - } - - template - int Intersector3DP0P0::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfElements(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP0P1.hxx b/medtool/src/INTERP_KERNEL/Intersector3DP0P1.hxx deleted file mode 100644 index 8ba8b6cc4..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP0P1.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERSECTOR3DP0P1_HXX__ -#define __INTERSECTOR3DP0P1_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP0P1 : public Intersector3D - { - public: - Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP0P1.txx b/medtool/src/INTERP_KERNEL/Intersector3DP0P1.txx deleted file mode 100644 index cd44920ce..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP0P1.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERSECTOR3DP0P1_TXX__ -#define __INTERSECTOR3DP0P1_TXX__ - -#include "Intersector3DP0P1.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP0P1::Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP0P1::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfNodes(); - } - - template - int Intersector3DP0P1::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfElements(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP1P0.hxx b/medtool/src/INTERP_KERNEL/Intersector3DP1P0.hxx deleted file mode 100644 index 8ba6bf53c..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP1P0.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __INTERSECTOR3DP1P0_HXX__ -#define __INTERSECTOR3DP1P0_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP1P0 : public Intersector3D - { - public: - Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP1P0.txx b/medtool/src/INTERP_KERNEL/Intersector3DP1P0.txx deleted file mode 100644 index 9db664d67..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP1P0.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __INTERSECTOR3DP1P0_TXX__ -#define __INTERSECTOR3DP1P0_TXX__ - -#include "Intersector3DP1P0.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP1P0::Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP1P0::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfElements(); - } - - template - int Intersector3DP1P0::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfNodes(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx b/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx deleted file mode 100644 index 8b69793dc..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __Intersector3DP1P0Bary_HXX__ -#define __Intersector3DP1P0Bary_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP1P0Bary : public Intersector3D - { - public: - Intersector3DP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx b/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx deleted file mode 100644 index 31e7f2401..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __Intersector3DP1P0Bary_TXX__ -#define __Intersector3DP1P0Bary_TXX__ - -#include "Intersector3DP1P0Bary.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP1P0Bary::Intersector3DP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP1P0Bary::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfElements(); - } - - template - int Intersector3DP1P0Bary::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfNodes(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP1P1.hxx b/medtool/src/INTERP_KERNEL/Intersector3DP1P1.hxx deleted file mode 100644 index ff5977fa7..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP1P1.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __Intersector3DP1P1_HXX__ -#define __Intersector3DP1P1_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP1P1 : public Intersector3D - { - public: - Intersector3DP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Intersector3DP1P1.txx b/medtool/src/INTERP_KERNEL/Intersector3DP1P1.txx deleted file mode 100644 index a8aea3824..000000000 --- a/medtool/src/INTERP_KERNEL/Intersector3DP1P1.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __Intersector3DP1P1_TXX__ -#define __Intersector3DP1P1_TXX__ - -#include "Intersector3DP1P1.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP1P1::Intersector3DP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP1P1::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfNodes(); - } - - template - int Intersector3DP1P1::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfNodes(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU.hxx b/medtool/src/INTERP_KERNEL/IntersectorCU.hxx deleted file mode 100644 index 3bd09d120..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU.hxx +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : IntersectorCU.hxx -// Created : Thu Dec 17 12:30:17 2009 -// Author : Edward AGAPOV (eap) -// - -#ifndef __IntersectorCU_HXX__ -#define __IntersectorCU_HXX__ - -#include "TargetIntersector.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template class _StabIntersector; - - template > - class IntersectorCU : public TargetIntersector - { - public: - static const int SPACEDIM=MyCMeshType::MY_SPACEDIM; - static const int MESHDIM=MyCMeshType::MY_MESHDIM; - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - //! \addtogroup InterpKerGrpIntCU @{ - IntersectorCU(const MyCMeshType& meshS, const MyUMeshType& meshT); - //! @} - virtual ~IntersectorCU(); - void getUElemBB(double* bb, UConnType iP); - void getUCoordinates(UConnType icell, std::vector& coords); - - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(CConnType icellU, const std::vector& icellC, MyMatrix& res); - double intersectGeometry(CConnType icellT, const std::vector& icellC) { return asLeaf().intersectGeometry(icellT,icellC); } - protected: - ConcreteIntersector& asLeaf() { return static_cast(*this); } - - protected: - const UConnType *_connectU; - const UConnType *_connIndexU; - const double * _coordsU; - const MyUMeshType& _meshU; - - const double * _coordsC[SPACEDIM]; - int _nbCellsC[SPACEDIM]; - const MyCMeshType& _meshC; - }; - - // class to enable usage of IntersectorCU not for intersection but for access to data it encapsulates - template - class _StabIntersector: public IntersectorCU > - { - public: - _StabIntersector(const MyCMeshType& meshS, const MyUMeshType& meshT) : IntersectorCU >(meshS, meshT) {} - double intersectGeometry(typename MyUMeshType::MyConnType icellT, const std::vector& icellC) { throw Exception("You must provide an intersector as the 4-th template argument of IntersectorCU"); return 0; } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU.txx b/medtool/src/INTERP_KERNEL/IntersectorCU.txx deleted file mode 100644 index b6111f732..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU.txx +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : IntersectorCU.txx -// Created : Thu Dec 17 12:30:17 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU_TXX__ -#define __IntersectorCU_TXX__ - -#include "IntersectorCU.hxx" - -// convert index "From Mesh Index" -#define _FMIU(i) OTT::ind2C((i)) -#define _FMIC(i) OTT::ind2C((i)) -// convert index "To Mesh Index" -#define _TMIU(i) OTT::indFC((i)) -#define _TMIC(i) OTT::indFC((i)) -// convert coord "From Mesh Coord" -#define _FMCOO(i) OTT::coo2C((i)) -// convert connectivity "From Mesh Connectivity" -#define _FMCON(i) OTT::conn2C((i)) - - -#define _CU_TEMPLATE \ -template -#define _INTERSECTOR_CU_ \ -IntersectorCU - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief Constructor - */ - //================================================================================ - - _CU_TEMPLATE - _INTERSECTOR_CU_::IntersectorCU(const MyCMeshType& meshS, const MyUMeshType& meshT): - _meshU(meshT), _meshC(meshS) - { - _connectU =meshT.getConnectivityPtr(); - _connIndexU=meshT.getConnectivityIndexPtr(); - _coordsU =meshT.getCoordinatesPtr(); - - for ( int j = 0; j < SPACEDIM; ++j ) - { - _coordsC [ j ] = _meshC.getCoordsAlongAxis( _TMIC( j )); - _nbCellsC[ j ] = _meshC.nbCellsAlongAxis ( _TMIC( j )); - } - } - - //================================================================================ - /*! - * \brief Destructor - */ - //================================================================================ - - _CU_TEMPLATE - _INTERSECTOR_CU_::~IntersectorCU() - { - } - - //================================================================================ - /*! - * \brief Return bounding box of an unstructured element - */ - //================================================================================ - - _CU_TEMPLATE - void _INTERSECTOR_CU_::getUElemBB(double* bb, UConnType icell) - { - //initializing bounding box limits - for(int idim=0; idim::max(); - bb[2*idim+1] = -std::numeric_limits::max(); - } - - UConnType nb_nodes = _connIndexU[icell+1] - _connIndexU[icell]; - for (UConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); - const double* coord_node=_coordsU+SPACEDIM*(_FMCOO( _connectU[_FMCON (_connIndexU[_FMIU(icell)]+i)])); - for(int idim=0; idimbb[2*idim+1])?x:bb[2*idim+1]; - } - } - } - - //================================================================================ - /*! - * \brief Return coordinates of nodes of an unstructured element - */ - //================================================================================ - - _CU_TEMPLATE - void _INTERSECTOR_CU_::getUCoordinates(UConnType icell, std::vector& coords) - { - UConnType nb_nodes = _connIndexU[icell+1] - _connIndexU[icell]; - coords.resize( SPACEDIM * nb_nodes ); - for (UConnType i=0; i& icellC, - MyMatrix& res) - { - double v = intersectGeometry(icellU, icellC); - - CConnType iC = icellC[0], area = _nbCellsC[0]; - for ( int j = 1; j < SPACEDIM; ++j ) - { - iC += icellC[j] * area; - area *= _nbCellsC[j]; - } - res[ icellU ][ iC ] = v; - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU1D.hxx b/medtool/src/INTERP_KERNEL/IntersectorCU1D.hxx deleted file mode 100644 index b22d4e5ab..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU1D.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : IntersectorCU1D.hxx -// Created : Thu Dec 17 14:10:00 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU1D_HXX__ -#define __IntersectorCU1D_HXX__ - -#include "IntersectorCU.hxx" - -namespace INTERP_KERNEL -{ - template - class IntersectorCU1D : public IntersectorCU > - { - public: - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - IntersectorCU1D(const MyCMeshType& meshS, const MyUMeshType& meshT); - ~IntersectorCU1D(); - double intersectGeometry(UConnType icellT, const std::vector& icellC); - - private: - }; -} - - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU1D.txx b/medtool/src/INTERP_KERNEL/IntersectorCU1D.txx deleted file mode 100644 index 832d7b3c1..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU1D.txx +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : IntersectorCU1D.txx -// Created : Thu Dec 17 14:17:49 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __IntersectorCU1D_TXX__ -#define __IntersectorCU1D_TXX__ - -#include "IntersectorCU1D.hxx" -#include "IntersectorCU.txx" - -#define IntersectorCU1D_TEMPLATE template -#define INTERSECTOR_CU1D IntersectorCU1D -#define _INTER_CU IntersectorCU > - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief intersector of the unstructured mesh and the cartesian mesh in 1D - */ - //================================================================================ - - IntersectorCU1D_TEMPLATE - INTERSECTOR_CU1D::IntersectorCU1D(const MyCMeshType& meshS, - const MyUMeshType& meshT): - _INTER_CU( meshS, meshT ) - { - if ( MyCMeshType::MY_SPACEDIM != 1 || MyCMeshType::MY_MESHDIM != 1 || - MyUMeshType::MY_SPACEDIM != 1 || MyUMeshType::MY_MESHDIM != 1 ) - throw Exception("IntersectorCU1D(): Invalid mesh dimension, it must be 1"); - } - - //================================================================================ - /*! - * \brief destructor - */ - //================================================================================ - - IntersectorCU1D_TEMPLATE - INTERSECTOR_CU1D::~IntersectorCU1D() - { - } - - //================================================================================ - /*! - * \brief Calculate length of intersection of an unstructured cell and a cartesian one. - * The cartesian cell is given by its [i,j,k] indices - */ - //================================================================================ - - IntersectorCU1D_TEMPLATE - double INTERSECTOR_CU1D::intersectGeometry(UConnType icellT, - const std::vector& icellS) - { - std::vector coordsU; - _INTER_CU::getUCoordinates(icellT, coordsU); - - const double* coordsC = & _INTER_CU::_coordsC[0][ _FMIC(icellS[0]) ]; - - double res = std::min( coordsU[1], coordsC[1] ) - std::max( coordsU[0], coordsC[0] ); - return res; - } -} -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU2D.hxx b/medtool/src/INTERP_KERNEL/IntersectorCU2D.hxx deleted file mode 100644 index e034028fa..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU2D.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : IntersectorCU2D.hxx -// Created : Thu Dec 17 14:10:00 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU2D_HXX__ -#define __IntersectorCU2D_HXX__ - -#include "IntersectorCU.hxx" - -namespace INTERP_KERNEL -{ - template - class IntersectorCU2D : public IntersectorCU > - { - public: - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - IntersectorCU2D(const MyCMeshType& meshS, const MyUMeshType& meshT); - double intersectGeometry(UConnType icellT, const std::vector& icellC); - - private: - TriangulationIntersector _intersector; - }; -} - - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU2D.txx b/medtool/src/INTERP_KERNEL/IntersectorCU2D.txx deleted file mode 100644 index df7c7efb7..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU2D.txx +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : IntersectorCU2D.txx -// Created : Thu Dec 17 14:17:49 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __IntersectorCU2D_TXX__ -#define __IntersectorCU2D_TXX__ - -#include "IntersectorCU2D.hxx" -#include "IntersectorCU.txx" - -#define IntersectorCU2D_TEMPLATE template -#define INTERSECTOR_CU2D IntersectorCU2D -#define INTER_CU IntersectorCU > - - -namespace INTERP_KERNEL -{ - IntersectorCU2D_TEMPLATE - INTERSECTOR_CU2D::IntersectorCU2D(const MyCMeshType& meshS, - const MyUMeshType& meshT): - IntersectorCU >( meshS, meshT ), - _intersector(meshT, meshT, 0,0,0,0,0,0,0 ) - { - if ( MyCMeshType::MY_SPACEDIM != 2 || MyCMeshType::MY_MESHDIM != 2 || - MyUMeshType::MY_SPACEDIM != 2 || MyUMeshType::MY_MESHDIM != 2 ) - throw Exception("IntersectorCU2D(): Invalid mesh dimension, it must be 2"); - } - - - //================================================================================ - /*! - * \brief Calculate area of intersection of an unstructured cell and a cartesian one. - * The cartesian cell is given by its [i,j] indices - */ - //================================================================================ - - IntersectorCU2D_TEMPLATE - double INTERSECTOR_CU2D::intersectGeometry(UConnType icellT, - const std::vector& icellS) - { - std::vector uCoords; - this->getUCoordinates( icellT, uCoords ); - - NormalizedCellType tT = INTER_CU::_meshU.getTypeOfElement( _TMIU(icellT)); - bool is_tgt_quad = CellModel::GetCellModel(tT).isQuadratic(); - - double quad[8] = { INTER_CU::_coordsC[0][icellS[0]], INTER_CU::_coordsC[1][icellS[1]], - INTER_CU::_coordsC[0][icellS[0]+1], INTER_CU::_coordsC[1][icellS[1]], - INTER_CU::_coordsC[0][icellS[0]+1], INTER_CU::_coordsC[1][icellS[1]+1], - INTER_CU::_coordsC[0][icellS[0]], INTER_CU::_coordsC[1][icellS[1]+1] }; - - double surf = _intersector.intersectGeometryWithQuadrangle( quad, - uCoords, - is_tgt_quad); - return surf; - } -} -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU3D.hxx b/medtool/src/INTERP_KERNEL/IntersectorCU3D.hxx deleted file mode 100644 index 32abb3d0c..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU3D.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : IntersectorCU3D.hxx -// Created : Thu Dec 17 14:10:00 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU3D_HXX__ -#define __IntersectorCU3D_HXX__ - -#include "IntersectorCU.hxx" -#include "SplitterTetra.hxx" - -namespace INTERP_KERNEL -{ - class _Cartesian3D2UnstructHexMesh; - - template - class IntersectorCU3D : public IntersectorCU > - { - public: - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - IntersectorCU3D(const MyCMeshType& meshS, const MyUMeshType& meshT, SplittingPolicy splitting_policy); - ~IntersectorCU3D(); - double intersectGeometry(UConnType icellT, const std::vector& icellC); - - private: - - typedef SplitterTetra2 TSplitter; - typedef SplitterTetra <_Cartesian3D2UnstructHexMesh > TTetra; - _Cartesian3D2UnstructHexMesh* _uHexMesh; - TSplitter* _split; - }; -} - - -#endif diff --git a/medtool/src/INTERP_KERNEL/IntersectorCU3D.txx b/medtool/src/INTERP_KERNEL/IntersectorCU3D.txx deleted file mode 100644 index c271120f0..000000000 --- a/medtool/src/INTERP_KERNEL/IntersectorCU3D.txx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2009-2015 OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : IntersectorCU3D.txx -// Created : Thu Dec 17 14:17:49 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __IntersectorCU3D_TXX__ -#define __IntersectorCU3D_TXX__ - -#include "IntersectorCU3D.hxx" -#include "IntersectorCU.txx" -#include "SplitterTetra.txx" - -#define IntersectorCU3D_TEMPLATE template -#define INTERSECTOR_CU3D IntersectorCU3D -#define _INTERSECTOR_CU IntersectorCU > - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief Unstructured hexahedral mesh derived from cartesian 3D mesh. - * Mesh contains one HEXA8 element - */ - //================================================================================ - - class _Cartesian3D2UnstructHexMesh - { - public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=3; - typedef int MyConnType; - static const NumberingPolicy My_numPol=ALL_C_MODE; - - _Cartesian3D2UnstructHexMesh(const double * coords[3]): _coordsC(coords) {} - void setHexa(int I, int J, int K) // indices in C mode - { - double* pCoord = _coordsU; - for ( int k = K; k < K+2; ++k ) - for ( int j = J; j < J+2; ++j ) - for ( int i = I; i < I+2; ++i ) - { - *pCoord++ = _coordsC[0][i]; - *pCoord++ = _coordsC[1][j]; - *pCoord++ = _coordsC[2][k]; - } - } - const int *getConnectivityPtr() const - { - static int conn[] = { 1,0,2,3,5,4,6,7 }; - return conn; - } - const int *getConnectivityIndexPtr() const - { - static int conInd[] = { 0,8 }; - return conInd; - } - void getBoundingBox(double *boundingBox) const - { - boundingBox[BoundingBox::XMIN] = _coordsU[0]; - boundingBox[BoundingBox::XMAX] = _coordsU[0+1*MY_SPACEDIM]; - boundingBox[BoundingBox::YMIN] = _coordsU[1]; - boundingBox[BoundingBox::YMAX] = _coordsU[1+2*MY_SPACEDIM]; - boundingBox[BoundingBox::ZMIN] = _coordsU[2]; - boundingBox[BoundingBox::ZMAX] = _coordsU[2+4*MY_SPACEDIM]; - } - NormalizedCellType getTypeOfElement(int eltId) const { return NORM_HEXA8; } - unsigned char getNumberOfNodesOfElement(int eltId) const { return 8; } - unsigned long getNumberOfElements() const { return 1; } - unsigned long getNumberOfNodes() const { return 8; } - const double *getCoordinatesPtr() const { return _coordsU; } - void releaseTempArrays() {} - private: - const double** _coordsC; - double _coordsU[3*8]; - }; - - //================================================================================ - /*! - * \brief intersector of the unstructured mesh and the cartesian mesh in 3D - */ - //================================================================================ - - IntersectorCU3D_TEMPLATE - INTERSECTOR_CU3D::IntersectorCU3D(const MyCMeshType& meshS, - const MyUMeshType& meshT, - SplittingPolicy splitting_policy): - _INTERSECTOR_CU( meshS, meshT ) - { - if ( MyCMeshType::MY_SPACEDIM != 3 || MyCMeshType::MY_MESHDIM != 3 || - MyUMeshType::MY_SPACEDIM != 3 || MyUMeshType::MY_MESHDIM != 3 ) - throw Exception("IntersectorCU3D(): Invalid mesh dimension, it must be 3"); - - _uHexMesh = new _Cartesian3D2UnstructHexMesh( _INTERSECTOR_CU::_coordsC ); - _split = new TSplitter( meshT, *_uHexMesh, splitting_policy ); - } - - //================================================================================ - /*! - * \brief destructor - */ - //================================================================================ - - IntersectorCU3D_TEMPLATE - INTERSECTOR_CU3D::~IntersectorCU3D() - { - delete _uHexMesh; _uHexMesh=0; - delete _split; _split=0; - } - - //================================================================================ - /*! - * \brief Calculate volume of intersection of an unstructured cell and a cartesian one. - * The cartesian cell is given by its [i,j,k] indices - */ - //================================================================================ - - IntersectorCU3D_TEMPLATE - double INTERSECTOR_CU3D::intersectGeometry(UConnType icellT, - const std::vector& icellS) - { - // split an unstructured cell into tetra - std::vector< TTetra* > tetra; - UConnType nb_nodes = - _INTERSECTOR_CU::_connIndexU[icellT+1] - _INTERSECTOR_CU::_connIndexU[icellT]; - _split->releaseArrays(); - _split->splitTargetCell( icellT, nb_nodes, tetra); - - // intersect a cartesian 3d cell with tetra - _uHexMesh->setHexa( _FMIC(icellS[0]),_FMIC(icellS[1]),_FMIC(icellS[2])); // set cell at i,j,k - double res = 0; - for ( unsigned int t = 0; t < tetra.size(); ++t ) - { - res += tetra[t]->intersectSourceCell( 0 ); - delete tetra[t]; - } - return res; - } -} -#endif diff --git a/medtool/src/INTERP_KERNEL/Log.hxx b/medtool/src/INTERP_KERNEL/Log.hxx deleted file mode 100644 index 3f0e35157..000000000 --- a/medtool/src/INTERP_KERNEL/Log.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _LOG_H_ -#define _LOG_H_ - -/** - * \file Log.hxx - * \brief Simple pre-processor logging utility. - * - * Replaces LOG( lvl, x ) with "if(lvl <= LOG_LEVEL) std::cout << x << std::endl" when logging is active - * (LOG_LEVEL > 0 is defined). x is the level at which the message should be logged - if it is smaller or equal to - * LOG_LEVEL (which can be defined at compile-time for each file by passing option -DLOG_LEVEL=x to gcc) - * than the message is logged. - * - * - * - */ - -/// define LOG_LEVEL here if it is not already defined -#ifndef LOG_LEVEL -#define LOG_LEVEL 0 -#endif - -#if LOG_LEVEL > 0 - -#include - -/// write message msg to std::cout if x <= LOG_LEVEL -#define LOG(x, msg) if(x <= LOG_LEVEL) std::cout << msg << std::endl; -#define LOG3( x , msg1 , msg2 ) if(x <= LOG_LEVEL) std::cout << msg1, msg2 << std::endl; - -#else - -#define LOG( x , msg ) -#define LOG3( x , msg1 , msg2 ) - -#endif - - - - - - - - - - - -#endif diff --git a/medtool/src/INTERP_KERNEL/MeshElement.cxx b/medtool/src/INTERP_KERNEL/MeshElement.cxx deleted file mode 100644 index 696d30b18..000000000 --- a/medtool/src/INTERP_KERNEL/MeshElement.cxx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MeshElement.hxx" - -namespace INTERP_KERNEL -{ - ///////////////////////////////////////////////////////////////////// - /// ElementBBoxOrder ///////////// - ///////////////////////////////////////////////////////////////////// - /** - * Constructor - * - * @param coord BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering - */ - ElementBBoxOrder::ElementBBoxOrder(BoundingBox::BoxCoord coord) - : _coord(coord) - { - } -} - diff --git a/medtool/src/INTERP_KERNEL/MeshElement.hxx b/medtool/src/INTERP_KERNEL/MeshElement.hxx deleted file mode 100644 index 3fb6ab652..000000000 --- a/medtool/src/INTERP_KERNEL/MeshElement.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MESHELEMENT_HXX__ -#define __MESHELEMENT_HXX__ - -#include "BoundingBox.hxx" - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing a single element of a mesh together with its bounding box. - * It gives access to the element's global number, type and bounding box and allows - * easy bounding box intersection tests between MeshElements and collections of MeshElement (MeshRegions) - */ - template - class MeshElement - { - - public: - template - MeshElement(const ConnType index, const MyMeshType& mesh); - - ~MeshElement(); - - ConnType getIndex() const { return _index; } - - unsigned char getNumberOfNodes() const { return _number; } - - const BoundingBox* getBoundingBox() const { return _box; } - - private: - /// disallow copying - MeshElement(const MeshElement& elem); - - /// disallow assignment - MeshElement& operator=(const MeshElement& elem); - - /// global number of the element - const ConnType _index; - - const unsigned char _number; - - /// bounding box of the element - does not change after having been initialised - BoundingBox* _box; - }; - - /** - * \brief Class defining an order for MeshElements based on their bounding boxes. - * The order defined between two elements is that between a given coordinate of - * their bounding boxes. For instance, if the order is based on YMIN, an element whose boxes - * has a smaller YMIN is sorted before one with a larger YMIN. - * - */ - class ElementBBoxOrder - { - public : - - ElementBBoxOrder(BoundingBox::BoxCoord coord); - template - bool operator()(MeshElement* elem1, MeshElement* elem2); - - private : - /// BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering - BoundingBox::BoxCoord _coord; - }; - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/MeshElement.txx b/medtool/src/INTERP_KERNEL/MeshElement.txx deleted file mode 100644 index 0da39e0a0..000000000 --- a/medtool/src/INTERP_KERNEL/MeshElement.txx +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __MESHELEMENT_TXX__ -#define __MESHELEMENT_TXX__ - -#include "MeshElement.hxx" - -#include "TetraAffineTransform.hxx" -#include "TransformedTriangle.hxx" -#include "MeshUtils.hxx" -#include "BoundingBox.hxx" -#include - -namespace INTERP_KERNEL -{ - - /** - * Constructor - * - * @param index global number of element in the mesh in C mode. - * @param mesh mesh that the element belongs to - */ - template - template - MeshElement::MeshElement(const ConnType index, const MyMeshType& mesh) - : _index(index), _number(mesh.getNumberOfNodesOfElement(OTT::indFC(index))), _box(0) - { - const double**vertices = new const double*[_number]; - - for(unsigned char i = 0 ; i < _number ; ++i) - vertices[i] = getCoordsOfNode(i , OTT::indFC(index), mesh); - - // create bounding box - _box = new BoundingBox(vertices,_number); - delete [] vertices; - } - - /** - * Destructor - * - */ - template - MeshElement::~MeshElement() - { - delete _box; - } - - - - ///////////////////////////////////////////////////////////////////// - /// ElementBBoxOrder ///////////// - ///////////////////////////////////////////////////////////////////// - - /** - * Comparison operator based on the bounding boxes of the elements - * - * @return true if the coordinate _coord of the bounding box of elem1 is - * strictly smaller than that of the bounding box of elem2 - */ - template - bool ElementBBoxOrder::operator()( MeshElement* elem1, MeshElement* elem2) - { - const BoundingBox* box1 = elem1->getBoundingBox(); - const BoundingBox* box2 = elem2->getBoundingBox(); - - assert(elem1 != 0); - assert(elem2 != 0); - assert(box1 != 0); - assert(box2 != 0); - - const double coord1 = box1->getCoordinate(_coord); - const double coord2 = box2->getCoordinate(_coord); - - return coord1 < coord2; - } - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/MeshRegion.hxx b/medtool/src/INTERP_KERNEL/MeshRegion.hxx deleted file mode 100644 index 6baf33e34..000000000 --- a/medtool/src/INTERP_KERNEL/MeshRegion.hxx +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MESHREGION_HXX__ -#define __MESHREGION_HXX__ - -#include "MeshElement.hxx" -#include "BoundingBox.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include - -namespace INTERP_KERNEL -{ - /** - * \brief Class representing a set of elements in a mesh together with their bounding box. - * It permits to split itself in two, which is used in the depth-first search filtering process. - * - */ - template - class MeshRegion - { - public: - - MeshRegion(); - - ~MeshRegion(); - - template - void addElement(MeshElement* const element, const MyMeshType& mesh); - - template - void split(MeshRegion& region1, MeshRegion& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh); - - bool isDisjointWithElementBoundingBox(const MeshElement& elem) const; - /** - * Accessor to beginning of elements vector - * - * @return constant iterator pointing at the beginning of the vector or elements - */ - typename std::vector< MeshElement* >::const_iterator getBeginElements() const { return _elements.begin(); } - - /** - * Accessor to end of elements vector - * - * @return constant iterator pointing at the end of the vector or elements - */ - typename std::vector< MeshElement* >::const_iterator getEndElements() const { return _elements.end(); } - - /** - * Gives information on how many elements are contained in the region. - * - * @return the number of elements contained in the region - */ - unsigned getNumberOfElements() const { return _elements.size(); } - - private: - - /// disallow copying - MeshRegion(const MeshRegion& m); - - /// disallow assignment - MeshRegion& operator=(const MeshRegion& m); - - /// Vector of pointers to contained MeshElements. - /// NB : these pointers are not owned by the region object, and are thus - /// neither allocated or liberated in this class. The elements must therefore be allocated and liberated outside the class. - std::vector< MeshElement* > _elements; - - /// BoundingBox containing all the nodes of all the elements in the region. - BoundingBox* _box; - - }; - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/MeshRegion.txx b/medtool/src/INTERP_KERNEL/MeshRegion.txx deleted file mode 100644 index 6183b9b7c..000000000 --- a/medtool/src/INTERP_KERNEL/MeshRegion.txx +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __MESHREGION_TXX__ -#define __MESHREGION_TXX__ - -#include "MeshRegion.hxx" - -#include "MeshElement.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * Default constructor - * - */ - template - MeshRegion::MeshRegion():_box(0) - { - } - - /** - * Destructor - * - */ - template - MeshRegion::~MeshRegion() - { - delete _box; - } - - /** - * Adds an element to the region, updating the bounding box. If the bounding box does not yet - * exist, it is created here. This creation is delayed to make it possible to have empty MeshRegions - * - * @param element pointer to element to add to region - * @param mesh mesh to which element belongs - * - */ - template - template - void MeshRegion::addElement(MeshElement* const element, const MyMeshType& mesh) - { - _elements.push_back(element); - - const unsigned char numNodes = element->getNumberOfNodes(); - const ConnType elemIdx = element->getIndex(); - - if(_box == 0) - { - const double** pts = new const double*[numNodes]; - - // get coordinates of the nodes of the element - for(unsigned char i = 0 ; i < numNodes ; ++i) - { - pts[i] = getCoordsOfNode(i, OTT::indFC(elemIdx), mesh); - } - - _box = new BoundingBox(pts, numNodes); - delete [] pts; - - } else { - - for(unsigned char i = 0 ; i < numNodes ; ++i) - { - const double* pt = getCoordsOfNode(i, OTT::indFC(elemIdx), mesh); - _box->updateWithPoint(pt); - } - } - } - - /** - * Splits the region in two along the given axis, copying the elements with bounding boxes whose maximum - * coordinate along the axis are smaller than the middle of the bounding box of this region in region1. The - * rest of the elements are copied to region2. - * - * @param region1 region in which to store one half of this region - * @param region2 region in which to store the other of this region - * @param coord coordinate of BoundingBox to use when splitting the region - * @param mesh mesh to which region belongs - * - */ - template - template - void MeshRegion::split(MeshRegion& region1, MeshRegion& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh) - { - // create ordering - ElementBBoxOrder cmp(coord); - - // sort elements by their bounding boxes - std::sort(_elements.begin(), _elements.end(), cmp); - - // put the first half of the elements in region1 and the - // rest in region2 - typename std::vector< MeshElement *>::const_iterator iter = _elements.begin(); - int elemCount = 0; - - while(elemCount < static_cast(_elements.size() / 2)) - { - region1.addElement(*iter, mesh); - ++iter; - ++elemCount; - } - - while(iter != _elements.end()) - { - region2.addElement(*iter, mesh); - ++iter; - } - } - - /** - * Determines if a given element can intersect the elements of this region by - * testing whether the bounding box of the region intersects the bounding box of the element. - * Note that the test is only true in one direction : if the bounding boxes are disjoint, the - * element cannot intersect any of the elements in the region, but if they are not disjoint, the - * element may or may not do so. - * - * @param elem Element with which to test for disjoint-ness - * @return true if the bounding box of the element is disjoint with the bounding box of the region, false otherwise - */ - template - bool MeshRegion::isDisjointWithElementBoundingBox(const MeshElement& elem) const - { - const BoundingBox* elemBox = elem.getBoundingBox(); - - assert(_box != 0); - assert(elemBox != 0); - - return _box->isDisjointWith(*elemBox); - } - - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/MeshUtils.hxx b/medtool/src/INTERP_KERNEL/MeshUtils.hxx deleted file mode 100644 index 6f751d134..000000000 --- a/medtool/src/INTERP_KERNEL/MeshUtils.hxx +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MESHUTILS_HXX__ -#define __MESHUTILS_HXX__ - -#include "InterpolationUtils.hxx" - -namespace INTERP_KERNEL -{ - /** - * Returns the global number of the node of an element. - * - * @param node the node for which the global number is sought (ALWAYS in C mode) - * @param element an element of the mesh (in numPol policy) - * @param mesh a mesh - * @return the node's global number so that (its coordinates in the coordinates array are at [SPACEDIM*globalNumber, SPACEDIM*globalNumber + SPACEDIM] - */ - template - inline typename MyMeshType::MyConnType getGlobalNumberOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - const ConnType elemIdx=OTT::conn2C(mesh.getConnectivityIndexPtr()[OTT::ind2C(element)]); - if(mesh.getTypeOfElement(element)!=INTERP_KERNEL::NORM_POLYHED) - return OTT::coo2C(mesh.getConnectivityPtr()[elemIdx + node]); - else - { - const ConnType *startNodalConnOfElem=mesh.getConnectivityPtr()+elemIdx; - ConnType ptr=0,ret=0; - while(startNodalConnOfElem[ret]==-1 || ptr!=node) - { - ret++; - if(startNodalConnOfElem[ret]!=-1) - ptr++; - } - return OTT::coo2C(startNodalConnOfElem[ret]); - } - } - - /** - * Returns the coordinates of a node of an element - * - * @param node the node for which the coordinates are sought. In C mode. - * @param element an element of the mesh. In mesh policy. - * @param mesh a mesh - * @return pointer to an array of 3 doubles containing the coordinates of the node - */ - template - inline const double* getCoordsOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) - { - typedef typename MyMeshType::MyConnType ConnType; - const ConnType connIdx = getGlobalNumberOfNode(node, element, mesh); - const double *ret=mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*connIdx; - return ret; - } - - /** - * Returns the coordinates of a node of an element - * - * @param node the node for which the coordinates are sought. In C mode. - * @param element an element of the mesh. In mesh policy. - * @param mesh a mesh - * @param nodeId globale nodeId in whole mesh point of view in C mode. - * @return pointer to an array of 3 doubles containing the coordinates of the node - */ - template - inline const double* getCoordsOfNode2(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh, typename MyMeshType::MyConnType& nodeId) - { - nodeId= getGlobalNumberOfNode(node, element, mesh); - return mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*nodeId; - } - - /** - * Returns the barycentric coordinates of a point within a triangle or tetrahedron - * - * @param point the point for which the barycentric coordinates are sought - * @param element an element of the mesh - * @param mesh a mesh - * @param barycentricCoords an array of 3 doubles containing the coordinates of the node - */ - template - inline void getBarycentricCoordinates(const double* point, - typename MyMeshType::MyConnType element, - const MyMeshType& mesh, - double* barycentricCoords) - { - std::vector nodes( NB_NODES ); - for ( int node = 0; node < NB_NODES; ++node ) - { - nodes[ node ] = getCoordsOfNode( node, element, mesh ); - } - barycentric_coords( nodes, point, barycentricCoords ); - } - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx b/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx deleted file mode 100644 index 4356a1c21..000000000 --- a/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANAR2D1DINTERSECTORP0P0_HXX__ -#define __PLANAR2D1DINTERSECTORP0P0_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class Planar2D1DIntersectorP0P0 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - const typename PlanarIntersector::DuplicateFacesType* getIntersectFaces() const - { - return &_intersect_faces; - } - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, - bool& isColinear) - { return asLeaf().intersectGeometry1D(icellT,icellS,nbNodesT,nbNodesS, isColinear); } - protected: - ConcreteP0P0Intersector& asLeaf() { return static_cast(*this); } - private: - typename PlanarIntersector::DuplicateFacesType _intersect_faces; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx b/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx deleted file mode 100644 index 848a8f592..000000000 --- a/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANAR2D1DINTERSECTORP0P0_TXX__ -#define __PLANAR2D1DINTERSECTORP0P0_TXX__ - -#include "Planar2D1DIntersectorP0P0.hxx" - -namespace INTERP_KERNEL -{ - template - Planar2D1DIntersectorP0P0::Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int Planar2D1DIntersectorP0P0::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int Planar2D1DIntersectorP0P0::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - template - void Planar2D1DIntersectorP0P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - typename MyMatrix::value_type& resRow=res[icellT]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - bool isColinear = false; - double surf=intersectGeometry1D(OTT::indFC(icellT),OTT::indFC(iS), - nbNodesT,nbNodesS, isColinear); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - - if (isColinear) - { - typename PlanarIntersector::DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(iS); - if (intersectFacesIter != _intersect_faces.end()) - { - intersectFacesIter->second.insert(icellT); - } - else - { - std::set targetCellSet; - targetCellSet.insert(icellT); - _intersect_faces.insert(std::make_pair(iS, targetCellSet)); - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersector.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersector.hxx deleted file mode 100644 index b0662104c..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersector.hxx +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTOR_HXX__ -#define __PLANARINTERSECTOR_HXX__ - -#include "TargetIntersector.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class TranslationRotationMatrix; - - template - class PlanarIntersector : public TargetIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - typedef typename std::map > DuplicateFacesType; - public: - PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - virtual ~PlanarIntersector(); - void createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox); - void adjustBoundingBoxes(std::vector& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs); - inline void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); - static int Projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate); - virtual const DuplicateFacesType* getIntersectFaces() const - { - return NULL; - } - protected : - int projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB); - void getRealTargetCoordinates(ConnType icellT, std::vector& coordsT); - void getRealSourceCoordinates(ConnType icellS, std::vector& coordsS); - void getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector& coordsT); - void getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector& coordsS); - void getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation); - double getValueRegardingOption(double val) const; - static void rotate3DTriangle( double* PP1, double*PP2, double*PP3, - TranslationRotationMatrix& rotation_matrix); - protected: - const ConnType *_connectT; - const ConnType *_connectS; - const double *_coordsT; - const double *_coordsS; - const ConnType *_connIndexT; - const ConnType *_connIndexS; - const MyMeshType& _meshT; - const MyMeshType& _meshS; - double _dim_caracteristic; - double _max_distance_3Dsurf_intersect; - double _min_dot_btw_3Dsurf_intersect; - double _precision; - double _median_plane; - bool _do_rotate; - int _orientation; - int _print_level; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersector.txx b/medtool/src/INTERP_KERNEL/PlanarIntersector.txx deleted file mode 100644 index ebaf24cb0..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersector.txx +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTOR_TXX__ -#define __PLANARINTERSECTOR_TXX__ - -#include "PlanarIntersector.hxx" -#include "InterpolationUtils.hxx" -#include "TranslationRotationMatrix.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - template - PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - _meshT(meshT),_meshS(meshS), - _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_min_dot_btw_3Dsurf_intersect(minDot3DSurf),_precision(precision),_median_plane(medianPlane), - _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel) - { - _connectT=meshT.getConnectivityPtr(); - _connectS=meshS.getConnectivityPtr(); - _connIndexT=meshT.getConnectivityIndexPtr(); - _connIndexS=meshS.getConnectivityIndexPtr(); - _coordsT=meshT.getCoordinatesPtr(); - _coordsS=meshS.getCoordinatesPtr(); - } - - template - PlanarIntersector::~PlanarIntersector() - { - } - - /*! - \brief creates the bounding boxes for all the cells of mesh \a mesh - - The method accepts mixed meshes (containing triangles and quadrangles). - The vector returned is of dimension 6*nb_elems with bounding boxes stored as xmin1, xmax1, ymin1, ymax1, zmin1, zmax1, xmin2, xmax2, ymin2,... - The returned pointer must be deleted by the calling code. - - \param mesh structure pointing to the mesh - \param bbox vector containing the bounding boxes - */ - template - void PlanarIntersector::createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox) - { - /* We build the segment tree for locating possible matching intersections*/ - long nbelems = mesh.getNumberOfElements(); - bbox.resize(2*SPACEDIM* nbelems); - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - int ibox=0; - for(long icell=0; icell::max(); - bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits::max(); - } - //updating the bounding box with each node of the element - for (int j=0; j::coo2C(conn[OTT::conn2C(conn_index[icell]+j)]); - for(int idim=0; idimx)?bbox[ibox*2*SPACEDIM + 2*idim+1]:x; - } - } - ibox++; - } - } - - /*! - Computes the bouding box of a given element. iP in numPol mode. - */ - template - void PlanarIntersector::getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes) - { - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - //initializing bounding box limits - for(int idim=0; idim::max(); - bb[2*idim+1] = -std::numeric_limits::max(); - } - - for (ConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); - for(int idim=0; idimbb[2*idim+1])?x:bb[2*idim+1]; - } - } - } - - /*! Readjusts a set of bounding boxes so that they are extended - in all dimensions for avoiding missing interesting intersections - - \param bbox vector containing the bounding boxes - */ - template - void PlanarIntersector::adjustBoundingBoxes(std::vector& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs) - { - /* We build the segment tree for locating possible matching intersections*/ - - long size = bbox.size()/(2*SPACEDIM); - for (int i=0; i::max(); - for(int idim=0; idim - void PlanarIntersector::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) - { - int nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; - coordsT.resize(SPACEDIM*nbNodesT); - for (ConnType iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - } - - /*! - * @param icellS id in source mesh in format of MyMeshType. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - */ - template - void PlanarIntersector::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) - { - int nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; - coordsS.resize(SPACEDIM*nbNodesS); - for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - - /*! - * @param icellT id in target mesh in format of MyMeshType. - * @param offset is a value in C format that indicates the number of circular permutation. - * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. - */ - template - void PlanarIntersector::getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector& coordsT) - { - int nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; - coordsT.resize(SPACEDIM*nbNodesT); - for (ConnType iTTmp=0; iTTmp::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - } - } - - /*! - * @param icellS id in source mesh in format of MyMeshType. - * @param offset is a value in C format that indicates the number of circular permutation. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - */ - template - void PlanarIntersector::getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector& coordsS) - { - int nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; - coordsS.resize(SPACEDIM*nbNodesS); - for (ConnType iSTmp=0; iSTmp::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - } - - /*! - * @param icellT id in target mesh in format of MyMeshType. - * @param icellS id in source mesh in format of MyMeshType. - * @param nbNodesT nb of nodes of the target cell. - * @param nbNodesS nb of nodes of the source cell. - * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - * @param orientation is an output value too, only set if SPACEDIM==3. - */ - template - void PlanarIntersector::getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation) - { - coordsT.resize(SPACEDIM*nbNodesT); - coordsS.resize(SPACEDIM*nbNodesS); - for (int idim=0; idim::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - - //project cells T and S on the median plane and rotate the median plane - if(SPACEDIM==3) - orientation = projectionThis(&coordsT[0], &coordsS[0], nbNodesT, nbNodesS); - - //DEBUG PRINTS - if(_print_level >= 3) - { - std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl; - std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " << nbNodesT << std::endl; - for(int iT =0; iT< nbNodesT; iT++) - {for (int idim=0; idim - double PlanarIntersector::getValueRegardingOption(double val) const - { - if(_orientation==0) - return val; - if(_orientation==2) - return fabs(val); - if (( val > 0.0 && _orientation==1) || ( val < 0.0 && _orientation==-1 )) - return _orientation*val; - return 0.; - } - - template - int PlanarIntersector::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB) - { - return Projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_min_dot_btw_3Dsurf_intersect,_median_plane,_do_rotate); - } - - template - int PlanarIntersector::Projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate) - { - double normal_A[3]={0,0,0}; - double normal_B[3]={0,0,0}; - double linear_comb[3]; - double proj; - bool same_orientation; - - //Find the normal to cells A and B - int i_A1(1); - while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) - i_A1++; - int i_A2(i_A1+1); - crossprod(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); - double normA(sqrt(dotprod(normal_A,normal_A))); - while(i_A2(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); - i_A2++; - normA = sqrt(dotprod(normal_A,normal_A)); - - } - int i_B1(1); - while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) - i_B1++; - int i_B2(i_B1+1); - crossprod(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); - double normB(sqrt(dotprod(normal_B,normal_B))); - while(i_B2(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); - i_B2++; - normB = sqrt(dotprod(normal_B,normal_B)); - } - - //fabien option - if(md3DSurf>0.) - { - double coords_GA[3]; - for(int i=0;i<3;i++) - { - coords_GA[i]=0.; - for (int j=0;jmd3DSurf) - return 0; - } - if(i_A2(normal_A,normal_B)/(normA*normB)); - - if(fabs(dotProd)=0); - - if(!same_orientation) - for(int idim =0; idim< SPACEDIM; idim++) - normal_A[idim] *=-1; - - double normBB(sqrt(dotprod(normal_B,normal_B))); - - for(int idim =0; idim< SPACEDIM; idim++) - linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normBB; - double norm= sqrt(dotprod(linear_comb,linear_comb)); - - //Necessarily: norm>epsilon, no need to check - for(int idim =0; idim< SPACEDIM; idim++) - linear_comb[idim]/=norm; - - //Project the nodes of A and B on the median plane - for(int i_A=0; i_A(&Coords_A[SPACEDIM*i_A],linear_comb); - for(int idim =0; idim< SPACEDIM; idim++) - Coords_A[SPACEDIM*i_A+idim] -= proj*linear_comb[idim]; - } - for(int i_B=0; i_B(Coords_B+SPACEDIM*i_B,linear_comb); - for(int idim =0; idim< SPACEDIM; idim++) - Coords_B[SPACEDIM*i_B+idim] -= proj*linear_comb[idim]; - } - - //Buid the matrix sending A into the Oxy plane and apply it to A and B - if(do_rotate) - { - TranslationRotationMatrix rotation; - //rotate3DTriangle(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2], rotation); - rotate3DTriangle(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2, rotation); - for (int i=0; i(Coords_A,&Coords_A[i_A1])= " << distance2(Coords_A,&Coords_A[i_A1]) << std::endl; - std::cout << "abs(normal_A) = " << fabs(normal_A[0]) << " ; " <(&Coords_B[0],&Coords_B[i_B1])= " << distance2(Coords_B,Coords_B+i_B1) << std::endl; - std::cout << "normal_B = " << normal_B[0] << " ; " << normal_B[1] << " ; " << normal_B[2] << std::endl; - return 1; - } - } - - template - void PlanarIntersector::rotate3DTriangle(double* PP1, double*PP2, double*PP3, - TranslationRotationMatrix& rotation_matrix) - { - //initializes - rotation_matrix.translate(PP1); - - double P2w[3]; - double P3w[3]; - P2w[0]=PP2[0]; P2w[1]=PP2[1];P2w[2]=PP2[2]; - P3w[0]=PP3[0]; P3w[1]=PP3[1];P3w[2]=PP3[2]; - - // translating to set P1 at the origin - for (int i=0; i<3; i++) - { - P2w[i]-=PP1[i]; - P3w[i]-=PP1[i]; - } - - // rotating to set P2 on the Oxy plane - TranslationRotationMatrix A; - A.rotate_x(P2w); - A.rotate_vector(P3w); - rotation_matrix.multiply(A); - - //rotating to set P2 on the Ox axis - TranslationRotationMatrix B; - B.rotate_z(P2w); - B.rotate_vector(P3w); - rotation_matrix.multiply(B); - - //rotating to set P3 on the Oxy plane - TranslationRotationMatrix C; - C.rotate_x(P3w); - rotation_matrix.multiply(C); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx deleted file mode 100644 index c20275ec6..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP0P0_HXX__ -#define __PLANARINTERSECTORP0P0_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P0 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) { return asLeaf().intersectGeometry(icellT,icellS,nbNodesT,nbNodesS); } - protected: - ConcreteP0P0Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx deleted file mode 100644 index 35e44ee80..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP0P0_TXX__ -#define __PLANARINTERSECTORP0P0_TXX__ - -#include "PlanarIntersectorP0P0.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P0::PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP0P0::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int PlanarIntersectorP0P0::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - template - void PlanarIntersectorP0P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - typename MyMatrix::value_type& resRow=res[icellT]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - double surf=intersectGeometry(OTT::indFC(icellT),OTT::indFC(iS),nbNodesT,nbNodesS); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx deleted file mode 100644 index bedddac9d..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP0P1_HXX__ -#define __PLANARINTERSECTORP0P1_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P1 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } - protected: - ConcreteP0P1Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx deleted file mode 100644 index 427b14b98..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP0P1_TXX__ -#define __PLANARINTERSECTORP0P1_TXX__ - -#include "PlanarIntersectorP0P1.hxx" -#include "InterpolationUtils.hxx" -#include "CellModel.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P1::PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP0P1::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP0P1::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - /*! - * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). - */ - template - void PlanarIntersectorP0P1::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - double triangle[9]; - double quadrangle[12]; - std::vector sourceCellCoords; - int orientation=1; - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - for(int nodeIdT=0;nodeIdT::coo2C(startOfCellNodeConn[nodeIdT]); - std::copy(PlanarIntersector::_coordsT+curNodeTInCmode*SPACEDIM, - PlanarIntersector::_coordsT+curNodeTInCmode*SPACEDIM+SPACEDIM,triangle); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),sourceCellCoords); - for(int subTriT=1;subTriT<=nbNodesT-2;subTriT++) - { - std::copy(PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM, - PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM+SPACEDIM, - triangle+SPACEDIM); - std::copy(PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM, - PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM+SPACEDIM, - triangle+2*SPACEDIM); - fillDualCellOfTri(triangle,quadrangle); - std::vector sourceCellCoordsTmp(sourceCellCoords); - if(SPACEDIM==3) - orientation=PlanarIntersector::projectionThis(&sourceCellCoordsTmp[0],quadrangle,sourceCellCoords.size()/SPACEDIM,4); - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(iS)); - double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,sourceCellCoordsTmp,CellModel::GetCellModel(tS).isQuadratic()); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - else - { - double val=(*iterRes).second+surf; - resRow.erase(OTT::indFC(iS)); - resRow.insert(std::make_pair(OTT::indFC(iS),val)); - } - } - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx deleted file mode 100644 index b4380b164..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PlanarIntersectorP0P1Bary_HXX__ -#define __PlanarIntersectorP0P1Bary_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P1Bary : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeoBary(const std::vector& sourceCell, - bool sourceCellQuadratic, - const double * targetTria, - std::vector& res) - { return asLeaf().intersectGeoBary(sourceCell,sourceCellQuadratic,targetTria,res); } - protected: - ConcreteP0P1Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx deleted file mode 100644 index 66c34174a..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PlanarIntersectorP0P1Bary_TXX__ -#define __PlanarIntersectorP0P1Bary_TXX__ - -#include "PlanarIntersectorP0P1Bary.hxx" -#include "InterpolationUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P1Bary::PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, - double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, - medianPlane,doRotate,orientation,printLevel) - { - // SPEC: - // "Limitation. For the P0P1 barycentric improvement only triangle target cells in 2D and - // tetrahedrons in 3D will be supported by interpolators. If a non - // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." - - // Check types of source elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numTrgElems = meshT.getNumberOfElements(); - for(unsigned long i = 0 ; i < numTrgElems ; ++i) - if ( meshT.getTypeOfElement( OTT::indFC( i )) != NORM_TRI3 ) - throw INTERP_KERNEL::Exception("P0P1 barycentric algorithm works only with triangular target meshes"); - } - - template - int PlanarIntersectorP0P1Bary::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP0P1Bary::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - /*! - * This method computes a value per each node of each source triangle for target. - */ - template - void PlanarIntersectorP0P1Bary::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int orientation=1; - std::vector trgTriaCoords,trgTriaCoordsTmp; - // target cell data - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),trgTriaCoords); - std::vector *tgtCoords(&trgTriaCoords); - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - // treat each source cells - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - std::vector srcCellCoords,srcCellCoordsTmp,nodeCeffs; - int iS=*iter; - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(iS)); - bool isSourceQuad=CellModel::GetCellModel(tS).isQuadratic(); - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),srcCellCoords); - std::vector *srcCoords(&srcCellCoords); - int srcNbNodes = srcCellCoords.size()/SPACEDIM; - if(SPACEDIM==3) - { - srcCellCoordsTmp=srcCellCoords; - trgTriaCoordsTmp=trgTriaCoords; - srcCoords=&srcCellCoordsTmp; - tgtCoords=&trgTriaCoordsTmp; - orientation=PlanarIntersector::projectionThis(&trgTriaCoordsTmp[0],&srcCellCoordsTmp[0], - 3,srcNbNodes); - } - //double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); - double surf=orientation*intersectGeoBary(*srcCoords,isSourceQuad,&((*tgtCoords)[0]),nodeCeffs); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - for(int nodeIdT=0;nodeIdT<3;nodeIdT++) - { - ConnType curNodeT=startOfCellNodeConn[nodeIdT]; - typename MyMatrix::value_type& resRow=res[curNodeT]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(*iter); - if(iterRes!=resRow.end()) - { - nodeCeffs[*iter] += iterRes->second; - resRow.erase(*iter); - } - resRow.insert(std::make_pair(*iter,nodeCeffs[nodeIdT])); - } - } - } - } -} -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx deleted file mode 100644 index d04e2da59..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP0P1PL_HXX__ -#define __PLANARINTERSECTORP0P1PL_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P1PL : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx deleted file mode 100644 index abb6cd8c5..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP0P1PL_TXX__ -#define __PLANARINTERSECTORP0P1PL_TXX__ - -#include "PlanarIntersectorP0P1PL.hxx" -#include "PlanarIntersector.txx" -#include "CellModel.hxx" - -#include "PointLocatorAlgos.txx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P1PL::PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, - double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) - { - } - - template - void PlanarIntersectorP0P1PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector< std::vector > coordsOfSources(icellsS.size()); - int ii=0; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++,ii++) - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(*iter),coordsOfSources[ii]); - const ConnType *startOfCellNodeConnT=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - std::vector coordsTarget; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),coordsTarget); - int nbNodesT=coordsTarget.size()/SPACEDIM; - ii=0; - for(typename std::vector::const_iterator iter2=icellsS.begin();iter2!=icellsS.end();iter2++,ii++) - { - std::vector tmpSource(coordsOfSources[ii]); - std::vector tmpTarget(coordsTarget); - if(SPACEDIM==3) - PlanarIntersector::projectionThis(&tmpSource[0],&tmpTarget[0],tmpSource.size()/SPACEDIM,nbNodesT); - for(int nodeIdT=0;nodeIdT::isElementContainsPointAlg2D(&tmpTarget[0]+nodeIdT*SPACEDIM,&tmpSource[0],tmpSource.size()/SPACEDIM,PlanarIntersector::_precision)) - { - ConnType curNodeTInCmode=OTT::coo2C(startOfCellNodeConnT[nodeIdT]); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iter2)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(*iter2),1.)); - } - } - } - } - - template - int PlanarIntersectorP0P1PL::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP0P1PL::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx deleted file mode 100644 index f351143a4..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP1P0_HXX__ -#define __PLANARINTERSECTORP1P0_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P0 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } - protected: - ConcreteP1P0Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx deleted file mode 100644 index 60617aee6..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP1P0_TXX__ -#define __PLANARINTERSECTORP1P0_TXX__ - -#include "PlanarIntersectorP1P0.hxx" -#include "InterpolationUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P0::PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP1P0::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int PlanarIntersectorP1P0::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } - - /*! - * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). - */ - template - void PlanarIntersectorP1P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - double triangle[9]; - double quadrangle[12]; - std::vector targetCellCoords; - int orientation=1; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),targetCellCoords); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(OTT::indFC(icellT)); - bool isTargetQuad=CellModel::GetCellModel(tT).isQuadratic(); - typename MyMatrix::value_type& resRow=res[icellT]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); - for(int nodeIdS=0;nodeIdS::coo2C(startOfCellNodeConn[nodeIdS]); - std::copy(PlanarIntersector::_coordsS+curNodeSInCmode*SPACEDIM, - PlanarIntersector::_coordsS+curNodeSInCmode*SPACEDIM+SPACEDIM,triangle); - for(int subTriS=1;subTriS<=nbNodesS-2;subTriS++) - { - std::copy(PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM, - PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM+SPACEDIM, - triangle+SPACEDIM); - std::copy(PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM, - PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM+SPACEDIM, - triangle+2*SPACEDIM); - fillDualCellOfTri(triangle,quadrangle); - std::vector targetCellCoordsTmp(targetCellCoords); - if(SPACEDIM==3) - orientation=PlanarIntersector::projectionThis(&targetCellCoordsTmp[0],quadrangle,targetCellCoords.size()/SPACEDIM,4); - double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),surf)); - else - { - double val=(*iterRes).second+surf; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx deleted file mode 100644 index ede9dc76f..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PlanarIntersectorP1P0Bary_HXX__ -#define __PlanarIntersectorP1P0Bary_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P0Bary : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { return asLeaf().intersectGeoBary(targetCell,targetCellQuadratic,sourceTria,res); } - protected: - ConcreteP1P0Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx deleted file mode 100644 index ae0b94f51..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PlanarIntersectorP1P0Bary_TXX__ -#define __PlanarIntersectorP1P0Bary_TXX__ - -#include "PlanarIntersectorP1P0Bary.hxx" -#include "InterpolationUtils.hxx" - -#define PLAN_INTERSECTOR PlanarIntersectorP1P0Bary -#define PLAN_INTER_TEMPLATE template - -namespace INTERP_KERNEL -{ - PLAN_INTER_TEMPLATE - PLAN_INTERSECTOR::PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, - double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, - medianPlane,doRotate,orientation,printLevel) - { - // SPEC: - // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and - // tetrahedrons in 3D will be supported by interpolators. If a non - // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." - - // Check types of source elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numSrcElems = meshS.getNumberOfElements(); - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - if ( meshS.getTypeOfElement( OTT::indFC( i )) != NORM_TRI3 ) - throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with triangular source meshes"); - } - - PLAN_INTER_TEMPLATE - int PLAN_INTERSECTOR::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - PLAN_INTER_TEMPLATE - int PLAN_INTERSECTOR::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } - - /*! - * This method computes a value per each node of each source triangle for target. - */ - PLAN_INTER_TEMPLATE - void PLAN_INTERSECTOR::intersectCells(ConnType icellT, - const std::vector& icellsS, - MyMatrix& res) - { - int orientation=1; - std::vector srcTriaCoords, tgtCellCoords, tgtCellCoordsTmp, nodeCeffs; - - // target cell data - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),tgtCellCoords); - std::vector * tgtCoords = & tgtCellCoords; - int tgtNbNodes = tgtCellCoords.size()/SPACEDIM; - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(OTT::indFC(icellT)); - bool isTargetQuad=CellModel::GetCellModel(tT).isQuadratic(); - - typename MyMatrix::value_type& resRow=res[icellT]; - - // treat each source triangle - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),srcTriaCoords); - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); - if(SPACEDIM==3) - { - tgtCellCoordsTmp = tgtCellCoords; - tgtCoords = & tgtCellCoordsTmp; - orientation=PlanarIntersector::projectionThis(&tgtCellCoordsTmp[0], &srcTriaCoords[0], - tgtNbNodes, 3); - } - //double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); - double surf=orientation*intersectGeoBary( *tgtCoords, isTargetQuad, &srcTriaCoords[0], nodeCeffs ); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - for(int nodeIdS=0;nodeIdS<3;nodeIdS++) - { - ConnType curNodeS=startOfCellNodeConn[nodeIdS]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS); - if(iterRes!=resRow.end()) - { - nodeCeffs[nodeIdS] += iterRes->second; - resRow.erase( curNodeS ); - } - resRow.insert(std::make_pair(curNodeS,nodeCeffs[nodeIdS])); - } - } - } - } -} -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx deleted file mode 100644 index 47e9121cb..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP1P0PL_HXX__ -#define __PLANARINTERSECTORP1P0PL_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P0PL : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx deleted file mode 100644 index c86fa2c50..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP1P0PL_TXX__ -#define __PLANARINTERSECTORP1P0PL_TXX__ - -#include "PlanarIntersectorP1P0PL.hxx" -#include "PlanarIntersector.txx" -#include "CellModel.hxx" - -#include "PointLocatorAlgos.txx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P0PL::PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, - double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) - { - } - - template - void PlanarIntersectorP1P0PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector CoordsT; - typename MyMatrix::value_type& resRow=res[icellT]; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),CoordsT); - double baryT[SPACEDIM]; - double baryTTmp[SPACEDIM]; - calculateBarycenterDyn2(&CoordsT[0],CoordsT.size()/SPACEDIM,baryT); - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(*iter)); - if(tS!=NORM_TRI3) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==2. Only TRI3 supported !"); - std::vector CoordsS; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(*iter),CoordsS); - if(SPACEDIM==2) - { - std::copy(baryT,baryT+SPACEDIM,baryTTmp); - } - else - { - double littleTargetCell[9]; - std::copy(baryT,baryT+SPACEDIM,littleTargetCell); - std::copy(CoordsT.begin(),CoordsT.begin()+3,littleTargetCell+3); - std::copy(CoordsT.begin()+3,CoordsT.begin()+6,littleTargetCell+6); - PlanarIntersector::projectionThis(&CoordsS[0],littleTargetCell,3,3); - std::copy(littleTargetCell,littleTargetCell+3,baryTTmp); - } - if(PointLocatorAlgos::isElementContainsPointAlg2D(baryTTmp,&CoordsS[0],3,PlanarIntersector::_precision)) - { - double resLoc[3]; - barycentric_coords(&CoordsS[0],baryTTmp,resLoc); - const ConnType *startOfCellNodeConnS=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[*iter]); - for(int nodeIdS=0;nodeIdS<3;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>PlanarIntersector::_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } - - template - int PlanarIntersectorP1P0PL::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int PlanarIntersectorP1P0PL::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx deleted file mode 100644 index 6c8cb310a..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP1P1_HXX__ -#define __PLANARINTERSECTORP1P1_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P1 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords) { return asLeaf().intersectGeometryGeneral(targetCoords,sourceCoords); } - protected: - ConcreteP1P1Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx deleted file mode 100644 index af1914139..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP1P1_TXX__ -#define __PLANARINTERSECTORP1P1_TXX__ - -#include "PlanarIntersectorP1P1.hxx" -#include "InterpolationUtils.hxx" -#include "CellModel.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P1::PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP1P1::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP1P1::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } - - /*! - * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). - */ - template - void PlanarIntersectorP1P1::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - int orientation=1; - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - std::vector polygT; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),polygT); - for(int nodeIdT=0;nodeIdT::coo2C(startOfCellNodeConn[nodeIdT]); - PlanarIntersector::getRealTargetCoordinatesPermute(OTT::indFC(icellT),nodeIdT,polygT); - std::vector polygDualT(SPACEDIM*2*(nbNodesT-1)); - fillDualCellOfPolyg(&polygT[0],polygT.size()/SPACEDIM,&polygDualT[0]); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - const ConnType *startOfCellNodeConnS=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); - for(int nodeIdS=0;nodeIdS::coo2C(startOfCellNodeConnS[nodeIdS]); - std::vector polygS; - PlanarIntersector::getRealSourceCoordinatesPermute(OTT::indFC(iS),nodeIdS,polygS); - std::vector polygDualS(SPACEDIM*2*(nbNodesS-1)); - fillDualCellOfPolyg(&polygS[0],polygS.size()/SPACEDIM,&polygDualS[0]); - std::vector polygDualTTmp(polygDualT); - if(SPACEDIM==3) - orientation=PlanarIntersector::projectionThis(&polygDualS[0],&polygDualTTmp[0],polygDualS.size()/SPACEDIM,polygDualT.size()/SPACEDIM); - double surf=orientation*intersectGeometryGeneral(polygDualTTmp,polygDualS); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),surf)); - else - { - double val=(*iterRes).second+surf; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx deleted file mode 100644 index 226d89e32..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PLANARINTERSECTORP1P1PL_HXX__ -#define __PLANARINTERSECTORP1P1PL_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P1PL : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx b/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx deleted file mode 100644 index aa36f5cfe..000000000 --- a/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PLANARINTERSECTORP1P1PL_TXX__ -#define __PLANARINTERSECTORP1P1PL_TXX__ - -#include "PlanarIntersectorP1P1PL.hxx" -#include "PlanarIntersector.txx" -#include "CellModel.hxx" - -#include "PointLocatorAlgos.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P1PL::PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, - double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) - { - } - - template - void PlanarIntersectorP1P1PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector CoordsT; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),CoordsT); - int nbOfNodesT=CoordsT.size()/SPACEDIM; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(*iter)); - if(tS!=NORM_TRI3) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==2. Only TRI3 supported !"); - std::vector CoordsS; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(*iter),CoordsS); - std::vector CoordsTTmp(CoordsT); - if(SPACEDIM==3) - PlanarIntersector::projectionThis(&CoordsS[0],&CoordsTTmp[0],CoordsS.size()/SPACEDIM,nbOfNodesT); - const ConnType *startOfCellNodeConnT=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - for(int nodeIdT=0;nodeIdT::ind2C(startOfCellNodeConnT[nodeIdT])]; - if( PointLocatorAlgos::isElementContainsPointAlg2D(&CoordsTTmp[nodeIdT*SPACEDIM],&CoordsS[0],3,PlanarIntersector::_precision) ) - { - double resLoc[3]; - barycentric_coords(&CoordsS[0],&CoordsTTmp[nodeIdT*SPACEDIM],resLoc); - const ConnType *startOfCellNodeConnS=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[*iter]); - for(int nodeIdS=0;nodeIdS<3;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>PlanarIntersector::_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } - } - - template - int PlanarIntersectorP1P1PL::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP1P1PL::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.hxx b/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.hxx deleted file mode 100644 index 51251c3ec..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POINTLOCATORINTERSECTOR_HXX__ -#define __POINTLOCATORINTERSECTOR_HXX__ - -#include "PlanarIntersectorP0P0.hxx" -#include "PlanarIntersectorP0P1.hxx" -#include "PlanarIntersectorP1P0.hxx" -#include "PlanarIntersectorP1P1.hxx" -#include "PlanarIntersectorP1P0Bary.hxx" - -namespace INTERP_KERNEL -{ - class QuadraticPolygon; - - template class InterpType> - class PointLocator2DIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - private: - QuadraticPolygon *buildPolygonFrom(const std::vector& coords, NormalizedCellType type); - QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.txx b/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.txx deleted file mode 100644 index 0f83435c6..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.txx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POINTLOCATORINTERSECTOR_TXX__ -#define __POINTLOCATORINTERSECTOR_TXX__ - -#include "PointLocator2DIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P1.txx" -#include "PlanarIntersectorP1P0Bary.txx" -#include "CellModel.hxx" - -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "PointLocatorAlgos.txx" - -#define PTLOC2D_INTERSECTOR PointLocator2DIntersector -#define INTERSECTOR_TEMPLATE template class InterpType> - -namespace INTERP_KERNEL -{ - INTERSECTOR_TEMPLATE - PTLOC2D_INTERSECTOR::PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, - double precision, int orientation): - InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) - { - } - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - int orientation = 1; - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); - QuadraticPolygon *pT=buildPolygonFrom(CoordsT,tT); - double baryT[SPACEDIM]; - pT->getBarycenterGeneral(baryT); - delete pT; - if(PointLocatorAlgos::isElementContainsPointAlg2D(baryT,&CoordsS[0],nbNodesS,InterpType::_precision)) - return 1.; - return 0.; - } - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, - const std::vector& sourceCoords, - bool isSourceQuad) - { - int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; - std::vector nodes2(nbOfSourceNodes); - for(int i=0;igetBarycenter(bary); - delete p2; - if( PointLocatorAlgos::isElementContainsPointAlg2D(bary,quadrangle,4) ) - return 1.; - return 0.; - } - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeometryGeneral(const std::vector& targetCoords, - const std::vector& sourceCoords) - { - int nbOfTargetNodes=targetCoords.size()/SPACEDIM; - int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; - std::vector nodes2(nbOfSourceNodes); - for(int i=0;igetBarycenterGeneral(bary); - delete p; - if( PointLocatorAlgos::isElementContainsPointAlg2D(bary,&targetCoords[0],nbOfTargetNodes) ) - return 1.; - return 0.; - } - - //================================================================================ - /*! - * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm - * \param targetCell - list of coordinates of target polygon in full interlace - * \param targetCellQuadratic - specifies if target polygon is quadratic or not - * \param sourceTria - list of coordinates of source triangle - * \param res - coefficients a,b and c associated to nodes of sourceTria - */ - //================================================================================ - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { - throw INTERP_KERNEL::Exception("intersectGeoBary incompatible with PointLocator. Desactivate P1P0Bary to avoid the problem"); - return 0.; - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonFrom(const std::vector& coords, NormalizedCellType type) - { - int nbNodes=coords.size()/SPACEDIM; - std::vector nodes(nbNodes); - for(int i=0;i::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsT+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - if(CellModel::GetCellModel(type).isQuadratic()) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) - { - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsS+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - if(type!=NORM_TRI6 && type!=NORM_QUAD8) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx deleted file mode 100644 index 54b46415d..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POINTLOCATOR3DINTERSECTORP0P0_HXX__ -#define __POINTLOCATOR3DINTERSECTORP0P0_HXX__ - -#include "Intersector3DP0P0.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP0P0 : public Intersector3DP0P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP0P0(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx deleted file mode 100644 index 197e644dd..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POINTLOCATOR3DINTERSECTORP0P0_TXX__ -#define __POINTLOCATOR3DINTERSECTORP0P0_TXX__ - -#include "PointLocator3DIntersectorP0P0.hxx" -#include "Intersector3DP0P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" -#include "PointLocatorAlgos.txx" - -namespace INTERP_KERNEL -{ - - /** - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PointLocator3DIntersectorP0P0::PointLocator3DIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP0P0(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP0P0::~PointLocator3DIntersectorP0P0() - { - } - - /** - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PointLocator3DIntersectorP0P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - Intersector3DP0P0::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - double bary[SPACEDIM]; - calculateBarycenterDyn2(&CoordsT[0],CoordsT.size()/SPACEDIM,bary); - typename MyMatrix::value_type& resRow=res[targetCell]; - const double *coordsS=Intersector3DP0P0::_src_mesh.getCoordinatesPtr(); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP0P0::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - std::vector connOfCurCellS; - Intersector3DP0P0::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if(PointLocatorAlgos::isElementContainsPointAlg3D(bary,&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision)) - { - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),1)); - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx deleted file mode 100644 index a7eb4fc19..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POINTLOCATOR3DINTERSECTORP0P1_HXX__ -#define __POINTLOCATOR3DINTERSECTORP0P1_HXX__ - -#include "Intersector3DP0P1.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP0P1 : public Intersector3DP0P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP0P1(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx deleted file mode 100644 index 0b0e68eeb..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POINTLOCATOR3DINTERSECTORP0P1_TXX__ -#define __POINTLOCATOR3DINTERSECTORP0P1_TXX__ - -#include "PointLocator3DIntersectorP0P1.hxx" -#include "Intersector3DP0P1.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PointLocator3DIntersectorP0P1::PointLocator3DIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP0P1(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP0P1::~PointLocator3DIntersectorP0P1() - { - } - - /** - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PointLocator3DIntersectorP0P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector coordsTarget; - Intersector3DP0P1::getRealTargetCoordinates(OTT::indFC(targetCell),coordsTarget); - int nbNodesT=coordsTarget.size()/SPACEDIM; - const double *coordsS=Intersector3DP0P1::_src_mesh.getCoordinatesPtr(); - const ConnType *startOfCellNodeConnT=Intersector3DP0P1::getStartConnOfTargetCell(targetCell); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP0P1::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - std::vector connOfCurCellS; - Intersector3DP0P1::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - for(int nodeIdT=0;nodeIdT::isElementContainsPointAlg3D(&coordsTarget[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision)) - { - ConnType curNodeTInCmode=OTT::coo2C(startOfCellNodeConnT[nodeIdT]); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iterCellS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),1.)); - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx deleted file mode 100644 index 012dc28c2..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POINTLOCATOR3DINTERSECTORP1P0_HXX__ -#define __POINTLOCATOR3DINTERSECTORP1P0_HXX__ - -#include "Intersector3DP1P0.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP1P0 : public Intersector3DP1P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP1P0(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx deleted file mode 100644 index e611b8bee..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POINTLOCATOR3DINTERSECTORP1P0_TXX__ -#define __POINTLOCATOR3DINTERSECTORP1P0_TXX__ - -#include "PointLocator3DIntersectorP1P0.hxx" -#include "Intersector3DP1P0.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - /** - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - * - * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. - */ - template - PointLocator3DIntersectorP1P0::PointLocator3DIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision):Intersector3DP1P0(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP1P0::~PointLocator3DIntersectorP1P0() - { - } - - /** - * @param targetCell in C mode. - * @param srcCells in C mode. - * - * WARNING : for all methods on _split object source and target are switched ! - */ - template - void PointLocator3DIntersectorP1P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - typename MyMatrix::value_type& resRow=res[targetCell]; - const double *coordsS=Intersector3DP1P0::_src_mesh.getCoordinatesPtr(); - Intersector3DP1P0::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - double baryT[SPACEDIM]; - calculateBarycenterDyn2(&CoordsT[0],CoordsT.size()/SPACEDIM,baryT); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP1P0::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - if(tS!=NORM_TETRA4) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - std::vector connOfCurCellS; - Intersector3DP1P0::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if( PointLocatorAlgos::isElementContainsPointAlg3D(baryT,&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) - { - double resLoc[4]; - std::vector srcCell; - Intersector3DP1P0::getRealSourceCoordinates(OTT::indFC(*iterCellS),srcCell); - std::vector eap(4); - eap[0]=&srcCell[0]; eap[1]=&srcCell[3]; eap[2]=&srcCell[6]; eap[3]=&srcCell[9]; - barycentric_coords(eap,baryT,resLoc); - const ConnType *startOfCellNodeConn=Intersector3DP1P0::getStartConnOfSourceCell(*iterCellS); - for(int nodeIdS=0;nodeIdS<4;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConn[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx deleted file mode 100644 index 6eb18993f..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POINTLOCATOR3DINTERSECTORP1P1_HXX__ -#define __POINTLOCATOR3DINTERSECTORP1P1_HXX__ - -#include "Intersector3DP1P1.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP1P1 : public Intersector3DP1P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP1P1(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx b/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx deleted file mode 100644 index ddc9c41b8..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POINTLOCATOR3DINTERSECTORP1P1_TXX__ -#define __POINTLOCATOR3DINTERSECTORP1P1_TXX__ - -#include "PointLocator3DIntersectorP1P1.hxx" -#include "Intersector3DP1P1.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PointLocator3DIntersectorP1P1::PointLocator3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP1P1(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP1P1::~PointLocator3DIntersectorP1P1() - { - } - - /** - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void PointLocator3DIntersectorP1P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - Intersector3DP1P1::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - int nbOfNodesT=CoordsT.size()/SPACEDIM; - const double *coordsS=Intersector3DP1P1::_src_mesh.getCoordinatesPtr(); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP1P1::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - if(tS!=NORM_TETRA4) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - const ConnType *startOfCellNodeConnT=Intersector3DP1P1::getStartConnOfTargetCell(targetCell); - for(int nodeIdT=0;nodeIdT::ind2C(startOfCellNodeConnT[nodeIdT])]; - std::vector connOfCurCellS; - Intersector3DP1P1::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if( PointLocatorAlgos::isElementContainsPointAlg3D(&CoordsT[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) - { - double resLoc[4]; - std::vector localCoordsS; - Intersector3DP1P1::getRealSourceCoordinates(OTT::indFC(*iterCellS),localCoordsS); - std::vector eap(4); - eap[0]=&localCoordsS[0]; eap[1]=&localCoordsS[3]; eap[2]=&localCoordsS[6]; eap[3]=&localCoordsS[9]; - barycentric_coords(eap,&CoordsT[nodeIdT*SPACEDIM],resLoc); - const ConnType *startOfCellNodeConnS=Intersector3DP1P1::getStartConnOfSourceCell(*iterCellS); - for(int nodeIdS=0;nodeIdS<4;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PointLocatorAlgos.txx b/medtool/src/INTERP_KERNEL/PointLocatorAlgos.txx deleted file mode 100644 index 8a59aed65..000000000 --- a/medtool/src/INTERP_KERNEL/PointLocatorAlgos.txx +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POINTLOCATORALGOS_TXX__ -#define __POINTLOCATORALGOS_TXX__ - -#include "InterpolationUtils.hxx" -#include "CellModel.hxx" -#include "BBTree.txx" - -#include -#include -#include - -namespace INTERP_KERNEL -{ - class GenericPointLocatorAlgos - { - public: - virtual ~GenericPointLocatorAlgos() { } - virtual std::list locates(const double* x, double eps) = 0; - }; - - template - class PointLocatorAlgos: public GenericPointLocatorAlgos - { - private : - double* _bb; - BBTree* _tree; - const MyMeshType& _mesh; - public: - PointLocatorAlgos(const MyMeshType& mesh):_mesh(mesh) - { - typedef typename MyMeshType::MyConnType ConnType; - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - const NumberingPolicy numPol=MyMeshType::My_numPol; - int nelem = _mesh.getNumberOfElements(); - _bb = new double[SPACEDIM*2*nelem]; - const ConnType* conn = _mesh.getConnectivityPtr(); - const ConnType* conn_index = _mesh.getConnectivityIndexPtr(); - const double* coords=_mesh.getCoordinatesPtr(); - for (int i=0; i::max(); - _bb[2*(i*SPACEDIM+idim)+1]=-std::numeric_limits::max(); - } - for (int index= conn_index[i]; index < conn_index[i+1];index++) - { - //coordelem points to the coordinates of the current node of the i-th element - const double* coordelem = coords+OTT::ind2C(conn[OTT::ind2C(index)])*SPACEDIM; - - //the bounding box is updated by checking wheher the node is at the min/max in exach dimension - for (int idim=0; idim_bb[2*(i*SPACEDIM+idim)+1])?coordelem[idim]:_bb[2*(i*SPACEDIM+idim)+1]; - } - } - } - _tree=new BBTree(_bb,0,0,nelem); - } - - ~PointLocatorAlgos() - { - delete[] _bb; - delete _tree; - } - - //returns the list of elements that contains - //the point pointed to by x - std::list locates(const double* x, double eps) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - std::vector candidates; - _tree->getElementsAroundPoint(x,candidates); - std::list retlist; - for(unsigned int i=0; i< candidates.size(); i++) - { - int ielem=candidates[i]; - if (elementContainsPoint(ielem,x,eps)) - retlist.push_back(OTT::indFC(ielem)); - } - return retlist; - } - - static bool isElementContainsPointAlg2D(const double *ptToTest, const double *cellPts, int nbEdges, double eps) - { - /* with dimension 2, it suffices to check all the edges - and see if the sign of double products from the point - is always the same. - C - / \ - / \ - Xo / \ - A-------B - - here XA^XC and XC^XB have different signs*/ - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - int* sign = new int[nbEdges]; - for (int iedge=0; iedgeeps) - sign[iedge]=1; - else - sign[iedge]=0; - } - bool ret=decideFromSign(sign, nbEdges); - delete [] sign; - return ret; - } - - static bool isElementContainsPointAlg3D(const double *ptToTest, const typename MyMeshType::MyConnType *conn_elem, int conn_elem_sz, const double *coords, const CellModel& cmType, double eps) - { - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - - int nbfaces = cmType.getNumberOfSons2(conn_elem,conn_elem_sz); - int *sign = new int[nbfaces]; - int *connOfSon = new int[conn_elem_sz]; - for (int iface=0; iface::coo2C(connOfSon[0])); - const double* BB=coords+SPACEDIM*(OTT::coo2C(connOfSon[1])); - const double* CC=coords+SPACEDIM*(OTT::coo2C(connOfSon[2])); - double Vol=triple_product(AA,BB,CC,ptToTest); - if (Vol<-eps) - sign[iface]=-1; - else if (Vol>eps) - sign[iface]=1; - else - sign[iface]=0; - } - bool ret=decideFromSign(sign, nbfaces); - delete [] sign; - delete [] connOfSon; - return ret; - } - - static bool isElementContainsPoint(const double *ptToTest, NormalizedCellType type, const double *coords, const typename MyMeshType::MyConnType *conn_elem, int conn_elem_sz, double eps) - { - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - - const CellModel& cmType=CellModel::GetCellModel(type); - // - if (SPACEDIM==2) - { - int nbEdges=cmType.getNumberOfSons(); - double *pts = new double[nbEdges*SPACEDIM]; - for (int iedge=0; iedge::ind2C(conn_elem[iedge])); - std::copy(a,a+SPACEDIM,pts+iedge*SPACEDIM); - } - bool ret=isElementContainsPointAlg2D(ptToTest,pts,nbEdges,eps); - delete [] pts; - return ret; - } - - if (SPACEDIM==3) - { - return isElementContainsPointAlg3D(ptToTest,conn_elem,conn_elem_sz,coords,cmType,eps); - } - - if(SPACEDIM==1) - { - double p1=coords[(OTT::ind2C(conn_elem[0]))]; - double p2=coords[(OTT::ind2C(conn_elem[1]))]; - double delta=fabs(p1-p2)+eps; - double val=*ptToTest-std::min(p1,p2); - return val>-eps && val::ind2C(conn_index[i]); - int conn_elem_sz=conn_index[i+1]-conn_index[i]; - NormalizedCellType type=_mesh.getTypeOfElement(OTT::indFC(i)); - return isElementContainsPoint(x,type,coords,conn_elem,conn_elem_sz,eps); - } - - static bool decideFromSign(const int* sign, int nbelem) - { - int min_sign = 1; - int max_sign = -1; - for (int i=0; imax_sign)?sign[i]:max_sign; - } - return (min_sign!=-1 || max_sign!=1); - } - }; - - template - class PointLocatorInSimplex : public PointLocatorAlgos - { - const MyMeshType& _mesh; - public: - PointLocatorInSimplex(const MyMeshType& mesh) - :PointLocatorAlgos(mesh),_mesh(mesh) - { - } - - //================================================================================ - /*! - * \brief Returns nodes composing the simplex the point x is in - */ - //================================================================================ - - virtual std::list locates(const double* x, double eps) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - - std::list simplexNodes; - std::list candidates = PointLocatorAlgos::locates(x,eps); - std::list::iterator eIt = candidates.begin(); - for ( ; eIt != candidates.end(); ++eIt ) - { - const int i = OTT::ind2C( *eIt ); - const double* coords= _mesh.getCoordinatesPtr(); - const ConnType* conn=_mesh.getConnectivityPtr(); - const ConnType* conn_index= _mesh.getConnectivityIndexPtr(); - const ConnType* conn_elem=conn+OTT::ind2C(conn_index[i]); - int conn_elem_sz=conn_index[i+1]-conn_index[i]; - NormalizedCellType type=_mesh.getTypeOfElement(OTT::indFC(i)); - CellModel cell = CellModel::GetCellModel(type); - - if ( cell.isQuadratic() ) - throw Exception("P2 not implemented yet"); - - if ( cell.isSimplex()) - { - for ( int n = 0; n < conn_elem_sz; ++n ) - simplexNodes.push_back( conn_elem[ n ]); - } - else - { - NormalizedCellType simlexType = cell.getDimension()==3 ? NORM_TETRA4 : NORM_TRI3; - std::vector sonNodes; - NormalizedCellType sonType; - const unsigned nbSons = cell.getNumberOfSons2( conn_elem, conn_elem_sz ); - for ( unsigned s = 0; s < nbSons; ++s ) - { - sonNodes.resize( cell.getNumberOfNodesConstituentTheSon2( s, conn_elem, conn_elem_sz )); - cell.fillSonCellNodalConnectivity2( s, conn_elem, conn_elem_sz, &sonNodes[0], sonType ); - std::set sonNodesSet( sonNodes.begin(), sonNodes.end() ); - - std::set< std::set< ConnType > > checkedSonSimplex; - for ( unsigned sn = 0; sn < sonNodes.size(); ++sn ) - { - std::vector< ConnType > simplexConn( cell.getDimension() + 1 ); - unsigned n; - for ( n = 0; n < cell.getDimension()-1; ++n ) - simplexConn[n] = sonNodes[ (sn+n) % sonNodes.size() ]; - - for ( unsigned n2 = 0; n2 < sonNodes.size()-cell.getDimension()+1; ++n2 ) - { - simplexConn[n] = sonNodes[ (sn+n+n2) % sonNodes.size() ]; - std::set< ConnType > sonSimplex( simplexConn.begin(), --simplexConn.end()); - if ( checkedSonSimplex.insert( sonSimplex ).second ) - { - for ( unsigned cn = 0; cn < conn_elem_sz; ++cn ) - if ( !sonNodesSet.count( conn_elem[cn] )) - { - simplexConn.back() = conn_elem[cn]; - if ( this->isElementContainsPoint( x, simlexType, coords, - &simplexConn[0], simplexConn.size(), eps )) - { - simplexNodes.insert( simplexNodes.end(), - simplexConn.begin(), simplexConn.end()); - return simplexNodes; - } - } - } - } - } - } - } - } - return simplexNodes; - } - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx b/medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx deleted file mode 100644 index 5d9f9d818..000000000 --- a/medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __POLYGONALGORITHMS_HXX__ -#define __POLYGONALGORITHMS_HXX__ - -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - class VertexLess - { - public: - bool operator()(const double * P_1, const double * P_2) const - { - for(int idim=0; idim P_2[idim]) return false; - } - return false; - } - }; - - template - class PolygonAlgorithms - { - public: - PolygonAlgorithms(double epsilon, double precision); - std::deque intersectConvexPolygons(const double* P_1,const double* P_2, int N1, int N2); - - //Not yet tested - int convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, - std::vector< int >& components_index, const double epsilon); - private: - void defineIndices(int& i_loc, int& i_next, int& i_prev, - const double *& Poly1, const double *& Poly2, - int& j1, int& j1_glob, int& j2, int& j2_glob, - int& j3, int& j3_glob, int& j4, int& j4_glob, - int& i_glob, int& i_next_glob, int& i_prev_glob, - const double * P_1, const double * P_2, - int N1, int N2, int sign); - void addCrossings( const double * A, const double * B, int i , int i_next, - const double * C, const double * D, int j1, int j2, - const double * E, const double * F, int j3, int j4, - const double * G); - void addCrossing0(const double * A, const double * B, int i, int i_next, - const double * C, const double * D, int j, int j_next); - void addCrossing( double * ABCD, std::pair< int,int > i_i_next, std::pair< int,int > j_j_next); - void addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, const double * P); - bool intersectSegmentSegment(const double * A, const double * B, const double * C, - const double * D, const double * E, double * V); - - - //Not yet tested - void convexDecomposition(const double* P, int N, double* n, std::vector< int > subP, int NsubP, - std::vector< std::map< int,int > >& components, std::vector< int >& components_index, - int& Ncomp, int sign, const double epsilon); - void convHull(const double *P, int N, double * n, std::map< int,int >& subP, - std::map< int,int >& not_in_hull, int& NsubP, const double epsilon); - private: - std::deque< double > _Inter;/* vertices of the intersection P1^P2 */ - std::vector< std::pair< int,int > > _End_segments; /* segments containing inter final edges */ - /* status list of segments (ending point, starting point) intersected by the sweeping line */ - /* and a boolean true if the ending point is in the intersection */ - std::multimap< int, std::pair< int,bool> > _Status; - bool _is_in_intersection; - bool _terminus; - double _vdouble[DIM]; - double _epsilon; - double _precision; - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolygonAlgorithms.txx b/medtool/src/INTERP_KERNEL/PolygonAlgorithms.txx deleted file mode 100644 index cda3f5b1f..000000000 --- a/medtool/src/INTERP_KERNEL/PolygonAlgorithms.txx +++ /dev/null @@ -1,824 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __POLYGONALGORITHMS_TXX__ -#define __POLYGONALGORITHMS_TXX__ - -#include "PolygonAlgorithms.hxx" -#include "InterpolationUtils.hxx" -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - PolygonAlgorithms::PolygonAlgorithms(double epsilon, double precision)//: (0) - { - _is_in_intersection = false; - _epsilon = epsilon; - _precision = precision; - } - /*************************************************************/ - /* Computes the 3D intersection between two COPLANAR */ - /* Segments [A,B] and [C,D], stores the result in V. */ - /* If A belongs to [CD] then the vertex E (preceeding A) */ - /* is used to decide if the crossing is real. If A coincides */ - /* with C or D, a special treatment is performed */ - /*************************************************************/ - template - bool PolygonAlgorithms::intersectSegmentSegment(const double * A, const double * B, const double * C, - const double * D, const double * E, double * V) - { - double AB[DIM], DC[DIM], AC[DIM], det, t1, t2, inv_det; - - /******* Initialisation of the linear system t1*AB+t2*DC=AC ***********/ - for(int idim=0;idim_epsilon) - { - inv_det = 1/det; - t1 = determinant(AC,DC)*inv_det;//solves the linear system t1*AB+t2*DC=AC - t2 = determinant(AB,AC)*inv_det;//solves the linear system t1*AB+t2*DC=AC - } - else - { - switch(DIM) - { - case 2: - { - if(distance2(A,D)<_epsilon) - crossprod(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) - return false;//case of paralell segments - } - case 3://beware AB and CD may belong to a vertical plane - det = determinant(&AB[1],&DC[1]);//determinant of the last two coefficients - if(fabs(det) > _epsilon) - { - inv_det = 1/det; - t1=(AC[1]*DC[DIM-1]-AC[DIM-1]*DC[1])*inv_det; - t2=(AB[1]*AC[DIM-1]-AB[DIM-1]*AC[1])*inv_det; - } - else //beware AB and CD may belong to a plane y = constant - { - det = AB[0]*DC[DIM-1]-AB[DIM-1]*DC[0]; - if(fabs(det) > _epsilon) - { - inv_det = 1/det; - t1=(AC[0]*DC[DIM-1]-AC[DIM-1]*DC[0])*inv_det; - t2=(AB[0]*AC[DIM-1]-AB[DIM-1]*AC[0])*inv_det; - } - else - { - if(distance2(A,D)<_epsilon) - crossprod(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) - return false;//case of paralell segments - } - } - } - } - - if(t1>_precision && t1<1-_precision) - { - if( t2>_precision && t2<1-_precision) - { - for(int idim=0;idim_precision && t2<1-_precision)//vertex on an edge - { - double V12[DIM]; - double V34[DIM]; - crossprod(A,D,B,V12); - crossprod(A,D,E,V34); - double same_side =dotprod(V12, V34); - if( same_side < -_epsilon ) // <= epsilon or 0 ?//crossing - { - for(int idim=0;idim _epsilon ) _terminus= !_is_in_intersection;//reflexion - else //separation of overlaping edges - { - if(_Inter.empty() ) _terminus=true; - else if(!_is_in_intersection) - { - for(int idim=0;idim(A,C,E,_vdouble);//store the angle between vectors AC and AE (E=vertex preceding A) - else if(fabs(t2) <= _precision)//vertex on a vertex (A=C), second run - { - double Vdoublebis[DIM]; - //crossprod(A,C,E,_vdouble); - crossprod(A,B,D,Vdoublebis); - double in_between =dotprod(Vdoublebis,_vdouble); - if(in_between>_epsilon)//crossing - { - for(int idim=0;idim(Vdoublebis,Vdoublebis) > _epsilon) - //ie _vdouble=0, separation of overlaping edges at a double point - { - //crossprod(A,E,B,_vdouble); - if(dotprod(_vdouble,Vdoublebis) >=_epsilon )//crossing - { - if(_Inter.empty()) _terminus=true; - else if(!_is_in_intersection) - { - for(int idim=0;idim - inline void PolygonAlgorithms::addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, - const double * P) - { - /* Question:Should we add vertex i to the front or back ? */ - if( _End_segments[1].second == i_glob) - { - for(int idim=0;idim-1;idim--) _Inter.push_front(P[DIM*i+idim]); - _End_segments[0] = std::make_pair(i_glob, i_next_glob); - } - } - - /************************************************************/ - /* adds a crossing between two segments starting at i and j */ - /* to the double ended list inter in the correct order */ - /* according to endsegments, updates _End_segments */ - /************************************************************/ - template - inline void PolygonAlgorithms::addCrossing( double * ABCD, std::pair< int,int > i_i_next, - std::pair< int,int > j_j_next) - { - if(!_Inter.empty() ) - { - if(_End_segments[0] ==i_i_next) - { - for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); - _terminus= (_End_segments[1]== j_j_next); - _End_segments[0] = j_j_next; - } - else - { - if( _End_segments[0]== j_j_next) - { - for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); - _terminus= (_End_segments[1]== i_i_next); - _End_segments[0] = i_i_next; - } - else - { - for(int idim=0;idim - void PolygonAlgorithms::addCrossing0(const double * A, const double * B, int i, int i_next, - const double * C, const double * D, int j, int j_next) - { - double ABCD[DIM]; - if(intersectSegmentSegment(A,B,C,D,ABCD, ABCD)) - //fifth and sixth arguments are useless here - { - /* Updating _End_segments */ - std::pair< int,int > i_i_next = std::make_pair(i, i_next); - std::pair< int,int > j_j_next = std::make_pair(j, j_next); - if( _End_segments[0] == i_i_next) - { - for(int idim=DIM-1;idim>-1;idim--) _Inter.push_front(ABCD[idim]); - _End_segments[0] = j_j_next; - } - else - { - for(int idim=0;idim >::iterator mi =_Status.find(j_next); - ((* mi).second).second= !((* mi).second).second; - } - else _Status.insert(std::make_pair(i_next,std::make_pair(i,true))); - } - - /*******************************************************/ - /* adds the possible crossings between segments [A,B] (with end-point global indices i and i_next) */ - /*and segments [C,D] and [E,F] to the list inter and updates _End_segments */ - /* In cases of ambiguity, the vertex G is used to decide wether the crossing should be accepted */ - /*******************************************************/ - template - inline void PolygonAlgorithms::addCrossings( const double * A, const double * B, int i , int i_next, - const double * C, const double * D, int j1, int j2, - const double * E, const double * F, int j3, int j4, - const double * G) - { - double ABCD[DIM]; - double ABEF[DIM]; - std::multimap< int, std::pair< int,bool> >::iterator mi; - - if(intersectSegmentSegment(A,B,C,D,G,ABCD)) - { - if(intersectSegmentSegment(A,B,E,F,G,ABEF)) - { - VertexLess vl; - if (vl(ABCD,ABEF)) - { - addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); - addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); - } - else - { - addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); - addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); - } - _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); - mi=_Status.find(j2); - ((* mi).second).second= !((* mi).second).second; - mi=_Status.find(j4); - ((* mi).second).second= !((* mi).second).second; - } - else - { - addCrossing(ABCD, std::make_pair( i, i_next), std::make_pair(j1,j2)); - _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); - mi=_Status.find(j2); - ((* mi).second).second= !((* mi).second).second; - } - } - else - { - if(intersectSegmentSegment(A,B,E,F,G, ABEF)) - { - addCrossing(ABEF, std::make_pair( i, i_next), std::make_pair( j3, j4)); - _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); - mi=_Status.find(j4); - ((* mi).second).second= !((* mi).second).second; - } - else _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); - } - } - - - /* define various indices required in the function intersect_conv_polygon */ - /* vertices from the both polygons are supposed to be present in the status */ - template - inline void PolygonAlgorithms::defineIndices(int& i_loc, int& i_next, int& i_prev, - const double *& Poly1, const double *& Poly2, - int& j1, int& j1_glob, int& j2, int& j2_glob, - int& j3, int& j3_glob, int& j4, int& j4_glob, - int& i_glob, int& i_next_glob, int& i_prev_glob, - const double * P_1, const double * P_2, - int N1, int N2, int sign) - { - int N0, shift; - if(i_glob < N1) - { - N0 = N1; - shift = 0; - Poly1 = P_1; - Poly2 = P_2; - - std::multimap< int, std::pair< int,bool> >::reverse_iterator mi1=_Status.rbegin(); - j1_glob=((*mi1).second).first; - j1=j1_glob-N1; - j2_glob=(*mi1).first; - j2=j2_glob-N1; - mi1++; - j3_glob=((*mi1).second).first; - j3=j3_glob-N1; - j4_glob=(*mi1).first; - j4=j4_glob-N1; - } - else - { - N0 = N2; - shift = N1; - Poly1 = P_2; - Poly2 = P_1; - - std::multimap< int, std::pair< int,bool> >::iterator mi2= _Status.begin(); - j1_glob=((*mi2).second).first; - j1=j1_glob; - j2_glob=(*mi2).first; - j2=j2_glob; - mi2++; - j3_glob=((*mi2).second).first; - j3=j3_glob; - j4_glob=(*mi2).first; - j4=j4_glob; - } - i_loc = i_glob-shift; - i_next = (i_next_glob-shift+N0)%N0;//end-point of segment starting at i - i_prev = (i_prev_glob-shift+N0)%N0; - i_next_glob = i_next+shift; - i_prev_glob = i_prev+shift; - //warning: sign is either 1 or -1; - //To do: test and remove from Convex_intersecor.cxx - // while(distance2(&Poly1[DIM*i_loc],&Poly1[DIM*i_next])< _epsilon && i_next != i_loc) - // i_next =(i_next+sign+N0)%N0; - // while(distance2(&Poly1[DIM*i_loc],&Poly1[DIM*i_prev])< _epsilon && i_prev != i_loc) - // i_prev =(i_prev+sign+N0)%N0; - } - /*******************************************************/ - /* computes the vertices of the intersection of two COPLANAR */ - /* simple (no dble points)convex polygons using line sweep algorithm */ - /* P1 and P2 contain the 3D coordinates of the successive vertices */ - /*******************************************************/ - template - std::deque< double > PolygonAlgorithms::intersectConvexPolygons(const double* P_1,const double* P_2, - int N1, int N2) - { - int i_loc, i_glob, j1, j1_glob, j2,j2_glob, j3, j3_glob, j4,j4_glob, - i_prev, i_prev_glob, i_next, i_next_glob, nb_prev, sign, idim; - const double * Poly1, * Poly2; - bool four_neighbours=false; - _terminus = N1 < 3 || N2<3; - - /* list of future events ordered according to their coordinates (x,y,z) (lexicographical order) */ - std::multimap< const double *, int, VertexLess > mmap_events; - typename std::list< std::pair< const double *, int > >::iterator mi1,mi2; - - std::multimap< int, std::pair< int,bool> >::iterator mi; - - /********** Initalisation of events with P1 and P2 vertices ************/ - for(i_loc=0;i_loc > events(mmap_events.begin(),mmap_events.end()); - - if(!_terminus) - { - /******** Treatment of the first vertex ********/ - mi1=events.begin(); - i_glob = (* mi1).second; - bool which_start = i_glob < N1; - if(i_glob < N1){ i_next_glob = (i_glob +1)%N1; i_prev_glob = (i_glob -1+N1)%N1;} - else{ i_next_glob = (i_glob-N1+1)%N2 + N1;i_prev_glob = (i_glob-N1-1+N2)%N2 + N1;} - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); - mi1++; - //std::cout<< "nb_prev= "<< 0 << " i_glob= " << i_glob << std::endl; - - /******* Loop until the second polygon is reached *******/ - while( !four_neighbours) - { - i_glob=(* mi1).second;//global index of vertex i - nb_prev = _Status.count(i_glob);//counts the number of segments ending at i - - //std::cout<< "nb_prev= "<< nb_prev << " i_glob= " << i_glob << std::endl; - switch (nb_prev) - { - case 1 : - mi=_Status.find(i_glob);// pointer to the segment ending at i - i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i - i_next= (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? i_glob - 1 : i_glob + 1; - if(i_glob < N1) i_next_glob = (i_next +N1)%N1; - else i_next_glob = (i_next-N1+N2)%N2 + N1; - _Status.erase(mi); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - mi1++; - break; - case 2 : - return _Inter; - case 0 : - if( (i_glob < N1) != which_start) - { - mi2=mi1; - mi2++; - /* detection of double points */ - if(distance2((* mi1).first, (*mi2).first) > _epsilon) - four_neighbours = true; - else /* Rare pothological case: */ - { - const std::pair< const double *, int > next_pt= *mi2; - events.erase(mi2); - mi1=events.insert(mi1,next_pt); - } - } - break; - default: - throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (1)"); - } - } - /******** Loop until a terminal point or crossing is reached ************/ - while( !_terminus) - { - //std::cout<< "nb_prev= "<< nb_prev<< " nb_inter= " << _Inter.size()/DIM << std::endl; - switch (nb_prev) - { - case 1 : - mi=_Status.find(i_glob);// pointer to the segment ending at i - i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i - sign = (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? - 1 : + 1; - i_next_glob = i_glob+sign; - _is_in_intersection = ((*mi).second).second;//boolean that tells if i is in the intersection - _Status.erase(mi); - defineIndices(i_loc,i_next,i_prev, Poly1,Poly2, - j1,j1_glob,j2,j2_glob,j3,j3_glob,j4,j4_glob, - i_glob,i_next_glob,i_prev_glob, P_1,P_2, N1, N2, sign); - if( _is_in_intersection ) addNewVertex(i_loc, i_glob, i_next_glob, i_prev_glob, Poly1); - addCrossings(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, - &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob, - &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob, &Poly1[DIM*i_prev]); - break; - case 2 : - if(!_Inter.empty()) - { - if(i_glob < N1) for(idim=0;idim(&Poly1[DIM*i_loc],&Poly2[DIM*j1],&Poly2[DIM*j2], - &Poly2[DIM*j3], &Poly2[DIM*j4],V12, V34); - _is_in_intersection=( inside < _epsilon ); // <= epsilon or 0 ? - - if(fabs(inside) > _epsilon)//vertex clearly inside or outside - { - //std::cout<<"coucou1" << std::endl; - if( _is_in_intersection) - { - for(int iidim=0;iidim(V34,V34) > _epsilon)//vertex i on edge (j1,j2), not on (j3,j4) - { - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); - is_inside_next= (dotprod(Vnext,V34)<0); - is_inside_prev= (dotprod(Vprev,V34)<0); - - if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); - - if(is_inside_next) - { - _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, - &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); - } - else - { - _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j2_glob); - ((* mi).second).second= !((* mi).second).second; - } - if(is_inside_prev) - { - _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, - &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); - } - else - { - _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j2_glob); - ((* mi).second).second= !((* mi).second).second; - } - } - else if(dotprod(V12,V12) > _epsilon)//vertex i on a edge (j3,j4), not on (j1,j2) - { - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],Vnext); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],Vprev); - is_inside_next= dotprod(Vnext,V12)<0; - is_inside_prev= dotprod(Vprev,V12)<0; - - if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); - - if(is_inside_next) - { - _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, - &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); - } - else - { - _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j4_glob); - ((* mi).second).second= ! ((* mi).second).second; - } - if(is_inside_prev) - { - _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, - &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); - } - else - { - _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j4_glob); - ((* mi).second).second= !((* mi).second).second; - } - } - else //vertices i, j1 and j3 share the same coordinates - { - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],V12); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],V34); - - double inside_next= dotprod(Vnext,V12); - double inside_prev= dotprod(Vprev,V34); - double inside_j2 = dotprod(Vnext,Vprev); - double inside_j4 = dotprod(V12,V34); - - std::map > which_is_inside; - which_is_inside[inside_next] = std::make_pair(i_glob,i_next_glob); - which_is_inside[inside_prev] = std::make_pair(i_glob,i_prev_glob); - which_is_inside[inside_j2] = std::make_pair(j1_glob,j2_glob); - which_is_inside[inside_j4] = std::make_pair(j3_glob,j4_glob); - - std::map >::iterator min = which_is_inside.begin(); - std::map >::iterator minext = min; - minext++; - std::map >::reverse_iterator max = which_is_inside.rbegin(); - std::multimap< int, std::pair< int,bool> >::iterator j2_in_status = _Status.find(((*min).second).second); - std::multimap< int, std::pair< int,bool> >::iterator j4_in_status = _Status.find(((*minext).second).second); - - if((*min).first < -_epsilon) //there is someone clearly inside - { - _End_segments.push_back( (*min).second ); - _End_segments.push_back((* minext).second); - if(j2_in_status != _Status.end()) - ((*j2_in_status).second).second = ! ((*j2_in_status).second).second; - if(j4_in_status != _Status.end()) - ((*j4_in_status).second).second = ! ((*j4_in_status).second).second; - is_inside_next = ((*min).second).second == i_next_glob || ((*minext).second).second == i_next_glob; - is_inside_prev = ((*min).second).second == i_prev_glob || ((*minext).second).second == i_prev_glob; - } - else - if(fabs((*min).first) <= _epsilon) //nobody is clearly inside but two segments are superposed - { - if(fabs((*max).first) > _epsilon) - return std::deque< double >(); - else //all four segments are superposed - { - _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); - _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); - is_inside_next= true; - is_inside_prev= true; - } - } - else //there is nobody inside - return std::deque< double >(); - - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob,is_inside_prev))); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob,is_inside_next))); - } - } - } - break; - default: - std::cout << "Problem: nbprev= " << nb_prev << " ; i_glob = " << i_glob << std::endl; - throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (2)"); - } - mi1++; - i_glob=(* mi1).second;//global index of vertex i - nb_prev = _Status.count(i_glob); - } - } - return _Inter; - } - - /**************************************************************************/ - /* computes the convex hull of a polygon subP which is a sub polygon of P */ - /* P is the array of coordinates, subP is a map containing initially the indices of a subpolygon of P */ - /* in the end, subP contains only the elements belonging to the convex hull, and not_in_hull the others */ - /**************************************************************************/ - template - inline void PolygonAlgorithms::convHull(const double *P, int N, double * normal, - std::map< int,int >& subP, std::map< int,int >& not_in_hull, - int& NsubP, const double epsilon) - { - if(NsubP>3) - { - std::map< int,int >::iterator mi_prev = subP.begin(); - std::map< int,int >::iterator mi = mi_prev; - mi++; - std::map< int,int >::iterator mi_next = mi; - mi_next++; - double directframe=0.; - - /* Check if the polygon subP is positively oriented */ - std::map< int,int >::iterator mi1=mi; - while(mi1 != subP.end() && distance2(&P[DIM*(*subP.begin()).second],&P[DIM*(*mi1).second])< epsilon) - mi1++; - std::map< int,int >::iterator mi2=mi1; - while(mi2 != subP.end() && fabs(directframe)(&P[DIM* (*mi1).second], - &P[DIM* (*subP.begin()).second], - &P[DIM* (*mi2).second], normal); - mi2++; - } - if(directframe < 0) for(int idim=0; idim< DIM; idim++) normal[idim] *= -1; - - /* Core of the algorithm */ - while(mi_next != subP.end()) - { - directframe = direct_frame(&P[DIM* (*mi).second], - &P[DIM* (*mi_prev).second], - &P[DIM* (*mi_next).second], normal); - if(directframe > -epsilon){ - mi ++; - mi_prev++; - mi_next++; - } - else - { - not_in_hull.insert(*mi); - subP.erase(mi); - NsubP--; - mi--; - } - } - directframe = direct_frame(&P[DIM*(*mi).second], - &P[DIM*(*mi_prev).second], - &P[DIM*(*subP.begin()).second], normal); - if(directframe < -epsilon) - { - not_in_hull.insert(*mi); - subP.erase(mi); - NsubP--; - } - } - } - - template - void PolygonAlgorithms::convexDecomposition(const double * P, int N, double *normal, std::vector< int > subP, int NsubP, - std::vector< std::map< int,int > >& components, std::vector< int >& components_index, - int& Ncomp, int sign, const double epsilon) - { - int i; - std::map< int, int > hull; - std::map< int, int > not_in_hull; - std::map< int, int >::iterator mi, mj; - std::vector< int > reflex_region; - int Nreflex; - int i_xmax=0; - const double * xmax=&P[DIM*subP[0]]; - /* checking an extremal point of subP */ - for(i=0; i xmax) - { - i_xmax=i; - xmax=&P[DIM*subP[i]]; - } - } - /* renumbering of SubP elements for the convex hull*/ - for(i=0; i - int PolygonAlgorithms::convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, - std::vector< int >& components_index, const double epsilon) - { - int Ncomp=0; - std::vector< int > subP(N); - double normal[3]={0,0,0}; - - for(int i = 0; i(&P[0],&P[i1])< epsilon) i1++; - int i2=i1+1; - while(i2(normal,normal))(&P[i1], &P[0], &P[i2],normal); - i2++; - } - - convexDecomposition(P, N, normal, subP, N, components, components_index, Ncomp, 1, epsilon); - return Ncomp; - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx b/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx deleted file mode 100644 index 6c5a2d1f9..000000000 --- a/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __POLYHEDRON3D2DINTERSECTORP0P0_HXX__ -#define __POLYHEDRON3D2DINTERSECTORP0P0_HXX__ - -#include "Intersector3DP0P0.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class Polyhedron3D2DIntersectorP0P0 : public Intersector3DP0P0 - { - typedef typename std::map > DuplicateFacesType; - - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - public: - - Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh, - const MyMeshType& srcMesh, - const double dimCaracteristic, - const double precision, - DuplicateFacesType& intersectFaces, - SplittingPolicy policy = PLANAR_FACE_5); - - ~Polyhedron3D2DIntersectorP0P0(); - - void intersectCells(ConnType targetCell, - const std::vector& srcCells, - MyMatrixType& matrix); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - double _dim_caracteristic; - double _precision; - - DuplicateFacesType& _intersect_faces; - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx b/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx deleted file mode 100644 index 85d58450b..000000000 --- a/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __POLYHEDRON3D2DINTERSECTORP0P0_TXX__ -#define __POLYHEDRON3D2DINTERSECTORP0P0_TXX__ - -#include "Polyhedron3D2DIntersectorP0P0.hxx" -#include "Intersector3DP0P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - Polyhedron3D2DIntersectorP0P0::Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh, - const MyMeshType& srcMesh, - const double dimCaracteristic, - const double precision, - DuplicateFacesType& intersectFaces, - SplittingPolicy policy) - : Intersector3DP0P0(targetMesh,srcMesh), - _split(targetMesh,srcMesh,policy), - _dim_caracteristic(dimCaracteristic), - _precision(precision), - _intersect_faces(intersectFaces) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - Polyhedron3D2DIntersectorP0P0::~Polyhedron3D2DIntersectorP0P0() - { - releaseArrays(); - } - - template - void Polyhedron3D2DIntersectorP0P0::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void Polyhedron3D2DIntersectorP0P0::intersectCells(ConnType targetCell, - const std::vector& srcCells, - MyMatrixType& matrix) - { - int nbOfNodesT=Intersector3D::_target_mesh.getNumberOfNodesOfElement(OTT::indFC(targetCell)); - releaseArrays(); - _split.splitTargetCell(targetCell,nbOfNodesT,_tetra); - - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - double surface = 0.; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - // calculate the coordinates of the nodes - typename MyMeshType::MyConnType cellSrc = *iterCellS; - int cellSrcIdx = OTT::indFC(cellSrc); - NormalizedCellType normCellType=Intersector3D::_src_mesh.getTypeOfElement(cellSrcIdx); - const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); - const MyMeshType& src_mesh = Intersector3D::_src_mesh; - unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? src_mesh.getNumberOfNodesOfElement(cellSrcIdx) : cellModelCell.getNumberOfNodes(); - int *polyNodes=new int[nbOfNodes4Type]; - double **polyCoords = new double*[nbOfNodes4Type]; - for(int i = 0;i<(int)nbOfNodes4Type;++i) - { - // we could store mapping local -> global numbers too, but not sure it is worth it - const int globalNodeNum = getGlobalNumberOfNode(i, OTT::indFC(*iterCellS), src_mesh); - polyNodes[i] = globalNodeNum; - polyCoords[i] = const_cast(src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum); - } - - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - surface += (*iter)->intersectSourceFace(normCellType, - nbOfNodes4Type, - polyNodes, - polyCoords, - _dim_caracteristic, - _precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - - if(surface!=0.) - { - - matrix[targetCell].insert(std::make_pair(cellSrcIdx, surface)); - - bool isSrcFaceColinearWithFaceOfTetraTargetCell = false; - std::set::iterator iter; - for (iter = listOfTetraFacesColinear.begin(); iter != listOfTetraFacesColinear.end(); ++iter) - { - if (listOfTetraFacesTreated.count(*iter) != 1) - { - isSrcFaceColinearWithFaceOfTetraTargetCell = false; - break; - } - else - { - isSrcFaceColinearWithFaceOfTetraTargetCell = true; - } - } - - if (isSrcFaceColinearWithFaceOfTetraTargetCell) - { - DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(cellSrcIdx); - if (intersectFacesIter != _intersect_faces.end()) - { - intersectFacesIter->second.insert(targetCell); - } - else - { - std::set targetCellSet; - targetCellSet.insert(targetCell); - _intersect_faces.insert(std::make_pair(cellSrcIdx, targetCellSet)); - } - } - } - delete [] polyNodes; - delete [] polyCoords; - } - _split.releaseArrays(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx deleted file mode 100644 index 35193ec13..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POLYHEDRONINTERSECTORP0P0_HXX__ -#define __POLYHEDRONINTERSECTORP0P0_HXX__ - -#include "Intersector3DP0P0.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP0P0 : public Intersector3DP0P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP0P0(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx deleted file mode 100644 index 6ed792171..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POLYHEDRONINTERSECTORP0P0_TXX__ -#define __POLYHEDRONINTERSECTORP0P0_TXX__ - -#include "PolyhedronIntersectorP0P0.hxx" -#include "Intersector3DP0P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PolyhedronIntersectorP0P0::PolyhedronIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P0(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP0P0::~PolyhedronIntersectorP0P0() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP0P0::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PolyhedronIntersectorP0P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - releaseArrays(); - _split.splitTargetCell2(targetCell,_tetra); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - double volume = 0.; - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - { - volume += (*iter)->intersectSourceCell(*iterCellS); - (*iter)->clearVolumesCache(); - } - if(volume!=0.) - res[targetCell].insert(std::make_pair(OTT::indFC(*iterCellS), volume)); - } - _split.releaseArrays(); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx deleted file mode 100644 index 2bf2ec0b3..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POLYHEDRONINTERSECTORP0P1_HXX__ -#define __POLYHEDRONINTERSECTORP0P1_HXX__ - -#include "Intersector3DP0P1.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP0P1 : public Intersector3DP0P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP0P1(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx deleted file mode 100644 index 43839bb45..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POLYHEDRONINTERSECTORP0P1_TXX__ -#define __POLYHEDRONINTERSECTORP0P1_TXX__ - -#include "PolyhedronIntersectorP0P1.hxx" -#include "Intersector3DP0P1.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PolyhedronIntersectorP0P1::PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P1(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP0P1::~PolyhedronIntersectorP0P1() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP0P1::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PolyhedronIntersectorP0P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - SplitterTetra* subTetras[24]; - releaseArrays(); - _split.splitTargetCell2(targetCell,_tetra); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - { - (*iter)->splitIntoDualCells(subTetras); - for(int i=0;i<24;i++) - { - SplitterTetra *tmp=subTetras[i]; - double volume = tmp->intersectSourceCell(*iterCellS); - if(volume!=0.) - { - int targetNodeId(tmp->getId(0)); - if(targetNodeId<0) - { - std::ostringstream oss; oss << "PolyhedronIntersectorP0P1::intersectCells : On target cell #" << targetCell << " the splitting into tetra4 leads to the creation of an additional point that interacts with source cell Id #" << *iterCellS << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - typename MyMatrix::value_type& resRow=res[targetNodeId]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iterCellS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),volume)); - else - { - double val=(*iterRes).second+volume; - resRow.erase(OTT::indFC(*iterCellS)); - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),val)); - } - } - delete tmp; - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx deleted file mode 100644 index 4c9cb248a..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __POLYHEDRONINTERSECTORP1P0_HXX__ -#define __POLYHEDRONINTERSECTORP1P0_HXX__ - -#include "Intersector3DP1P0.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP1P0 : public Intersector3DP1P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP1P0(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx deleted file mode 100644 index 350f33252..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __POLYHEDRONINTERSECTORP1P0_TXX__ -#define __POLYHEDRONINTERSECTORP1P0_TXX__ - -#include "PolyhedronIntersectorP1P0.hxx" -#include "Intersector3DP1P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - * - * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. - */ - template - PolyhedronIntersectorP1P0::PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P0(targetMesh,srcMesh),_split(srcMesh,targetMesh,policy) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP1P0::~PolyhedronIntersectorP1P0() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP1P0::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - * WARNING : for all methods on _split object source and target are switched ! - */ - template - void PolyhedronIntersectorP1P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - SplitterTetra* subTetras[24]; - typename MyMatrix::value_type& resRow=res[targetCell]; - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - releaseArrays(); - int nbOfNodesS=Intersector3D::_src_mesh.getNumberOfNodesOfElement(OTT::indFC(*iterCellS)); - _split.splitTargetCell(*iterCellS,nbOfNodesS,_tetra); - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - { - (*iter)->splitIntoDualCells(subTetras); - for(int i=0;i<24;i++) - { - SplitterTetra *tmp=subTetras[i]; - double volume = tmp->intersectSourceCell(targetCell); - ConnType sourceNode=tmp->getId(0); - if(volume!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(sourceNode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(sourceNode),volume)); - else - { - double val=(*iterRes).second+volume; - resRow.erase(OTT::indFC(sourceNode)); - resRow.insert(std::make_pair(OTT::indFC(sourceNode),val)); - } - } - delete tmp; - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx deleted file mode 100644 index 9dabe51fe..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PolyhedronIntersectorP1P0Bary_HXX__ -#define __PolyhedronIntersectorP1P0Bary_HXX__ - -#include "Intersector3DP1P0Bary.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP1P0Bary : public Intersector3DP1P0Bary - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP1P0Bary(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx deleted file mode 100644 index 6136b5ee9..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PolyhedronIntersectorP1P0Bary_TXX__ -#define __PolyhedronIntersectorP1P0Bary_TXX__ - -#include "PolyhedronIntersectorP1P0Bary.hxx" -#include "Intersector3DP1P0Bary.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - * - * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. - */ - template - PolyhedronIntersectorP1P0Bary::PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh, - const MyMeshType& srcMesh, - SplittingPolicy policy) - :Intersector3DP1P0Bary(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) - { - // SPEC: - // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and - // tetrahedrons in 3D will be supported by interpolators. If a non - // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." - - // Check types of source elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - if ( srcMesh.getTypeOfElement( OTT::indFC(i) ) != NORM_TETRA4 ) - throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with tetrahedral source meshes"); - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP1P0Bary::~PolyhedronIntersectorP1P0Bary() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP1P0Bary::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - //================================================================================ - /*! - * \brief This method computes a value per each node of source cell for each target cell. - * \param srcCell - a source tetrahedron - * \param tgtCells - target elements - * \param res - matrix to fill in - */ - //================================================================================ - - template - void PolyhedronIntersectorP1P0Bary::intersectCells(ConnType tgtCell, - const std::vector& srcCells, - MyMatrix& res) - { - typename MyMatrix::value_type& resRow=res[tgtCell]; - - int nbOfNodesT=Intersector3D::_target_mesh.getNumberOfNodesOfElement(OTT::indFC(tgtCell)); - releaseArrays(); - _split.splitTargetCell(tgtCell,nbOfNodesT,_tetra); - - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - // intersect a source tetrahedron with each target tetrahedron: get intersection volume and barycenter - double baryCentre[SPACEDIM], total_baryCentre[3] = { 0., 0., 0.}; - double interVolume = 0; - for(typename std::vector*>::iterator iterTetraT = _tetra.begin(); iterTetraT != _tetra.end(); ++iterTetraT) - { - SplitterTetra *tmp=*iterTetraT; - tmp->clearVolumesCache(); - double volume = tmp->intersectSourceCell(*iterCellS, baryCentre); - if ( volume > 0 ) - { - interVolume += volume; - for ( int i = 0; i < SPACEDIM; ++i ) - total_baryCentre[i] += baryCentre[i]*volume; - } - } - if(interVolume!=0) - { - for ( int i = 0; i < SPACEDIM; ++i ) - total_baryCentre[i] /= interVolume; - - // coordinates of the source tetrahedron - std::vector srcCellCoords(4); - for ( int n = 0; n < 4; ++n ) - srcCellCoords[ n ] = getCoordsOfNode( n, *iterCellS, Intersector3D::_src_mesh ); - - // compute barycentric coordinates - double baryCoords[4]; - barycentric_coords( srcCellCoords, total_baryCentre, baryCoords); - - // store coeffs of each node of the source tetrahedron - const ConnType *srcCellNodes=Intersector3D::_src_mesh.getConnectivityPtr()+OTT::conn2C(Intersector3D::_src_mesh.getConnectivityIndexPtr()[*iterCellS]); - for ( int n = 0; n < 4; ++n ) - { - double val = baryCoords[n] * interVolume; - ConnType curNodeS = srcCellNodes[n]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS); - if(iterRes!=resRow.end()) - { - val += iterRes->second; - resRow.erase( curNodeS ); - } - resRow.insert(std::make_pair(curNodeS,val)); - } - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx deleted file mode 100644 index 002a173ca..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PolyhedronIntersectorP1P1_HXX__ -#define __PolyhedronIntersectorP1P1_HXX__ - -#include "Intersector3DP1P1.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP1P1 : public Intersector3DP1P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP1P1(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx b/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx deleted file mode 100644 index f26320187..000000000 --- a/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __PolyhedronIntersectorP1P1_TXX__ -#define __PolyhedronIntersectorP1P1_TXX__ - -#include "PolyhedronIntersectorP1P1.hxx" -#include "Intersector3DP1P1.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PolyhedronIntersectorP1P1::PolyhedronIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P1(targetMesh,srcMesh) - { - // SPEC: - // "Limitation. Concerning P1P1 3D improvement only tetrahedron will be supported. - // If another type than tetrahedron is detected an INTERP_KERNEL::Exception should be thrown" - - // Check types of elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - if ( srcMesh.getTypeOfElement( OTT::indFC( i )) != NORM_TETRA4 ) - throw INTERP_KERNEL::Exception("P1P1 3D algorithm works only with tetrahedral meshes"); - - const unsigned long numTgtElems = targetMesh.getNumberOfElements(); - for(unsigned long i = 0 ; i < numTgtElems ; ++i) - if ( targetMesh.getTypeOfElement( OTT::indFC( i )) != NORM_TETRA4 ) - throw INTERP_KERNEL::Exception("P1P1 3D algorithm works only with tetrahedral meshes"); - } - - /** - * Destructor. - */ - template - PolyhedronIntersectorP1P1::~PolyhedronIntersectorP1P1() - { - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void PolyhedronIntersectorP1P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { -#ifdef _DEBUG_ - UnitTetraIntersectionBary b; b.init(); -#endif - // split the targetCell into dual cells - std::pair< int, std::vector > subTetraNodes[24]; // a node of sub tetra and its coordinates - const double* nodes[4]; int conn[4]; - for(int node = 0; node < 4 ; ++node) - nodes[node]=getCoordsOfNode2(node, OTT::indFC(targetCell), - Intersector3D::_target_mesh,conn[node]); - SplitterTetra tgtTetra(Intersector3D::_src_mesh, nodes, conn); - for (int i=0; i<24; i++) - { - subTetraNodes[i].second.resize(12); - tgtTetra.splitMySelfForDual(&subTetraNodes[i].second[0],i,subTetraNodes[i].first); - } - // intersect each source tetrahedron with each of target dual cells - SplitterTetra* subTetrasS[24]; - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - // split a source cell into dual cells - for(int node = 0; node < 4 ; ++node) - nodes[node]=getCoordsOfNode2(node, OTT::indFC(*iterCellS), - Intersector3D::_src_mesh,conn[node]); - - SplitterTetra srcTetra(Intersector3D::_target_mesh, nodes, conn); - srcTetra.splitIntoDualCells(subTetrasS); - - // intersect each target subTetra with each source one - for(int i=0;i<24;i++) - { - SplitterTetra *tmp=subTetrasS[i]; - ConnType sourceNode=OTT::indFC(tmp->getId(0)); - for(int j=0;j<24;j++) - { - const double* tetraNodes12 = &subTetraNodes[j].second[0]; - const double* tetraNodesT[4]={ tetraNodes12, tetraNodes12+3, tetraNodes12+6, tetraNodes12+9 }; - double volume = tmp->intersectTetra( tetraNodesT ); - if(volume!=0.) - { - ConnType tgtNode=subTetraNodes[j].first; - typename MyMatrix::value_type& resRow = res[tgtNode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find( sourceNode ); - if(iterRes!=resRow.end()) - { - volume += (*iterRes).second; - resRow.erase(sourceNode); - } - resRow.insert(std::make_pair(sourceNode,volume)); - } - } - delete tmp; - } - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/RegionNode.hxx b/medtool/src/INTERP_KERNEL/RegionNode.hxx deleted file mode 100644 index c7aaf7532..000000000 --- a/medtool/src/INTERP_KERNEL/RegionNode.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __REGIONNODE_HXX__ -#define __REGIONNODE_HXX__ - -#include "MeshRegion.hxx" - -namespace INTERP_KERNEL -{ - - /** - * \brief Class containing a tuplet of a source region and a target region. - * This is used as the object to put on the stack in the depth-first search - * in the bounding-box filtering process. - */ - template - class RegionNode - { - public: - - RegionNode() { } - - ~RegionNode() { } - - /** - * Accessor to source region - * - * @return reference to source region - */ - MeshRegion& getSrcRegion() { return _srcRegion; } - - /** - * Accessor to target region - * - * @return reference to target region - */ - MeshRegion& getTargetRegion() { return _targetRegion; } - - private: - - /// source region - MeshRegion _srcRegion; - - /// target region - MeshRegion _targetRegion; - - }; - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/SplitterTetra.cxx b/medtool/src/INTERP_KERNEL/SplitterTetra.cxx deleted file mode 100644 index 06dbb101e..000000000 --- a/medtool/src/INTERP_KERNEL/SplitterTetra.cxx +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "SplitterTetra.hxx" - -namespace INTERP_KERNEL -{ - - void SplitHexa8IntoTetras(SplittingPolicy policy, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords) - { - if(std::distance(nodalConnBg,nodalConnEnd)!=8) - throw INTERP_KERNEL::Exception("SplitHexa8IntoTetras : input hexa do not have 8 nodes !"); - switch(policy) - { - case PLANAR_FACE_5: - { - tetrasNodalConn.resize(20); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[SPLIT_NODES_5_WO[0]]; conn[1]=nodalConnBg[SPLIT_NODES_5_WO[1]]; conn[2]=nodalConnBg[SPLIT_NODES_5_WO[2]]; conn[3]=nodalConnBg[SPLIT_NODES_5_WO[3]]; - conn[4]=nodalConnBg[SPLIT_NODES_5_WO[4]]; conn[5]=nodalConnBg[SPLIT_NODES_5_WO[5]]; conn[6]=nodalConnBg[SPLIT_NODES_5_WO[6]]; conn[7]=nodalConnBg[SPLIT_NODES_5_WO[7]]; - conn[8]=nodalConnBg[SPLIT_NODES_5_WO[8]]; conn[9]=nodalConnBg[SPLIT_NODES_5_WO[9]]; conn[10]=nodalConnBg[SPLIT_NODES_5_WO[10]]; conn[11]=nodalConnBg[SPLIT_NODES_5_WO[11]]; - conn[12]=nodalConnBg[SPLIT_NODES_5_WO[12]]; conn[13]=nodalConnBg[SPLIT_NODES_5_WO[13]]; conn[14]=nodalConnBg[SPLIT_NODES_5_WO[14]]; conn[15]=nodalConnBg[SPLIT_NODES_5_WO[15]]; - conn[16]=nodalConnBg[SPLIT_NODES_5_WO[16]]; conn[17]=nodalConnBg[SPLIT_NODES_5_WO[17]]; conn[18]=nodalConnBg[SPLIT_NODES_5_WO[18]]; conn[19]=nodalConnBg[SPLIT_NODES_5_WO[19]]; - return ; - } - case PLANAR_FACE_6: - { - tetrasNodalConn.resize(24); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[SPLIT_NODES_6_WO[0]]; conn[1]=nodalConnBg[SPLIT_NODES_6_WO[1]]; conn[2]=nodalConnBg[SPLIT_NODES_6_WO[2]]; conn[3]=nodalConnBg[SPLIT_NODES_6_WO[3]]; - conn[4]=nodalConnBg[SPLIT_NODES_6_WO[4]]; conn[5]=nodalConnBg[SPLIT_NODES_6_WO[5]]; conn[6]=nodalConnBg[SPLIT_NODES_6_WO[6]]; conn[7]=nodalConnBg[SPLIT_NODES_6_WO[7]]; - conn[8]=nodalConnBg[SPLIT_NODES_6_WO[8]]; conn[9]=nodalConnBg[SPLIT_NODES_6_WO[9]]; conn[10]=nodalConnBg[SPLIT_NODES_6_WO[10]]; conn[11]=nodalConnBg[SPLIT_NODES_6_WO[11]]; - conn[12]=nodalConnBg[SPLIT_NODES_6_WO[12]]; conn[13]=nodalConnBg[SPLIT_NODES_6_WO[13]]; conn[14]=nodalConnBg[SPLIT_NODES_6_WO[14]]; conn[15]=nodalConnBg[SPLIT_NODES_6_WO[15]]; - conn[16]=nodalConnBg[SPLIT_NODES_6_WO[16]]; conn[17]=nodalConnBg[SPLIT_NODES_6_WO[17]]; conn[18]=nodalConnBg[SPLIT_NODES_6_WO[18]]; conn[19]=nodalConnBg[SPLIT_NODES_6_WO[19]]; - conn[20]=nodalConnBg[SPLIT_NODES_6_WO[20]]; conn[21]=nodalConnBg[SPLIT_NODES_6_WO[21]]; conn[22]=nodalConnBg[SPLIT_NODES_6_WO[22]]; conn[23]=nodalConnBg[SPLIT_NODES_6_WO[23]]; - return ; - } - case GENERAL_24: - { - addCoords.resize(7*3); - tetrasNodalConn.resize(24*4); - int *conn(&tetrasNodalConn[0]); - double *tmp(&addCoords[18]); - tmp[0]=0.; tmp[1]=0.; tmp[2]=0.; - double *tmp2(&addCoords[0]); - for(int i=0;i<6;i++,tmp2+=3) - { - tmp2[0]=0.; tmp2[1]=0.; tmp2[2]=0.; - for(int j=0;j<4;j++,conn+=4) - { - int tmp3(nodalConnBg[GENERAL_24_SUB_NODES_WO[4*i+j]]); - tmp2[0]+=coords[3*tmp3+0]; - tmp2[1]+=coords[3*tmp3+1]; - tmp2[2]+=coords[3*tmp3+2]; - conn[0]=tmp3; - conn[1]=nodalConnBg[GENERAL_24_SUB_NODES_WO[4*i+(j+1)%4]]; - conn[2]=-(i+1); conn[3]=-7; - } - tmp2[0]/=4.; tmp2[1]/=4.; tmp2[2]/=4.; - tmp[0]+=tmp2[0]; tmp[1]+=tmp2[1]; tmp[2]+=tmp2[2]; - } - tmp[0]/=6.; tmp[1]/=6.; tmp[2]/=6.; - return ; - } - case GENERAL_48: - { - addCoords.resize(19*3); - tetrasNodalConn.resize(48*4); - double *tmp2(&addCoords[0]),*tmp(&addCoords[0]); - for(int i=0;i<12;i++,tmp2+=3) - { - tmp2[0]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+0]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+0])/2.; - tmp2[1]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+1]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+1])/2.; - tmp2[2]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+2]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+2])/2.; - } - for(int i=0;i<7;i++,tmp2+=3) - { - tmp2[0]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+0]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+0])/2.; - tmp2[1]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+1]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+1])/2.; - tmp2[2]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+2]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+2])/2.; - } - int *conn(&tetrasNodalConn[0]); - std::vector dummy; - for(int i=0;i<8;i++) - { - std::vector c; - SplitHexa8IntoTetras(PLANAR_FACE_6,GENERAL_48_SUBZONES_2+i*8,GENERAL_48_SUBZONES_2+(i+1)*8,coords,c,dummy); - int *conn2(&c[0]); - for(int j=0;j<6;j++,conn+=4,conn2+=4) - { - conn[0]=conn2[0]>=0?nodalConnBg[conn2[0]]:conn2[0]; - conn[1]=conn2[1]>=0?nodalConnBg[conn2[1]]:conn2[1]; - conn[2]=conn2[2]>=0?nodalConnBg[conn2[2]]:conn2[2]; - conn[3]=conn2[3]>=0?nodalConnBg[conn2[3]]:conn2[3]; - } - } - return ; - } - default: - throw INTERP_KERNEL::Exception("SplitHexa8IntoTetras : invalid input policy ! Should be in [PLANAR_FACE_5,PLANAR_FACE_6,GENERAL_24,GENERAL_48] !"); - } - } - - void SplitIntoTetras(SplittingPolicy policy, NormalizedCellType gt, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords) - { - switch(gt) - { - case NORM_TETRA4: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=4) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input tetra do not have 4 nodes !"); - tetrasNodalConn.insert(tetrasNodalConn.end(),nodalConnBg,nodalConnEnd); - return ; - } - case NORM_HEXA8: - { - SplitHexa8IntoTetras(policy,nodalConnBg,nodalConnEnd,coords,tetrasNodalConn,addCoords); - return ; - } - case NORM_PYRA5: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=5) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input pyra5 do not have 5 nodes !"); - tetrasNodalConn.resize(8); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[2]; conn[3]=nodalConnBg[4]; - conn[4]=nodalConnBg[0]; conn[5]=nodalConnBg[2]; conn[6]=nodalConnBg[3]; conn[7]=nodalConnBg[4]; - return ; - } - case NORM_PENTA6: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=6) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input penta6 do not have 6 nodes !"); - tetrasNodalConn.resize(12); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[2]; conn[3]=nodalConnBg[3]; - conn[4]=nodalConnBg[3]; conn[5]=nodalConnBg[5]; conn[6]=nodalConnBg[4]; conn[7]=nodalConnBg[2]; - conn[8]=nodalConnBg[4]; conn[9]=nodalConnBg[2]; conn[10]=nodalConnBg[1]; conn[11]=nodalConnBg[3]; - return ; - } - case NORM_HEXGP12: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=12) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input octa12 (hexagone prism) do not have 12 nodes !"); - tetrasNodalConn.resize(48); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[5]; conn[3]=nodalConnBg[6]; - conn[4]=nodalConnBg[6]; conn[5]=nodalConnBg[11]; conn[6]=nodalConnBg[7]; conn[7]=nodalConnBg[5]; - conn[8]=nodalConnBg[7]; conn[9]=nodalConnBg[5]; conn[10]=nodalConnBg[1]; conn[11]=nodalConnBg[6]; - // - conn[12]=nodalConnBg[1]; conn[13]=nodalConnBg[4]; conn[14]=nodalConnBg[5]; conn[15]=nodalConnBg[7]; - conn[16]=nodalConnBg[7]; conn[17]=nodalConnBg[11]; conn[18]=nodalConnBg[10]; conn[19]=nodalConnBg[5]; - conn[20]=nodalConnBg[10]; conn[21]=nodalConnBg[5]; conn[22]=nodalConnBg[4]; conn[23]=nodalConnBg[7]; - // - conn[24]=nodalConnBg[1]; conn[25]=nodalConnBg[2]; conn[26]=nodalConnBg[4]; conn[27]=nodalConnBg[7]; - conn[28]=nodalConnBg[7]; conn[29]=nodalConnBg[10]; conn[30]=nodalConnBg[8]; conn[31]=nodalConnBg[4]; - conn[32]=nodalConnBg[8]; conn[33]=nodalConnBg[4]; conn[34]=nodalConnBg[2]; conn[35]=nodalConnBg[7]; - // - conn[36]=nodalConnBg[2]; conn[37]=nodalConnBg[3]; conn[38]=nodalConnBg[4]; conn[39]=nodalConnBg[8]; - conn[40]=nodalConnBg[8]; conn[41]=nodalConnBg[10]; conn[42]=nodalConnBg[9]; conn[43]=nodalConnBg[4]; - conn[44]=nodalConnBg[9]; conn[45]=nodalConnBg[4]; conn[46]=nodalConnBg[3]; conn[47]=nodalConnBg[8]; - return ; - } - case NORM_POLYHED: - { - std::size_t nbOfFaces(std::count(nodalConnBg,nodalConnEnd,-1)+1); - std::size_t nbOfTetra(std::distance(nodalConnBg,nodalConnEnd)-nbOfFaces+1); - addCoords.resize((nbOfFaces+1)*3); - tetrasNodalConn.resize(nbOfTetra*4); - int *conn(&tetrasNodalConn[0]); - const int *work(nodalConnBg); - double *tmp(&addCoords[0]),*tmp2(&addCoords[3*nbOfFaces]); - tmp2[0]=0.; tmp2[1]=0.; tmp2[2]=0.; - for(std::size_t i=0;i -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - // Schema according to which the splitting is performed. - // Each line represents one tetrahedron. The numbering is as follows : - // - // 7 ------ 6 - // /| /| - // / | / | - // 3 ------ 2 | - // | | | | - // | | | | - // | 4-----|- 5 - // | / | / - // 0 ------ 1 - - static const int SPLIT_NODES_5[20] = /* WHY not all well oriented ???? */ - { - 0, 1, 5, 2, - 0, 4, 5, 7, - 0, 3, 7, 2, - 5, 6, 7, 2, - 0, 2, 5, 7 - }; - - static const int SPLIT_NODES_5_WO[20] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */ - { - 0, 5, 1, 2, - 0, 4, 5, 7, - 0, 3, 7, 2, - 5, 7, 6, 2, - 0, 5, 2, 7 - }; - - static const int SPLIT_NODES_6[24] = /* WHY all badly oriented ???? */ - { - 0, 1, 5, 6, - 0, 2, 1, 6, - 0, 5, 4, 6, - 0, 4, 7, 6, - 0, 3, 2, 6, - 0, 7, 3, 6 - }; - - static const int SPLIT_NODES_6_WO[24] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */ - { - 0, 5, 1, 6, - 0, 1, 2, 6, - 0, 4, 5, 6, - 0, 7, 4, 6, - 0, 2, 3, 6, - 0, 3, 7, 6 - }; - - // Each sub-node is the barycenter of 4 other nodes. - // For the faces, these are on the orignal mesh. - // For the barycenter, the four face sub-nodes are used. - static const int GENERAL_24_SUB_NODES[28] = - { - 0,1,4,5,// sub-node 8 (face) - 0,1,2,3,// sub-node 9 (face) - 0,3,4,7,// sub-node 10 (face) - 1,2,5,6,// sub-node 11 (face) - 4,5,6,7,// sub-node 12 (face) - 2,3,6,7,// sub-node 13 (face) - 8,9,10,11// sub-node 14 (cell) - }; - - static const int GENERAL_24_SUB_NODES_WO[28] = - { - 0,4,5,1,// sub-node 8 (face) - 0,1,2,3,// sub-node 9 (face) - 0,3,7,4,// sub-node 10 (face) - 1,5,6,2,// sub-node 11 (face) - 4,7,6,5,// sub-node 12 (face) - 2,6,7,3,// sub-node 13 (face) - 8,9,10,11// sub-node 14 (cell) - }; - - static const int TETRA_EDGES_GENERAL_24[48] = - { - // face with center 8 - 0,1, - 1,5, - 5,4, - 4,0, - // face with center 9 - 0,1, - 1,2, - 2,3, - 3,0, - // face with center 10 - 0,4, - 4,7, - 7,3, - 3,0, - // face with center 11 - 1,5, - 5,6, - 6,2, - 2,1, - // face with center 12 - 5,6, - 6,7, - 7,4, - 4,5, - // face with center 13 - 2,6, - 6,7, - 7,3, - 3,2 - }; - - // Each sub-node is the barycenter of two other nodes. - // For the edges, these lie on the original mesh. - // For the faces, these are the edge sub-nodes. - // For the cell these are two face sub-nodes. - static const int GENERAL_48_SUB_NODES[38] = - { - 0,1, // sub-node 8 (edge) - 0,4, // sub-node 9 (edge) - 1,5, // sub-node 10 (edge) - 4,5, // sub-node 11 (edge) - 0,3, // sub-node 12 (edge) - 1,2, // sub-node 13 (edge) - 4,7, // sub-node 14 (edge) - 5,6, // sub-node 15 (edge) - 2,3, // sub-node 16 (edge) - 3,7, // sub-node 17 (edge) - 2,6, // sub-node 18 (edge) - 6,7, // sub-node 19 (edge) - 8,11, // sub-node 20 (face) - 12,13, // sub-node 21 (face) - 9,17, // sub-node 22 (face) - 10,18, // sub-node 23 (face) - 14,15, // sub-node 24 (face) - 16,19, // sub-node 25 (face) - 20,25 // sub-node 26 (cell) - }; - - // Define 8 hexahedral subzones as in Grandy, p449 - // the values correspond to the nodes that correspond to nodes 1,2,3,4,5,6,7,8 in the subcell - // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes - static const int GENERAL_48_SUBZONES[64] = - { - 0,8,21,12,9,20,26,22, - 8,1,13,21,20,10,23,26, - 12,21,16,3,22,26,25,17, - 21,13,2,16,26,23,18,25, - 9,20,26,22,4,11,24,14, - 20,10,23,26,11,5,15,24, - 22,26,25,17,14,24,19,7, - 26,23,18,25,24,15,6,19 - }; - - static const int GENERAL_48_SUBZONES_2[64] = - { - 0,-1,-14,-5,-2,-13,-19,-15, - -1,1,-6,-14,-13,-3,-16,-19, - -5,-14,-9,3,-15,-19,-18,-10, - -14,-6,2,-9,-19,-16,-11,-18, - -2,-13,-19,-15,4,-4,-17,-7, - -13,-3,-16,-19,-4,5,-8,-17, - -15,-19,-18,-10,-7,-17,-12,7, - -19,-16,-11,-18,-17,-8,6,-12}; - - void SplitHexa8IntoTetras(SplittingPolicy policy, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords); - - INTERPKERNEL_EXPORT void SplitIntoTetras(SplittingPolicy policy, NormalizedCellType gt, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords); - - /** - * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra. - * - */ - class TriangleFaceKey - { - public: - - /** - * Constructor - * Sorts the given nodes (so that the order in which they are passed does not matter) and - * calculates a hash value for the key. - * - * @param node1 global number of the first node of the face - * @param node2 global number of the second node of the face - * @param node3 global number of the third node of the face - */ - TriangleFaceKey(int node1, int node2, int node3) - { - Sort3Ints(_nodes, node1, node2, node3); - _hashVal = ( _nodes[0] + _nodes[1] + _nodes[2] ) % 29; - } - - /** - * Equality comparison operator. - * Compares this TriangleFaceKey object to another and determines if they represent the same face. - * - * @param key TriangleFaceKey with which to compare - * @return true if key has the same three nodes as this object, false if not - */ - bool operator==(const TriangleFaceKey& key) const - { - return _nodes[0] == key._nodes[0] && _nodes[1] == key._nodes[1] && _nodes[2] == key._nodes[2]; - } - - /** - * Less than operator. - * - * @param key TriangleFaceKey with which to compare - * @return true if this object has the three nodes less than the nodes of the key object, false if not - */ - bool operator<(const TriangleFaceKey& key) const - { - for (int i = 0; i < 3; ++i) - { - if (_nodes[i] < key._nodes[i]) - { - return true; - } - else if (_nodes[i] > key._nodes[i]) - { - return false; - } - } - return false; - } - - /** - * Returns a hash value for the object, based on its three nodes. - * This value is not unique for each face. - * - * @return a hash value for the object - */ - int hashVal() const - { - return _hashVal; - } - - inline static void Sort3Ints(int* sorted, int node1, int node2, int node3); - - private: - /// global numbers of the three nodes, sorted in ascending order - int _nodes[3]; - - /// hash value for the object, calculated in the constructor - int _hashVal; - }; - - /** - * Method to sort three integers in ascending order - * - * @param sorted int[3] array in which to store the result - * @param x1 first integer - * @param x2 second integer - * @param x3 third integer - */ - inline void TriangleFaceKey::Sort3Ints(int* sorted, int x1, int x2, int x3) - { - if(x1 < x2) - { - if(x1 < x3) - { - // x1 is min - sorted[0] = x1; - sorted[1] = x2 < x3 ? x2 : x3; - sorted[2] = x2 < x3 ? x3 : x2; - } - else - { - // x3, x1, x2 - sorted[0] = x3; - sorted[1] = x1; - sorted[2] = x2; - } - } - else // x2 < x1 - { - if(x2 < x3) - { - // x2 is min - sorted[0] = x2; - sorted[1] = x1 < x3 ? x1 : x3; - sorted[2] = x1 < x3 ? x3 : x1; - } - else - { - // x3, x2, x1 - sorted[0] = x3; - sorted[1] = x2; - sorted[2] = x1; - } - } - } - - /** - * \brief Template specialization of INTERP_KERNEL::hash function object for use with a - * with TriangleFaceKey as key class. - * - */ - template<> class hash - { - public: - /** - * Operator() that returns the precalculated hashvalue of a TriangleFaceKey object. - * - * @param key a TriangleFaceKey object - * @return an integer hash value for key - */ - int operator()(const INTERP_KERNEL::TriangleFaceKey& key) const - { - return key.hashVal(); - } - }; -} - -namespace INTERP_KERNEL -{ - /** - * \brief Class calculating the volume of intersection between a tetrahedral target element and - * source elements with triangular or quadratilateral faces. - * - */ - template - class SplitterTetra - { - public: - - SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId); - - SplitterTetra(const MyMeshType& srcMesh, const double tetraCorners[12], const int *conn = 0); - - ~SplitterTetra(); - - double intersectSourceCell(typename MyMeshType::MyConnType srcCell, double* baryCentre=0); - double intersectSourceFace(const NormalizedCellType polyType, - const int polyNodesNbr, - const int *const polyNodes, - const double *const *const polyCoords, - const double dimCaracteristic, - const double precision, - std::multiset& listOfTetraFacesTreated, - std::set& listOfTetraFacesColinear); - - double intersectTetra(const double** tetraCorners); - - typename MyMeshType::MyConnType getId(int id) { return _conn[id]; } - - void splitIntoDualCells(SplitterTetra **output); - - void splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId); - - void clearVolumesCache(); - - private: - inline static void CheckIsOutside(const double* pt, bool* isOutside, const double errTol = DEFAULT_ABS_TOL); - inline static void CheckIsStrictlyOutside(const double* pt, bool* isStrictlyOutside, const double errTol = DEFAULT_ABS_TOL); - inline void calculateNode(typename MyMeshType::MyConnType globalNodeNum); - inline void calculateNode2(typename MyMeshType::MyConnType globalNodeNum, const double* node); - inline void calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key); - inline void calculateSurface(TransformedTriangle& tri, const TriangleFaceKey& key); - - static inline bool IsFacesCoplanar(const double *const planeNormal, const double planeConstant, - const double *const *const coordsFace, const double precision); - static inline double CalculateIntersectionSurfaceOfCoplanarTriangles(const double *const planeNormal, - const double planeConstant, - const double *const p1, const double *const p2, const double *const p3, - const double *const p4, const double *const p5, const double *const p6, - const double dimCaracteristic, const double precision); - - /// disallow copying - SplitterTetra(const SplitterTetra& t); - - /// disallow assignment - SplitterTetra& operator=(const SplitterTetra& t); - - // member variables - /// affine transform associated with this target element - TetraAffineTransform* _t; - - /// HashMap relating node numbers to transformed nodes, used for caching - HashMap< int , double* > _nodes; - - /// HashMap relating triangular faces to calculated volume contributions, used for caching - HashMap< TriangleFaceKey, double > _volumes; - - /// reference to the source mesh - const MyMeshType& _src_mesh; - - // node id of the first node in target mesh in C mode. - typename MyMeshType::MyConnType _conn[4]; - - double _coords[12]; - - /// Smallest volume of the intersecting elements in the transformed space that will be returned as non-zero. - /// Since the scale is always the same in the transformed space (the target tetrahedron is unitary), this number is independent of the scale of the meshes. - static const double SPARSE_TRUNCATION_LIMIT; - }; - - /** - * Function used to filter out elements by checking if they belong to one of the halfspaces - * x <= 0, x >= 1, y <= 0, y >= 1, z <= 0, z >= 1, (indexed 0 - 7). The function updates an array of boolean variables - * which indicates whether the points that have already been checked are all in a halfspace. For each halfspace, - * the corresponding array element will be true if and only if it was true when the method was called and pt lies in the halfspace. - * - * @param pt double[3] containing the coordiantes of a transformed point - * @param isOutside bool[8] which indicate the results of earlier checks. - */ - template - inline void SplitterTetra::CheckIsOutside(const double* pt, bool* isOutside, const double errTol) - { - isOutside[0] = isOutside[0] && (pt[0] < errTol); - isOutside[1] = isOutside[1] && (pt[0] > (1.0-errTol) ); - isOutside[2] = isOutside[2] && (pt[1] < errTol); - isOutside[3] = isOutside[3] && (pt[1] > (1.0-errTol)); - isOutside[4] = isOutside[4] && (pt[2] < errTol); - isOutside[5] = isOutside[5] && (pt[2] > (1.0-errTol)); - isOutside[6] = isOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] < errTol); - isOutside[7] = isOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] > (1.0-errTol) ); - } - - template - inline void SplitterTetra::CheckIsStrictlyOutside(const double* pt, bool* isStrictlyOutside, const double errTol) - { - isStrictlyOutside[0] = isStrictlyOutside[0] && (pt[0] < -errTol); - isStrictlyOutside[1] = isStrictlyOutside[1] && (pt[0] > (1.0 + errTol)); - isStrictlyOutside[2] = isStrictlyOutside[2] && (pt[1] < -errTol); - isStrictlyOutside[3] = isStrictlyOutside[3] && (pt[1] > (1.0 + errTol)); - isStrictlyOutside[4] = isStrictlyOutside[4] && (pt[2] < -errTol); - isStrictlyOutside[5] = isStrictlyOutside[5] && (pt[2] > (1.0 + errTol)); - isStrictlyOutside[6] = isStrictlyOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] < -errTol); - isStrictlyOutside[7] = isStrictlyOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] > (1.0 + errTol)); - } - - /** - * Calculates the transformed node with a given global node number. - * Gets the coordinates for the node in _src_mesh with the given global number and applies TetraAffineTransform - * _t to it. Stores the result in the cache _nodes. The non-existance of the node in _nodes should be verified before - * calling. - * - * @param globalNodeNum global node number of the node in the mesh _src_mesh - * - */ - template - inline void SplitterTetra::calculateNode(typename MyMeshType::MyConnType globalNodeNum) - { - const double* node = _src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum; - double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; - assert(transformedNode != 0); - _t->apply(transformedNode, node); - _nodes[globalNodeNum] = transformedNode; - } - - - /** - * Calculates the transformed node with a given global node number. - * Applies TetraAffineTransform * _t to it. - * Stores the result in the cache _nodes. The non-existence of the node in _nodes should be verified before * calling. - * The only difference with the previous method calculateNode is that the coordinates of the node are passed in arguments - * and are not recalculated in order to optimize the method. - * - * @param globalNodeNum global node number of the node in the mesh _src_mesh - * - */ - template - inline void SplitterTetra::calculateNode2(typename MyMeshType::MyConnType globalNodeNum, const double* node) - { - double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; - assert(transformedNode != 0); - _t->apply(transformedNode, node); - _nodes[globalNodeNum] = transformedNode; - } - - /** - * Calculates the volume contribution from the given TransformedTriangle and stores it with the given key in . - * Calls TransformedTriangle::calculateIntersectionVolume to perform the calculation. - * - * @param tri triangle for which to calculate the volume contribution - * @param key key associated with the face - */ - template - inline void SplitterTetra::calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key) - { - const double vol = tri.calculateIntersectionVolume(); - _volumes.insert(std::make_pair(key, vol)); - } - - /** - * Calculates the surface contribution from the given TransformedTriangle and stores it with the given key in. - * Calls TransformedTriangle::calculateIntersectionSurface to perform the calculation. - * - * @param tri triangle for which to calculate the surface contribution - * @param key key associated with the face - */ - template - inline void SplitterTetra::calculateSurface(TransformedTriangle& tri, const TriangleFaceKey& key) - { - const double surf = tri.calculateIntersectionSurface(_t); - _volumes.insert(std::make_pair(key, surf)); - } - - template - class SplitterTetra2 - { - public: - SplitterTetra2(const MyMeshTypeT& targetMesh, const MyMeshTypeS& srcMesh, SplittingPolicy policy); - ~SplitterTetra2(); - void releaseArrays(); - void splitTargetCell2(typename MyMeshTypeT::MyConnType targetCell, typename std::vector< SplitterTetra* >& tetra); - void splitTargetCell(typename MyMeshTypeT::MyConnType targetCell, typename MyMeshTypeT::MyConnType nbOfNodesT, - typename std::vector< SplitterTetra* >& tetra);//to suppress - void fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra);//to suppress - void sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra);//to suppress - void calculateGeneral24Tetra(typename std::vector< SplitterTetra* >& tetra);//to suppress - void calculateGeneral48Tetra(typename std::vector< SplitterTetra* >& tetra);//to suppress - void splitPyram5(typename std::vector< SplitterTetra* >& tetra);//to suppress - void splitConvex(typename MyMeshTypeT::MyConnType targetCell,//to suppress - typename std::vector< SplitterTetra* >& tetra);//to suppress - void calculateSubNodes(const MyMeshTypeT& targetMesh, typename MyMeshTypeT::MyConnType targetCell);//to suppress - inline const double* getCoordsOfSubNode(typename MyMeshTypeT::MyConnType node);//to suppress - inline const double* getCoordsOfSubNode2(typename MyMeshTypeT::MyConnType node, typename MyMeshTypeT::MyConnType& nodeId);//to suppress - //template - inline void calcBarycenter(int n, double* barycenter, const typename MyMeshTypeT::MyConnType* pts);//to suppress - private: - const MyMeshTypeT& _target_mesh; - const MyMeshTypeS& _src_mesh; - SplittingPolicy _splitting_pol; - /// vector of pointers to double[3] containing the coordinates of the - /// (sub) - nodes of split target cell - std::vector _nodes; - std::vector _node_ids; - }; - - /** - * Calculates the barycenter of n (sub) - nodes - * - * @param n number of nodes for which to calculate barycenter - * @param barycenter pointer to double[3] array in which to store the result - * @param pts pointer to int[n] array containing the (sub)-nodes for which to calculate the barycenter - */ - template - //template - inline void SplitterTetra2::calcBarycenter(int n, double* barycenter, const typename MyMeshTypeT::MyConnType* pts) - { - barycenter[0] = barycenter[1] = barycenter[2] = 0.0; - for(int i = 0; i < n ; ++i) - { - const double* pt = getCoordsOfSubNode(pts[i]); - barycenter[0] += pt[0]; - barycenter[1] += pt[1]; - barycenter[2] += pt[2]; - } - - barycenter[0] /= n; - barycenter[1] /= n; - barycenter[2] /= n; - } - - /** - * Accessor to the coordinates of a given (sub)-node - * - * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. - * @return pointer to double[3] containing the coordinates of the nodes - */ - template - inline const double* SplitterTetra2::getCoordsOfSubNode(typename MyMeshTypeT::MyConnType node) - { - // replace "at()" with [] for unsafe but faster access - return _nodes.at(node); - } - - /** - * Accessor to the coordinates of a given (sub)-node - * - * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. - * @param nodeId is an output that is node id in target whole mesh in C mode. - * @return pointer to double[3] containing the coordinates of the nodes - */ - template - const double* SplitterTetra2::getCoordsOfSubNode2(typename MyMeshTypeT::MyConnType node, typename MyMeshTypeT::MyConnType& nodeId) - { - const double *ret=_nodes.at(node); - if(node<8) - nodeId=_node_ids[node]; - else - nodeId=-1; - return ret; - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/SplitterTetra.txx b/medtool/src/INTERP_KERNEL/SplitterTetra.txx deleted file mode 100644 index 226a6264c..000000000 --- a/medtool/src/INTERP_KERNEL/SplitterTetra.txx +++ /dev/null @@ -1,1319 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef __SPLITTERTETRA_TXX__ -#define __SPLITTERTETRA_TXX__ - -#include "SplitterTetra.hxx" - -#include "TetraAffineTransform.hxx" -#include "TransformedTriangle.hxx" -#include "MeshUtils.hxx" -#include "VectorUtils.hxx" -#include "CellModel.hxx" -#include "Log.hxx" -#include "UnitTetraIntersectionBary.hxx" -#include "VolSurfFormulae.hxx" - -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - const double SplitterTetra::SPARSE_TRUNCATION_LIMIT=1.0e-14; - - /*! - * output is expected to be allocated with 24*sizeof(void*) in order to store the 24 tetras. - * These tetras have to be deallocated. - */ - template - void SplitterTetra::splitIntoDualCells(SplitterTetra **output) - { - double tmp[12]; - const double *tmp2[4]={tmp,tmp+3,tmp+6,tmp+9}; - typename MyMeshType::MyConnType conn[4]={-1,-1,-1,-1}; - for(int i=0;i<24;i++) - { - splitMySelfForDual(tmp,i,conn[0]); - output[i]=new SplitterTetra(_src_mesh,tmp2,conn); - } - } - - /** - * SplitterTetra class computes for a list of cell ids of a given mesh \a srcMesh (badly named) the intersection with a - * single TETRA4 cell given by \a tetraCorners (of length 4) and \a nodesId (of length 4 too). \a nodedIds is given only to establish - * if a partial computation of a triangle has already been performed (to increase performance). - * - * The \a srcMesh can contain polyhedron cells. - * - * - * Constructor creating object from the four corners of the tetrahedron. - * - * @param srcMesh mesh containing the source elements - * @param tetraCorners array of four pointers to double[3] arrays containing the coordinates of the - * corners of the tetrahedron - */ - template - SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId) - : _t(0), _src_mesh(srcMesh) - { - std::copy(nodesId,nodesId+4,_conn); - _coords[0]=tetraCorners[0][0]; _coords[1]=tetraCorners[0][1]; _coords[2]=tetraCorners[0][2]; - _coords[3]=tetraCorners[1][0]; _coords[4]=tetraCorners[1][1]; _coords[5]=tetraCorners[1][2]; - _coords[6]=tetraCorners[2][0]; _coords[7]=tetraCorners[2][1]; _coords[8]=tetraCorners[2][2]; - _coords[9]=tetraCorners[3][0]; _coords[10]=tetraCorners[3][1]; _coords[11]=tetraCorners[3][2]; - // create the affine transform - _t=new TetraAffineTransform(_coords); - } - - /** - * SplitterTetra class computes for a list of cell ids of a given mesh \a srcMesh (badly named) the intersection with a - * single TETRA4 cell given by \a tetraCorners (of length 4) and \a nodesId (of length 4 too). \a nodedIds is given only to establish - * if a partial computation of a triangle has already been performed (to increase performance). - * - * The \a srcMesh can contain polyhedron cells. - * - * - * Constructor creating object from the four corners of the tetrahedron. - * - * \param [in] srcMesh mesh containing the source elements - * \param [in] tetraCorners array 4*3 doubles containing corners of input tetrahedron (P0X,P0Y,P0Y,P1X,P1Y,P1Z,P2X,P2Y,P2Z,P3X,P3Y,P3Z). - */ - template - SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const double tetraCorners[12], const int *conn): _t(0),_src_mesh(srcMesh) - { - if(!conn) - { _conn[0]=0; _conn[1]=1; _conn[2]=2; _conn[3]=3; } - else - { _conn[0]=conn[0]; _conn[1]=conn[1]; _conn[2]=conn[2]; _conn[3]=conn[3]; } - _coords[0]=tetraCorners[0]; _coords[1]=tetraCorners[1]; _coords[2]=tetraCorners[2]; _coords[3]=tetraCorners[3]; _coords[4]=tetraCorners[4]; _coords[5]=tetraCorners[5]; - _coords[6]=tetraCorners[6]; _coords[7]=tetraCorners[7]; _coords[8]=tetraCorners[8]; _coords[9]=tetraCorners[9]; _coords[10]=tetraCorners[10]; _coords[11]=tetraCorners[11]; - // create the affine transform - _t=new TetraAffineTransform(_coords); - } - - /** - * Destructor - * - * Deletes _t and the coordinates (double[3] vectors) in _nodes - * - */ - template - SplitterTetra::~SplitterTetra() - { - delete _t; - for(HashMap< int, double* >::iterator iter = _nodes.begin(); iter != _nodes.end() ; ++iter) - delete[] iter->second; - } - - /*! - * \Forget already calculated triangles, which is crucial for calculation of barycenter of intersection - */ - template - void SplitterTetra::clearVolumesCache() - { - _volumes.clear(); - } - - /*! - * This method destroys the 4 pointers pointed by tetraCorners[0],tetraCorners[1],tetraCorners[2] and tetraCorners[3] - * @param i is in 0..23 included. - * @param output is expected to be sized of 12 in order to. - */ - template - void SplitterTetra::splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId) - { - double *tmp[4]; - int offset=i/6; - nodeId=_conn[offset]; - tmp[0]=_coords+3*offset; tmp[1]=_coords+((offset+1)%4)*3; tmp[2]=_coords+((offset+2)%4)*3; tmp[3]=_coords+((offset+3)%4)*3; - int caseToTreat=i%6; - int case1=caseToTreat/2; - int case2=caseToTreat%2; - const int tab[3][2]={{1,2},{3,2},{1,3}}; - const int *curTab=tab[case1]; - double pt0[3]; pt0[0]=(tmp[curTab[case2]][0]+tmp[0][0])/2.; pt0[1]=(tmp[curTab[case2]][1]+tmp[0][1])/2.; pt0[2]=(tmp[curTab[case2]][2]+tmp[0][2])/2.; - double pt1[3]; pt1[0]=(tmp[0][0]+tmp[curTab[0]][0]+tmp[curTab[1]][0])/3.; pt1[1]=(tmp[0][1]+tmp[curTab[0]][1]+tmp[curTab[1]][1])/3.; pt1[2]=(tmp[0][2]+tmp[curTab[0]][2]+tmp[curTab[1]][2])/3.; - double pt2[3]; pt2[0]=(tmp[0][0]+tmp[1][0]+tmp[2][0]+tmp[3][0])/4.; pt2[1]=(tmp[0][1]+tmp[1][1]+tmp[2][1]+tmp[3][1])/4.; pt2[2]=(tmp[0][2]+tmp[1][2]+tmp[2][2]+tmp[3][2])/4.; - std::copy(pt1,pt1+3,output+case2*3); - std::copy(pt0,pt0+3,output+(abs(case2-1))*3); - std::copy(pt2,pt2+3,output+2*3); - std::copy(tmp[0],tmp[0]+3,output+3*3); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element. - * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the - * faces of the source element are triangulated and the calculated transformation is applied - * to each triangle. The algorithm of Grandy, implemented in INTERP_KERNEL::TransformedTriangle is used - * to calculate the contribution to the volume from each triangle. The volume returned is the sum of these contributions - * divided by the determinant of the transformation. - * - * The class will cache the intermediary calculations of transformed nodes of source cells and volumes associated - * with triangulated faces to avoid having to recalculate these. - * - * @param element global number of the source element in C mode. - */ - template - double SplitterTetra::intersectSourceCell(typename MyMeshType::MyConnType element, - double* baryCentre) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - //{ could be done on outside? - // check if we have planar tetra element - if(_t->determinant() == 0.0) - { - // tetra is planar - LOG(2, "Planar tetra -- volume 0"); - return 0.0; - } - - // get type of cell - NormalizedCellType normCellType=_src_mesh.getTypeOfElement(OTT::indFC(element)); - const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); - unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? _src_mesh.getNumberOfNodesOfElement(OTT::indFC(element)) : cellModelCell.getNumberOfNodes(); - // halfspace filtering - bool isOutside[8] = {true, true, true, true, true, true, true, true}; - bool isTargetOutside = false; - - // calculate the coordinates of the nodes - int *cellNodes=new int[nbOfNodes4Type]; - for(int i = 0;i<(int)nbOfNodes4Type;++i) - { - // we could store mapping local -> global numbers too, but not sure it is worth it - const int globalNodeNum = getGlobalNumberOfNode(i, OTT::indFC(element), _src_mesh); - cellNodes[i]=globalNodeNum; - if(_nodes.find(globalNodeNum) == _nodes.end()) - { - //for(HashMap< int , double* >::iterator iter3=_nodes.begin();iter3!=_nodes.end();iter3++) - // std::cout << (*iter3).first << " "; - //std::cout << std::endl << "*** " << globalNodeNum << std::endl; - calculateNode(globalNodeNum); - } - CheckIsOutside(_nodes[globalNodeNum], isOutside); - } - - // halfspace filtering check - // NB : might not be beneficial for caching of triangles - for(int i = 0; i < 8; ++i) - { - if(isOutside[i]) - { - isTargetOutside = true; - } - } - - double totalVolume = 0.0; - - if(!isTargetOutside) - { - /// calculator of intersection barycentre - UnitTetraIntersectionBary baryCalculator( _t->determinant() < 0.); - - // get nb of sons of a cell - const ConnType* rawCellConn = _src_mesh.getConnectivityPtr() + OTT::conn2C( _src_mesh.getConnectivityIndexPtr()[ element ]); - const int rawNbCellNodes = _src_mesh.getConnectivityIndexPtr()[ element+1 ] - _src_mesh.getConnectivityIndexPtr()[ element ]; - unsigned nbOfSons = cellModelCell.getNumberOfSons2(rawCellConn, rawNbCellNodes); - - for(unsigned ii = 0 ; ii < nbOfSons; ++ii) - { - // get sons connectivity - NormalizedCellType faceType; - int *faceNodes, nbFaceNodes=-1; - if ( cellModelCell.isDynamic() ) - { - faceNodes=new int[nbOfNodes4Type]; - nbFaceNodes = cellModelCell.fillSonCellNodalConnectivity2(ii,rawCellConn,rawNbCellNodes,faceNodes,faceType); - for ( int i = 0; i < nbFaceNodes; ++i ) - faceNodes[i] = OTT::coo2C(faceNodes[i]); - } - else - { - faceType = cellModelCell.getSonType(ii); - const CellModel& faceModel=CellModel::GetCellModel(faceType); - assert(faceModel.getDimension() == 2); - faceNodes=new int[faceModel.getNumberOfNodes()]; - cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); - } - // intersect a son with the unit tetra - switch(faceType) - { - case NORM_TRI3: - { - // create the face key - TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); - - // calculate the triangle if needed - if(_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); - calculateVolume(tri, key); - totalVolume += _volumes[key]; - if ( baryCentre ) - baryCalculator.addSide( tri ); - } else { - // count negative as face has reversed orientation - totalVolume -= _volumes[key]; - } - } - break; - - case NORM_QUAD4: - - // simple triangulation of faces along a diagonal : - // - // 2 ------ 3 - // | / | - // | / | - // | / | - // | / | - // | / | - // | / | - // 1 ------ 4 - // - //? not sure if this always works - { - // calculate the triangles if needed - - // local nodes 1, 2, 3 - TriangleFaceKey key1 = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); - if(_volumes.find(key1) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); - calculateVolume(tri, key1); - totalVolume += _volumes[key1]; - } else { - // count negative as face has reversed orientation - totalVolume -= _volumes[key1]; - } - - // local nodes 1, 3, 4 - TriangleFaceKey key2 = TriangleFaceKey(faceNodes[0], faceNodes[2], faceNodes[3]); - if(_volumes.find(key2) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[2]], _nodes[faceNodes[3]]); - calculateVolume(tri, key2); - totalVolume += _volumes[key2]; - } - else - { - // count negative as face has reversed orientation - totalVolume -= _volumes[key2]; - } - } - break; - - case NORM_POLYGON: - { - int nbTria = nbFaceNodes - 2; // split polygon into nbTria triangles - for ( int iTri = 0; iTri < nbTria; ++iTri ) - { - TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1+iTri], faceNodes[2+iTri]); - if(_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1+iTri]], _nodes[faceNodes[2+iTri]]); - calculateVolume(tri, key); - totalVolume += _volumes[key]; - } - else - { - totalVolume -= _volumes[key]; - } - } - } - break; - - default: - std::cout << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." << std::endl; - assert(false); - } - delete [] faceNodes; - } - - if ( baryCentre ) { - baryCalculator.getBary( baryCentre ); - _t->reverseApply( baryCentre, baryCentre ); - } - } - delete [] cellNodes; - // reset if it is very small to keep the matrix sparse - // is this a good idea? - if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) - { - totalVolume = 0.0; - } - - LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); - - // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation - // that should be used (which is equivalent to dividing by the determinant) - return std::fabs(1.0 / _t->determinant() * totalVolume) ; - } - - /** - * Calculates the intersection surface of two coplanar triangles. - * - * @param palneNormal normal of the plane for the first triangle - * @param planeConstant constant of the equation of the plane for the first triangle - * @param p1 coordinates of the first node of the first triangle - * @param p2 coordinates of the second node of the first triangle - * @param p3 coordinates of the third node of the first triangle - * @param p4 coordinates of the first node of the second triangle - * @param p5 coordinates of the second node of the second triangle - * @param p6 coordinates of the third node of the second triangle - * @param dimCaracteristic characteristic size of the meshes containing the triangles - * @param precision precision for double float data used for comparison - */ - template - double SplitterTetra::CalculateIntersectionSurfaceOfCoplanarTriangles(const double *const planeNormal, - const double planeConstant, - const double *const p1, const double *const p2, const double *const p3, - const double *const p4, const double *const p5, const double *const p6, - const double dimCaracteristic, const double precision) - { - typedef typename MyMeshType::MyConnType ConnType; - typedef double Vect2[2]; - typedef double Triangle2[3][2]; - - const double *const tri0[3] = {p1, p2, p3}; - const double *const tri1[3] = {p4, p5, p6}; - - // Plane of the first triangle defined by the normal of the triangle and the constant - // Project triangles onto coordinate plane most aligned with plane normal - int maxNormal = 0; - double fmax = std::abs(planeNormal[0]); - double absMax = std::abs(planeNormal[1]); - if (absMax > fmax) - { - maxNormal = 1; - fmax = absMax; - } - absMax = std::abs(planeNormal[2]); - if (absMax > fmax) - { - maxNormal = 2; - } - - Triangle2 projTri0, projTri1; - int i; - - if (maxNormal == 0) - { - // Project onto yz-plane. - for (i = 0; i < 3; ++i) - { - projTri0[i][0] = tri0[i][1]; - projTri0[i][1] = tri0[i][2]; - projTri1[i][0] = tri1[i][1]; - projTri1[i][1] = tri1[i][2]; - } - } - else if (maxNormal == 1) - { - // Project onto xz-plane. - for (i = 0; i < 3; ++i) - { - projTri0[i][0] = tri0[i][0]; - projTri0[i][1] = tri0[i][2]; - projTri1[i][0] = tri1[i][0]; - projTri1[i][1] = tri1[i][2]; - } - } - else - { - // Project onto xy-plane. - for (i = 0; i < 3; ++i) - { - projTri0[i][0] = tri0[i][0]; - projTri0[i][1] = tri0[i][1]; - projTri1[i][0] = tri1[i][0]; - projTri1[i][1] = tri1[i][1]; - } - } - - // 2D triangle intersection routines require counterclockwise ordering. - Vect2 save; - Vect2 edge0; - Vect2 edge1; - for (int ii = 0; ii < 2; ++ii) - { - edge0[ii] = projTri0[1][ii] - projTri0[0][ii]; - edge1[ii] = projTri0[2][ii] - projTri0[0][ii]; - } - if ((edge0[0] * edge1[1] - edge0[1] * edge1[0]) < (double) 0.) - { - // Triangle is clockwise, reorder it. - for (int ii = 0; ii < 2; ++ii) - { - save[ii] = projTri0[1][ii]; - projTri0[1][ii] = projTri0[2][ii]; - projTri0[2][ii] = save[ii]; - } - } - - for (int ii = 0; ii < 2; ++ii) - { - edge0[ii] = projTri1[1][ii] - projTri1[0][ii]; - edge1[ii] = projTri1[2][ii] - projTri1[0][ii]; - } - if ((edge0[0] * edge1[1] - edge0[1] * edge1[0]) < (double) 0.) - { - // Triangle is clockwise, reorder it. - for (int ii = 0; ii < 2; ++ii) - { - save[ii] = projTri1[1][ii]; - projTri1[1][ii] = projTri1[2][ii]; - projTri1[2][ii] = save[ii]; - } - } - - std::vector inter2; - intersec_de_triangle(projTri0[0], projTri0[1], projTri0[2], - projTri1[0], projTri1[1], projTri1[2], - inter2, - dimCaracteristic, precision); - ConnType nb_inter=((ConnType)inter2.size())/2; - double surface = 0.; - if(nb_inter >3) inter2=reconstruct_polygon(inter2); - if (nb_inter > 0) - { - std::vector inter3; - inter3.resize(3 * nb_inter); - // Map 2D intersections back to the 3D triangle space. - if (maxNormal == 0) - { - double invNX = ((double) 1.) / planeNormal[0]; - for (i = 0; i < nb_inter; i++) - { - inter3[3 * i + 1] = inter2[2 * i]; - inter3[3 * i + 2] = inter2[2 * i + 1]; - inter3[3 * i] = invNX * (planeConstant - planeNormal[1] * inter3[3 * i + 1] - planeNormal[2] * inter3[3 * i + 2]); - } - } - else if (maxNormal == 1) - { - double invNY = ((double) 1.) / planeNormal[1]; - for (i = 0; i < nb_inter; i++) - { - inter3[3 * i] = inter2[2 * i]; - inter3[3 * i + 2] = inter2[2 * i + 1]; - inter3[3 * i + 1] = invNY * (planeConstant - planeNormal[0] * inter3[3 * i] - planeNormal[2] * inter3[3 * i + 2]); - } - } - else - { - double invNZ = ((double) 1.) / planeNormal[2]; - for (i = 0; i < nb_inter; i++) - { - inter3[3 * i] = inter2[2 * i]; - inter3[3 * i + 1] = inter2[2 * i + 1]; - inter3[3 * i + 2] = invNZ * (planeConstant - planeNormal[0] * inter3[3 * i] - planeNormal[1] * inter3[3 * i + 1]); - } - } - surface = polygon_area<3>(inter3); - } - return surface; - } - - /** - * Determine if a face is coplanar with a triangle. - * The first face is characterized by the equation of her plane - * - * @param palneNormal normal of the plane for the first triangle - * @param planeConstant constant of the equation of the plane for the first triangle - * @param coordsFace coordinates of the triangle face - * @param precision precision for double float data used for comparison - */ - template - bool SplitterTetra::IsFacesCoplanar(const double *const planeNormal, - const double planeConstant, - const double *const *const coordsFace, - const double precision) - { - // Compute the signed distances of triangle vertices to the plane. Use an epsilon-thick plane test. - // For faces not left - int counter = 0; - for (int i = 0; i < 3; ++i) - { - const double distance = dot(planeNormal, coordsFace[i]) - planeConstant; - if (epsilonEqual(distance, precision)) - { - counter++; - } - } - return counter == 3; - } - - /** - * Calculates the surface of intersection of a polygon face in the source mesh and a cell of the target mesh. - * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the - * faces of the source element are triangulated and the calculated transformation is applied - * to each triangle. - * The algorithm is based on the algorithm of Grandy used in intersectSourceCell to compute - * the volume of intersection of two cell elements. - * The case with a source face colinear to one of the face of tetrahedrons is taking into account: - * the contribution of the face must not be counted two times. - * - * The class will cache the intermediary calculations of transformed nodes of source faces and surfaces associated - * with triangulated faces to avoid having to recalculate these. - * - * @param polyType type of the polygon source face - * @param polyNodesNbr number of the nodes of the polygon source face - * @param polyNodes numbers of the nodes of the polygon source face - * @param polyCoords coordinates of the nodes of the polygon source face - * @param dimCaracteristic characteristic size of the meshes containing the triangles - * @param precision precision for double float data used for comparison - * @param listOfTetraFacesTreated list of tetra faces treated - * @param listOfTetraFacesColinear list of tetra faces colinear with the polygon source faces - */ - template - double SplitterTetra::intersectSourceFace(const NormalizedCellType polyType, - const int polyNodesNbr, - const int *const polyNodes, - const double *const *const polyCoords, - const double dimCaracteristic, - const double precision, - std::multiset& listOfTetraFacesTreated, - std::set& listOfTetraFacesColinear) - { - double totalSurface = 0.0; - - // check if we have planar tetra element - if(_t->determinant() == 0.0) - { - // tetra is planar - LOG(2, "Planar tetra -- volume 0"); - return 0.0; - } - - // halfspace filtering - bool isOutside[8] = {true, true, true, true, true, true, true, true}; - bool isStrictlyOutside[8] = {true, true, true, true, true, true, true, true}; - bool isTargetStrictlyOutside = false; - bool isTargetOutside = false; - - // calculate the coordinates of the nodes - for(int i = 0;i<(int)polyNodesNbr;++i) - { - const int globalNodeNum = polyNodes[i]; - if(_nodes.find(globalNodeNum) == _nodes.end()) - { - calculateNode2(globalNodeNum, polyCoords[i]); - } - - CheckIsStrictlyOutside(_nodes[globalNodeNum], isStrictlyOutside, precision); - CheckIsOutside(_nodes[globalNodeNum], isOutside, precision); - } - - // halfspace filtering check - // NB : might not be beneficial for caching of triangles - for(int i = 0; i < 8; ++i) - { - if(isStrictlyOutside[i]) - { - isTargetStrictlyOutside = true; - break; - } - else if (isOutside[i]) - { - isTargetOutside = true; - } - } - - if (!isTargetStrictlyOutside) - { - - if (isTargetOutside) - { - // Faces are parallel - const int tetraFacesNodesConn[4][3] = { - { 0, 1, 2 }, - { 0, 2, 3 }, - { 0, 3, 1 }, - { 1, 2, 3 } }; - double planeNormal[3]; - for (int iTetraFace = 0; iTetraFace < 4; ++iTetraFace) - { - const int * const tetraFaceNodesConn = tetraFacesNodesConn[iTetraFace]; - TriangleFaceKey key = TriangleFaceKey(_conn[tetraFaceNodesConn[0]], - _conn[tetraFaceNodesConn[1]], - _conn[tetraFaceNodesConn[2]]); - if (listOfTetraFacesTreated.find(key) == listOfTetraFacesTreated.end()) - { - const double * const coordsTetraTriNode1 = _coords + tetraFaceNodesConn[0] * MyMeshType::MY_SPACEDIM; - const double * const coordsTetraTriNode2 = _coords + tetraFaceNodesConn[1] * MyMeshType::MY_SPACEDIM; - const double * const coordsTetraTriNode3 = _coords + tetraFaceNodesConn[2] * MyMeshType::MY_SPACEDIM; - calculateNormalForTria(coordsTetraTriNode1, coordsTetraTriNode2, coordsTetraTriNode3, planeNormal); - const double normOfTetraTriNormal = norm(planeNormal); - if (epsilonEqual(normOfTetraTriNormal, 0.)) - { - for (int i = 0; i < 3; ++i) - { - planeNormal[i] = 0.; - } - } - else - { - const double invNormOfTetraTriNormal = 1. / normOfTetraTriNormal; - for (int i = 0; i < 3; ++i) - { - planeNormal[i] *= invNormOfTetraTriNormal; - } - } - double planeConstant = dot(planeNormal, coordsTetraTriNode1); - if (IsFacesCoplanar(planeNormal, planeConstant, polyCoords, precision)) - { - int nbrPolyTri = polyNodesNbr - 2; // split polygon into nbrPolyTri triangles - for (int iTri = 0; iTri < nbrPolyTri; ++iTri) - { - double volume = CalculateIntersectionSurfaceOfCoplanarTriangles(planeNormal, - planeConstant, - polyCoords[0], - polyCoords[1 + iTri], - polyCoords[2 + iTri], - coordsTetraTriNode1, - coordsTetraTriNode2, - coordsTetraTriNode3, - dimCaracteristic, - precision); - if (!epsilonEqual(volume, 0.)) - { - totalSurface += volume; - listOfTetraFacesColinear.insert(key); - } - } - } - } - listOfTetraFacesTreated.insert(key); - } - } - else - { - // intersect a son with the unit tetra - switch (polyType) - { - case NORM_TRI3: - { - // create the face key - TriangleFaceKey key = TriangleFaceKey(polyNodes[0], polyNodes[1], polyNodes[2]); - - // calculate the triangle if needed - if (_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1]], _nodes[polyNodes[2]]); - calculateSurface(tri, key); - totalSurface += _volumes[key]; - } - else - { - // count negative as face has reversed orientation - totalSurface -= _volumes[key]; - } - } - break; - - case NORM_QUAD4: - - // simple triangulation of faces along a diagonal : - // - // 2 ------ 3 - // | / | - // | / | - // | / | - // | / | - // | / | - // | / | - // 1 ------ 4 - // - //? not sure if this always works - { - // calculate the triangles if needed - - // local nodes 1, 2, 3 - TriangleFaceKey key1 = TriangleFaceKey(polyNodes[0], polyNodes[1], polyNodes[2]); - if (_volumes.find(key1) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1]], _nodes[polyNodes[2]]); - calculateSurface(tri, key1); - totalSurface += _volumes[key1]; - } - else - { - // count negative as face has reversed orientation - totalSurface -= _volumes[key1]; - } - - // local nodes 1, 3, 4 - TriangleFaceKey key2 = TriangleFaceKey(polyNodes[0], polyNodes[2], polyNodes[3]); - if (_volumes.find(key2) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[2]], _nodes[polyNodes[3]]); - calculateSurface(tri, key2); - totalSurface += _volumes[key2]; - } - else - { - // count negative as face has reversed orientation - totalSurface -= _volumes[key2]; - } - } - break; - - case NORM_POLYGON: - { - int nbrPolyTri = polyNodesNbr - 2; // split polygon into nbrPolyTri triangles - for (int iTri = 0; iTri < nbrPolyTri; ++iTri) - { - TriangleFaceKey key = TriangleFaceKey(polyNodes[0], polyNodes[1 + iTri], polyNodes[2 + iTri]); - if (_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1 + iTri]], - _nodes[polyNodes[2 + iTri]]); - calculateSurface(tri, key); - totalSurface += _volumes[key]; - } - else - { - totalSurface -= _volumes[key]; - } - } - } - break; - - default: - std::cout - << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." - << std::endl; - assert(false); - } - - } - } - - // reset if it is very small to keep the matrix sparse - // is this a good idea? - if(epsilonEqual(totalSurface, 0.0, SPARSE_TRUNCATION_LIMIT)) - { - totalSurface = 0.0; - } - - LOG(2, "Volume = " << totalSurface << ", det= " << _t->determinant()); - - return totalSurface; - } - - /** - * Calculates the volume of intersection of this tetrahedron with another one. - */ - template - double SplitterTetra::intersectTetra(const double** tetraCorners) - { - //{ could be done on outside? - // check if we have planar tetra element - if(_t->determinant() == 0.0) - { - // tetra is planar - LOG(2, "Planar tetra -- volume 0"); - return 0.0; - } - - const unsigned nbOfNodes4Type=4; - // halfspace filtering - bool isOutside[8] = {true, true, true, true, true, true, true, true}; - bool isTargetOutside = false; - - // calculate the transformed coordinates of the nodes - double nodes[nbOfNodes4Type][3]; - for(int i = 0;i<(int)nbOfNodes4Type;++i) - { - _t->apply(nodes[i], tetraCorners[i]); - CheckIsOutside(nodes[i], isOutside); - } - - // halfspace filtering check - // NB : might not be beneficial for caching of triangles - for(int i = 0; i < 8; ++i) - { - if(isOutside[i]) - { - isTargetOutside = true; - } - } - - double totalVolume = 0.0; - - if(!isTargetOutside) - { - const CellModel& cellModelCell=CellModel::GetCellModel(NORM_TETRA4); - int cellNodes[4] = { 0, 1, 2, 3 }, faceNodes[3]; - - for(unsigned ii = 0 ; ii < 4 ; ++ii) - { - cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); - - TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); - double vol = tri.calculateIntersectionVolume(); - totalVolume += vol; - } - - // reset if it is very small to keep the matrix sparse - // is this a good idea? - if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) - { - totalVolume = 0.0; - } - } - LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); - - // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation - // that should be used (which is equivalent to dividing by the determinant) - return std::fabs(1.0 / _t->determinant() * totalVolume) ; - } - - //////////////////////////////////////////////////////// - - template - SplitterTetra2::SplitterTetra2(const MyMeshTypeT& targetMesh, const MyMeshTypeS& srcMesh, SplittingPolicy policy) - :_target_mesh(targetMesh),_src_mesh(srcMesh),_splitting_pol(policy) - { - } - - template - SplitterTetra2::~SplitterTetra2() - { - releaseArrays(); - } - - template - void SplitterTetra2::releaseArrays() - { - // free potential sub-mesh nodes that have been allocated - typename MyMeshTypeT::MyConnType nbOfNodesT = _node_ids.size();// Issue 0020634. - if((int)_nodes.size()>=/*8*/nbOfNodesT) - { - std::vector::iterator iter = _nodes.begin() + /*8*/nbOfNodesT; - while(iter != _nodes.end()) - { - delete[] *iter; - ++iter; - } - } - _nodes.clear(); - } - - /*! - * \param [in] targetCell in C mode. - * \param [out] tetra is the output result tetra containers. - */ - template - void SplitterTetra2::splitTargetCell2(typename MyMeshTypeT::MyConnType targetCell, typename std::vector< SplitterTetra* >& tetra) - { - const int *refConn(_target_mesh.getConnectivityPtr()); - const int *cellConn(refConn+_target_mesh.getConnectivityIndexPtr()[targetCell]); - INTERP_KERNEL::NormalizedCellType gt(_target_mesh.getTypeOfElement(targetCell)); - std::vector tetrasNodalConn; - std::vector addCoords; - const double *coords(_target_mesh.getCoordinatesPtr()); - SplitIntoTetras(_splitting_pol,gt,cellConn,refConn+_target_mesh.getConnectivityIndexPtr()[targetCell+1],coords,tetrasNodalConn,addCoords); - std::size_t nbTetras(tetrasNodalConn.size()/4); tetra.resize(nbTetras); - double tmp[12]; - int tmp2[4]; - for(std::size_t i=0;i=0) - { - tmp[j*3+0]=coords[3*cellId+0]; - tmp[j*3+1]=coords[3*cellId+1]; - tmp[j*3+2]=coords[3*cellId+2]; - } - else - { - tmp[j*3+0]=addCoords[3*(-cellId-1)+0]; - tmp[j*3+1]=addCoords[3*(-cellId-1)+1]; - tmp[j*3+2]=addCoords[3*(-cellId-1)+2]; - } - } - tetra[i]=new SplitterTetra(_src_mesh,tmp,tmp2); - } - } - - /*! - * @param targetCell in C mode. - * @param tetra is the output result tetra containers. - */ - template - void SplitterTetra2::splitTargetCell(typename MyMeshTypeT::MyConnType targetCell, - typename MyMeshTypeT::MyConnType nbOfNodesT, - typename std::vector< SplitterTetra* >& tetra) - { - typedef typename MyMeshTypeT::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshTypeT::My_numPol; - const int numTetra = static_cast(_splitting_pol); - if(nbOfNodesT==4) - { - _nodes.resize(8); - _node_ids.resize(8); - tetra.reserve(1); - const double *nodes[4]; - int conn[4]; - for(int node = 0; node < 4 ; ++node) - { - nodes[node]=getCoordsOfNode2(node, OTT::indFC(targetCell),_target_mesh,conn[node]); - } - std::copy(conn,conn+4,_node_ids.begin()); - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - return ; - } - // Issue 0020634. To pass nbOfNodesT to calculateSubNodes (don't want to add an arg) - _node_ids.resize(nbOfNodesT); - - // pre-calculate nodes - calculateSubNodes(_target_mesh, OTT::indFC(targetCell)); - - tetra.reserve(numTetra); - _nodes.reserve(30); // we never have more than this - - switch ( nbOfNodesT ) - { - case 8: - { - switch(_splitting_pol) - { - case PLANAR_FACE_5: - { - const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - fiveSplit(subZone,tetra); - } - break; - - case PLANAR_FACE_6: - { - const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - sixSplit(subZone,tetra); - } - break; - - case GENERAL_24: - { - calculateGeneral24Tetra(tetra); - } - break; - - case GENERAL_48: - { - calculateGeneral48Tetra(tetra); - } - break; - default: - assert(false); - } - break; - } - case 5: - { - splitPyram5(tetra); - break; - } - default: - { - splitConvex(targetCell, tetra); - } - } - } - - /** - * Splits the hexahedron into five tetrahedra. - * This method adds five SplitterTetra objects to the vector tetra. - * - * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the - * splitting to be reused on the subzones of the GENERAL_* types of splitting - */ - template - void SplitterTetra2::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) - { - // create tetrahedra - for(int i = 0; i < 5; ++i) - { - const double* nodes[4]; - int conn[4]; - for(int j = 0; j < 4; ++j) - { - conn[j] = subZone[ SPLIT_NODES_5[4*i+j] ]; - nodes[j] = getCoordsOfSubNode(conn[j]); - } - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - } - - /** - * Splits the hexahedron into six tetrahedra. - * This method adds six SplitterTetra objects to the vector tetra. - * - * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the - * splitting to be reused on the subzones of the GENERAL_* types of splitting - */ - template - void SplitterTetra2::sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) - { - for(int i = 0; i < 6; ++i) - { - const double* nodes[4]; - int conn[4]; - for(int j = 0; j < 4; ++j) - { - conn[j] = subZone[SPLIT_NODES_6[4*i+j]]; - nodes[j] = getCoordsOfSubNode(conn[j]); - } - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - } - - /** - * Splits the hexahedron into 24 tetrahedra. - * The splitting is done by combining the barycenter of the tetrahedron, the barycenter of each face - * and the nodes of each edge of the face. This creates 6 faces * 4 edges / face = 24 tetrahedra. - * The submesh nodes introduced are the barycenters of the faces and the barycenter of the cell. - * - */ - template - void SplitterTetra2::calculateGeneral24Tetra(typename std::vector< SplitterTetra* >& tetra) - { - // The two nodes of the original mesh cell used in each tetrahedron. - // The tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2) - // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes - - // nodes to use for tetrahedron - const double* nodes[4]; - int conn[4]; - // get the cell center - conn[0] = 14; - nodes[0] = getCoordsOfSubNode(conn[0]); - - for(int faceCenterNode = 8; faceCenterNode < 14; ++faceCenterNode) - { - // get the face center - conn[1] = faceCenterNode; - nodes[1] = getCoordsOfSubNode(conn[1]); - for(int j = 0; j < 4; ++j) - { - const int row = 4*(faceCenterNode - 8) + j; - conn[2] = TETRA_EDGES_GENERAL_24[2*row]; - conn[3] = TETRA_EDGES_GENERAL_24[2*row + 1]; - nodes[2] = getCoordsOfSubNode(conn[2]); - nodes[3] = getCoordsOfSubNode(conn[3]); - - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes, conn); - tetra.push_back(t); - } - } - } - - - /** - * Splits the hexahedron into 48 tetrahedra. - * The splitting is done by introducing the midpoints of all the edges - * and the barycenter of the element as submesh nodes. The 8 hexahedral subzones thus defined - * are then split into 6 tetrahedra each, as in Grandy, p. 449. The division of the subzones - * is done by calling sixSplit(). - * - */ - template - void SplitterTetra2::calculateGeneral48Tetra(typename std::vector< SplitterTetra* >& tetra) - { - for(int i = 0; i < 8; ++i) - { - sixSplit(GENERAL_48_SUBZONES+8*i,tetra); - } - } - - /** - * Splits the NORM_PYRA5 into 2 tetrahedra. - */ - template - void SplitterTetra2::splitPyram5(typename std::vector< SplitterTetra* >& tetra) - { - static const int SPLIT_PYPA5[2][4] = - { - { - 0, 1, 2, 4 - }, - { - 0, 2, 3, 4 - } - }; - - // create tetrahedra - const double* nodes[4]; - int conn[4]; - for(int i = 0; i < 2; ++i) - { - for(int j = 0; j < 4; ++j) - nodes[j] = getCoordsOfSubNode2(SPLIT_PYPA5[i][j],conn[j]); - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - } - - /** - * Splits a convex cell into tetrahedra. - */ - template - void SplitterTetra2::splitConvex(typename MyMeshTypeT::MyConnType targetCell, - typename std::vector< SplitterTetra* >& tetra) - { - // Each face of a cell is split into triangles and - // each of triangles and a cell barycenter form a tetrahedron. - - typedef typename MyMeshTypeT::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshTypeT::My_numPol; - - // get type of cell and nb of cell nodes - NormalizedCellType normCellType=_target_mesh.getTypeOfElement(OTT::indFC(targetCell)); - const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); - unsigned nbOfCellNodes=cellModelCell.isDynamic() ? _target_mesh.getNumberOfNodesOfElement(OTT::indFC(targetCell)) : cellModelCell.getNumberOfNodes(); - - // get nb of cell sons (faces) - const ConnType* rawCellConn = _target_mesh.getConnectivityPtr() + OTT::conn2C( _target_mesh.getConnectivityIndexPtr()[ targetCell ]); - const int rawNbCellNodes = _target_mesh.getConnectivityIndexPtr()[ targetCell+1 ] - _target_mesh.getConnectivityIndexPtr()[ targetCell ]; - unsigned nbOfSons = cellModelCell.getNumberOfSons2(rawCellConn, rawNbCellNodes); - - // indices of nodes of a son - static std::vector allNodeIndices; // == 0,1,2,...,nbOfCellNodes-1 - while ( allNodeIndices.size() < nbOfCellNodes ) - allNodeIndices.push_back( allNodeIndices.size() ); - std::vector classicFaceNodes(4); - if(cellModelCell.isQuadratic()) - throw INTERP_KERNEL::Exception("SplitterTetra2::splitConvex : quadratic 3D cells are not implemented yet !"); - int* faceNodes = cellModelCell.isDynamic() ? &allNodeIndices[0] : &classicFaceNodes[0]; - - // nodes of tetrahedron - int conn[4]; - const double* nodes[4]; - nodes[3] = getCoordsOfSubNode2( nbOfCellNodes,conn[3]); // barycenter - - for(unsigned ii = 0 ; ii < nbOfSons; ++ii) - { - // get indices of son's nodes: it's just next portion of allNodeIndices for polyhedron - // and some of allNodeIndices accodring to cell model for a classsic cell - unsigned nbFaceNodes = cellModelCell.getNumberOfNodesConstituentTheSon2(ii, rawCellConn, rawNbCellNodes); - if ( normCellType != NORM_POLYHED ) - cellModelCell.fillSonCellNodalConnectivity(ii,&allNodeIndices[0],faceNodes); - - int nbTetra = nbFaceNodes - 2; // split polygon into nbTetra triangles - - // create tetrahedra - for(int i = 0; i < nbTetra; ++i) - { - nodes[0] = getCoordsOfSubNode2( faceNodes[0], conn[0]); - nodes[1] = getCoordsOfSubNode2( faceNodes[1+i],conn[1]); - nodes[2] = getCoordsOfSubNode2( faceNodes[2+i],conn[2]); - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - - if ( normCellType == NORM_POLYHED ) - faceNodes += nbFaceNodes; // go to the next face - } - } - - /** - * Precalculates all the nodes. - * Retrieves the mesh nodes and allocates the necessary sub-mesh - * nodes according to the splitting policy used. - * This method is meant to be called once by the constructor. - * - * @param targetMesh the target mesh - * @param targetCell the global number of the cell that the object represents, in targetMesh mode. - * @param policy the splitting policy of the object - * - */ - template - void SplitterTetra2::calculateSubNodes(const MyMeshTypeT& targetMesh, typename MyMeshTypeT::MyConnType targetCell) - { - // retrieve real mesh nodes - - typename MyMeshTypeT::MyConnType nbOfNodesT = _node_ids.size();// Issue 0020634. _node_ids.resize(8); - for(int node = 0; node < nbOfNodesT ; ++node) - { - // calculate only normal nodes - _nodes.push_back(getCoordsOfNode2(node, targetCell, targetMesh,_node_ids[node])); - } - - switch ( nbOfNodesT ) - { - case 8: - - // create sub-mesh nodes if needed - switch(_splitting_pol) - { - case GENERAL_24: - { - for(int i = 0; i < 7; ++i) - { - double* barycenter = new double[3]; - calcBarycenter(4, barycenter, &GENERAL_24_SUB_NODES[4*i]); - _nodes.push_back(barycenter); - } - } - break; - - case GENERAL_48: - { - for(int i = 0; i < 19; ++i) - { - double* barycenter = new double[3]; - calcBarycenter(2, barycenter, &GENERAL_48_SUB_NODES[2*i]); - _nodes.push_back(barycenter); - } - } - break; - - default: - break; - } - - case 5: // NORM_PYRA5 - break; - - default: // convex 3d cell - { - // add barycenter of a cell - std::vector allIndices(nbOfNodesT); - for ( int i = 0; i < nbOfNodesT; ++i ) allIndices[i] = i; - double* barycenter = new double[3]; - calcBarycenter(nbOfNodesT, barycenter, &allIndices[0]); - _nodes.push_back(barycenter); - } - } - - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/TargetIntersector.hxx b/medtool/src/INTERP_KERNEL/TargetIntersector.hxx deleted file mode 100644 index e79d1e747..000000000 --- a/medtool/src/INTERP_KERNEL/TargetIntersector.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __TARGETINTERSECTOR__HXX__ -#define __TARGETINTERSECTOR__HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - /** - * \brief Abstract base class of Intersector classes. - * These classes represent a target element and calculate its intersection - * with the source elements. - */ - template - class TargetIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - /*! - * Tool for cell intersection, result is always positive. - * @param icellT id of cell in target mesh in \b C \b mode. - * @param icellsS ids of cells in source mesh in \b C \b mode. - * @param res is an IN/OUT parameter that represents the icellTth row in final matrix, fed with at most icellsS elements. - */ - virtual void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) = 0; - - virtual int getNumberOfRowsOfResMatrix() const = 0; - virtual int getNumberOfColsOfResMatrix() const = 0; - virtual ~TargetIntersector() { } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/TetraAffineTransform.cxx b/medtool/src/INTERP_KERNEL/TetraAffineTransform.cxx deleted file mode 100644 index f01b160d6..000000000 --- a/medtool/src/INTERP_KERNEL/TetraAffineTransform.cxx +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TetraAffineTransform.hxx" -#include "VectorUtils.hxx" - -#include -#include -#include - -#include "Log.hxx" - -namespace INTERP_KERNEL -{ - ///////////////////////////////////////////////////////////////////////////////////////// - /// PUBLIC INTERFACE METHODS ////////////// - ///////////////////////////////////////////////////////////////////////////////////////// - - /** - * Constructor - * Create the TetraAffineTransform object from the tetrahedron - * with corners specified in pts. If the tetrahedron is degenerate or almost degenerate, - * construction succeeds, but the determinant of the transform is set to 0. - * - * @param pts a 4x3 matrix containing 4 points (P0X,P0Y,P0Z,P1X,P1Y,P1Z,...) of 3 coordinates each - */ - TetraAffineTransform::TetraAffineTransform(const double *pts) - { - - LOG(2,"Creating transform from tetraeder : "); - - // three last points -> linear transform - for(int i = 0; i < 3 ; ++i) - { - for(int j = 0 ; j < 3 ; ++j) - { - // NB we insert columns, not rows - _linear_transform[3*j + i] = pts[(i+1)*3+j] - pts[j]; - } - } - - // remember _linear_transform for the reverse transformation - memcpy( _back_linear_transform, _linear_transform, 9*sizeof(double)); - memcpy( _back_translation, pts, 3*sizeof(double)); - - calculateDeterminant(); - - LOG(3, "determinant before inverse = " << _determinant); - - // check that tetra is non-planar -> determinant is not zero - // otherwise set _determinant to zero to signal caller that transformation did not work - if(epsilonEqual(_determinant, 0.0)) - { - _determinant = 0.0; - return; - } - - // we need the inverse transform - invertLinearTransform(); - - // first point -> translation - // calculate here because translation takes place in "transformed space", - // or in other words b = -A*O where A is the linear transform - // and O is the position vector of the point that is mapped onto the origin - for(int i = 0 ; i < 3 ; ++i) - { - _translation[i] = -(_linear_transform[3*i]*pts[0] + _linear_transform[3*i+1]*pts[1] + _linear_transform[3*i+2]*pts[2]) ; - } - - // precalculate determinant (again after inversion of transform) - calculateDeterminant(); - -#ifdef INVERSION_SELF_CHECK - // debugging : check that applying the inversed transform to the original points - // gives us the unit tetrahedron - LOG(4, "transform determinant is " << _determinant); - LOG(4, "*Self-check : Applying transformation to original points ... "); - for(int i = 0; i < 4 ; ++i) - { - double v[3]; - apply(v, pts+3*i); - LOG(4, vToStr(v)) - for(int j = 0; j < 3; ++j) - { - assert(epsilonEqual(v[j], (3*i+j == 3 || 3*i+j == 7 || 3*i+j == 11 ) ? 1.0 : 0.0)); - } - } - - LOG(4, " ok"); -#endif - } - - /** - * Calculates the transform of point srcPt and stores the result in destPt. - * If destPt == srcPt, then srcPt is overwritten safely. - * - * - * @param destPt double[3] in which to store the transformed point - * @param srcPt double[3] containing coordinates of points to be transformed - * - */ - void TetraAffineTransform::apply(double* destPt, const double* srcPt) const - { - double* dest = destPt; - - // are we self-allocating ? - const bool selfAllocation = (destPt == srcPt); - - if(selfAllocation) - { - // alloc temporary memory - dest = new double[3]; - - LOG(6, "Info : Self-affectation in TetraAffineTransform::apply"); - } - - for(int i = 0 ; i < 3 ; ++i) - { - // matrix - vector multiplication - dest[i] = _linear_transform[3*i] * srcPt[0] + _linear_transform[3*i + 1] * srcPt[1] + _linear_transform[3*i + 2] * srcPt[2]; - - // translation - dest[i] += _translation[i]; - } - - if(selfAllocation) - { - // copy result back to destPt - for(int i = 0 ; i < 3 ; ++i) - { - destPt[i] = dest[i]; - } - delete[] dest; - } - } - - /** - * Calculates the reverse transform of point srcPt and stores the result in destPt. - * If destPt == srcPt, then srcPt is overwritten safely. - * - * @param destPt double[3] in which to store the transformed point - * @param srcPt double[3] containing coordinates of points to be transformed - */ - void TetraAffineTransform::reverseApply(double* destPt, const double* srcPt) const - { - double* dest = destPt; - - // are we self-allocating ? - const bool selfAllocation = (destPt == srcPt); - - if(selfAllocation) - { - // alloc temporary memory - dest = new double[3]; - - LOG(6, "Info : Self-affectation in TetraAffineTransform::reverseApply"); - } - - for(int i = 0 ; i < 3 ; ++i) - { - // matrix - vector multiplication - dest[i] = _back_linear_transform[3*i] * srcPt[0] + _back_linear_transform[3*i + 1] * srcPt[1] + _back_linear_transform[3*i + 2] * srcPt[2]; - - // translation - dest[i] += _back_translation[i]; - } - - if(selfAllocation) - { - // copy result back to destPt - for(int i = 0 ; i < 3 ; ++i) - { - destPt[i] = dest[i]; - } - delete[] dest; - } - } - - /** - * Returns the determinant of the linear part A of the transform. - * - * @return determinant of the transform - * - */ - double TetraAffineTransform::determinant() const - { - return _determinant; - } - - /** - * Outputs to std::cout the matrix A and the vector b - * of the transform Ax + b - * - */ - void TetraAffineTransform::dump() const - { - std::cout << "A = " << std::endl << "["; - for(int i = 0; i < 3; ++i) - { - std::cout << _linear_transform[3*i] << ", " << _linear_transform[3*i + 1] << ", " << _linear_transform[3*i + 2]; - if(i != 2 ) std::cout << std::endl; - } - std::cout << "]" << std::endl; - - std::cout << "b = " << "[" << _translation[0] << ", " << _translation[1] << ", " << _translation[2] << "]" << std::endl; - } - - ///////////////////////////////////////////////////////////////////////////////////////// - /// PRIVATE METHODS ////////////// - ///////////////////////////////////////////////////////////////////////////////////////// - - /** - * Calculates the inverse of the matrix A, stored in _linear_transform - * by LU-factorization and substitution - * - */ - void TetraAffineTransform::invertLinearTransform() - { - //{ we copy the matrix for the lu-factorization - // maybe inefficient - double lu[9]; - for(int i = 0 ; i < 9; ++i) - { - lu[i] = _linear_transform[i]; - } - - // calculate LU factorization - int idx[3]; - factorizeLU(lu, idx); - - // calculate inverse by forward and backward substitution - // store in _linear_transform - // NB _linear_transform cannot be overwritten with lu in the loop - for(int i = 0 ; i < 3 ; ++i) - { - // form standard base vector i - const double b[3] = - { - double ( int(i == 0) ), - double ( int(i == 1) ), - double ( int(i == 2) ), - }; - - LOG(6, "b = [" << b[0] << ", " << b[1] << ", " << b[2] << "]"); - - double y[3]; - forwardSubstitution(y, lu, b, idx); - - double x[3]; - backwardSubstitution(x, lu, y, idx); - - // copy to _linear_transform matrix - // NB : this is a column operation, so we cannot - // do this directly when we calculate x - for(int j = 0 ; j < 3 ; j++) - { - _linear_transform[3*j + i] = x[idx[j]]; - } - } - } - - /** - * Updates the member _determinant of the matrix A of the transformation. - * - */ - void TetraAffineTransform::calculateDeterminant() - { - const double subDet[3] = - { - _linear_transform[4] * _linear_transform[8] - _linear_transform[5] * _linear_transform[7], - _linear_transform[3] * _linear_transform[8] - _linear_transform[5] * _linear_transform[6], - _linear_transform[3] * _linear_transform[7] - _linear_transform[4] * _linear_transform[6] - }; - - _determinant = _linear_transform[0] * subDet[0] - _linear_transform[1] * subDet[1] + _linear_transform[2] * subDet[2]; - } - - - ///////////////////////////////////////////////// - /// Auxiliary methods for inverse calculation /// - ///////////////////////////////////////////////// - - - /** - * Calculates the LU-factorization of the matrix A (_linear_transform) - * and stores it in lu. Since partial pivoting is used, there are - * row swaps. This is represented by the index permutation vector idx : to access element - * (i,j) of lu, use lu[3*idx[i] + j] - * - * @param lu double[9] in which to store LU-factorization - * @param idx int[3] in which to store row permutation vector - */ - void TetraAffineTransform::factorizeLU(double* lu, int* idx) const - { - // 3 x 3 LU factorization - // initialise idx - for(int i = 0 ; i < 3 ; ++i) - { - idx[i] = i; - } - - for(int k = 0; k < 2 ; ++k) - { - - // find pivot - int i = k; - double max = std::fabs(lu[3*idx[k] + k]); - int row = i; - while(i < 3) - { - if(std::fabs(lu[3*idx[i] + k]) > max) - { - max = fabs(lu[3*idx[i] + k]); - row = i; - } - ++i; - } - - // swap rows in index vector - int tmp = idx[k]; - idx[k] = idx[row]; - idx[row] = tmp; - - // calculate row - for(int j = k + 1 ; j < 3 ; ++j) - { - // l_jk = u_jk / u_kk - lu[3*idx[j] + k] /= lu[3*idx[k] + k]; - for(int s = k + 1; s < 3 ; ++s) - { - // case s = k will always become zero, and then be replaced by - // the l-value - // there's no need to calculate this explicitly - - // u_js = u_js - l_jk * u_ks - lu[3*idx[j] + s] -= lu[3*idx[j] + k] * lu[3*idx[k] + s] ; - } - } - } - } - - /** - * Solves the system Lx = b, where L is lower unit-triangular (ones on the diagonal) - * - * @param x double[3] in which the solution is stored - * @param lu double[9] containing the LU-factorization - * @param b double[3] containing the right-hand side - * @param idx int[3] containing the permutation vector associated with lu - * - */ - void TetraAffineTransform::forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const - { - // divisions are not carried out explicitly because lu does not store - // the diagonal values of L, which are all 1 - // Compare with backwardSubstitution() - x[idx[0]] = ( b[idx[0]] ); // / lu[3*idx[0]] - x[idx[1]] = ( b[idx[1]] - lu[3*idx[1]] * x[idx[0]] ); // / lu[3*idx[1] + 1]; - x[idx[2]] = ( b[idx[2]] - lu[3*idx[2]] * x[idx[0]] - lu[3*idx[2] + 1] * x[idx[1]] ); // / lu[3*idx[2] + 2]; - } - - /** - * Solves the system Ux = b, where U is upper-triangular - * - * @param x double[3] in which the solution is stored - * @param lu double[9] containing the LU-factorization - * @param b double[3] containing the right-hand side - * @param idx int[3] containing the permutation vector associated with lu - * - */ - void TetraAffineTransform::backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const - { - x[idx[2]] = ( b[idx[2]] ) / lu[3*idx[2] + 2]; - x[idx[1]] = ( b[idx[1]] - lu[3*idx[1] + 2] * x[idx[2]] ) / lu[3*idx[1] + 1]; - x[idx[0]] = ( b[idx[0]] - lu[3*idx[0] + 1] * x[idx[1]] - lu[3*idx[0] + 2] * x[idx[2]] ) / lu[3*idx[0]]; - } - -} diff --git a/medtool/src/INTERP_KERNEL/TetraAffineTransform.hxx b/medtool/src/INTERP_KERNEL/TetraAffineTransform.hxx deleted file mode 100644 index fcdb152db..000000000 --- a/medtool/src/INTERP_KERNEL/TetraAffineTransform.hxx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TETRA_AFFINE_TRANSFORM_HXX__ -#define __TETRA_AFFINE_TRANSFORM_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#undef INVERSION_SELF_CHECK // debugging : check that calculated inverse is correct - -namespace INTERP_KERNEL -{ - /** - * \brief Class representing an affine transformation x -> Ax + b that transforms a given tetrahedron - * into the unit tetrahedron. - * - */ - class INTERPKERNEL_EXPORT TetraAffineTransform - { - - public: - TetraAffineTransform(const double *pts); - - void apply(double* destPt, const double* srcPt) const; - - void reverseApply(double* destPt, const double* srcPt) const; - - double determinant() const; - - void dump() const; - - private: - - void invertLinearTransform(); - - void calculateDeterminant(); - - void factorizeLU(double* lu, int* idx) const; - - void forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; - - void backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; - - // The affine transformation Ax + b is represented with _linear_transformation containing the elements of - // A in row-first ordering and _translation containing the elements of b - - /// 3x3 matrix A in affine transform x -> Ax + b - double _linear_transform[9]; - - /// 3x1 vector b in affine transform x -> Ax + b - double _translation[3]; - - /// The determinant of the matrix A is calculated at the construction of the object and cached. - double _determinant; - - /// 3x3 matrix AT is transposed A matrix used for y -> ATy - c transformation - double _back_linear_transform[9]; - - /// 3x1 vector c in affine transform y -> ATy - c - double _back_translation[3]; - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/TransformedTriangle.cxx b/medtool/src/INTERP_KERNEL/TransformedTriangle.cxx deleted file mode 100644 index 8b735cb46..000000000 --- a/medtool/src/INTERP_KERNEL/TransformedTriangle.cxx +++ /dev/null @@ -1,842 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangle.hxx" -#include "VectorUtils.hxx" -#include "TetraAffineTransform.hxx" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing a circular order of a set of points around their barycenter. - * It is used with the STL sort() algorithm to sort the point of the two polygons - * - */ - class ProjectedCentralCircularSortOrder - { - public: - - /// Enumeration of different planes to project on when calculating order - enum CoordType { XY, XZ, YZ }; - - /** - * Constructor - * - * @param barycenter double[3] containing the barycenter of the points to be compared - * @param type plane to project on when comparing. The comparison will not work if all the points are in a plane perpendicular - * to the plane being projected on - */ - ProjectedCentralCircularSortOrder(const double* barycenter, const CoordType type) - : _aIdx((type == YZ) ? 1 : 0), - _bIdx((type == XY) ? 1 : 2), - _a(barycenter[_aIdx]), - _b(barycenter[_bIdx]) - { - } - - /** - * Comparison operator. - * Compares the relative position between two points in their ordering around the barycenter. - * - * @param pt1 a double[3] representing a point - * @param pt2 a double[3] representing a point - * @return true if the angle of the difference vector between pt1 and the barycenter is greater than that - * of the difference vector between pt2 and the barycenter. - */ - bool operator()(const double* pt1, const double* pt2) - { - // calculate angles with the axis - const double ang1 = atan2(pt1[_aIdx] - _a, pt1[_bIdx] - _b); - const double ang2 = atan2(pt2[_aIdx] - _a, pt2[_bIdx] - _b); - - return ang1 > ang2; - } - - private: - /// index corresponding to first coordinate of plane on which points are projected - const int _aIdx; - - /// index corresponding to second coordinate of plane on which points are projected - const int _bIdx; - - /// value of first projected coordinate of the barycenter - const double _a; - - /// value of second projected coordinate of the barycenter - const double _b; - }; - - // ---------------------------------------------------------------------------------- - // TransformedTriangle PUBLIC - // ---------------------------------------------------------------------------------- - - /** - * Constructor - * - * The coordinates are copied to the internal member variables - * - * @param p array of three doubles containing coordinates of P - * @param q array of three doubles containing coordinates of Q - * @param r array of three doubles containing coordinates of R - */ - TransformedTriangle::TransformedTriangle(double* p, double* q, double* r) - : _is_double_products_calculated(false), _is_triple_products_calculated(false), _volume(0) - { - - for(int i = 0 ; i < 3 ; ++i) - { - // xyz coordinates - _coords[5*P + i] = p[i]; - _coords[5*Q + i] = q[i]; - _coords[5*R + i] = r[i]; - } - - // h coordinate - - _coords[5*P + 3] = 1 - p[0] - p[1] - p[2]; - _coords[5*Q + 3] = 1 - q[0] - q[1] - q[2]; - _coords[5*R + 3] = 1 - r[0] - r[1] - r[2]; - - // H coordinate - _coords[5*P + 4] = 1 - p[0] - p[1]; - _coords[5*Q + 4] = 1 - q[0] - q[1]; - _coords[5*R + 4] = 1 - r[0] - r[1]; - - resetNearZeroCoordinates(); - - // initialise rest of data - preCalculateDoubleProducts(); - - preCalculateTriangleSurroundsEdge(); - - preCalculateTripleProducts(); - - } - - /** - * Destructor - * - * Deallocates the memory used to store the points of the polygons. - * This memory is allocated in calculateIntersectionAndProjectionPolygons(). - */ - TransformedTriangle::~TransformedTriangle() - { - // delete elements of polygons - for(std::vector::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) - { - delete[] *it; - } - for(std::vector::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) - { - delete[] *it; - } - } - - /** - * Calculates the volume of intersection between the triangle and the - * unit tetrahedron. - * - * @return volume of intersection of this triangle with unit tetrahedron, - * as described in Grandy - * - */ - double TransformedTriangle::calculateIntersectionVolume() - { - // check first that we are not below z - plane - if(isTriangleBelowTetraeder()) - { - LOG(2, " --- Triangle is below tetraeder - V = 0.0"); - return 0.0; - } - - // get the sign of the volume - equal to the sign of the z-component of the normal - // of the triangle, u_x * v_y - u_y * v_x, where u = q - p and v = r - p - // if it is zero, the triangle is perpendicular to the z - plane and so the volume is zero -// const double uv_xy[4] = -// { -// _coords[5*Q] - _coords[5*P], _coords[5*Q + 1] - _coords[5*P + 1], // u_x, u_y -// _coords[5*R] - _coords[5*P], _coords[5*R + 1] - _coords[5*P + 1] // v_x, v_y -// }; - -// double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; - int sign = isTriangleInclinedToFacet( OXY ); - - if(sign == 0 ) - { - LOG(2, " --- Triangle is perpendicular to z-plane - V = 0.0"); - return _volume = 0.0; - } - - - // normalize sign - //sign = sign > 0.0 ? 1.0 : -1.0; - - LOG(2, "-- Calculating intersection polygons ... "); - calculateIntersectionAndProjectionPolygons(); - - double barycenter[3]; - - // calculate volume under A - double volA = 0.0; - if(_polygonA.size() > 2) - { - LOG(2, "---- Treating polygon A ... "); - calculatePolygonBarycenter(A, barycenter); - sortIntersectionPolygon(A, barycenter); - volA = calculateVolumeUnderPolygon(A, barycenter); - LOG(2, "Volume is " << sign * volA); - } - - double volB = 0.0; - // if triangle is not in h = 0 plane, calculate volume under B - if(_polygonB.size() > 2 && !isTriangleInPlaneOfFacet(XYZ)) - { - LOG(2, "---- Treating polygon B ... "); - - calculatePolygonBarycenter(B, barycenter); - sortIntersectionPolygon(B, barycenter); - volB = calculateVolumeUnderPolygon(B, barycenter); - LOG(2, "Volume is " << sign * volB); - } - - LOG(2, "volA + volB = " << sign * (volA + volB) << std::endl << "***********"); - - return _volume = sign * (volA + volB); - - } - - /** - * Calculates the volume of intersection between the triangle and the - * unit tetrahedron. - * - * @return volume of intersection of this triangle with unit tetrahedron, - * as described in Grandy - * - */ - double TransformedTriangle::calculateIntersectionSurface(TetraAffineTransform* tat) - { - // check first that we are not below z - plane - if(isTriangleBelowTetraeder()) - { - LOG(2, " --- Triangle is below tetraeder - V = 0.0"); - return 0.0; - } - - LOG(2, "-- Calculating intersection polygon ... "); - calculateIntersectionPolygon(); - - _volume = 0.; - if(_polygonA.size() > 2) { - double barycenter[3]; - calculatePolygonBarycenter(A, barycenter); - sortIntersectionPolygon(A, barycenter); - const std::size_t nbPoints = _polygonA.size(); - for(std::size_t i = 0 ; i < nbPoints ; ++i) - tat->reverseApply(_polygonA[i], _polygonA[i]); - _volume = calculateSurfacePolygon(); - } - - return _volume; - } - - // ---------------------------------------------------------------------------------- - // TransformedTriangle PRIVATE - // ---------------------------------------------------------------------------------- - - /** - * Calculates the intersection polygons A and B, performing the intersection tests - * and storing the corresponding points in the vectors _polygonA and _polygonB. - * - * @post _polygonA contains the intersection polygon A and _polygonB contains the - * intersection polygon B. - * - */ - void TransformedTriangle::calculateIntersectionAndProjectionPolygons() - { - assert(_polygonA.size() == 0); - assert(_polygonB.size() == 0); - // avoid reallocations in push_back() by pre-allocating enough memory - // we should never have more than 20 points - _polygonA.reserve(20); - _polygonB.reserve(20); - // -- surface intersections - // surface - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - if(testSurfaceEdgeIntersection(edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSurfaceEdge(edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); - if(edge >= XY) - { - double* ptB = new double[3]; - copyVector3(ptA, ptB); - _polygonB.push_back(ptB); - LOG(3,"Surface-edge : " << vToStr(ptB) << " added to B "); - } - - } - } - - // surface - ray - for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - if(testSurfaceRayIntersection(corner)) - { - double* ptB = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); - _polygonB.push_back(ptB); - LOG(3,"Surface-ray : " << vToStr(ptB) << " added to B"); - } - } - - // -- segment intersections - for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) - { - - bool isZero[NO_DP]; - - // check beforehand which double-products are zero - for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[dp] = (calcStableC(seg, dp) == 0.0); - } - - // segment - facet - for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) - { - // is this test worth it? - const bool doTest = - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; - - if(doTest && testSegmentFacetIntersection(seg, facet)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentFacet(seg, facet, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); - if(facet == XYZ) - { - double* ptB = new double[3]; - copyVector3(ptA, ptB); - _polygonB.push_back(ptB); - LOG(3,"Segment-facet : " << vToStr(ptB) << " added to B"); - } - - } - } - - // segment - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - const DoubleProduct edge_dp = DoubleProduct(edge); - - if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentEdge(seg, edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); - if(edge >= XY) - { - double* ptB = new double[3]; - copyVector3(ptA, ptB); - _polygonB.push_back(ptB); - } - } - } - - // segment - corner - for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - const bool doTest = - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; - - if(doTest && testSegmentCornerIntersection(seg, corner)) - { - double* ptA = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); - if(corner != O) - { - double* ptB = new double[3]; - _polygonB.push_back(ptB); - copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); - LOG(3,"Segment-corner : " << vToStr(ptB) << " added to B"); - } - } - } - - // segment - ray - for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - if(isZero[DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] && testSegmentRayIntersection(seg, corner)) - { - double* ptB = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); - _polygonB.push_back(ptB); - LOG(3,"Segment-ray : " << vToStr(ptB) << " added to B"); - } - } - - // segment - halfstrip - for(TetraEdge edge = XY ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - -#if 0 - const int edgeIdx = int(edge) - 3; // offset since we only care for edges XY - ZX - const bool doTest = - !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx]] && - !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx+1]]; - - - if(doTest && testSegmentHalfstripIntersection(seg, edge)) -#endif - if(testSegmentHalfstripIntersection(seg, edge)) - { - double* ptB = new double[3]; - calcIntersectionPtSegmentHalfstrip(seg, edge, ptB); - _polygonB.push_back(ptB); - LOG(3,"Segment-halfstrip : " << vToStr(ptB) << " added to B"); - } - } - } - - // inclusion tests - for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) - { - // { XYZ - inclusion only possible if in Tetrahedron? - // tetrahedron - if(testCornerInTetrahedron(corner)) - { - double* ptA = new double[3]; - copyVector3(&_coords[5*corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); - } - - // XYZ - plane - if(testCornerOnXYZFacet(corner)) - { - double* ptB = new double[3]; - copyVector3(&_coords[5*corner], ptB); - _polygonB.push_back(ptB); - LOG(3,"Inclusion XYZ-plane : " << vToStr(ptB) << " added to B"); - } - - // projection on XYZ - facet - if(testCornerAboveXYZFacet(corner)) - { - double* ptB = new double[3]; - copyVector3(&_coords[5*corner], ptB); - ptB[2] = 1 - ptB[0] - ptB[1]; - assert(epsilonEqual(ptB[0]+ptB[1]+ptB[2] - 1, 0.0)); - _polygonB.push_back(ptB); - LOG(3,"Projection XYZ-plane : " << vToStr(ptB) << " added to B"); - } - - } - - } - - /** - * Calculates the intersection polygon A, performing the intersection tests - * and storing the corresponding point in the vector _polygonA. - * - * @post _polygonA contains the intersection polygon A. - * - */ - void TransformedTriangle::calculateIntersectionPolygon() - { - assert(_polygonA.size() == 0); - // avoid reallocations in push_back() by pre-allocating enough memory - // we should never have more than 20 points - _polygonA.reserve(20); - // -- surface intersections - // surface - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - if(testSurfaceEdgeIntersection(edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSurfaceEdge(edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); - } - } - - // -- segment intersections - for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) - { - - bool isZero[NO_DP]; - - // check beforehand which double-products are zero - for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[dp] = (calcStableC(seg, dp) == 0.0); - } - - // segment - facet - for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) - { - // is this test worth it? - const bool doTest = - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; - - if(doTest && testSegmentFacetIntersection(seg, facet)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentFacet(seg, facet, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); - } - } - - // segment - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - const DoubleProduct edge_dp = DoubleProduct(edge); - - if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentEdge(seg, edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); - } - } - - // segment - corner - for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - const bool doTest = - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; - - if(doTest && testSegmentCornerIntersection(seg, corner)) - { - double* ptA = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); - } - } - - } - - // inclusion tests - for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) - { - // { XYZ - inclusion only possible if in Tetrahedron? - // tetrahedron - if(testCornerInTetrahedron(corner)) - { - double* ptA = new double[3]; - copyVector3(&_coords[5*corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); - } - - } - - } - - - /** - * Returns the surface of polygon A. - * - * @return the surface of polygon A. - */ - double TransformedTriangle::calculateSurfacePolygon() - { - const std::size_t nbPoints = _polygonA.size(); - double pdt[3]; - double sum[3] = {0., 0., 0.}; - - for(std::size_t i = 0 ; i < nbPoints ; ++i) - { - const double *const ptCurr = _polygonA[i]; // pt "i" - const double *const ptNext = _polygonA[(i + 1) % nbPoints]; // pt "i+1" (pt nbPoints == pt 0) - - cross(ptCurr, ptNext, pdt); - add(pdt, sum); - } - - const double surface = norm(sum) * 0.5; - LOG(2,"Surface is " << surface); - return surface; - } - - /** - * Calculates the barycenters of the given intersection polygon. - * - * @pre the intersection polygons have been calculated with calculateIntersectionAndProjectionPolygons() - * - * @param poly one of the two intersection polygons - * @param barycenter array of three doubles where barycenter is stored - * - */ - void TransformedTriangle::calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter) - { - LOG(3,"--- Calculating polygon barycenter"); - - // get the polygon points - std::vector& polygon = (poly == A) ? _polygonA : _polygonB; - - // calculate barycenter - const std::size_t m = polygon.size(); - - for(int j = 0 ; j < 3 ; ++j) - { - barycenter[j] = 0.0; - } - - if(m != 0) - { - for(std::size_t i = 0 ; i < m ; ++i) - { - const double* pt = polygon[i]; - for(int j = 0 ; j < 3 ; ++j) - { - barycenter[j] += pt[j] / double(m); - } - } - } - LOG(3,"Barycenter is " << vToStr(barycenter)); - } - - /** - * Sorts the given intersection polygon in circular order around its barycenter. - * @pre the intersection polygons have been calculated with calculateIntersectionAndProjectionPolygons() - * @post the vertices in _polygonA and _polygonB are sorted in circular order around their - * respective barycenters - * - * @param poly one of the two intersection polygons - * @param barycenter array of three doubles with the coordinates of the barycenter - * - */ - void TransformedTriangle::sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter) - { - LOG(3,"--- Sorting polygon ..."); - - using INTERP_KERNEL::ProjectedCentralCircularSortOrder; - typedef ProjectedCentralCircularSortOrder SortOrder; // change is only necessary here and in constructor - typedef SortOrder::CoordType CoordType; - - // get the polygon points - std::vector& polygon = (poly == A) ? _polygonA : _polygonB; - - if(polygon.size() == 0) - return; - - // determine type of sorting - CoordType type = SortOrder::XY; - if(poly == A && !isTriangleInclinedToFacet( OXY )) // B is on h = 0 plane -> ok - { - // NB : the following test is never true if we have eliminated the - // triangles parallel to x == 0 and y == 0 in calculateIntersectionVolume(). - // We keep the test here anyway, to avoid interdependency. - - // is triangle inclined to x == 0 ? - if(isTriangleInclinedToFacet(OZX)) - { - type = SortOrder::XZ; - } - else //if(isTriangleParallelToFacet(OYZ)) - { - type = SortOrder::YZ; - } - } - - // create order object - SortOrder order(barycenter, type); - - // sort vector with this object - // NB : do not change place of first object, with respect to which the order - // is defined - sort((polygon.begin()), polygon.end(), order); - - LOG(3,"Sorted polygon is "); - for(size_t i = 0 ; i < polygon.size() ; ++i) - { - LOG(3,vToStr(polygon[i])); - } - - } - - /** - * Calculates the volume between the given polygon and the z = 0 plane. - * - * @pre the intersection polygones have been calculated with calculateIntersectionAndProjectionPolygons(), - * and they have been sorted in circular order with sortIntersectionPolygons(void) - * - * @param poly one of the two intersection polygons - * @param barycenter array of three doubles with the coordinates of the barycenter - * @return the volume between the polygon and the z = 0 plane - * - */ - double TransformedTriangle::calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter) - { - LOG(2,"--- Calculating volume under polygon"); - - // get the polygon points - std::vector& polygon = (poly == A) ? _polygonA : _polygonB; - - double vol = 0.0; - const std::size_t m = polygon.size(); - - for(std::size_t i = 0 ; i < m ; ++i) - { - const double* ptCurr = polygon[i]; // pt "i" - const double* ptNext = polygon[(i + 1) % m]; // pt "i+1" (pt m == pt 0) - - const double factor1 = ptCurr[2] + ptNext[2] + barycenter[2]; - const double factor2 = - ptCurr[0]*(ptNext[1] - barycenter[1]) - + ptNext[0]*(barycenter[1] - ptCurr[1]) - + barycenter[0]*(ptCurr[1] - ptNext[1]); - vol += (factor1 * factor2) / 6.0; - } - - LOG(2,"Abs. Volume is " << vol); - return vol; - } - - - //////////////////////////////////////////////////////////////////////////////////// - // Detection of (very) degenerate cases ///////////// - //////////////////////////////////////////////////////////////////////////////////// - - /** - * Checks if the triangle lies in the plane of a given facet - * - * @param facet one of the facets of the tetrahedron - * @return true if PQR lies in the plane of the facet, false if not - */ - bool TransformedTriangle::isTriangleInPlaneOfFacet(const TetraFacet facet) const - { - - // coordinate to check - const int coord = static_cast(facet); - - for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) - { - if(_coords[5*c + coord] != 0.0) - { - return false; - } - } - - return true; - } - - /** - * Checks if the triangle is parallel to the given facet - * - * @param facet one of the facets of the unit tetrahedron - * @return true if triangle is parallel to facet, false if not - */ - bool TransformedTriangle::isTriangleParallelToFacet(const TetraFacet facet) const - { - // coordinate to check - const int coord = static_cast(facet); - return (_coords[5*P + coord] == _coords[5*Q + coord]) && (_coords[5*P + coord] == _coords[5*R + coord]); - } - - /** - * Checks if the triangle is not perpedicular to the given facet - * - * @param facet one of the facets of the unit tetrahedron - * @return zero if the triangle is perpendicular to the facet, - * else 1 or -1 depending on the sign of cross product of facet edges - */ - int TransformedTriangle::isTriangleInclinedToFacet(const TetraFacet facet) const - { - // coordinate to check - const int coord = static_cast(facet); - const int ind1 = ( coord+1 ) % 3, ind2 = ( coord+2 ) % 3; - const double uv_xy[4] = - { - // u_x, u_y - _coords[5*Q+ind1] - _coords[5*P+ind1], _coords[5*Q+ind2] - _coords[5*P+ind2], - // v_x, v_y - _coords[5*R+ind1] - _coords[5*P+ind1], _coords[5*R+ind2] - _coords[5*P+ind2] - }; - - double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; - if(epsilonEqual(sign, 0.)) - { - sign = 0.; - } - return (sign < 0.) ? -1 : (sign > 0.) ? 1 : 0; - } - - /** - * Determines whether the triangle is below the z-plane. - * - * @return true if the z-coordinate of the three corners of the triangle are all less than 0, false otherwise. - */ - bool TransformedTriangle::isTriangleBelowTetraeder() const - { - for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) - { - // check z-coords for all points - if(_coords[5*c + 2] >= 0.0) - { - return false; - } - } - return true; - } - - /** - * Prints the coordinates of the triangle to std::cout - * - */ - void TransformedTriangle::dumpCoords() const - { - std::cout << "Coords : "; - for(int i = 0 ; i < 3; ++i) - { - std::cout << vToStr(&_coords[5*i]) << ","; - } - std::cout << std::endl; - } - - } // NAMESPACE diff --git a/medtool/src/INTERP_KERNEL/TransformedTriangle.hxx b/medtool/src/INTERP_KERNEL/TransformedTriangle.hxx deleted file mode 100644 index 51433c9d2..000000000 --- a/medtool/src/INTERP_KERNEL/TransformedTriangle.hxx +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TRANSFORMED_TRIANGLE_HXX__ -#define __TRANSFORMED_TRIANGLE_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -// Levels : -// 1 - overview of algorithm + volume result -// 2 - algorithm detail -// 3 - intersection polygon results detail -// 4 - intersection polygon search detail -// higher -> misc. gory details of calculation - -#include "Log.hxx" - -#ifdef WIN32 -#pragma warning(disable:4251) -#endif - -namespace INTERP_TEST -{ - class TransformedTriangleTest; - class TransformedTriangleIntersectTest; -} - - -namespace INTERP_KERNEL -{ - class TetraAffineTransform; - - /** \class TransformedTriangle - * \brief Class representing one of the faces of the triangulated source polyhedron after having been transformed - * with the affine transform that takes the target tetrahedron to the unit tetrahedron. It contains the - * logic for calculating the volume of intersection between the triangle and the unit tetrahedron. - * - * \see TransformedTriangle.hxx - * - * Reference : J. Grandy, "Conservative Remapping and Region Overlays by Intersecting Arbitrary Polyhedra", - * Journal of Computational Physics (1999) - * - */ - - /** \file TransformedTriangle.hxx - * - * OVERVIEW of how the class works : (details can be found in the documentation of each method) - * - * Constructor : - * The constructor takes as arguments three pointers to double[3] vectors holding the transformed - * coordinates of the corners of the triangle. It copies their coordinates and then proceeds to pre-calculating certain - * entities used in the intersection calculation : the double products, triple products and the values of the function E - * (Grandy, [53]). - * - * calculateIntersectionVolume() : - * This is the only method in the public interface. It calculates the volume under the intersection polygons - * between the triangle and the unit tetrahedron, as described in Grandy, pp. 435-447. It does this by first calculating the - * intersection polygons A and B, with the method calculateIntersectionPolygons(). It then calculates the barycenter of each - * polygon in calculatePolygonBarycenter(), and sorts their points in a circular order around the barycenter in - * sortIntersecionPolygon(). The sorting is done with STL sort, using the order defined in the class - * ProjectedCentralCircularSortOrder. The volume under each polygon is then calculated with calculateVolumeUnderPolygon(), which - * implements formula [34] in Grandy. - * - * calculateIntersectionPolygons() : - * This method goes through all the possible ways in which the triangle can intersect the tetrahedron and tests for these - * types of intersections in accordance with the formulas described in Grandy. These tests are implemented in the test* - methods. - * The formulas in the article are stated for one case each only, while the calculation must take into account all cases. - * To this end, a number of tables, implemented as static const arrays of different types, are used. The tables - * mainly contain values of the different enumeration types described at the beginning of the class interface. For example, - * the formula Grandy gives for the segment-halfstrip intersection tests ([30]) is for use with the halfstrip above the zx edge. - * For the other two halfstrips (above the xy and yz edges), other double products are used, which - * are stored in the table DP_FOR_HALFSTRIP_INTERSECTION. This allows us to treat - * all the edges equally, avoiding switch() - statements. It is the careful choice of order of the enumeration types that makes this - * possible. Notably, there is a correspondance between the TetraEdge type and the DoubleProduct type (see Grandy, table III) that - * is used throughout the code, permitting statements such as DoubleProduct(some_edge) to work. - * When an intersection point has been detected it is calculated with a corresponding calc* - method in the cases where it - * is not known directly. It is then added to the polygon A and/or B as necessary. - * - * OPTIMIZE : - * If OPTIMIZE is defined, a large number of methods will be prefixed with inline and some optimizations concerning the tests - * with zero double products will be used. - */ - class INTERPKERNEL_EXPORT TransformedTriangle - { - - - public: - - friend class INTERP_TEST::TransformedTriangleTest; - friend class INTERP_TEST::TransformedTriangleIntersectTest; - /* - * Enumerations representing the different geometric elements of the unit tetrahedron - * and the triangle. The end element, NO_* gives the number of elements in the enumeration - * and can be used as end element in loops. - */ - - /// Corners of tetrahedron - enum TetraCorner { O = 0, X, Y, Z, NO_TET_CORNER }; - - /// Edges of tetrahedron - enum TetraEdge { OX = 0, OY, OZ, XY, YZ, ZX, H01, H10, NO_TET_EDGE }; - - /// Facets (faces) of tetrahedron - enum TetraFacet { OYZ = 0, OZX, OXY, XYZ, NO_TET_FACET }; - - /// Corners of triangle - enum TriCorner { P = 0, Q, R, NO_TRI_CORNER }; - - /// Segments (edges) of triangle - enum TriSegment { PQ = 0, QR, RP, NO_TRI_SEGMENT }; - - /// Intersection polygons - enum IntersectionPolygon{ A = 0, B, NO_INTERSECTION_POLYGONS }; - - /// Double products - /// NB : order corresponds to TetraEdges (Grandy, table III) - enum DoubleProduct { C_YZ = 0, C_ZX, C_XY, C_ZH, C_XH, C_YH, C_01, C_10, NO_DP }; - - TransformedTriangle(double* p, double* q, double* r); - ~TransformedTriangle(); - - double calculateIntersectionVolume(); - double calculateIntersectionSurface(TetraAffineTransform* tat); - - void dumpCoords() const; - - // Queries of member values used by UnitTetraIntersectionBary - - const double* getCorner(TriCorner corner) const { return _coords + 5*corner; } - - const std::vector& getPolygonA() const { return _polygonA; } - - double getVolume() const { return _volume; } - - protected: - - TransformedTriangle() { } - - // ---------------------------------------------------------------------------------- - // High-level methods called directly by calculateIntersectionVolume() - // ---------------------------------------------------------------------------------- - void calculateIntersectionAndProjectionPolygons(); - - void calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter); - - void sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter); - - double calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter); - - // ---------------------------------------------------------------------------------- - // High-level methods called directly by calculateIntersectionSurface() - // ---------------------------------------------------------------------------------- - void calculateIntersectionPolygon(); - - double calculateSurfacePolygon(); - - // ---------------------------------------------------------------------------------- - // Detection of degenerate triangles - // ---------------------------------------------------------------------------------- - - bool isTriangleInPlaneOfFacet(const TetraFacet facet) const; - - bool isTriangleParallelToFacet(const TetraFacet facet) const; - - int isTriangleInclinedToFacet(const TetraFacet facet) const; - - bool isTriangleBelowTetraeder() const; - - // ---------------------------------------------------------------------------------- - // Intersection test methods and intersection point calculations - // ---------------------------------------------------------------------------------- - - inline bool testSurfaceEdgeIntersection(const TetraEdge edge) const; - - void calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const; - - inline bool testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const; - - void calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const; - - bool testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const; - - void calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const ; - - bool testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const ; - - inline bool testSurfaceRayIntersection(const TetraCorner corner) const; - - bool testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edg); - - void calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const; - - bool testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const; - - inline bool testCornerInTetrahedron(const TriCorner corner) const; - - inline bool testCornerOnXYZFacet(const TriCorner corner) const; - - inline bool testCornerAboveXYZFacet(const TriCorner corner) const; - - // ---------------------------------------------------------------------------------- - // Utility methods used in intersection tests - // ---------------------------------------------------------------------------------- - - bool testTriangleSurroundsEdge(const TetraEdge edge) const; - - inline bool testEdgeIntersectsTriangle(const TetraEdge edge) const; - - inline bool testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const; - - inline bool testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const; - - bool testSegmentIntersectsHPlane(const TriSegment seg) const; - - bool testSurfaceAboveCorner(const TetraCorner corner) const; - - bool testTriangleSurroundsRay(const TetraCorner corner) const; - - // ---------------------------------------------------------------------------------- - // Double and triple product calculations - // ---------------------------------------------------------------------------------- - - void resetNearZeroCoordinates(); - - bool areDoubleProductsConsistent(const TriSegment seg) const; - - void preCalculateDoubleProducts(void); - - inline void resetDoubleProducts(const TriSegment seg, const TetraCorner corner); - - double calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const; - - void preCalculateTripleProducts(void); - - double calculateAngleEdgeTriangle(const TetraEdge edge) const; - - inline double calcStableC(const TriSegment seg, const DoubleProduct dp) const; - - inline double calcStableT(const TetraCorner corner) const; - - inline double calcUnstableC(const TriSegment seg, const DoubleProduct dp) const; - - double calcTByDevelopingRow(const TetraCorner corner, const int row = 1, const bool project = false) const; - - // ---------------------------------------------------------------------------------- - // Member variables - // ---------------------------------------------------------------------------------- - protected: - - /// Array holding the coordinates of the triangle's three corners - /// order : - /// [ p_x, p_y, p_z, p_h, p_H, q_x, q_y, q_z, q_h, q_H, r_x, r_y, r_z, r_h, r_H ] - double _coords[15]; - - /// Flag showing whether the double products have been calculated yet - bool _is_double_products_calculated; - - /// Flag showing whether the triple products have been calculated yet - bool _is_triple_products_calculated; - - /// Array containing the 24 double products. - /// order : c^PQ_YZ, ... ,cPQ_10, ... c^QR_YZ, ... c^RP_YZ - /// following order in enumeration DoubleProduct - double _doubleProducts[24]; - - /// Array containing the 4 triple products. - /// order : t_O, t_X, t_Y, t_Z - double _tripleProducts[4]; - - /// Vector holding the points of the intersection polygon A. - /// these points are allocated in calculateIntersectionPolygons() and liberated in the destructor - std::vector _polygonA; - - /// Vector holding the points of the intersection polygon B. - /// These points are allocated in calculateIntersectionPolygons() and liberated in the destructor - std::vector _polygonB; - - /// Array holding the coordinates of the barycenter of the polygon A - /// This point is calculated in calculatePolygonBarycenter - double _barycenterA[3]; - - /// Array holding the coordinates of the barycenter of the polygon B - /// This point is calculated in calculatePolygonBarycenter - //double _barycenterB[3]; - - /// Array of flags indicating which of the four triple products have been correctly calculated. - /// Used for asserts in debug mode - bool _validTP[4]; - - /// calculated volume for use of UnitTetraIntersectionBary - double _volume; - - /** - * Calls TransformedTriangle::testTriangleSurroundsEdge for edges OX to ZX and stores the result in - * member variable array_triangleSurroundsEdgeCache. - * - */ - void preCalculateTriangleSurroundsEdge(); - - /// Array holding results of the test testTriangleSurroundsEdge() for all the edges. - /// These are calculated in preCalculateTriangleSurroundsEdge(). - bool _triangleSurroundsEdgeCache[NO_TET_EDGE]; - - // ---------------------------------------------------------------------------------- - // Constants - // ---------------------------------------------------------------------------------- - - // offsets : 0 -> x, 1 -> y, 2 -> z, 3 -> h, 4 -> H - // corresponds to order of double products in DoubleProduct - // so that offset[C_*] gives the right coordinate - static const int DP_OFFSET_1[8]; - static const int DP_OFFSET_2[8]; - - // the coordinates used in the expansion of triple products by a given row - // in constellation (corner, row-1) - // (0,1,2,3) <=> (x,y,z,h) - static const int COORDINATE_FOR_DETERMINANT_EXPANSION[12]; - - // contains the edge of the double product used when - // expanding the triple product determinant associated with each corner - // by a given row - static const DoubleProduct DP_FOR_DETERMINANT_EXPANSION[12]; - - // values used to decide how imprecise the double products - // should be to set them to 0.0 - static const long double MACH_EPS; // machine epsilon - static const long double MULT_PREC_F; // precision of multiplications (Grandy : f) - static const long double THRESHOLD_F; // threshold for zeroing (Grandy : F/f) - - static const double TRIPLE_PRODUCT_ANGLE_THRESHOLD; - - // correspondance facet - double product - // Grandy, table IV - static const DoubleProduct DP_FOR_SEG_FACET_INTERSECTION[12]; - - // signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION - static const double SIGN_FOR_SEG_FACET_INTERSECTION[12]; - - // coordinates of corners of tetrahedron - static const double COORDS_TET_CORNER[12]; - - // indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION - // for the calculation of the coordinates (x,y,z) of the intersection points - // for Segment-Facet and Segment-Edge intersections - static const int DP_INDEX[12]; - - // correspondance edge - corners - static const TetraCorner CORNERS_FOR_EDGE[12]; - - // correspondance edge - facets - // facets shared by each edge - static const TetraFacet FACET_FOR_EDGE[12]; - - // correspondance edge - corners - static const TetraEdge EDGES_FOR_CORNER[12]; - - // double products used in segment-halfstrip test - static const DoubleProduct DP_FOR_HALFSTRIP_INTERSECTION[12]; - - // double products used in segment - ray test - static const DoubleProduct DP_SEGMENT_RAY_INTERSECTION[21]; - - }; - - // include definitions of inline methods - -#include "TransformedTriangleInline.hxx" -} - - -#endif diff --git a/medtool/src/INTERP_KERNEL/TransformedTriangleInline.hxx b/medtool/src/INTERP_KERNEL/TransformedTriangleInline.hxx deleted file mode 100644 index 3f473ec75..000000000 --- a/medtool/src/INTERP_KERNEL/TransformedTriangleInline.hxx +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TRANSFORMEDTRIANGLEINLINE_HXX__ -#define __TRANSFORMEDTRIANGLEINLINE_HXX__ - -// This file contains inline versions of some of the methods in the TransformedTriangle*.cxx files. -// It replaces those methods if OPTIMIZE is defined. -// NB : most of these methods have documentation in their corresponding .cxx - file. - -// ---------------------------------------------------------------------------------- -// Optimization methods. These are only defined and used if OPTIMIZE is defined. -// ----------------------------------------------------------------------------------- - - -inline void TransformedTriangle::preCalculateTriangleSurroundsEdge() -{ - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - _triangleSurroundsEdgeCache[edge] = testTriangleSurroundsEdge(edge); - } -} - - -// ---------------------------------------------------------------------------------- -// TransformedTriangle_math.cxx -// ---------------------------------------------------------------------------------- - -inline void TransformedTriangle::resetDoubleProducts(const TriSegment seg, const TetraCorner corner) -{ - // set the three corresponding double products to 0.0 - static const DoubleProduct DOUBLE_PRODUCTS[12] = - { - C_YZ, C_ZX, C_XY, // O - C_YZ, C_ZH, C_YH, // X - C_ZX, C_ZH, C_XH, // Y - C_XY, C_YH, C_XH // Z - }; - - for(int i = 0 ; i < 3 ; ++i) { - const DoubleProduct dp = DOUBLE_PRODUCTS[3*corner + i]; - - LOG(6, std::endl << "resetting inconsistent dp :" << dp << " for corner " << corner); - _doubleProducts[8*seg + dp] = 0.0; - }; -} - -inline double TransformedTriangle::calcStableC(const TriSegment seg, const DoubleProduct dp) const -{ - return _doubleProducts[8*seg + dp]; -} - -inline double TransformedTriangle::calcStableT(const TetraCorner corner) const -{ - // assert(_isTripleProductsCalculated); - // assert(_validTP[corner]); - return _tripleProducts[corner]; -} - -inline double TransformedTriangle::calcUnstableC(const TriSegment seg, const DoubleProduct dp) const -{ - - // find the points of the triangle - // 0 -> P, 1 -> Q, 2 -> R - const int pt1 = seg; - const int pt2 = (seg + 1) % 3; - - // find offsets - const int off1 = DP_OFFSET_1[dp]; - const int off2 = DP_OFFSET_2[dp]; - - return _coords[5*pt1 + off1] * _coords[5*pt2 + off2] - _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; -} - -// ---------------------------------------------------------------------------------- -// TransformedTriangle_intersect.cxx -// ---------------------------------------------------------------------------------- -inline bool TransformedTriangle::testSurfaceEdgeIntersection(const TetraEdge edge) const -{ - return _triangleSurroundsEdgeCache[edge] && testEdgeIntersectsTriangle(edge); -} - -inline bool TransformedTriangle::testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const -{ - return testFacetSurroundsSegment(seg, facet) && testSegmentIntersectsFacet(seg, facet); -} - -inline bool TransformedTriangle::testSurfaceRayIntersection(const TetraCorner corner) const -{ - return testTriangleSurroundsRay( corner ) && testSurfaceAboveCorner( corner ); -} - -inline bool TransformedTriangle::testCornerInTetrahedron(const TriCorner corner) const -{ - const double pt[4] = - { - _coords[5*corner], // x - _coords[5*corner + 1], // y - _coords[5*corner + 2], // z - _coords[5*corner + 3] // z - }; - - for(int i = 0 ; i < 4 ; ++i) - { - if(pt[i] < 0.0 || pt[i] > 1.0) - { - return false; - } - } - return true; -} - -inline bool TransformedTriangle::testCornerOnXYZFacet(const TriCorner corner) const -{ -#if 0 - const double pt[4] = - { - _coords[5*corner], // x - _coords[5*corner + 1], // y - _coords[5*corner + 2], // z - _coords[5*corner + 3] // h - }; -#endif - const double* pt = &_coords[5*corner]; - - if(pt[3] != 0.0) - { - return false; - } - - for(int i = 0 ; i < 3 ; ++i) - { - if(pt[i] < 0.0 || pt[i] > 1.0) - { - return false; - } - } - return true; -} - -inline bool TransformedTriangle::testCornerAboveXYZFacet(const TriCorner corner) const -{ - const double x = _coords[5*corner]; - const double y = _coords[5*corner + 1]; - const double h = _coords[5*corner + 3]; - const double H = _coords[5*corner + 4]; - - return h < 0.0 && H >= 0.0 && x >= 0.0 && y >= 0.0; - -} - -inline bool TransformedTriangle::testEdgeIntersectsTriangle(const TetraEdge edge) const -{ - - // assert(edge < H01); - - // correspondance edge - triple products - // for edges OX, ..., ZX (Grandy, table III) - static const TetraCorner TRIPLE_PRODUCTS[12] = - { - X, O, // OX - Y, O, // OY - Z, O, // OZ - X, Y, // XY - Y, Z, // YZ - Z, X, // ZX - }; - - // Grandy, [16] - const double t1 = calcStableT(TRIPLE_PRODUCTS[2*edge]); - const double t2 = calcStableT(TRIPLE_PRODUCTS[2*edge + 1]); - - //? should equality with zero use epsilon? - LOG(5, "testEdgeIntersectsTriangle : t1 = " << t1 << " t2 = " << t2 ); - return (t1*t2 <= 0.0) && (t1 - t2 != 0.0); -} - -inline bool TransformedTriangle::testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const -{ -#if 0 - const double signs[3] = - { - SIGN_FOR_SEG_FACET_INTERSECTION[3*facet], - SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 1], - SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 2] - }; -#endif - - const double* signs = &SIGN_FOR_SEG_FACET_INTERSECTION[3*facet]; - const double c1 = signs[0]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet]); - const double c2 = signs[1]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]); - const double c3 = signs[2]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]); - - return (c1*c3 > 0.0) && (c2*c3 > 0.0); -} - -inline bool TransformedTriangle::testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const -{ - // use correspondance facet a = 0 <=> offset for coordinate a in _coords - // and also correspondance segment AB => corner A - const double coord1 = _coords[5*seg + facet]; - const double coord2 = _coords[5*( (seg + 1) % 3) + facet]; - - //? should we use epsilon-equality here in second test? - LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); - - return (coord1*coord2 <= 0.0) && (coord1 != coord2); -} - -inline bool TransformedTriangle::testSegmentIntersectsHPlane(const TriSegment seg) const -{ - // get the H - coordinates - const double coord1 = _coords[5*seg + 4]; - const double coord2 = _coords[5*( (seg + 1) % 3) + 4]; - //? should we use epsilon-equality here in second test? - LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); - - return (coord1*coord2 <= 0.0) && (coord1 != coord2); -} - -inline bool TransformedTriangle::testSurfaceAboveCorner(const TetraCorner corner) const -{ - // ? There seems to be an error in Grandy -> it should be C_XY instead of C_YZ in [28]. - // ? I haven't really figured out why, but it seems to work. - const double normal = calcStableC(PQ, C_XY) + calcStableC(QR, C_XY) + calcStableC(RP, C_XY); - - LOG(6, "surface above corner " << corner << " : " << "n = " << normal << ", t = [" << calcTByDevelopingRow(corner, 1, false) << ", " << calcTByDevelopingRow(corner, 2, false) << ", " << calcTByDevelopingRow(corner, 3, false) ); - LOG(6, "] - stable : " << calcStableT(corner) ); - - //? we don't care here if the triple product is "invalid", that is, the triangle does not surround one of the - // edges going out from the corner (Grandy [53]) - if(!_validTP[corner]) - { - return ( calcTByDevelopingRow(corner, 1, false) * normal ) >= 0.0; - } - else - { - return ( calcStableT(corner) * normal ) >= 0.0; - } -} - -inline bool TransformedTriangle::testTriangleSurroundsRay(const TetraCorner corner) const -{ - // assert(corner == X || corner == Y || corner == Z); - - // double products to use for the possible corners - static const DoubleProduct DP_FOR_RAY_INTERSECTION[4] = - { - DoubleProduct(0), // O - only here to fill out and make indices match - C_10, // X - C_01, // Y - C_XY // Z - }; - - const DoubleProduct dp = DP_FOR_RAY_INTERSECTION[corner]; - - const double cPQ = calcStableC(PQ, dp); - const double cQR = calcStableC(QR, dp); - const double cRP = calcStableC(RP, dp); - - //? NB here we have no correction for precision - is this good? - // Our authority Grandy says nothing - LOG(5, "dp in triSurrRay for corner " << corner << " = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); - - return ( cPQ*cQR > 0.0 ) && ( cPQ*cRP > 0.0 ); - -} -#endif diff --git a/medtool/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx b/medtool/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx deleted file mode 100644 index fa4c8a535..000000000 --- a/medtool/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangle.hxx" -#include -#include -#include -#include -#include "VectorUtils.hxx" - -namespace INTERP_KERNEL -{ - - // ---------------------------------------------------------------------------------- - // Correspondance tables describing all the variations of formulas. - // ---------------------------------------------------------------------------------- - - /// \brief Correspondance between facets and double products. - /// - /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_SEG_FACET_INTERSECTION[12] = - { - C_XH, C_XY, C_ZX, // OYZ - C_YH, C_YZ, C_XY, // OZX - C_ZH, C_ZX, C_YZ, // OXY - C_XH, C_YH, C_ZH // XYZ - }; - - /// \brief Signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION. - /// - /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index - const double TransformedTriangle::SIGN_FOR_SEG_FACET_INTERSECTION[12] = - { - 1.0, 1.0, -1.0, - 1.0, 1.0, -1.0, - 1.0, 1.0, -1.0, - 1.0, 1.0, 1.0 - }; - - /// \brief Coordinates of corners of tetrahedron. - /// - /// Use 3*Corner + coordinate as index - const double TransformedTriangle::COORDS_TET_CORNER[12] = - { - 0.0, 0.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0 - }; - - /// \brief Indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION - /// for the calculation of the coordinates (x,y,z) of the intersection points - /// for Segment-Facet and Segment-Edge intersections. - /// - /// Use 3*facet + coordinate as index. -1 indicates that the coordinate is 0. - const int TransformedTriangle::DP_INDEX[12] = - { - // x, y, z - -1, 1, 2, // OYZ - 5, -1, 4, // OZX - 7, 8, -1, // OXY - 9, 10, 11 // XYZ - }; - - /// \brief Correspondance edge - corners. - /// - /// Gives the two corners associated with each edge - /// Use 2*edge + {0, 1} as index - const TransformedTriangle::TetraCorner TransformedTriangle::CORNERS_FOR_EDGE[12] = - { - O, X, // OX - O, Y, // OY - O, Z, // OZ - X, Y, // XY - Y, Z, // YZ - Z, X // ZX - }; - - /// \brief Correspondance edge - facets. - /// - /// Gives the two facets shared by and edge. Use 2*facet + {0, 1} as index - const TransformedTriangle::TetraFacet TransformedTriangle::FACET_FOR_EDGE[12] = - { - OXY, OZX, // OX - OXY, OYZ, // OY - OZX, OYZ, // OZ - OXY, XYZ, // XY - OYZ, XYZ, // YZ - OZX, XYZ // ZX - }; - - /// \brief Correspondance corners - edges. - /// - /// Gives edges meeting at a given corner. Use 3*corner + {0,1,2} as index - const TransformedTriangle::TetraEdge TransformedTriangle::EDGES_FOR_CORNER[12] = - { - OX, OY, OZ, // O - OX, XY, ZX, // X - OY, XY, YZ, // Y - OZ, ZX, YZ // Z - }; - - /// \brief Double products to use in halfstrip intersection tests. - /// - /// Use 4*(offset_edge) + {0,1,2,3} as index. offset_edge = edge - 3 (so that XY -> 0, YZ -> 1, ZX -> 2) - /// Entries with offset 0 and 1 are for the first condition (positive product) - /// and those with offset 2 and 3 are for the second condition (negative product). - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_HALFSTRIP_INTERSECTION[12] = - { - C_10, C_01, C_ZH, C_10, // XY - C_01, C_XY, C_XH, C_01, // YZ - C_XY, C_10, C_YH, C_XY // ZX - }; - - /// \brief Double products to use in segment-ray test. - /// - /// Use 7*corner_offset + {0,1,2,3,4,5,6} as index. corner_offset = corner - 1 (so that X -> 0, Y-> 1, Z->2) - /// Entries with offset 0 are for first condition (zero double product) and the rest are for condition 3 (in the same - /// order as in the article) - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_SEGMENT_RAY_INTERSECTION[21] = - { - C_10, C_YH, C_ZH, C_01, C_XY, C_YH, C_XY, // X - C_01, C_XH, C_ZH, C_XY, C_10, C_ZH, C_10, // Y - C_XY, C_YH, C_XH, C_10, C_01, C_XH, C_01 // Z - }; - - /** - * Calculates the point of intersection between the given edge of the tetrahedron and the - * triangle PQR. (Grandy, eq [22]) - * - * @pre testSurfaceEdgeIntersection(edge) returns true - * @param edge edge of tetrahedron - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const - { - assert(edge < H01); - - // barycentric interpolation between points A and B - // : (x,y,z)* = (1-alpha)*A + alpha*B where - // alpha = t_A / (t_A - t_B) - - const TetraCorner corners[2] = - { - CORNERS_FOR_EDGE[2*edge], - CORNERS_FOR_EDGE[2*edge + 1] - }; - - // calculate alpha - const double tA = calcStableT(corners[0]); - const double tB = calcStableT(corners[1]); - const double alpha = tA / (tA - tB); - - // calculate point - LOG(4, "corner A = " << corners[0] << " corner B = " << corners[1] ); - LOG(4, "tA = " << tA << " tB = " << tB << " alpha= " << alpha ); - for(int i = 0; i < 3; ++i) - { - - pt[i] = (1 - alpha) * COORDS_TET_CORNER[3*corners[0] + i] + - alpha * COORDS_TET_CORNER[3*corners[1] + i]; -#if 0 - pt[i] = (1 - alpha) * getCoordinateForTetCorner() + - alpha * getCoordinateForTetCorner(); -#endif - LOG(6, pt[i] ); - assert(pt[i] >= 0.0); - assert(pt[i] <= 1.0); - } - } - - /** - * Calculates the point of intersection between the given segment of the triangle - * and the given facet of the tetrahedron. (Grandy, eq. [23]) - * - * @pre testSurfaceEdgeIntersection(seg, facet) returns true - * - * @param seg segment of the triangle - * @param facet facet of the tetrahedron - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const - { - // calculate s - double s = 0.0; - for(int i = 0; i < 3; ++i) - { - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facet + i]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + i]; - s -= sign * calcStableC(seg, dp); - } - - assert(s != 0.0); - - // calculate coordinates of intersection point - for(int i = 0 ; i < 3; ++i) - { - const int dpIdx = DP_INDEX[3*facet + i]; - - if(dpIdx < 0) - { - pt[i] = 0.0; - } - else - { - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; - pt[i] = -( sign * calcStableC(seg, dp) ) / s; - - LOG(4, "SegmentFacetIntPtCalc : pt[" << i << "] = " << pt[i] ); - LOG(4, "c(" << seg << ", " << dp << ") = " << sign * calcStableC(seg, dp) ); - assert(pt[i] >= 0.0); - assert(pt[i] <= 1.0); - } - } - - } - - /** - * Tests if the given segment of the triangle intersects the given edge of the tetrahedron (Grandy, eq. [20] - * If the OPTIMIZE is defined, it does not do the test the double product that should be zero. - * @param seg segment of the triangle - * @param edge edge of tetrahedron - * @return true if the segment intersects the edge - */ - bool TransformedTriangle::testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const - { - { - // check condition that the double products for one of the two - // facets adjacent to the edge has a positive product - bool isFacetCondVerified = false; - TetraFacet facet[2]; - for(int i = 0 ; i < 2 ; ++i) - { - facet[i] = FACET_FOR_EDGE[2*edge + i]; - - // find the two c-values -> the two for the other edges of the facet - int idx1 = 0 ; - int idx2 = 1; - DoubleProduct dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; - DoubleProduct dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; - - if(dp1 == DoubleProduct( edge )) - { - idx1 = 2; - dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; - } - else if(dp2 == DoubleProduct( edge )) - { - idx2 = 2; - dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; - } - - const double c1 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]*calcStableC(seg, dp1); - const double c2 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]*calcStableC(seg, dp2); - - //isFacetCondVerified = isFacetCondVerified || c1*c2 > 0.0; - if(c1*c2 > 0.0) - { - isFacetCondVerified = true; - } - } - - if(!isFacetCondVerified) - { - return false; - } - else - { - return testSegmentIntersectsFacet(seg, facet[0]) || testSegmentIntersectsFacet(seg, facet[1]); - } - } - } - - /** - * Calculates the point of intersection between the given segment of the triangle - * and the given edge of the tetrahedron. (Grandy, eq. [25]) - * - * @pre testSegmentEdgeIntersection(seg, edge) returns true - * - * @param seg segment of the triangle - * @param edge edge of the tetrahedron - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const - { - assert(edge < H01); - - // get the two facets associated with the edge - static const TetraFacet FACETS_FOR_EDGE[12] = - { - OXY, OZX, // OX - OXY, OYZ, // OY - OZX, OYZ, // OZ - OXY, XYZ, // XY - OYZ, XYZ, // YZ - OZX, XYZ // ZX - }; - - const TetraFacet facets[2] = - { - FACETS_FOR_EDGE[2*edge], - FACETS_FOR_EDGE[2*edge + 1] - }; - - // calculate s for the two edges - double s[2]; - for(int i = 0; i < 2; ++i) - { - s[i] = 0.0; - for(int j = 0; j < 3; ++j) - { - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; - s[i] += sign * calcStableC(seg, dp); - } - } - - // calculate denominator - const double denominator = s[0]*s[0] + s[1]*s[1]; - - // calculate intersection point - for(int i = 0; i < 3; ++i) - { - // calculate double product values for the two faces - double c[2]; - for(int j = 0 ; j < 2; ++j) - { - const int dpIdx = DP_INDEX[3*facets[j] + i]; - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; - c[j] = dpIdx < 0.0 ? 0.0 : sign * calcStableC(seg, dp); - } - - // pt[i] = (c1*s1 + c2*s2) / (s1^2 + s2^2) - - pt[i] = (c[0] * s[0] + c[1] * s[1]) / denominator; - - // strange bug with -O2 enabled : assertion fails when we don't have the following - // trace - line - //std::cout << "pt[i] = " << pt[i] << std::endl; - //assert(pt[i] >= 0.0); // check we are in tetraeder - //assert(pt[i] <= 1.0); - - } - } - - - /** - * Tests if the given segment of the triangle intersects the given corner of the tetrahedron. - * (Grandy, eq. [21]). If OPTIMIZE is defined, the double products that should be zero are not verified. - * - * @param seg segment of the triangle - * @param corner corner of the tetrahedron - * @return true if the segment intersects the corner - */ - bool TransformedTriangle::testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const - { - - - // facets meeting at a given corner - static const TetraFacet FACETS_FOR_CORNER[12] = - { - OXY, OYZ, OZX, // O - OZX, OXY, XYZ, // X - OYZ, XYZ, OXY, // Y - OZX, XYZ, OYZ // Z - }; - - // check segment intersect a facet - for(int i = 0 ; i < 3 ; ++i) - { - const TetraFacet facet = FACETS_FOR_CORNER[3*corner + i]; - if(testSegmentIntersectsFacet(seg, facet)) - { - return true; - } - } - - return false; - } - - /** - * Tests if the given segment of the triangle intersects the half-strip above the - * given edge of the h = 0 plane. (Grandy, eq. [30]) - * - * @param seg segment of the triangle - * @param edge edge of the h = 0 plane of the tetrahedron (XY, YZ, ZX) - * @return true if the upwards ray from the corner intersects the triangle. - */ - bool TransformedTriangle::testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edge) - { - // get right index here to avoid "filling out" array - const int edgeIndex = static_cast(edge) - 3; - - // double products used in test - // products 1 and 2 for each edge -> first condition in Grandy [30] - // products 3 and 4 for each edge -> third condition - // NB : some uncertainty whether these last are correct - // DP_FOR_HALFSTRIP_INTERSECTION - - // facets to use in second condition (S_m) - static const TetraFacet FACET_FOR_HALFSTRIP_INTERSECTION[3] = - { - NO_TET_FACET, // XY -> special case : test with plane H = 0 - OYZ, // YZ - OZX // ZX - }; - - const double cVals[4] = - { - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]), - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]), - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 2]), - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 3]) - }; - - const TetraFacet facet = FACET_FOR_HALFSTRIP_INTERSECTION[edgeIndex]; - - - // special case : facet H = 0 - const bool cond2 = (facet == NO_TET_FACET) ? testSegmentIntersectsHPlane(seg) : testSegmentIntersectsFacet(seg, facet); - LOG(4, "Halfstrip tests (" << seg << ", " << edge << ") : " << (cVals[0]*cVals[1] < 0.0) << ", " << cond2 << ", " << (cVals[2]*cVals[3] > 0.0) ); - LOG(4, "c2 = " << cVals[2] << ", c3 = " << cVals[3] ); - - return (cVals[0]*cVals[1] < 0.0) && cond2 && (cVals[2]*cVals[3] > 0.0); - } - - /** - * Calculates the point of intersection between the given segment of the triangle - * and the halfstrip above the given edge of the tetrahedron. (Grandy, eq. [31]) - * - * @pre testSegmentHalfstripIntersection(seg, edge) returns true - * - * @param seg segment of the triangle - * @param edge edge of the tetrahedron defining the halfstrip - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const - { - assert(edge > OZ); - assert(edge < H01); - - // get right index here to avoid "filling out" array - const int edgeIndex = static_cast(edge) - 3; - assert(edgeIndex >= 0); - assert(edgeIndex < 3); - - // Barycentric interpolation on the edge - // for edge AB : (x,y,z)* = (1-alpha) * A + alpha * B - // where alpha = cB / (cB - cA) - - const double cA = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]); - const double cB = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]); - assert(cA != cB); - - const double alpha = cA / (cA - cB); - - for(int i = 0; i < 3; ++i) - { - const TetraCorner corners[2] = - { - CORNERS_FOR_EDGE[2*edge], - CORNERS_FOR_EDGE[2*edge + 1] - }; - - const double cornerCoords[2] = - { - COORDS_TET_CORNER[3*corners[0] + i], - COORDS_TET_CORNER[3*corners[1] + i] - }; - - pt[i] = (1 - alpha) * cornerCoords[0] + alpha * cornerCoords[1]; - LOG(6, pt[i] ); - assert(pt[i] >= 0.0); - assert(pt[i] <= 1.0); - } - assert(epsilonEqualRelative(pt[0] + pt[1] + pt[2], 1.0)); - } - - /** - * Tests if the given segment of triangle PQR intersects the ray pointing - * in the upwards z - direction from the given corner of the tetrahedron. (Grandy eq. [29]) - * If OPTIMIZE is defined, the double product that should be zero is not verified. - * - * @param seg segment of the triangle PQR - * @param corner corner of the tetrahedron on the h = 0 facet (X, Y, or Z) - * @return true if the upwards ray from the corner intersects the segment. - */ - bool TransformedTriangle::testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const - { - assert(corner == X || corner == Y || corner == Z); - LOG(4, "Testing seg - ray intersection for seg = " << seg << ", corner = " << corner ); - - // readjust index since O is not used - const int cornerIdx = static_cast(corner) - 1; - - // facets to use - //? not sure this is correct - static const TetraFacet FIRST_FACET_SEGMENT_RAY_INTERSECTION[3] = - { - OZX, // X - OYZ, // Y - OZX, // Z - }; - - // cond 2 - const bool cond21 = testSegmentIntersectsFacet(seg, FIRST_FACET_SEGMENT_RAY_INTERSECTION[cornerIdx]); - const bool cond22 = (corner == Z) ? testSegmentIntersectsFacet(seg, OYZ) : testSegmentIntersectsHPlane(seg); - - if(!(cond21 || cond22)) - { - LOG(4, "SR fails at cond 2 : cond21 = " << cond21 << ", cond22 = " << cond22 ); - return false; - } - - // cond 3 - const double cVals[6] = - { - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 1]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 2]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 3]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 4]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 5]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 6]), - }; - - // cond. 3 - if(( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) >= 0.0) - { - LOG(4, "SR fails at cond 3 : " << (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ); - } - return ( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) < 0.0; - - } - - // ///////////////////////////////////////////////////////////////////////////////// - // Utility methods used in intersection tests /////////////// - // ///////////////////////////////////////////////////////////////////////////////// - /** - * Tests if the triangle PQR surrounds the axis on which the - * given edge of the tetrahedron lies. - * - * @param edge edge of tetrahedron - * @return true if PQR surrounds edge, false if not (see Grandy, eq. [53]) - */ - bool TransformedTriangle::testTriangleSurroundsEdge(const TetraEdge edge) const - { - // NB DoubleProduct enum corresponds to TetraEdge enum according to Grandy, table III - // so we can use the edge directly - - const double cPQ = calcStableC(PQ, DoubleProduct(edge)); - const double cQR = calcStableC(QR, DoubleProduct(edge)); - const double cRP = calcStableC(RP, DoubleProduct(edge)); - - LOG(5, "TriangleSurroundsEdge : edge = " << edge << " c = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); - - // if two or more c-values are zero we disallow x-edge intersection - // Grandy, p.446 - const int numZeros = (cPQ == 0.0 ? 1 : 0) + (cQR == 0.0 ? 1 : 0) + (cRP == 0.0 ? 1 : 0); - - if(numZeros >= 2 ) - { - LOG(5, "TriangleSurroundsEdge test fails due to too many 0 dp" ); - } - - return (cPQ*cQR >= 0.0) && (cQR*cRP >= 0.0) && (cRP*cPQ >= 0.0) && numZeros < 2; - } - -} // NAMESPACE diff --git a/medtool/src/INTERP_KERNEL/TransformedTriangleMath.cxx b/medtool/src/INTERP_KERNEL/TransformedTriangleMath.cxx deleted file mode 100644 index b61edc1cd..000000000 --- a/medtool/src/INTERP_KERNEL/TransformedTriangleMath.cxx +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangle.hxx" -#include -#include -#include -#include -#include -#include -#include - -#include "VectorUtils.hxx" - -namespace INTERP_KERNEL -{ - - // ---------------------------------------------------------------------------------- - // Tables - // ---------------------------------------------------------------------------------- - - /// Table with first coordinate (a) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) - const int TransformedTriangle::DP_OFFSET_1[8] = {1, 2, 0, 2, 0, 1, 4, 1}; - - /// Table with second coordinate (b) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) - const int TransformedTriangle::DP_OFFSET_2[8] = {2, 0, 1, 3, 3, 3, 0, 4}; - - /// Coordinates used to calculate triple products by the expanding one of the three rows of the determinant (index to be used : 3*Corner + row) - const int TransformedTriangle::COORDINATE_FOR_DETERMINANT_EXPANSION[12] = - { - // row 1, 2, 3 - 0, 1, 2, // O - 3, 1, 2, // X - 0, 3, 2, // Y - 0, 1, 3 // Z - }; - - /// Double products used to calculate triple products by expanding one of the three rows of the determinant (index to be used : 3*Corner + row) - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_DETERMINANT_EXPANSION[12] = - { - // row 1, 2, 3 - C_YZ, C_ZX, C_XY, // O - C_YZ, C_ZH, C_YH, // X - C_ZH, C_ZX, C_XH, // Y - C_YH, C_XH, C_XY // Z - }; - - /// The machine epsilon, used in precision corrections - const long double TransformedTriangle::MACH_EPS = std::numeric_limits::epsilon(); - - /// 4.0 * the machine epsilon, represents the precision of multiplication when performing corrections corrections ( f in Grandy ) - const long double TransformedTriangle::MULT_PREC_F = 4.0 * TransformedTriangle::MACH_EPS; - - /// Threshold for resetting double and triple products to zero; ( F / f in Grandy ) - const long double TransformedTriangle::THRESHOLD_F = 500.0; - - /// Threshold for what is considered a small enough angle to warrant correction of triple products by Grandy, [57] - const double TransformedTriangle::TRIPLE_PRODUCT_ANGLE_THRESHOLD = 0.1; - - - // after transformation to the U-space, coordinates are inaccurate - // small variations around zero should not be taken into account - void TransformedTriangle::resetNearZeroCoordinates() - { - for (int i=0; i<15; i++) - if (fabs(_coords[i]) distances; - - // -- (1) for each segment : check that double products satisfy Grandy, [46] - // -- and make corrections if not - for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) - { - if(!areDoubleProductsConsistent(seg)) - { - LOG(4, "inconsistent! "); - for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) - { - // calculate distance corner - segment axis - const double dist = calculateDistanceCornerSegment(corner, seg); - distances.insert( std::make_pair( dist, corner ) ); - } - - // first element -> minimum distance - const TetraCorner minCorner = distances.begin()->second; - resetDoubleProducts(seg, minCorner); - distances.clear(); - } - } - - // -- (2) check that each double product statisfies Grandy, [47], else set to 0 - for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) - { - for(DoubleProduct dp = C_YZ ; dp <= C_10 ; dp = DoubleProduct(dp + 1)) - { - // find the points of the triangle - // 0 -> P, 1 -> Q, 2 -> R - const int pt1 = seg; - const int pt2 = (seg + 1) % 3; - - // find offsets - const int off1 = DP_OFFSET_1[dp]; - const int off2 = DP_OFFSET_2[dp]; - - const double term1 = _coords[5*pt1 + off1] * _coords[5*pt2 + off2]; - const double term2 = _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; - - const long double delta = MULT_PREC_F * ( std::fabs(term1) + std::fabs(term2) ); - - if( epsilonEqual(_doubleProducts[8*seg + dp], 0.0, THRESHOLD_F * delta)) - { - // debug output -#if LOG_LEVEL >= 5 - if(_doubleProducts[8*seg + dp] != 0.0) - { - LOG(5, "Double product for (seg,dp) = (" << seg << ", " << dp << ") = " ); - LOG(5, std::fabs(_doubleProducts[8*seg + dp]) << " is imprecise, reset to 0.0" ); - } -#endif - - - _doubleProducts[8*seg + dp] = 0.0; - - } - } - } - - _is_double_products_calculated = true; - } - - /** - * Checks if the double products for a given segment are consistent, as defined by - * Grandy, [46]. - * - * @param seg Segment for which to check consistency of double products - * @return true if the double products are consistent, false if not - */ - bool TransformedTriangle::areDoubleProductsConsistent(const TriSegment seg) const - { - const double term1 = _doubleProducts[8*seg + C_YZ] * _doubleProducts[8*seg + C_XH]; - const double term2 = _doubleProducts[8*seg + C_ZX] * _doubleProducts[8*seg + C_YH]; - const double term3 = _doubleProducts[8*seg + C_XY] * _doubleProducts[8*seg + C_ZH]; - - LOG(2, "for seg " << seg << " consistency " << term1 + term2 + term3 ); - LOG(2, "term1 :" << term1 << " term2 :" << term2 << " term3: " << term3 ); - - const int num_zero = (term1 == 0.0 ? 1 : 0) + (term2 == 0.0 ? 1 : 0) + (term3 == 0.0 ? 1 : 0); - const int num_neg = (term1 < 0.0 ? 1 : 0) + (term2 < 0.0 ? 1 : 0) + (term3 < 0.0 ? 1 : 0); - const int num_pos = (term1 > 0.0 ? 1 : 0) + (term2 > 0.0 ? 1 : 0) + (term3 > 0.0 ? 1 : 0); - - assert( num_zero + num_neg + num_pos == 3 ); - - // calculated geometry is inconsistent if we have one of the following cases - // * one term zero and the other two of the same sign - // * two terms zero - // * all terms positive - // * all terms negative - if(((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 )) - { - LOG(4, "inconsistent dp found" ); - } - return !((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 ); - - } - - /** - * Calculate the shortest distance between a tetrahedron corner and a triangle segment. - * - * @param corner corner of the tetrahedron - * @param seg segment of the triangle - * @return shortest distance from the corner to the segment - */ - double TransformedTriangle::calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const - { - // NB uses fact that TriSegment <=> TriCorner that is first point of segment (PQ <=> P) - const TriCorner ptP_idx = TriCorner(seg); - const TriCorner ptQ_idx = TriCorner( (seg + 1) % 3); - - const double ptP[3] = { _coords[5*ptP_idx], _coords[5*ptP_idx + 1], _coords[5*ptP_idx + 2] }; - const double ptQ[3] = { _coords[5*ptQ_idx], _coords[5*ptQ_idx + 1], _coords[5*ptQ_idx + 2] }; - - // coordinates of corner - const double ptTetCorner[3] = - { - COORDS_TET_CORNER[3*corner ], - COORDS_TET_CORNER[3*corner + 1], - COORDS_TET_CORNER[3*corner + 2] - }; - - // dist^2 = ( PQ x CP )^2 / |PQ|^2 where C is the corner point - - // difference vectors - const double diffPQ[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; - const double diffCornerP[3] = { ptP[0] - ptTetCorner[0], ptP[1] - ptTetCorner[1], ptP[2] - ptTetCorner[2] }; - - // cross product of difference vectors - double crossProd[3]; - cross(diffPQ, diffCornerP, crossProd); - - const double cross_squared = dot(crossProd, crossProd); - const double norm_diffPQ_squared = dot(diffPQ, diffPQ); - - assert(norm_diffPQ_squared != 0.0); - - return cross_squared / norm_diffPQ_squared; - } - - /** - * Pre-calculates all triple products for the tetrahedron with respect to - * this triangle, and stores them internally. This method takes into account - * the problem of errors due to cancellation. - * - */ - void TransformedTriangle::preCalculateTripleProducts(void) - { - if(_is_triple_products_calculated) - { - return; - } - - // find edge / row to use -> that whose edge makes the smallest angle to the triangle - // use a map to find the minimum - std::map anglesForRows; - - LOG(4, "Precalculating triple products" ); - for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) - { - LOG(6, "- Triple product for corner " << corner ); - - for(int row = 1 ; row < 4 ; ++row) - { - const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3*corner + (row - 1)]; - - // get edge by using correspondance between Double Product and Edge - TetraEdge edge = TetraEdge(dp); - - // use edge only if it is surrounded by the surface - if( _triangleSurroundsEdgeCache[edge] ) - { - // -- calculate angle between edge and PQR - const double angle = calculateAngleEdgeTriangle(edge); - anglesForRows.insert(std::make_pair(angle, row)); - } - } - - if(anglesForRows.size() != 0) // we have found a good row - { - const double minAngle = anglesForRows.begin()->first; - const int minRow = anglesForRows.begin()->second; - - if(minAngle < TRIPLE_PRODUCT_ANGLE_THRESHOLD) - { - _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, true); - } - else - { - _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, false); - } - _validTP[corner] = true; - } - else - { - // this value will not be used - // we set it to whatever - LOG(6, "Triple product not calculated for corner " << corner ); - _tripleProducts[corner] = -3.14159265; - _validTP[corner] = false; - - } - anglesForRows.clear(); - - } - - _is_triple_products_calculated = true; - } - - /** - * Calculates the angle between an edge of the tetrahedron and the triangle - * - * @param edge edge of the tetrahedron - * @return angle between triangle and edge - */ - double TransformedTriangle::calculateAngleEdgeTriangle(const TetraEdge edge) const - { - // find normal to PQR - cross PQ and PR - const double pq[3] = - { - _coords[5*Q] - _coords[5*P], - _coords[5*Q + 1] - _coords[5*P + 1], - _coords[5*Q + 2] - _coords[5*P + 2] - }; - - const double pr[3] = - { - _coords[5*R] - _coords[5*P], - _coords[5*R + 1] - _coords[5*P + 1], - _coords[5*R + 2] - _coords[5*P + 2] - }; - - double normal[3]; - - cross(pq, pr, normal); - - static const double EDGE_VECTORS[18] = - { - 1.0, 0.0, 0.0, // OX - 0.0, 1.0, 0.0, // OY - 0.0, 0.0, 1.0, // OZ - -1.0, 1.0, 0.0, // XY - 0.0,-1.0, 1.0, // YZ - 1.0, 0.0,-1.0 // ZX - }; - - const double edgeVec[3] = { - EDGE_VECTORS[3*edge], - EDGE_VECTORS[3*edge + 1], - EDGE_VECTORS[3*edge + 2], - }; - - //return angleBetweenVectors(normal, edgeVec); - - const double lenNormal = norm(normal); - const double lenEdgeVec = norm(edgeVec); - const double dotProd = dot(normal, edgeVec); - - //? is this more stable? -> no subtraction - // return asin( dotProd / ( lenNormal * lenEdgeVec ) ) + 3.141592625358979 / 2.0; - double tmp=dotProd / ( lenNormal * lenEdgeVec ); - tmp=std::max(tmp,-1.); - tmp=std::min(tmp,1.); - return atan(1.0)*4.0 - acos(tmp); - - } - - /** - * Calculates triple product associated with the given corner of tetrahedron, developing - * the determinant by the given row. The triple product gives the signed volume of - * the tetrahedron between this corner and the triangle PQR. If the flag project is true, - * one coordinate is projected out in order to eliminate errors in the intersection point - * calculation due to cancellation. - * - * @pre double products have already been calculated - * @param corner corner for which the triple product is calculated - * @param row row (1 <= row <= 3) used to calculate the determinant - * @param project indicates whether or not to perform projection as inidicated in Grandy, p.446 - * @return triple product associated with corner (see Grandy, [50]-[52]) - */ - double TransformedTriangle::calcTByDevelopingRow(const TetraCorner corner, const int row, const bool project) const - { - - // OVERVIEW OF CALCULATION - // --- sign before the determinant - // the sign used depends on the sign in front of the triple product (Grandy, [15]), - // and the convention used in the definition of the double products - - // the sign in front of the determinant gives the following schema for the three terms (I): - // corner/row 1 2 3 - // O (sign:+) + - + - // X (sign:-) - + - - // Y (sign:-) - + - - // Z (sign:-) - + - - - // the 2x2 determinants are the following (C_AB <=> A_p*B_q - B_p*A_q, etc) - // corner/row 1 2 3 - // O (sign:+) C_YZ C_XZ C_XY - // X (sign:-) C_YZ C_HZ C_HY - // Y (sign:-) C_HZ C_XZ C_XH - // Z (sign:-) C_YH C_XH C_XY - - // these are represented in DP_FOR_DETERMINANT_EXPANSION, - // except for the fact that certain double products are inversed (C_AB <-> C_BA) - - // comparing with the DOUBLE_PRODUCTS and using the fact that C_AB = -C_BA - // we deduce the following schema (II) : - // corner/row 1 2 3 - // O (sign:+) + - + - // X (sign:-) + - - - // Y (sign:-) - - + - // Z (sign:-) + + + - - // comparing the two schemas (I) and (II) gives us the following matrix of signs, - // putting 1 when the signs in (I) and (II) are equal and -1 when they are different : - - static const int SIGNS[12] = - { - 1, 1, 1, - -1,-1, 1, - 1,-1,-1, - -1, 1,-1 - }; - - // find the offsets of the rows of the determinant - const int offset = COORDINATE_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; - - const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; - - const int sign = SIGNS[3 * corner + (row - 1)]; - - const double cQR = calcStableC(QR, dp); - const double cRP = calcStableC(RP, dp); - const double cPQ = calcStableC(PQ, dp); - - double alpha = 0.0; - - // coordinate to use for projection (Grandy, [57]) with edges - // OX, OY, OZ, XY, YZ, ZX in order : - // (y, z, x, h, h, h) - // for the first three we could also use {2, 0, 1} - static const int PROJECTION_COORDS[6] = { 1, 2, 0, 3, 3, 3 } ; - - const int coord = PROJECTION_COORDS[ dp ]; - - // coordinate values for P, Q and R - const double coordValues[3] = { _coords[5*P + coord], _coords[5*Q + coord], _coords[5*R + coord] }; - - if(project) - { - // products coordinate values with corresponding double product - const double coordDPProd[3] = { coordValues[0] * cQR, coordValues[1] * cRP, coordValues[2] * cPQ }; - - const double sumDPProd = coordDPProd[0] + coordDPProd[1] + coordDPProd[2]; - const double sumDPProdSq = dot(coordDPProd, coordDPProd); - - // alpha = sumDPProd / sumDPProdSq; - alpha = (sumDPProdSq != 0.0) ? sumDPProd / sumDPProdSq : 0.0; - } - - const double cQRbar = cQR * (1.0 - alpha * coordValues[0] * cQR); - const double cRPbar = cRP * (1.0 - alpha * coordValues[1] * cRP); - const double cPQbar = cPQ * (1.0 - alpha * coordValues[2] * cPQ); - - // check sign of barred products - should not change - // assert(cQRbar * cQR >= 0.0); - //assert(cRPbar * cRP >= 0.0); - //assert(cPQbar * cPQ >= 0.0); - - const double p_term = _coords[5*P + offset] * cQRbar; - const double q_term = _coords[5*Q + offset] * cRPbar; - const double r_term = _coords[5*R + offset] * cPQbar; - - // check that we are not so close to zero that numerical errors could take over, - // otherwise reset to zero (cf Grandy, p. 446) -#ifdef FIXED_DELTA - const double delta = FIXED_DELTA; -#else - const long double delta = MULT_PREC_F * (std::fabs(p_term) + std::fabs(q_term) + std::fabs(r_term)); -#endif - - if( epsilonEqual( p_term + q_term + r_term, 0.0, THRESHOLD_F * delta) ) - { - LOG(4, "Reset imprecise triple product for corner " << corner << " to zero" ); - return 0.0; - } - else - { - // NB : using plus also for the middle term compensates for a double product - // which is inversely ordered - LOG(6, "Triple product for corner " << corner << ", row " << row << " = " << sign*( p_term + q_term + r_term ) ); - return sign*( p_term + q_term + r_term ); - } - - } - -} diff --git a/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.cxx b/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.cxx deleted file mode 100644 index 345df1096..000000000 --- a/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.cxx +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TranslationRotationMatrix.hxx" - -const double INTERP_KERNEL::TranslationRotationMatrix::EPS=1e-12; diff --git a/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.hxx b/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.hxx deleted file mode 100644 index a0e4a0ebc..000000000 --- a/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.hxx +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TRANSLATIONROTATIONMATRIX_HXX__ -#define __TRANSLATIONROTATIONMATRIX_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT TranslationRotationMatrix - { - - public: - - TranslationRotationMatrix() - { - unsigned i; - for(i=0;i class InterpType > - class TriangulationIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, int orientation, int printLevel); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/TriangulationIntersector.txx b/medtool/src/INTERP_KERNEL/TriangulationIntersector.txx deleted file mode 100644 index a7a080b28..000000000 --- a/medtool/src/INTERP_KERNEL/TriangulationIntersector.txx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __TRIANGULATIONINTERSECTOR_TXX__ -#define __TRIANGULATIONINTERSECTOR_TXX__ - -#include "TriangulationIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P0Bary.txx" - -#include "InterpolationUtils.hxx" -#include "PlanarIntersector.hxx" - -#include - -#define TRI_INTERSECTOR TriangulationIntersector -#define TRI_INTER_TEMPLATE template class InterpType> - -namespace INTERP_KERNEL -{ - TRI_INTER_TEMPLATE - TRI_INTERSECTOR::TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double DimCaracteristic, double Precision, double md3DSurf, double minDot3DSurf, - double MedianPlane, int orientation, int PrintLevel) - :InterpType(meshT,meshS,DimCaracteristic, Precision, md3DSurf, minDot3DSurf, - MedianPlane, true, orientation, PrintLevel) - { - if(PlanarIntersector::_print_level >= 1) - { - std::cout << " - intersection type = triangles " << std::endl; - if(SPACEDIM==3) std::cout << "_do_rotate = true"<< std::endl; - } - } - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - double result = 0.; - int orientation = 1; - - //Obtain the coordinates of T and S - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - //Compute the intersection area - double area[SPACEDIM]; - for(ConnType iT = 1; iT inter; - INTERP_KERNEL::intersec_de_triangle(&CoordsT[0],&CoordsT[SPACEDIM*iT],&CoordsT[SPACEDIM*(iT+1)], - &CoordsS[0],&CoordsS[SPACEDIM*iS],&CoordsS[SPACEDIM*(iS+1)], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); - result +=0.5*fabs(area[0]); - } - //DEBUG prints - if(PlanarIntersector::_print_level >= 3) - { - std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; - for(ConnType i=0; i< nb_inter; i++) - {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } - } - } - } - - //DEBUG PRINTS - if(PlanarIntersector::_print_level >= 3) - std::cout << std::endl <<"Intersection area = " << result << std::endl; - - return orientation*result; - } - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, - const std::vector& sourceCoords, - bool isSourceQuad) - { - double result = 0.; - ConnType nbNodesS=sourceCoords.size()/SPACEDIM; - //Compute the intersection area - double area[SPACEDIM]; - for(ConnType iT = 1; iT<3; iT++) - { - for(ConnType iS = 1; iS inter; - INTERP_KERNEL::intersec_de_triangle(quadrangle,&quadrangle[SPACEDIM*iT],&quadrangle[SPACEDIM*(iT+1)], - &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); - result +=0.5*fabs(area[0]); - } - //DEBUG prints - if(PlanarIntersector::_print_level >= 3) - { - std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; - for(ConnType i=0; i< nb_inter; i++) - {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } - } - } - } - - //DEBUG PRINTS - if(PlanarIntersector::_print_level >= 3) - std::cout << std::endl <<"Intersection area = " << result << std::endl; - - return result; - } - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeometryGeneral(const std::vector& targetCoords, - const std::vector& sourceCoords) - { - double result = 0.; - ConnType nbNodesS=sourceCoords.size()/SPACEDIM; - ConnType nbNodesT=targetCoords.size()/SPACEDIM; - //Compute the intersection area - double area[SPACEDIM]; - for(ConnType iT = 1; iT inter; - INTERP_KERNEL::intersec_de_triangle(&targetCoords[0],&targetCoords[SPACEDIM*iT],&targetCoords[SPACEDIM*(iT+1)], - &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); - result +=0.5*fabs(area[0]); - } - } - } - return result; - } - - //================================================================================ - /*! - * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm - * \param targetCell - list of coordinates of target polygon in full interlace - * \param targetCellQuadratic - specifies if target polygon is quadratic or not - * \param sourceTria - list of coordinates of source triangle - * \param res - coefficients a,b and c associated to nodes of sourceTria - */ - //================================================================================ - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { - std::vector sourceCell(3); - sourceCell[0] = &sourceTria[0]; - sourceCell[1] = &sourceTria[SPACEDIM]; - sourceCell[2] = &sourceTria[SPACEDIM*2]; - - //Compute the intersection area - double inter_area[SPACEDIM], total_area = 0.; - double total_barycenter[SPACEDIM]={0.,0.}; - - const ConnType nbNodesT=targetCell.size()/SPACEDIM; - for(ConnType iT = 1; iT inter; - INTERP_KERNEL::intersec_de_triangle(&targetCell[0],&targetCell[SPACEDIM*iT],&targetCell[SPACEDIM*(iT+1)], - sourceCell[0], sourceCell[1], sourceCell[2], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],inter_area); - inter_area[0] = 0.5 * fabs( inter_area[0] ); - total_area += inter_area[0]; - std::vector inter_bary=INTERP_KERNEL::bary_poly(inter); - total_barycenter[0] += inter_area[0] * inter_bary[0]; - total_barycenter[1] += inter_area[0] * inter_bary[1]; - } - } - if ( total_area > std::numeric_limits::min() ) - { - total_barycenter[0] /= total_area; - total_barycenter[1] /= total_area; - res.resize(3); - barycentric_coords( sourceCell, &total_barycenter[0], &res[0]); - res[0] *= total_area; - res[1] *= total_area; - res[2] *= total_area; - } - else - { - total_area = 0; - } - return total_area; - } - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx b/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx deleted file mode 100644 index 4cd663089..000000000 --- a/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx +++ /dev/null @@ -1,755 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : UnitTetraIntersectionBary.cxx -// Created : Tue Dec 9 16:48:49 2008 -// Author : Edward AGAPOV (eap) -// -#include "UnitTetraIntersectionBary.hxx" - -#include "VectorUtils.hxx" -#include "InterpolationUtils.hxx" -#include "VolSurfFormulae.hxx" - -#define NB_TETRA_SIDES 4 -#define NB_TETRA_NODES 4 - -//#define DMP_UNITTETRAINTERSECTIONBARY - - -namespace INTERP_KERNEL -{ - enum { _X=0, _Y, _Z }; - - inline bool samePoint( const double* p1, const double* p2 ) - { - return ( epsilonEqual( p1[0], p2[0]) && - epsilonEqual( p1[1], p2[1]) && - epsilonEqual( p1[2], p2[2])); - } - - //================================================================================ - /*! - * \brief Creates a ready-to-use tool - */ - //================================================================================ - - UnitTetraIntersectionBary::UnitTetraIntersectionBary(bool isTetraInversed) - :TransformedTriangle(),_int_volume(0),_isTetraInversed( isTetraInversed ) - { - //init(); - } - //================================================================================ - /*! - * \brief Initializes fields - */ - //================================================================================ - - void UnitTetraIntersectionBary::init(bool isTetraInversed) - { - _int_volume = 0; - _isTetraInversed = isTetraInversed; - _faces.clear(); - _polyNormals.clear(); - } - - //================================================================================ - /*! - * \brief Stores a part of triangle common with the unit tetrahedron - * \param triangle - triangle side of other cell - */ - //================================================================================ - - void UnitTetraIntersectionBary::addSide(const TransformedTriangle& triangle) - { - _int_volume += triangle.getVolume(); - - double triNormal[3], polyNormal[3]; - crossprod<3>( triangle.getCorner(P),triangle.getCorner(Q),triangle.getCorner(R), triNormal); - - const std::vector * pPolygonA = &triangle.getPolygonA(); - if ( pPolygonA->size() < 3 ) - { - if ( !epsilonEqual( triNormal[_Z], 0 )) - return; // not vertical triangle does not intersect the unit tetra - - // Vertical triangle. Use inherited methods of TransformedTriangle to - // calculate intesection polygon - *((TransformedTriangle*)this) = triangle; // copy triangle fields - _polygonA.clear(); - _polygonB.clear(); - calculateIntersectionAndProjectionPolygons(); - if (this->_polygonA.size() < 3) - return; - calculatePolygonBarycenter(A, _barycenterA); - sortIntersectionPolygon(A, _barycenterA); - pPolygonA = & _polygonA; - } - - // check if polygon orientation is same as the one of triangle - std::vector::const_iterator p = pPolygonA->begin(), pEnd = pPolygonA->end(); -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout.precision(18); - std::cout << "**** int polygon() " << std::endl; - while ( p != pEnd ) - { - double* pp = *p++; - std::cout << pEnd - p << ": ( " << pp[0] << ", " << pp[1] << ", " << pp[2] << " )" << std::endl; - } - p = pPolygonA->begin(); -#endif - double* p1 = *p++; - double* p2 = *p; - while ( samePoint( p1, p2 ) && ++p != pEnd ) - p2 = *p; - if ( p == pEnd ) - { -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "All points equal" << std::endl; -#endif - clearPolygons(); - return; - } - double* p3 = *p; - while (( samePoint( p2, p3 ) || samePoint( p1, p3 )) && ++p != pEnd ) - p3 = *p; - if ( p == pEnd ) - { -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "Only two points differ" << std::endl; -#endif - clearPolygons(); - return ; - } - crossprod<3>( p1, p2, p3, polyNormal ); - bool reverse = ( dotprod<3>( triNormal, polyNormal ) < 0.0 ); - if (_isTetraInversed) reverse = !reverse; - - // store polygon - _faces.push_back( std::vector< double* > () ); - std::vector< double* >& faceCorner = _faces.back(); - faceCorner.resize( pPolygonA->size()/* + 1*/ ); - - int i = 0; - if ( reverse ) - { - std::vector::const_reverse_iterator polyF = pPolygonA->rbegin(), polyEnd; - for ( polyEnd = pPolygonA->rend(); polyF != polyEnd; ++i, ++polyF ) - if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) - copyVector3( *polyF, faceCorner[i] = new double[3] ); - else - --i; - polyNormal[0] *= -1.; - polyNormal[1] *= -1.; - polyNormal[2] *= -1.; - } - else - { - std::vector::const_iterator polyF = pPolygonA->begin(), polyEnd; - for ( polyEnd = pPolygonA->end(); polyF != polyEnd; ++i, ++polyF ) - if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) - copyVector3( *polyF, faceCorner[i] = new double[3] ); - else - --i; - } - if ( i < 3 ) - { - clearPolygons(); // free memory of _polygonA - _polygonA = faceCorner; - _faces.pop_back(); - } - else - { - if ( i < (int)pPolygonA->size() ) - faceCorner.resize( i ); - - if ( _polyNormals.empty() ) - _polyNormals.reserve(4); - _polyNormals.push_back( std::vector< double >( polyNormal, polyNormal+3 )); - } - -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** addSide() " << _faces.size() << std::endl; - for ( int i = 0; i < faceCorner.size(); ++i ) - { - double* p = faceCorner[i]; - std::cout << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - std::cout << "NORM: ( " << _polyNormals.back()[0] << ", " << _polyNormals.back()[1] << ", " << _polyNormals.back()[2] << " )" << std::endl; -#endif - clearPolygons(); - } - - //================================================================================ - /*! - * \brief Computes and returns coordinates of barycentre - */ - //================================================================================ - - bool UnitTetraIntersectionBary::getBary(double* baryCenter) - { - baryCenter[0] = baryCenter[1] = baryCenter[2] = -1.0; - if ( addSideFaces() < NB_TETRA_SIDES ) - { - // tetra is not intersected - if ( fabs(_int_volume) > 1e-10 ) - { - // tetra is fully inside the other cell - baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.25; - _int_volume = 0.16666666666666666; - return true; - } - return false; - } - // Algo: - // - pick up one point P among the summits of the polyhedron - // - for each face of the polyhedron which does not contain the point : - // - compute the barycenter of the volume obtained by forming the "pyramid" with - // the face as a base and point P as a summit - // - compute the volume of the "pyramid" - // - Add up all barycenter positions weighting them with the volumes. - - baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.; - - std::list< std::vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); - double * PP = f->at(0); - - for ( ++f; f != fEnd; ++f ) - { - std::vector< double* >& polygon = *f; - if ( polygon.empty() ) - continue; - - bool pBelongsToPoly = false; - std::vector::iterator v = polygon.begin(), vEnd = polygon.end(); - for ( ; !pBelongsToPoly && v != vEnd; ++v ) - pBelongsToPoly = samePoint( PP, *v ); - if ( pBelongsToPoly ) - continue; - - // Compute the barycenter of the volume. Barycenter of pyramid is on line - // ( barycenter of polygon -> PP ) with 1/4 of pyramid height from polygon. - - double bary[] = { 0, 0, 0 }; - - // base polygon bary - for ( v = polygon.begin(); v != vEnd ; ++v ) - { - double* p = *v; - bary[0] += p[0]; - bary[1] += p[1]; - bary[2] += p[2]; - } - bary[0] /= (int)polygon.size(); - bary[1] /= (int)polygon.size(); - bary[2] /= (int)polygon.size(); - - // pyramid volume - double vol = 0; - for ( int i = 0; i < (int)polygon.size(); ++i ) - { - double* p1 = polygon[i]; - double* p2 = polygon[(i+1)%polygon.size()]; - vol += std::fabs( calculateVolumeForTetra( p1, p2, bary, PP )); - } - - // put bary on the line ( barycenter of polygon -> PP ) and multiply by volume - baryCenter[0] += ( bary[0] * 0.75 + PP[0] * 0.25 ) * vol; - baryCenter[1] += ( bary[1] * 0.75 + PP[1] * 0.25 ) * vol; - baryCenter[2] += ( bary[2] * 0.75 + PP[2] * 0.25 ) * vol; - } - if ( _int_volume < 0. ) - _int_volume = -_int_volume; - baryCenter[0] /= _int_volume; - baryCenter[1] /= _int_volume; - baryCenter[2] /= _int_volume; - -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout.precision(5); - std::cout << "**** Barycenter " << baryCenter[0] <<", "<< baryCenter[1] <<", "<< baryCenter[2] - << "\t **** Volume " << _int_volume << std::endl; - std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; -#endif - return true; - } - - //================================================================================ - /*! - * \brief Add faces of the intersection polyhedron formed on faces of the - * unit tetrahedron by sides of already added faces - * \retval int - number of faces of intersection polyhedron - */ - //================================================================================ - - int UnitTetraIntersectionBary::addSideFaces() - { - int nbPolyhedraFaces = 0; - - if ( _faces.empty() ) - return nbPolyhedraFaces; - - // ------------------------------------------- - // Detect polygons laying on sides of a tetra - // ------------------------------------------- - - bool sideAdded[NB_TETRA_SIDES] = { false, false, false, false }; - int nbAddedSides = 0; - std::list< std::vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); - for ( ; f != fEnd; ++f ) - { - std::vector< double* >& polygon = *f; - double coordSum[3] = {0,0,0}; - for ( int i = 0; i < (int)polygon.size(); ++i ) - { - double* p = polygon[i]; - coordSum[0] += p[0]; - coordSum[1] += p[1]; - coordSum[2] += p[2]; - } - for ( int j = 0; j < 3 && !sideAdded[j]; ++j ) - { - if ( epsilonEqual( coordSum[j], 0.0 )) - sideAdded[j] = ++nbAddedSides != 0 ; - } - if ( !sideAdded[3] && - ( epsilonEqual( (coordSum[0]+coordSum[1]+coordSum[2]) / (int)polygon.size(), 1. ))) - sideAdded[3] = ++nbAddedSides != 0 ; - } - if ( nbAddedSides == NB_TETRA_SIDES ) - return nbAddedSides; - - // --------------------------------------------------------------------------------- - // Add segments of already added polygons to future polygonal faces on sides of tetra - // --------------------------------------------------------------------------------- - - std::size_t nbIntersectPolygs = _faces.size(); - - std::vector< double* > * sideFaces[ 4 ]; // future polygons on sides of tetra - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - sideFaces[ i ]=0; - if ( !sideAdded[ i ] ) - { - _faces.push_back( std::vector< double* > () ); - sideFaces[ i ] = &_faces.back(); - } - } - f = _faces.begin(), fEnd = _faces.end(); - for ( std::size_t iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons - { - std::vector< double* >& polygon = *f; - for ( std::size_t i = 0; i < polygon.size(); ++i ) - { - // segment ends - double* p1 = polygon[i]; - double* p2 = polygon[(i+1)%polygon.size()]; - bool p1OnSide, p2OnSide;//, onZeroSide = false; - for ( int j = 0; j < 3; ++j ) - { - if ( !sideFaces[ j ] ) - continue; - p1OnSide = epsilonEqual( p1[j], 0. ); - p2OnSide = epsilonEqual( p2[j], 0. ); - if ( p1OnSide && p2OnSide ) - { - // segment p1-p2 is on j-th orthogonal side of tetra - sideFaces[j]->push_back( new double[3] ); - copyVector3( p1, sideFaces[j]->back() ); - sideFaces[j]->push_back( new double[3] ); - copyVector3( p2, sideFaces[j]->back() ); - //break; - } - } - // check if the segment p1-p2 is on the inclined side - if ( sideFaces[3] && - epsilonEqual( p1[_X] + p1[_Y] + p1[_Z], 1.0 ) && - epsilonEqual( p2[_X] + p2[_Y] + p2[_Z], 1.0 )) - { - sideFaces[3]->push_back( new double[3] ); - copyVector3( p1, sideFaces[3]->back() ); - sideFaces[3]->push_back( new double[3] ); - copyVector3( p2, sideFaces[3]->back() ); - } - } - } -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** after Add segments to sides " << std::endl; - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - std::cout << "\t Side " << i << std::endl; - if ( !sideFaces[i] ) - { - std::cout << "\t cut by triagle" << std::endl; - } - else - { - std::vector< double* >& sideFace = *sideFaces[i]; - for ( int i = 0; i < sideFace.size(); ++i ) - { - double* p = sideFace[i]; - std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - } - } -#endif - - // --------------------------------------------------------------------------- - // Make closed polygons on tetra sides by adding not cut off corners of tetra - // --------------------------------------------------------------------------- - - double origin[3] = { 0,0,0 }; - - // find corners of tetra cut off by triangles of other tetra - // --------------------------------------------------------- - - // corners are coded like this: index = 1*X + 2*Y + 3*Z - // (0,0,0) -> index == 0; (0,0,1) -> index == 3 - int cutOffCorners[NB_TETRA_NODES] = { false, false, false, false }; - int passedCorners[NB_TETRA_NODES] = { false, false, false, false }; - - // find cutOffCorners by normals of intersection polygons - int nbCutOffCorners = 0; - for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) - { - f = _faces.begin(), fEnd = _faces.end(); - for ( std::size_t iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons - { - std::vector< double* >& polygon = *f; - - double corner2Poly[3] = { polygon[0][0], polygon[0][1], polygon[0][2] }; - if ( ic ) corner2Poly[ ic-1 ] -= 1.0; - - // _polyNormals are outside of a tetrahedron - double dot = dotprod<3>( corner2Poly, &_polyNormals[iF][0] ); - if ( dot < -DEFAULT_ABS_TOL*DEFAULT_ABS_TOL ) - { -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "side " << iF+1 << ": cut " << ic << std::endl; -#endif - cutOffCorners[ ic ] = true; - nbCutOffCorners++; - break; - } - } - } - - for ( int i = 0; i < 3; ++i ) // loop on orthogonal faces of the unit tetra - { - if ( !sideFaces[i] ) continue; - std::vector< double* >& sideFace = *sideFaces[i]; - - std::size_t nbPoints = sideFace.size(); - if ( nbPoints == 0 ) - continue; // not intersected face at all - no cut off corners can be detected - - int ind1 = (i+1)%3, ind2 = (i+2)%3; // indices of coords on i-th tetra side - - int nbCutOnSide = 0; - bool isSegmentOnEdge=false; - for ( std::size_t ip = 0; ip < nbPoints; ++ip ) - { - std::size_t isSegmentEnd = ( ip % 2 ); - - double* p = sideFace[ ip ]; - double* p2 = isSegmentEnd ? 0 : sideFace[ip+1]; - - if ( !isSegmentEnd ) - isSegmentOnEdge = false; // initialize - - int cutOffIndex = -1, passThIndex = -1;// no cut off neither pass through - int pCut[] = { 0,0,0 }, pPass[] = { 0,0,0 }; - - if ( epsilonEqual( p[ind1], 0.)) - { - // point is on orthogonal edge - if ( !isSegmentEnd && epsilonEqual( p2[ind1], 0. )) - isSegmentOnEdge = true; - - if ( !isSegmentOnEdge ) - { // segment ends are on different edges - pCut[ind2] = (int)isSegmentEnd; // believe that cutting triangles are well oriented - cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; - } - if ( epsilonEqual( p[ind2], 0.) || epsilonEqual( p[ind2], 1.)) - { - pPass[ind2] = ( p[ind2] < 0.5 ) ? 0 : 1; - passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; - } - } - else if ( epsilonEqual( p[ind2], 0.)) - { - // point is on orthogonal edge - if ( !isSegmentEnd && epsilonEqual( p2[ind2], 0. )) - isSegmentOnEdge = true; - if ( !isSegmentEnd ) - {// segment ends are on different edges - pCut[ind1] = 1-(int)isSegmentEnd; - cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; - } - if ( epsilonEqual( p[ind1], 0.) || epsilonEqual( p[ind1], 1.)) - { - pPass[ind1] = ( p[ind1] < 0.5 ) ? 0 : 1; - passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; - } - } - else if ( epsilonEqual(p[ind1] + p[ind2], 1.0 )) - { - // point is on inclined edge - if ( !isSegmentEnd && epsilonEqual(p2[ind1] + p2[ind2], 1.0 )) - isSegmentOnEdge = true; - if ( !isSegmentOnEdge ) - { //segment ends are on different edges - pCut[ind1] = (int)isSegmentEnd; - pCut[ind2] = 1-(int)isSegmentEnd; - cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; - } - } - else - { - continue; - } - // remember cut off and passed through points - if ( passThIndex >= 0 ) - { - passedCorners[ passThIndex ] = true; - if ( cutOffCorners[ passThIndex ] ) - { - nbCutOffCorners--; - cutOffCorners[ passThIndex ] = false; -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "PASS THROUGH " << passThIndex << std::endl; -#endif - } - } - if ( cutOffIndex >= 0 ) - { - nbCutOnSide++; - if ( !passedCorners[ cutOffIndex ] && !cutOffCorners[ cutOffIndex ] ) - { - nbCutOffCorners++; - cutOffCorners[ cutOffIndex ] = true; - } - } - } // loop on points on a unit tetra side - - if ( nbCutOnSide == 0 && nbPoints <= 2 ) - continue; // one segment laying on edge at most - - if ( nbCutOffCorners == NB_TETRA_NODES ) - break; // all tetra corners are cut off - - if ( /*nbCutOnSide <= 2 &&*/ nbPoints >= 6 ) - { - // at least 3 segments - all corners of a side are cut off - for (int cutIndex = 0; cutIndex < NB_TETRA_NODES; ++cutIndex ) - if ( cutIndex != i+1 && !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) - cutOffCorners[ cutIndex ] = ++nbCutOffCorners != 0 ; - } - - } - // loop on orthogonal faces of tetra - - // check if all corners are cut off on the inclined tetra side - if ( sideFaces[ XYZ ] && sideFaces[ XYZ ]->size() >= 6 ) - { - for (int cutIndex = 1; cutIndex < NB_TETRA_NODES; ++cutIndex ) - if ( !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) - cutOffCorners[ cutIndex ] = ++nbCutOffCorners != 0 ; - } - - // Add to faces on tetra sides the corners not cut off by segments of intersection polygons - // ---------------------------------------------------------------------------------- - if ( nbCutOffCorners > 0 ) - { - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - if ( !sideFaces[ i ] ) continue; - std::vector< double* >& sideFace = *sideFaces[i]; - - int excludeCorner = (i + 1) % NB_TETRA_NODES; - for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) - { - if ( !cutOffCorners[ ic ] && ic != excludeCorner ) - { - sideFace.push_back( new double[3] ); - copyVector3( origin, sideFace.back() ); - if ( ic ) - sideFace.back()[ ic-1 ] = 1.0; - } - } - } - } - -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** after Add corners to sides " << std::endl; - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - std::cout << "\t Side " << i << std::endl; - if ( !sideFaces[i] ) { - std::cout << "\t cut by triagle" << std::endl; - } - else - { - std::vector< double* >& sideFace = *sideFaces[i]; - for ( int i = 0; i < sideFace.size(); ++i ) - { - double* p = sideFace[i]; - std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - } - } - std::cout << "Cut off corners: "; - if ( nbCutOffCorners == 0 ) - std::cout << "NO"; - else - for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) - std::cout << cutOffCorners[ ic ]; - std::cout << std::endl; -#endif - // ------------------------------------------------------------------------ - // Sort corners of filled up faces on tetra sides and exclude equal points - // ------------------------------------------------------------------------ - - std::size_t iF = 0; - for ( f = _faces.begin(); f != fEnd; ++f, ++iF ) - { - std::vector< double* >& face = *f; - if ( face.size() >= 3 ) - { - clearPolygons(); // free memory of _polygonA - _polygonA = face; - face.clear(); - face.reserve( _polygonA.size() ); - if ( iF >= nbIntersectPolygs ) - { // sort points of side faces - calculatePolygonBarycenter( A, _barycenterA ); - setTriangleOnSide( (int)(iF-nbIntersectPolygs) ); - sortIntersectionPolygon( A, _barycenterA ); - } - // exclude equal points - std::vector< double* >::iterator v = _polygonA.begin(), vEnd = _polygonA.end(); - face.push_back( *v ); - *v = 0; - for ( ++v; v != vEnd; ++v ) - { - double* pPrev = face.back(); - double* p = *v; - if ( !samePoint( p, pPrev )) - { - face.push_back( p ); - *v = 0; - } - } - } - if ( face.size() < 3 ) - { // size could decrease - clearPolygons(); // free memory of _polygonA - _polygonA = face; - face.clear(); - } - else - { - nbPolyhedraFaces++; - } - } -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** after HEALING all faces " << std::endl; - for (iF=0, f = _faces.begin(); f != fEnd; ++f, ++iF ) - { - std::cout << "\t Side " << iF << std::endl; - std::vector< double* >& sideFace = *f; - for ( int i = 0; i < sideFace.size(); ++i ) - { - double* p = sideFace[i]; - std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - } -#endif - return nbPolyhedraFaces; - } - - //================================================================================ - /*! - * \brief set corners of inherited TransformedTriangle as corners of i-th side of - * the Unit tetra. It is necessary to sort points of faces on sides of the unit - * tetrahedron using sortIntersectionPolygon(A) - */ - //================================================================================ - - void UnitTetraIntersectionBary::setTriangleOnSide(int iSide) - { - if ( iSide >= 3 ) - iSide = 0; - for(int i = 0 ; i < 3 ; ++i) - { - _coords[5*i] = _coords[5*i + 1] = _coords[5*i + 2] = 0.; - if ( i != iSide ) - _coords[5*i + i] = 1.; - } - } - - //================================================================================ - /*! - * \brief Free memory of polygons - */ - //================================================================================ - - void UnitTetraIntersectionBary::clearPolygons(bool andFaces) - { - for(std::vector::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) - { delete[] *it; - *it = 0; - } - for(std::vector::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) - { - delete[] *it; - *it = 0; - } - - _polygonA.clear(); - _polygonB.clear(); - - if ( andFaces ) - { - std::list< std::vector< double* > >::iterator f = this->_faces.begin(), fEnd = this->_faces.end(); - for ( ; f != fEnd; ++f ) - { - std::vector< double* >& polygon = *f; - for(std::vector::iterator it = polygon.begin() ; it != polygon.end() ; ++it) - { - delete[] *it; - *it = 0; - } - } - this->_faces.clear(); - } - } - - //================================================================================ - /*! - * \brief Destructor clears coordinates of faces - */ - //================================================================================ - - UnitTetraIntersectionBary::~UnitTetraIntersectionBary() - { - clearPolygons(/*andFaces=*/true ); - } - -} diff --git a/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx b/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx deleted file mode 100644 index c1446832d..000000000 --- a/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : UnitTetraIntersectionBary.hxx -// Created : Tue Dec 9 16:06:33 2008 -// Author : Edward AGAPOV (eap) -// -#ifndef __UNITTETRAINTERSECTIONBARY_HXX__ -#define __UNITTETRAINTERSECTIONBARY_HXX__ - -#include "TransformedTriangle.hxx" -#include "INTERPKERNELDefines.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class UnitTetraIntersectionBary : protected TransformedTriangle - { - public: - INTERPKERNEL_EXPORT UnitTetraIntersectionBary(bool isTetraInversed=false); - - INTERPKERNEL_EXPORT void init(bool isTetraInversed=false); - /*! - * \brief Stores a part of triangle common with the unit tetrahedron - * \param triangle - triangle side of other cell, whose calculateIntersectionVolume() - * must have already been called - */ - INTERPKERNEL_EXPORT void addSide(const TransformedTriangle& triangle); - - /*! - * \brief Computes and return coordinates of barycentre - */ - INTERPKERNEL_EXPORT bool getBary(double* baryCenter); - - /*! - * \brief Returns volume of intersection - * \retval double - - */ - INTERPKERNEL_EXPORT inline double getVolume() const { return _int_volume; } - - INTERPKERNEL_EXPORT virtual ~UnitTetraIntersectionBary(); - - private: - - int addSideFaces(); - - void setTriangleOnSide(int i); - - void clearPolygons(bool andFaces=false); - - /// volume of intersection - double _int_volume; - - /// faces of intersection polyhedron - std::list< std::vector< double* > > _faces; - std::vector< std::vector< double > > _polyNormals; - - bool _isTetraInversed; - }; - -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx b/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx deleted file mode 100644 index 678ab55db..000000000 --- a/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ - -#include "NormalizedUnstructuredMesh.hxx" - -#include "vtkType.h" - -class vtkUnstructuredGrid; - -template -class INTERPKERNEL_EXPORT VTKNormalizedUnstructuredMesh -{ -public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=MESHDIM; - typedef vtkIdType MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -public: - VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh); - ~VTKNormalizedUnstructuredMesh(); - void getBoundingBox(double *boundingBox) const; - NormalizedCellType getTypeOfElement(vtkIdType eltId) const; - unsigned long getNumberOfElements() const; - unsigned long getNumberOfNodes() const; - const vtkIdType *getConnectivityPtr() const; - const double *getCoordinatesPtr() const; - const vtkIdType *getConnectivityIndexPtr() const; - void releaseTempArrays(); -protected: - void putinMEDFormat() const; -protected: - vtkUnstructuredGrid *_mesh_in_vtk_mode; - mutable vtkIdType *_tmp_index_array; -}; - -#endif diff --git a/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx b/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx deleted file mode 100644 index 96482ff7e..000000000 --- a/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ -#define __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ - -#include "VTKNormalizedUnstructuredMesh.hxx" - -#include "vtkUnstructuredGrid.h" -#include "vtkCellArray.h" -#include "vtkPoints.h" - -template -VTKNormalizedUnstructuredMesh::VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh):_mesh_in_vtk_mode(mesh), - _tmp_index_array(0) -{ -} - -template -VTKNormalizedUnstructuredMesh::~VTKNormalizedUnstructuredMesh() -{ - _mesh_in_vtk_mode->Delete(); - releaseTempArrays(); -} - -template -void VTKNormalizedUnstructuredMesh::getBoundingBox(double *boundingBox) const -{ - double tmp[6]; - _mesh_in_vtk_mode->GetBounds(tmp); - for(unsigned i=0;i<3;i++) - { - boundingBox[i]=tmp[2*i]; - boundingBox[3+i]=tmp[2*i+1]; - } -} - -template -NormalizedCellType VTKNormalizedUnstructuredMesh::getTypeOfElement(vtkIdType eltId) const -{ - int cellType=_mesh_in_vtk_mode->GetCellType(eltId); - int convTab[30]={0,0,0,0,0,(int)NORM_TRI3,0,(int)NORM_POLYGON,0,(int)NORM_QUAD4,(int)NORM_TETRA4,0,(int)NORM_HEXA8 - 0,(int)NORM_PYRA5,0,0,0,(int)NORM_TRI6,(int)NORM_QUAD8,}; -} - -template -unsigned long VTKNormalizedUnstructuredMesh::getNumberOfElements() const -{ - return _mesh_in_vtk_mode->GetNumberOfCells(); -} - -template -unsigned long VTKNormalizedUnstructuredMesh::getNumberOfNodes() const -{ - return _mesh_in_vtk_mode->GetNumberOfPoints(); -} - -template -const vtkIdType *VTKNormalizedUnstructuredMesh::getConnectivityPtr() const -{ - vtkIdType *ret=_mesh_in_vtk_mode->GetCells()->GetPointer(); - if(_tmp_index_array) - return ret; - else - { - putinMEDFormat(); - return ret; - } -} - -template -const double *VTKNormalizedUnstructuredMesh::getCoordinatesPtr() const -{ - return (const double *)_mesh_in_vtk_mode->GetPoints()->GetVoidPointer(0); -} - -template -const vtkIdType *VTKNormalizedUnstructuredMesh::getConnectivityIndexPtr() const -{ - if(_tmp_index_array) - return _tmp_index_array; - else - { - putinMEDFormat(); - return _tmp_index_array; - } -} - -template -void VTKNormalizedUnstructuredMesh::putinMEDFormat() const -{ - long nbOfElem=getNumberOfElements(); - _tmp_index_array=new vtkIdType[nbOfElem+1]; - _tmp_index_array[0]=0; - vtkIdType *coarseConn=_mesh_in_vtk_mode->GetCells()->GetPointer(); - long ptInCC=0; - vtkIdType *finalConn=coarseConn; - for(long i=0;i -void VTKNormalizedUnstructuredMesh::releaseTempArrays() -{ - delete [] _tmp_index_array; - _tmp_index_array=0; -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/VectorUtils.hxx b/medtool/src/INTERP_KERNEL/VectorUtils.hxx deleted file mode 100644 index 21d69803a..000000000 --- a/medtool/src/INTERP_KERNEL/VectorUtils.hxx +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __VECTORUTILS_HXX__ -#define __VECTORUTILS_HXX__ - -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - /// Precision used for tests of 3D part of INTERP_KERNEL - const double VOL_PREC = 1.0e-6; - - /// Default relative tolerance in epsilonEqualRelative - const double DEFAULT_REL_TOL = 1.0e-6; - - /// Default absolute tolerance in epsilonEqual and epsilonEqualRelative - const double DEFAULT_ABS_TOL = 5.0e-12; - - /** - * @param a first point. Should point on a array of size at least equal to SPACEDIM. - * @param b second point. Should point on a array of size at least equal to SPACEDIM. - */ - template - inline double getDistanceBtw2Pts(const double *a, const double *b) - { - double ret2=0.; - for(int i=0;i -#include - -namespace INTERP_KERNEL -{ - inline void calculateBarycenterDyn(const double **pts, int nbPts, - int dim, double *bary); - - inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, - int spaceDim); - - - inline double calculateAreaForQPolyg(const double **coords, int nbOfPtsInPolygs, - int spaceDim); - - inline double calculateLgthForSeg2(const double *p1, const double *p2, int spaceDim) - { - if(spaceDim==1) - return *p2-*p1; - else - { - double ret=0; - for(int i=0;igetCurveLength(); ed->decrRef(); - return ret; - } - else - return calculateLgthForSeg2(begin,end,spaceDim); - } - - // =========================== - // Calculate Area for triangle - // =========================== - inline double calculateAreaForTria(const double *p1, const double *p2, - const double *p3, int spaceDim) - { - double area ; - - if ( spaceDim == 2 ) - { - area = -((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; - } - else - { - area = sqrt(((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))* - ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2])) - + - ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))* - ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2])) - + - ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))* - ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1])))/2.0; - } - - return area ; - } - - // ============================= - // Calculate Area for quadrangle - // ============================= - inline double calculateAreaForQuad(const double *p1, const double *p2, - const double *p3, const double *p4, - int spaceDim) - { - double area ; - - if (spaceDim==2) - { - double a1 = (p2[0]-p1[0])/4.0, a2 = (p2[1]-p1[1])/4.0; - double b1 = (p3[0]-p4[0])/4.0, b2 = (p3[1]-p4[1])/4.0; - double c1 = (p3[0]-p2[0])/4.0, c2 = (p3[1]-p2[1])/4.0; - double d1 = (p4[0]-p1[0])/4.0, d2 = (p4[1]-p1[1])/4.0; - - area = - 4.0*( b1*c2 - c1*b2 + a1*c2 - c1*a2 - + b1*d2 - d1*b2 + a1*d2 - d1*a2); - } - else - { - area = (sqrt(((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]))* - ((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2])) - + ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]))* - ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2])) - + ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))* - ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))) - + - sqrt(((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2]))* - ((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2])) - + ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2]))* - ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2])) - + ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))* - ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))) - )/2.0; - } - - return area ; - } - - // ==================================== - // Calculate Normal Vector for Triangle - // ==================================== - inline void calculateNormalForTria(const double *p1, const double *p2, - const double *p3, double *normal) - { - normal[0] = ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))/2.0; - normal[1] = ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))/2.0; - normal[2] = ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; - } - - // ====================================== - // Calculate Normal Vector for Quadrangle - // ====================================== - inline void calculateNormalForQuad(const double *p1, const double *p2, - const double *p3, const double *p4, - double *normal) - { - double xnormal1 = (p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]); - double xnormal2 = (p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]); - double xnormal3 = (p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]); - double xarea = sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); - xnormal1 = xnormal1/xarea; - xnormal2 = xnormal2/xarea; - xnormal3 = xnormal3/xarea; - xarea = calculateAreaForQuad(p1,p2,p3,p4,3); - normal[0] = xnormal1*xarea ; - normal[1] = xnormal2*xarea ; - normal[2] = xnormal3*xarea ; - } - - // =================================== - // Calculate Normal Vector for Polygon - // =================================== - inline void calculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, - double *normal) - { - double coordOfBary[3]; - - calculateBarycenterDyn(coords,nbOfPtsInPolygs,3,coordOfBary); - double xnormal1 = (coords[0][1]-coords[1][1]) * (coordOfBary[2]-coords[1][2]) - - (coords[0][2]-coords[1][2]) * (coordOfBary[1]-coords[1][1]); - - double xnormal2 = (coords[0][2]-coords[1][2]) * (coordOfBary[0]-coords[1][0]) - - (coords[0][0]-coords[1][0]) * (coordOfBary[2]-coords[1][2]); - - double xnormal3 = (coords[0][0]-coords[1][0]) * (coordOfBary[1]-coords[1][1]) - - (coords[0][1]-coords[1][1]) * (coordOfBary[0]-coords[1][0]); - - double xarea=sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); - - if ( xarea < 1.e-6 ) - { - //std::string diagnosis"Can not calculate normal - polygon is singular"; - throw std::exception(); - } - - xnormal1 = -xnormal1/xarea; - xnormal2 = -xnormal2/xarea; - xnormal3 = -xnormal3/xarea; - xarea = calculateAreaForPolyg(coords,nbOfPtsInPolygs,3); - normal[0] = xnormal1*xarea ; - normal[1] = xnormal2*xarea ; - normal[2] = xnormal3*xarea ; - } - - // ========================== - // Calculate Area for Polygon - // ========================== - inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, - int spaceDim) - { - double ret=0.; - double coordOfBary[3]; - - calculateBarycenterDyn(coords,nbOfPtsInPolygs,spaceDim,coordOfBary); - for ( int i=0; i nodes(nbOfPtsInPolygs); - for(int i=0;igetArea(); - delete pol; - return -ret; - } - else - return calculateAreaForPolyg(coords,nbOfPtsInPolygs/2,spaceDim); - } - else - { - std::ostringstream oss; oss << "INTERP_KERNEL::calculateAreaForQPolyg : nb of points in quadratic polygon is " << nbOfPtsInPolygs << " should be even !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - - // ========================== - // Calculate Volume for Tetra - // ========================== - inline double calculateVolumeForTetra(const double *p1, const double *p2, - const double *p3, const double *p4) - { - return ( (p3[0]-p1[0])*( (p2[1]-p1[1])*(p4[2]-p1[2]) - - (p2[2]-p1[2])*(p4[1]-p1[1]) ) - - (p2[0]-p1[0])*( (p3[1]-p1[1])*(p4[2]-p1[2]) - - (p3[2]-p1[2])*(p4[1]-p1[1]) ) - + (p4[0]-p1[0])*( (p3[1]-p1[1])*(p2[2]-p1[2]) - - (p3[2]-p1[2])*(p2[1]-p1[1]) ) - ) / 6.0 ; - } - - // ========================= - // Calculate Volume for Pyra - // ========================= - inline double calculateVolumeForPyra(const double *p1, const double *p2, - const double *p3, const double *p4, - const double *p5) - { - return ( ((p3[0]-p1[0])*( (p2[1]-p1[1])*(p5[2]-p1[2]) - - (p2[2]-p1[2])*(p5[1]-p1[1]) ) - -(p2[0]-p1[0])*( (p3[1]-p1[1])*(p5[2]-p1[2]) - - (p3[2]-p1[2])*(p5[1]-p1[1]) ) - +(p5[0]-p1[0])*( (p3[1]-p1[1])*(p2[2]-p1[2]) - - (p3[2]-p1[2])*(p2[1]-p1[1]) )) - + - ((p4[0]-p1[0])*( (p3[1]-p1[1])*(p5[2]-p1[2]) - - (p3[2]-p1[2])*(p5[1]-p1[1]) ) - -(p3[0]-p1[0])*( (p4[1]-p1[1])*(p5[2]-p1[2]) - - (p4[2]-p1[2])*(p5[1]-p1[1])) - +(p5[0]-p1[0])*( (p4[1]-p1[1])*(p3[2]-p1[2]) - - (p4[2]-p1[2])*(p3[1]-p1[1]) )) - ) / 6.0 ; - } - - // ========================== - // Calculate Volume for Penta - // ========================== - inline double calculateVolumeForPenta(const double *p1, const double *p2, - const double *p3, const double *p4, - const double *p5, const double *p6) - { - double a1 = (p2[0]-p3[0])/2.0, a2 = (p2[1]-p3[1])/2.0, a3 = (p2[2]-p3[2])/2.0; - double b1 = (p5[0]-p6[0])/2.0, b2 = (p5[1]-p6[1])/2.0, b3 = (p5[2]-p6[2])/2.0; - double c1 = (p4[0]-p1[0])/2.0, c2 = (p4[1]-p1[1])/2.0, c3 = (p4[2]-p1[2])/2.0; - double d1 = (p5[0]-p2[0])/2.0, d2 = (p5[1]-p2[1])/2.0, d3 = (p5[2]-p2[2])/2.0; - double e1 = (p6[0]-p3[0])/2.0, e2 = (p6[1]-p3[1])/2.0, e3 = (p6[2]-p3[2])/2.0; - double f1 = (p1[0]-p3[0])/2.0, f2 = (p1[1]-p3[1])/2.0, f3 = (p1[2]-p3[2])/2.0; - double h1 = (p4[0]-p6[0])/2.0, h2 = (p4[1]-p6[1])/2.0, h3 = (p4[2]-p6[2])/2.0; - - double A = a1*c2*f3 - a1*c3*f2 - a2*c1*f3 + a2*c3*f1 + a3*c1*f2 - a3*c2*f1; - double B = b1*c2*h3 - b1*c3*h2 - b2*c1*h3 + b2*c3*h1 + b3*c1*h2 - b3*c2*h1; - double C = (a1*c2*h3 + b1*c2*f3) - (a1*c3*h2 + b1*c3*f2) - - (a2*c1*h3 + b2*c1*f3) + (a2*c3*h1 + b2*c3*f1) - + (a3*c1*h2 + b3*c1*f2) - (a3*c2*h1 + b3*c2*f1); - double D = a1*d2*f3 - a1*d3*f2 - a2*d1*f3 + a2*d3*f1 + a3*d1*f2 - a3*d2*f1; - double E = b1*d2*h3 - b1*d3*h2 - b2*d1*h3 + b2*d3*h1 + b3*d1*h2 - b3*d2*h1; - double F = (a1*d2*h3 + b1*d2*f3) - (a1*d3*h2 + b1*d3*f2) - - (a2*d1*h3 + b2*d1*f3) + (a2*d3*h1 + b2*d3*f1) - + (a3*d1*h2 + b3*d1*f2) - (a3*d2*h1 + b3*d2*f1); - double G = a1*e2*f3 - a1*e3*f2 - a2*e1*f3 + a2*e3*f1 + a3*e1*f2 - a3*e2*f1; - double H = b1*e2*h3 - b1*e3*h2 - b2*e1*h3 + b2*e3*h1 + b3*e1*h2 - b3*e2*h1; - double P = (a1*e2*h3 + b1*e2*f3) - (a1*e3*h2 + b1*e3*f2) - - (a2*e1*h3 + b2*e1*f3) + (a2*e3*h1 + b2*e3*f1) - + (a3*e1*h2 + b3*e1*f2) - (a3*e2*h1 + b3*e2*f1); - - return (-2.0*(2.0*(A + B + D + E + G + H) + C + F + P)/9.0); - } - - // ========================= - // Calculate Volume for Hexa - // ========================= - inline double calculateVolumeForHexa(const double *pt1, const double *pt2, - const double *pt3, const double *pt4, - const double *pt5, const double *pt6, - const double *pt7, const double *pt8) - { - double a1=(pt3[0]-pt4[0])/8.0, a2=(pt3[1]-pt4[1])/8.0, a3=(pt3[2]-pt4[2])/8.0; - double b1=(pt2[0]-pt1[0])/8.0, b2=(pt2[1]-pt1[1])/8.0, b3=(pt2[2]-pt1[2])/8.0; - double c1=(pt7[0]-pt8[0])/8.0, c2=(pt7[1]-pt8[1])/8.0, c3=(pt7[2]-pt8[2])/8.0; - double d1=(pt6[0]-pt5[0])/8.0, d2=(pt6[1]-pt5[1])/8.0, d3=(pt6[2]-pt5[2])/8.0; - double e1=(pt3[0]-pt2[0])/8.0, e2=(pt3[1]-pt2[1])/8.0, e3=(pt3[2]-pt2[2])/8.0; - double f1=(pt4[0]-pt1[0])/8.0, f2=(pt4[1]-pt1[1])/8.0, f3=(pt4[2]-pt1[2])/8.0; - double h1=(pt7[0]-pt6[0])/8.0, h2=(pt7[1]-pt6[1])/8.0, h3=(pt7[2]-pt6[2])/8.0; - double p1=(pt8[0]-pt5[0])/8.0, p2=(pt8[1]-pt5[1])/8.0, p3=(pt8[2]-pt5[2])/8.0; - double q1=(pt3[0]-pt7[0])/8.0, q2=(pt3[1]-pt7[1])/8.0, q3=(pt3[2]-pt7[2])/8.0; - double r1=(pt4[0]-pt8[0])/8.0, r2=(pt4[1]-pt8[1])/8.0, r3=(pt4[2]-pt8[2])/8.0; - double s1=(pt2[0]-pt6[0])/8.0, s2=(pt2[1]-pt6[1])/8.0, s3=(pt2[2]-pt6[2])/8.0; - double t1=(pt1[0]-pt5[0])/8.0, t2=(pt1[1]-pt5[1])/8.0, t3=(pt1[2]-pt5[2])/8.0; - - double A = a1*e2*q3 - a1*e3*q2 - a2*e1*q3 + a2*e3*q1 + a3*e1*q2 - a3*e2*q1; - double B = c1*h2*q3 - c1*h3*q2 - c2*h1*q3 + c2*h3*q1 + c3*h1*q2 - c3*h2*q1; - double C = (a1*h2 + c1*e2)*q3 - (a1*h3 + c1*e3)*q2 - - (a2*h1 + c2*e1)*q3 + (a2*h3 + c2*e3)*q1 - + (a3*h1 + c3*e1)*q2 - (a3*h2 + c3*e2)*q1; - double D = b1*e2*s3 - b1*e3*s2 - b2*e1*s3 + b2*e3*s1 + b3*e1*s2 - b3*e2*s1; - double E = d1*h2*s3 - d1*h3*s2 - d2*h1*s3 + d2*h3*s1 + d3*h1*s2 - d3*h2*s1; - double F = (b1*h2 + d1*e2)*s3 - (b1*h3 + d1*e3)*s2 - - (b2*h1 + d2*e1)*s3 + (b2*h3 + d2*e3)*s1 - + (b3*h1 + d3*e1)*s2 - (b3*h2 + d3*e2)*s1; - double G = (a1*e2*s3 + b1*e2*q3) - (a1*e3*s2 + b1*e3*q2) - - (a2*e1*s3 + b2*e1*q3) + (a2*e3*s1 + b2*e3*q1) - + (a3*e1*s2 + b3*e1*q2) - (a3*e2*s1 + b3*e2*q1); - double H = (c1*h2*s3 + d1*h2*q3) - (c1*h3*s2 + d1*h3*q2) - - (c2*h1*s3 + d2*h1*q3) + (c2*h3*s1 + d2*h3*q1) - + (c3*h1*s2 + d3*h1*q2) - (c3*h2*s1 + d3*h2*q1); - double I = ((a1*h2 + c1*e2)*s3 + (b1*h2 + d1*e2)*q3) - - ((a1*h3 + c1*e3)*s2 + (b1*h3 + d1*e3)*q2) - - ((a2*h1 + c2*e1)*s3 + (b2*h1 + d2*e1)*q3) - + ((a2*h3 + c2*e3)*s1 + (b2*h3 + d2*e3)*q1) - + ((a3*h1 + c3*e1)*s2 + (b3*h1 + d3*e1)*q2) - - ((a3*h2 + c3*e2)*s1 + (b3*h2 + d3*e2)*q1); - double J = a1*f2*r3 - a1*f3*r2 - a2*f1*r3 + a2*f3*r1 + a3*f1*r2 - a3*f2*r1; - double K = c1*p2*r3 - c1*p3*r2 - c2*p1*r3 + c2*p3*r1 + c3*p1*r2 - c3*p2*r1; - double L = (a1*p2 + c1*f2)*r3 - (a1*p3 + c1*f3)*r2 - - (a2*p1 + c2*f1)*r3 + (a2*p3 + c2*f3)*r1 - + (a3*p1 + c3*f1)*r2 - (a3*p2 + c3*f2)*r1; - double M = b1*f2*t3 - b1*f3*t2 - b2*f1*t3 + b2*f3*t1 + b3*f1*t2 - b3*f2*t1; - double N = d1*p2*t3 - d1*p3*t2 - d2*p1*t3 + d2*p3*t1 + d3*p1*t2 - d3*p2*t1; - double O = (b1*p2 + d1*f2)*t3 - (b1*p3 + d1*f3)*t2 - - (b2*p1 + d2*f1)*t3 + (b2*p3 + d2*f3)*t1 - + (b3*p1 + d3*f1)*t2 - (b3*p2 + d3*f2)*t1; - double P = (a1*f2*t3 + b1*f2*r3) - (a1*f3*t2 + b1*f3*r2) - - (a2*f1*t3 + b2*f1*r3) + (a2*f3*t1 + b2*f3*r1) - + (a3*f1*t2 + b3*f1*r2) - (a3*f2*t1 + b3*f2*r1); - double Q = (c1*p2*t3 + d1*p2*r3) - (c1*p3*t2 + d1*p3*r2) - - (c2*p1*t3 + d2*p1*r3) + (c2*p3*t1 + d2*p3*r1) - + (c3*p1*t2 + d3*p1*r2) - (c3*p2*t1 + d3*p2*r1); - double R = ((a1*p2 + c1*f2)*t3 + (b1*p2 + d1*f2)*r3) - - ((a1*p3 + c1*f3)*t2 + (b1*p3 + d1*f3)*r2) - - ((a2*p1 + c2*f1)*t3 + (b2*p1 + d2*f1)*r3) - + ((a2*p3 + c2*f3)*t1 + (b2*p3 + d2*f3)*r1) - + ((a3*p1 + c3*f1)*t2 + (b3*p1 + d3*f1)*r2) - - ((a3*p2 + c3*f2)*t1 + (b3*p2 + d3*f2)*r1); - double S = (a1*e2*r3 + a1*f2*q3) - (a1*e3*r2 + a1*f3*q2) - - (a2*e1*r3 + a2*f1*q3) + (a2*e3*r1 + a2*f3*q1) - + (a3*e1*r2 + a3*f1*q2) - (a3*e2*r1 + a3*f2*q1); - double T = (c1*h2*r3 + c1*p2*q3) - (c1*h3*r2 + c1*p3*q2) - - (c2*h1*r3 + c2*p1*q3) + (c2*h3*r1 + c2*p3*q1) - + (c3*h1*r2 + c3*p1*q2) - (c3*h2*r1 + c3*p2*q1); - double U = ((a1*h2 + c1*e2)*r3 + (a1*p2 + c1*f2)*q3) - - ((a1*h3 + c1*e3)*r2 + (a1*p3 + c1*f3)*q2) - - ((a2*h1 + c2*e1)*r3 + (a2*p1 + c2*f1)*q3) - + ((a2*h3 + c2*e3)*r1 + (a2*p3 + c2*f3)*q1) - + ((a3*h1 + c3*e1)*r2 + (a3*p1 + c3*f1)*q2) - - ((a3*h2 + c3*e2)*r1 + (a3*p2 + c3*f2)*q1); - double V = (b1*e2*t3 + b1*f2*s3) - (b1*e3*t2 + b1*f3*s2) - - (b2*e1*t3 + b2*f1*s3) + (b2*e3*t1 + b2*f3*s1) - + (b3*e1*t2 + b3*f1*s2) - (b3*e2*t1 + b3*f2*s1); - double W = (d1*h2*t3 + d1*p2*s3) - (d1*h3*t2 + d1*p3*s2) - - (d2*h1*t3 + d2*p1*s3) + (d2*h3*t1 + d2*p3*s1) - + (d3*h1*t2 + d3*p1*s2) - (d3*h2*t1 + d3*p2*s1); - double X = ((b1*h2 + d1*e2)*t3 + (b1*p2 + d1*f2)*s3) - - ((b1*h3 + d1*e3)*t2 + (b1*p3 + d1*f3)*s2) - - ((b2*h1 + d2*e1)*t3 + (b2*p1 + d2*f1)*s3) - + ((b2*h3 + d2*e3)*t1 + (b2*p3 + d2*f3)*s1) - + ((b3*h1 + d3*e1)*t2 + (b3*p1 + d3*f1)*s2) - - ((b3*h2 + d3*e2)*t1 + (b3*p2 + d3*f2)*s1); - double Y = (a1*e2*t3 + a1*f2*s3 + b1*e2*r3 + b1*f2*q3) - - (a1*e3*t2 + a1*f3*s2 + b1*e3*r2 + b1*f3*q2) - - (a2*e1*t3 + a2*f1*s3 + b2*e1*r3 + b2*f1*q3) - + (a2*e3*t1 + a2*f3*s1 + b2*e3*r1 + b2*f3*q1) - + (a3*e1*t2 + a3*f1*s2 + b3*e1*r2 + b3*f1*q2) - - (a3*e2*t1 + a3*f2*s1 + b3*e2*r1 + b3*f2*q1); - double Z = (c1*h2*t3 + c1*p2*s3 + d1*h2*r3 + d1*p2*q3) - - (c1*h3*t2 + c1*p3*s2 + d1*h3*r2 + d1*p3*q2) - - (c2*h1*t3 + c2*p1*s3 + d2*h1*r3 + d2*p1*q3) - + (c2*h3*t1 + c2*p3*s1 + d2*h3*r1 + d2*p3*q1) - + (c3*h1*t2 + c3*p1*s2 + d3*h1*r2 + d3*p1*q2) - - (c3*h2*t1 + c3*p2*s1 + d3*h2*r1 + d3*p2*q1); - double AA = ((a1*h2 + c1*e2)*t3 + (a1*p2 + c1*f2)*s3 - +(b1*h2 + d1*e2)*r3 + (b1*p2 + d1*f2)*q3) - - ((a1*h3 + c1*e3)*t2 + (a1*p3 + c1*f3)*s2 - +(b1*h3 + d1*e3)*r2 + (b1*p3 + d1*f3)*q2) - - ((a2*h1 + c2*e1)*t3 + (a2*p1 + c2*f1)*s3 - +(b2*h1 + d2*e1)*r3 + (b2*p1 + d2*f1)*q3) - + ((a2*h3 + c2*e3)*t1 + (a2*p3 + c2*f3)*s1 - +(b2*h3 + d2*e3)*r1 + (b2*p3 + d2*f3)*q1) - + ((a3*h1 + c3*e1)*t2 + (a3*p1 + c3*f1)*s2 - +(b3*h1 + d3*e1)*r2 + (b3*p1 + d3*f1)*q2) - - ((a3*h2 + c3*e2)*t1 + (a3*p2 + c3*f2)*s1 - + (b3*h2 + d3*e2)*r1 + (b3*p2 + d3*f2)*q1); - - return 64.0*( 8.0*(A + B + D + E + J + K + M + N) - + 4.0*(C + F + G + H + L + O + P + Q + S + T + V + W) - + 2.0*(I + R + U + X + Y + Z) + AA ) / 27.0 ; - } - - // ========================================================================================================================= - // Calculate Volume for Generic Polyedron, even not convex one, WARNING !!! The polyedron's faces must be correctly ordered - // ========================================================================================================================= - inline double calculateVolumeForPolyh(const double ***pts, - const int *nbOfNodesPerFaces, - int nbOfFaces, - const double *bary) - { - double volume=0.; - - for ( int i=0; i - inline double calculateVolumeForPolyh2(const ConnType *connec, int lgth, const double *coords) - { - std::size_t nbOfFaces=std::count(connec,connec+lgth,-1)+1; - double volume=0.; - const int *work=connec; - for(std::size_t iFace=0;iFace::coo2C(work[ptId]); - const double *pti1=coords+3*OTT::coo2C(work[(ptId+1)%nbOfNodesOfCurFace]); - areaVector[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; - areaVector[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; - areaVector[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; - } - const double *pt=coords+3*work[0]; - volume+=pt[0]*areaVector[0]+pt[1]*areaVector[1]+pt[2]*areaVector[2]; - work=work2+1; - } - return volume/6.; - } - - /*! - * This method returns the area oriented vector of a polygon. This method is useful for normal computation without - * any troubles if several edges are colinears. - * @param res must be of size at least 3 to store the result. - */ - template - inline void areaVectorOfPolygon(const ConnType *connec, int lgth, const double *coords, double *res) - { - res[0]=0.; res[1]=0.; res[2]=0.; - for(int ptId=0;ptId::coo2C(connec[ptId]); - const double *pti1=coords+3*OTT::coo2C(connec[(ptId+1)%lgth]); - res[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; - res[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; - res[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; - } - } - - template - inline void computePolygonBarycenter3D(const ConnType *connec, int lgth, const double *coords, double *res) - { - double area[3]; - areaVectorOfPolygon(connec,lgth,coords,area); - double norm=sqrt(area[0]*area[0]+area[1]*area[1]+area[2]*area[2]); - if(norm>std::numeric_limits::min()) - { - area[0]/=norm; area[1]/=norm; area[2]/=norm; - res[0]=0.; res[1]=0.; res[2]=0.; - for(int i=1;i::coo2C(connec[0])]+ - coords[3*OTT::coo2C(connec[i])]+ - coords[3*OTT::coo2C(connec[i+1])])/3.; - v[1]=(coords[3*OTT::coo2C(connec[0])+1]+ - coords[3*OTT::coo2C(connec[i])+1]+ - coords[3*OTT::coo2C(connec[i+1])+1])/3.; - v[2]=(coords[3*OTT::coo2C(connec[0])+2]+ - coords[3*OTT::coo2C(connec[i])+2]+ - coords[3*OTT::coo2C(connec[i+1])+2])/3.; - ConnType tmpConn[3]={connec[0],connec[i],connec[i+1]}; - areaVectorOfPolygon(tmpConn,3,coords,tmpArea); - double norm2=sqrt(tmpArea[0]*tmpArea[0]+tmpArea[1]*tmpArea[1]+tmpArea[2]*tmpArea[2]); - if(norm2>1e-12) - { - tmpArea[0]/=norm2; tmpArea[1]/=norm2; tmpArea[2]/=norm2; - double signOfArea=area[0]*tmpArea[0]+area[1]*tmpArea[1]+area[2]*tmpArea[2]; - res[0]+=signOfArea*norm2*v[0]/norm; res[1]+=signOfArea*norm2*v[1]/norm; res[2]+=signOfArea*norm2*v[2]/norm; - } - } - } - else - { - res[0]=0.; res[1]=0.; res[2]=0.; - if(lgth<1) - throw INTERP_KERNEL::Exception("computePolygonBarycenter3D : lgth of polygon is < 1 !"); - norm=0.; - double v[3]; - for(int i=0;i::coo2C(connec[(i+1)%lgth])]-coords[3*OTT::coo2C(connec[i])]; - v[1]=coords[3*OTT::coo2C(connec[(i+1)%lgth])+1]-coords[3*OTT::coo2C(connec[i])+1]; - v[2]=coords[3*OTT::coo2C(connec[(i+1)%lgth])+2]-coords[3*OTT::coo2C(connec[i])+2]; - double norm2=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); - res[0]+=(coords[3*OTT::coo2C(connec[(i+1)%lgth])]+coords[3*OTT::coo2C(connec[i])])/2.*norm2; - res[1]+=(coords[3*OTT::coo2C(connec[(i+1)%lgth])+1]+coords[3*OTT::coo2C(connec[i])+1])/2.*norm2; - res[2]+=(coords[3*OTT::coo2C(connec[(i+1)%lgth])+2]+coords[3*OTT::coo2C(connec[i])+2])/2.*norm2; - norm+=norm2; - } - if(norm>std::numeric_limits::min()) - { - res[0]/=norm; res[1]/=norm; res[2]/=norm; - return; - } - else - { - res[0]=0.; res[1]=0.; res[2]=0.; - for(int i=0;i::coo2C(connec[i])]; - res[1]+=coords[3*OTT::coo2C(connec[i])+1]; - res[2]+=coords[3*OTT::coo2C(connec[i])+2]; - } - res[0]/=lgth; res[1]/=lgth; res[2]/=lgth; - return; - } - } - } - - inline double integrationOverA3DLine(double u1, double v1, double u2, double v2, double A, double B, double C) - { - return (u1-u2)*(6.*C*C*(v1+v2)+B*B*(v1*v1*v1+v1*v1*v2+v1*v2*v2+v2*v2*v2)+A*A*(2.*u1*u2*(v1+v2)+u1*u1*(3.*v1+v2)+u2*u2*(v1+3.*v2))+ - 4.*C*(A*(2*u1*v1+u2*v1+u1*v2+2.*u2*v2)+B*(v1*v1+v1*v2+v2*v2))+A*B*(u1*(3.*v1*v1+2.*v1*v2+v2*v2)+u2*(v1*v1+2.*v1*v2+3.*v2*v2)))/24.; - } - - template - inline void barycenterOfPolyhedron(const ConnType *connec, int lgth, const double *coords, double *res) - { - std::size_t nbOfFaces=std::count(connec,connec+lgth,-1)+1; - res[0]=0.; res[1]=0.; res[2]=0.; - const int *work=connec; - for(std::size_t i=0;i(work,nbOfNodesOfCurFace,coords,normal); - double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); - if(normOfNormal::min()) - continue; - normal[0]/=normOfNormal; normal[1]/=normOfNormal; normal[2]/=normOfNormal; - double u[2]={normal[1],-normal[0]}; - double s=sqrt(u[0]*u[0]+u[1]*u[1]); - double c=normal[2]; - if(fabs(s)>1e-12) - { - u[0]/=std::abs(s); u[1]/=std::abs(s); - } - else - { u[0]=1.; u[1]=0.; } - //C : high in plane of polyhedron face : always constant - double w=normal[0]*coords[3*OTT::coo2C(work[0])]+ - normal[1]*coords[3*OTT::coo2C(work[0])+1]+ - normal[2]*coords[3*OTT::coo2C(work[0])+2]; - // A,B,D,F,G,H,L,M,N coeffs of rotation matrix defined by (u,c,s) - double A=u[0]*u[0]*(1-c)+c; - double B=u[0]*u[1]*(1-c); - double D=u[1]*s; - double F=B; - double G=u[1]*u[1]*(1-c)+c; - double H=-u[0]*s; - double L=-u[1]*s; - double M=u[0]*s; - double N=c; - double CX=-w*D; - double CY=-w*H; - double CZ=-w*N; - for(int j=0;j::coo2C(work[j]); - const double *p2=coords+3*OTT::coo2C(work[(j+1)%nbOfNodesOfCurFace]); - double u1=A*p1[0]+B*p1[1]+D*p1[2]; - double u2=A*p2[0]+B*p2[1]+D*p2[2]; - double v1=F*p1[0]+G*p1[1]+H*p1[2]; - double v2=F*p2[0]+G*p2[1]+H*p2[2]; - // - double gx=integrationOverA3DLine(u1,v1,u2,v2,A,B,CX); - double gy=integrationOverA3DLine(u1,v1,u2,v2,F,G,CY); - double gz=integrationOverA3DLine(u1,v1,u2,v2,L,M,CZ); - res[0]+=gx*normal[0]; - res[1]+=gy*normal[1]; - res[2]+=gz*normal[2]; - } - work=work2+1; - } - double vol=calculateVolumeForPolyh2(connec,lgth,coords); - if(fabs(vol)>std::numeric_limits::min()) - { - res[0]/=vol; res[1]/=vol; res[2]/=vol; - } - else - { - double sum=0.; - res[0]=0.; res[1]=0.; res[2]=0.; - work=connec; - for(std::size_t i=0;i(work,nbOfNodesOfCurFace,coords,normal); - double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); - if(normOfNormal::min()) - continue; - sum+=normOfNormal; - double tmpBary[3]; - computePolygonBarycenter3D(work,nbOfNodesOfCurFace,coords,tmpBary); - res[0]+=normOfNormal*tmpBary[0]; res[1]+=normOfNormal*tmpBary[1]; res[2]+=normOfNormal*tmpBary[2]; - work=work2+1; - } - res[0]/=sum; res[1]/=sum; res[2]/=sum; - } - } - - // ============================================================================================================================================ - // Calculate Volume for NON Generic Polyedron. Only polydrons with bary included in pts is supported by this method. Result is always positive. - // ============================================================================================================================================ - inline double calculateVolumeForPolyhAbs(const double ***pts, - const int *nbOfNodesPerFaces, - int nbOfFaces, - const double *bary) - { - double volume=0.; - - for ( int i=0; i - inline double addComponentsOfVec(const double **pts, int rk) - { - return pts[N-1][rk]+addComponentsOfVec(pts,rk); - } - - template<> - inline double addComponentsOfVec<1>(const double **pts, int rk) - { - return pts[0][rk]; - } - - template - inline void calculateBarycenter(const double **pts, double *bary) - { - bary[DIM-1]=addComponentsOfVec(pts,DIM-1)/N; - calculateBarycenter(pts,bary); - } - - template<> - inline void calculateBarycenter<2,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<3,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<4,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<5,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<6,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<7,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<8,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - inline void calculateBarycenterDyn(const double **pts, int nbPts, - int dim, double *bary) - { - for(int i=0;i - inline void calculateBarycenterDyn2(const double *pts, int nbPts, double *bary) - { - for(int i=0;i - inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res) - { - double **coords2=new double *[lgth]; - for(int i=0;i(coords+2*OTT::coo2C(connec[i])); - computePolygonBarycenter2DEngine(coords2,lgth,res); - delete [] coords2; - } - - inline void computeQPolygonBarycenter2D(double **coords, int nbOfPtsInPolygs, int spaceDim, double *res) - { - if(nbOfPtsInPolygs%2==0) - { - if(spaceDim==2) - { - std::vector nodes(nbOfPtsInPolygs); - for(int i=0;igetBarycenter(res); - delete pol; - } - else - return computePolygonBarycenter2DEngine(coords,nbOfPtsInPolygs/2,res); - } - else - { - std::ostringstream oss; oss << "INTERP_KERNEL::computeQPolygonBarycenter2D : nb of points in quadratic polygon is " << nbOfPtsInPolygs << " should be even !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/VolSurfUser.cxx b/medtool/src/INTERP_KERNEL/VolSurfUser.cxx deleted file mode 100644 index dcbf7b6f4..000000000 --- a/medtool/src/INTERP_KERNEL/VolSurfUser.cxx +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "VolSurfUser.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint) - { - double dx=pt1Seg2[0]-pt0Seg2[0],dy=pt1Seg2[1]-pt0Seg2[1]; - double norm=sqrt(dx*dx+dy*dy); - if(norm==0.) - return (pt[0]-pt0Seg2[0])*(pt[0]-pt0Seg2[0])+(pt[1]-pt0Seg2[1])*(pt[1]-pt0Seg2[1]);//return std::numeric_limits::max(); - dx/=norm; dy/=norm; - double dx2=pt[0]-pt0Seg2[0],dy2=pt[1]-pt0Seg2[1]; - double dotP=(dx2*dx+dy2*dy); - if(dotP<0. || dotP>norm) - return dotP<0.?(pt[0]-pt0Seg2[0])*(pt[0]-pt0Seg2[0])+(pt[1]-pt0Seg2[1])*(pt[1]-pt0Seg2[1]):(pt[0]-pt1Seg2[0])*(pt[0]-pt1Seg2[0])+(pt[1]-pt1Seg2[1])*(pt[1]-pt1Seg2[1]); - nbOfHint++; - double x=pt0Seg2[0]+dotP*dx,y=pt0Seg2[1]+dotP*dy; - return (x-pt[0])*(x-pt[0])+(y-pt[1])*(y-pt[1]); - } - - double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) - { - double matrix[12]; - if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(pt0Tri3,pt1Tri3,pt2Tri3,matrix)) - return std::numeric_limits::max(); - double xy0[2],xy1[2],xy2[2],xy[2]; xy0[0]=0.; xy0[1]=0.; - xy1[0]=matrix[0]*pt1Tri3[0]+matrix[1]*pt1Tri3[1]+matrix[2]*pt1Tri3[2]+matrix[3]; xy1[1]=0.; - xy2[0]=matrix[0]*pt2Tri3[0]+matrix[1]*pt2Tri3[1]+matrix[2]*pt2Tri3[2]+matrix[3]; - xy2[1]=matrix[4]*pt2Tri3[0]+matrix[5]*pt2Tri3[1]+matrix[6]*pt2Tri3[2]+matrix[7]; - xy[0]=matrix[0]*pt[0]+matrix[1]*pt[1]+matrix[2]*pt[2]+matrix[3]; - xy[1]=matrix[4]*pt[0]+matrix[5]*pt[1]+matrix[6]*pt[2]+matrix[7]; - double z=matrix[8]*pt[0]+matrix[9]*pt[1]+matrix[10]*pt[2]+matrix[11]; - double ret=std::numeric_limits::max(); - std::size_t nbOfHint=0; - if(xy[0]>0. && xy[0](),1./((double)nbOfEdges))); - double matrix[12]; - if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(coords+3*connOfPolygonBg[0],coords+3*connOfPolygonBg[1],baryOfNodes,matrix)) - return std::numeric_limits::max(); - INTERP_KERNEL::AutoPtr ptXY=new double[2*nbOfEdges]; ptXY[0]=0.; ptXY[1]=0.; - ptXY[2]=matrix[0]*coords[3*connOfPolygonBg[1]]+matrix[1]*coords[3*connOfPolygonBg[1]+1]+matrix[2]*coords[3*connOfPolygonBg[1]+2]+matrix[3]; ptXY[3]=0.; - for(std::size_t i=2;i::max(); - std::size_t nbOfHint=0; - for(std::size_t i=0;i - double computeVolSurfOfCell(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords); - - template - double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim); - - template - void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res); - - template - void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); - - double INTERPKERNEL_EXPORT SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint); - - double INTERPKERNEL_EXPORT DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3); - - double INTERPKERNEL_EXPORT DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords); - - bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix); -} - -#endif diff --git a/medtool/src/INTERP_KERNEL/VolSurfUser.txx b/medtool/src/INTERP_KERNEL/VolSurfUser.txx deleted file mode 100644 index c3f1aa4b0..000000000 --- a/medtool/src/INTERP_KERNEL/VolSurfUser.txx +++ /dev/null @@ -1,438 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) -#ifndef __VOLSURFUSER_TXX__ -#define __VOLSURFUSER_TXX__ - -#include "VolSurfUser.hxx" -#include "VolSurfFormulae.hxx" -#include "InterpolationUtils.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - double computeVolSurfOfCell(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords) - { - switch(type) - { - case INTERP_KERNEL::NORM_SEG2 : - case INTERP_KERNEL::NORM_SEG4 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - return INTERP_KERNEL::calculateLgthForSeg2(coords+(SPACEDIM*N1),coords+(SPACEDIM*N2),SPACEDIM); - } - case INTERP_KERNEL::NORM_SEG3 : - { - int beginNode = OTT::coo2C(connec[0]); - int endNode = OTT::coo2C(connec[1]); - int middleNode = OTT::coo2C(connec[2]); - return INTERP_KERNEL::calculateLgthForSeg3(coords+(SPACEDIM*beginNode),coords+(SPACEDIM*endNode),coords+(SPACEDIM*middleNode),SPACEDIM); - } - case INTERP_KERNEL::NORM_TRI3 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - - return INTERP_KERNEL::calculateAreaForTria(coords+(SPACEDIM*N1), - coords+(SPACEDIM*N2), - coords+(SPACEDIM*N3), - SPACEDIM); - } - break; - - case INTERP_KERNEL::NORM_TRI6 : - case INTERP_KERNEL::NORM_TRI7 : - { - const double *pts[6]; - pts[0] = coords+SPACEDIM*OTT::coo2C(connec[0]); - pts[1] = coords+SPACEDIM*OTT::coo2C(connec[1]); - pts[2] = coords+SPACEDIM*OTT::coo2C(connec[2]); - pts[3] = coords+SPACEDIM*OTT::coo2C(connec[3]); - pts[4] = coords+SPACEDIM*OTT::coo2C(connec[4]); - pts[5] = coords+SPACEDIM*OTT::coo2C(connec[5]); - return INTERP_KERNEL::calculateAreaForQPolyg(pts,6,SPACEDIM); - } - break; - case INTERP_KERNEL::NORM_QUAD4 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - - return INTERP_KERNEL::calculateAreaForQuad(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - SPACEDIM); - } - break; - case INTERP_KERNEL::NORM_QUAD8 : - case INTERP_KERNEL::NORM_QUAD9 : - { - const double *pts[8]; - pts[0] = coords+SPACEDIM*OTT::coo2C(connec[0]); - pts[1] = coords+SPACEDIM*OTT::coo2C(connec[1]); - pts[2] = coords+SPACEDIM*OTT::coo2C(connec[2]); - pts[3] = coords+SPACEDIM*OTT::coo2C(connec[3]); - pts[4] = coords+SPACEDIM*OTT::coo2C(connec[4]); - pts[5] = coords+SPACEDIM*OTT::coo2C(connec[5]); - pts[6] = coords+SPACEDIM*OTT::coo2C(connec[6]); - pts[7] = coords+SPACEDIM*OTT::coo2C(connec[7]); - return INTERP_KERNEL::calculateAreaForQPolyg(pts,8,SPACEDIM); - } - break; - case INTERP_KERNEL::NORM_POLYGON : - { - const double **pts=new const double *[lgth]; - for(int inod=0;inod::coo2C(connec[inod]); - double val=INTERP_KERNEL::calculateAreaForPolyg(pts,lgth,SPACEDIM); - delete [] pts; - return val; - } - break; - case INTERP_KERNEL::NORM_QPOLYG : - { - const double **pts=new const double *[lgth]; - for(int inod=0;inod::coo2C(connec[inod]); - double val=INTERP_KERNEL::calculateAreaForQPolyg(pts,lgth,SPACEDIM); - delete [] pts; - return val; - } - break; - case INTERP_KERNEL::NORM_TETRA4 : - case INTERP_KERNEL::NORM_TETRA10 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - - return INTERP_KERNEL::calculateVolumeForTetra(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4); - } - break; - - case INTERP_KERNEL::NORM_PYRA5 : - case INTERP_KERNEL::NORM_PYRA13 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - int N5 = OTT::coo2C(connec[4]); - - return INTERP_KERNEL::calculateVolumeForPyra(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - coords+SPACEDIM*N5); - } - break; - - case INTERP_KERNEL::NORM_PENTA6 : - case INTERP_KERNEL::NORM_PENTA15 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - int N5 = OTT::coo2C(connec[4]); - int N6 = OTT::coo2C(connec[5]); - - return INTERP_KERNEL::calculateVolumeForPenta(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - coords+SPACEDIM*N5, - coords+SPACEDIM*N6); - } - break; - - case INTERP_KERNEL::NORM_HEXA8 : - case INTERP_KERNEL::NORM_HEXA20 : - case INTERP_KERNEL::NORM_HEXA27 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - int N5 = OTT::coo2C(connec[4]); - int N6 = OTT::coo2C(connec[5]); - int N7 = OTT::coo2C(connec[6]); - int N8 = OTT::coo2C(connec[7]); - - return INTERP_KERNEL::calculateVolumeForHexa(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - coords+SPACEDIM*N5, - coords+SPACEDIM*N6, - coords+SPACEDIM*N7, - coords+SPACEDIM*N8); - } - break; - case INTERP_KERNEL::NORM_HEXGP12: - { - const int connecHexa12[43]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[6]),OTT::coo2C(connec[11]),OTT::coo2C(connec[10]),OTT::coo2C(connec[9]),OTT::coo2C(connec[8]),OTT::coo2C(connec[7]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),OTT::coo2C(connec[1]),-1, - OTT::coo2C(connec[1]),OTT::coo2C(connec[7]),OTT::coo2C(connec[8]),OTT::coo2C(connec[2]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[8]),OTT::coo2C(connec[9]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[9]),OTT::coo2C(connec[10]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[4]),OTT::coo2C(connec[10]),OTT::coo2C(connec[11]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[5]),OTT::coo2C(connec[11]),OTT::coo2C(connec[6]),OTT::coo2C(connec[0])}; - return calculateVolumeForPolyh2(connecHexa12,43,coords); - } - case INTERP_KERNEL::NORM_POLYHED : - { - return calculateVolumeForPolyh2(connec,lgth,coords); - } - break; - default: - throw INTERP_KERNEL::Exception("Not recognized cell type to get Length/Area/Volume on it !"); - } - } - - template - double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim) - { - if(spaceDim==3) - return computeVolSurfOfCell(type,connec,lgth,coords); - if(spaceDim==2) - return computeVolSurfOfCell(type,connec,lgth,coords); - if(spaceDim==1) - return computeVolSurfOfCell(type,connec,lgth,coords); - throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 1, 2 or 3"); - } - - - template - void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res) - { - switch(type) - { - case NORM_SEG2: - case NORM_SEG4: - { - std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), - coords+SPACEDIM*OTT::coo2C(connec[0]+1),res); - std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[1]),res,std::plus()); - std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),0.5)); - break; - } - case NORM_SEG3: - { - if(SPACEDIM==2) - { - Edge *ed=Edge::BuildEdgeFrom3Points(coords+2*OTT::coo2C(connec[0]),coords+2*OTT::coo2C(connec[2]),coords+2*OTT::coo2C(connec[1])); - ed->getBarycenter(res); - ed->decrRef(); - } - else if(SPACEDIM==1) - { - *res=(coords[OTT::coo2C(connec[0])]+coords[OTT::coo2C(connec[1])])/2.; - } - else if(SPACEDIM==3) - { - std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), - coords+SPACEDIM*OTT::coo2C(connec[0]+1),res); - std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[1]),res,std::plus()); - std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),0.5)); - } - else - throw INTERP_KERNEL::Exception("computeBarycenter for SEG3 only SPACEDIM 1,2 or 3 supported !"); - break; - } - case NORM_TRI3: - case NORM_TRI7: - { - std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), - coords+SPACEDIM*OTT::coo2C(connec[0]+1),res); - std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[1]),res,std::plus()); - std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[2]),res,std::plus()); - std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),1./3.)); - break; - } - case NORM_TRI6: - { - if(SPACEDIM==2) - { - double *pts[6]; - pts[0] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[0])); - pts[1] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[1])); - pts[2] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[2])); - pts[3] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[3])); - pts[4] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[4])); - pts[5] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[5])); - computeQPolygonBarycenter2D(pts,6,2,res); - } - else if(SPACEDIM==3) - computePolygonBarycenter3D(connec,lgth/2,coords,res); - else - throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); - break; - } - case NORM_QUAD4: - case NORM_POLYGON: - { - if(SPACEDIM==2) - computePolygonBarycenter2D(connec,lgth,coords,res); - else if(SPACEDIM==3) - computePolygonBarycenter3D(connec,lgth,coords,res); - else - throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); - break; - } - case NORM_QUAD8: - { - if(SPACEDIM==2) - { - double *pts[8]; - pts[0] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[0])); - pts[1] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[1])); - pts[2] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[2])); - pts[3] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[3])); - pts[4] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[4])); - pts[5] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[5])); - pts[6] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[6])); - pts[7] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[7])); - computeQPolygonBarycenter2D(pts,8,2,res); - } - else if(SPACEDIM==3) - computePolygonBarycenter3D(connec,lgth/2,coords,res); - else - throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); - break; - } - case INTERP_KERNEL::NORM_QPOLYG : - { - if(SPACEDIM==2) - { - double **pts=new double *[lgth]; - for(int i=0;i(coords+2*OTT::coo2C(connec[i])); - computeQPolygonBarycenter2D(pts,lgth,2,res); - delete [] pts; - } - else if(SPACEDIM==3) - computePolygonBarycenter3D(connec,lgth/2,coords,res); - else - throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); - break; - } - break; - case NORM_TETRA4: - { - res[0]=coords[3*OTT::coo2C(connec[0])]; - res[1]=coords[3*OTT::coo2C(connec[0])+1]; - res[2]=coords[3*OTT::coo2C(connec[0])+2]; - res[0]+=coords[3*OTT::coo2C(connec[1])]; - res[1]+=coords[3*OTT::coo2C(connec[1])+1]; - res[2]+=coords[3*OTT::coo2C(connec[1])+2]; - res[0]+=coords[3*OTT::coo2C(connec[2])]; - res[1]+=coords[3*OTT::coo2C(connec[2])+1]; - res[2]+=coords[3*OTT::coo2C(connec[2])+2]; - res[0]+=coords[3*OTT::coo2C(connec[3])]; - res[1]+=coords[3*OTT::coo2C(connec[3])+1]; - res[2]+=coords[3*OTT::coo2C(connec[3])+2]; - res[0]*=0.25; res[1]*=0.25; res[2]*=0.25; - break; - } - case NORM_PYRA5: - { - double tmp[3]; - computePolygonBarycenter3D(connec,lgth-1,coords,tmp); - res[0]=(coords[3*OTT::coo2C(connec[4])]+3.*tmp[0])/4.; - res[1]=(coords[3*OTT::coo2C(connec[4])+1]+3.*tmp[1])/4.; - res[2]=(coords[3*OTT::coo2C(connec[4])+2]+3.*tmp[2])/4.; - break; - } - case NORM_HEXA8: - { - const int conn[29]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[4]),OTT::coo2C(connec[7]),OTT::coo2C(connec[6]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[3]),OTT::coo2C(connec[7]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[2]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[1]),OTT::coo2C(connec[5]),OTT::coo2C(connec[6]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),OTT::coo2C(connec[1]), - }; - barycenterOfPolyhedron(conn,29,coords,res); - break; - } - case NORM_PENTA6: - { - const int conn[22]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[5]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[2]),OTT::coo2C(connec[5]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[1]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[1]),OTT::coo2C(connec[0]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]) - }; - barycenterOfPolyhedron(conn,22,coords,res); - break; - } - case INTERP_KERNEL::NORM_HEXGP12: - { - const int connecHexa12[43]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[6]),OTT::coo2C(connec[11]),OTT::coo2C(connec[10]),OTT::coo2C(connec[9]),OTT::coo2C(connec[8]),OTT::coo2C(connec[7]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),OTT::coo2C(connec[1]),-1, - OTT::coo2C(connec[1]),OTT::coo2C(connec[7]),OTT::coo2C(connec[8]),OTT::coo2C(connec[2]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[8]),OTT::coo2C(connec[9]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[9]),OTT::coo2C(connec[10]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[4]),OTT::coo2C(connec[10]),OTT::coo2C(connec[11]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[5]),OTT::coo2C(connec[11]),OTT::coo2C(connec[6]),OTT::coo2C(connec[0])}; - barycenterOfPolyhedron(connecHexa12,43,coords,res); - break; - } - case NORM_POLYHED: - { - barycenterOfPolyhedron(connec,lgth,coords,res); - break; - } - default: - throw INTERP_KERNEL::Exception("Not recognized cell type to get Barycenter on it !"); - } - } - - template - void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res) - { - if(spaceDim==3) - return computeBarycenter(type,connec,lgth,coords,res); - if(spaceDim==2) - return computeBarycenter(type,connec,lgth,coords,res); - if(spaceDim==1) - return computeBarycenter(type,connec,lgth,coords,res); - throw INTERP_KERNEL::Exception("Invalid spaceDim specified for compute barycenter : must be 1, 2 or 3"); - } -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/BBTreeTest.cxx b/medtool/src/INTERP_KERNELTest/BBTreeTest.cxx deleted file mode 100644 index a4420571a..000000000 --- a/medtool/src/INTERP_KERNELTest/BBTreeTest.cxx +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "BBTreeTest.hxx" -#include -#include -#include "DirectedBoundingBox.hxx" - -namespace INTERP_TEST -{ - - - void BBTreeTest::setUp() - { - } - - - void BBTreeTest::tearDown() - { - } - - /** - * Test that creates a tree in 2D and check that - * the results are correct in three - * cases : - * a non matching search - * a standard case - * a bbox overlapping the bboxes of the tree - */ - void BBTreeTest::test_BBTree() { - //bbox tree creation - const int N=10; - double* bbox=new double[4*N*N]; - for (int i=0; i tree(bbox,0,0,N*N); - std::vector elems; - - //box outside the tree - double bbox1[4]={-2.0, -1.0, 0.0, 1.0}; - tree.getIntersectingElems(bbox1,elems); - CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); - elems.clear(); - - //box intersecting 4 tree elems - double bbox2[4]={2.5, 3.5, 0.5, 1.5}; - tree.getIntersectingElems(bbox2,elems); - CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); - elems.clear(); - - //box exactly superimposed to two tree elems - double bbox3[4]={5.0,6.0,7.0,9.0}; - tree.getIntersectingElems(bbox3,elems); - CPPUNIT_ASSERT_EQUAL(2,(int)elems.size()); - elems.clear(); - - double xx[2]={1.0,1.0}; - tree.getElementsAroundPoint(xx,elems); - CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); - - delete[] bbox; - } - - void BBTreeTest::test_DirectedBB_3D() - { - // a rectangle 1x2 extruded along vector (10,0,10) - const int nbP = 8, dim = 3; - double coords[nbP*dim] = - { - 0,0,0, 2,0,0, 2,1,0, 0,1,0, - 10,0,10, 12,0,10, 12,1,10, 10,1,10 - }; - INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); - bb.enlarge( 1e-12 ); - - // corners of extrusion are IN - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( !bb.isOut( coords + i )); - - // points near corners of extrusion are OUT - double p[nbP*dim] = - { - 0,0,3, 6,0,3, 5,1,2, 0,1,2, - 8,0,9, 11,0,8, 11,0.5,8, 8,0.5,9 - }; - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( bb.isOut( p + i )); - - // the extrusions shifted by 3 in XOY plane are OUT - double shifted_X[nbP*dim] = - { - 3,0,0, 5,0,0, 5,1,0, 3,1,0, - 13,0,10, 15,0,10, 15,1,10, 13,1,10 - }; - double shifted_x[nbP*dim] = - { - -3,0,0, -1,0,0, -1,1,0, -3,1,0, - 7,0,10, 9,0,10, 9,1,10, 7,1,10 - }; - double shifted_Y[nbP*dim] = - { - 0,3,0, 2,3,0, 2,4,0, 0,4,0, - 10,3,10, 12,3,10, 12,4,10, 10,4,10 - }; - double shifted_y[nbP*dim] = - { - 0,-3,0, 2,-3,0, 2,-2,0, 0,-2,0, - 10,-3,10, 12,-3,10, 12,-2,10, 10,-2,10 - }; - INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_y( shifted_y, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_Y( shifted_Y, nbP, dim); - - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_y )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_Y )); - - // intersecting box is IN - double inters_coords[nbP*dim] = - { - 0,0,0, 2,0,0, 2,1,0, 0,1,0, - 0,0,2, 2,0,2, 2,1,2, 0,1,2 - }; - INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); - CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); - - // overlapping non-directed BB - double overlappingBB[2*dim] = - { - 5,6, 0, 1, -5,4 - }; - CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); - - // non-overlapping non-directed BB - double nonoverlappingBB_1[2*dim] = - { - 5,6, 0,1, -5,2 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); - double nonoverlappingBB_2[2*dim] = - { - 5,6, 0,1, 7,20 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); - } - - void BBTreeTest::test_DirectedBB_2D() - { - // a segment of length 2 extruded along vector (10,10) - const int nbP = 4, dim = 2; - double coords[nbP*dim] = - { - 0,0, 2,0, - 10,10, 12,10, - }; - INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); - bb.enlarge( 1e-12 ); - - // corners of extrusion are IN - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( !bb.isOut( coords + i )); - - // points near corners of extrusion are OUT - double p[nbP*dim] = - { - 1,2, 4,1, - 11,8, 8,9, - }; - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( bb.isOut( p + i )); - - // the extrusions shifted by 3 along OX are OUT - double shifted_X[nbP*dim] = - { - 3,0, 5,0, - 13,10, 15,10, - }; - double shifted_x[nbP*dim] = - { - -3,0, -1,0, - 7,10, 9,10, - }; - INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); - - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); - - // intersecting box is IN - double inters_coords[nbP*dim] = - { - 0,0, 2,0, - 0,2, 2,2 - }; - INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); - CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); - - // overlapping non-directed BB - double overlappingBB[2*dim] = - { - 5,6, -5,4 - }; - CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); - - // non-overlapping non-directed BB - double nonoverlappingBB_1[2*dim] = - { - 5,6, -5,2 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); - double nonoverlappingBB_2[2*dim] = - { - 5,6, 7,20 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); - } - - void BBTreeTest::test_DirectedBB_1D() - { - const int nbP = 2, dim = 1; - double coords[nbP*dim] = - { - 0, 10 - }; - INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); - bb.enlarge( 1e-12 ); - - // coords are IN - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( !bb.isOut( coords + i )); - - // points near ends are OUT - double p[nbP*dim] = - { - -0.0001, 10.1 - }; - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( bb.isOut( p + i )); - - // shifted boxes are OUT - double shifted_X[nbP*dim] = - { - 10.1, 11 - }; - double shifted_x[nbP*dim] = - { - -3.0, -0.001 - }; - INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); - - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); - - // intersecting box is IN - double inters_coords[nbP*dim] = - { - -2,2 - }; - INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); - CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); - - // overlapping non-directed BB - double overlappingBB[2*dim] = - { - -5,4 - }; - CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); - - // non-overlapping non-directed BB - double nonoverlappingBB_1[2*dim] = - { - -5,-2 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); - double nonoverlappingBB_2[2*dim] = - { - 11,16 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); - } - -} diff --git a/medtool/src/INTERP_KERNELTest/BBTreeTest.hxx b/medtool/src/INTERP_KERNELTest/BBTreeTest.hxx deleted file mode 100644 index 89f98835e..000000000 --- a/medtool/src/INTERP_KERNELTest/BBTreeTest.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_BB_TREE_HXX__ -#define __TU_BB_TREE_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "BBTree.txx" - -namespace INTERP_TEST -{ - - /** - * \brief Test suite testing some of the low level methods of TransformedTriangle. - * - */ - class INTERPKERNELTEST_EXPORT BBTreeTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( BBTreeTest ); - CPPUNIT_TEST( test_BBTree ); - CPPUNIT_TEST( test_DirectedBB_1D ); - CPPUNIT_TEST( test_DirectedBB_2D ); - CPPUNIT_TEST( test_DirectedBB_3D ); - CPPUNIT_TEST_SUITE_END(); - - - public: - void setUp(); - - void tearDown(); - - // tests - void test_BBTree(); - void test_DirectedBB_1D(); - void test_DirectedBB_2D(); - void test_DirectedBB_3D(); - - }; - - - - -} - - - -#endif diff --git a/medtool/src/INTERP_KERNELTest/BasicMainTest.hxx b/medtool/src/INTERP_KERNELTest/BasicMainTest.hxx deleted file mode 100644 index e1a78e6c9..000000000 --- a/medtool/src/INTERP_KERNELTest/BasicMainTest.hxx +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BASICMAINTEST_HXX_ -#define _BASICMAINTEST_HXX_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef WIN32 -#include -#endif - -// ============================================================================ -/*! - * Main program source for Unit Tests with cppunit package does not depend - * on actual tests, so we use the same for all partial unit tests. - */ -// ============================================================================ - -int main(int argc, char* argv[]) -{ -#ifndef WIN32 - fpu_control_t cw = _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM); - _FPU_SETCW(cw); -#endif - // --- Create the event manager and test controller - CPPUNIT_NS::TestResult controller; - - // --- Add a listener that colllects test result - CPPUNIT_NS::TestResultCollector result; - controller.addListener( &result ); - - // --- Add a listener that print dots as test run. -#ifdef WIN32 - CPPUNIT_NS::TextTestProgressListener progress; -#else - CPPUNIT_NS::BriefTestProgressListener progress; -#endif - controller.addListener( &progress ); - - // --- Get the top level suite from the registry - - CPPUNIT_NS::Test *suite = - CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); - - // --- Adds the test to the list of test to run - - CPPUNIT_NS::TestRunner runner; - runner.addTest( suite ); - runner.run( controller); - - // --- Print test in a compiler compatible format. - - std::ofstream testFile; - testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); - //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); - CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); - outputter.write(); - - // --- Run the tests. - - bool wasSucessful = result.wasSuccessful(); - testFile.close(); - - // --- Return error code 1 if the one of test failed. - - return wasSucessful ? 0 : 1; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/CMakeLists.txt b/medtool/src/INTERP_KERNELTest/CMakeLists.txt deleted file mode 100644 index cb4720248..000000000 --- a/medtool/src/INTERP_KERNELTest/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${XDR_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${XDR_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ) - -SET(InterpKernelTest_SOURCES - BBTreeTest.cxx - CppUnitTest.cxx - ExprEvalInterpTest.cxx - QuadraticPlanarInterpTest.cxx - QuadraticPlanarInterpTest2.cxx - QuadraticPlanarInterpTest3.cxx - QuadraticPlanarInterpTest4.cxx - QuadraticPlanarInterpTest5.cxx - SingleElementPlanarTests.cxx - TransformedTriangleIntersectTest.cxx - TransformedTriangleTest.cxx - UnitTetra3D2DIntersectionTest.cxx - UnitTetraIntersectionBaryTest.cxx - TestInterpKernelUtils.cxx - ThreeDSurfProjectionTest.cxx -) - -SET(TestINTERP_KERNEL_SOURCES - TestInterpKernel.cxx - ) - -SET(PerfTest_SOURCES - PerfTest.cxx - ) - -IF(NOT MED_ENABLE_MICROMED) - SET(InterpKernelTest_SOURCES - ${InterpKernelTest_SOURCES} - InterpolationOptionsTest.cxx - MEDMeshMaker.cxx - ) - - SET(PerfTest_SOURCES - PerfTest.cxx - ) - ADD_EXECUTABLE(PerfTest ${PerfTest_SOURCES}) - TARGET_LINK_LIBRARIES(PerfTest InterpKernelTest ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) - INSTALL(TARGETS PerfTest DESTINATION ${MEDCOUPLING_INSTALL_BINS}) -ENDIF(NOT MED_ENABLE_MICROMED) - -ADD_LIBRARY(InterpKernelTest SHARED ${InterpKernelTest_SOURCES}) - -SET(InterpKernelTest_LIBS medcoupling interpkernel ${CPPUNIT_LIBRARIES}) -IF(NOT MED_ENABLE_MICROMED) - SET(InterpKernelTest_LIBS medloader ${InterpKernelTest_LIBS}) -ENDIF(NOT MED_ENABLE_MICROMED) -TARGET_LINK_LIBRARIES(InterpKernelTest ${InterpKernelTest_LIBS}) - -ADD_EXECUTABLE(TestINTERP_KERNEL ${TestINTERP_KERNEL_SOURCES}) -TARGET_LINK_LIBRARIES(TestINTERP_KERNEL InterpKernelTest ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestINTERP_KERNEL TestINTERP_KERNEL) - -INSTALL(TARGETS TestINTERP_KERNEL DESTINATION ${MEDCOUPLING_INSTALL_BINS}) -INSTALL(TARGETS InterpKernelTest DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) -INSTALL(FILES CppUnitTest.hxx InterpKernelTestExport.hxx DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_TESTS}/MEDCoupling/INTERP_KERNELTest) -INSTALL(TARGETS TestINTERP_KERNEL InterpKernelTest DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/INTERP_KERNELTest/CTestTestfileInstall.cmake b/medtool/src/INTERP_KERNELTest/CTestTestfileInstall.cmake deleted file mode 100644 index 1152205af..000000000 --- a/medtool/src/INTERP_KERNELTest/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(TestINTERP_KERNEL TestINTERP_KERNEL) -SET_TESTS_PROPERTIES(TestINTERP_KERNEL PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/INTERP_KERNELTest/CppUnitTest.cxx b/medtool/src/INTERP_KERNELTest/CppUnitTest.cxx deleted file mode 100644 index 18cbc1531..000000000 --- a/medtool/src/INTERP_KERNELTest/CppUnitTest.cxx +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CppUnitTest.hxx" diff --git a/medtool/src/INTERP_KERNELTest/CppUnitTest.hxx b/medtool/src/INTERP_KERNELTest/CppUnitTest.hxx deleted file mode 100644 index 14f16c78d..000000000 --- a/medtool/src/INTERP_KERNELTest/CppUnitTest.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_TEST_CPPUNIT_HXX__ -#define __TU_TEST_CPPUNIT_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -/** - * \brief Class tested by TestBogusClass : not very useful - */ -class INTERPKERNELTEST_EXPORT BogusClass { - friend class TestBogusClass; - -public: - BogusClass(double _x) : x(_x) {;} - - double getX() { return x; } - -private: - double x; -}; - -/** - * \brief Class used to figure out CppUnit : not very useful - * - */ -class INTERPKERNELTEST_EXPORT TestBogusClass : public CppUnit::TestFixture -{ - - CPPUNIT_TEST_SUITE( TestBogusClass ); - CPPUNIT_TEST( test1 ); - CPPUNIT_TEST( test2 ); - CPPUNIT_TEST_SUITE_END(); - -public: - void setUp() { - obj = new BogusClass(3.14); - } - - void tearDown() { - delete obj; - } - - void test1() { - // test something - CPPUNIT_ASSERT(obj->x == 3.14); - CPPUNIT_ASSERT(obj->getX() == obj->x); - } - - void test2() { - // test something else - obj->x += 2.6; - CPPUNIT_ASSERT(obj->getX() > 3.14); - } - -private: - BogusClass* obj; - -}; - - - - - - - - -#endif diff --git a/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx deleted file mode 100644 index c5753d73e..000000000 --- a/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx +++ /dev/null @@ -1,696 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "ExprEvalInterpTest.hxx" -#include "InterpKernelExprParser.hxx" - -#include -#include - -using namespace INTERP_TEST; - -void ExprEvalInterpTest::testBuildStringFromFortran() -{ - char toto1[]="123456 "; - char result[]="123456"; - std::string titi; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto1,8); - CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); - CPPUNIT_ASSERT(titi==result); - // - char toto2[]=" 23456 "; - char result2[]=" 23456"; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto2,8); - CPPUNIT_ASSERT(titi==result2); - CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); - // - char toto3[]=" 3456 "; - char result3[]=" 3456"; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto3,8); - CPPUNIT_ASSERT(titi==result3); - CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); - // - char toto4[]=" "; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto4,8); - CPPUNIT_ASSERT_EQUAL(0,(int)titi.length()); - // - char toto5[]=" 345677"; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto5,8); - CPPUNIT_ASSERT(titi==toto5); - CPPUNIT_ASSERT_EQUAL(8,(int)titi.length()); -} - -void ExprEvalInterpTest::testDeleteWhiteSpaces() -{ - char toto[]=" jkhjkh ooooppp l "; - char result[]="jkhjkhoooopppl"; - std::string totoS(toto); - std::string totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto2[]=" jkhjkh ooooppp l "; - totoS=toto2; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto3[]=" jkhjkh oooo pppl "; - totoS=toto3; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto4[]=" jkhjkh oooo pppl"; - totoS=toto4; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto5[]="jkhjkh oooo pppl"; - totoS=toto5; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - totoS=result; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto6[]="j k h j k h o o o o p p p l"; - totoS=toto6; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto7[]="j k h j k h o o o o p pp l"; - totoS=toto7; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto8[]=" "; - totoS=toto8; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR.empty()); - // - char toto9[]=""; - totoS=toto9; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR.empty()); - // - char toto10[]="j\n k \nh\nj \n\n k\nh \n o \no\n o\n o \np\n\npp \n\n l"; - totoS=toto10; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); -} - -void ExprEvalInterpTest::testInterpreter0() -{ - INTERP_KERNEL::ExprParser expr1("3*-2"); - expr1.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,expr1.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr2("-2.3"); - expr2.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr2.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr3("--2.3"); - expr3.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr3.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr4("-++2.3"); - expr4.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr4.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr5("+2.3"); - expr5.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr5.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr6("3^-1"); - expr6.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,expr6.evaluate(),1e-15); -} - -void ExprEvalInterpTest::testInterpreter1() -{ - INTERP_KERNEL::ExprParser expr1("3+2*5"); - expr1.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,expr1.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr2("3+2^3*5"); - expr2.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(43.,expr2.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr3("3+2^(2*5)"); - expr3.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1027.,expr3.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr4("(3.2+4.3)*(1.3+2.3*7.8)"); - expr4.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(144.3,expr4.evaluate(),1e-10); - INTERP_KERNEL::ExprParser expr5("(3.2+4.3)*cos(1.3+2.3*7.8)"); - expr5.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.9355510138337619,expr5.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr6("3+2-4-7+4.3"); - expr6.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.7,expr6.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr7("3.2*4.5/3.3/2.2"); - expr7.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr7.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr8("3.2*4.5/3.3/2.2"); - expr8.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr8.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr9("(((1.23456789)))"); - expr9.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.23456789,expr9.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr10("3.2*((2*5.2+6.)+(1.2*1.2+3.))"); - expr10.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr10.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr11("((3.2*(((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr11.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr11.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr12("((3.2*(cos((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr12.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3038041398761016,expr12.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr13("((3.2*(sin((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr13.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.9223440531261784,expr13.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr14("((3.2*(tan((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr14.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.1724737512280257,expr14.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr15("((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr15.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.608271629457059,expr15.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr16("-((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr16.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr16.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr17("(-(3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr17.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr17.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr18("((-3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr18.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr18.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr19("((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.)))))"); - expr19.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3596226038.1784945,expr19.evaluate(),1e-6); - INTERP_KERNEL::ExprParser expr20("((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr20.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.7179974940325309,expr20.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr21("max(3.2,4.5)"); - expr21.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,expr21.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr22("3.*max(((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.))))),((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.))))))"); - expr22.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10788678114.535484,expr22.evaluate(),1e-5); - INTERP_KERNEL::ExprParser expr23("min(3.2,4.5)"); - expr23.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2,expr23.evaluate(),1e-14); -} - -void ExprEvalInterpTest::testInterpreter2() -{ - INTERP_KERNEL::ExprParser expr1("3.5*x+x*x*x/(2+x)+2*5*y"); - expr1.parse(); - std::set res,expected; - expr1.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - expected.insert("x"); expected.insert("y"); - CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); - double xyValue[2]={1.,3.}; - double res1; - std::vector vars; vars.push_back("x"); vars.push_back("y"); - expr1.prepareExprEvaluation(vars,2,1); - expr1.evaluateExpr(1,xyValue,&res1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13); - xyValue[0]=-2.; - CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,xyValue,&res1),INTERP_KERNEL::Exception); - double res2[2]; - xyValue[0]=1.; - expr1.evaluateExpr(2,xyValue,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13); - INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)"); - expr2.parse(); - res.clear(); expected.clear(); - expr2.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(4,(int)res.size()); - expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec"); - CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); - expr2.prepareExprEvaluation(vars,2,2); - expr2.evaluateExpr(2,xyValue,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14); - INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2."); - expr3.parse(); - expr3.prepareExprEvaluationVec(); - expr3.evaluateExpr(2,xyValue,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14); - INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2."); - expr4.parse(); - CPPUNIT_ASSERT_THROW(expr4.prepareExprEvaluationVec(),INTERP_KERNEL::Exception); -} - -void ExprEvalInterpTest::testInterpreterUnit0() -{ - INTERP_KERNEL::ExprParser expr1("kg"); - expr1.parse(); - INTERP_KERNEL::DecompositionInUnitBase unit=expr1.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1000.)); - INTERP_KERNEL::ExprParser expr2("kgT"); - expr2.parse(); - CPPUNIT_ASSERT_THROW(expr2.evaluateUnit(),INTERP_KERNEL::Exception); - INTERP_KERNEL::ExprParser expr3("g"); - expr3.parse(); - unit=expr3.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1.)); - INTERP_KERNEL::ExprParser expr4("g*m"); - expr4.parse(); - unit=expr4.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,0,0.,1.)); - INTERP_KERNEL::ExprParser expr5("g*m/K"); - expr5.parse(); - unit=expr5.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-1,0.,1.)); - INTERP_KERNEL::ExprParser expr6("g*m/K^2"); - expr6.parse(); - unit=expr6.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.)); - INTERP_KERNEL::ExprParser expr7("g/K^2*m"); - expr7.parse(); - unit=expr7.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.)); - INTERP_KERNEL::ExprParser expr8("g/(K^2*m)"); - expr8.parse(); - unit=expr8.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,-1,0,0,-2,0.,1.)); - INTERP_KERNEL::ExprParser expr9("km/h"); - expr9.parse(); - unit=expr9.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,0.27777777777777779)); - INTERP_KERNEL::ExprParser expr10("m/s"); - expr10.parse(); - unit=expr10.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,1.)); - INTERP_KERNEL::ExprParser expr11("m+s"); - expr11.parse(); - CPPUNIT_ASSERT_THROW(expr11.evaluateUnit(),INTERP_KERNEL::Exception); - INTERP_KERNEL::ExprParser expr12("m-m"); - expr12.parse(); - CPPUNIT_ASSERT_THROW(expr12.evaluateUnit(),INTERP_KERNEL::Exception); - const char expr13C[3]={-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr13(expr13C); - expr13.parse(); - unit=expr13.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); - const char expr14C[4]={-0x3E,-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr14(expr14C); - expr14.parse(); - unit=expr14.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); - INTERP_KERNEL::ExprParser expr15("kN/kg"); - expr15.parse(); - unit=expr15.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,-2,0,0,0.,1000.)); - INTERP_KERNEL::ExprParser expr16("cm"); - expr16.parse(); - unit=expr16.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,0.01)); - INTERP_KERNEL::ExprParser expr17("m"); - expr17.parse(); - unit=expr17.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,1)); - const char expr18C[3]={-0x08,0x43,0x0}; - INTERP_KERNEL::ExprParser expr18(expr18C); - expr18.parse(); - unit=expr18.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); - const char expr19C[6]={-0x50,0x43,0x2F,-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr19(expr19C); - expr19.parse(); - unit=expr19.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,0,0.,1.)); - const char expr20C[9]={-0x50,0x43,0x2A,-0x50,0x43,0x2F,-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr20(expr20C); - expr20.parse(); - unit=expr20.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,0.,1.)); -} - -void ExprEvalInterpTest::testInterpreterUnit1() -{ - INTERP_KERNEL::Unit unit1("m/s"); - INTERP_KERNEL::Unit unit2("km/h"); - CPPUNIT_ASSERT(unit1.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit1)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit1.convert(unit2,100.),1e-10); - INTERP_KERNEL::Unit unit3("J/s"); - INTERP_KERNEL::Unit unit4("kW"); - CPPUNIT_ASSERT(unit3.isCompatibleWith(unit4) && unit4.isCompatibleWith(unit3)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,unit3.convert(unit4,1000.),1e-10); - CPPUNIT_ASSERT(unit4.getCoarseRepr()=="kW"); - INTERP_KERNEL::Unit unit5("kpT"); - CPPUNIT_ASSERT(!unit5.isInterpretationOK()); - CPPUNIT_ASSERT(unit5.getCoarseRepr()=="kpT"); - INTERP_KERNEL::Unit unit6("m*kpT"); - CPPUNIT_ASSERT(!unit6.isInterpretationOK()); - INTERP_KERNEL::Unit unit7("m*s^-1"); - CPPUNIT_ASSERT(unit7.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit7)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit7.convert(unit2,100.),1e-10); - const char unit8C[3]={-0x50,0x43,0x0}; - INTERP_KERNEL::Unit unit8(unit8C); - INTERP_KERNEL::Unit unit9("K"); - CPPUNIT_ASSERT(unit9.isCompatibleWith(unit8) && unit8.isCompatibleWith(unit9)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(335.15,unit8.convert(unit9,62.),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-16.37,unit9.convert(unit8,256.78),1e-10); - INTERP_KERNEL::Unit unit10("m"); - INTERP_KERNEL::Unit unit11("cm"); - CPPUNIT_ASSERT(unit10.isCompatibleWith(unit11) && unit11.isCompatibleWith(unit10)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6200.,unit10.convert(unit11,62.),1e-8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.62,unit11.convert(unit10,62.),1e-15); - INTERP_KERNEL::Unit unit12("m-m"); - CPPUNIT_ASSERT(!unit12.isInterpretationOK()); -} - -void ExprEvalInterpTest::testInterpreter3() -{ - std::set res; - double input[3]; - double res2[3]; - INTERP_KERNEL::ExprParser expr1("2.3+x>5."); - expr1.parse(); - expr1.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr1.prepareExprEvaluationVec(); - input[0]=0.; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); - input[0]=2.8; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(std::numeric_limits::max()==res2[0]); - input[0]=2.6; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); - // - INTERP_KERNEL::ExprParser expr2("2.3+x<5."); - expr2.parse(); - res.clear(); - expr2.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr2.prepareExprEvaluationVec(); - input[0]=0.; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(std::numeric_limits::max()==res2[0]); - input[0]=2.8; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); - input[0]=2.6; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(std::numeric_limits::max()==res2[0]); - // - INTERP_KERNEL::ExprParser expr3("if(2.3+x<5.,2+3*x,3+x/2)"); - expr3.parse(); - res.clear(); - expr3.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr3.prepareExprEvaluationVec(); - input[0]=0.; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res2[0],1e-12); - input[0]=2.8; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.4,res2[0],1e-12); - input[0]=2.6; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.8,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr4("if(x>1000,2*x,x/3)"); - expr4.parse(); - res.clear(); - expr4.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr4.prepareExprEvaluationVec(); - input[0]=2.7; - expr4.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.9,res2[0],1e-12); - input[0]=999.; - expr4.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(333.,res2[0],1e-12); - input[0]=1002.; - expr4.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2004.,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr5("4.4*x*log10(x)*10"); - expr5.parse(); - res.clear(); - expr5.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr5.prepareExprEvaluationVec(); - input[0]=273.15; - expr5.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(29282.131520617437,res2[0],1e-9); - input[0]=0.; - CPPUNIT_ASSERT_THROW(expr5.evaluateExpr(1,input,res2),INTERP_KERNEL::Exception); -} - -/*! - * Bug detected by Marc concerning expressions with blanks. - */ -void ExprEvalInterpTest::testInterpreter4() -{ - INTERP_KERNEL::ExprParser expr("2*x + 1"); - double vals[3]={0.1,0.2,0.3}; - std::vector varsV(3); - varsV[0] = "x"; - varsV[1] = "y"; - varsV[2] = "z"; - expr.parse(); - expr.prepareExprEvaluation(varsV,3,1); - double result; - expr.evaluateExpr(1,vals, &result); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2,result,1e-12); -} - -/*! - * Allowing scientific format for floats. - */ -void ExprEvalInterpTest::testInterpreter5() -{ - std::set res; - double input[3]; - double res2[3]; - INTERP_KERNEL::ExprParser expr1("1.85e-3*x"); - expr1.parse(); - expr1.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - input[0]=56.7; - expr1.prepareExprEvaluationVec(); - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); - input[0]=-65.7; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr2("x*1.85e-3"); - expr2.parse(); - expr2.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - input[0]=56.7; - expr2.prepareExprEvaluationVec(); - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); - input[0]=-65.7; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr3("2.6E+1+x*1.85e-3"); - expr3.parse(); - expr3.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - input[0]=56.7; - expr3.prepareExprEvaluationVec(); - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.104895,res2[0],1e-12); - input[0]=-65.7; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.878455,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr4("3.*max(((3.2e+1*(ln((2*5.2E-02+6.)+(1.2E-001*1.2E+2+3e-4))))),((3.2E-2*(exp((6e-1+2*5.2e-2)+(1.2E001*1.2+3.))))))"); - expr4.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6994207.8359543988,expr4.evaluate(),1e-5); -} - -/*! - * Test focusing on fast evaluator. - */ -void ExprEvalInterpTest::testInterpreter6() -{ - std::vector stackOfVal; - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr1("1.-2./3."); - expr1.parse(); - expr1.prepareFastEvaluator(); - expr1.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,stackOfVal.back(),1e-14); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr2("1.-2.^3."); - expr2.parse(); - expr2.prepareFastEvaluator(); - expr2.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.,stackOfVal.back(),1e-14); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr3("(7.-2.)^3."); - expr3.parse(); - expr3.prepareFastEvaluator(); - expr3.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125.,stackOfVal.back(),1e-12); - // now playing with one parameter - calling several times - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr4("1.2/(7.-2.*cos(x/3))"); - expr4.parse(); - expr4.prepareFastEvaluator(); - double z; - expr4.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr4.prepareFastEvaluator(); - z=0.77; - expr4.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.23689586281558844,stackOfVal.back(),1e-12); - stackOfVal.pop_back(); - z=0.55; - expr4.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2384018932069258,stackOfVal.back(),1e-12); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr5("x-2*cos(y/3.)"); - expr5.parse(); - expr5.prepareFastEvaluator(); - double *aa(new double[2]); - std::vector vv(2); vv[0]="x"; vv[1]="y"; - expr5.prepareExprEvaluationDouble(vv,2,1,0,aa,aa+2); - expr5.prepareFastEvaluator(); - aa[0]=0.3; aa[1]=0.5; - expr5.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.67228646312585,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - aa[0]=0.5; aa[1]=0.3; - expr5.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.4900083305560516,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - delete [] aa; - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr6("x*IVec-2*cos(y/3.)*JVec"); - expr6.parse(); - aa=new double[2]; - vv.resize(2); vv[0]="x"; vv[1]="y"; - expr6.prepareExprEvaluationDouble(vv,2,2,0,aa,aa+2);//emulate 1st interpreter - expr6.prepareFastEvaluator(); - aa[0]=0.3; aa[1]=0.5; - expr6.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.3,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - expr6.prepareExprEvaluationDouble(vv,2,2,1,aa,aa+2);//emulate 2nd interpreter - expr6.prepareFastEvaluator(); - expr6.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.97228646312585,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - delete [] aa; - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr7("if(x>3.,-6,7.)"); - expr7.parse(); - expr7.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr7.prepareFastEvaluator(); - z=3.1; - expr7.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - z=2.8; - expr7.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr8("if(x<3.,-6,7.)"); - expr8.parse(); - expr8.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr8.prepareFastEvaluator(); - z=3.1; - expr8.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - z=2.8; - expr8.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr9("x*x/2");//this test is very important to test for iso priority with more than one - expr9.parse(); - expr9.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr9.prepareFastEvaluator(); - z=3.; - expr9.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr10("2./3./4./5."); - expr10.parse(); - expr10.prepareFastEvaluator(); - expr10.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03333333333333333,stackOfVal.back(),1e-13); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr11("2./3./4.*5."); - expr11.parse(); - expr11.prepareFastEvaluator(); - expr11.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83333333333333333,stackOfVal.back(),1e-14); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr12("2./3.*4.*5."); - expr12.parse(); - expr12.prepareFastEvaluator(); - expr12.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.333333333333333,stackOfVal.back(),1e-14); -} diff --git a/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx b/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx deleted file mode 100644 index 5d5bd0ef8..000000000 --- a/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef _EXPREVALINTERPTEST_HXX_ -#define _EXPREVALINTERPTEST_HXX_ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - class INTERPKERNELTEST_EXPORT ExprEvalInterpTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( ExprEvalInterpTest ); - CPPUNIT_TEST( testBuildStringFromFortran ); - CPPUNIT_TEST( testDeleteWhiteSpaces ); - CPPUNIT_TEST( testInterpreter0 ); - CPPUNIT_TEST( testInterpreter1 ); - CPPUNIT_TEST( testInterpreter2 ); - CPPUNIT_TEST( testInterpreterUnit0 ); - CPPUNIT_TEST( testInterpreterUnit1 ); - CPPUNIT_TEST( testInterpreter3 ); - CPPUNIT_TEST( testInterpreter4 ); - CPPUNIT_TEST( testInterpreter5 ); - CPPUNIT_TEST( testInterpreter6 ); - CPPUNIT_TEST_SUITE_END(); - public: - void setUp() { } - void tearDown() { } - void cleanUp() { } - void testBuildStringFromFortran(); - void testDeleteWhiteSpaces(); - void testInterpreter0(); - void testInterpreter1(); - void testInterpreter2(); - void testInterpreter3(); - void testInterpreter4(); - void testInterpreter5(); - void testInterpreter6(); - void testInterpreterUnit0(); - void testInterpreterUnit1(); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/HexaTests.hxx b/medtool/src/INTERP_KERNELTest/HexaTests.hxx deleted file mode 100644 index 3edcbd326..000000000 --- a/medtool/src/INTERP_KERNELTest/HexaTests.hxx +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __HEXA_TESTS_HXX_ -#define __HEXA_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class performing intersection tests on meshes with hexahedral elements. - * - */ - class HexaTests : public InterpolationTestSuite<3,3> - { - CPPUNIT_TEST_SUITE( HexaTests ); - - CPPUNIT_TEST( simpleHexaBox ); - //VB : slightly inaccurate so that it triggers a failure of the test - // should be investigated in the future - // CPPUNIT_TEST( reflexiveHexaBox ); - CPPUNIT_TEST( hexaBoxes ); - CPPUNIT_TEST( hexaBoxesMoved ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - /// Intersection between two boxes, aligned with the axes.One has 60 hexahedral elements and the other has 39 tetrahedral elements - /// \brief Status : pass - void simpleHexaBox() - { - _testTools->intersectMeshes("BoxHexa1", "BoxTetra2", 65250, 1.0e-5); - } - - /// Intersection of a box with 60 hexahedral elements with itself - /// \brief Status : pass - void reflexiveHexaBox() - { - _testTools->intersectMeshes("BoxHexa1", "BoxHexa1", 204000); - } - - /// Intersection between two boxes, aligned with the axes.Both have hexahedral elements : one 36, the other 60 - /// \brief Status : pass - void hexaBoxes() - { - _testTools->intersectMeshes("BoxHexa1", "BoxHexa2", 65250); - } - - /// Intersection between two boxes in general position with hexahedral elements. One has 200 elements and the other 420. - /// \brief Status : fails - reason unknown. The matrix does not fulfil the transpose requirement : that W_AB = W_BA^T - void hexaBoxesMoved() - { - _testTools->intersectMeshes("MovedHexaBox1", "MovedHexaBox2", 65250); - } - - }; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/InterpKernelTestExport.hxx b/medtool/src/INTERP_KERNELTest/InterpKernelTestExport.hxx deleted file mode 100644 index f34c58fe4..000000000 --- a/medtool/src/INTERP_KERNELTest/InterpKernelTestExport.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _INTERPKERNELTESTEXPORT_HXX_ -#define _INTERPKERNELTESTEXPORT_HXX_ - -#ifdef WIN32 -# if defined InterpKernelTest_EXPORTS -# define INTERPKERNELTEST_EXPORT __declspec( dllexport ) -# else -# define INTERPKERNELTEST_EXPORT __declspec( dllimport ) -# endif -#else -# define INTERPKERNELTEST_EXPORT -#endif - -#endif diff --git a/medtool/src/INTERP_KERNELTest/Interpolation3DTest.cxx b/medtool/src/INTERP_KERNELTest/Interpolation3DTest.cxx deleted file mode 100644 index 1cdf7d2e3..000000000 --- a/medtool/src/INTERP_KERNELTest/Interpolation3DTest.cxx +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Interpolation3DTest.hxx" - -#include "MEDFileMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include -#include - -#include "VectorUtils.hxx" - -// levels : -// 1 - titles and volume results -// 2 - symmetry / diagonal results and intersection matrix output -// 3 - empty -// 4 - empty -// 5 - misc -#include "Log.hxx" - - -//#define VOL_PREC 1.0e-6 - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - -double Interpolation3DTest::sumRow(const IntersectionMatrix& m, int i) const -{ - double vol = 0.0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - if(iter->count(i) != 0.0) - { - std::map::const_iterator iter2 = iter->find(i); - vol += iter2->second; - } - } - return vol; -} - -double Interpolation3DTest::sumCol(const IntersectionMatrix& m, int i) const -{ - double vol = 0.0; - const std::map& col = m[i]; - for(std::map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) - { - vol += std::fabs(iter->second); - } - return vol; -} - - -void Interpolation3DTest::getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double *tab) const -{ - MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(true); - std::copy(vol->getArray()->begin(),vol->getArray()->end(),tab); -} - -double Interpolation3DTest::sumVolume(const IntersectionMatrix& m) const -{ - - std::vector volumes; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - volumes.push_back(iter2->second); - // vol += std::abs(iter2->second); - } - } - - // sum in ascending order to avoid rounding errors - - sort(volumes.begin(), volumes.end()); - const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); - - return vol; -} - -bool Interpolation3DTest::testVolumes(const IntersectionMatrix& m, MEDCouplingUMesh& sMesh, MEDCouplingUMesh& tMesh) const -{ - bool ok = true; - - // source elements - double* sVol = new double[sMesh.getNumberOfCells()]; - getVolumes(sMesh, sVol); - - for(int i = 0; i < sMesh.getNumberOfCells(); ++i) - { - const double sum_row = sumRow(m, i+1); - if(!epsilonEqualRelative(sum_row, sVol[i], VOL_PREC)) - { - LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); - ok = false; - } - LOG(1, "diff = " <::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double v1 = iter2->second; - //if(m2[j - 1].count(i+1) > 0) - // { - std::map theMap = m2.at(j-1); - const double v2 = theMap[i + 1]; - if(v1 != v2) - { - LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); - if(!epsilonEqualRelative(v1, v2, VOL_PREC)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isSymmetric = false; - } - } - } - ++i; - } - if(!isSymmetric) - { - LOG(1, "*** matrices are not symmetric"); - } - return isSymmetric; -} - -bool Interpolation3DTest::testDiagonal(const IntersectionMatrix& m) const -{ - LOG(1, "Checking if matrix is diagonal" ); - int i = 1; - bool isDiagonal = true; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double vol = iter2->second; - if(vol != 0.0 && (i != j)) - { - LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); - if(!epsilonEqual(vol, 0.0, VOL_PREC)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isDiagonal = false; - } - } - } - ++i; - } - if(!isDiagonal) - { - LOG(1, "*** matrix is not diagonal"); - } - return isDiagonal; -} - -void Interpolation3DTest::dumpIntersectionMatrix(const IntersectionMatrix& m) const -{ - int i = 0; - std::cout << "Intersection matrix is " << std::endl; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - - std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << std::endl; - - } - ++i; - } - std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; -} - -void Interpolation3DTest::setUp() -{ - interpolator = new Interpolation3D(); -} - -void Interpolation3DTest::tearDown() -{ - delete interpolator; -} - -void Interpolation3DTest::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const -{ - string dataDir = ""; - if ( getenv("MEDCOUPLING_ROOT_DIR") ) { - dataDir = getenv("MEDCOUPLING_ROOT_DIR"); - dataDir += "/share/resources/med/"; - } - else { - dataDir = get_current_dir_name(); - dataDir += "/../../resources/"; - } - - LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); - - m = interpolator->interpolateMeshes(sMesh, tMesh); - - // if reflexive, check volumes - if(strcmp(mesh1path,mesh2path) == 0) - { - const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); - } - - LOG(1, "Intersection calculation done. " << std::endl ); - -} - -void Interpolation3DTest::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const -{ - LOG(1, std::endl << std::endl << "=============================" ); - - using std::string; - const string path1 = string(mesh1path) + string(mesh1); - const string path2 = string(mesh2path) + string(mesh2); - - const bool isTestReflexive = (path1.compare(path2) == 0); - - IntersectionMatrix matrix1; - calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix1); -#endif - - std::cout.precision(16); - - const double vol1 = sumVolume(matrix1); - - if(!doubleTest) - { - LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); - - if(isTestReflexive) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); - } - } - else - { - - IntersectionMatrix matrix2; - calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix2); -#endif - - const double vol2 = sumVolume(matrix2); - - LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testSymmetric(matrix1, matrix2)); - } - -} - - - diff --git a/medtool/src/INTERP_KERNELTest/Interpolation3DTest.hxx b/medtool/src/INTERP_KERNELTest/Interpolation3DTest.hxx deleted file mode 100644 index 6680f94e9..000000000 --- a/medtool/src/INTERP_KERNELTest/Interpolation3DTest.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_INTERPOLATION_3D_TEST_HXX__ -#define __TU_INTERPOLATION_3D_TEST_HXX__ - -#include -#include "Interpolation3D.hxx" - -#define ERR_TOL 1.0e-8 - -/// \brief OBSOLETE - renamed Interpolation3DTestSuite -class Interpolation3DTest : public CppUnit::TestFixture -{ - -public: - void setUp() - { - _testTools = new MeshTestToolkit(); - } - - void tearDown() - { - delete _testTools; - } - -protected: - - MeshToolkit* _testTools; - -}; - -#endif diff --git a/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx b/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx deleted file mode 100644 index 9bc5c7406..000000000 --- a/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDFileMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include "InterpolationOptionsTest.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "Interpolation2D.txx" -#include "TestInterpKernelUtils.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -namespace INTERP_TEST -{ - void InterpolationOptionsTest::setUp() - { - } - - - void InterpolationOptionsTest::tearDown() - { - } - - /** - * Test that creates a tree in 2D and check that - * the results are correct in three - * cases : - * a non matching search - * a standard case - * a bbox overlapping the bboxes of the tree - */ - void InterpolationOptionsTest::test_InterpolationOptions() - { - std::string sourcename=INTERP_TEST::getResourceFile("square1.med"); - MEDFileUMesh *source_mesh=MEDFileUMesh::New(sourcename.c_str(),"Mesh_2"); - - std::string targetname=INTERP_TEST::getResourceFile("square2.med"); - MEDFileUMesh *target_mesh=MEDFileUMesh::New(targetname.c_str(),"Mesh_3"); - - MEDCouplingUMesh *source_mesh_mc=source_mesh->getMeshAtLevel(0); - MEDCouplingFieldDouble *source_field=MEDCouplingFieldDouble::New(ON_CELLS); - source_field->setMesh(source_mesh_mc); source_mesh_mc->decrRef(); - DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(source_mesh_mc->getNumberOfCells(),1); - source_field->setArray(arr); arr->decrRef(); - double *value=arr->getPointer(); - for(int i=0; igetNumberOfCells(); i++) - value[i]=1.0; - MEDCouplingUMesh *target_mesh_mc=target_mesh->getMeshAtLevel(0); - MEDCouplingFieldDouble *target_field=MEDCouplingFieldDouble::New(ON_CELLS); - target_field->setMesh(target_mesh_mc); target_mesh_mc->decrRef(); - arr=DataArrayDouble::New(); arr->alloc(target_mesh_mc->getNumberOfCells(),1); - target_field->setArray(arr); arr->decrRef(); - double* targetvalue=arr->getPointer(); - for(int i=0; igetNumberOfCells(); i++) - targetvalue[i]=0.0; - // Ok at this point we have our mesh in MED-Memory format. - // Go to wrap med_source_mesh and med_target_mesh. - MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_source_mesh(source_mesh_mc); - MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_target_mesh(target_mesh_mc); - // Go for interpolation... - INTERP_KERNEL::Interpolation2D myInterpolator; - //optionnal call to parametrize your interpolation. First precision, tracelevel, intersector wanted. - myInterpolator.setPrecision(1e-7); - myInterpolator.setPrintLevel(1); - source_mesh->decrRef(); - source_field->decrRef(); - target_field->decrRef(); - target_mesh->decrRef(); - } -} diff --git a/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx b/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx deleted file mode 100644 index d97856a59..000000000 --- a/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_INTERPOLATIONOPTIONS_HXX__ -#define __TU_INTERPOLATIONOPTIONS_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_TEST -{ - - /** - * \brief Test suite testing some of the low level methods of TransformedTriangle. - * - */ - class INTERPKERNELTEST_EXPORT InterpolationOptionsTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( InterpolationOptionsTest ); - CPPUNIT_TEST( test_InterpolationOptions ); - CPPUNIT_TEST_SUITE_END(); - - - public: - void setUp(); - - void tearDown(); - - // tests - void test_InterpolationOptions(); - - private: - - }; - - - - -} - - - -#endif diff --git a/medtool/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx b/medtool/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx deleted file mode 100644 index 6d9c84f9e..000000000 --- a/medtool/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ -#define __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ - -#include -#include -#include -#include - -namespace INTERP_TEST -{ - - /** - * \brief Base class for planar mesh intersection test suites. - * - */ - class InterpolationPlanarTestSuite : public CppUnit::TestFixture - { - - public: - double _Epsilon; - double _Precision; - - /** - * Sets up the test suite. - * - */ - void setUp() - { - _Epsilon = 1.e-6; - _Precision = 1.e-6; - } - void tearDown() {} - - // bool checkDequesEqual(std::deque< double > deque1, std::deque< double > deque2, double epsilon); - // bool checkVectorsEqual(std::vector< double > Vect1, std::vector< double > Vect2, double epsilon); - // void dequePrintOut(std::deque< double > deque1); - // void vectPrintOut(std::vector< double > vect); - // void tabPrintOut( const double * tab, int size); - - bool checkDequesEqual(std::deque< double > deque1, - std::deque< double > deque2, double epsilon) - { - int size1 = deque1.size(); - int size2 = deque2.size(); - bool are_equal = size1 == size2; - - if(are_equal) - for(int i = 0; i < size1 && are_equal; i++) - are_equal = fabs(deque1[i] - deque2[i]) < epsilon; - - return are_equal; - } - bool checkVectorsEqual(std::vector< double > vect1, - std::vector< double > vect2, double epsilon) - { - int size1 = vect1.size(); - int size2 = vect2.size(); - bool are_equal = size1 == size2; - - if(are_equal) - for(int i = 0; i < size1 && are_equal; i++) - are_equal = fabs(vect1[i] - vect2[i]) < epsilon; - - return are_equal; - } - void dequePrintOut(std::deque< double > deque1) - { - for(int i = 0; i< (int)deque1.size(); i++) - { - std::cerr << deque1[i] << " "; - } - std::cerr<< std::endl; - } - void vectPrintOut(std::vector< double > vect) - { - for(int i = 0; i< (int)vect.size(); i++) - { - std::cerr << vect[i] << " "; - } - std::cerr<< std::endl; - } - void tabPrintOut( const double * tab,int size) - { - for(int i = 0; i< size; i++) - { - std::cerr << tab[i] << " "; - } - std::cerr<< std::endl; - } - - /** - * Cleans up after the test suite. - * Liberates the MeshTestToolkit object used by the tests. - */ - // void tearDown() - // { - // delete _testTools; - // } - - - - // protected: - // /// MeshTestToolkit object to which the tests are delegated - // MeshTestToolkit* _testTools; - - }; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/InterpolationTestSuite.hxx b/medtool/src/INTERP_KERNELTest/InterpolationTestSuite.hxx deleted file mode 100644 index 9c4ec7a7b..000000000 --- a/medtool/src/INTERP_KERNELTest/InterpolationTestSuite.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_INTERPOLATION_TEST_SUITE_HXX__ -#define __TU_INTERPOLATION_TEST_SUITE_HXX__ - -#include "MeshTestToolkit.txx" - -#include - -namespace INTERP_TEST -{ - - /** - * \brief Base class for mesh intersection test suites. - * - */ - template - class InterpolationTestSuite : public CppUnit::TestFixture - { - - public: - /** - * Sets up the test suite. - * Creates the MeshTestToolkit object used by the tests. - * - */ - void setUp() - { - _testTools = new MeshTestToolkit(); - } - - /** - * Cleans up after the test suite. - * Liberates the MeshTestToolkit object used by the tests. - */ - void tearDown() - { - delete _testTools; - } - - - - protected: - /// MeshTestToolkit object to which the tests are delegated - MeshTestToolkit* _testTools; - - }; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/MEDMeshMaker.cxx b/medtool/src/INTERP_KERNELTest/MEDMeshMaker.cxx deleted file mode 100644 index f0538b113..000000000 --- a/medtool/src/INTERP_KERNELTest/MEDMeshMaker.cxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingCMesh.hxx" - -#include "MEDMeshMaker.hxx" - -using namespace ParaMEDMEM; - -ParaMEDMEM::MEDCouplingUMesh *MEDMeshMaker(int dim, int nbedge) -{ - MEDCouplingAutoRefCountObjectPtr c=MEDCouplingCMesh::New(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbedge+1,1); arr->iota(0.); arr->applyLin(1./double(nbedge),0.); - switch(dim) - { - case 2: - { - c->setCoords(arr,arr); - break; - } - case 3: - { - c->setCoords(arr,arr,arr); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDMeshMaker : only dim 2 or 3 supported !"); - } - return c->buildUnstructured(); -} diff --git a/medtool/src/INTERP_KERNELTest/MEDMeshMaker.hxx b/medtool/src/INTERP_KERNELTest/MEDMeshMaker.hxx deleted file mode 100644 index 44bcdf19b..000000000 --- a/medtool/src/INTERP_KERNELTest/MEDMeshMaker.hxx +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDCouplingUMesh.hxx" - -ParaMEDMEM::MEDCouplingUMesh *MEDMeshMaker(int dim, int nbedge); diff --git a/medtool/src/INTERP_KERNELTest/MeshTestToolkit.hxx b/medtool/src/INTERP_KERNELTest/MeshTestToolkit.hxx deleted file mode 100644 index 0144c9d0f..000000000 --- a/medtool/src/INTERP_KERNELTest/MeshTestToolkit.hxx +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_MESH_TEST_TOOLKIT_HXX__ -#define __TU_MESH_TEST_TOOLKIT_HXX__ - -#include "Interpolation3D.hxx" -#include "Interpolation3D.txx" -#include "InterpolationPlanar.hxx" - -#include -#include - -#define ERR_TOL 1.0e-8 - -typedef std::vector > IntersectionMatrix; - -namespace INTERP_KERNEL -{ - class Interpolation3D; -} - - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; -} - -namespace INTERP_TEST -{ - /** - * \brief Class providing services for mesh intersection tests. - * - */ - template - class MeshTestToolkit - { - - public: - double _precision; - INTERP_KERNEL::IntersectionType _intersectionType;//Used only in the case MESHDIM==2 (planar intersections) - - MeshTestToolkit():_precision(1.e-6),_intersectionType(INTERP_KERNEL::Triangulation) {} - - ~MeshTestToolkit() {} - - void intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; - - // 1.0e-5 here is due to limited precision of "correct" volumes calculated in Salome - void intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; - - void dumpIntersectionMatrix(const IntersectionMatrix& m) const; - - double sumRow(const IntersectionMatrix& m, int i) const; - - double sumCol(const IntersectionMatrix& m, int i) const; - - void getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double* tab) const; - - bool testVolumes(const IntersectionMatrix& m, ParaMEDMEM::MEDCouplingUMesh& sMesh, ParaMEDMEM::MEDCouplingUMesh& tMesh) const; - - double sumVolume(const IntersectionMatrix& m) const; - - bool areCompatitable( const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; - - bool testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; - - bool testDiagonal(const IntersectionMatrix& m) const; - - void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const; - - }; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/MeshTestToolkit.txx b/medtool/src/INTERP_KERNELTest/MeshTestToolkit.txx deleted file mode 100644 index 2c80463b8..000000000 --- a/medtool/src/INTERP_KERNELTest/MeshTestToolkit.txx +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#include "TestInterpKernelUtils.hxx" - -#include "MeshTestToolkit.hxx" - -#include "MEDFileMesh.hxx" - -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingFieldDouble.hxx" - -#include "Interpolation3DSurf.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3D.txx" - -#include -#include -#include -#include -#include -#include - - -// levels : -// 1 - titles and volume results -// 2 - symmetry / diagonal results and intersection matrix output -// 3 - empty -// 4 - empty -// 5 - misc -#include "Log.hxx" - -#include - -//#define VOL_PREC 1.0e-6 -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - /** - * Calculates the sum of a row of an intersection matrix - * - * @param m an intersection matrix - * @param i the index of the row (1 <= i <= no. rows) - * @return the sum of the values of row i - * - */ - template - double MeshTestToolkit::sumRow(const IntersectionMatrix& m, int i) const - { - double vol = 0.0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - if(iter->count(i) != 0.0) - { - std::map::const_iterator iter2 = iter->find(i); - vol += fabs(iter2->second); - } - } - return vol; - } - - /** - * Calculates the sum of a column of an intersection matrix - * - * @param m an intersection matrix - * @param i the index of the column (0 <= i <= no. rows - 1) - * @return the sum of the values of column i - * - */ - template - double MeshTestToolkit::sumCol(const IntersectionMatrix& m, int i) const - { - double vol = 0.0; - const std::map& col = m[i]; - for(std::map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) - { - vol += fabs(iter->second); - } - return vol; - } - - /** - * Gets the volumes of the elements in a mesh. - * - * @param mesh the mesh - * @param tab pointer to double[no. elements of mesh] array in which to store the volumes - */ - template - void MeshTestToolkit::getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double *tab) const - { - MEDCouplingAutoRefCountObjectPtr vol=mesh.getMeasureField(true); - std::copy(vol->getArray()->begin(),vol->getArray()->end(),tab); - } - - /** - * Sums all the elements (volumes) of an intersection matrix - * - * @param m the intersection matrix - * @return the sum of the elements of m - */ - - template - double MeshTestToolkit::sumVolume(const IntersectionMatrix& m) const - { - std::vector volumes; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - volumes.push_back(fabs(iter2->second)); - } - } - - // sum in ascending order to avoid rounding errors - - sort(volumes.begin(), volumes.end()); - const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); - - return vol; - } - - /** - * Verifies if for a given intersection matrix the sum of each row is equal to the volumes - * of the corresponding source elements and the sum of each column is equal to the volumes - * of the corresponding target elements. This will be true as long as the meshes correspond - * to the same geometry. The equalities are in the "epsilon-sense", making sure the relative - * error is small enough. - * - * @param m the intersection matrix - * @param sMesh the source mesh - * @param tMesh the target mesh - * @return true if the condition is verified, false if not. - */ - template - bool MeshTestToolkit::testVolumes(const IntersectionMatrix& m, ParaMEDMEM::MEDCouplingUMesh& sMesh, ParaMEDMEM::MEDCouplingUMesh& tMesh) const - { - bool ok = true; - - // source elements - double* sVol = new double[sMesh.getNumberOfCells()]; - getVolumes(sMesh, sVol); - - for(int i = 0; i < sMesh.getNumberOfCells(); ++i) - { - const double sum_row = sumRow(m, i); - if(!epsilonEqualRelative(sum_row, fabs(sVol[i]), _precision)) - { - LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); - ok = false; - } - LOG(1, "diff = " < - bool MeshTestToolkit::testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const - { - int i = 0; - bool isSymmetric = true; - - LOG(1, "Checking symmetry src - target" ); - isSymmetric = isSymmetric & areCompatitable(m1, m2) ; - LOG(1, "Checking symmetry target - src" ); - isSymmetric = isSymmetric & areCompatitable(m2, m1); - - for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double v1 = fabs(iter2->second); - //if(m2[j - 1].count(i+1) > 0) - // { - std::map theMap = m2.at(j); - const double v2 = fabs(theMap[i]); - if(v1 != v2) - { - LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j << ", " << i << ") = " << v2 << " | diff = " << v1 - v2 ); - if(!epsilonEqualRelative(v1, v2, _precision)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isSymmetric = false; - } - } - } - ++i; - } - if(!isSymmetric) - { - LOG(1, "*** matrices are not symmetric"); - } - return isSymmetric; - } - - /** - * Tests if an intersection matrix is diagonal. - * - * @param m the intersection matrix - * @return true if m is diagonal; false if not - * - */ - template - bool MeshTestToolkit::testDiagonal(const IntersectionMatrix& m) const - { - LOG(1, "Checking if matrix is diagonal" ); - int i = 0; - bool isDiagonal = true; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double vol = iter2->second; - if(vol != 0.0 && (i != j)) - { - LOG(2, "V( " << i << ", " << j << ") = " << vol << " which is not zero" ); - if(!epsilonEqual(vol, 0.0, _precision)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isDiagonal = false; - } - } - } - ++i; - } - if(!isDiagonal) - { - LOG(1, "*** matrix is not diagonal"); - } - return isDiagonal; - } - - /** - * Outputs the intersection matrix as a list of all its elements to std::cout. - * - * @param m the intersection matrix to output - */ - template - void MeshTestToolkit::dumpIntersectionMatrix(const IntersectionMatrix& m) const - { - int i = 0; - std::cout << "Intersection matrix is " << std::endl; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << std::endl; - } - ++i; - } - std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; - } - - /** - * Calculates the intersection matrix for two meshes. - * If the source and target meshes are the same, a CppUnit assertion raised if testVolumes() returns false. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * @param mesh2 the name of the target mesh - * @param m intersection matrix in which to store the result of the intersection - */ - template - void MeshTestToolkit::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const - { - LOG(1, std::endl << "=== -> intersecting src = " << mesh1path << ", target = " << mesh2path ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MEDCouplingAutoRefCountObjectPtr sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1); - MEDCouplingAutoRefCountObjectPtr sMesh=sMeshML->getMeshAtLevel(0); - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MEDCouplingAutoRefCountObjectPtr tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2); - MEDCouplingAutoRefCountObjectPtr tMesh=tMeshML->getMeshAtLevel(0); - - MEDCouplingNormalizedUnstructuredMesh sMesh_wrapper(sMesh); - MEDCouplingNormalizedUnstructuredMesh tMesh_wrapper(tMesh); - - if (SPACEDIM==2 && MESHDIM==2) - { - Interpolation2D interpolator; - interpolator.setOptions(_precision, LOG_LEVEL, _intersectionType,1); - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - } - else if (SPACEDIM==3 && MESHDIM==2) - { - Interpolation3DSurf interpolator; - interpolator.setOptions(_precision,LOG_LEVEL, 0.5,_intersectionType,false,1); - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - } - else if (SPACEDIM==3 && MESHDIM==3) - { - Interpolation3D interpolator; - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - } - else - { - throw INTERP_KERNEL::Exception("Wrong dimensions"); - } - // if reflexive, check volumes - if(strcmp(mesh1path,mesh2path) == 0) - { - const bool row_and_col_sums_ok = testVolumes(m, *sMesh, *tMesh); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); - const bool is_diagonal =testDiagonal(m); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Self intersection matrix is not diagonal", true, is_diagonal); - } - - LOG(1, "Intersection calculation done. " << std::endl ); - } - - /** - * Tests the intersection algorithm for two meshes. - * Depending on the nature of the meshes, different tests will be performed. The sum of the elements will - * be compared to the given total volume of the intersection in all cases. If the two meshes are the same, then - * it will be confirmed that the intersection matrix is diagonal, otherwise the intersection matrices will be - * calculated once which each mesh as source mesh, and it will be verified that the they are each others' transpose. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * @param mesh2 the name of the target mesh - * @param correctVol the total volume of the intersection of the two meshes - * @param prec maximum relative error to be tolerated in volume comparisions - * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed - * - */ - template - void MeshTestToolkit::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const - { - LOG(1, std::endl << std::endl << "=============================" ); - - using std::string; - const string path1 = string(mesh1path) + string(mesh1); - const string path2 = string(mesh2path) + string(mesh2); - - const bool isTestReflexive = (path1.compare(path2) == 0); - - IntersectionMatrix matrix1; - calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix1); -#endif - - std::cout.precision(16); - - const double vol1 = sumVolume(matrix1); - - if(!doubleTest) - { - LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); - - if(isTestReflexive) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); - } - } - else - { - IntersectionMatrix matrix2; - calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix2); -#endif - - const double vol2 = sumVolume(matrix2); - - LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testTranspose(matrix1, matrix2)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); - } - } - - /** - * Utility method used to facilitate the call to intersect meshes. - * It calls intersectMeshes, using "mesh1.med" as file name for the mesh with name "mesh1" and - * "mesh2.med" as file name for the mesh with name "mesh2". The rest of the arguments are passed - * along as they are. - * - * @param mesh1 the name of the source mesh - * @param mesh2 the name of the target mesh - * @param correctVol the total volume of the intersection of the two meshes - * @param prec maximum relative error to be tolerated in volume comparisions - * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed - * - */ - template - void MeshTestToolkit::intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const - { - const std::string path1 = std::string(mesh1) + std::string(".med"); - std::cout << "here :" << path1 << std::endl; - const std::string path2 = std::string(mesh2) + std::string(".med"); - - intersectMeshes(path1.c_str(), mesh1, path2.c_str(), mesh2, correctVol, prec, doubleTest); - } -} diff --git a/medtool/src/INTERP_KERNELTest/MultiElement2DTests.hxx b/medtool/src/INTERP_KERNELTest/MultiElement2DTests.hxx deleted file mode 100644 index 12d3036ef..000000000 --- a/medtool/src/INTERP_KERNELTest/MultiElement2DTests.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MULTI_ELEMENT_2D_TESTS_HXX_ -#define __MULTI_ELEMENT_2D_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting meshes of several - * polygonal elements - up to a few thousand. This serves to check the - * filtering methods and the matrix assemblage, as well as verifying - * that computation errors do not become unmanageable. It uses mehes of - * different geometries : triangle, quadrilateral. - * - */ - class MultiElement2DTests : public InterpolationTestSuite<2,2> - { - CPPUNIT_TEST_SUITE( MultiElement2DTests ); - - CPPUNIT_TEST(SymetryTranspose2DTest); - CPPUNIT_TEST(SelfIntersection2DTest); - - CPPUNIT_TEST_SUITE_END(); - - public: - void SymetryTranspose2DTest() - { - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - _testTools->_intersectionType=INTERP_KERNEL::Convex; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - } - void SelfIntersection2DTest() - { - IntersectionMatrix m; - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - //_testTools->_intersectionType=INTERP_KERNEL::Convex;// valgrind complains ! - //_testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx b/medtool/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx deleted file mode 100644 index 6308c046c..000000000 --- a/medtool/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MULTI_ELEMENT_3DSurf_TESTS_HXX_ -#define __MULTI_ELEMENT_3DSurf_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting meshes of several - * polygonal elements - up to a few thousand. This serves to check the - * filtering methods and the matrix assemblage, as well as verifying - * that computation errors do not become unmanageable. It uses mehes of - * different geometries : triangle, quadrilateral. - * - */ - class MultiElement2DTests : public InterpolationTestSuite<3,2> - { - CPPUNIT_TEST_SUITE( MultiElement3DSurfTests ); - - CPPUNIT_TEST(SymetryTranspose3DSurfTest); - CPPUNIT_TEST(SelfIntersection3DSurfTest); - - CPPUNIT_TEST_SUITE_END(); - - public: - void SymetryTranspose3DSurfTest() - { - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - _testTools->_intersectionType=INTERP_KERNEL::Convex; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - } - void SelfIntersection3DSurfTest() - { - IntersectionMatrix m; - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - _testTools->_intersectionType=INTERP_KERNEL::Convex; - _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - } - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/MultiElementTetraTests.hxx b/medtool/src/INTERP_KERNELTest/MultiElementTetraTests.hxx deleted file mode 100644 index d901eb332..000000000 --- a/medtool/src/INTERP_KERNELTest/MultiElementTetraTests.hxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MULTI_ELEMENT_TETRA_TESTS_HXX_ -#define __MULTI_ELEMENT_TETRA_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting meshes of several - * elements (all tetrahedra) - up to a few thousand. This serves to check the - * filtering methods and the matrix assemblage, as well as verifying - * that computation errors do not become unmanageable. It uses mehes of - * different geometries : tetrahedra, boxes and cylinders. - * - */ - class MultiElementTetraTests : public InterpolationTestSuite<3,3> - { - CPPUNIT_TEST_SUITE( MultiElementTetraTests ); - - CPPUNIT_TEST( tetraComplexIncluded ); - CPPUNIT_TEST( dividedUnitTetraSimplerReflexive ); - CPPUNIT_TEST( dividedUnitTetraReflexive ); - CPPUNIT_TEST( nudgedDividedUnitTetraSimpler ); - CPPUNIT_TEST( nudgedDividedUnitTetra ); - CPPUNIT_TEST( dividedGenTetra ); - CPPUNIT_TEST( tinyBoxReflexive ); - CPPUNIT_TEST( moderateBoxEvenSmallerReflexive ); - CPPUNIT_TEST( moderateBoxSmallReflexive ); - CPPUNIT_TEST( boxReflexive ); - CPPUNIT_TEST( boxReflexiveModerate ); - CPPUNIT_TEST( tetraBoxes ); - CPPUNIT_TEST( moderateBoxesSmaller ); - CPPUNIT_TEST( moderateBoxes ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - /// Tetrahedron situated totally inside another - /// \brief Status : pass - void tetraComplexIncluded() - { - _testTools->intersectMeshes("ComplexIncludedTetra", "ComplexIncludingTetra", 17.0156); - } - - /// Unit tetrahedron divided in 4 elements intersecting itself. - /// \brief Status : pass - void dividedUnitTetraSimplerReflexive() - { - _testTools->intersectMeshes("DividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.1666667); - } - - /// Unit tetrahedron divided in 14 elements intersecting itself. - /// \brief Status : pass - void dividedUnitTetraReflexive() - { - _testTools->intersectMeshes("DividedUnitTetra", "DividedUnitTetra", 0.1666667); - } - - /// Unit tetrahedron divided in 4 elements intersecting slightly displaced version of itself. - /// \brief Status : pass - void nudgedDividedUnitTetraSimpler() - { - _testTools->intersectMeshes("NudgedDividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.150191); - } - - /// Unit tetrahedron divided in 14 elements intersecting slightly displaced version of itself. - /// \brief Status : pass - void nudgedDividedUnitTetra() - { - _testTools->intersectMeshes("NudgedDividedUnitTetra", "DividedUnitTetra", 0.150191); - } - - /// Two intersecting tetrahedra in general position, one with 23 elements, the other with 643 elements - /// \brief Status : pass - void dividedGenTetra() - { - _testTools->intersectMeshes("DividedGenTetra1", "DividedGenTetra2", 0.546329); - } - - /// Large box in general position with 12 elements intersecting itself - /// \brief Status : pass - void tinyBoxReflexive() - { - _testTools->intersectMeshes("TinyBox", "TinyBox", 979200); - } - - /// Small box in general position with 33 elements intersecting itself - /// \brief Status : pass - void boxReflexive() - { - _testTools->intersectMeshes("Box3", "Box3", 13.9954); - } - - /// Box in general position with 67 elements intersecting itself - /// \brief Status : pass - void moderateBoxEvenSmallerReflexive() - { - _testTools->intersectMeshes("BoxEvenSmaller1", "BoxEvenSmaller1", 1.44018e6); - } - - /// Box in general position with 544 elements intersecting itself - /// \brief Status : pass - void moderateBoxSmallReflexive() - { - _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall1", 1.44018e6); - } - - /// Large box in general position with 2943 elements intersecting itself - /// \brief Status : pass - void boxReflexiveModerate() - { - _testTools->intersectMeshes("Box1Moderate", "Box1Moderate", 1.0e6); - } - - /// Two intersecting boxes in general position with 12 and 18 elements - /// \brief Status : pass - void tetraBoxes() - { - _testTools->intersectMeshes("Box1", "Box2", 124.197); - } - - /// Two intersecting boxes in general position with 430 and 544 elements - /// \brief Status : pass - void moderateBoxesSmaller() - { - _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall2", 321853); - } - - /// Two intersecting boxes in general position with 2943 and 3068 elements - /// \brief Status : pass - void moderateBoxes() - { - _testTools->intersectMeshes("Box1Moderate", "Box2Moderate", 376856); - } - - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/PerfTest.cxx b/medtool/src/INTERP_KERNELTest/PerfTest.cxx deleted file mode 100644 index be60bcb0d..000000000 --- a/medtool/src/INTERP_KERNELTest/PerfTest.cxx +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Interpolation3D.hxx" -#include "Interpolation3D.txx" -#include "MeshTestToolkit.txx" -#include "Log.hxx" -#include "VectorUtils.hxx" -#include "TestInterpKernelUtils.hxx" - -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" - -#include -#include - -/** - * \file PerfTest.cxx - * Test program which takes two meshes and calculates their intersection matrix. - * - * USAGE : PerfTest mesh1 mesh2 - * where mesh1 and mesh2 are the names of two meshes located in - * the files mesh1.med, mesh2.med in {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * - */ - -namespace INTERP_TEST -{ - /** - * \brief Specialization of MeshTestToolkit for the purposes of performance testing. - * - */ - class PerfTestToolkit : public MeshTestToolkit<3,3> - { - - public: - - /** - * Calculates the intersection matrix for two meshes. - * Outputs the names of the meshes intersected, the number of elements in each mesh, - * the number of matrix elements and the number of non-zero matrix elements, etc. - * These values help to determine how well the filtering algorithm is working. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/ - * @param mesh2 the name of the target mesh - * @param m intersection matrix in which to store the result of the intersection - */ - void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) - { - LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MEDCouplingAutoRefCountObjectPtr sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1); - MEDCouplingAutoRefCountObjectPtr sMesh=sMeshML->getMeshAtLevel(0); - - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MEDCouplingAutoRefCountObjectPtr tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2); - MEDCouplingAutoRefCountObjectPtr tMesh=tMeshML->getMeshAtLevel(0); - - MEDCouplingNormalizedUnstructuredMesh<3,3> sMesh_wrapper(sMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> tMesh_wrapper(tMesh); - - Interpolation3D interpolator; - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - - std::pair eff = countNumberOfMatrixEntries(m); - LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = " - << double(eff.first) / double(numTargetElems * numSrcElems)); - LOG(1, eff.second << " non-zero elements of " << eff.first << " total : filter efficiency = " - << double(eff.second) / double(eff.first)); - - LOG(1, "Intersection calculation done. " << std::endl ); - - } - - /** - * Counts the number of elements in an intersection matrix, and the number of these which are non-zero. - * - * @param m the intersection matrix - * @return pair containing as its first element the number of elements in m and as its second element the - * number these which are non-zero - */ - std::pair countNumberOfMatrixEntries(const IntersectionMatrix& m) - { - - int numElems = 0; - int numNonZero = 0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - numElems += iter->size(); - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - if(!INTERP_KERNEL::epsilonEqual(iter2->second, 0.0, VOL_PREC)) - { - ++numNonZero; - } - } - } - return std::make_pair(numElems, numNonZero); - } - - }; -} - -/** - * Main method of the program. - * Intersects the meshes and outputs some information about the calculation as well as the - * intersection matrix on std::cout. - * - * @param argc number of arguments given to the program (should be 3, the user giving 2 mesh names) - * @param argv vector to the arguments as strings. - */ -int main(int argc, char** argv) -{ - using INTERP_TEST::PerfTestToolkit; - - assert(argc == 3); - - // load meshes - const std::string mesh1 = argv[1]; - const std::string mesh2 = argv[2]; - - const std::string mesh1path = mesh1 + ".med"; - const std::string mesh2path = mesh2 + ".med"; - - IntersectionMatrix m; - - PerfTestToolkit testTools; - - testTools.calcIntersectionMatrix(mesh1path.c_str(), mesh1.c_str(), mesh2path.c_str(), mesh2.c_str(), m); - - testTools.dumpIntersectionMatrix(m); - - return 0; - -} - diff --git a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx b/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx deleted file mode 100644 index 3a1f8a46a..000000000 --- a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx +++ /dev/null @@ -1,1023 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "TestInterpKernelUtils.hxx" - -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -static const double ADMISSIBLE_ERROR = 1.e-14; - -void QuadraticPlanarInterpTest::setUp() -{ -} - -void QuadraticPlanarInterpTest::tearDown() -{ -} - -void QuadraticPlanarInterpTest::cleanUp() -{ -} - -void QuadraticPlanarInterpTest::ReadWriteInXfigElementary() -{ - //Testing bounds calculation. For Seg2 - std::istringstream stream("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4700"); - EdgeLin *e1=new EdgeLin(stream); - Bounds bound=e1->getBounds(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); - e1->decrRef(); - std::istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4500 4700 3200 3400"); - e1=new EdgeLin(stream2); - bound=e1->getBounds(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); - e1->decrRef(); - //Testing bounds calculation For Arc of circle. - -} - -void QuadraticPlanarInterpTest::ReadWriteInXfigGlobal() -{ - QuadraticPolygon pol1(INTERP_TEST::getResourceFile("Pol1.fig").c_str()); - pol1.dumpInXfigFile("Pol1_gen.fig"); - QuadraticPolygon pol2(INTERP_TEST::getResourceFile("Pol2.fig").c_str()); - pol2.dumpInXfigFile("Pol2_gen.fig"); - QuadraticPolygon pol3(INTERP_TEST::getResourceFile("Pol3.fig").c_str()); - pol3.dumpInXfigFile("Pol3_gen.fig"); - QuadraticPolygon pol4(INTERP_TEST::getResourceFile("Pol4.fig").c_str()); - CPPUNIT_ASSERT_EQUAL(1,pol4.size()); - ElementaryEdge *edge1=dynamic_cast(pol4[0]); - CPPUNIT_ASSERT(edge1); - Edge *edge2=edge1->getPtr(); - EdgeArcCircle *edge=dynamic_cast(edge2); - CPPUNIT_ASSERT(edge); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); - double center[2]; - edge->getCenter(center); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,center[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48375,center[1],ADMISSIBLE_ERROR); - const double *start=*edge->getStartNode(); - Node *n1=new Node(start[0]+2*(center[0]-start[0]),start[1]+2*(center[1]-start[1])); - edge->changeMiddle(n1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); - n1->decrRef(); - n1=new Node(center[0],center[1]+0.24375); - edge->changeMiddle(n1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49741997818704586,edge->getAngle(),ADMISSIBLE_ERROR);//5.7857653289925404 + 2*PI - n1->decrRef(); - //A half circle. - EdgeArcCircle *e=new EdgeArcCircle(0.84,0.54,0.78,0.6,0.84,0.66); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.1415925921507317,e->getAngle(),1e-5); - e->decrRef(); - e=new EdgeArcCircle(0.84,0.54,0.9,0.6,0.84,0.66); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415925921507317,e->getAngle(),1e-5); - e->decrRef(); -} - -void QuadraticPlanarInterpTest::BasicGeometricTools() -{ - Node *n1=new Node(1.,1.); - Node *n2=new Node(4.,2.); - EdgeLin *e1=new EdgeLin(n1,n2); - double tmp[2]; - e1->getNormalVector(tmp); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.94868329805051377,tmp[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.31622776601683794,tmp[0],ADMISSIBLE_ERROR); - e1->decrRef(); - n1->decrRef(); n2->decrRef(); - n1=new Node(1.,1.); - n2=new Node(0.,4.); - e1=new EdgeLin(n1,n2); - double tmp2[2]; - e1->getNormalVector(tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,Node::dot(tmp,tmp2),1e-10); - tmp[0]=0.5; tmp[1]=2.5; - CPPUNIT_ASSERT(e1->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e1->getDistanceToPoint(tmp),1e-12); - tmp[1]=2.55; CPPUNIT_ASSERT(!e1->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0158113883008418,e1->getDistanceToPoint(tmp),1e-12); - tmp[0]=0.; tmp[1]=5.; - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,e1->getDistanceToPoint(tmp),1e-12); - EdgeArcCircle *e=new EdgeArcCircle(4.,3.,0.,5.,-5.,0.); - tmp[0]=-4.; tmp[1]=3.; - CPPUNIT_ASSERT(e->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e->getDistanceToPoint(tmp),1e-12); - tmp[1]=3.1; CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.0632371551998077e-2,e->getDistanceToPoint(tmp),1e-12); - tmp[0]=-4.; tmp[1]=-3.; - CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1622776601683795,e->getDistanceToPoint(tmp),1e-12); - e->decrRef(); - e1->decrRef(); - n1->decrRef(); n2->decrRef(); -} - -void QuadraticPlanarInterpTest::IntersectionBasics() -{ - //Testing intersection of Bounds. - std::istringstream stream1("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); - EdgeLin *e1=new EdgeLin(stream1); - std::istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); - EdgeLin *e2=new EdgeLin(stream2); - Bounds *bound=e1->getBounds().amIIntersectingWith(e2->getBounds()); CPPUNIT_ASSERT(bound); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,(*bound)[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,(*bound)[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,(*bound)[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[3],ADMISSIBLE_ERROR); - delete bound; - e2->decrRef(); e1->decrRef(); - // - std::istringstream stream3("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3000 7200 6000 3700"); - EdgeLin *e3=new EdgeLin(stream3); - std::istringstream stream4("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4800 6600 7200 4200"); - EdgeLin *e4=new EdgeLin(stream4); - bound=e3->getBounds().amIIntersectingWith(e4->getBounds()); CPPUNIT_ASSERT(bound); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6,(*bound)[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.42,(*bound)[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.66,(*bound)[3],ADMISSIBLE_ERROR); - delete bound; - e3->decrRef(); e4->decrRef(); -} - -void QuadraticPlanarInterpTest::EdgeLinUnitary() -{ - EdgeLin *e1=new EdgeLin(0.5,0.5,3.7,4.1); - Node *n=new Node(2.1,2.3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.5,1e-8); - n->decrRef(); - n=new Node(3.7,4.1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.,1e-8); - n->decrRef(); - n=new Node(0.5,0.5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.,1e-8); - n->decrRef(); - n=new Node(-1.1,-1.3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),-0.5,1e-8); - n->decrRef(); - n=new Node(5.3,5.9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.5,1e-8); - n->decrRef(); e1->decrRef(); -} - -/*! - * Here two things are tested. - * 1 ) One the overlapping calculation capability of edge/edge intersector. - * 2 ) Then the capability to handle the case where 2 segs (whatever their type) are overlapped. - * All the configuration of full or part overlapping have been tested. - */ -void QuadraticPlanarInterpTest::IntersectionEdgeOverlapUnitarySegSeg() -{ - ComposedEdge& v1=*(new ComposedEdge); - ComposedEdge& v2=*(new ComposedEdge); - MergePoints v3; - //Testing merge of geometric equals seg2. - Edge *e1=new EdgeLin(0.5,0.5,1.,1.); Edge *e2=new EdgeLin(0.5,0.5,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - v1.clear(); v2.clear(); v3.clear(); - // - testing by adding some noise - e1->decrRef(); e1=new EdgeLin(0.5+5.e-15,0.5-5.e-15,1.,1.+7.e-15); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Testing merge of geometric equals seg2 but now with opposite direction - e1=new EdgeLin(0.5,0.5,0.7,0.7); e2=new EdgeLin(0.7+6.e-15,0.7-2.e-15,0.5+3.e-15,0.5-4.e-15); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection());//compared 8 lines above !v2[0]->getDirection() - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 0 - //Test 1 - OUT_AFTER - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,2.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.5,0.,1.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.5,0.,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,1.5,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | opp. dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,0.5,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(!v1[1]->intresicEqualDirSensitive(v2[1]) && v1[1]->intresicEqual(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.25,0.,0.75,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.25,0.,0.75); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.25,0.25,0.75,0.75); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.75,0.75,0.25,0.25); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | opp dir. - double center[2]={0.,0.}; - double radius=1.; - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(!v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(!v2[2]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | same dir. - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | opp dir. | e1<->e2 to test symetry - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(!v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(!v1[2]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | same dir. | e1<->e2 to test symetry - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 4 - OUT_BEFORE - OUT_BEFORE | same dir. - 0 ° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-1.,0.,-0.5,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0,-0.5,0.,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,0.5,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,-0.5,-0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(!v1[0]->intresicEqualDirSensitive(v2[0]) && v1[0]->intresicEqual(v2[0]) ); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.5,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,-0.5,-0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 7 - END - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.5,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 7 - END - OUT_AFTER | opp dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,1.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | same dir. - 0° - e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,0.7,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,0.7); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | same dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,0.7,0.7); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | opp. dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.7,0.7,0.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 9 - OUT_BEFORE - START | same dir. - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - CPPUNIT_ASSERT(e2->getEndNode()==e1->getStartNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | same dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | opp dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(1.,1.,0.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.7,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.7,0.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.7,0.7,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,0.7,0.7); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,-0.5,-0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,0.,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,0.5,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,0.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && !v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getEndNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 14 - INSIDE - START | same dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,M_PI/3.,-M_PI); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqual(v2[0])); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 14 - INSIDE - START | opp dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-M_PI,M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(v2[1]->getPtr()) && !v2[1]->getDirection() && v1[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 15 - END - INSIDE | same dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,0.,-4.*M_PI/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqual(v2[1])); - CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 15 - END - INSIDE | opp dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-4.*M_PI/3,0.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr()) && !v2[0]->getDirection() && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - // - ComposedEdge::Delete(&v1); - ComposedEdge::Delete(&v2); -} - -/*! - * Here there is test of cases where between 2 edges intersects only in points not on edge. - */ -void QuadraticPlanarInterpTest::IntersectionPointOnlyUnitarySegSeg() -{ - // 0° - classical - EdgeLin *e1=new EdgeLin(0.,0.,1.,0.); - EdgeLin *e2=new EdgeLin(0.3,0.3,0.5,-0.3); - ComposedEdge& v1=*(new ComposedEdge); - ComposedEdge& v2=*(new ComposedEdge); MergePoints v3; - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - // 90° - classical - e1=new EdgeLin(0.,0.,0.,1.); - e2=new EdgeLin(-0.3,0.3,0.3,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 1 - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.,1.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 1 - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 1 - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,1.,-1.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,1.,1.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.,1.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 4 - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,-1.,0.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 2 End. - e1=new EdgeLin(0.,0.,1.,0.); - e2=new EdgeLin(0.5,1.,0.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getEndNode() && v1[1]->getStartNode()==e2->getEndNode() && v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 2 Start. - e1=new EdgeLin(0.,0.,1.,0.); - e2=new EdgeLin(0.5,0.,0.5,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getStartNode() && v1[1]->getStartNode()==e2->getStartNode() && v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 1 Start. - e1=new EdgeLin(0.5,0.,0.5,1.); - e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getStartNode() && v2[1]->getStartNode()==e1->getStartNode() && v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 1 End. - e1=new EdgeLin(0.5,1.,0.5,0.); - e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getEndNode() && v2[1]->getStartNode()==e1->getEndNode() && v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - ComposedEdge::Delete(&v2); - ComposedEdge::Delete(&v1); -} - -} diff --git a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx b/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx deleted file mode 100644 index 991e47b28..000000000 --- a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef _QUADRATICPLANARINTERPTEST_HXX_ -#define _QUADRATICPLANARINTERPTEST_HXX_ - -#include - -#include "InterpKernelTestExport.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" - -namespace INTERP_TEST -{ - class INTERPKERNELTEST_EXPORT QuadraticPlanarInterpTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( QuadraticPlanarInterpTest ); - CPPUNIT_TEST( ReadWriteInXfigElementary ); - CPPUNIT_TEST( ReadWriteInXfigGlobal ); - CPPUNIT_TEST( BasicGeometricTools ); - CPPUNIT_TEST( IntersectionBasics ); - CPPUNIT_TEST( EdgeLinUnitary ); - CPPUNIT_TEST( IntersectionEdgeOverlapUnitarySegSeg ); - CPPUNIT_TEST( IntersectionPointOnlyUnitarySegSeg ); - CPPUNIT_TEST( IntersectArcCircleBase ); - CPPUNIT_TEST( IntersectArcCircleFull ); - CPPUNIT_TEST( IntersectArcCircleSegumentBase ); - CPPUNIT_TEST( checkInOutDetection ); - CPPUNIT_TEST( checkAssemblingBases1 ); - CPPUNIT_TEST( checkAssemblingBases2 ); - CPPUNIT_TEST( checkPolygonsIntersection1 ); - CPPUNIT_TEST( checkPolygonsIntersection2 ); - CPPUNIT_TEST( checkAreasCalculations ); - CPPUNIT_TEST( checkBarycenterCalculations ); - CPPUNIT_TEST( checkHighLevelFunctionTest1 ); - CPPUNIT_TEST( check1DInterpLin ); - CPPUNIT_TEST( checkEpsilonCoherency1 ); - CPPUNIT_TEST( checkNonRegression1 ); - CPPUNIT_TEST( checkNonRegression2 ); - CPPUNIT_TEST( checkNonRegression3 ); - CPPUNIT_TEST( checkNonRegression4 ); - CPPUNIT_TEST( checkNonRegression5 ); - CPPUNIT_TEST( checkNonRegression6 ); - CPPUNIT_TEST( checkNonRegression7 ); - CPPUNIT_TEST( checkNonRegression8 ); - CPPUNIT_TEST( checkNonRegression9 ); - CPPUNIT_TEST( checkNonRegression10 ); - CPPUNIT_TEST( checkNonRegression11 ); - CPPUNIT_TEST( checkNonRegression12 ); - CPPUNIT_TEST ( checkNonRegression13 ); - CPPUNIT_TEST ( checkNonRegression14 ); - CPPUNIT_TEST ( checkNonRegression15 ); - CPPUNIT_TEST ( checkNonRegression16 ); - CPPUNIT_TEST ( checkNonRegression17 ); - // - CPPUNIT_TEST ( checkNonRegressionOmar0000 ); - CPPUNIT_TEST ( checkNonRegressionOmar0001 ); - CPPUNIT_TEST ( checkNonRegressionOmar0002 ); - CPPUNIT_TEST ( checkNonRegressionOmar0003 ); - CPPUNIT_TEST ( checkNonRegressionOmar0004 ); - CPPUNIT_TEST ( checkNonRegressionOmar0005 ); - CPPUNIT_TEST ( checkNonRegressionOmar0006 ); - CPPUNIT_TEST ( checkNonRegressionOmar0007 ); - CPPUNIT_TEST ( checkNonRegressionOmar0008 ); - CPPUNIT_TEST ( checkNonRegressionOmar0009 ); - CPPUNIT_TEST ( checkNonRegressionOmar0010 ); - CPPUNIT_TEST ( checkNonRegressionOmar0011 ); - CPPUNIT_TEST ( checkNonRegressionOmar2511 ); - CPPUNIT_TEST ( checkNonRegressionOmar0012 ); - CPPUNIT_TEST ( checkNonRegressionOmar0013 ); - CPPUNIT_TEST ( checkNonRegressionOmar0014 ); - CPPUNIT_TEST ( checkNonRegressionOmar0015 ); - CPPUNIT_TEST ( checkNonRegressionOmar0016 ); - CPPUNIT_TEST ( checkNonRegressionOmar0017 ); - CPPUNIT_TEST ( checkNonRegressionOmar0018 ); - CPPUNIT_TEST ( checkNonRegressionOmar0019 ); - CPPUNIT_TEST ( checkNonRegressionOmar0020 ); - CPPUNIT_TEST ( checkNonRegressionOmar0021 ); - CPPUNIT_TEST ( checkNonRegressionOmar0022 ); - CPPUNIT_TEST ( checkNonRegressionOmar0023 ); - CPPUNIT_TEST ( checkNonRegressionOmar0024 ); - CPPUNIT_TEST ( checkNonRegressionOmar2524 ); - CPPUNIT_TEST ( checkNonRegressionOmar0025 ); - CPPUNIT_TEST ( checkNonRegressionOmar0026 ); - CPPUNIT_TEST ( checkNonRegressionOmar0027 ); - CPPUNIT_TEST ( checkNonRegressionOmar0028 ); - CPPUNIT_TEST ( checkNonRegressionOmar0029 ); - CPPUNIT_TEST ( checkNonRegressionOmar0030 ); - // - CPPUNIT_TEST( checkNormalize ); - CPPUNIT_TEST( checkMakePartitionAbs1 ); - // - CPPUNIT_TEST( checkIsInOrOut ); - CPPUNIT_TEST( checkGetMiddleOfPoints ); - CPPUNIT_TEST( checkGetMiddleOfPointsOriented ); - CPPUNIT_TEST_SUITE_END(); - public: - void setUp(); - void tearDown(); - void cleanUp(); - // - void ReadWriteInXfigElementary(); - void ReadWriteInXfigGlobal(); - void BasicGeometricTools(); - void IntersectionBasics(); - void EdgeLinUnitary(); - void IntersectionEdgeOverlapUnitarySegSeg(); - void IntersectionPointOnlyUnitarySegSeg(); - // - void IntersectArcCircleBase(); - void IntersectArcCircleFull(); - void IntersectArcCircleSegumentBase(); - // - void checkInOutDetection(); - // - void checkAssemblingBases1(); - void checkAssemblingBases2(); - // - void checkPolygonsIntersection1(); - void checkPolygonsIntersection2(); - void checkAreasCalculations(); - void checkBarycenterCalculations(); - // - void checkHighLevelFunctionTest1(); - // - void check1DInterpLin(); - // - void checkEpsilonCoherency1(); - // - void checkNonRegression1(); - void checkNonRegression2(); - void checkNonRegression3(); - void checkNonRegression4(); - void checkNonRegression5(); - void checkNonRegression6(); - void checkNonRegression7(); - void checkNonRegression8(); - void checkNonRegression9(); - void checkNonRegression10(); - void checkNonRegression11(); - void checkNonRegression12(); - void checkNonRegression13(); - void checkNonRegression14(); - void checkNonRegression15(); - void checkNonRegression16(); - void checkNonRegression17(); - // - void checkNonRegressionOmar0000(); - void checkNonRegressionOmar0001(); - void checkNonRegressionOmar0002(); - void checkNonRegressionOmar0003(); - void checkNonRegressionOmar0004(); - void checkNonRegressionOmar0005(); - void checkNonRegressionOmar0006(); - void checkNonRegressionOmar0007(); - void checkNonRegressionOmar0008(); - void checkNonRegressionOmar0009(); - void checkNonRegressionOmar0010(); - void checkNonRegressionOmar0011(); - void checkNonRegressionOmar2511(); - void checkNonRegressionOmar0012(); - void checkNonRegressionOmar0013(); - void checkNonRegressionOmar0014(); - void checkNonRegressionOmar0015(); - void checkNonRegressionOmar0016(); - void checkNonRegressionOmar0017(); - void checkNonRegressionOmar0018(); - void checkNonRegressionOmar0019(); - void checkNonRegressionOmar0020(); - void checkNonRegressionOmar0021(); - void checkNonRegressionOmar0022(); - void checkNonRegressionOmar0023(); - void checkNonRegressionOmar0024(); - void checkNonRegressionOmar2524(); - void checkNonRegressionOmar0025(); - void checkNonRegressionOmar0026(); - void checkNonRegressionOmar0027(); - void checkNonRegressionOmar0028(); - void checkNonRegressionOmar0029(); - void checkNonRegressionOmar0030(); - // - void checkNormalize(); - void checkMakePartitionAbs1(); - // From Adrien: - void checkIsInOrOut(); - void checkGetMiddleOfPoints(); - void checkGetMiddleOfPointsOriented(); - - private: - INTERP_KERNEL::QuadraticPolygon *buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth); - INTERP_KERNEL::EdgeArcCircle *buildArcOfCircle(const double *center, double radius, double alphaStart, double alphaEnd); - double btw2NodesAndACenter(const INTERP_KERNEL::Node& n1, const INTERP_KERNEL::Node& n2, const double *center); - void checkBasicsOfPolygons(INTERP_KERNEL::QuadraticPolygon& pol1, INTERP_KERNEL::QuadraticPolygon& pol2, bool checkDirection); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx b/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx deleted file mode 100644 index a41827b15..000000000 --- a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx +++ /dev/null @@ -1,675 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" - -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -static const double ADMISSIBLE_ERROR = 1.e-14; - -void QuadraticPlanarInterpTest::IntersectArcCircleBase() -{ - double center[2]={0.5,0.5}; - double radius=0.3; - EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,M_PI/3.,M_PI/2.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/2),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,M_PI/3.,3.*M_PI/4.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR);//<< - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,3*M_PI/4,7*M_PI/8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,7.*M_PI/8.,9.*M_PI/8.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI),ADMISSIBLE_ERROR);//<< - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,9.*M_PI/8.,11.*M_PI/8.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(9*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(11*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,11.*M_PI/8.,7.*M_PI/4.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/2),ADMISSIBLE_ERROR);//<< - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,7.*M_PI/4.,15.*M_PI/8.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(15*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,-M_PI/8.,M_PI/4.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(0.),ADMISSIBLE_ERROR); //<< - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); - e1->decrRef(); - // - // ArcCArcCIntersector - // - TypeOfLocInEdge where1,where2; - std::vector v4; - MergePoints v3; - EdgeArcCircle *e2; - ArcCArcCIntersector *intersector=0; - for(unsigned k=0;k<8;k++) - { - e1=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); - e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==START && where2==END); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,7*M_PI/24.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==INSIDE && where2==END); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,7*M_PI/24.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==START && where2==INSIDE); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,13.*M_PI/48.+k*M_PI/4.,15*M_PI/48.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==INSIDE && where2==INSIDE); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,-M_PI/4.+k*M_PI/4.,M_PI/6.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_BEFORE); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,0+k*M_PI/4.,5*M_PI/6.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_AFTER); - delete intersector; v3.clear(); e2->decrRef(); - e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Opposite order. - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); - e2=buildArcOfCircle(center2,1.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Same order. - for(unsigned k=0;k<7;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); - e2=buildArcOfCircle(center2,1.,M_PI+(k+1)*M_PI/4.,M_PI+(k-1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // 2 intersections R1>R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // 2 intersections R1>R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; Opposite order. - for(unsigned k=0;k<1;k++) - { - double center2[2]; center[0]=0.; center[1]=0.; - center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,1.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); - e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; same order. - for(unsigned k=0;k<8;k++) - { - double center2[2]; center[0]=0.; center[1]=0.; - center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); - e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Tangent intersection - QUADRATIC_PLANAR::setPrecision(1e-5); - for(unsigned k=0;k<8;k++) - { - double center2[2]; center[0]=0.; center[1]=0.; - center2[0]=4.*cos(k*M_PI/4.); center2[1]=4.*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); - e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); // order has no sence here because v4.size() expected to 1 but for valgrind serenity test. - CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v4.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - QUADRATIC_PLANAR::setPrecision(1e-14); - // Extremities # 1 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.-0.55978664859225125,M_PI+k*M_PI/4.+0.55978664859225125); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getStartNode()==e1->getEndNode()); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.55978664859225125); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==e1->getEndNode()); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Extremities # 2 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); - CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v4[0]); - v4[0]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Extremities # 3 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); CPPUNIT_ASSERT(e1->getEndNode()==v4[1]); - v4[0]->decrRef(); v4[1]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Extremities # 4 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); - Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.),center[1]+3.*sin(k*M_PI/4.)); - double angle=k*M_PI/4.-0.17793931986099812; - angle=angle>M_PI?angle-2.*M_PI:angle; - e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. - center,3.,angle,0.17793931986099812); - nodeS->decrRef(); nodeE->decrRef(); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); - v4[0]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - //Extremities # 5 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); - Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.)+0.5,center[1]+3.*sin(k*M_PI/4.)); - double angle=k*M_PI/4.-0.17793931986099812; - angle=angle>M_PI?angle-2.*M_PI:angle; - e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. - center,3.,angle,0.67793931986099812); - nodeS->decrRef(); nodeE->decrRef(); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); - v4[0]->decrRef(); v4[1]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } -} - -void QuadraticPlanarInterpTest::IntersectArcCircleFull() -{ - double center1[2]; center1[0]=0.; center1[1]=0.; double radius1=3.; - double center2[2]; center2[0]=0.75; center2[1]=-2.6; double radius2=1.; - EdgeArcCircle *e1=buildArcOfCircle(center1,radius1,-M_PI/3.,4.*M_PI/3.); - EdgeArcCircle *e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); - MergePoints commonNode; - QuadraticPolygon pol1; QuadraticPolygon pol2; - QuadraticPolygon pol3; QuadraticPolygon pol4; - pol3.pushBack(e1); pol4.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol3.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol4.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol3.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol4.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol1,pol2)); - CPPUNIT_ASSERT_EQUAL(2,pol1.size()); - CPPUNIT_ASSERT_EQUAL(2,pol2.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol1.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol2.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol1.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol2.getPerimeter(),1e-6); - // - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); - commonNode.clear(); - QuadraticPolygon pol5; QuadraticPolygon pol6; - QuadraticPolygon pol7; QuadraticPolygon pol8; - pol7.pushBack(e1); pol8.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol7.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol8.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol7.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol8.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol5,pol6)); - CPPUNIT_ASSERT_EQUAL(2,pol5.size()); - CPPUNIT_ASSERT_EQUAL(2,pol6.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol5.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol6.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol5.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol6.getPerimeter(),1e-6); - // - center2[0]=3.5; center2[1]=0.; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/2.,3*M_PI/2.); - commonNode.clear(); - QuadraticPolygon pol9; QuadraticPolygon pol10; - QuadraticPolygon pol11; QuadraticPolygon pol12; - pol11.pushBack(e1); pol12.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol11.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol12.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol11.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol12.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol9,pol10)); - CPPUNIT_ASSERT_EQUAL(3,pol9.size()); - CPPUNIT_ASSERT_EQUAL(3,pol10.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol9.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol10.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol9.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol10.getArea(),1e-6); - // - center2[0]=0.; center2[1]=0.; radius2=radius1; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/3.,2*M_PI/3.); - commonNode.clear(); - QuadraticPolygon pol13; QuadraticPolygon pol14; - QuadraticPolygon pol15; QuadraticPolygon pol16; - pol15.pushBack(e1); pol16.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol15.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol16.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol15.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol16.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol13,pol14)); - CPPUNIT_ASSERT_EQUAL(3,pol13.size()); - CPPUNIT_ASSERT_EQUAL(1,pol14.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol13.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol13.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol14.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol14.getArea(),1e-6); - // - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,2*M_PI/3.,M_PI/3.); - commonNode.clear(); - QuadraticPolygon pol17; QuadraticPolygon pol18; - QuadraticPolygon pol19; QuadraticPolygon pol20; - pol19.pushBack(e1); pol20.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol19.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol20.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol19.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol20.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol17,pol18)); - CPPUNIT_ASSERT_EQUAL(3,pol17.size()); - CPPUNIT_ASSERT_EQUAL(1,pol18.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol17.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol17.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol18.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol18.getArea(),1e-6); - //no intersection #1 - center2[0]=4.277; center2[1]=-4.277; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); - QuadraticPolygon polTemp1; QuadraticPolygon polTemp2; - CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); - e1->decrRef(); e2->decrRef(); - //no intersection #2 - center2[0]=1.; center2[1]=-1.; radius2=0.2; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); - e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::IntersectArcCircleSegumentBase() -{ - double center[2]={2.,2.}; - EdgeArcCircle *e1=buildArcOfCircle(center,2.3,M_PI/4.,5.*M_PI/4.); - EdgeLin *e2=new EdgeLin(-1.3,1.,3.,5.3); - EdgeIntersector *intersector=new ArcCSegIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - std::vector v4; - MergePoints v3; - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); - v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; - // - e2=new EdgeLin(3.,5.3,-1.3,1.); - intersector=new ArcCSegIntersector(*e1,*e2); - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); - v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; - // tangent intersection - e2=new EdgeLin(-1.,4.3,3.,4.3); - intersector=new ArcCSegIntersector(*e1,*e2); - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); - v4[0]->decrRef(); e2->decrRef(); v3.clear(); delete intersector; - // no intersection - e2=new EdgeLin(-2.,-2.,-1.,-3.); - intersector=new ArcCSegIntersector(*e1,*e2); - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(obvious && !areOverlapped); - e2->decrRef(); v3.clear(); delete intersector; - // - e1->decrRef(); -} - -QuadraticPolygon *QuadraticPlanarInterpTest::buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth) -{ - std::vector nodes; - for(int i=0;i -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -void QuadraticPlanarInterpTest::checkInOutDetection() -{ - Node *n1=new Node(0.,0.); - Node *n2=new Node(1.,0.); - Node *n3=new Node(0.5,1.); - EdgeLin *e1=new EdgeLin(n1,n2); - EdgeLin *e2=new EdgeLin(n2,n3); - EdgeLin *e3=new EdgeLin(n3,n1); - ComposedEdge *tri=new ComposedEdge; - tri->pushBack(e1); tri->pushBack(e2); tri->pushBack(e3); - // - Node *where=new Node(0.4,0.1); - CPPUNIT_ASSERT(tri->isInOrOut(where)); where->decrRef(); - where=new Node(-0.1,1.); - CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); - where=new Node(0.6,-0.1); - CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); - //Clean-up - n1->decrRef(); n2->decrRef(); n3->decrRef(); - ComposedEdge::Delete(tri); -} - -/*! - * Check Iterators mechanism. - */ -void QuadraticPlanarInterpTest::checkAssemblingBases1() -{ - Node *n1=new Node(0.,0.); - Node *n2=new Node(0.1,0.); EdgeLin *e1_2=new EdgeLin(n1,n2); - Node *n3=new Node(0.2,0.); EdgeLin *e2_3=new EdgeLin(n2,n3); - Node *n4=new Node(0.3,0.); EdgeLin *e3_4=new EdgeLin(n3,n4); - Node *n5=new Node(0.4,0.); EdgeLin *e4_5=new EdgeLin(n4,n5); - Node *n6=new Node(0.5,0.); EdgeLin *e5_6=new EdgeLin(n5,n6); - Node *n7=new Node(0.6,0.); EdgeLin *e6_7=new EdgeLin(n6,n7); - Node *n8=new Node(0.7,0.); EdgeLin *e7_8=new EdgeLin(n7,n8); - Node *n9=new Node(0.8,0.); EdgeLin *e8_9=new EdgeLin(n8,n9); - Node *n10=new Node(0.9,0.); EdgeLin *e9_10=new EdgeLin(n9,n10); - Node *n11=new Node(1.,0.); EdgeLin *e10_11=new EdgeLin(n10,n11); - Node *n12=new Node(0.5,1.); EdgeLin *e11_12=new EdgeLin(n11,n12); - EdgeLin *e12_1=new EdgeLin(n12,n1); - //Only one level - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); - e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); - ComposedEdge *c=new ComposedEdge; - c->pushBack(e1_2); c->pushBack(e2_3); c->pushBack(e3_4); c->pushBack(e4_5); c->pushBack(e5_6); c->pushBack(e6_7); - c->pushBack(e7_8); c->pushBack(e8_9); c->pushBack(e9_10); c->pushBack(e10_11); c->pushBack(e11_12); c->pushBack(e12_1); - CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); - IteratorOnComposedEdge it(c); - CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); - it.next(); it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); - it.next(); CPPUNIT_ASSERT(it.finished()); - it.first(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); - it.nextLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.last(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); - //Multi-Level - ComposedEdge::Delete(c); - //(e1_2, (e2_3,(e3_4, e4_5, e5_6, e6_7, (e7_8, e8_9 ), ( e9_10 , e10_11 ), e11_12 ),e12_1 ) ) - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); - e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); - ComposedEdge *c2_2_4=new ComposedEdge; c2_2_4->pushBack(e7_8); c2_2_4->pushBack(e8_9); - ComposedEdge *c2_2_5=new ComposedEdge; c2_2_5->pushBack(e9_10); c2_2_5->pushBack(e10_11); - ComposedEdge *c2_2=new ComposedEdge; c2_2->pushBack(e3_4); c2_2->pushBack(e4_5); c2_2->pushBack(e5_6); c2_2->pushBack(e6_7); c2_2->pushBack(c2_2_4); c2_2->pushBack(c2_2_5); c2_2->pushBack(e11_12); - ComposedEdge *c2=new ComposedEdge; c2->pushBack(e2_3); c2->pushBack(c2_2); c2->pushBack(e12_1); - c=new ComposedEdge; c->pushBack(e1_2); c->pushBack(c2); CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); - IteratorOnComposedEdge it2(c); - CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.finished()); - it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.last(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - // substitutions. - /*it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - ElementaryEdge *&tmp=it2.current(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - ComposedEdge *c1=new ComposedEdge; Node *n1_bis=new Node(0.,0.05); EdgeLin *e1_1bis=new EdgeLin(n1,n1_bis); EdgeLin *e1bis_2=new EdgeLin(n1_bis,n2); e1_1bis->incrRef(); e1bis_2->incrRef(); - c1->pushBack(e1_1bis); c1->pushBack(e1bis_2); delete tmp; tmp=(ElementaryEdge *)c1; CPPUNIT_ASSERT_EQUAL(13,c->recursiveSize()); - CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());// here testing capability of Iterator.'current' method to deal with change of hierarchy. - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - //go forward - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());*/ - ComposedEdge::SoftDelete(c2_2_4); - ComposedEdge::SoftDelete(c2_2_5); - ComposedEdge::SoftDelete(c2_2); - ComposedEdge::SoftDelete(c2); - ComposedEdge::Delete(c); - //clean-up - //e1_1bis->decrRef(); e1bis_2->decrRef(); - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_7->decrRef(); - e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); - //n1_bis->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); -} - -/*! - * Check splitting of 2 polygons. After this operation, all ElementaryEdge are either in/out/on. - */ -void QuadraticPlanarInterpTest::checkAssemblingBases2() -{ - //The "most" basic test1 - Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); - Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); - Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - QuadraticPolygon cpyPol1(pol1); int nbOfSplits=0; - cpyPol1.SplitPolygonsEachOther(pol1,pol2,nbOfSplits); - CPPUNIT_ASSERT_EQUAL(5,pol1.recursiveSize()); - CPPUNIT_ASSERT_EQUAL(5,pol2.recursiveSize());CPPUNIT_ASSERT_EQUAL(15,nbOfSplits); - checkBasicsOfPolygons(pol1,pol2,true); - CPPUNIT_ASSERT(pol2[1]->getEndNode()==pol1[1]->getEndNode()); - CPPUNIT_ASSERT(pol2[1]->getEndNode()->getLoc()==ON_1); - CPPUNIT_ASSERT(pol2[3]->getEndNode()==pol1[0]->getEndNode()); - CPPUNIT_ASSERT(pol2[3]->getEndNode()->getLoc()==ON_1); - cpyPol1.performLocatingOperation(pol2); - ElementaryEdge *tmp=dynamic_cast(pol2[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol2[1]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol2[2]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); - tmp=dynamic_cast(pol2[3]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); - tmp=dynamic_cast(pol2[4]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - //clean-up for test1 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Deeper test some extremities of pol2 are on edges of pol1. - - n1=new Node(0.,0.); n4=new Node(1.5,-0.5); - n2=new Node(1.,0.); n5=new Node(0.5,0.); - n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - QuadraticPolygon pol4; pol4.pushBack(e5_4); pol4.pushBack(e4_7); pol4.pushBack(e7_6); pol4.pushBack(e6_5); - QuadraticPolygon cpyPol3(pol3); nbOfSplits=0; - cpyPol3.SplitPolygonsEachOther(pol3,pol4,nbOfSplits); - CPPUNIT_ASSERT_EQUAL(5,pol3.recursiveSize()); - CPPUNIT_ASSERT_EQUAL(4,pol4.recursiveSize());CPPUNIT_ASSERT_EQUAL(16,nbOfSplits); - checkBasicsOfPolygons(pol3,pol4,true); - CPPUNIT_ASSERT(pol4[0]->getStartNode()==pol3[0]->getEndNode()); CPPUNIT_ASSERT(pol4[0]->getStartNode()==n5); - CPPUNIT_ASSERT(n5->getLoc()==ON_LIM_1); - CPPUNIT_ASSERT(pol4[2]->getEndNode()==pol3[2]->getEndNode()); CPPUNIT_ASSERT(pol4[2]->getEndNode()==n6); - CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); - cpyPol3.performLocatingOperation(pol4); - tmp=dynamic_cast(pol4[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_7); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); - tmp=dynamic_cast(pol4[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_4); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol4[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e7_6); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); - //clean-up for test2 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); - - //Test with one edge of pol2 is included in pol1. - - n1=new Node(0.,0.); n4=new Node(-0.5,0.); - n2=new Node(1.,0.); n5=new Node(0.,-1.); - n3=new Node(0.5,1.); n6=new Node(0.5,0.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); - QuadraticPolygon pol6; pol6.pushBack(e4_5); pol6.pushBack(e5_6); pol6.pushBack(e6_4); - QuadraticPolygon cpyPol5(pol5); nbOfSplits=0; - cpyPol5.SplitPolygonsEachOther(pol5,pol6,nbOfSplits); - CPPUNIT_ASSERT_EQUAL(4,pol5.recursiveSize()); - CPPUNIT_ASSERT_EQUAL(4,pol6.recursiveSize()); CPPUNIT_ASSERT_EQUAL(13,nbOfSplits); - checkBasicsOfPolygons(pol5,pol6,false); - CPPUNIT_ASSERT(pol6[2]->getStartNode()==pol5[0]->getEndNode()); CPPUNIT_ASSERT(pol6[2]->getStartNode()==n6); - CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); - CPPUNIT_ASSERT(pol6[2]->getEndNode()==pol5[0]->getStartNode()); CPPUNIT_ASSERT(pol5[0]->getStartNode()==n1); - CPPUNIT_ASSERT(n1->getLoc()==ON_LIM_1); - cpyPol5.performLocatingOperation(pol6); - tmp=dynamic_cast(pol6[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol6[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_6); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol6[2]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - tmp=dynamic_cast(pol6[3]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - //clean-up test3 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Test of full overlapped polygons. - - n1=new Node(0.,0.); n4=new Node(0.,0.); - n2=new Node(1.,0.); n5=new Node(1.,0.); - n3=new Node(0.5,1.); n6=new Node(0.5,1.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); - QuadraticPolygon pol8; pol8.pushBack(e4_5); pol8.pushBack(e5_6); pol8.pushBack(e6_4); - QuadraticPolygon cpyPol7(pol7); nbOfSplits=0; - cpyPol7.SplitPolygonsEachOther(pol7,pol8,nbOfSplits); - tmp=dynamic_cast(pol8[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e1_2); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - tmp=dynamic_cast(pol8[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e2_3); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - tmp=dynamic_cast(pol8[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e3_1); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - //clean-up test4 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); -} - -void QuadraticPlanarInterpTest::checkBasicsOfPolygons(QuadraticPolygon& pol1, QuadraticPolygon& pol2, bool checkDirection) -{ - IteratorOnComposedEdge it1(&pol1),it2(&pol2); it1.previousLoop(); it2.previousLoop(); - Node *nIter1=it1.current()->getEndNode(); Node *nIter2=it2.current()->getEndNode(); - for(it2.first();!it2.finished();it2.next()) - { - CPPUNIT_ASSERT(nIter2==it2.current()->getStartNode()); - if(checkDirection) - CPPUNIT_ASSERT(it2.current()->getDirection()); - nIter2=it2.current()->getEndNode(); - } - for(it1.first();!it1.finished();it1.next()) - { - CPPUNIT_ASSERT(nIter1==it1.current()->getStartNode()); - if(checkDirection) - CPPUNIT_ASSERT(it1.current()->getDirection()); - nIter1=it1.current()->getEndNode(); - } -} - -} diff --git a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx b/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx deleted file mode 100644 index c9c34bd27..000000000 --- a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx +++ /dev/null @@ -1,1685 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -void QuadraticPlanarInterpTest::checkPolygonsIntersection1() -{ - //The "most" basic test1 - Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); - Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); - Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); - // - std::vector result; - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<1;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol1; pol1.circularPermute(); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - double tmp1=0.,tmp2=0.,tmp3=0.; - pol1.intersectForPerimeter(pol2,tmp1,tmp2,tmp3); - std::vector v1,v2; - std::vector v3; - pol1.intersectForPerimeterAdvanced(pol2,v1,v2);//no common edge - pol1.intersectForPoint(pol2,v3); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v3.size()); - if(k==0) - { - CPPUNIT_ASSERT_EQUAL(2,v3[(3-i)%3]); - CPPUNIT_ASSERT_EQUAL(0,v3[(4-i)%3]); - CPPUNIT_ASSERT_EQUAL(0,v3[(5-i)%3]); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,v1[(3-i)%3],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(4-i)%3],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(5-i)%3],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v2[0],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[1],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[2],1.e-14); - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,tmp1,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5652475842498528,tmp2,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp3,1.e-14);//no common edge - delete result[0]; - } - } - //clean-up for test1 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Deeper test some extremities of pol2 are on edges of pol1. - - n1=new Node(0.,0.); n4=new Node(1.5,-0.5); - n2=new Node(1.,0.); n5=new Node(0.5,0.); - n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); - // - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<4;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - } - } - //clean-up for test2 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); - - //Test with one edge of pol2 is included in pol1. - - n1=new Node(0.,0.); n4=new Node(-0.5,0.); - n2=new Node(1.,0.); n5=new Node(0.,-1.); - n3=new Node(0.5,1.); n6=new Node(0.5,0.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); - for(int i1=0;i1decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Test of full overlapped polygons. - - n1=new Node(0.,0.); n4=new Node(0.,0.); - n2=new Node(1.,0.); n5=new Node(1.,0.); - n3=new Node(0.5,1.); n6=new Node(0.5,1.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - double tmp1=0.,tmp2=0.,tmp3=0.; - pol7.intersectForPerimeter(pol8,tmp1,tmp2,tmp3); - std::vector v1,v2; - pol7.intersectForPerimeterAdvanced(pol8,v1,v2);//only common edges. - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v1[0]+v1[1]+v1[2],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v2[0]+v2[1]+v2[2],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp1,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp2,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,tmp3,1.e-14); - } - } - //clean-up test4 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Test of closing process - - n1=new Node(0.,0.); n4=new Node(0.539,-0.266); - n2=new Node(1.,0.); n5=new Node(1.039,0.6); - n3=new Node(0.5,1.); n6=new Node(-0.077,0.667); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol9; pol9.pushBack(e1_2); pol9.pushBack(e2_3); pol9.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - } - } - //clean-up test5 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - // Full in case - - n1=new Node(0.,0.); n4=new Node(0.3,0.1); - n2=new Node(1.,0.); n5=new Node(0.7,0.1); - n3=new Node(0.5,1.); n6=new Node(0.5,0.7); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol11; pol11.pushBack(e1_2); pol11.pushBack(e2_3); pol11.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - } - } - //clean-up test6 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - // Full out case - - n1=new Node(0.,0.); n4=new Node(-2,0.); - n2=new Node(1.,0.); n5=new Node(-1.,0.); - n3=new Node(0.5,1.); n6=new Node(-1.5,1.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol13; pol13.pushBack(e1_2); pol13.pushBack(e2_3); pol13.pushBack(e3_1); - for(int i1=0;i1decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Multi polygons - - n1=new Node(0.,0.); - n2=new Node(1.,0.); - n3=new Node(1.,1.); - n4=new Node(0.,1.); - // - n5=new Node(0.2,0.7); - n6=new Node(0.4,0.7); - n7=new Node(0.4,1.3); - Node *n8=new Node(0.6,1.3); - Node *n9=new Node(0.6,0.7); - Node *n10=new Node(0.9,0.7); - Node *n11=new Node(0.9,2.); - Node *n12=new Node(0.2,2.); - // - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); Edge *e3_4=new EdgeLin(n3,n4); Edge *e4_1=new EdgeLin(n4,n1); - e5_6=new EdgeLin(n5,n6); Edge *e6_7=new EdgeLin(n6,n7); Edge *e7_8=new EdgeLin(n7,n8); Edge *e8_9=new EdgeLin(n8,n9); Edge *e9_10=new EdgeLin(n9,n10); Edge *e10_11=new EdgeLin(n10,n11); - Edge *e11_12=new EdgeLin(n11,n12); Edge *e12_1=new EdgeLin(n12,n5); - // - for(int k=0;k<2;k++) - for(int i=0;i<4;i++) - { - for(int j=0;j<8;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); e5_6->incrRef(); e6_7->incrRef(); e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); - QuadraticPolygon pol15; pol15.pushBack(e1_2); pol15.pushBack(e2_3); pol15.pushBack(e3_4); pol15.pushBack(e4_1); - for(int i1=0;i1recursiveSize()); CPPUNIT_ASSERT_EQUAL(4,result[1]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,result[0]->getArea()+result[1]->getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03,fabs(result[0]->getArea()-result[1]->getArea()),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,pol15.intersectWith(pol16),1e-10); - delete result[0]; delete result[1]; - } - } - //clean-up test8 - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); e5_6->decrRef(); e6_7->decrRef(); e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); -} - -/*! - * Testing case where a polygon pol1 is included in an onother polygon pol2. - */ -void QuadraticPlanarInterpTest::checkPolygonsIntersection2() -{ - Node *n1=new Node(0.,0.); Node *n4=new Node(0.2,0.2); - Node *n2=new Node(1.,0.); Node *n5=new Node(0.8,0.2); - Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.8); - Edge *e1_2=new EdgeLin(n1,n2); Edge *e4_5=new EdgeLin(n4,n5); - Edge *e2_3=new EdgeLin(n2,n3); Edge *e5_6=new EdgeLin(n5,n6); - Edge *e3_1=new EdgeLin(n3,n1); Edge *e6_4=new EdgeLin(n6,n4); - // - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - std::vector result=pol1.intersectMySelfWith(pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); - CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); - delete result[0]; - result.clear(); - pol1.initLocations(); - pol2.initLocations(); - result=pol2.intersectMySelfWith(pol1); - CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); - CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); - delete result[0]; - //clean-up - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); -} - -void QuadraticPlanarInterpTest::checkAreasCalculations() -{ - Node *n1=new Node(0.,0.); - Node *n2=new Node(1.,0.); - Node *n3=new Node(0.5,1.); - Edge *e1_2=new EdgeLin(n1,n2); - Edge *e2_3=new EdgeLin(n2,n3); - Edge *e3_1=new EdgeLin(n3,n1); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,pol1.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); - pol1.reverse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5,pol1.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); - //clean-up - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); - - //case 2 - - n1=new Node(0.,0.); - n2=new Node(1.,0.); - Node *n3m=new Node(1.5,0.5); - n3=new Node(1.,1.); - Node *n4=new Node(0.,1.); - e1_2=new EdgeLin(n1,n2); - e2_3=new EdgeArcCircle(n2,n3m,n3); - Edge *e3_4=new EdgeLin(n3,n4); - Edge *e4_1=new EdgeLin(n4,n1); - // - for(int k=0;k<8;k++) - { - n2->setNewCoords(cos(k*M_PI/4),sin(k*M_PI/4)); - n3->setNewCoords(sqrt(2.)*cos((k+1)*M_PI/4),sqrt(2.)*sin((k+1)*M_PI/4)); - n3m->setNewCoords(1.5811388300841898*cos(0.3217505543966423+k*M_PI/4),1.5811388300841898*sin(0.3217505543966423+k*M_PI/4)); - n4->setNewCoords(cos(k*M_PI/4+M_PI/2),sin(k*M_PI/4+M_PI/2)); - e1_2->update(n3m); e2_3->update(n3m); e3_4->update(n3m); e4_1->update(n3m); - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); - QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_3); pol2.pushBack(e3_4); pol2.pushBack(e4_1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.3926990816987241,pol2.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); - pol2.reverse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3926990816987241,pol2.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); - } - //clean-up case2 - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); - - //case 3 - - const double radius1=0.7; - const double radius2=0.9; - n1=new Node(1.+radius1*cos(-2.*M_PI/3.),1.+radius1*sin(-2.*M_PI/3.)); - n2=new Node(1.+radius1*cos(-M_PI/3.),1.+radius1*sin(-M_PI/3.)); - Node *n2m=new Node(1.+radius1*cos(M_PI/2.),1.+radius1*sin(M_PI/2.)); - n3=new Node(1.+radius2*cos(-M_PI/3.),1.+radius2*sin(-M_PI/3.)); - n3m=new Node(1.+radius2*cos(M_PI/2.),1.+radius2*sin(M_PI/2.)); - n4=new Node(1.+radius2*cos(-2.*M_PI/3.),1.+radius2*sin(-2.*M_PI/3.)); - e1_2=new EdgeArcCircle(n1,n2m,n2); - e2_3=new EdgeLin(n2,n3); - e3_4=new EdgeArcCircle(n3,n3m,n4); - e4_1=new EdgeLin(n4,n1); - // - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_4); pol3.pushBack(e4_1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83775804095727857,pol3.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); - pol3.reverse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.83775804095727857,pol3.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); - //clean-up case3 - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); - n1->decrRef(); n2->decrRef(); n2m->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); -} - -void QuadraticPlanarInterpTest::checkBarycenterCalculations() -{ - Node *n1=new Node(3.,7.); - Node *n2=new Node(5.,7.); - Node *n3=new Node(4.,8.); - Edge *e1_2=new EdgeLin(n1,n2); - Edge *e2_3=new EdgeLin(n2,n3); - Edge *e3_1=new EdgeLin(n3,n1); - // - double bary[2]; - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - bary[0]=0.; bary[1]=0.; - e1_2->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-56.,bary[0],1.e-10); - bary[0]=0.; bary[1]=0.; - e2_3->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.66666666666667,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.16666666666667,bary[1],1.e-10); - bary[0]=0.; bary[1]=0.; - e3_1->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.333333333333336,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.1666666666667,bary[1],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,pol1.getArea(),1e-10); - pol1.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol4; pol4.pushBack(e3_1,false); pol4.pushBack(e2_3,false); pol4.pushBack(e1_2,false); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol4.getArea(),1e-10); - pol4.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); - //clean-up - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); - //Inverting polygon - n1=new Node(3.,7.); - n2=new Node(5.,7.); - n3=new Node(4.,8.); - e1_2=new EdgeLin(n1,n3); - e2_3=new EdgeLin(n3,n2); - e3_1=new EdgeLin(n2,n1); - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - bary[0]=0.; bary[1]=0.; - pol3.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol3.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); - //clean-up - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); - // - double center[2]={3.,7.}; - e1_2=buildArcOfCircle(center,4.,M_PI/3.,4.*M_PI/3.); - bary[0]=0.; bary[1]=0.; - e1_2->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(131.685410765053,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(303.262521934362,bary[1],1.e-10); - n1=new Node(0.99999999999999822,3.5358983848622465); - n2=new Node(5.,10.4641016151377544); - Edge *e2_1=new EdgeLin(n1,n2); - // - e1_2->incrRef(); e2_1->incrRef(); - QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_1); - pol2.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.132741228718345,pol2.getArea(),1e-10); - //4*radius/(3.*pi) - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5297896122085546,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8488263631567756,bary[1],1.e-10); - //clean-up - e1_2->decrRef(); e2_1->decrRef(); - n1->decrRef(); n2->decrRef(); -} - -/*! - * Testing user interface high level function. - */ -void QuadraticPlanarInterpTest::checkHighLevelFunctionTest1() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - double coords[]={ - 8.8334591186000004, 5.0999999999999996, - 7.1014083111000001, 6.0999999999999996, - 7.8334591186000004, 6.8320508074999999, - 7.9674337149000003, 5.5999999999999996, - 7.4192455562999999, 6.5142135623000001, - 8.3334591186000004, 5.9660254036999998 - }; - std::vector nodes; - nodes.push_back(new Node(coords)); - nodes.push_back(new Node(coords+2)); - nodes.push_back(new Node(coords+4)); - nodes.push_back(new Node(coords+6)); - nodes.push_back(new Node(coords+8)); - nodes.push_back(new Node(coords+10)); - QuadraticPolygon *pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.04719755,pol->getArea(),1e-5); - CPPUNIT_ASSERT_EQUAL(3,pol->size()); - ElementaryEdge *e0=dynamic_cast((*pol)[0]); - ElementaryEdge *e1=dynamic_cast((*pol)[1]); - ElementaryEdge *e2=dynamic_cast((*pol)[0]); - CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); - CPPUNIT_ASSERT(dynamic_cast(e0->getPtr()));//<- testing detection of colinearity - CPPUNIT_ASSERT(dynamic_cast(e1->getPtr())); - CPPUNIT_ASSERT(dynamic_cast(e2->getPtr()));//<- testing detection of colinearity - nodes.clear(); - delete pol; - nodes.push_back(new Node(coords)); - nodes.push_back(new Node(coords+4)); - nodes.push_back(new Node(coords+2)); - nodes.push_back(new Node(coords+10)); - nodes.push_back(new Node(coords+8)); - nodes.push_back(new Node(coords+6)); - pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.04719755,pol->getArea(),1e-5); - CPPUNIT_ASSERT_EQUAL(3,pol->size()); - e0=dynamic_cast((*pol)[0]); - e1=dynamic_cast((*pol)[1]); - e2=dynamic_cast((*pol)[0]); - CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); - CPPUNIT_ASSERT(dynamic_cast(e0->getPtr()));//<- testing detection of colinearity - CPPUNIT_ASSERT(dynamic_cast(e1->getPtr())); - CPPUNIT_ASSERT(dynamic_cast(e2->getPtr()));//<- testing detection of colinearity - delete pol; - const double coords2[]={ - 0.,0., - 1.5,0., - 1.5,1., - 0.,1. - }; - nodes.clear(); - nodes.push_back(new Node(coords2)); - nodes.push_back(new Node(coords2+2)); - nodes.push_back(new Node(coords2+4)); - nodes.push_back(new Node(coords2+6)); - pol=QuadraticPolygon::BuildLinearPolygon(nodes); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,pol->getArea(),1e-12); - double tmp[2],tmp2; - pol->getBarycenter(tmp,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,tmp[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,tmp[1],1e-12); - delete pol; - const double coords3[]={ - 1.0999999999000001, -1.9052558882999999, - 1.9052558881999999, -1.0999999999000001, - 1.7320508075000001, -0.99999999989999999, - 0.99999999989999999, -1.7320508075000001, - 1.5556349186, -1.5556349185, - 1.8186533478, -1.0499999999, - 1.4142135623000001, -1.4142135623000001, - 1.0499999999, -1.8186533479 - }; - nodes.clear(); - nodes.push_back(new Node(coords3)); - nodes.push_back(new Node(coords3+2)); - nodes.push_back(new Node(coords3+4)); - nodes.push_back(new Node(coords3+6)); - nodes.push_back(new Node(coords3+8)); - nodes.push_back(new Node(coords3+10)); - nodes.push_back(new Node(coords3+12)); - nodes.push_back(new Node(coords3+14)); - pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); - pol->getBarycenter(tmp,tmp2); - delete pol; - QUADRATIC_PLANAR::setPrecision(1e-14); -} - -void QuadraticPlanarInterpTest::check1DInterpLin() -{ - QUADRATIC_PLANAR::setPrecision(1e-7); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - const int NB_OF_CELL_AXIAL_1=30; - static const double Z_VALS_1[NB_OF_CELL_AXIAL_1+1]= - { -0.1550 , -0.1356, -0.1162, -0.0969, -0.0775 ,-0.0581, -0.0387, -0.0194, 0.0000 , 0.0500, - 0.1000 , 0.1500 , 0.2000 , 0.2500, 0.3000, 0.3500, 0.4000, 0.4500, 0.5000, 0.5500, - 0.6000, 0.6500, 0.7000, 0.7194, 0.7388, 0.7581, 0.7775, 0.7969, 0.8163, 0.8356, - 0.8550}; - std::vector zLev1(Z_VALS_1,Z_VALS_1+NB_OF_CELL_AXIAL_1+1); - - const int NB_OF_CELL_AXIAL_2=46; - static const double Z_VALS_2[NB_OF_CELL_AXIAL_2+1]= - { -0.3050 ,-0.2863,-0.2675,-0.2488,-0.2300,-0.2113,-0.1925,-0.1738,-0.1550,-0.1356 - , -0.1162,-0.0969,-0.0775,-0.0581,-0.0387,-0.0194,0.0000, 0.0500, 0.1 ,0.15 - , 0.20, 0.25, 0.30, 0.350 ,0.40 ,0.450 ,0.500 , 0.550, 0.600 ,0.650 ,0.700 - , 0.7194 ,0.7388 ,0.7581 ,0.7775 ,0.7969 ,0.8163 ,0.8356, 0.8550 - , 0.8738 ,0.8925 ,0.9113 ,0.9300 ,0.9488 ,0.9675 ,0.9863, 1.0050}; - std::vector zLev2(Z_VALS_2,Z_VALS_2+NB_OF_CELL_AXIAL_2+1); - std::map > m; - Edge::Interpolate1DLin(zLev1,zLev2,m); - CPPUNIT_ASSERT_EQUAL(30,(int)m.size()); - double ret=0; - for(int i=0;i<30;i++) - { - CPPUNIT_ASSERT_EQUAL(1,(int)m[i].size()); - CPPUNIT_ASSERT(m[i][8+i] > 0.15); - ret+=m[i][8+i]; - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(ret,30.,1e-12); - // - m.clear(); - const int NB_OF_CELL_AXIAL_3=13; - static const double Z_VALS_3[NB_OF_CELL_AXIAL_3+1]={ - 0.,0.01,0.05,0.10,0.15,0.20,0.25,0.30, - 0.35,0.40,0.45,0.50,0.55,0.60 }; - std::vector zLev3(Z_VALS_3,Z_VALS_3+NB_OF_CELL_AXIAL_3+1); - Edge::Interpolate1DLin(zLev3,zLev1,m); - CPPUNIT_ASSERT_EQUAL(13,(int)m.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[1][8],1e-12); - for(int i=0;i<11;i++) - { - CPPUNIT_ASSERT_EQUAL(1,(int)m[i+2].size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[i+2][i+9],1e-12); - } - QUADRATIC_PLANAR::setPrecision(1e-14); -} - -/*! - * This test looks if intersectors are in coherency. - */ -void QuadraticPlanarInterpTest::checkEpsilonCoherency1() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - - const double pol1[]={ - -2.1083388455000001, 1.2172499999999999, - -1.7320508075000001, 1, - -1.9201948265, 1.108625 - }; - - const double pol2[]={ - -2.2379999998, 0, - -1.9381648534, 1.1189999998, - -2.1617419990000002, 0.57923702298000002, - -1.9381648534, 1.1189999998, - -1.9909924031999999, 1.1494999999, - -1.9645786283, 1.1342499998 - }; - // - Node *n1=new Node(pol1[0],pol1[1]); - Node *n2=new Node(pol1[2],pol1[3]); - Node *n3; - // - Edge *e1=new EdgeLin(n1,n2); n1->decrRef(); n2->decrRef(); - n1=new Node(pol2[0],pol2[1]); - n2=new Node(pol2[4],pol2[5]); - n3=new Node(pol2[2],pol2[3]); - Edge *e2=new EdgeArcCircle(n1,n2,n3); n1->decrRef(); n2->decrRef(); n3->decrRef(); - e2->decrRef(); - e1->decrRef(); -} - -/*! - * Tests to avoid regressions : Basic one. - */ -void QuadraticPlanarInterpTest::checkNonRegression1() -{ - const double coords1[]= - { - 16.1732057215, -25.110999999800001, - 16.02555485246479, -25.340997988918762 - }; - Node *nS1=new Node(coords1); - Node *nE1=new Node(coords1+2); - const double radius1=2.902; - const double angleS1=-0.49999999950907054; const double angleL1=-0.0942156629996692; - const double center1[2]={13.66, -23.66}; - EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); - // - const double coords2[]= - { - 16.041579804000001, -25.350249998999999, - 16.367740958999999, -24.132999999999999 - }; - Node *nS2=new Node(coords2); - Node *nE2=new Node(coords2+2); - const double radius2=2.4345; - const double angleS2=-0.523598776190207; const double angleL2=0.5235987755846041; - const double center2[]={ 13.933240960547204, -24.132999998525658 }; - EdgeArcCircle *e2=new EdgeArcCircle(nS2,nE2,center2,radius2,angleS2,angleL2); - MergePoints merge; - QuadraticPolygon c1,c2; - e1->intersectWith(e2,merge,c1,c2); - CPPUNIT_ASSERT_EQUAL(2,c1.size()); CPPUNIT_ASSERT_EQUAL(2,c2.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCurveLength(),c1.getPerimeter(),1e-5); - //clean-up - nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::checkNonRegression2() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - double coords1[]= - { - 15.141499999899999, -26.226033271399999, - 16.226033271199999, -25.141499999800001, - 16.1732057215, -25.110999999800001, - 15.110999999899999, -26.1732057217, - 15.755157392699999, -25.755157392499999, - 16.199619496299999, -25.126249999799999, - 15.7120238788, -25.712023879099998, - 15.126249999899999, -26.199619496499999 - }; - double coords2[]= - { - 15.933240959000001, -24.132999999999999, - 15.665291765999999, -25.132999998999999, - 16.041579804000001, -25.350249998999999, - 16.367740958999999, -24.132999999999999, - 15.865092611, -24.650638091000001, - 15.853435785, -25.241624998999999, - 16.284787383000001, -24.763094964, - 16.150490958999999, -24.132999999999999 - }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,v[0]->getArea(),1e-7); - delete v[0]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,pol1->intersectWith(*pol2),1e-7); - delete pol1; - delete pol2; -} - -/*! - * Tests to avoid regressions : Basic one. - */ -void QuadraticPlanarInterpTest::checkNonRegression3() -{ - const double coords1[]= - { - 10.962340811000001, -22.417749999000002, - 12.217990959, -21.162099852000001 - }; - Node *nS1=new Node(coords1); - Node *nE1=new Node(coords1+2); - const double radius1=3.4304999897666599; - const double angleS1=2.6179938783536514; const double angleL1=-0.52359877711901204; - const double center1[2]={13.933240950441375, -24.132999992807399}; - EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); - // - const double coords2[]= - { - 11.1467942784, -22.2090000002, - 11.0939667286, -22.178500000099998 - }; - Node *nS2=new Node(coords2); - Node *nE2=new Node(coords2+2); - EdgeLin *e2=new EdgeLin(nS2,nE2); - MergePoints merge; - QuadraticPolygon c1,c2; - CPPUNIT_ASSERT(e1->intersectWith(e2,merge,c1,c2)); - CPPUNIT_ASSERT_EQUAL(2,c1.size()); - CPPUNIT_ASSERT_EQUAL(2,c2.size()); - ElementaryEdge *tmp1=dynamic_cast(c1.front()); CPPUNIT_ASSERT(tmp1); - EdgeArcCircle *tmp2=dynamic_cast(tmp1->getPtr()); CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.6179938783536514,tmp2->getAngle0(),1e-14); - //clean-up - nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::checkNonRegression4() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - double coords1[]= - { - 10.962340811000001, -22.417749999000002, - 12.217990959, -21.162099852000001, - 12.051990958999999, -20.874579418, - 10.674820377, -22.251749999000001, - 11.507511146000001, -21.707270185999999, - 12.134990959, -21.018339635, - 11.272751694, -21.472510735, - 10.818580594, -22.334749999 - }; - - double coords2[]= - { - 10.758000000199999, -23.66, - 11.1467942784, -22.2090000002, - 11.0939667286, -22.178500000099998, - 10.696999999999999, -23.66, - 10.856883252299999, -22.908907131159999, - 11.1203805035, -22.1937500001, - 10.797961776699999, -22.893119169449999, - 10.727500000099999, -23.66 - }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); - delete v[0]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression5() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - -1.7320508075000001, 1, - -1, 1.7320508075000001 , - -1.2172499999999999, 2.1083388455000001, - -2.1083388455000001, 1.2172499999999999, - -1.4142135623000001, 1.4142135623000001, - -1.108625, 1.9201948265, - -1.7214514588000001, 1.7214514588000001, - -1.9201948265, 1.108625}; - - double coords2[]= - { - -2.2379999998, 0, - -1.9381648534, 1.1189999998, - -1.9909924031999999, 1.1494999999, - -2.2989999998999999, 0, - -2.1617419990000002, 0.57923702298000002, - -1.9645786283, 1.1342499998, - -2.2206634745999998, 0.59502498461999997, - -2.2684999997999999, 0}; - //Edge1_of_pol2 inter Edge4_of_pol1 = {-1.9381648533711939, 1.1189999998498941} - //Edge4_of_pol1 _angle = -0.523598775922546, _angle0 = -3.1415926535897931, _radius = 2.2379999983074721, _center = {-1.4925279436059493e-09, 1.3300635705141101e-10}} - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); - //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); - //delete v[0]; - //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression6() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - 10.962340811000001, -22.417749999000002, - 12.217990959, -21.162099852000001, - 12.051990958999999, -20.874579418, - 10.674820377, -22.251749999000001, - 11.507511146000001, -21.707270185999999, - 12.134990959, -21.018339635, - 11.272751694, -21.472510735, - 10.818580594, -22.334749999 - }; - double coords2[]= - { 10.426, -23.66, - 10.859273844199999, -22.043000000100001, - 10.806446294799999, -22.012500000199999, - 10.3650000002, -23.66, - 10.536195877799999, -22.822979208099998, - 10.832860069499999, -22.027750000200001, - 10.477274402499999, -22.80719124657, - 10.3955000001, -23.66}; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0]->getArea(),0.0150659,1e-7); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression7() -{ - QUADRATIC_PLANAR::setPrecision(1e-5); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - -2., 0, - -1.7320508075000001, 1, - -2.1083388455000001, 1.2172499999999999, - -2.4344999999999999, 0, - -1.9318516525603098, 0.51763809027157182, - -1.9201948265, 1.108625, - -2.3515464241024469, 0.63009496529570408, - -2.2172499999999999, 0 - }; - double coords2[]= - { -2.3369999999000002, 0, - -2.0239013684999998, 1.1684999999000001, - -2.1927763221999998, 1.2659999998, - -2.5319999998, 0, - -2.2573686559260442, 0.60486010843437632, - -2.1083388453499996, 1.2172499998499999, - -2.445724191994314, 0.65532982205982326, - -2.4344999998499999, 0 }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.121795,v[0]->getArea(),1.e-6); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression8() -{ - QUADRATIC_PLANAR::setPrecision(1e-3); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - -13.933240959000001, -28.559499999, - -16.146490959000001, -27.966461449000001, - -16.383240958999998, -28.376524478, - -13.933240959000001, -29.032999999000001, - -15.078903461873765, -28.408670669106311, - -16.264865958999998, -28.1714929635, - -15.201454280317435, -28.866036547696734, - -13.933240959000001, -28.796249999 }; - double coords2[]= - { -16.382999999950002, -28.376524478457149, - -13.933000000014729, -29.03299999982551, - -13.93300000006697, -28.793999999915993, - -16.263500000000001, -28.169544407039268, - -15.201213320921273, -28.866036548734634, - -13.933000000040851, -28.913499999870751, - -15.139355569325469, -28.635180276305853, - -16.323249999975001, -28.273034442748209 }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.598232,v[0]->getArea(),1.e-6); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression9() -{ - QUADRATIC_PLANAR::setPrecision(1e-7); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-8); - double coords1[]= - { - -0.04476229252902969, -0.085118027765365603, - -0.046952683430894329, -0.085704941238358354, - -0.046952683430894329, -0.088063823748058725, - -0.043582851274179504, -0.087160879944491371, - -0.045818853668170414, -0.085555669718918592, - -0.046952683430894329, -0.086884382493208526, - -0.045208329947517549, -0.087834175256748526, - -0.044172571901604597, -0.086139453854928494 }; - - double coords2[]= - { -0.05065868681155701, -0.087744551996665671, - -0.046951871439587615, -0.088737790182236015, - -0.046951871439683469, -0.088063823751059062, - -0.050321703596054014, -0.087160879946116557, - -0.0488706602695924, -0.08848517684025306, - -0.046951871439635542, -0.088400806966647538, - -0.048696224921445964, -0.087834175258503858, - -0.050490195203805516, -0.087452715971391121}; - - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression10() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[]= - { -0.002269581957210453, -0.09851030343724453, - -0.004268022334182935, -0.1059685844580936, - -0.002777851483521377, -0.1023709937816271}; - double coords2[]= - { -0.004114727297178323, -0.1049870239624718, - -0.003544545103522544, -0.1053162188055505}; - Node *n1_1=new Node(coords1); - Node *n2_1=new Node(coords1+2); - Node *n3_1=new Node(coords1+4); - Node *n1_2=new Node(coords2); - Node *n2_2=new Node(coords2+2); - EdgeArcCircle *e1=new EdgeArcCircle(n1_1,n3_1,n2_1); - EdgeLin *e2=new EdgeLin(n1_2,n2_2); - MergePoints merge; - ComposedEdge *c1=new ComposedEdge; - ComposedEdge *c2=new ComposedEdge; - CPPUNIT_ASSERT(e1->intersectWith(e2,merge,*c1,*c2)); - CPPUNIT_ASSERT_EQUAL(2,c1->size()); - CPPUNIT_ASSERT_EQUAL(2,c2->size()); - ComposedEdge::Delete(c1); ComposedEdge::Delete(c2); - n1_1->decrRef(); n2_1->decrRef(); n3_1->decrRef(); - n1_2->decrRef(); n2_2->decrRef(); - e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::checkNonRegression11() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[]= - { -0.002269581957210453, -0.09851030343724453, - -0.004268022334182935, -0.1059685844580936, - -0.002886178753789801, -0.1067663922211958, - -0.0006739664310059821, -0.09851030343724453, - -0.002777851483521377, -0.1023709937816271, - -0.003577100543986368, -0.1063674883396447, - -0.001236605237717319, -0.1027839694676665, - -0.001471774194108217, -0.09851030343724453}; - double coords2[]= - { -0.003544545103522544, -0.1053162188055505, - -0.001941023322604723, -0.09851030343724451, - -0.002598140593501099, -0.09851030343724451, - -0.004114727297178323, -0.1049870239624718, - -0.002347317802266182, -0.1020064358043286, - -0.002269581958052911, -0.09851030343724451, - -0.002982346712452072, -0.1018362598405457, - -0.003829636200350435, -0.1051516213840111}; - - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.28973e-06,v[0]->getArea(),1.e-11); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression12() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-6); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[]= - { -0.5032251558760915, -0.8716087994449138, - -0.4695268343089433, -0.8806382374805872, - -0.4695268343089433, -0.8570494123835835, - -0.4914307433275896, -0.8511802776536561, - -0.4869703691141082, -0.8783417525751493, - -0.4695268343089433, -0.8688438249320853, - -0.480865131947653, -0.8555566971861125, - -0.4973279496018406, -0.8613945385492849}; - - double coords2[]= - { -0.5065868681155701, -0.8774455199666568, - -0.4695187143958762, -0.8873779018223601, - -0.4695187143968347, -0.8806382375105907, - -0.5032170359605401, -0.8716087994611657, - -0.488706602695924, -0.8848517684025307, - -0.4695187143963554, -0.8840080696664754, - -0.4869622492144596, -0.8783417525850385, - -0.5049019520380551, -0.8745271597139112}; - - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v[0]->getArea(),1.e-6); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression13() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); - - double coords_1[194]={ - 0, 0, 0.304375, -7.454791178893722e-17, 0.2152256265236553, -0.2152256265236555, -5.591093384170291e-17, -0.304375, - -0.2152256265236555, -0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, - 0.2152256265236554, 0.2152256265236554, 0.60875, -1.490958235778744e-16, 0.5624116654162459, -0.2329585394522483, 0.4304512530473107, -0.4304512530473109, - 0.2329585394522485, -0.5624116654162458, -1.118218676834058e-16, -0.60875, -0.2329585394522482, -0.5624116654162459, -0.4304512530473109, -0.4304512530473108, - -0.5624116654162459, -0.2329585394522483, -0.60875, 7.454791178893722e-17, -0.5624116654162458, 0.2329585394522485, -0.4304512530473108, 0.4304512530473109, - -0.2329585394522484, 0.5624116654162458, 3.727395589446861e-17, 0.60875, 0.2329585394522485, 0.5624116654162458, 0.4304512530473109, 0.4304512530473108, - 0.5624116654162458, 0.2329585394522484, 0.913125, -2.236437353668116e-16, 0.645676879570966, -0.6456768795709663, -1.677328015251087e-16, -0.913125, - -0.6456768795709663, -0.6456768795709661, -0.913125, 1.118218676834058e-16, -0.6456768795709661, 0.6456768795709662, 5.591093384170291e-17, 0.913125, - 0.6456768795709662, 0.6456768795709661, 1.2175, -2.981916471557489e-16, 1.124823330832492, -0.4659170789044966, 0.8609025060946214, -0.8609025060946218, - 0.4659170789044971, -1.124823330832492, -2.236437353668116e-16, -1.2175, -0.4659170789044965, -1.124823330832492, -0.8609025060946218, -0.8609025060946216, - -1.124823330832492, -0.4659170789044967, -1.2175, 1.490958235778744e-16, -1.124823330832492, 0.465917078904497, -0.8609025060946216, 0.8609025060946217, - -0.4659170789044967, 1.124823330832492, 7.454791178893722e-17, 1.2175, 0.4659170789044969, 1.124823330832492, 0.8609025060946217, 0.8609025060946216, - 1.124823330832492, 0.4659170789044968, 1.521875, -3.727395589446861e-16, 1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, - -1.076128132618277, -1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, - 1.076128132618277, 1.076128132618277, 1.82625, -4.472874707336233e-16, 1.687234996248738, -0.6988756183567448, 1.291353759141932, -1.291353759141933, - 0.6988756183567456, -1.687234996248737, -3.354656030502175e-16, -1.82625, -0.6988756183567447, -1.687234996248738, -1.291353759141933, -1.291353759141932, - -1.687234996248738, -0.6988756183567449, -1.82625, 2.236437353668116e-16, -1.687234996248737, 0.6988756183567454, -1.291353759141932, 1.291353759141932, - -0.6988756183567451, 1.687234996248737, 1.118218676834058e-16, 1.82625, 0.6988756183567453, 1.687234996248737, 1.291353759141932, 1.291353759141932, - 1.687234996248737, 0.6988756183567452, 2.130625, -5.218353825225606e-16, 1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, - -1.506579385665588, -1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, - 1.506579385665588, 1.506579385665588, 2.435, -5.963832943114977e-16, 2.249646661664984, -0.9318341578089931, 1.721805012189243, -1.721805012189244, - 0.9318341578089941, -2.249646661664983, -4.472874707336233e-16, -2.435, -0.9318341578089929, -2.249646661664984, -1.721805012189244, -1.721805012189243, - -2.249646661664984, -0.9318341578089934, -2.435, 2.981916471557489e-16, -2.249646661664983, 0.9318341578089939, -1.721805012189243, 1.721805012189243, - -0.9318341578089935, 2.249646661664983, 1.490958235778744e-16, 2.435, 0.9318341578089938, 2.249646661664983, 1.721805012189243, 1.721805012189243, - 2.249646661664983, 0.9318341578089936 }; - - int tab6_1[48]={ - 0, 9, 11, 1, 10, 2, 0, 11, 13, 2, 12, 3, 0, 13, 15, 3, 14, 4, 0, 15, - 17, 4, 16, 5, 0, 17, 19, 5, 18, 6, 0, 19, 21, 6, 20, 7, 0, 21, 23, 7, - 22, 8, 0, 23, 9, 8, 24, 1 }; - - int tab8_1[192]={ - 9, 33, 35, 11, 25, 34, 26, 10, 11, 35, 37, 13, 26, 36, 27, 12, 13, 37, 39, 15, - 27, 38, 28, 14, 15, 39, 41, 17, 28, 40, 29, 16, 17, 41, 43, 19, 29, 42, 30, 18, - 19, 43, 45, 21, 30, 44, 31, 20, 21, 45, 47, 23, 31, 46, 32, 22, 23, 47, 33, 9, - 32, 48, 25, 24, 33, 57, 59, 35, 49, 58, 50, 34, 35, 59, 61, 37, 50, 60, 51, 36, - 37, 61, 63, 39, 51, 62, 52, 38, 39, 63, 65, 41, 52, 64, 53, 40, 41, 65, 67, 43, - 53, 66, 54, 42, 43, 67, 69, 45, 54, 68, 55, 44, 45, 69, 71, 47, 55, 70, 56, 46, - 47, 71, 57, 33, 56, 72, 49, 48, 57, 81, 83, 59, 73, 82, 74, 58, 59, 83, 85, 61, - 74, 84, 75, 60, 61, 85, 87, 63, 75, 86, 76, 62, 63, 87, 89, 65, 76, 88, 77, 64, - 65, 89, 91, 67, 77, 90, 78, 66, 67, 91, 93, 69, 78, 92, 79, 68, 69, 93, 95, 71, - 79, 94, 80, 70, 71, 95, 81, 57, 80, 96, 73, 72 }; - - double coords_2[20]={ - 0.5159941860137611, 0, 0, -0.5159941860137611, -0.5159941860137611, 0, 0, 0.5159941860137611, - 0.6684941860137611, 0, 0, -0.6684941860137611, -0.6684941860137611, 0, 0, 0.6684941860137611, - 0.5922441860137611, 0, -0.5922441860137611, 0 }; - - int tab8_2[16]={ - 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; - - double perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2; - - const int *work1=tab6_1; - for(int i=0;i<8;i++,work1+=6) - { - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,6); - const int *work2=tab8_2; - for(int j=0;j<2;j++,work2+=8) - { - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); - //std::vector tmp; - //pol1->intersectForPoint(*pol2,tmp); - pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); - //pol1->intersectMySelfWith(*pol2); - delete pol2; - } - delete pol1; - } - work1=tab8_1; - for(int i=0;i<24;i++,work1+=8) - { - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,8); - const int *work2=tab8_2; - for(int j=0;j<2;j++,work2+=8) - { - - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); - //std::vector tmp; - //pol1->intersectForPoint(*pol2,tmp); - pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); - delete pol2; - } - delete pol1; - } -} - -/*! - Some overlapping cases for intersectForPoint. -*/ -void QuadraticPlanarInterpTest::checkNonRegression14() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); - - double coords[72]={ - 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., - -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., - -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, - 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, - -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, - -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, - -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, - -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, - 0.,-1.3,0.,-1.5 - }; - int tab[48]={ - 0,1,2,3,4,5,6,7, - 8,9,10,11,2,14,12,13, - 9,15,16,10,5,17,18,14, - 9,15,16,10,34,17,35,14, - 19,20,21,22,23,24,25,26, - 27,28,29,30,31,32,2,33 - }; - QuadraticPolygon *pol1,*pol2; - std::vector goalOfTest; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); - // Level 1 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res1[4]={0,1,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res1)); - delete pol2; - // Level 2 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res2[4]={0,2,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2)); - delete pol2; - //Level 2 bis - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+24,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res2Bis[4]={0,2,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2Bis)); - delete pol2; - // Level 3 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+40,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res3[4]={0,3,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res3)); - delete pol2; - // Level 4 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+32,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res4[4]={0,4,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res4)); - delete pol2; - // - delete pol1; -} - -/*! - * This test is one of the most complicated intersection configuration. - */ -void QuadraticPlanarInterpTest::checkNonRegression15() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); - - double coords[72]={ - 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., - -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., - -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, - 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, - -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, - -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, - -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, - -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, - 0.,-1.3,0.,-1.5 - }; - - int tab[24]={ - 0,1,2,3,4,5,6,7, - 9,15,16,10,7,17,5,14, - 9,10,16,15,14,5,17,7 - }; - - const double RefLgth=3.88995883524451; - const double RefArea=0.383185168001075; - // - QuadraticPolygon *pol1,*pol2; - //pol1 and pol2 in same orientation - pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); - std::vector res=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); - delete res[0]; - //pol1 and pol2 in same orientation but inversing intersection call pol1<->pol2 - res=pol2->intersectMySelfWith(*pol1); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); - delete res[0]; - delete pol2; - //pol1 and pol2 in opposite orientation - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); - res=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-RefArea,res[0]->getArea(),1e-12); - delete res[0]; - //pol1 and pol2 in opposite orientation but inversing intersection call pol1<->pol2 - res=pol2->intersectMySelfWith(*pol1); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); - delete res[0]; - delete pol2; - // - delete pol1; -} - -class DoubleEqual -{ -public: - DoubleEqual(double eps):_eps(eps) { } - bool operator()(double x, double y) { return fabs(x-y)<_eps; } -private: - double _eps; -}; - -/*! - * This test is to see the reuse of a polygon in intersect* methods. initLocation needed ... - */ -void QuadraticPlanarInterpTest::checkNonRegression16() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[194]={ - 0, 0, 0.304375, 0, 0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, - -0.2152256265236554, 0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236555, -0.2152256265236554, -5.591093384170291e-17, -0.304375, - 0.2152256265236553, -0.2152256265236555, 0.60875, 0, 0.5624116654162458, 0.2329585394522484, 0.4304512530473109, 0.4304512530473108, - 0.2329585394522485, 0.5624116654162458, 3.727395589446861e-17, 0.60875, -0.2329585394522484, 0.5624116654162458, -0.4304512530473108, 0.4304512530473109, - -0.5624116654162458, 0.2329585394522485, -0.60875, 7.454791178893722e-17, -0.5624116654162459, -0.2329585394522483, -0.4304512530473109, -0.4304512530473108, - -0.2329585394522482, -0.5624116654162459, -1.118218676834058e-16, -0.60875, 0.2329585394522485, -0.5624116654162458, 0.4304512530473107, -0.4304512530473109, - 0.5624116654162459, -0.2329585394522483, 0.913125, 0, 0.6456768795709662, 0.6456768795709661, 5.591093384170291e-17, 0.913125, - -0.6456768795709661, 0.6456768795709662, -0.913125, 1.118218676834058e-16, -0.6456768795709663, -0.6456768795709661, -1.677328015251087e-16, -0.913125, - 0.645676879570966, -0.6456768795709663, 1.2175, 0, 1.124823330832492, 0.4659170789044968, 0.8609025060946217, 0.8609025060946216, - 0.4659170789044969, 1.124823330832492, 7.454791178893722e-17, 1.2175, -0.4659170789044967, 1.124823330832492, -0.8609025060946216, 0.8609025060946217, - -1.124823330832492, 0.465917078904497, -1.2175, 1.490958235778744e-16, -1.124823330832492, -0.4659170789044967, -0.8609025060946218, -0.8609025060946216, - -0.4659170789044965, -1.124823330832492, -2.236437353668116e-16, -1.2175, 0.4659170789044971, -1.124823330832492, 0.8609025060946214, -0.8609025060946218, - 1.124823330832492, -0.4659170789044966, 1.521875, 0, 1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, - -1.076128132618277, 1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, - 1.076128132618277, -1.076128132618277, 1.82625, 0, 1.687234996248737, 0.6988756183567452, 1.291353759141932, 1.291353759141932, - 0.6988756183567453, 1.687234996248737, 1.118218676834058e-16, 1.82625, -0.6988756183567451, 1.687234996248737, -1.291353759141932, 1.291353759141932, - -1.687234996248737, 0.6988756183567454, -1.82625, 2.236437353668116e-16, -1.687234996248738, -0.6988756183567449, -1.291353759141933, -1.291353759141932, - -0.6988756183567447, -1.687234996248738, -3.354656030502175e-16, -1.82625, 0.6988756183567456, -1.687234996248737, 1.291353759141932, -1.291353759141933, - 1.687234996248738, -0.6988756183567448, 2.130625, 0, 1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, - -1.506579385665588, 1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, - 1.506579385665588, -1.506579385665588, 2.435, 0, 2.249646661664983, 0.9318341578089936, 1.721805012189243, 1.721805012189243, - 0.9318341578089938, 2.249646661664983, 1.490958235778744e-16, 2.435, -0.9318341578089935, 2.249646661664983, -1.721805012189243, 1.721805012189243, - -2.249646661664983, 0.9318341578089939, -2.435, 2.981916471557489e-16, -2.249646661664984, -0.9318341578089934, -1.721805012189244, -1.721805012189243, - -0.9318341578089929, -2.249646661664984, -4.472874707336233e-16, -2.435, 0.9318341578089941, -2.249646661664983, 1.721805012189243, -1.721805012189244, - 2.249646661664984, -0.9318341578089931, }; - - int tab1_8[192]={ - 11, 35, 33, 9, 26, 34, 25, 10, 13, 37, 35, 11, 27, 36, 26, 12, 15, 39, 37, 13, - 28, 38, 27, 14, 17, 41, 39, 15, 29, 40, 28, 16, 19, 43, 41, 17, 30, 42, 29, 18, - 21, 45, 43, 19, 31, 44, 30, 20, 23, 47, 45, 21, 32, 46, 31, 22, 9, 33, 47, 23, - 25, 48, 32, 24, 35, 59, 57, 33, 50, 58, 49, 34, 37, 61, 59, 35, 51, 60, 50, 36, - 39, 63, 61, 37, 52, 62, 51, 38, 41, 65, 63, 39, 53, 64, 52, 40, 43, 67, 65, 41, - 54, 66, 53, 42, 45, 69, 67, 43, 55, 68, 54, 44, 47, 71, 69, 45, 56, 70, 55, 46, - 33, 57, 71, 47, 49, 72, 56, 48, 59, 83, 81, 57, 74, 82, 73, 58, 61, 85, 83, 59, - 75, 84, 74, 60, 63, 87, 85, 61, 76, 86, 75, 62, 65, 89, 87, 63, 77, 88, 76, 64, - 67, 91, 89, 65, 78, 90, 77, 66, 69, 93, 91, 67, 79, 92, 78, 68, 71, 95, 93, 69, - 80, 94, 79, 70, 57, 81, 95, 71, 73, 96, 80, 72, }; - - double coords2[20]={ - 2.435, 0, 0, -2.435, -2.435, 0, 0, 2.435, - 2.6925, 0, 0, -2.6925, -2.6925, 0, 0, 2.6925, - 2.56375, 0, -2.56375, 0, }; - - int tab2_8[16]={ 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; - - QuadraticPolygon *pol1,*pol2; - //pol1 and pol2 in same orientation - std::vector test1,test2; - for(int ii=0;ii<24;ii++) - { - pol1=buildQuadraticPolygonCoarseInfo(coords1,tab1_8+8*ii,8); - for(int jj=0;jj<2;jj++) - { - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab2_8+jj*8,8); - // - std::vector v1,v2; - pol1->initLocations(); - pol1->intersectForPerimeterAdvanced(*pol2,v1,v2); - if(ii==16 && jj==1) - test1=v1; - if(ii==20 && jj==1) - test2=v1; - delete pol2; - } - delete pol1; - } - const double test1_res[4]={0.,1.9124445278727873,0.,0.}; - CPPUNIT_ASSERT(std::equal(test1.begin(),test1.end(),test1_res,DoubleEqual(1e-10))); - const double test2_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(test2.begin(),test2.end(),test2_res,DoubleEqual(1e-10))); -} - -/*! - * This test checks overlapped intersections END-INSIDE and INSIDE-START with same and opposite orientation. - */ -void QuadraticPlanarInterpTest::checkNonRegression17() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1., 0., 1., 0. , 1.5, 0., -1.5, 0., - 0. , 1., 1.25, 0., 0., 1.5, -1.25, 0.}; - - double coords2[16]={ - 0.70710678118654757, 0.70710678118654757, -1., 0., -1.25, 0., 0.88388347648318444, 0.88388347648318444, - 0., -1., -1.125, 0., 0., -1.25, 0.79549512883486606, 0.79549512883486606 }; - - double coords3[16]={ - 0.70710678118654757, 0.70710678118654757, 0.88388347648318444, 0.88388347648318444, -1.25, 0., -1., 0., - 0.79549512883486606, 0.79549512883486606, 0., -1.25, -1.125, 0., 0., -1. }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNormalize() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); - Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-3.); - Node *n2=new Node(10.,0.); Node *n5=new Node(10.,-3.); - Node *n3=new Node(5.,10.); Node *n6=new Node(5.,7.); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); - // - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - double area1Start=pol1.getArea(); - double xb,yb; - double fact=pol1.normalize(&pol2,xb,yb); - double area1End=pol1.getArea(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(area1Start,area1End*fact*fact,1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,fact,1.e-14); - double area=pol1.intersectWith(pol2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,area*fact*fact,1e-14); - // - n1=new Node(0.,0.); n4=new Node(0.,-3.); - n2=new Node(10.,0.); n5=new Node(10.,-3.); - n3=new Node(5.,10.); n6=new Node(5.,7.); - e1_2=new EdgeLin(n1,n2); e4_5=new EdgeLin(n4,n5); - e2_3=new EdgeLin(n2,n3); e5_6=new EdgeLin(n5,n6); - e3_1=new EdgeLin(n3,n1); e6_4=new EdgeLin(n6,n4); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - QuadraticPolygon pol4; pol4.pushBack(e4_5); pol4.pushBack(e5_6); pol4.pushBack(e6_4); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,pol3.intersectWithAbs(pol4),1.e-14); - // Ok testing EdgeArcCircle update. - double center[2]={5.,5.}; - double radius=300.; - EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); - const Bounds& b=e1->getBounds(); - double x,y,fact2; - fact2=b.getCaracteristicDim(); - b.getBarycenter(x,y); - CPPUNIT_ASSERT_DOUBLES_EQUAL(78.539816339744817,e1->getCurveLength(),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15106.061037591669,e1->getAreaOfZone(),1e-10); - e1->getStartNode()->applySimilarity(x,y,fact2); - e1->getEndNode()->applySimilarity(x,y,fact2); - e1->applySimilarity(x,y,fact2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(62.132034355964237,fact2,1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2640792652913602,e1->getCurveLength(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.034741420428165526,e1->getAreaOfZone(),1e-13); - e1->decrRef(); -} - -void QuadraticPlanarInterpTest::checkMakePartitionAbs1() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); - Node *n0=new Node(0.,0.); Node *n4=new Node(0.5,0.25); - Node *n1=new Node(0.,0.5); Node *n5=new Node(0.3,1.2); - Node *n2=new Node(1.,0.5); Node *n6=new Node(1.1,1.3); - Node *n3=new Node(1.,0.); Node *n7=new Node(-0.1,0.9); - EdgeLin *e0_1=new EdgeLin(n0,n1); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_0=new EdgeLin(n3,n0); EdgeLin *e6_4=new EdgeLin(n6,n4); - EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_5=new EdgeLin(n7,n5); - QuadraticPolygon pol1; pol1.pushBack(e0_1); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_0); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - pol2.pushBack(e7_5); e4_5->incrRef(); pol2.pushBack(new ElementaryEdge(e4_5,false)); pol2.pushBack(e4_7); - n0->decrRef(); n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); - pol1.dumpInXfigFileWithOther(pol2,"tony.fig"); -} - -} diff --git a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx b/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx deleted file mode 100644 index 615969ffb..000000000 --- a/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx +++ /dev/null @@ -1,1286 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -class DoubleEqual -{ -public: - DoubleEqual(double eps):_eps(eps) { } - bool operator()(double x, double y) { return fabs(x-y)<_eps; } -private: - double _eps; -}; - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0000() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.383022221559489, -0.1786061951567303, -0.5745333323392334, -0.01790929273509539, 0.5745333323392335, -0.01790929273509556, 0.383022221559489, -0.1786061951567304, - -0.4787777769493612, -0.0982577439459128, 4.592273826833915e-17, 0.25, 0.4787777769493612, -0.09825774394591297, 3.061515884555943e-17, 0 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0001() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0002() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, - -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0003() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3535533905932737, 0.3535533905932738, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.3535533905932738, 0.3535533905932737, - -0.4419417382415922, 0.4419417382415922, 4.592273826833915e-17, 0.75, 0.4419417382415922, 0.4419417382415922, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, - -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0004() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, - -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; - - double coords2[16]={ - -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, - -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0005() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, - -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, - -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0006() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, - -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.1811733315717646, 0.6761480784023478, -0.2070552360820167, 0.7727406610312547, 0.2070552360820166, 0.7727406610312547, 0.1811733315717645, 0.6761480784023478, - -0.1941142838268906, 0.7244443697168013, 4.898425415289509e-17, 0.8, 0.1941142838268906, 0.7244443697168013, 4.28612223837832e-17, 0.7 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.366519,0.,0.}; - double test2_res[4]={0.,0.,0.,0.366519}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0007() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, - -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4499513267805775, 0.5362311101832846, -0.5142300877492315, 0.6128355544951825, -0.1389185421335442, 0.7878462024097664, -0.1215537243668512, 0.6893654271085455, - -0.4820907072649045, 0.5745333323392335, -0.3380946093925595, 0.7250462296293201, -0.1302361332501977, 0.738605814759156, -0.2958327832184895, 0.634415450925655 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.366519,0.,0.}; - double test2_res[4]={0.,0.,0.,0.366519}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0008() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, - -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.6344154509256549, 0.2958327832184896, -0.72504622962932, 0.3380946093925596, -0.4588611490808367, 0.6553216354311937, -0.401503505445732, 0.5734064310022944, - -0.6797308402774874, 0.3169636963055246, -0.6128355544951823, 0.5142300877492316, -0.4301823272632844, 0.614364033216744, -0.5362311101832845, 0.4499513267805776 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.18326,0.,0.}; - double test2_res[4]={0.,0.,0.,0.18326}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-5))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-5))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0009() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, - -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; - double coords2[16]={ - 0.5, -1.224606353822377e-16, 0.6, -1.469527624586853e-16, -0.6, 7.347638122934263e-17, -0.5, 6.123031769111886e-17, - 0.55, -1.347066989204615e-16, -1.102145718440139e-16, -0.6, -0.55, 6.735334946023075e-17, -9.184547653667829e-17, -0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0010() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, --0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; - double coords2[16]={ - 0.4346666218300808, -0.1164685702961343, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4346666218300808, -0.1164685702961342, -0.5071110588017609, -0.1358799986788234, -1.102145718440139e-16, -0.6, -0.507111058801761, -0.1358799986788232, -8.266092888301047e-17, -0.45 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0011() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, --0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; - double coords2[16]={ - 0.4829629131445342, -0.1294095225512603, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, -0.5312592044589877, -0.1423504748063864, -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - double val1,val2,val3; - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - std::vector val4,val5; - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - double test1_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - val4.clear(); val5.clear(); - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar2511() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, - -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4, }; - - double coords2[16]={ - 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512603, - -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5, 0.5312592044589877, -0.1423504748063864, }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - double val1,val2,val3; - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - std::vector val4,val5; - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - double test1_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - val4.clear(); val5.clear(); - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0012() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 1.85, 1.224606353822377e-17, 1.95, 1.224606353822377e-17, 1.55, 6.123031769111886e-18, 1.65, - 9.18454765366783e-18, 1.9, 0.2, 1.75, 9.18454765366783e-18, 1.6, 0.1, 1.75 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.05,0.}; - double test2_res[4]={0.,0.,0.05,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,1,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0013() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 1.7, 1.224606353822377e-17, 1.8, 1.224606353822377e-17, 1.4, 6.123031769111886e-18, 1.5, - 9.18454765366783e-18, 1.75, 0.2, 1.6, 9.18454765366783e-18, 1.45, 0.1, 1.6 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.1,0.}; - double test2_res[4]={0.,0.,0.1,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,2,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0014() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, --1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - double coords2[16]={ - 6.123031769111886e-18, 1.55, 1.224606353822377e-17, 1.65, 1.224606353822377e-17, 1.25, 6.123031769111886e-18, 1.35, -9.18454765366783e-18, 1.6, 0.2, 1.45, 9.18454765366783e-18, 1.3, 0.1, 1.45 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.15,0.}; - double test2_res[4]={0.05,0.,0.1,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,3,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0015() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, --1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - double coords2[16]={ - 6.123031769111886e-18, 1.4, 1.224606353822377e-17, 1.5, 1.224606353822377e-17, 1.1, 6.123031769111886e-18, 1.2, -9.18454765366783e-18, 1.45, 0.2, 1.3, 9.18454765366783e-18, 1.15, 0.1, 1.3 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.2,0.}; - double test2_res[4]={0.1,0.,0.1,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,4,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0016() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, --1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - double coords2[16]={ - 6.123031769111886e-18, 1.25, 1.224606353822377e-17, 1.35, 1.224606353822377e-17, 0.95, 6.123031769111886e-18, 1.05, -9.18454765366783e-18, 1.3, 0.2, 1.15, 9.18454765366783e-18, 0.9999999999999999, 0.1, 1.15 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.15,0.}; - double test2_res[4]={0.1,0.,0.05,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,3,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0017() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 1.1, 1.224606353822377e-17, 1.2, 1.224606353822377e-17, 0.8, 6.123031769111886e-18, 0.9, - 9.18454765366783e-18, 1.15, 0.2, 1, 9.18454765366783e-18, 0.85, 0.1, 1 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.1,0.}; - double test2_res[4]={0.1,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,2,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0018() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 0.95, 1.224606353822377e-17, 1.05, 1.224606353822377e-17, 0.6499999999999999, 6.123031769111886e-18, 0.75, - 9.18454765366783e-18, 1, 0.2, 0.85, 9.18454765366783e-18, 0.7, 0.1, 0.85 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.05,0.}; - double test2_res[4]={0.05,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,1,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0019() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.9500000000000001, 1.836909530733566e-17, 0.8, 3.673819061467131e-17, 1.4, 0, 1.25, 0, - 0.8750000000000001, 2.755364296100349e-17, 1.1, 0.3, 1.325, 0, 1.1, 0.15 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0020() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.05000000000000002, 1.836909530733566e-17, -0.09999999999999998, 3.673819061467131e-17, 0.5, 0, 0.35, 0, - -0.02499999999999997, 2.755364296100349e-17, 0.2, 0.3, 0.425, 0, 0.2, 0.15 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0021() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -1, -0.07999999999999999, -1.15, -0.07999999999999996, -0.55, -0.08, -0.7, -0.08, - -1.075, -0.07999999999999997, -0.85, 0.22, -0.625, -0.08, -0.85, 0.06999999999999999 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.162251,0.151523,0.,0.}; - double test2_res[4]={0.,0.311383,0.,0.0978193}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={2,2,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} -void QuadraticPlanarInterpTest::checkNonRegressionOmar0022() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.15, -0.07999999999999999, 0, -0.07999999999999996, 0.6, -0.08, 0.45, -0.08, - 0.07500000000000001, -0.07999999999999997, 0.3, 0.22, 0.5249999999999999, -0.08, 0.3, 0.06999999999999999 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0023() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5, }; - - double coords2[16]={ - 0.4156854249492381, 0.5656854249492381, 0.2656854249492381, 0.5656854249492381, 0.8656854249492381, 0.5656854249492381, 0.7156854249492381, 0.5656854249492381, - 0.3406854249492381, 0.5656854249492381, 0.5656854249492381, 0.8656854249492381, 0.7906854249492381, 0.5656854249492381, 0.5656854249492381, 0.7156854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0024() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, --0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - double coords2[16]={ - 0.5656854249492381, 0.5656854249492381, 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, -0.4906854249492382, 0.5656854249492381, 0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar2524() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, --0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - double coords2[16]={ - 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, 0.5656854249492381, 0.5656854249492381, -0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381, 0.4906854249492382, 0.5656854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0025() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.715685424949238, 0.5656854249492381, 0.565685424949238, 0.5656854249492381, 1.165685424949238, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, - 0.6406854249492381, 0.5656854249492381, 0.8656854249492381, 0.8656854249492381, 1.090685424949238, 0.5656854249492381, 0.8656854249492381, 0.7156854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0026() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - 0.1, 0.95, 0.2, 0.95, -0.2, 0.95, -0.1, 0.95, - 0.15, 0.95, 1.224606353822377e-17, 0.75, -0.15, 0.95, 6.123031769111886e-18, 0.85 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0027() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.1, 0.7, -0.2, 0.7, 0.2, 0.7, 0.1, 0.7, - -0.15, 0.7, 1.224606353822377e-17, 0.8999999999999999, 0.15, 0.7, 6.123031769111886e-18, 0.7999999999999999 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.222704,0.,0.}; - double test2_res[4]={0.1,0.0465335,0.1,0.092554}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,4,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0028() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.07071067811865477, 0.4792893218813453, -0.1414213562373095, 0.4085786437626905, 0.1414213562373095, 0.6914213562373095, 0.07071067811865477, 0.6207106781186548, - -0.1060660171779822, 0.4439339828220179, -0.1414213562373095, 0.6914213562373096, 0.1060660171779822, 0.6560660171779822, -0.07071067811865475, 0.6207106781186548 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.1,0.628319,0.1,0.314159}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0029() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.07071067811865477, 0.1292893218813453, -0.1414213562373095, 0.05857864376269051, 0.1414213562373095, 0.3414213562373095, 0.07071067811865477, 0.2707106781186548, - -0.1060660171779822, 0.09393398282201787, -0.1414213562373095, 0.3414213562373095, 0.1060660171779822, 0.3060660171779822, -0.07071067811865475, 0.2707106781186548 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,0,1}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0030() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.4889087296526012, 0.3889087296526012, -0.5889087296526012, 0.3889087296526012, -0.1889087296526012, 0.3889087296526012, -0.2889087296526012, 0.3889087296526012, - -0.5389087296526012, 0.3889087296526012, -0.3889087296526012, 0.5889087296526012, -0.2389087296526012, 0.3889087296526012, -0.3889087296526012, 0.4889087296526012 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.1,0.628319,0.1,0.314159}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkIsInOrOut() -{ - double coords[8]={ 0.30662641093707971, -0.47819928619088981, - -0.47819928619088964, 0.30662641093707987, - 0.0, 0.0, - 0.4, 0.4 - }; - coords[4] = (coords[0] + coords[2]) / 2.0; - coords[5] = (coords[1] + coords[3]) / 2.0; - - int tab4[4]={ 0, 1, 2, 3}; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab4,4); - Node * n = new Node(0.3175267678416348, -0.4890996430954449); - - CPPUNIT_ASSERT(! pol1->isInOrOut(n)); // node should be out - n->decrRef(); - delete pol1; -} - -void QuadraticPlanarInterpTest::checkGetMiddleOfPoints() -{ - { // from testIntersect2DMeshWith1DLine6() - double p1[] = {0.51641754716735844, 2.0}; - double p2[] = {0.0, 1.0}; - double e_center[] = {-0.71, 2.0}; - double mid[] = {0.0,0.0}; // out - double mide[] = {0.0,0.0}; // expected - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 1.2264175471673588, -0.9533904350433241, 0.95339043504332388); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.37969180470645592, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.4372640310451197, mid[1], 1.e-7); - - e.getMiddleOfPoints(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.37969180470645592, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.4372640310451197, mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } - { // from testSwig2Intersect2DMeshWith1DLine11() - double p1[] = {-1., 0.23453685964236054}; - double p2[] = {-0.23453685964235979, 1.0}; - double e_center[] = {-4.85, 4.85}; - double mid[] = {0.0,0.0}; // out - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 6.0104076400856474, -0.69522150912422953, -0.18035330854643861); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.6, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6, mid[1], 1.e-7); - - e.getMiddleOfPoints(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.6, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6, mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } - { // from testSwig2Intersect2DMeshWith1DLine11() - double p1[] = {-0.1303327636866019, -1.0}; - double p2[] = {-1.0, -0.1303327636866019}; - double e_center[] = {-1.9833333333333298, -1.9833333333333298}; - double mid[] = {0.0,0.0}; // out - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 2.0977501175200861, 1.0829141821052615, -0.59503203741562627); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[1], 1.e-7); - - e.getMiddleOfPoints(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } -} - -void QuadraticPlanarInterpTest::checkGetMiddleOfPointsOriented() -{ - { // from testSwig2Colinearize2D3() - double p1[] = {-0.70710678118654746, 0.70710678118654757}; - double p2[] = {-0.70710678118654768, -0.70710678118654746}; - double e_center[] = {0., 0.}; - double mid[] = {0.0,0.0}; // out - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 1.0, -0.7853981633974485, -1.5707963267948966); - - e.getMiddleOfPointsOriented(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1., mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); - - e.getMiddleOfPointsOriented(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } -} - -} diff --git a/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx b/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx deleted file mode 100644 index 185b9accd..000000000 --- a/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx +++ /dev/null @@ -1,1053 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "SingleElementPlanarTests.hxx" -#include "InterpolationUtils.hxx" -#include "PolygonAlgorithms.hxx" -#include "PolygonAlgorithms.txx" -#include "InterpolationPlanarTestSuite.hxx" -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - const double _Epsilon = 1.e-12; - const double _Precision = 1.e-12; - const double _losange1[8] = { 1,0, 0,1, -1,0, 0,-1 }; - const double _losange2[8] = { 2,0, 1,1, 0,0, 1,-1 }; - const double _losange3[8] = {2.5,0.5,1.5,1.5,0.5,0.5,1.5,-0.5 }; - const double _square1[8] = { -1,-1, -1,1, 1,1, 1,-1}; - const double _square2[8] = {1,-0.25,0,-0.25,0,0.25,1,0.25 }; - const double _losange4[8] = { 3,0, 2,1, 1,0, 2,-1 }; - const double _losange5[8] = { 1.5,0, 0,1.5,-1.5,0, 0,-1.5 }; - const double _losange6[12]= { 2,0, 1,1, 0.5,0.5,0,0, 0.5,-0.5, 1,-1 }; - const double _losange7[10]= { 1,0, 0,1, -1,0, 0,-1, 0.5,-0.5 }; - const double _square3[10] = { -1,-1, -1,1, 0.5,1, 1,1, 1,-1, }; - const double _square4[8] = {-0.5,-1,-0.5,1,1.5,1,1.5,-1 }; - const double _square5[10] = { -1,-1, -1,1, 0,1, 1,1, 1,-1 }; - const double _losange8[8] = { 0,1, 1,-1, 0,-1.5,-0.5,-1 }; - const double _losange9[8] = {0.5,0, 0,1, -1.5,0, 0,-1 }; - const double _hexagon1[12]= { -2,0, -1,-1, 1,-1, 2,0, 1,1, -1,1 }; - const double _hexagon2[12]= {-1.5,0.5,-1,-1, 1,-1, 2,1, 1,1, -1,1 }; - const double _hexagon3[12]= { -2,2, -1,1, 1,1, 2,2, 1,3, -1,3 }; - const double _square6[8] = { -1,1, -1,3, 0.5,3,0.5,1 }; - const double _losange10[8]= { 0,-1, 1,-2, 0,-3, -1,-2 }; - const double _triangle1[6]= {0.5,0, 1,1, 0,1 }; - const double _triangle2[6]= { 0,0.5, 0,-0.5,1.5,0 }; - const double _triangle3[9]= {-1,2,0, 1,2,0, 0,2,1 }; - const double _triangle4[9]= {1./2,2,0, 1, 2, 1, 1, 2, 0.5 }; - const double _parallel1[8] = {-1,0, -0.5,1, 0.5,1, 0,0}; - const double _parallel2[8]= {-0.5,1, 0,0, 1.,0, 0.5,1 }; - const double _parallel3[8]= {-0.5,-1, 0,0, 1,0, 0.5,-1}; - const double _triangle5[6]= { 0,0, 0,0.5, 0.5,0.5 }; - const double _triangle6[6]= { 1./3,1./3, 1./3,2./3, 2./3,2./3 }; - const double _triangle7[6]= {0.5,2, 1,1, 0,1 }; - const double _triangle8[6]= {22.4601,35.2129, 13.9921,34.693, 18.2853,26.2812 }; - const double _triangle9[6]= {13.9921,34.693, 22.4601,35.2129, 18.2785,42.3869 }; - const double _triangle10[6]= {84.8575,98.2042, 80,100, 82.2601,95.7202}; - const double _triangle11[6]= {80,100, 76.6659,91.9804, 85.3912,92.5061 }; - - // Two diamonds intersecting without degeneracy (two distinct crossing points) - // /\ /\ - // / \/ \ - // / /\ \ - // / / \ \ - // \ \ / / - // \ \/ / - // \ /\ / - // \/ \/ - - - // \brief Status : pass - void SingleElementPlanarTests::diamondsBasic() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange2,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(-0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(1);expected_result.push_back(0); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - void SingleElementPlanarTests::diamondsBasic_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange2,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(-0.5); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - - // Two diamonds with overlapping edges in an exclusion configuration - // /\ - // / \ - // /\ / \ - // / \/ \ - // / \ / - // / \ / - // \ /\ / - // \ / \/ - // \ / - // \/ - // \brief Status : pass - void SingleElementPlanarTests::tangentDiamonds() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange3,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::tangentDiamonds_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange3,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(1);expected_result.push_back(0); - - CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent squares with overlapping edges, in an inclusion configuration - // _____________ - // | | - // | _______| - // | | | - // | |_______| - // | | - // |_____________| - - // \brief Status : pass - void SingleElementPlanarTests::tangentSquares() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square2,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(0.25); - expected_result.push_back(0.);expected_result.push_back(-0.25); - expected_result.push_back(1.);expected_result.push_back(-0.25); - expected_result.push_back(1.);expected_result.push_back(0.25); - - CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::tangentSquares_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square2,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(0.25); - expected_result.push_back(0.25);expected_result.push_back(0.25); - expected_result.push_back(1./6);expected_result.push_back(1./6); - expected_result.push_back(0.);expected_result.push_back(0.25); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(-0.25); - expected_result.push_back(1.);expected_result.push_back(-0.25); - - CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two diamonds sharing a vertex in an exclusion configuration - // /\ /\ - // / \ / \ - // / \ / \ - // / \/ \ - // \ /\ / - // \ / \ / - // \ / \ / - // \/ \/ - - - // \brief Status : pass - void SingleElementPlanarTests::diamondsSharingVertex1() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange4,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Diamond sharing (1) vertex test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::diamondsSharingVertex1_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange4,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Diamonds sharing (1) vertex test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two identical squares - // _____________ - // | | - // | | - // | | - // | | - // | | - // |_____________| - - // \brief Status : pass - void SingleElementPlanarTests::identicalSquares() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - /* - ////////////////// TEST DESACTIVATED by A. GEAY because memory fault : - // conditional jump INTERP_KERNEL::PolygonAlgorithms<2>::intersectConvexPolygons(double const*, double const*, int, int) (PolygonAlgorithms.txx:629) - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square1,4,4); - std::deque< double > expected_result; - - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - */ - } - void SingleElementPlanarTests::identicalSquares_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square1,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Square and diamond intersecting with no degeneracy - // /\ - // / \ - // / \ - // __/______\__ - // | / \ | - // |/ \| - // / \ - // /| |\ - // \| |/ - // \ / - // |\ /| - // |_\________/_| - // \ / - // \ / - // \ / - // \/ - // \brief Status : pass - void SingleElementPlanarTests::squareAndDiamondBasic() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange5,4,4); - std::deque< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(0.5); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(0.5); - expected_result.push_back(-1.);expected_result.push_back(-0.5); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-0.5); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::squareAndDiamondBasic_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange5,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(0.); - expected_result.push_back(1.);expected_result.push_back(0.5); - expected_result.push_back(0.75);expected_result.push_back(0.75); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(0.5); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(-1.);expected_result.push_back(-0.5); - expected_result.push_back(-0.75);expected_result.push_back(-0.75); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-0.5); - - - // EAP: different place of (0,0) point on 32 and 64-bits platforms - // we comment it for the sake of "make check" to pass - //CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION), maybe not significant (0,0) should be removed", - //(INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // square and diamond intersecting at four degenerated pointss - // ______ - // | /\ | - // | / \ | - // |/ \| - // |\ /| - // | \ / | - // |__\/__| - // \brief Status : pass - - void SingleElementPlanarTests::squareAndDiamondCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange1,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(1.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::squareAndDiamondCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange1,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(-0.5);expected_result.push_back(-0.5); - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(0.); - - // 0020208: Unit Test of MED failed -// CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION) maybe not significant (0,0) should be removed", -// (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Two diamonds intersecting at one vertex on edge and one double vertex - // /\ /\ - // / \ / \ - // / ¤ \ - // / / \ \ - // \ \ / / - // \ * / - // \ / \ / - // \/ \/ - - - // \brief Status : pass - void SingleElementPlanarTests::diamondsCritical() - { - - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange6,_losange7,6,5); - std::deque< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(-0.5); - expected_result.push_back(0.5);expected_result.push_back(-0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(1);expected_result.push_back(0); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::diamondsCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange6,_losange7,6,5,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(-0.5); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent squares with starting and ending vertices on edges - // _____ ___.___ ______ - // | | | | - // | | | | - // | | | | - // | | | | - // | | | | - // |_____|_______|______| - - // \brief Status : pass - void SingleElementPlanarTests::quadranglesCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square4,_square3,4,5); - std::deque< double > expected_result; - - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::quadranglesCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square4,_square3,4,5,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(0.5); - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(-1./3); - expected_result.push_back(-0.5);expected_result.push_back(-0.5); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - - // square and diamond crossing and tangency at double vertices, starting vertex on edge - // _____.____ - // | / \ | - // | / \ | - // | / \ | - // |_/_______\| - // \ / - // \ / - // \ / - // \ / - // \brief Status : pass - void SingleElementPlanarTests::quadrangleAndDiamondCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square5,_losange8,5,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::quadrangleAndDiamondCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square5,_losange8,5,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1./3);expected_result.push_back(1./3); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(-1./3);expected_result.push_back(-1./3); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(0.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } // square and diamond intersecting at four degenerated pointss - // - // ²/²\ - // ² / ² \ - // ² / ² \ - // ² \ ² / - // ² \ ² / - // ²\²/ - // \brief Status : pass - - void SingleElementPlanarTests::diamondsCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange9,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::diamondsCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange9,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(0.5);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent hexagons with double vertices and a critical starting vertex on edge - // _________ - // / \²²² - // ² \² - // / \ - // / ² ² \ - // \ / - // \ ² ² / - // \ / - // \²_______²/ - - - // \brief Status : pass - void SingleElementPlanarTests::hexagonsCritical1() - { - - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon2,6,6); - std::deque< double > expected_result; - - expected_result.push_back(5./3);expected_result.push_back(1./3); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(-1.5);expected_result.push_back(0.5); - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::hexagonsCritical1_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon2,6,6,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(-1.5);expected_result.push_back(0.5); - expected_result.push_back(-8./7);expected_result.push_back(2./7); - expected_result.push_back(-1.4);expected_result.push_back(0.2); - expected_result.push_back(-4./3);expected_result.push_back(0.); - expected_result.push_back(-2./3);expected_result.push_back(0.); - expected_result.push_back(-1.25);expected_result.push_back(-0.25); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.5);expected_result.push_back(0.); - expected_result.push_back(5./3);expected_result.push_back(1./3); - expected_result.push_back(1.125);expected_result.push_back(0.875); - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(0.25);expected_result.push_back(0.75); - - CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent hexagons with double vertices and a critical starting vertex on edge - // _______ - // / \ - // / \ - // \ / - // \_______/ - // / \ - // / \ - // \ / - // \_______/ - - - // \brief Status : pass - void SingleElementPlanarTests::hexagonsCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon3,6,6); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::hexagonsCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon3,6,6,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Square and quadrilateron with outer tangency - // ________ - // | | - // | | - // | | - // |________|___ - // | | - // | | - // | | - // | | - // | | - // |____________| - - // \brief Status : pass - void SingleElementPlanarTests::squareAndQuadrangleCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square6,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::squareAndQuadrangleCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square6,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Two diamonds sharing a vertex in an exclusion configuration - // /\ - // / \ - // / \ - // / \ - // \ / - // \ / - // \ / - // \/ - // /\ - // / \ - // / \ - // / \ - // \ / - // \ / - // \ / - // \/ - - - // \brief Status : pass - void SingleElementPlanarTests:: diamondsSharingVertex2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange10,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests:: diamondsSharingVertex2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange10,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(0.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Triangle and diamond with a critical crossing at double starting vertex - // ____ - // /|\ / - // / | \/ - // / | /\ - // / |/ \ - // \ / - // \ / - // \ / - // \ / - - // \brief Status : pass - void SingleElementPlanarTests:: triangleAndDiamondCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_triangle1,4,3); - std::deque< double > expected_result; - - expected_result.push_back(2./3);expected_result.push_back(1./3); - expected_result.push_back(0.5);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests:: triangleAndDiamondCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_triangle1,4,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(2./3);expected_result.push_back(1./3); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Basic triangle and square intersection (two distinct points) - // __________ - // | | - // | |\ | - // | | \| - // | | \ - // | | |\ - // | | |/ - // | | / - // | | /| - // | |/ | - // |__________| - - // \brief Status : pass - void SingleElementPlanarTests::triangleAndSquareBasic() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_triangle2,4,3); - std::deque< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(1./6); - expected_result.push_back(1.);expected_result.push_back(-1./6); - expected_result.push_back(0.);expected_result.push_back(-0.5); - expected_result.push_back(0.);expected_result.push_back(0.5); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - void SingleElementPlanarTests::triangleAndSquareBasic_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_triangle2,4,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(1./6); - expected_result.push_back(0.375);expected_result.push_back(0.375); - expected_result.push_back(0.);expected_result.push_back(0.5); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(-0.5); - expected_result.push_back(1.);expected_result.push_back(-1./6); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Two triangles with a starting vertex on edge - - // /\ ²²²² - // / ² ² - // / ² ² - // /__²___\ - - // \brief Status : pass - void SingleElementPlanarTests::trianglesCritical() - { - INTERP_KERNEL::PolygonAlgorithms<3> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle3,_triangle4,3,3); - std::deque< double > expected_result; - - expected_result.push_back(2./3);expected_result.push_back(2.);expected_result.push_back(1./3); - expected_result.push_back(0.5);expected_result.push_back(2.);expected_result.push_back(0.); - expected_result.push_back(0.75);expected_result.push_back(2.);expected_result.push_back(0.25); - - CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,3>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesCritical_Triangulation() - { - std::vector< double > actual_result; - double _triangle3rotated[6],_triangle4rotated[6]; - for (int i=0; i<3; i++)_triangle3rotated[2*i] = _triangle3[3*i]; - for (int i=0; i<3; i++)_triangle3rotated[2*i+1] = _triangle3[3*i+2]; - for (int i=0; i<3; i++)_triangle4rotated[2*i] = _triangle4[3*i]; - for (int i=0; i<3; i++)_triangle4rotated[2*i+1] = _triangle4[3*i+2]; - - INTERP_KERNEL::intersec_de_polygone<2>(_triangle3rotated,_triangle4rotated,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(0.); - expected_result.push_back(2./3);expected_result.push_back(1./3); - expected_result.push_back(0.75);expected_result.push_back(0.25); - - CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent paralellograms intersecting at 3 double vertices (one being a starting vertex) - // _______ - // /\ /\ - // / \ / \ - // / \ / \ - // /______\/______\ - - - // \brief Status : pass - void SingleElementPlanarTests::paralellogramsCritical1() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel2,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::paralellogramsCritical1_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel2,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.25);expected_result.push_back(0.5); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(2./3); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-0.25);expected_result.push_back(0.5); - expected_result.push_back(0.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two paralellograms sharing a vertex in an exclusion configuration - // ________ - // / / - // / / - // / / - // /_______/_______ - // / / - // / / - // / / - // /_______/ - - - // \brief Status : pass - void SingleElementPlanarTests::paralellogramsCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel3,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::paralellogramsCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel3,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two triangles in a tangency configuration with a starting vertex on edge - - // _____ - // | / - // __|___/ - // | | / - // | | / - // | |/ - // | / - // | / - // |/ - - // \brief Status : pass - void SingleElementPlanarTests::trianglesTangencyCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle5,_triangle6,3,3); - std::deque< double > expected_result; - - expected_result.push_back(1./3);expected_result.push_back(1./2); - expected_result.push_back(1./3);expected_result.push_back(1./3); - expected_result.push_back(1./2);expected_result.push_back(1./2); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle5,_triangle6,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1./3);expected_result.push_back(1./2); - expected_result.push_back(1./2);expected_result.push_back(1./2); - expected_result.push_back(1./3);expected_result.push_back(1./3); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two triangles with double starting point in an outer tangency configuration - // /\ - // / \ - // / \ - // /______\ - // \ / - // \ / - // \ / - // \/ - - - // \brief Status : pass - void SingleElementPlanarTests::trianglesTangencyCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle1,_triangle7,3,3); - std::deque< double > expected_result; - - // if(!checkDequesEqual(actual_result,expected_result, _Epsilon)) - // { - // std::cerr<< "CPP_UNIT expected result= " << std::endl; - // dequePrintOut(expected_result); - // std::cerr<< "CPP_UNIT actual result= " << std::endl; - // dequePrintOut(actual_result); - // } - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle1,_triangle7,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(1.); - - // if(!checkVectorsEqual(actual_result,expected_result, _Epsilon)) - // { - // cerr<< "CPP_UNIT expected result= " << endl; - // vectPrintOut(expected_result); - // cerr<< "CPP_UNIT actual result= " << endl; - // vectPrintOut(actual_result); - // } - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // \brief Status : pass - void SingleElementPlanarTests::trianglesTangencyCritical3() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle8,_triangle9,3,3); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical3_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle8,_triangle9,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(22.4601);expected_result.push_back(35.2129); - expected_result.push_back(13.9921);expected_result.push_back(34.693); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical4() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle10,_triangle11,3,3); - - std::deque< double > expected_result; - expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); - expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); - expected_result.push_back(80);expected_result.push_back(100.); - - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical4_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle10,_triangle11,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(80);expected_result.push_back(100.); - expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); - expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - -} diff --git a/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx b/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx deleted file mode 100644 index 446781f24..000000000 --- a/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ -#define __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ - -#include "InterpKernelTestExport.hxx" -#include "InterpolationPlanarTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting simple meshes having only one planar element each. - * This serves mainly to verify that the volume calculations between elements is correct. - * - */ - class INTERPKERNELTEST_EXPORT SingleElementPlanarTests : public InterpolationPlanarTestSuite - { - CPPUNIT_TEST_SUITE( SingleElementPlanarTests ); - - CPPUNIT_TEST( diamondsBasic ); - CPPUNIT_TEST( tangentDiamonds ); - CPPUNIT_TEST( tangentSquares ); - CPPUNIT_TEST( diamondsSharingVertex1 ); - CPPUNIT_TEST( identicalSquares ); - CPPUNIT_TEST( squareAndDiamondBasic ); - CPPUNIT_TEST( squareAndDiamondCritical ); - CPPUNIT_TEST( diamondsCritical ); - CPPUNIT_TEST( quadranglesCritical ); - CPPUNIT_TEST( quadrangleAndDiamondCritical ); - CPPUNIT_TEST( diamondsCritical2 ); - CPPUNIT_TEST( hexagonsCritical1 ); - CPPUNIT_TEST( hexagonsCritical2 ); - CPPUNIT_TEST( squareAndQuadrangleCritical ); - CPPUNIT_TEST( diamondsSharingVertex2 ); - CPPUNIT_TEST( triangleAndDiamondCritical ); - CPPUNIT_TEST( triangleAndSquareBasic ); - CPPUNIT_TEST( trianglesCritical ); - CPPUNIT_TEST( paralellogramsCritical1 ); - CPPUNIT_TEST( paralellogramsCritical2 ); - CPPUNIT_TEST( trianglesTangencyCritical ); - CPPUNIT_TEST( trianglesTangencyCritical2 ); - CPPUNIT_TEST( trianglesTangencyCritical3 ); - CPPUNIT_TEST( trianglesTangencyCritical4 ); - CPPUNIT_TEST( diamondsBasic_Triangulation ); - CPPUNIT_TEST( tangentDiamonds_Triangulation ); - CPPUNIT_TEST( tangentSquares_Triangulation ); - CPPUNIT_TEST( diamondsSharingVertex1_Triangulation ); - CPPUNIT_TEST( identicalSquares_Triangulation ); - //CPPUNIT_TEST( squareAndDiamondBasic_Triangulation ); - //CPPUNIT_TEST( squareAndDiamondCritical_Triangulation ); - CPPUNIT_TEST( diamondsCritical_Triangulation ); - CPPUNIT_TEST( quadranglesCritical_Triangulation ); - CPPUNIT_TEST( quadrangleAndDiamondCritical_Triangulation ); - CPPUNIT_TEST( diamondsCritical2_Triangulation ); - CPPUNIT_TEST( hexagonsCritical1_Triangulation ); - CPPUNIT_TEST( hexagonsCritical2_Triangulation ); - CPPUNIT_TEST( squareAndQuadrangleCritical_Triangulation ); - CPPUNIT_TEST( diamondsSharingVertex2_Triangulation ); - CPPUNIT_TEST( triangleAndDiamondCritical_Triangulation ); - CPPUNIT_TEST( triangleAndSquareBasic_Triangulation ); - CPPUNIT_TEST( trianglesCritical_Triangulation ); - CPPUNIT_TEST( paralellogramsCritical1_Triangulation ); - CPPUNIT_TEST( paralellogramsCritical2_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical2_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical3_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical4_Triangulation ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - void diamondsBasic(); - void tangentDiamonds(); - void tangentSquares(); - void diamondsSharingVertex1(); - void identicalSquares(); - void squareAndDiamondBasic(); - void squareAndDiamondCritical(); - void diamondsCritical(); - void quadranglesCritical(); - void quadrangleAndDiamondCritical(); - void diamondsCritical2(); - void hexagonsCritical1(); - void hexagonsCritical2(); - void squareAndQuadrangleCritical(); - void diamondsSharingVertex2(); - void triangleAndDiamondCritical(); - void triangleAndSquareBasic(); - void trianglesCritical(); - void paralellogramsCritical1(); - void paralellogramsCritical2(); - void trianglesTangencyCritical(); - void trianglesTangencyCritical2(); - void trianglesTangencyCritical3(); - void trianglesTangencyCritical4(); - void diamondsBasic_Triangulation(); - void tangentDiamonds_Triangulation(); - void tangentSquares_Triangulation(); - void diamondsSharingVertex1_Triangulation(); - void identicalSquares_Triangulation(); - void squareAndDiamondBasic_Triangulation(); - void squareAndDiamondCritical_Triangulation(); - void diamondsCritical_Triangulation(); - void quadranglesCritical_Triangulation(); - void quadrangleAndDiamondCritical_Triangulation(); - void diamondsCritical2_Triangulation(); - void hexagonsCritical1_Triangulation(); - void hexagonsCritical2_Triangulation(); - void squareAndQuadrangleCritical_Triangulation(); - void diamondsSharingVertex2_Triangulation(); - void triangleAndDiamondCritical_Triangulation(); - void triangleAndSquareBasic_Triangulation(); - void trianglesCritical_Triangulation(); - void paralellogramsCritical1_Triangulation(); - void paralellogramsCritical2_Triangulation(); - void trianglesTangencyCritical_Triangulation(); - void trianglesTangencyCritical2_Triangulation(); - void trianglesTangencyCritical3_Triangulation(); - void trianglesTangencyCritical4_Triangulation(); - }; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/SingleElementTetraTests.hxx b/medtool/src/INTERP_KERNELTest/SingleElementTetraTests.hxx deleted file mode 100644 index 023b7a2ab..000000000 --- a/medtool/src/INTERP_KERNELTest/SingleElementTetraTests.hxx +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __SINGLE_ELEMENT_TETRA_TESTS_HXX_ -#define __SINGLE_ELEMENT_TETRA_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting simple meshes having only one element each. This serves mainly to verify that - * the volume calculations between elements is correct. - * - */ - class SingleElementTetraTests : public InterpolationTestSuite<3,3> - { - CPPUNIT_TEST_SUITE( SingleElementTetraTests ); - - CPPUNIT_TEST( tetraReflexiveUnit ); - CPPUNIT_TEST( tetraReflexiveGeneral ); - CPPUNIT_TEST( tetraNudgedSimpler ); - CPPUNIT_TEST( tetraNudged ); - CPPUNIT_TEST( tetraCorner ); - CPPUNIT_TEST( tetraSimpleIncluded ); - CPPUNIT_TEST( tetraDegenEdge ); - CPPUNIT_TEST( tetraDegenFace ); - CPPUNIT_TEST( tetraDegenTranslatedInPlane ); - CPPUNIT_TEST( tetraHalfstripOnly ); - CPPUNIT_TEST( tetraHalfstripOnly2 ); - CPPUNIT_TEST( tetraSimpleHalfstripOnly ); - CPPUNIT_TEST( generalTetra ); - CPPUNIT_TEST( trickyTetra1 ); - // CPPUNIT_TEST( inconsistentTetra ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - /// Unit tetrahedron mesh intersecting itself - /// \brief Status : pass - void tetraReflexiveUnit() - { - _testTools->intersectMeshes("UnitTetra", "UnitTetra", 1.0/6.0); - } - - /// Tetrahedron mesh with itself - /// \brief Status : pass - void tetraReflexiveGeneral() - { - _testTools->intersectMeshes("GeneralTetra", "GeneralTetra", 0.428559); - } - - /// Unit tetrahedron mesh intersecting slightly displaced copy of itself - /// \brief Status : pass - void tetraNudged() - { - _testTools->intersectMeshes("UnitTetra", "NudgedTetra", 0.142896); - } - - /// Single-element unit tetrahedron mesh intersecting even slightly displaced (along one axis only) copy of itself - /// \brief Status : pass - void tetraNudgedSimpler() - { - _testTools->intersectMeshes("UnitTetra", "NudgedSimpler", 0.152112); - } - - /// Tetrahedron intersecting unit tetrahedron with in non-degenerate way around corner O - /// \brief Status : pass - void tetraCorner() - { - _testTools->intersectMeshes("UnitTetra", "CornerTetra", 0.0135435); - } - - /// Tetrahedron situated totally inside another - /// \brief Status : pass - void tetraSimpleIncluded() - { - _testTools->intersectMeshes("SimpleIncludedTetra", "SimpleIncludingTetra", 17.0156); - } - - /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares an edge - /// \brief Status : pass - void tetraDegenEdge() - { - _testTools->intersectMeshes("UnitTetraDegenT", "DegenEdgeXY", 0.0); - } - - /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a face - /// \brief Status : pass - void tetraDegenFace() - { - _testTools->intersectMeshes("UnitTetraDegenT", "DegenFaceXYZ", 0.0); - } - - /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a part of the face XYZ - /// \brief Status : pass - void tetraDegenTranslatedInPlane() - { - _testTools->intersectMeshes("UnitTetraDegenT", "DegenTranslatedInPlane", 0.0571667); - } - - /// Tetrahedron having only half-strip intersections with the unit tetrahedron - /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. - void tetraHalfstripOnly() - { - // NB this test is not completely significant : we should also verify that - // there are triangles on the element that give a non-zero volume - _testTools->intersectMeshes("HalfstripOnly", "UnitTetra", 0.0); - } - - /// Tetrahedron having only half-strip intersections with the unit tetrahedron - /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. - void tetraHalfstripOnly2() - { - // NB this test is not completely significant : we should also verify that - // there are triangles on the element that give a non-zero volume - _testTools->intersectMeshes("HalfstripOnly2", "UnitTetra", 0.0); - } - - /// Tetrahedron having only half-strip intersections with the unit tetrahedron - /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. - void tetraSimpleHalfstripOnly() - { - // NB this test is not completely significant : we should also verify that - // there are triangles on the element that give a non-zero volume - _testTools->intersectMeshes("SimpleHalfstripOnly", "UnitTetra", 0.0); - } - - /// Two intersecting tetrahedra situated in a general position in space - /// \brief Status : pass - void generalTetra() - { - _testTools->intersectMeshes("GenTetra1", "GenTetra2", 4.91393); - } - - /// Tetrahedron which is in a tricky position relative to unit tetrahedron. - /// \brief Status : pass - void trickyTetra1() - { - _testTools->intersectMeshes("UnitTetra", "TrickyTetra1", 0.0); - } - - /// Two large tetrahedra which nearly share part of an edge and intersect at the origin. Created with goal of getting the as-of-yet uncovered "consistency" test - /// part of the correction of double products covered. However, it does not succeed with this. - /// \brief Status : fails, but is quite far-fetched as far as typical use cases are concerned - void inconsistentTetra() - { - _testTools->intersectMeshes("LargeUnitTetra.med", "LargeUnitTetra", "LargeInconsistentTetra.med", "LargeInconsistent", 7.86231e7); - } - - }; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/TestInterpKernel.cxx b/medtool/src/INTERP_KERNELTest/TestInterpKernel.cxx deleted file mode 100644 index bfc450a26..000000000 --- a/medtool/src/INTERP_KERNELTest/TestInterpKernel.cxx +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CppUnitTest.hxx" -#include "BBTreeTest.hxx" -#include "ExprEvalInterpTest.hxx" -#include "QuadraticPlanarInterpTest.hxx" -#include "SingleElementPlanarTests.hxx" -#include "TransformedTriangleIntersectTest.hxx" -#include "TransformedTriangleTest.hxx" -#include "UnitTetraIntersectionBaryTest.hxx" -#include "UnitTetra3D2DIntersectionTest.hxx" - -#include "HexaTests.hxx" -#include "InterpolationOptionsTest.hxx" -#include "MultiElement2DTests.hxx" -#include "MultiElementTetraTests.hxx" -#include "SingleElementTetraTests.hxx" -#include "ThreeDSurfProjectionTest.hxx" - -using namespace INTERP_TEST; - -//--- Registers the fixture into the 'registry' - -CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( ExprEvalInterpTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( QuadraticPlanarInterpTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleIntersectTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetraIntersectionBaryTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetra3D2DIntersectionTest ); - -CPPUNIT_TEST_SUITE_REGISTRATION( InterpolationOptionsTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( HexaTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( MultiElement2DTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( MultiElementTetraTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementTetraTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( ThreeDSurfProjectionTest ); -// --- generic Main program from KERNEL_SRC/src/Basics/Test - -#include "BasicMainTest.hxx" diff --git a/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx b/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx deleted file mode 100644 index 5c42053e6..000000000 --- a/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TestInterpKernelUtils.hxx" - -#include -#include - -namespace INTERP_TEST -{ - std::string getResourceFile( const std::string& filename ) - { - std::string resourceFile = ""; - - if ( getenv("MEDCOUPLING_ROOT_DIR") ) { - // use MEDCOUPLING_ROOT_DIR env.var - resourceFile = getenv("MEDCOUPLING_ROOT_DIR"); - resourceFile += "/share/resources/med/"; - } - else { - resourceFile = get_current_dir_name(); - resourceFile += "/../../resources/"; - } - - resourceFile += filename; - return resourceFile; - } - -} // namespace INTERP_TEST diff --git a/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx b/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx deleted file mode 100644 index d17240a7f..000000000 --- a/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _TESTINTERPKERNELUTILS_HXX_ -#define _TESTINTERPKERNELUTILS_HXX_ - -#include "InterpKernelTestExport.hxx" - -#include - -namespace INTERP_TEST -{ - - INTERPKERNELTEST_EXPORT std::string getResourceFile( const std::string& ); - -} // namespace INTERP_TEST - -#endif // _TESTINTERPKERNELUTILS_HXX_ diff --git a/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx b/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx deleted file mode 100644 index 2a84b503a..000000000 --- a/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ThreeDSurfProjectionTest.hxx" -#include "PlanarIntersector.txx" - -class MyMeshType -{ -public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=3; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; - typedef int MyConnType; -}; - -class MyMatrixType -{ -}; - -void INTERP_TEST::ThreeDSurfProjectionTest::test1() -{ - // Two triangles coo and coo2 are perfectly // each others with a distance equal to 1e-6. - // A little rotation to make it more funny. - //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) - //eps=1e-6 - //coo2=DataArrayDouble([0.,0.,eps,1.,0.,eps,0.,1.,eps],3,3) - //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo) - //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo2) - const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; - const double coo2[9]={9.8122602102980502e-08,-1.4839144255482456e-7,9.8404874611628791e-7,0.96809759035517784,0.24332364548962007,-0.059838608733325221,-0.23056269265149082,0.9585265915109058,0.16753393126402524}; - double *tmp0(new double[9]),*tmp1(new double[9]); - int ret; - //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. - // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - const double expected0[9]={0.,0.,0.,1.,0.,0.,0.,1.,0.}; - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp0[i],1e-15); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp1[i],1e-15); - } - // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // here testing when max 3D distance is 1e-5 > 1e-6 with inverted cells - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+3,tmp1+6); std::copy(coo2+3,coo2+6,tmp1+3); std::copy(coo2+6,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(-1,ret); - const double expected1[9]={-0.7071067811865476,-0.7071067811865476,0.,0.,-1.4142135623730951,0.,-1.4142135623730951,-1.4142135623730951,0.}; - const double expected2[9]={-1.4142135623730951,-1.4142135623730951,0.,0.,-1.4142135623730951,0.,-0.7071067811865476,-0.7071067811865476,0.}; - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp0[i],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp1[i],1e-14); - } - // - delete [] tmp0; - delete [] tmp1; -} - -void INTERP_TEST::ThreeDSurfProjectionTest::test2() -{// here the two triangles have their center of inertia very close (eps) but the angle between the two planes is "big" - //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) - //coocpy=coo.deepCpy() - //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[-1,-1.,0.],pi/3,coocpy) - //coocpy+=[eps*sqrt(3)/2,eps/2,eps*0.] - // - const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; - const double coo2[9]={7.2311562622637225e-07,6.8998795679738294e-07,3.1943866106249849e-08,0.72852072144314628,0.33125439126063028,0.5996079016637561,0.0090154262465889021,0.87059752249869415,-0.49191448334281612}; - double *tmp0(new double[9]),*tmp1(new double[9]); - int ret; - //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. - // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // again max 3D distance is 1e-5 > 1e-6 so 1 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.8. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.8 - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.8/* <- */,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 1 expected. because the angle is pi/4 so cos(pi/3) < 0.49 - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.49/* <- */,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.51 - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.51/* <- */,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // - delete [] tmp0; - delete [] tmp1; -} diff --git a/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx b/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx deleted file mode 100644 index 40d27a587..000000000 --- a/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __THREEDSURFPROJECTIONTEST_HXX__ -#define __THREEDSURFPROJECTIONTEST_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class dedicated of the test of the preprocessing of 3D surf cells before performing invoking 2D algorithms. - */ - class INTERPKERNELTEST_EXPORT ThreeDSurfProjectionTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( ThreeDSurfProjectionTest ); - CPPUNIT_TEST ( test1 ); - CPPUNIT_TEST ( test2 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test1(); - void test2(); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx b/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx deleted file mode 100644 index 8fdc77df3..000000000 --- a/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx +++ /dev/null @@ -1,2284 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangleIntersectTest.hxx" -#include - -#include "Log.hxx" - -/// macro to test for zero double products outside the segment-edge intersection test method -/// as is done in TransformedTriangle when OPTIMIZE is defined -#define TEST_ZERO_DP_EDGE(seg, edge) isZero[TT::NO_DP*int(seg) + int(DoubleProduct(edge))] - -/// macro to test for zero double products outside the segment-corner intersection test method -/// as is done in TransformedTriangle when OPTIMIZE is defined -#define TEST_ZERO_DP_CORNER(seg, corner) \ - isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner] )] && \ - isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+1] )] && \ - isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+2] )] - -/// macro to test for zero double products outside the segment-ray intersection test method -/// as is done in TransformedTriangle when OPTIMIZE is defined -#define TEST_ZERO_DP_RAY(seg, corner) isZero[TT::NO_DP*int(seg) + TT::DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// \class TransformedTriangleIntersectTest - /// \brief Class testing the intersection detection methods of TransformedTriangle. - /// - /// This class contains unit tests for the intersection methods of the TransformedTriangle class. - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Each method in the class runs all the intersection tests with some triangle. The goal is to cover all - /// the different types of intersections between a triangle and a tetrahedron. The table below gives a - /// a summary of what is being tested. Before each method, there is also a summary of what how the - /// triangle in the method intersects the unit tetrahedron. - /// - /// Since performing all tests would require a large number of triangles, we have limited our coverage to - /// be such that each column and each row in the table below has at least one entry for each type of - /// intersection. The intersection forumlae are totally symmetric with respect to changing the segment - /// (PQ, QR, or RP) of the triangle, so they only enter in a very simple way in the code. Testing - /// all these cases is therefore of low priority. - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Intersections tested (number indicates first triangle which contains the intersection): - ///
-  /// -----------------------------------------------------------------------------------------------------
-  /// CI  ->  P: 3      Q: 4     R: 7
-  /// COH ->  P: 9      Q: 8     R: 10
-  /// CAH ->  P: 4      Q: 10    R: 9
-  /// -----------------------------------------------------------------------------------------------------
-  /// SF  ->  (PQ, OZX) : 1   (PQ, OYZ) : 2   (PQ, OXY) : 1   (PQ, XYZ) : 3
-  ///     ->  (QR, OZX) : 8   (QR, OYZ) : -   (QR, OXY) : 4   (QR, XYZ) : 7
-  ///     ->  (RP, OZX) : 1   (RP, OYZ) : 3   (RP, OXY) : 7   (RP, XYZ) : 1
-  /// -----------------------------------------------------------------------------------------------------
-  /// SE  ->  (PQ, OX)  : 11  (PQ, OY)  : -   (PQ, OZ)  : 12  (PQ, XY)  : 2   (PQ, ZX)  : -  (PQ, YZ)  : 10
-  ///     ->  (QR, OX)  : -   (QR, OY)  : -   (QR, OZ)  : -   (QR, XY)  : -   (QR, ZX)  : 9  (QR, YZ)  : -
-  ///     ->  (RP, OX)  : -   (RP, OY)  : 12  (RP, OZ)  : -   (RP, XY)  : -   (RP, ZX)  : -  (RP, YZ)  : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// SC  ->  (PQ, O)   : -   (PQ, X)   : -   (PQ, Y)   : 8   (PQ, Z)   : -
-  ///     ->  (QR, O)   : -   (QR, X)   : 2   (QR, Y)   : -   (QR, Z)   : 13
-  ///     ->  (RP, O)   : 11  (RP, X)   : -   (RP, Y)   : -   (RP, Z)   : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// SHS ->  (PQ, XY)  : 3   (PQ, ZX)  : -   (PQ, YZ)  : 13
-  ///     ->  (QR, XY)  : 3   (QR, ZX)  : 5   (QR, YZ)  : 3
-  ///     ->  (RP, XY)  : 1   (RP, ZX)  : 4   (RP, YZ)  : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// SR  ->  (PQ, X)   : 6   (PQ, Y)   : 5   (PQ, Z)   : -
-  ///     ->  (QR, X)   : -   (QR, Y)   : -   (QR, Z)   : 6
-  ///     ->  (RP, X)   : -   (RP, Y)   : -   (RP, Z)   : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// TE  ->  OX : 4   OY : 7    OZ : 8     XY : 1     ZX : 4    YZ : 3
-  /// -----------------------------------------------------------------------------------------------------
-  /// TR  ->  X  : 7    Y : 6     Z : 5
-  /// -----------------------------------------------------------------------------------------------------
-  /// 
- //////////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Key to triangle descriptions : - /// CI = Triangle corner contained in tetrahedron - /// COH = Triangle corner on h = 0 face of tetrahedron - /// CAH = Triangle corner above h = 0 face of tetrahedron in z-direction - /// SF = Segment - facet intersection - /// SE = Segment - edge intersection - /// SC = Segment - corner intersection - /// SHS = Segment - halfstrip intersection - /// SR = Segment - ray intersection - /// TE = Tetrahedron edge intersects triangle (surface - edge intersection) - /// TR = Surface - ray intersection - /// - /// In the descriptions for each triangle, square brackets indicate superfluous but allowed intersections - /// that arise as by-products of for instance segment-corner intersections. - /// E.g. A segment - corner intersection can imply three surface - edge intersections - /// Since these "extra" intersections arise under special circumstances, they are not counted in the - /// table above - //////////////////////////////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Triangle 1 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (PQ, OXY), (PQ, OZX), (RP, XYZ), (RP, OZX)
-  /// SE     -
-  /// SC     - 
-  /// SHS    (RP, XY)
-  /// SR     - 
-  /// TE     XY
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle1() - { - LOG(1, "+++++++ Testing triangle 1" ); - - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.4,-0.5, 0.5, // P - 0.4, 2.5,-1.0, // Q - 0.4, 2.5, 0.5 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT(tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - - } - - /// Triangle 2 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (PQ, OYZ)
-  /// SE     (PQ, XY)
-  /// SC     (QR, X)
-  /// SHS    -
-  /// SR     - 
-  /// TE     [OX, OZ, ZX]
-  /// TR     - 
-  /// 
- /// \brief Status: pass - void TransformedTriangleIntersectTest::testTriangle2() - { - LOG(1, "+++++++ Testing triangle 2" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.5, 0.5, 0.25, // P - 1.5, 0.5,-0.25, // Q - -0.5,-1.5, 0.75 // R - }; - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 3 has the following intersections - ///
-  /// CI     P
-  /// COH    -
-  /// CAH    -
-  /// SF     (PQ, XYZ), (RP, OYZ)
-  /// SE     -
-  /// SC     -
-  /// SHS    (PQ, XY), (QR, YZ), (QR, XY)
-  /// SR     - 
-  /// TE     YZ
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle3() - { - LOG(1, "+++++++ Testing triangle 3" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.35, 0.15, 0.1, // P - 0.8, 0.8, 0.8, // Q - -0.4, 0.3, 0.9 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 4 has the following intersections - ///
-  /// CI     Q
-  /// COH    -
-  /// CAH    P
-  /// SF     (PQ, XYZ), (QR, OXY)
-  /// SE     -
-  /// SC     -
-  /// SHS    (RP, ZX)
-  /// SR     - 
-  /// TE     (OX, ZX)
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle4() - { - LOG(1, "+++++++ Testing triangle 4" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.3, 0.3, 1.8, // P - 0.75, 0.1, 0.1, // Q - 0.2, -1.3, -1.4 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 5 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     -
-  /// SE     -
-  /// SC     -
-  /// SHS    (QR, ZX), (QR, XY)
-  /// SR     (PQ, Y)
-  /// TE     -
-  /// TR     Z
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle5() - { - LOG(1, "+++++++ Testing triangle 5" ); - - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.5, 0.5, 2.3, // P - 0.5, 1.5, 2.8, // Q - 0.5, -2.6, 1.3 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 6 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     -
-  /// SE     -
-  /// SC     -
-  /// SHS    -
-  /// SR     (PQ, X), (QR, Z) 
-  /// TE     -
-  /// TR     Y 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle6() - { - LOG(1, "+++++++ Testing triangle 6" ); - - typedef TransformedTriangle TT; - - double coords[9] = - { - 1.5, 0.5, 1.35, // P - 0.5, -0.5, 2.1, // Q - -3.0, 3.0, -0.5 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 7 has the following intersections - ///
-  /// CI     R
-  /// COH    -
-  /// CAH    -
-  /// SF     (RP, OXY),(QR,XYZ)
-  /// SE     -
-  /// SC     -
-  /// SHS    (QR, XY)
-  /// SR     - 
-  /// TE     OX, ZX
-  /// TR     X 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle7() - { - - LOG(1, "+++++++ Testing triangle 7" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -2.3, -1.5, -2.5, // P - 3.1, 0.15, 0.8, // Q - 0.3, 0.4, 0.2 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 8 has the following intersections - ///
-  /// CI     [Q] 
-  /// COH    Q
-  /// CAH    -
-  /// SF     (QR, OZX), [ (QR, XYZ) ]
-  /// SE     -
-  /// SC     (PQ,Y)
-  /// SHS    -
-  /// SR     - 
-  /// TE     OZ, [YZ,OY,XY]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle8() - { - LOG(1, "+++++++ Testing triangle 8" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.75, 3.25, -1.5, // P - 0.25, 0.25, 0.5, // Q - -0.1, -0.4, 0.9 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 9 has the following intersections - ///
-  /// CI     [P]
-  /// COH    P
-  /// CAH    R
-  /// SF     (PQ, OZX), [(PQ, XYZ), (RP,XYZ)]
-  /// SE     (QR, ZX)
-  /// SC     -
-  /// SHS    -
-  /// SR     - 
-  /// TE     [ZX]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle9() - { - LOG(1, "+++++++ Testing triangle 9" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.6, 0.2, 0.2, // P - 0.3, -0.2, 0.8, // Q - 0.1, 0.2, 0.8 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - - /// Triangle 10 has the following intersections - ///
-  /// CI     [R]
-  /// COH    R
-  /// CAH    Q
-  /// SF     (RP, OYZ), [ (RP, XYZ), (QR, XYZ) ]
-  /// SE     (PQ, YZ)
-  /// SC     -
-  /// SHS    -
-  /// SR     - 
-  /// TE     [YZ]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle10() - { - LOG(1, "+++++++ Testing triangle 10" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.1, 0.3, 0.6, // P - 0.1, 0.1, 1.0, // Q - 0.4, 0.3, 0.3 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 11 has the following intersections - ///
-  /// CI     Q, R
-  /// COH    -
-  /// CAH    -
-  /// SF     -
-  /// SE     (PQ, OX)
-  /// SC     (RP, O)
-  /// SHS    -
-  /// SR     - 
-  /// TE     [OY, OZ]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle11() - { - LOG(1, "+++++++ Testing triangle 11" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.2, -0.2, -0.2, // P - 0.2, 0.1, 0.1, // Q - 0.3, 0.3, 0.3 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - - /// Triangle 12 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (QR, OXY), (QR, OZX)
-  /// SE     (RP, OY), (PQ, OZ)
-  /// SC     -
-  /// SHS    -
-  /// SR     - 
-  /// TE     [OY], [OZ]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle12() - { - LOG(1, "+++++++ Testing triangle 12" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.2, 0.2, 0.2, // P - 0.2, -0.2, 0.3, // Q - 0.6, 0.6, -0.6 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - - /// Triangle 13 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (QR, OYZ), (PQ, OXY), (PQ, XYZ)
-  /// SE     -
-  /// SC     (QR, Z)
-  /// SHS    (PQ, YZ)
-  /// SR     - 
-  /// TE     [OZ, YZ, ZX]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle13() - { - LOG(1, "+++++++ Testing triangle 13" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.2, 0.3, 5.0, // P - 0.2, 0.1, -1.0, // Q - -0.2, -0.1, 3.0 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - -} // NAMESPACE - - - - - - - -///// TEMPLATE /////////////////////////////// - - - -#if 0 -// Triangle x has the following intersections -// CI - -// COH - -// CAH - -// SF - -// SE - -// SC - -// SHS - -// SR - -// TE - -// TR - - -void TransformedTriangleIntersectTest::testTriangleX() -{ - LOG(1, "+++++++ Testing triangle X" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.0, 0.0, 0.0, // P - 0.0, 0.0, 0.0, // Q - 0.0, 0.0, 0.0 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; -} -#endif diff --git a/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx b/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx deleted file mode 100644 index 8ff1196d9..000000000 --- a/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ -#define __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "TransformedTriangle.hxx" - -namespace INTERP_TEST -{ - - class INTERPKERNELTEST_EXPORT TransformedTriangleIntersectTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( TransformedTriangleIntersectTest ); - - CPPUNIT_TEST( testTriangle1 ); - CPPUNIT_TEST( testTriangle2 ); - CPPUNIT_TEST( testTriangle3 ); - CPPUNIT_TEST( testTriangle4 ); - CPPUNIT_TEST( testTriangle5 ); - CPPUNIT_TEST( testTriangle6 ); - CPPUNIT_TEST( testTriangle7 ); - CPPUNIT_TEST( testTriangle8 ); - CPPUNIT_TEST( testTriangle9 ); - CPPUNIT_TEST( testTriangle10 ); - CPPUNIT_TEST( testTriangle11 ); - CPPUNIT_TEST( testTriangle12 ); - CPPUNIT_TEST( testTriangle13 ); - - CPPUNIT_TEST_SUITE_END(); - - typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; - typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; - - public: - - void testTriangle1(); - - void testTriangle2(); - - void testTriangle3(); - - void testTriangle4(); - - void testTriangle5(); - - void testTriangle6(); - - void testTriangle7(); - - void testTriangle8(); - - void testTriangle9(); - - void testTriangle10(); - - void testTriangle11(); - - void testTriangle12(); - - void testTriangle13(); - - private: - - }; - -} - - - - - - -#endif diff --git a/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.cxx b/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.cxx deleted file mode 100644 index ee4eb20c2..000000000 --- a/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.cxx +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangleTest.hxx" - -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - - /** - * Creates the TransformedTriangle objects used by the tests. - * - */ - void TransformedTriangleTest::setUp() - { - // tri1 -> no unstable double products - no changes brought about by preCalculateDoubleProducts - // this allows the testing of calcUnstableT - // tri2 -> unstable double products - for testing calcStableC / preCalculateDoubleProducts - - // triangle to test unstable C and T calculations - p1[0] = -1.5 ; p1[1] = 0.5; p1[2] = 0.5; - q1[0] = 2.0 ; q1[1] = 0.4; q1[2] = 0.6; - r1[0] = 1.0 ; r1[1] = 2.4; r1[2] = 1.2; - hp1 = 1 - p1[0] - p1[1] - p1[2]; - hq1 = 1 - q1[0] - q1[1] - q1[2]; - hr1 = 1 - r1[0] - r1[1] - r1[2]; - Hp1 = 1 - p1[0] - p1[1]; - Hq1 = 1 - q1[0] - q1[1]; - Hr1 = 1 - r1[0] - r1[1]; - - // std::cout <_coords[i], ERR_TOL); - CPPUNIT_ASSERT_DOUBLES_EQUAL(good_values2[i], tri2->_coords[i], ERR_TOL); - } - - CPPUNIT_ASSERT_EQUAL(true, tri1->_is_double_products_calculated); - CPPUNIT_ASSERT_EQUAL(true, tri2->_is_double_products_calculated); - } - - /// Tests the calculation of double products (without the corrections) - /// \brief Status : pass - void TransformedTriangleTest::test_calcUnstableC() { - typedef TransformedTriangle::TriSegment TriSegment; - - // test that the correct c-values are calculated - - double correct_c_vals[24] = - { - p1[0] * q1[1] - p1[1] * q1[0], - p1[1] * q1[2] - p1[2] * q1[1], - p1[2] * q1[0] - p1[0] * q1[2], - p1[0] * hq1 - hp1 * q1[0], - p1[1] * hq1 - hp1 * q1[1], - p1[2] * hq1 - hp1 * q1[2], - Hp1 * q1[0] - p1[0] * Hq1, - p1[1] * Hq1 - Hp1 * q1[1], - q1[0] * r1[1] - q1[1] * r1[0], - q1[1] * r1[2] - q1[2] * r1[1], - q1[2] * r1[0] - q1[0] * r1[2], - q1[0] * hr1 - hq1 * r1[0], - q1[1] * hr1 - hq1 * r1[1], - q1[2] * hr1 - hq1 * r1[2], - Hq1 * r1[0] - q1[0] * Hr1, - q1[1] * Hr1 - Hq1 * r1[1], - r1[0]*p1[1]-r1[1]*p1[0], - r1[1]*p1[2]-r1[2]*p1[1], - r1[2]*p1[0]-r1[0]*p1[2], - r1[0] * hp1 - hr1 * p1[0], - r1[1] * hp1 - hr1 * p1[1], - r1[2] * hp1 - hr1 * p1[2], - Hr1 * p1[0] - r1[0] * Hp1, - r1[1] * Hp1 - Hr1 * p1[1] - }; - - double c_vals[3 * 8]; - for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { - - c_vals[seg*8 + 0] = tri1->calcUnstableC(seg, TransformedTriangle::C_XY); - c_vals[seg*8 + 1] = tri1->calcUnstableC(seg, TransformedTriangle::C_YZ); - c_vals[seg*8 + 2] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZX); - c_vals[seg*8 + 3] = tri1->calcUnstableC(seg, TransformedTriangle::C_XH); - c_vals[seg*8 + 4] = tri1->calcUnstableC(seg, TransformedTriangle::C_YH); - c_vals[seg*8 + 5] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZH); - c_vals[seg*8 + 6] = tri1->calcUnstableC(seg, TransformedTriangle::C_01); - c_vals[seg*8 + 7] = tri1->calcUnstableC(seg, TransformedTriangle::C_10); - - } - - for(int i = 0 ; i < 3*8 ; ++i) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( correct_c_vals[i], c_vals[i], ERR_TOL ); - } - - - } - - /// Tests the calculation of triple products (without corrections) - /// \brief Status : pass - void TransformedTriangleTest::test_calcUnstableT() - { - typedef TransformedTriangle::TetraCorner TetraCorner; - - // correct values calculated by determinants (Grandy, [15]) - const double correct_t_vals[4] = - { - p1[0]*(q1[1]*r1[2] - q1[2]*r1[1]) - - q1[0]*(p1[1]*r1[2] - p1[2]*r1[1]) + - r1[0]*(p1[1]*q1[2] - p1[2]*q1[1]), - - -(hp1*(q1[1]*r1[2] - q1[2]*r1[1]) - - hq1*(p1[1]*r1[2] - p1[2]*r1[1]) + - hr1*(p1[1]*q1[2] - p1[2]*q1[1])), - - -(p1[0]*(hq1*r1[2] - q1[2]*hr1) - - q1[0]*(hp1*r1[2] - p1[2]*hr1) + - r1[0]*(hp1*q1[2] - p1[2]*hq1)), - - -(p1[0]*(q1[1]*hr1 - r1[1]*hq1) - - q1[0]*(p1[1]*hr1 - r1[1]*hp1) + - r1[0]*(p1[1]*hq1 - q1[1]*hp1)) - }; - - - // test that triple products are correctly calculated - for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) - { - - for(int row = 1 ; row < 4 ; ++row) - { - const double t = tri1->calcTByDevelopingRow(corner, row, false); - // std::cout << std::endl << " Corner = " << corner << " Row = " << row << " got: " << t << - // " expected: " << correct_t_vals[corner]<< std::endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_t_vals[corner], t, ERR_TOL); - } - } - } - - /// Tests the consistency correction - /// \brief Status : fails because it is not significant - the consistency correction is not brought into play - void TransformedTriangleTest::test_calcStableC_Consistency() - { - - typedef TransformedTriangle::TriSegment TriSegment; - typedef TransformedTriangle::TetraCorner TetraCorner; - - // grandy, eq 14 - double correct_c_vals[24] = - { - p2[0] * q2[1] - p2[1] * q2[0], - p2[1] * q2[2] - p2[2] * q2[1], - p2[2] * q2[0] - p2[0] * q2[2], - p2[0] * hq2 - hp2 * q2[0], - p2[1] * hq2 - hp2 * q2[1], - p2[2] * hq2 - hp2 * q2[2], - Hp2 * q2[0] - p2[0] * Hq2, - p2[1] * Hq2 - Hp2 * q2[1], - q2[0] * r2[1] - q2[1] * r2[0], - q2[1] * r2[2] - q2[2] * r2[1], - q2[2] * r2[0] - q2[0] * r2[2], - q2[0] * hr2 - hq2 * r2[0], - q2[1] * hr2 - hq2 * r2[1], - q2[2] * hr2 - hq2 * r2[2], - Hq2 * r2[0] - q2[0] * Hr2, - q2[1] * Hr2 - Hq2 * r2[1], - r2[0]*p2[1]-r2[1]*p2[0], - r2[1]*p2[2]-r2[2]*p2[1], - r2[2]*p2[0]-r2[0]*p2[2], - r2[0] * hp2 - hr2 * p2[0], - r2[1] * hp2 - hr2 * p2[1], - r2[2] * hp2 - hr2 * p2[2], - Hr2 * p2[0] - r2[0] * Hp2, - r2[1] * Hp2 - Hr2 * p2[1] - }; - - - // number of inconsistent cases found : - // should be (at least) 1 for the test to be meaningful - int num_cases = 0; - - // find unstable products to check for consistency (Grandy [46]) - for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) - { - const double c_xy = tri2->calcUnstableC(seg, TransformedTriangle::C_XY); - const double c_yz = tri2->calcUnstableC(seg, TransformedTriangle::C_YZ); - const double c_zx = tri2->calcUnstableC(seg, TransformedTriangle::C_ZX); - const double c_xh = tri2->calcUnstableC(seg, TransformedTriangle::C_XH); - const double c_yh = tri2->calcUnstableC(seg, TransformedTriangle::C_YH); - const double c_zh = tri2->calcUnstableC(seg, TransformedTriangle::C_ZH); - - const int num_zero = (c_yz*c_xh == 0.0 ? 1 : 0) + (c_zx*c_yh == 0.0 ? 1 : 0) + (c_xy*c_zh == 0.0 ? 1 : 0); - const int num_neg = (c_yz*c_xh < 0.0 ? 1 : 0) + (c_zx*c_yh < 0.0 ? 1 : 0) + (c_xy*c_zh < 0.0 ? 1 : 0); - - if((num_zero == 1 && num_neg != 1) || num_zero == 2 || num_neg == 0 && num_zero !=3 || num_neg == 3 ) - { - ++num_cases; - - double min_dist = -1.0; // initialised first time through loop - TetraCorner min_corner = TransformedTriangle::O; - - for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) - { - // calculate distance from each corner of tetraeder to the segment - // formula : ( (Q-P) x (P - corner) )^2 / norm(Q-P)^2 - - const double ptP[3] = { tri2->_coords[5*seg], tri2->_coords[5*seg + 1], tri2->_coords[5*seg + 2] }; - const double ptQ[3] = { tri2->_coords[5*( (seg+1) % 3)], tri2->_coords[5*( (seg+1) % 3) + 1], tri2->_coords[5*( (seg+1) % 3) + 2] }; - const double ptCorner[3] = { - corner == TransformedTriangle::X ? 1.0 : 0.0, - corner == TransformedTriangle::Y ? 1.0 : 0.0, - corner == TransformedTriangle::Z ? 1.0 : 0.0, - }; - - const double diff_21[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; - const double diff_1_corner[3] = { ptP[0] - ptCorner[0], ptP[1] - ptCorner[1], ptP[2] - ptCorner[2] }; - - const double cross[3] = { - diff_21[1]*diff_1_corner[2] - diff_21[2]*diff_1_corner[1], - diff_21[2]*diff_1_corner[0] - diff_21[0]*diff_1_corner[2], - diff_21[0]*diff_1_corner[1] - diff_21[1]*diff_1_corner[0] - }; - - const double cross_sq = cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]; - - const double norm_pq = diff_21[0]*diff_21[0] + diff_21[1]*diff_21[1] + diff_21[2]*diff_21[2]; - - if(corner == TransformedTriangle::O || (cross_sq / norm_pq) < min_dist) - { - min_dist = cross_sq / norm_pq; - min_corner = corner; - } - } - - // now check if the corresponding double products are zero - static const DoubleProduct DOUBLE_PRODUCTS[12] = - { - TransformedTriangle::C_YZ, TransformedTriangle::C_XY, TransformedTriangle::C_ZX, // O - TransformedTriangle::C_ZH, TransformedTriangle::C_YZ, TransformedTriangle::C_YH, // X - TransformedTriangle::C_ZH, TransformedTriangle::C_ZX, TransformedTriangle::C_XH, // Y - TransformedTriangle::C_XY, TransformedTriangle::C_YH, TransformedTriangle::C_XH // Z - }; - - for(int i = 0; i < 3 ; ++i) - { - DoubleProduct dp = DOUBLE_PRODUCTS[3*min_corner + i]; - // std::cout << std::endl << "in test inconsistent (seg,dp) :(" << seg <<", " << dp << ")" << std::endl; - CPPUNIT_ASSERT_EQUAL(0.0, tri2->calcStableC(seg, dp)); - correct_c_vals[8*seg + dp] = 0.0; - } - } - - } - - if(num_cases < 1) - { - CPPUNIT_FAIL("Consistency test not pertinent"); - } - - // std::cout << std::endl << "Number of geometric inconsistencies : " << num_cases << std::endl; - - // check that all other double products have right value too - double c_vals[8*3]; - - for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { - - c_vals[seg*8 + 0] = tri2->calcStableC(seg, TransformedTriangle::C_XY); - c_vals[seg*8 + 1] = tri2->calcStableC(seg, TransformedTriangle::C_YZ); - c_vals[seg*8 + 2] = tri2->calcStableC(seg, TransformedTriangle::C_ZX); - c_vals[seg*8 + 3] = tri2->calcStableC(seg, TransformedTriangle::C_XH); - c_vals[seg*8 + 4] = tri2->calcStableC(seg, TransformedTriangle::C_YH); - c_vals[seg*8 + 5] = tri2->calcStableC(seg, TransformedTriangle::C_ZH); - c_vals[seg*8 + 6] = tri2->calcStableC(seg, TransformedTriangle::C_01); - c_vals[seg*8 + 7] = tri2->calcStableC(seg, TransformedTriangle::C_10); - - } - - for(int i = 0 ; i < 24 ; ++i) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_c_vals[i], c_vals[i], ERR_TOL); - } - } - -} diff --git a/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.hxx b/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.hxx deleted file mode 100644 index 064f4059c..000000000 --- a/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.hxx +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TU_TRANSFORMED_TRIANGLE_HXX__ -#define __TU_TRANSFORMED_TRIANGLE_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "TransformedTriangle.hxx" - -#define ERR_TOL 1.0e-8 - -namespace INTERP_TEST -{ - - /** - * \brief Test suite testing some of the low level methods of TransformedTriangle. - * - */ - class INTERPKERNELTEST_EXPORT TransformedTriangleTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( TransformedTriangleTest ); - CPPUNIT_TEST( test_constructor ); - CPPUNIT_TEST( test_calcUnstableC ); - CPPUNIT_TEST( test_calcUnstableT ); - //removed because the test fails to enter the desired code branch - // CPPUNIT_TEST( test_calcStableC_Consistency ); - CPPUNIT_TEST_SUITE_END(); - - typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; - typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; - - public: - void setUp(); - - void tearDown(); - - // tests - void test_constructor(); - - void test_calcUnstableC(); - - void test_calcUnstableT(); - - void test_calcStableC_Consistency(); - - double p1[3], q1[3], r1[3]; - double hp1, hq1, hr1; - double Hp1, Hq1, Hr1; - - double p2[3], q2[3], r2[3]; - double hp2, hq2, hr2; - double Hp2, Hq2, Hr2; - - double stable_c2[24]; - - private: - INTERP_KERNEL::TransformedTriangle* tri1; - INTERP_KERNEL::TransformedTriangle* tri2; - - }; - - - - -} - - - -#endif diff --git a/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx b/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx deleted file mode 100644 index 031becc04..000000000 --- a/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "UnitTetra3D2DIntersectionTest.hxx" - -#include "TetraAffineTransform.hxx" -#include "InterpolationUtils.hxx" -#include "SplitterTetra.txx" - -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - struct __MESH_DUMMY - { - typedef int MyConnType; - static const int MY_SPACEDIM=3; - }; - - static SplitterTetra<__MESH_DUMMY>* buildSplitterTetra() - { - const int conn[4] = { 0,1,2,3 }; - - const double targetCoords[] = { -20., 0.,10., - -20.,10.,10., - -12., 0.,10., - -20., 0.,18. }; - - const double* tetraCoords[]={ targetCoords, targetCoords+3, targetCoords+6, targetCoords+9 }; - - __MESH_DUMMY dummyMesh; - SplitterTetra<__MESH_DUMMY>* targetTetra = new SplitterTetra<__MESH_DUMMY>( dummyMesh, tetraCoords, conn ); - return targetTetra; - } - - void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_1() - { - const int conn[4] = { 0,1,2 }; - - const double sourceCoords[] = { -20., 0., 10., - -12., 0., 10., - -20.,10., 10. }; - - SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); - const double dimCaracteristic = 1.; - const double precision = 1.e-12; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - const double* sourceTriCoords[] = { sourceCoords, sourceCoords+3, sourceCoords+6 }; - double surface = targetTetra->intersectSourceFace(NORM_TRI3, - 3, - conn, - sourceTriCoords, - dimCaracteristic, - precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - delete targetTetra; - CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision); - - CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size()); - std::multiset correctListOfTetraFacesTreated; - TriangleFaceKey key1 = TriangleFaceKey(0, 1, 2); - correctListOfTetraFacesTreated.insert(key1); - TriangleFaceKey key2 = TriangleFaceKey(0, 1, 3); - correctListOfTetraFacesTreated.insert(key2); - TriangleFaceKey key3 = TriangleFaceKey(0, 2, 3); - correctListOfTetraFacesTreated.insert(key3); - TriangleFaceKey key4 = TriangleFaceKey(1, 2, 3); - correctListOfTetraFacesTreated.insert(key4); - CPPUNIT_ASSERT(correctListOfTetraFacesTreated == listOfTetraFacesTreated); - - CPPUNIT_ASSERT_EQUAL(1,(int)listOfTetraFacesColinear.size()); - std::set correctListOfTetraFacesColinear; - correctListOfTetraFacesColinear.insert(key1); - CPPUNIT_ASSERT(correctListOfTetraFacesColinear == listOfTetraFacesColinear); - - } - - void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_2() - { - const int conn[4] = { 0,1,2,3 }; - - const double sourceCoords[] = { -20., 0., 10., - -12., 0., 10., - -12.,10., 10., - -20.,10., 10. }; - - SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); - const double dimCaracteristic = 1.; - const double precision = 1.e-12; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - const double* sourceQuadCoords[] = { sourceCoords, sourceCoords+3, sourceCoords+6, sourceCoords+9 }; - double surface = targetTetra->intersectSourceFace(NORM_QUAD4, - 4, - conn, - sourceQuadCoords, - dimCaracteristic, - precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - delete targetTetra; - CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision); - - CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size()); - std::multiset correctListOfTetraFacesTreated; - TriangleFaceKey key1 = TriangleFaceKey(0, 1, 2); - correctListOfTetraFacesTreated.insert(key1); - TriangleFaceKey key2 = TriangleFaceKey(0, 1, 3); - correctListOfTetraFacesTreated.insert(key2); - TriangleFaceKey key3 = TriangleFaceKey(0, 2, 3); - correctListOfTetraFacesTreated.insert(key3); - TriangleFaceKey key4 = TriangleFaceKey(1, 2, 3); - correctListOfTetraFacesTreated.insert(key4); - CPPUNIT_ASSERT(correctListOfTetraFacesTreated == listOfTetraFacesTreated); - - CPPUNIT_ASSERT_EQUAL(1,(int)listOfTetraFacesColinear.size()); - std::set correctListOfTetraFacesColinear; - correctListOfTetraFacesColinear.insert(key1); - CPPUNIT_ASSERT(correctListOfTetraFacesColinear == listOfTetraFacesColinear); - - } - - void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_3() - { - const int conn[4] = { 0,1,2 }; - - const double sourceCoords[] = { -20., 0., 16., - -18., 0., 16., - -20.,2.5, 16. }; - - SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); - const double dimCaracteristic = 1.; - const double precision = 1.e-12; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - const double* sourceTri2Coords[] = { sourceCoords, sourceCoords+3, sourceCoords+6 }; - double surface = targetTetra->intersectSourceFace(NORM_TRI3, - 3, - conn, - sourceTri2Coords, - dimCaracteristic, - precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - delete targetTetra; - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5,surface,precision); - - CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesTreated.size()); - - CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesColinear.size()); - } - -} diff --git a/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx b/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx deleted file mode 100644 index 7ccc1219e..000000000 --- a/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __UNITTETRA3D2DINTERSECTIONTEST_HXX__ -#define __UNITTETRA3D2DINTERSECTIONTEST_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Test suite testing UnitTetra3D2DIntersection class. - * - */ - class INTERPKERNELTEST_EXPORT UnitTetra3D2DIntersectionTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( UnitTetra3D2DIntersectionTest ); - CPPUNIT_TEST( test_UnitTetra3D2DIntersection_1 ); - CPPUNIT_TEST( test_UnitTetra3D2DIntersection_2 ); - CPPUNIT_TEST( test_UnitTetra3D2DIntersection_3 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test_UnitTetra3D2DIntersection_1(); - void test_UnitTetra3D2DIntersection_2(); - void test_UnitTetra3D2DIntersection_3(); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx b/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx deleted file mode 100644 index d901f218a..000000000 --- a/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : UnitTetraIntersectionBaryTest.cxx -// Created : Thu Dec 11 15:54:41 2008 -// Author : Edward AGAPOV (eap) -// -#include "UnitTetraIntersectionBaryTest.hxx" - -#include "UnitTetraIntersectionBary.hxx" -#include "TetraAffineTransform.hxx" -#include "InterpolationUtils.hxx" -#include "SplitterTetra.txx" - -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - void fill_UnitTetraIntersectionBary(UnitTetraIntersectionBary& bary, double nodes[][3]) - { - int faceConn[4][3] = { { 0, 1, 2 },// inverse order - { 0, 3, 1 }, - { 1, 3, 2 }, - { 3, 0, 2 } }; -// int faceConn[4][3] = { { 0, 2, 1 }, -// { 0, 1, 3 }, -// { 1, 2, 3 }, -// { 3, 2, 0 } }; - bary.init(true); - for ( int i = 0; i < 4; ++i ) { - int* faceNodes = faceConn[ i ]; - TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); - tri.calculateIntersectionVolume(); - bary.addSide( tri ); - } - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_1() - { - // cutting tetra coincides with the unit one - double nodes[4][3] = { { 0.0, 0.0, 0.0 }, - { 1.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 1.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_2() - { - // cutting tetra fully include the unit one - double nodes[4][3] = { {-0.1,-0.1,-0.1 }, - { 1.5,-0.1,-0.1 }, - {-0.1, 1.5,-0.1 }, - {-0.1,-0.1, 1.5 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_3() - { - // cutting tetra is same as the unit one but moved up by 0.5 - double nodes[4][3] = { { 0.0, 0.0, 0.5 }, - { 1.0, 0.0, 0.5 }, - { 0.0, 1.0, 0.5 }, - { 0.0, 0.0, 1.5 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_4() - { - // same as previous but no cutting sides lay on the sides of unit tetra - double nodes[4][3] = { {-0.2,-0.2, 0.5 }, - { 1.0, 0.0, 0.5 }, - { 0.0, 1.0, 0.5 }, - { 0.0, 0.0, 2.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_5() - { - // cutting tetra is similar and parallel to the UT but moved (-0.1,-0.1,-0.1) - double nodes[4][3] = { {-0.1,-0.1,-0.1 }, - { 1.1,-0.1,-0.1 }, - {-0.1, 1.1,-0.1 }, - {-0.1,-0.1, 1.1 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1215, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_6() - { - // cutting tetra is deeped into the UT with one corner - double nodes[4][3] = { { 0.2, 0.2, 0.2 }, - { 1.0, 0.2, 0.2 }, - { 0.9, 1.0, 0.2 }, - { 0.9, 9.0, 1.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.000441855, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.353463 , baryCenter[0], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.33877 , baryCenter[1], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.207767 , baryCenter[2], 1e-5 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_7() - { - // cutting tetra passes through the UT with one corner - double nodes[4][3] = { {-0.2, 0.2, 0.2 }, - { 1.0, 0.2, 0.2 }, - { 0.9, 1.0, 0.2 }, - { 0.9, 0.9, 1.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0103501, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.215578 , baryCenter[0], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.341363 , baryCenter[1], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.263903 , baryCenter[2], 1e-5 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_8() - { - // cutting tetra passes through the UT with one edge - double nodes[4][3] = { { 0.5, 0.2, -0.2 }, // O - {-0.5,-0.2, -0.2 }, // OX - { 1.0,-0.5, -0.2 }, // OY - { 0.5, 0.2, 1.5 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0349217, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.332275 , baryCenter[0], 1e-2 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0565892 , baryCenter[1], 1e-3 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.308713 , baryCenter[2], 1e-2 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_9() - { - // cutting tetra touches the UT at an edge, intersection volume == 0 - double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 - {-1.0, 2.0, 2.0 }, // OX - {-1.0,-2.0, 2.0 }, // OY - { 1.0, 0.0, 2.0 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( !ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, vol, 1e-15); - CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[0], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[1], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[2], 1e-5 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_10() - { - // cutting tetra fully includes theUT and touches it at an edge - double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 - {-1.0,-4.0, 2.0 }, // OX - {-1.0, 4.0, 2.0 }, // OY - { 1.0, 0.0,-2.0 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_11() - { - // cutting tetra intersects the UT and touches it at an edge - double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 - {-1.0,-4.0, 2.0 }, // OX - {-1.0, 4.0, 2.0 }, // OY - {-1.0, 0.0,-1.0 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.15873 , vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.230952, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.260714, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_12() - { - // cutting tetra has one corner inside the UT and one its side passes through an UT edge - double nodes[4][3] = { { 0.25, 0.25, 0.25 }, // 0 - { 1.75,-0.25,-0.25 }, // OX - { 0.5 , 0.25, 0.25 }, // OY - { 0.5 , 0 , 0.5 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.005208 , vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.562500, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125000, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[2], 1e-5); - } - - struct __MESH_DUMMY - { - typedef int MyConnType; - }; - - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_13() - { - double T[] = { - 66.6666666666666714,133.333333333333343,66.6666666666666714, - 100,200,100, - 100,100,100, - 200,200,0 }; - - double S[] = { - 100,166.666666666666657,66.6666666666666714, - 100,150,50, - 75,150,75, - 100,100,100}; - - int conn[4] = { 0,1,2,3 }; - - const double* tnodes[4]={ T, T+3, T+6, T+9 }; - const double* snodes[4]={ S, S+3, S+6, S+9 }; - - __MESH_DUMMY dummyMesh; - SplitterTetra<__MESH_DUMMY> src( dummyMesh, snodes, conn ); - double volume = src.intersectTetra( tnodes ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6944.4444444444443,volume,1e-9); - } - - void UnitTetraIntersectionBaryTest::test_TetraAffineTransform_reverseApply() - { - double nodes[12] = { -4.0, 9.0, 3.0, - 11.0, 0.0, 2.0, - 0.0, 0.0, 0.0, - 2.0, 1.0,10.0 }; - // double pSrc[3] = { -4.0, 9.0, 3.0 }; - double pSrc[3] = { 40., -20., 100. }; - double pDest[] = {1,1,1}; - TetraAffineTransform a(nodes); - a.apply( pDest, pSrc ); - a.reverseApply( pDest, pDest ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[0], pDest[0], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[1], pDest[1], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[2], pDest[2], 1e-12); - } - - void UnitTetraIntersectionBaryTest::test_barycentric_coords() - { - // compute barycentric coordinates - double nodes[4][3] = { {11.0, 0.0, 2.0 }, - {-4.0, 9.0, 3.0 }, - { 0.0, 0.0, 0.0 }, - { 6.0, 1.0,10.0 }}; - std::vector n (4); - n[0] = &nodes[0][0]; - n[1] = &nodes[1][0]; - n[2] = &nodes[2][0]; - n[3] = &nodes[3][0]; - double p [3] = { 2, 2, 5 }, bc[4]; - barycentric_coords(n, p, bc); - double bcSum = 0; - double p2 [3] = { 0,0,0 }; - for ( int i = 0; i < 4; ++i ) { - bcSum += bc[i]; - p2[0] += bc[i]*n[i][0]; - p2[1] += bc[i]*n[i][1]; - p2[2] += bc[i]*n[i][2]; - } - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., bcSum, 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( p[0], p2[0], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( p[1], p2[1], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( p[2], p2[2], 1e-12); - } -} diff --git a/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx b/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx deleted file mode 100644 index 220da14bc..000000000 --- a/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : UnitTetraIntersectionBaryTests.hxx -// Created : Thu Nov 6 17:11:27 2008 -// Author : Edward AGAPOV (eap) -// -#ifndef __UNITTETRAINTERSECTIONBARYTEST_HXX__ -#define __UNITTETRAINTERSECTIONBARYTEST_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Test suite testing UnitTetraIntersectionBary class. - * - */ - class INTERPKERNELTEST_EXPORT UnitTetraIntersectionBaryTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( UnitTetraIntersectionBaryTest ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_13 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_12 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_1 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_2 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_3 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_4 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_5 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_6 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_7 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_8 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_9 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_10 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_11 ); - CPPUNIT_TEST( test_TetraAffineTransform_reverseApply ); - CPPUNIT_TEST( test_barycentric_coords ); - CPPUNIT_TEST_SUITE_END(); - public: - void test_UnitTetraIntersectionBary_1(); - void test_UnitTetraIntersectionBary_2(); - void test_UnitTetraIntersectionBary_3(); - void test_UnitTetraIntersectionBary_4(); - void test_UnitTetraIntersectionBary_5(); - void test_UnitTetraIntersectionBary_6(); - void test_UnitTetraIntersectionBary_7(); - void test_UnitTetraIntersectionBary_8(); - void test_UnitTetraIntersectionBary_9(); - void test_UnitTetraIntersectionBary_10(); - void test_UnitTetraIntersectionBary_11(); - void test_UnitTetraIntersectionBary_12(); - void test_UnitTetraIntersectionBary_13(); - void test_TetraAffineTransform_reverseApply(); - void test_barycentric_coords(); - }; -} - -#endif diff --git a/medtool/src/INTERP_KERNELTest/perf_test.py b/medtool/src/INTERP_KERNELTest/perf_test.py deleted file mode 100755 index 97f5579b0..000000000 --- a/medtool/src/INTERP_KERNELTest/perf_test.py +++ /dev/null @@ -1,146 +0,0 @@ -#! /bin/env python -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -import re -import sys -import time -import subprocess - -RES_FILE="perf_OPTIMIZE" - -def test_pair(par1,par2): - c=re.compile("[\D]*(?P[\d]+)") - val1=c.match(par1).group("num") - val2=c.match(par2).group("num") - st="%s %s"%(val1,val2) - ret=subprocess.call(["./PerfTest",par1,par2]) - if ret!=0: - f=file(RES_FILE,"w") ; f.write("Error on case %s %s !!!!\n"%(par1,par2)) ; del f - sys.exit(ret) - pass - return st - -def test_box_box(): - st="PerfBox PerfBox\n" - st+=test_pair("PerfBox1495","PerfBox1495") - st+=test_pair("PerfBox2506","PerfBox2506") - st+=test_pair("PerfBox5708","PerfBox5708") - st+=test_pair("PerfBox13461","PerfBox13461") - st+=test_pair("PerfBox30808","PerfBox30808") - st+=test_pair("PerfBox47176","PerfBox47176") - st+=test_pair("PerfBox1495","PerfBox2506") - st+=test_pair("PerfBox1495","PerfBox5708") - st+=test_pair("PerfBox1495","PerfBox13461") - st+=test_pair("PerfBox1495","PerfBox30808") - st+=test_pair("PerfBox1495","PerfBox47176") - st+=test_pair("PerfBox2506","PerfBox5708") - st+=test_pair("PerfBox2506","PerfBox13461") - st+=test_pair("PerfBox2506","PerfBox30808") - st+=test_pair("PerfBox2506","PerfBox47176") - st+=test_pair("PerfBox5708","PerfBox13461") - st+=test_pair("PerfBox5708","PerfBox30808") - st+=test_pair("PerfBox5708","PerfBox47176") - st+=test_pair("PerfBox13461","PerfBox30808") - st+=test_pair("PerfBox13461","PerfBox47176") - st+=test_pair("PerfBox30808","PerfBox47176") - pass - -def test_cyl_cyl(): - st="PerfCyl PerfCyl\n" - st+=test_pair("PerfCyl1047","PerfCyl1047") - st+=test_pair("PerfCyl3020","PerfCyl3020") - st+=test_pair("PerfCyl6556","PerfCyl6556") - st+=test_pair("PerfCyl9766","PerfCyl9766") - st+=test_pair("PerfCyl25745","PerfCyl25745") - st+=test_pair("PerfCyl47601","PerfCyl47601") - st+=test_pair("PerfCyl1047","PerfCyl3020") - st+=test_pair("PerfCyl1047","PerfCyl6556") - st+=test_pair("PerfCyl1047","PerfCyl9766") - st+=test_pair("PerfCyl1047","PerfCyl25745") - st+=test_pair("PerfCyl1047","PerfCyl47601") - st+=test_pair("PerfCyl3020","PerfCyl6556") - st+=test_pair("PerfCyl3020","PerfCyl9766") - st+=test_pair("PerfCyl3020","PerfCyl25745") - st+=test_pair("PerfCyl3020","PerfCyl47601") - st+=test_pair("PerfCyl6556","PerfCyl9766") - st+=test_pair("PerfCyl6556","PerfCyl25745") - st+=test_pair("PerfCyl6556","PerfCyl47601") - st+=test_pair("PerfCyl9766","PerfCyl25745") - st+=test_pair("PerfCyl9766","PerfCyl47601") - st+=test_pair("PerfCyl25745","PerfCyl47601") - return st - -def test_box_cyl(): - st="PerfBox PerfCyl\n" - st+=test_pair("PerfBox1495","PerfCyl1047") - st+=test_pair("PerfBox1495","PerfCyl3020") - st+=test_pair("PerfBox1495","PerfCyl6556") - st+=test_pair("PerfBox1495","PerfCyl9766") - st+=test_pair("PerfBox1495","PerfCyl25745") - st+=test_pair("PerfBox1495","PerfCyl47601") - st+=test_pair("PerfBox2506","PerfCyl1047") - st+=test_pair("PerfBox2506","PerfCyl3020") - st+=test_pair("PerfBox2506","PerfCyl6556") - st+=test_pair("PerfBox2506","PerfCyl9766") - st+=test_pair("PerfBox2506","PerfCyl25745") - st+=test_pair("PerfBox2506","PerfCyl47601") - st+=test_pair("PerfBox5708","PerfCyl1047") - st+=test_pair("PerfBox5708","PerfCyl3020") - st+=test_pair("PerfBox5708","PerfCyl6556") - st+=test_pair("PerfBox5708","PerfCyl9766") - st+=test_pair("PerfBox5708","PerfCyl25745") - st+=test_pair("PerfBox5708","PerfCyl47601") - st+=test_pair("PerfBox13461","PerfCyl1047") - st+=test_pair("PerfBox13461","PerfCyl3020") - st+=test_pair("PerfBox13461","PerfCyl6556") - st+=test_pair("PerfBox13461","PerfCyl9766") - st+=test_pair("PerfBox13461","PerfCyl25745") - st+=test_pair("PerfBox13461","PerfCyl47601") - st+=test_pair("PerfBox30808","PerfCyl1047") - st+=test_pair("PerfBox30808","PerfCyl3020") - st+=test_pair("PerfBox30808","PerfCyl6556") - st+=test_pair("PerfBox30808","PerfCyl9766") - st+=test_pair("PerfBox30808","PerfCyl25745") - st+=test_pair("PerfBox30808","PerfCyl47601") - st+=test_pair("PerfBox47176","PerfCyl1047") - st+=test_pair("PerfBox47176","PerfCyl3020") - st+=test_pair("PerfBox47176","PerfCyl6556") - st+=test_pair("PerfBox47176","PerfCyl9766") - st+=test_pair("PerfBox47176","PerfCyl25745") - st+=test_pair("PerfBox47176","PerfCyl47601") - return st - -def test_box_transbox(): - st=" PerfBox PerfBoxT\n" - st+=test_pair("PerfBox1495","PerfBoxT1493") - st+=test_pair("PerfBox2506","PerfBoxT2676") - st+=test_pair("PerfBox5708","PerfBoxT5717") - st+=test_pair("PerfBox13461","PerfBoxT12469") - st+=test_pair("PerfBox30808","PerfBoxT29019") - st+=test_pair("PerfBox47176","PerfBoxT47278") - return st - -gm=time.strftime("%a. %B %H:%M:%S",gm).lower()+time.strftime(" CET %Y",gm) -st="PerfTest execution on %s\n"%(time.strftime("%a. %B %H:%M:%S",gm).lower()+time.strftime(" CET %Y",gm)) -st+=test_box_cyl() -st+=test_box_box() -st+=test_cyl_cyl() -st+=test_box_transbox() -f=file(RES_FILE,"w") diff --git a/medtool/src/INTERP_KERNELTest/perf_test.sh b/medtool/src/INTERP_KERNELTest/perf_test.sh deleted file mode 100755 index d65415e1d..000000000 --- a/medtool/src/INTERP_KERNELTest/perf_test.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/bin/bash -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# should be run from the build directory, so that ./PerfTest is available -# output file -# -RES_FILE=perf_OPTIMIZE - -#outputs lines of form : -#"no. source elems no. target elems user time" -function test_pair { - echo -n $1 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE - echo -n " " >> $RES_FILE - echo -n $2 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE - echo -n " " >> $RES_FILE - time -o $RES_FILE --append -f"%U" ./PerfTest $1 $2 - echo -} - -function test_box_box { -echo PerfBox PerfBox >> $RES_FILE - -test_pair PerfBox1495 PerfBox1495 -test_pair PerfBox2506 PerfBox2506 -test_pair PerfBox5708 PerfBox5708 -test_pair PerfBox13461 PerfBox13461 -test_pair PerfBox30808 PerfBox30808 -test_pair PerfBox47176 PerfBox47176 - -test_pair PerfBox1495 PerfBox2506 -test_pair PerfBox1495 PerfBox5708 -test_pair PerfBox1495 PerfBox13461 -test_pair PerfBox1495 PerfBox30808 -test_pair PerfBox1495 PerfBox47176 - -test_pair PerfBox2506 PerfBox5708 -test_pair PerfBox2506 PerfBox13461 -test_pair PerfBox2506 PerfBox30808 -test_pair PerfBox2506 PerfBox47176 - -test_pair PerfBox5708 PerfBox13461 -test_pair PerfBox5708 PerfBox30808 -test_pair PerfBox5708 PerfBox47176 - -test_pair PerfBox13461 PerfBox30808 -test_pair PerfBox13461 PerfBox47176 - -test_pair PerfBox30808 PerfBox47176 - -} - -function test_cyl_cyl { -echo PerfCyl PerfCyl >> $RES_FILE - -test_pair PerfCyl1047 PerfCyl1047 -test_pair PerfCyl3020 PerfCyl3020 -test_pair PerfCyl6556 PerfCyl6556 -test_pair PerfCyl9766 PerfCyl9766 -test_pair PerfCyl25745 PerfCyl25745 -test_pair PerfCyl47601 PerfCyl47601 - -test_pair PerfCyl1047 PerfCyl3020 -test_pair PerfCyl1047 PerfCyl6556 -test_pair PerfCyl1047 PerfCyl9766 -test_pair PerfCyl1047 PerfCyl25745 -test_pair PerfCyl1047 PerfCyl47601 - -test_pair PerfCyl3020 PerfCyl6556 -test_pair PerfCyl3020 PerfCyl9766 -test_pair PerfCyl3020 PerfCyl25745 -test_pair PerfCyl3020 PerfCyl47601 - -test_pair PerfCyl6556 PerfCyl9766 -test_pair PerfCyl6556 PerfCyl25745 -test_pair PerfCyl6556 PerfCyl47601 - -test_pair PerfCyl9766 PerfCyl25745 -test_pair PerfCyl9766 PerfCyl47601 - -test_pair PerfCyl25745 PerfCyl47601 - -} - -function test_box_cyl { - echo PerfBox PerfCyl >> $RES_FILE - test_pair PerfBox1495 PerfCyl1047 - test_pair PerfBox1495 PerfCyl3020 - test_pair PerfBox1495 PerfCyl6556 - test_pair PerfBox1495 PerfCyl9766 - test_pair PerfBox1495 PerfCyl25745 - test_pair PerfBox1495 PerfCyl47601 - - test_pair PerfBox2506 PerfCyl1047 - test_pair PerfBox2506 PerfCyl3020 - test_pair PerfBox2506 PerfCyl6556 - test_pair PerfBox2506 PerfCyl9766 - test_pair PerfBox2506 PerfCyl25745 - test_pair PerfBox2506 PerfCyl47601 - - test_pair PerfBox5708 PerfCyl1047 - test_pair PerfBox5708 PerfCyl3020 - test_pair PerfBox5708 PerfCyl6556 - test_pair PerfBox5708 PerfCyl9766 - test_pair PerfBox5708 PerfCyl25745 - test_pair PerfBox5708 PerfCyl47601 - - test_pair PerfBox13461 PerfCyl1047 - test_pair PerfBox13461 PerfCyl3020 - test_pair PerfBox13461 PerfCyl6556 - test_pair PerfBox13461 PerfCyl9766 - test_pair PerfBox13461 PerfCyl25745 - test_pair PerfBox13461 PerfCyl47601 - - test_pair PerfBox30808 PerfCyl1047 - test_pair PerfBox30808 PerfCyl3020 - test_pair PerfBox30808 PerfCyl6556 - test_pair PerfBox30808 PerfCyl9766 - test_pair PerfBox30808 PerfCyl25745 - test_pair PerfBox30808 PerfCyl47601 - - test_pair PerfBox47176 PerfCyl1047 - test_pair PerfBox47176 PerfCyl3020 - test_pair PerfBox47176 PerfCyl6556 - test_pair PerfBox47176 PerfCyl9766 - test_pair PerfBox47176 PerfCyl25745 - test_pair PerfBox47176 PerfCyl47601 -} - -function test_box_transbox { - echo PerfBox PerfBoxT >> $RES_FILE - test_pair PerfBox1495 PerfBoxT1493 - test_pair PerfBox2506 PerfBoxT2676 - test_pair PerfBox5708 PerfBoxT5717 - test_pair PerfBox13461 PerfBoxT12469 - test_pair PerfBox30808 PerfBoxT29019 - test_pair PerfBox47176 PerfBoxT47278 -} - - - -#functions to execute : - -echo PerfTest execution on `date` > $RES_FILE -test_box_cyl -test_box_box -test_cyl_cyl -test_box_transbox - -cat $RES_FILE \ No newline at end of file diff --git a/medtool/src/MEDCoupling/CMakeLists.txt b/medtool/src/MEDCoupling/CMakeLists.txt deleted file mode 100644 index ec1570ace..000000000 --- a/medtool/src/MEDCoupling/CMakeLists.txt +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -IF(MEDCOUPLING_BUILD_TESTS) - ADD_SUBDIRECTORY(Test) -ENDIF(MEDCOUPLING_BUILD_TESTS) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_BINARY_DIR}/../.. - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SET(medcoupling_SOURCES - MEDCouplingField.cxx - MEDCouplingFieldDouble.cxx - MEDCouplingUMesh.cxx - MEDCoupling1GTUMesh.cxx - MEDCouplingMemArray.cxx - MEDCouplingMemArrayChar.cxx - MEDCouplingTimeLabel.cxx - MEDCouplingCMesh.cxx - MEDCouplingIMesh.cxx - MEDCouplingCurveLinearMesh.cxx - MEDCouplingStructuredMesh.cxx - MEDCouplingTimeDiscretization.cxx - MEDCouplingFieldDiscretization.cxx - MEDCouplingRefCountObject.cxx - MEDCouplingPointSet.cxx - MEDCouplingFieldTemplate.cxx - MEDCouplingExtrudedMesh.cxx - MEDCouplingMesh.cxx - MEDCouplingGaussLocalization.cxx - MEDCouplingNatureOfField.cxx - MEDCouplingMultiFields.cxx - MEDCouplingDefinitionTime.cxx - MEDCouplingFieldOverTime.cxx - MEDCouplingCartesianAMRMesh.cxx - MEDCouplingAMRAttribute.cxx - MEDCouplingMatrix.cxx - MEDCouplingPartDefinition.cxx - MEDCouplingSkyLineArray.cxx - ) - -SET(medcouplingremapper_SOURCES - MEDCouplingRemapper.cxx - ) - -ADD_LIBRARY(medcoupling SHARED ${medcoupling_SOURCES}) -TARGET_LINK_LIBRARIES(medcoupling interpkernel) -INSTALL(TARGETS medcoupling EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -ADD_LIBRARY(medcouplingremapper SHARED ${medcouplingremapper_SOURCES}) -TARGET_LINK_LIBRARIES(medcouplingremapper medcoupling) -INSTALL(TARGETS medcouplingremapper EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -FILE(GLOB medcoupling_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") -FILE(GLOB medcoupling_HEADERS_TXX "${CMAKE_CURRENT_SOURCE_DIR}/*.txx") -INSTALL(FILES ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} MEDCouplingNatureOfFieldEnum DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -# To allow usage as SWIG dependencies: -SET(medcoupling_HEADERS_HXX PARENT_SCOPE) -SET(medcoupling_HEADERS_TXX PARENT_SCOPE) diff --git a/medtool/src/MEDCoupling/MEDCoupling.hxx b/medtool/src/MEDCoupling/MEDCoupling.hxx deleted file mode 100644 index 813515ac8..000000000 --- a/medtool/src/MEDCoupling/MEDCoupling.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef _MEDCOUPLING_HXX_ -#define _MEDCOUPLING_HXX_ - -#ifdef WIN32 -# if defined medcoupling_EXPORTS -# define MEDCOUPLING_EXPORT __declspec( dllexport ) -# else -# define MEDCOUPLING_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDCOUPLING_EXPORT -#endif - -#ifdef WIN32 -# if defined medcouplingremapper_EXPORTS -# define MEDCOUPLINGREMAPPER_EXPORT __declspec( dllexport ) -# else -# define MEDCOUPLINGREMAPPER_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDCOUPLINGREMAPPER_EXPORT -#endif - -#ifdef WIN32 -#pragma warning( disable : 4290 ) -#endif - -#endif diff --git a/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.cxx b/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.cxx deleted file mode 100644 index 38eae7a7e..000000000 --- a/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.cxx +++ /dev/null @@ -1,3740 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingCMesh.hxx" - -#include "SplitterTetra.hxx" -#include "DiameterCalculator.hxx" -#include "InterpKernelAutoPtr.hxx" - -using namespace ParaMEDMEM; - -const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5}; - -MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0) -{ -} - -MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm) -{ - setName(name); -} - -MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm) -{ -} - -MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) -{ - if(type==INTERP_KERNEL::NORM_ERROR) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(!cm.isDynamic()) - return MEDCoupling1SGTUMesh::New(name,type); - else - return MEDCoupling1DGTUMesh::New(name,type); -} - -MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !"); - std::set gts(m->getAllGeoTypes()); - if(gts.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin()); - if(!cm.isDynamic()) - return MEDCoupling1SGTUMesh::New(m); - else - return MEDCoupling1DGTUMesh::New(m); -} - -const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const -{ - return *_cm; -} - -INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const -{ - return _cm->getEnum(); -} - -int MEDCoupling1GTUMesh::getMeshDimension() const -{ - return (int)_cm->getDimension(); -} - -/*! - * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. - * This method does not throw exception if geometric type \a type is not in \a this. - * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. - * The coordinates array is not considered here. - * - * \param [in] type the geometric type - * \return cell ids in this having geometric type \a type. - */ -DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - if(type==getCellModelEnum()) - ret->alloc(getNumberOfCells(),1); - else - ret->alloc(0,1); - ret->iota(); - return ret.retn(); -} - -/*! - * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. - */ -int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - return type==getCellModelEnum()?getNumberOfCells():0; -} - -/*! - * Returns a type of a cell by its id. - * \param [in] cellId - the id of the cell of interest. - * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type. - * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). - */ -INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const -{ - if(cellId>=0 && cellId - the set of cell types. - * \warning this method does not throw any exception even if \a this is not defined. - */ -std::set MEDCoupling1GTUMesh::getAllGeoTypes() const -{ - std::set ret; - ret.insert(getCellModelEnum()); - return ret; -} - -/*! - * This method expects that \a this is sorted by types. If not an exception will be thrown. - * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how - * \a this is composed in cell types. - * The returned array is of size 3*n where n is the number of different types present in \a this. - * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. - * This parameter is kept only for compatibility with other methode listed above. - */ -std::vector MEDCoupling1GTUMesh::getDistributionOfTypes() const -{ - std::vector ret(3); - ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1; - return ret; -} - -/*! - * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. - * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. - * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. - * - * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. - * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, - * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] - * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. - * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. - * - * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. - * - * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined - * - * \b Example1:
- * - Before \a this has 3 cells \a profile contains [0,1,2] - * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty
- * - * \b Example2:
- * - Before \a this has 3 cells \a profile contains [1,2] - * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
- - */ -void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - if(!profile) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !"); - if(profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !"); - int nbTuples=profile->getNumberOfTuples(); - int nbOfCells=getNumberOfCells(); - code.resize(3); idsInPflPerType.resize(1); - code[0]=(int)getCellModelEnum(); code[1]=nbTuples; - idsInPflPerType.resize(1); - if(profile->isIdentity() && nbTuples==nbOfCells) - { - code[2]=-1; - idsInPflPerType[0]=const_cast(profile); idsInPflPerType[0]->incrRef(); - idsPerType.clear(); - return ; - } - code[2]=0; - profile->checkAllIdsInRange(0,nbOfCells); - idsPerType.resize(1); - idsPerType[0]=const_cast(profile); idsPerType[0]->incrRef(); - idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); -} - -/*! - * This method tries to minimize at most the number of deep copy. - * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. - * - * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig - */ -DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - int nbOfCells=getNumberOfCells(); - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); - if(code[0]!=(int)getCellModelEnum()) - { - std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(code[2]==-1) - { - if(code[1]==nbOfCells) - return 0; - else - { - std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(code[2]!=0) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); - if(idsPerType.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); - const DataArrayInt *pfl=idsPerType[0]; - if(!pfl) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); - if(pfl->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); - pfl->checkAllIdsInRange(0,nbOfCells); - pfl->incrRef(); - return const_cast(pfl); -} - -void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - m->writeVTKLL(ofs,cellData,pointData,byteData); -} - -std::string MEDCoupling1GTUMesh::getVTKDataSetType() const -{ - return std::string("UnstructuredGrid"); -} - -std::string MEDCoupling1GTUMesh::getVTKFileExtension() const -{ - return std::string("vtu"); -} - -std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren(); -} - -bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCoupling1GTUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingSGTUMesh !"; - return false; - } - if(_cm!=otherC->_cm) - { - reason="mismatch in geometric type !"; - return false; - } - return true; -} - -bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) - return false; - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); - const MEDCoupling1GTUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_cm!=otherC->_cm) - return false; - return true; -} - -void MEDCoupling1GTUMesh::checkCoherency() const -{ - MEDCouplingPointSet::checkCoherency(); -} - -DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->getBarycenterAndOwner(); - return ret.retn(); -} - -MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->getMeasureField(isAbs); - ret->setMesh(this); - return ret.retn(); -} - -MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->getMeasureFieldOnNode(isAbs); - ret->setMesh(this); - return ret.retn(); -} - -/*! - * to improve perf ! - */ -int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->getCellContainingPoint(pos,eps); -} - -MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->buildOrthogonalField(); - ret->setMesh(this); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->getCellsInBoundingBox(bbox,eps); -} - -DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->getCellsInBoundingBox(bbox,eps); -} - -MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->buildFacePartOfMySelfNode(start,end,fullyIn); -} - -DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->findBoundaryNodes(); -} - -MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->buildBoundaryMesh(keepCoords); -} - -void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr); -} - -int MEDCoupling1GTUMesh::getNodalConnectivityLength() const -{ - const DataArrayInt *c1(getNodalConnectivity()); - if(!c1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !"); - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !"); - if(!c1->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !"); - return c1->getNumberOfTuples(); -} - -/*! - * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned). - * The order of cells is the returned instance is those in the order of instances in \a parts. - * - * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates. - * \return MEDCouplingUMesh * - new object to be dealt by the caller. - * - * \throw If one element is null in \a parts. - * \throw If not all the parts do not have the same mesh dimension. - * \throw If not all the parts do not share the same coordinates. - * \throw If not all the parts have their connectivity set properly. - * \throw If \a parts is empty. - */ -MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) -{ - if(parts.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !"); - const MEDCoupling1GTUMesh *firstPart(parts[0]); - if(!firstPart) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !"); - const DataArrayDouble *coords(firstPart->getCoords()); - int meshDim(firstPart->getMeshDimension()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription()); - ret->setCoords(coords); - int nbOfCells(0),connSize(0); - for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !"); - if((*it)->getMeshDimension()!=meshDim) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !"); - if((*it)->getCoords()!=coords) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !"); - nbOfCells+=(*it)->getNumberOfCells(); - connSize+=(*it)->getNodalConnectivityLength(); - } - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1); - int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0; - for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++) - { - int curNbCells((*it)->getNumberOfCells()); - int geoType((int)(*it)->getCellModelEnum()); - const int *cinPtr((*it)->getNodalConnectivity()->begin()); - const MEDCoupling1SGTUMesh *ps(dynamic_cast(*it)); - const MEDCoupling1DGTUMesh *pd(dynamic_cast(*it)); - if(ps && !pd) - { - int nNodesPerCell(ps->getNumberOfNodesPerCell()); - for(int i=0;igetNodalConnectivityIndex()->begin()); - for(int i=0;isetConnectivity(conn,connI,true); - return ret.retn(); -} - -//== - -MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) -{ - if(recDeepCpy) - { - const DataArrayInt *c(other._conn); - if(c) - _conn=c->deepCpy(); - } -} - -MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) -{ -} - -MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh() -{ -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New() -{ - return new MEDCoupling1SGTUMesh; -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) -{ - if(type==INTERP_KERNEL::NORM_ERROR) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return new MEDCoupling1SGTUMesh(name,cm); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !"); - std::set gts(m->getAllGeoTypes()); - if(gts.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !"); - int geoType((int)*gts.begin()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin())); - ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription()); - int nbCells(m->getNumberOfCells()); - int nbOfNodesPerCell(ret->getNumberOfNodesPerCell()); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1); - int *c(conn->getPointer()); - const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin()); - for(int i=0;isetNodalConnectivity(conn); - try - { ret->copyTinyInfoFrom(m); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const -{ - return new MEDCoupling1SGTUMesh(*this,recDeepCpy); -} - -/*! - * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. - * The coordinates are shared between \a this and the returned instance. - * - * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) - * \sa MEDCoupling1SGTUMesh::deepCpy - */ -MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr c(_conn->deepCpy()); - ret->setNodalConnectivity(c); - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !"); - setNodalConnectivity(otherC->getNodalConnectivity()); -} - -void MEDCoupling1SGTUMesh::updateTime() const -{ - MEDCoupling1GTUMesh::updateTime(); - const DataArrayInt *c(_conn); - if(c) - updateTimeWith(*c); -} - -std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayInt *)_conn); - return ret; -} - -MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const -{ - return clone(true); -} - -bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !"); - std::ostringstream oss; oss.precision(15); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !"; - return false; - } - if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - { - reason="in connectivity of single static geometric type exactly one among this and other is null !"; - return false; - } - if(!c1->isEqualIfNotWhy(*c2,reason)) - { - reason.insert(0,"Nodal connectivity DataArrayInt differ : "); - return false; - } - return true; -} - -bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - return false; - if(!c1->isEqualWithoutConsideringStr(*c2)) - return false; - return true; -} - -void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const -{ - const DataArrayInt *c1(_conn); - if(c1) - { - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); - if(c1->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); - c1->checkAllocated(); - } - else - throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); -} - -void MEDCoupling1SGTUMesh::checkCoherency() const -{ - MEDCouplingPointSet::checkCoherency(); - checkCoherencyOfConnectivity(); -} - -void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - const DataArrayInt *c1(_conn); - int nbOfTuples=c1->getNumberOfTuples(); - int nbOfNodesPerCell=(int)_cm->getNumberOfNodes(); - if(nbOfTuples%nbOfNodesPerCell!=0) - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=nbOfTuples/nbOfNodesPerCell; - const int *w(c1->begin()); - for(int i=0;i=nbOfNodes) - { - std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -int MEDCoupling1SGTUMesh::getNumberOfCells() const -{ - int nbOfTuples=getNodalConnectivityLength(); - int nbOfNodesPerCell=getNumberOfNodesPerCell(); - if(nbOfTuples%nbOfNodesPerCell!=0) - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return nbOfTuples/nbOfNodesPerCell; -} - -int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const -{ - return getNumberOfNodesPerCell(); -} - -int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const -{ - checkNonDynamicGeoType(); - return (int)_cm->getNumberOfNodes(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const -{ - checkNonDynamicGeoType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfCells(),1); - ret->fillWithValue((int)_cm->getNumberOfNodes()); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const -{ - checkNonDynamicGeoType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfCells(),1); - ret->fillWithValue((int)_cm->getNumberOfSons()); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const -{ - checkNonDynamicGeoType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbCells(getNumberOfCells()); - ret->alloc(nbCells,1); - int *retPtr(ret->getPointer()); - int nbNodesPerCell(getNumberOfNodesPerCell()); - const int *conn(_conn->begin()); - for(int i=0;i s(conn,conn+nbNodesPerCell); - *retPtr=(int)s.size(); - } - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int sz=getNumberOfNodesPerCell(); - conn.resize(sz); - if(cellId>=0 && cellIdbegin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin()); - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const -{ - if(_cm->isDynamic()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !"); -} - -std::string MEDCoupling1SGTUMesh::simpleRepr() const -{ - static const char msg0[]="No coordinates specified !"; - std::ostringstream ret; - ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; - if(_coords!=0) - { - const int spaceDim=getSpaceDimension(); - ret << spaceDim << "\nInfo attached on space dimension : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - ret << msg0 << "\n"; - ret << "Number of nodes : "; - if(_coords!=0) - ret << getNumberOfNodes() << "\n"; - else - ret << msg0 << "\n"; - ret << "Number of cells : "; - if((const DataArrayInt *)_conn) - { - if(_conn->isAllocated()) - { - if(_conn->getNumberOfComponents()==1) - ret << getNumberOfCells() << "\n"; - else - ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; - } - else - ret << "Nodal connectivity array specified but not allocated !" << "\n"; - } - else - ret << "No connectivity specified !" << "\n"; - ret << "Cell type : " << _cm->getRepr() << "\n"; - return ret.str(); -} - -std::string MEDCoupling1SGTUMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << simpleRepr(); - ret << "\nCoordinates array : \n___________________\n\n"; - if(_coords) - _coords->reprWithoutNameStream(ret); - else - ret << "No array set !\n"; - ret << "\n\nConnectivity array : \n____________________\n\n"; - // - if((const DataArrayInt *)_conn) - { - if(_conn->isAllocated()) - { - if(_conn->getNumberOfComponents()==1) - { - int nbOfCells=getNumberOfCells(); - int sz=getNumberOfNodesPerCell(); - const int *connPtr=_conn->begin(); - for(int i=0;i(ret," ")); - ret << "\n"; - } - } - else - ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; - } - else - ret << "Nodal connectivity array specified but not allocated !" << "\n"; - } - else - ret << "No connectivity specified !" << "\n"; - return ret.str(); -} - -DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells();//checkCoherency() - int nbOfNodes=getNumberOfNodes(); - ret->alloc(nbOfCells,spaceDim); - double *ptToFill=ret->getPointer(); - const double *coor=_coords->begin(); - const int *nodal=_conn->begin(); - int sz=getNumberOfNodesPerCell(); - double coeff=1./(double)sz; - for(int i=0;i=0 && *nodal()); - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),coeff)); - } - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) -{ - int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); - o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); - if(check) - o2n=o2n->checkAndPreparePermutation(); - // - const int *conn=_conn->begin(); - MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(nbCells); - const int *n2oPtr=n2o->begin(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - newConn->alloc(_conn->getNumberOfTuples(),1); - newConn->copyStringInfoFrom(*_conn); - int sz=getNumberOfNodesPerCell(); - // - int *newC=newConn->getPointer(); - for(int i=0;i cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); - int tmp=-1; - int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; - std::vector fastFinder(sz,false); - for(const int *work=begin;work!=end;work++) - if(*work>=0 && *workbegin(); - int nbNodesPerCell=getNumberOfNodesPerCell(); - for(int i=0;i=0) - { - ref++; - if(fastFinder[conn[j]]) - nbOfHit++; - } - if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) - cellIdsKept->pushBackSilent(i); - } - cellIdsKeptArr=cellIdsKept.retn(); -} - -MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !"); - const MEDCoupling1SGTUMesh *otherC=static_cast(other); - return Merge1SGTUMeshes(this,otherC); -} - -MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); - ret->setCoords(getCoords()); - const int *nodalConn=_conn->begin(); - int nbCells=getNumberOfCells(); - int nbNodesPerCell=getNumberOfNodesPerCell(); - int geoType=(int)getCellModelEnum(); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1); - int *cPtr=c->getPointer(); - for(int i=0;i cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1); - ret->setConnectivity(c,cI,true); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) -{ - switch(policy) - { - case 0: - return simplexizePol0(); - case 1: - return simplexizePol1(); - case (int) INTERP_KERNEL::PLANAR_FACE_5: - return simplexizePlanarFace5(); - case (int) INTERP_KERNEL::PLANAR_FACE_6: - return simplexizePlanarFace6(); - default: - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); - } -} - -/// @cond INTERNAL - -struct MEDCouplingAccVisit -{ - MEDCouplingAccVisit():_new_nb_of_nodes(0) { } - int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } - int _new_nb_of_nodes; -}; - -/// @endcond - -/*! - * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller. - * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except - * the format of returned DataArrayInt instance. - * - * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. - * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const -{ - checkCoherencyOfConnectivity(); - int nbNodes(getNumberOfNodes()); - std::vector fetchedNodes(nbNodes,false); - computeNodeIdsAlg(fetchedNodes); - int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - int *retPtr(ret->getPointer()); - for(int i=0;igetNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const -{ - nbrOfNodesInUse=-1; - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - ret->alloc(nbOfNodes,1); - int *traducer=ret->getPointer(); - std::fill(traducer,traducer+nbOfNodes,-1); - const int *conn=_conn->begin(); - int nbNodesPerCell=getNumberOfNodesPerCell(); - for(int i=0;i=0 && *connapplyLin(1,offset); - updateTime(); -} - -/*! - * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead - * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction - * of a big mesh. - */ -void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - int *begPtr(_conn->getPointer()); - int nbElt(_conn->getNumberOfTuples()); - int *endPtr(begPtr+nbElt); - for(int *it=begPtr;it!=endPtr;it++) - { - INTERP_KERNEL::HashMap::const_iterator it2(newNodeNumbersO2N.find(*it)); - if(it2!=newNodeNumbersO2N.end()) - { - *it=(*it2).second; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - updateTime(); -} - -/*! - * Changes ids of nodes within the nodal connectivity arrays according to a permutation - * array in "Old to New" mode. The node coordinates array is \b not changed by this method. - * This method is a generalization of shiftNodeNumbersInConn(). - * \warning This method performs no check of validity of new ids. **Use it with care !** - * \param [in] newNodeNumbersO2N - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \throw If the nodal connectivity of cells is not defined. - */ -void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes()); - updateTime(); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); - return Merge1SGTUMeshes(tmp); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector& a) -{ - std::size_t sz=a.size(); - if(sz==0) - return Merge1SGTUMeshesLL(a); - for(std::size_t ii=0;iigetCellModel()); - for(std::size_t ii=0;iigetCellModel())!=cm) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > bb(sz); - std::vector< const MEDCoupling1SGTUMesh * > aa(sz); - int spaceDim=-3; - for(std::size_t i=0;igetCoords(); - if(coo) - spaceDim=coo->getNumberOfComponents(); - } - if(spaceDim==-3) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !"); - for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); - aa[i]=bb[i]; - } - return Merge1SGTUMeshesLL(aa); -} - -/*! - * \throw If presence of a null instance in the input vector \a a. - * \throw If a is empty - */ -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !"); - std::vector ncs(a.size()); - (*it)->getNumberOfCells();//to check that all is OK - const DataArrayDouble *coords=(*it)->getCoords(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - ncs[0]=(*it)->getNodalConnectivity(); - it++; - for(int i=1;it!=a.end();i++,it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !"); - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); - (*it)->getNumberOfCells();//to check that all is OK - ncs[i]=(*it)->getNodalConnectivity(); - if(coords!=(*it)->getCoords()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !"); - } - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh("merge",*cm)); - ret->setCoords(coords); - ret->_conn=DataArrayInt::Aggregate(ncs); - return ret.retn(); -} - -/*! - * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL) - */ -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - int nbOfCells=(*it)->getNumberOfCells(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - int nbNodesPerCell=(*it)->getNumberOfNodesPerCell(); - it++; - for(;it!=a.end();it++) - { - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); - nbOfCells+=(*it)->getNumberOfCells(); - } - std::vector aps(a.size()); - std::copy(a.begin(),a.end(),aps.begin()); - MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh("merge",*cm)); - ret->setCoords(pts); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - c->alloc(nbOfCells*nbNodesPerCell,1); - int *cPtr=c->getPointer(); - int offset=0; - for(it=a.begin();it!=a.end();it++) - { - int curConnLgth=(*it)->getNodalConnectivityLength(); - const int *curC=(*it)->_conn->begin(); - cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus(),offset)); - offset+=(*it)->getNumberOfNodes(); - } - // - ret->setNodalConnectivity(c); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const -{ - int ncell=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - std::size_t nbOfElemsRet=std::distance(begin,end); - const int *inConn=_conn->getConstPointer(); - int sz=getNumberOfNodesPerCell(); - MEDCouplingAutoRefCountObjectPtr connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); - int *connPtr=connRet->getPointer(); - for(const int *work=begin;work!=end;work++,connPtr+=sz) - { - if(*work>=0 && *work_conn=connRet; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const -{ - int ncell=getNumberOfCells(); - int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : "); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - const int *inConn=_conn->getConstPointer(); - int sz=getNumberOfNodesPerCell(); - MEDCouplingAutoRefCountObjectPtr connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); - int *connPtr=connRet->getPointer(); - int curId=start; - for(int i=0;i=0 && curId_conn=connRet; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const -{ - int sz((int)nodeIdsInUse.size()); - for(const int *conn=_conn->begin();conn!=_conn->end();conn++) - { - if(*conn>=0 && *connbegin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); - MEDCouplingAutoRefCountObjectPtr tmp1; - const DataArrayInt *nodalConn(_conn); - if(!nodalConn) - { - tmp1=DataArrayInt::New(); tmp1->alloc(0,1); - } - else - tmp1=_conn; - ret->_conn=tmp1; - if(!_coords) - { - MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); - ret->setCoords(coords); - } - else - ret->setCoords(_coords); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() -{ - int nbOfCells=getNumberOfCells(); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4) - return DataArrayInt::Range(0,nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;iisAllocated()) - { stream << " Coordinates set but not allocated !"; return ; } - stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; - stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; - if(!(const DataArrayInt *)_conn) - { stream << std::endl << "Nodal connectivity NOT set !"; return ; } - if(_conn->isAllocated()) - { - if(_conn->getNumberOfComponents()==1) - stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; - } -} - -void MEDCoupling1SGTUMesh::checkFullyDefined() const -{ - if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined."); -} - -/*! - * First step of unserialization process. - */ -bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector& tinyInfo) const -{ - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !"); -} - -void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time=getTime(it,order); - tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear(); - // - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); - littleStrings.push_back(getTimeUnit()); - // - std::vector littleStrings2,littleStrings3; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationStrInformation(littleStrings2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationStrInformation(littleStrings3); - int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()); - littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); - littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end()); - // - tinyInfo.push_back(getCellModelEnum()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - std::vector tinyInfo2,tinyInfo3; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationIntInformation(tinyInfo2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationIntInformation(tinyInfo3); - int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size()); - tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end()); - // - tinyInfoD.push_back(time); -} - -void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - std::vector tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]); - std::vector tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]); - a1->resizeForUnserialization(tinyInfo1); - a2->resizeForUnserialization(tinyInfo2); -} - -void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - int sz(0); - if((const DataArrayInt *)_conn) - if(_conn->isAllocated()) - sz=_conn->getNbOfElems(); - a1=DataArrayInt::New(); - a1->alloc(sz,1); - if(sz!=0 && (const DataArrayInt *)_conn) - std::copy(_conn->begin(),_conn->end(),a1->getPointer()); - sz=0; - if((const DataArrayDouble *)_coords) - if(_coords->isAllocated()) - sz=_coords->getNbOfElems(); - a2=DataArrayDouble::New(); - a2->alloc(sz,1); - if(sz!=0 && (const DataArrayDouble *)_coords) - std::copy(_coords->begin(),_coords->end(),a2->getPointer()); -} - -void MEDCoupling1SGTUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]); - _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt); - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]); - int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]); - // - _coords=DataArrayDouble::New(); - std::vector tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2); - _coords->resizeForUnserialization(tinyInfo2); - std::copy(a2->begin(),a2->end(),_coords->getPointer()); - _conn=DataArrayInt::New(); - std::vector tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3); - _conn->resizeForUnserialization(tinyInfo3); - std::copy(a1->begin(),a1->end(),_conn->getPointer()); - std::vector littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0); - _coords->finishUnserialization(tinyInfo2,littleStrings2); - std::vector littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1); - _conn->finishUnserialization(tinyInfo3,littleStrings3); -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent with high - * probability, else an exception is thrown. The meshes are considered equivalent if - * (1) meshes contain the same number of nodes and the same number of elements of the - * same types (2) three cells of the two meshes (first, last and middle) are based - * on coincident nodes (with a specified precision). - * \param [in] other - the mesh to compare with. - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \throw If the two meshes do not match. - */ -void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !"); - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return; - if(!c1 || !c2) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); - if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); - if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); - if(c1->getHashCode()!=c2->getHashCode()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs"); -} - -MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - return Merge1SGTUMeshesOnSameCoords(ms); -} - -void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); - int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int)); - revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1); - std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0); - const int *conn=_conn->begin(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; - int nbOfNodesPerCell=getNumberOfNodesPerCell(); - for(int eltId=0;eltId=0 && conn[0]()); - conn=_conn->begin(); - int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int)); - revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1); - std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1); - for(int eltId=0;eltId(),-1))=eltId; - } - } -} - -/*! - * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null. - */ -void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) -{ - if(nodalConn) - nodalConn->incrRef(); - _conn=nodalConn; - declareAsNew(); -} - -/*! - * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. - */ -DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const -{ - const DataArrayInt *ret(_conn); - return const_cast(ret); -} - -/*! - * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted, - * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter. - * If a nodal connectivity previouly existed before the call of this method, it will be reset. - * - * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. - */ -void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) -{ - if(nbOfCells<0) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !"); - _conn=DataArrayInt::New(); - _conn->reserve(getNumberOfNodesPerCell()*nbOfCells); - declareAsNew(); -} - -/*! - * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). - * - * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. - * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. - * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type - * attached to \a this. - * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). - */ -void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) -{ - int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); - int ref=getNumberOfNodesPerCell(); - if(sz==ref) - { - DataArrayInt *c(_conn); - if(c) - c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); - else - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !"); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this ("; - oss << ref << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method builds the dual mesh of \a this and returns it. - * - * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller. - * \throw If \a this is not a mesh containing only simplex cells. - * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !). - * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !) - */ -MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const -{ - const INTERP_KERNEL::CellModel& cm(getCellModel()); - if(!cm.isSimplex()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !"); - switch(getMeshDimension()) - { - case 3: - return computeDualMesh3D(); - case 2: - return computeDualMesh2D(); - default: - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !"); - } -} - -/*! - * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance. - * - * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion. - * \throw If \a this is not a mesh containing only NORM_HEXA8 cells. - * \throw If \a this is not properly allocated. - */ -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const -{ - const INTERP_KERNEL::CellModel& cm(getCellModel()); - if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !"); - int nbHexa8(getNumberOfCells()); - const int *inConnPtr(getNodalConnectivity()->begin()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4)); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1); - int *cPtr(c->getPointer()); - for(int i=0;isetCoords(getCoords()); - ret->setNodalConnectivity(c); - return ret.retn(); -} - -/*! - * This method starts from an unstructured mesh that hides in reality a cartesian mesh. - * If it is not the case, an exception will be thrown. - * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells - * and a permutation of nodes. - * - * - this[cellPerm[i]]=ret[i] - * - * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells() - * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes() - * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this. - */ -MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const -{ - checkCoherency(); - int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes()); - if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !"); - MEDCouplingAutoRefCountObjectPtr cm(MEDCouplingCMesh::New()); - for(int i=0;i tmp(1,i); - MEDCouplingAutoRefCountObjectPtr elt(static_cast(getCoords()->keepSelectedComponents(tmp))); - elt=elt->getDifferentValues(eps); - elt->sort(true); - cm->setCoordsAt(i,elt); - } - if(nbNodes!=cm->getNumberOfNodes()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : considering the number of nodes after split per components in space this can't be a cartesian mesh ! Maybe your epsilon parameter is invalid ?"); - try - { cm->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - MEDCouplingAutoRefCountObjectPtr um(cm->buildUnstructured()),self(buildUnstructured()); - self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm); - return cm.retn(); -} - -/// @cond INTERNAL - -bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours) -{ - static const int TAB[48]={ - 0,1,2,3,4,5,6,7,//0 - 4,7,6,5,0,3,2,1,//1 - 0,3,7,4,1,2,6,5,//2 - 4,0,3,7,5,1,2,6,//3 - 5,1,0,4,6,2,3,7,//4 - 3,7,4,0,2,6,5,1 //5 - }; - static const int TAB2[6]={0,0,3,3,3,3}; - if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]]) - return true; - int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId))); - std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis))); - std::size_t pos0(pos/2),pos1(pos%2); - int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]); - int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6]; - oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3]; - oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5]; - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8)); - for(int i=0;i<4;i++) - myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4]; - for(int i=0;i<4;i++) - { - int nodeId(myConn2[i]);//the node id for which the opposite one will be found - bool found(false); - INTERP_KERNEL::NormalizedCellType typeOfSon; - for(int j=0;j<12 && !found;j++) - { - cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon); - if(edgeConn[0]==nodeId || edgeConn[1]==nodeId) - { - if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4) - { - myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0]; - found=true; - } - } - } - if(!found) - throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !"); - } - const int *myTab(TAB+8*validAxis); - for(int i=0;i<8;i++) - myConn[i]=myConn2[myTab[i]]; - for(int i=0;i<6;i++) - { - cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i); - std::set s(allFacesTmp+4*i,allFacesTmp+4*i+4); - bool found(false); - for(int j=0;j<6 && !found;j++) - { - std::set s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4); - if(s==s1) - { - neighTmp[i]=myNeighbours[j]; - found=true; - } - } - if(!found) - throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !"); - } - std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn); - std::copy(neighTmp,neighTmp+6,myNeighbours); - return false; -} - -/// @endcond - -/*! - * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was - * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh. - * - * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids. - * - * \throw If \a this is not a mesh containing only NORM_HEXA8 cells. - * \throw If \a this is not properly allocated. - * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther() -{ - MEDCouplingAutoRefCountObjectPtr quads(explodeEachHexa8To6Quad4());//checks that only hexa8 - int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer()); - MEDCouplingAutoRefCountObjectPtr neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1); - int *ptNeigh(neighOfQuads->getPointer()); - {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face. - MEDCouplingAutoRefCountObjectPtr quadsTmp(quads->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr ccSafe,cciSafe; - DataArrayInt *cc(0),*cci(0); - quadsTmp->findCommonCells(3,0,cc,cci); - ccSafe=cc; cciSafe=cci; - const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1); - for(int i=0;i ret(DataArrayInt::New()); ret->alloc(0,1); - std::vector fetched(nbHexa8,false); - std::vector::iterator it(std::find(fetched.begin(),fetched.end(),false)); - while(it!=fetched.end())//it will turns as time as number of connected zones - { - int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone. - std::set s; s.insert(cellId);//s contains already organized. - while(!s.empty()) - { - std::set sNext; - for(std::set::const_iterator it0=s.begin();it0!=s.end();it0++) - { - fetched[*it0]=true; - int *myNeighb(ptNeigh+6*(*it0)); - for(int i=0;i<6;i++) - { - if(myNeighb[i]!=-1 && !fetched[myNeighb[i]]) - { - std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i))); - std::size_t pos0(pos/2),pos1(pos%2); - if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i])) - ret->pushBackSilent(myNeighb[i]); - fetched[myNeighb[i]]=true; - sNext.insert(myNeighb[i]); - } - } - } - s=sNext; - } - it=std::find(fetched.begin(),fetched.end(),false); - } - if(!ret->empty()) - { - int *conn(getNodalConnectivity()->getPointer()); - for(const int *pt=ret->begin();pt!=ret->end();pt++) - { - int cellId(*pt); - conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3]; - conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5]; - } - declareAsNew(); - } - return ret.retn(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const -{ - static const int DUAL_TETRA_0[36]={ - 4,1,0, 6,0,3, 7,3,1, - 4,0,1, 5,2,0, 8,1,2, - 6,3,0, 5,0,2, 9,2,3, - 7,1,3, 9,3,2, 8,2,1 - }; - static const int DUAL_TETRA_1[36]={ - 8,4,10, 11,5,8, 10,7,11, - 9,4,8, 8,5,12, 12,6,9, - 10,4,9, 9,6,13, 13,7,10, - 12,5,11, 13,6,12, 11,7,13 - }; - static const int FACEID_NOT_SH_NODE[4]={2,3,1,0}; - if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !"); - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr thisu(buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New()); - thisu->getReverseNodalConnectivity(revNodArr,revNodIArr); - const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin()); - MEDCouplingAutoRefCountObjectPtr d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr)); - const int *d1(d1Arr->begin()); - MEDCouplingAutoRefCountObjectPtr d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0; - const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin()); - MEDCouplingAutoRefCountObjectPtr edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner()); - const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells()); - edges=0; faces=0; - std::vector v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr; - MEDCouplingAutoRefCountObjectPtr zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0; - std::string name("DualOf_"); name+=getName(); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1); - for(int i=0;ipushBackSilent(-1); - int tmp[14]; - // - tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes; - tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes; - tmp[4]=-1; - tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes; - tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes; - tmp[9]=-1; - tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes; - tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes; - cArr->insertAtTheEnd(tmp,tmp+14); - int kk(0); - for(int k=0;k<4;k++) - { - if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k) - { - const int *faceId(d2+4*curCellId+k); - if(rdi2[*faceId+1]-rdi2[*faceId]==1) - { - int tmp2[5]; tmp2[0]=-1; tmp2[1]=i; - tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0; - tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes; - tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0; - cArr->insertAtTheEnd(tmp2,tmp2+5); - } - kk++; - } - } - } - ciArr->setIJ(i+1,0,cArr->getNumberOfTuples()); - } - ret->setNodalConnectivity(cArr,ciArr); - return ret.retn(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const -{ - static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1}; - static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5}; - static const int FACEID_NOT_SH_NODE[3]={1,2,0}; - if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !"); - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr thisu(buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New()); - thisu->getReverseNodalConnectivity(revNodArr,revNodIArr); - const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin()); - MEDCouplingAutoRefCountObjectPtr d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0; - const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin()); - MEDCouplingAutoRefCountObjectPtr edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner()); - const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells()); - edges=0; - std::vector v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr; - MEDCouplingAutoRefCountObjectPtr zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; - std::string name("DualOf_"); name+=getName(); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1); - for(int i=0;i > polyg; - for(int j=0;j locV(3); - locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes; - polyg.push_back(locV); - int kk(0); - for(int k=0;k<3;k++) - { - if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k) - { - const int *edgeId(d2+3*curCellId+k); - if(rdi2[*edgeId+1]-rdi2[*edgeId]==1) - { - std::vector locV2(2); - int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]); - if(zeLocEdgeIdRel>0) - { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; } - else - { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; } - polyg.push_back(locV2); - } - kk++; - } - } - } - std::vector zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg)); - cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end()); - ciArr->setIJ(i+1,0,cArr->getNumberOfTuples()); - } - ret->setNodalConnectivity(cArr,ciArr); - return ret.retn(); -} - -/*! - * This method aggregate the bbox of each cell and put it into bbox - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * For all other cases this input parameter is ignored. - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - */ -DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const -{ - int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - for(int i=0;i::max(); - bbox[2*i+1]=-std::numeric_limits::max(); - } - const double *coordsPtr(_coords->getConstPointer()); - const int *conn(_conn->getConstPointer()); - for(int i=0;i=0 && nodeId ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); - int nbCells(getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr arr(DataArrayDouble::New()); - arr->alloc(nbCells,1); - INTERP_KERNEL::AutoCppPtr dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension())); - dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer()); - ret->setMesh(this); - ret->setArray(arr); - ret->setName("Diameter"); - return ret.retn(); -} - -//== - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New() -{ - return new MEDCoupling1DGTUMesh; -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) -{ - if(type==INTERP_KERNEL::NORM_ERROR) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(!cm.isDynamic()) - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return new MEDCoupling1DGTUMesh(name,cm); -} - -MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh() -{ -} - -MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) -{ -} - -MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) -{ - if(recDeepCpy) - { - const DataArrayInt *c(other._conn); - if(c) - _conn=c->deepCpy(); - c=other._conn_indx; - if(c) - _conn_indx=c->deepCpy(); - } -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const -{ - return new MEDCoupling1DGTUMesh(*this,recDeepCpy); -} - -/*! - * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. - * The coordinates are shared between \a this and the returned instance. - * - * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) - * \sa MEDCoupling1DGTUMesh::deepCpy - */ -MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr c(_conn->deepCpy()),ci(_conn_indx->deepCpy()); - ret->setNodalConnectivity(c,ci); - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::updateTime() const -{ - MEDCoupling1GTUMesh::updateTime(); - const DataArrayInt *c(_conn); - if(c) - updateTimeWith(*c); - c=_conn_indx; - if(c) - updateTimeWith(*c); -} - -std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayInt *)_conn); - ret.push_back((const DataArrayInt *)_conn_indx); - return ret; -} - -MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const -{ - return clone(true); -} - -bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !"); - std::ostringstream oss; oss.precision(15); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !"; - return false; - } - if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - { - reason="in connectivity of single dynamic geometric type exactly one among this and other is null !"; - return false; - } - if(!c1->isEqualIfNotWhy(*c2,reason)) - { - reason.insert(0,"Nodal connectivity DataArrayInt differs : "); - return false; - } - c1=_conn_indx; c2=otherC->_conn_indx; - if(c1==c2) - return true; - if(!c1 || !c2) - { - reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !"; - return false; - } - if(!c1->isEqualIfNotWhy(*c2,reason)) - { - reason.insert(0,"Nodal connectivity index DataArrayInt differs : "); - return false; - } - return true; -} - -bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - return false; - if(!c1->isEqualWithoutConsideringStr(*c2)) - return false; - return true; - c1=_conn_indx; c2=otherC->_conn_indx; - if(c1==c2) - return true; - if(!c1 || !c2) - return false; - if(!c1->isEqualWithoutConsideringStr(*c2)) - return false; - return true; -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent with high - * probability, else an exception is thrown. The meshes are considered equivalent if - * (1) meshes contain the same number of nodes and the same number of elements of the - * same types (2) three cells of the two meshes (first, last and middle) are based - * on coincident nodes (with a specified precision). - * \param [in] other - the mesh to compare with. - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \throw If the two meshes do not match. - */ -void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !"); - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1!=c2) - { - if(!c1 || !c2) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); - if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); - if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); - if(c1->getHashCode()!=c2->getHashCode()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs"); - } - c1=_conn_indx; c2=otherC->_conn_indx; - if(c1!=c2) - { - if(!c1 || !c2) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !"); - if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !"); - if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !"); - if(c1->getHashCode()!=c2->getHashCode()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs"); - } -} - -void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const -{ - const DataArrayInt *c1(_conn); - if(c1) - { - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); - if(c1->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); - c1->checkAllocated(); - } - else - throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); - // - int sz2=_conn->getNumberOfTuples(); - c1=_conn_indx; - if(c1) - { - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); - c1->checkAllocated(); - if(c1->getNumberOfTuples()<1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !"); - if(c1->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); - int f=c1->front(),ll=c1->back(); - if(f<0 || f>=sz2) - { - std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(ll<0 || ll>sz2) - { - std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f>ll) - { - std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !"); - int szOfC1Exp=_conn_indx->back(); - if(sz2getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated. - * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one. - * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array. - */ -void MEDCoupling1DGTUMesh::checkCoherency() const -{ - MEDCouplingPointSet::checkCoherency(); - checkCoherencyOfConnectivity(); -} - -void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - const DataArrayInt *c1(_conn),*c2(_conn_indx); - if(!c2->isMonotonic(true)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !"); - // - int nbOfTuples=c1->getNumberOfTuples(); - int nbOfNodes=getNumberOfNodes(); - const int *w(c1->begin()); - for(int i=0;i=nbOfNodes) - { - std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -int MEDCoupling1DGTUMesh::getNumberOfCells() const -{ - checkCoherencyOfConnectivity();//do not remove - return _conn_indx->getNumberOfTuples()-1; -} - -/*! - * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of nodes constituting cell is computed. - * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. - * So for pohyhedrons some nodes can be counted several times in the returned result. - * - * \return a newly allocated array - */ -DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const -{ - checkCoherency(); - _conn_indx->checkMonotonic(true); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - return _conn_indx->deltaShiftIndex(); - // for polyhedrons - int nbOfCells=_conn_indx->getNumberOfTuples()-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *ci=_conn_indx->begin(),*c=_conn->begin(); - for(int i=0;igetNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. - * - * \return a newly allocated array - */ -DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const -{ - checkCoherency(); - _conn_indx->checkMonotonic(true); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG) - return _conn_indx->deltaShiftIndex(); - if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG) - { - MEDCouplingAutoRefCountObjectPtr ret=_conn_indx->deltaShiftIndex(); - ret->applyDivideBy(2); - return ret.retn(); - } - // for polyhedrons - int nbOfCells=_conn_indx->getNumberOfTuples()-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *ci=_conn_indx->begin(),*c=_conn->begin(); - for(int i=0;icheckMonotonic(true); - int nbOfCells(_conn_indx->getNumberOfTuples()-1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr(ret->getPointer()); - const int *ci(_conn_indx->begin()),*c(_conn->begin()); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i s(c+ci[0],c+ci[1]); - *retPtr=(int)s.size(); - } - } - else - { - for(int i=0;i s(c+ci[0],c+ci[1]); s.erase(-1); - *retPtr=(int)s.size(); - } - } - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int nbOfCells(getNumberOfCells());//performs checks - if(cellId>=0 && cellIdgetIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); - int nbOfNodes=stp-strt; - if(nbOfNodes<0) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !"); - conn.resize(nbOfNodes); - std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin()); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const -{ - int nbOfCells(getNumberOfCells());//performs checks - if(cellId>=0 && cellIdbegin()); - int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); - return stp-strt-std::count(conn+strt,conn+stp,-1); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -std::string MEDCoupling1DGTUMesh::simpleRepr() const -{ - static const char msg0[]="No coordinates specified !"; - std::ostringstream ret; - ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; - if(_coords!=0) - { - const int spaceDim=getSpaceDimension(); - ret << spaceDim << "\nInfo attached on space dimension : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - ret << msg0 << "\n"; - ret << "Number of nodes : "; - if(_coords!=0) - ret << getNumberOfNodes() << "\n"; - else - ret << msg0 << "\n"; - ret << "Number of cells : "; - bool isOK=true; - try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */) - { - ret << "Nodal connectivity arrays are not set or badly set !\n"; - isOK=false; - } - if(isOK) - ret << getNumberOfCells() << "\n"; - ret << "Cell type : " << _cm->getRepr() << "\n"; - return ret.str(); -} - -std::string MEDCoupling1DGTUMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << simpleRepr(); - ret << "\nCoordinates array : \n___________________\n\n"; - if(_coords) - _coords->reprWithoutNameStream(ret); - else - ret << "No array set !\n"; - ret << "\n\nNodal Connectivity : \n____________________\n\n"; - // - bool isOK=true; - try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */) - { - ret << "Nodal connectivity arrays are not set or badly set !\n"; - isOK=false; - } - if(!isOK) - return ret.str(); - int nbOfCells=getNumberOfCells(); - const int *ci=_conn_indx->begin(),*c=_conn->begin(); - for(int i=0;i(ret," ")); - ret << "\n"; - } - return ret.str(); -} - -DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells();//checkCoherency() - int nbOfNodes=getNumberOfNodes(); - ret->alloc(nbOfCells,spaceDim); - double *ptToFill=ret->getPointer(); - const double *coor=_coords->begin(); - const int *nodal=_conn->begin(),*nodali=_conn_indx->begin(); - nodal+=nodali[0]; - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i= to avoid division by 0. - { - for(int j=nodali[0];j=0 && *nodal()); - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(nodali[1]-nodali[0]))); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - for(int i=0;i= to avoid division by 0. - { - int nbOfNod=0; - for(int j=nodali[0];j=0 && *nodal()); - nbOfNod++; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(nbOfNod!=0) - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./nbOfNod)); - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) -{ - int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); - o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); - if(check) - o2n=o2n->checkAndPreparePermutation(); - // - const int *o2nPtr=o2n->getPointer(); - const int *conn=_conn->begin(),*conni=_conn_indx->begin(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1); - newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx); - // - int *newC=newConn->getPointer(),*newCI=newConnI->getPointer(); - for(int i=0;i=0) - newCI[newPos]=sz; - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - newConnI->computeOffsets2(); newCI=newConnI->getPointer(); - // - for(int i=0;igetType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !"); - const MEDCoupling1DGTUMesh *otherC=static_cast(other); - return Merge1DGTUMeshes(this,otherC); -} - -MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); - ret->setCoords(getCoords()); - const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin(); - int nbCells=getNumberOfCells();//checkCoherency - int geoType=(int)getCellModelEnum(); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); cI->alloc(nbCells+1); - int *cPtr=c->getPointer(),*ciPtr=cI->getPointer(); - ciPtr[0]=0; - for(int i=0;i=0) - { - *cPtr++=geoType; - cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr); - ciPtr[1]=ciPtr[0]+sz+1; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setConnectivity(c,cI,true); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -/*! - * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes - */ -DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) -{ - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - ret->iota(0); - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\"."; - stream << " Mesh dimension : " << getMeshDimension() << "."; - if(!_coords) - { stream << " No coordinates set !"; return ; } - if(!_coords->isAllocated()) - { stream << " Coordinates set but not allocated !"; return ; } - stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; - stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; - bool isOK=true; - try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */) - { - stream << std::endl << "Nodal connectivity NOT set properly !\n"; - isOK=false; - } - if(isOK) - stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; -} - -void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !"); - setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex()); -} - -MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - return Merge1DGTUMeshesOnSameCoords(ms); -} - -MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - DataArrayInt *c=0,*ci=0; - MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci); - MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); - ret->setNodalConnectivity(c,ci); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - DataArrayInt *c=0,*ci=0; - MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci); - MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); - ret->setNodalConnectivity(c,ci); - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const -{ - checkCoherency2(); - int sz((int)nodeIdsInUse.size()); - for(const int *conn=_conn->begin();conn!=_conn->end();conn++) - { - if(*conn>=0 && *connbegin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); - int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int)); - revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1); - std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0); - const int *conn=_conn->begin(),*conni=_conn_indx->begin(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; - for(int eltId=0;eltId=0) - { - for(int j=0;j=0 && nodeId()); - conn=_conn->begin(); - int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int)); - revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1); - std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1); - for(int eltId=0;eltId(),-1))=eltId; - } - } -} - -void MEDCoupling1DGTUMesh::checkFullyDefined() const -{ - if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined."); -} - -bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector& tinyInfo) const -{ - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !"); -} - -void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time=getTime(it,order); - tinyInfo.clear(); tinyInfoD.clear(); littleStrings.clear(); - // - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); - littleStrings.push_back(getTimeUnit()); - // - std::vector littleStrings2,littleStrings3,littleStrings4; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationStrInformation(littleStrings2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationStrInformation(littleStrings3); - if((const DataArrayInt *)_conn_indx) - _conn_indx->getTinySerializationStrInformation(littleStrings4); - int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size()); - littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); - littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end()); - littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end()); - // - tinyInfo.push_back(getCellModelEnum()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - std::vector tinyInfo2,tinyInfo3,tinyInfo4; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationIntInformation(tinyInfo2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationIntInformation(tinyInfo3); - if((const DataArrayInt *)_conn_indx) - _conn_indx->getTinySerializationIntInformation(tinyInfo4); - int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size()); - tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end()); - // - tinyInfoD.push_back(time); -} - -void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - std::vector tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]); - std::vector tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]); - std::vector tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]); - MEDCouplingAutoRefCountObjectPtr p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1); - MEDCouplingAutoRefCountObjectPtr p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12); - std::vector v(2); v[0]=p1; v[1]=p2; - p2=DataArrayInt::Aggregate(v); - a2->resizeForUnserialization(tinyInfo2); - a1->alloc(p2->getNbOfElems(),1); -} - -void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - int sz(0); - if((const DataArrayInt *)_conn) - if(_conn->isAllocated()) - sz=_conn->getNbOfElems(); - if((const DataArrayInt *)_conn_indx) - if(_conn_indx->isAllocated()) - sz+=_conn_indx->getNbOfElems(); - a1=DataArrayInt::New(); - a1->alloc(sz,1); - int *work(a1->getPointer()); - if(sz!=0 && (const DataArrayInt *)_conn) - work=std::copy(_conn->begin(),_conn->end(),a1->getPointer()); - if(sz!=0 && (const DataArrayInt *)_conn_indx) - std::copy(_conn_indx->begin(),_conn_indx->end(),work); - sz=0; - if((const DataArrayDouble *)_coords) - if(_coords->isAllocated()) - sz=_coords->getNbOfElems(); - a2=DataArrayDouble::New(); - a2->alloc(sz,1); - if(sz!=0 && (const DataArrayDouble *)_coords) - std::copy(_coords->begin(),_coords->end(),a2->getPointer()); -} - -void MEDCoupling1DGTUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]); - _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt); - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]); - int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]); - // - _coords=DataArrayDouble::New(); - std::vector tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3); - _coords->resizeForUnserialization(tinyInfo2); - std::copy(a2->begin(),a2->end(),_coords->getPointer()); - _conn=DataArrayInt::New(); - std::vector tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4); - _conn->resizeForUnserialization(tinyInfo3); - std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer()); - _conn_indx=DataArrayInt::New(); - std::vector tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5); - _conn_indx->resizeForUnserialization(tinyInfo4); - std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer()); - std::vector littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0); - _coords->finishUnserialization(tinyInfo2,littleStrings2); - std::vector littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1); - _conn->finishUnserialization(tinyInfo3,littleStrings3); - std::vector littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2); - _conn_indx->finishUnserialization(tinyInfo4,littleStrings4); -} - -/*! - * Finds nodes not used in any cell and returns an array giving a new id to every node - * by excluding the unused nodes, for which the array holds -1. The result array is - * a mapping in "Old to New" mode. - * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. - * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a - * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const -{ - checkCoherency2(); - int nbNodes(getNumberOfNodes()); - std::vector fetchedNodes(nbNodes,false); - computeNodeIdsAlg(fetchedNodes); - int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - int *retPtr(ret->getPointer()); - for(int i=0;igetNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const -{ - nbrOfNodesInUse=-1; - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=getNumberOfCells();//checkCoherency - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfNodes,1); - int *traducer=ret->getPointer(); - std::fill(traducer,traducer+nbOfNodes,-1); - const int *conn=_conn->begin(),*conni(_conn_indx->begin()); - for(int i=0;i=0 && nodeIdgetNumberOfTuples()); - int *pt(_conn->getPointer()); - for(int i=0;i& newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - // - int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples()); - int *pt(_conn->getPointer()); - for(int i=0;i=0 && *pt::const_iterator it(newNodeNumbersO2N.find(*pt)); - if(it!=newNodeNumbersO2N.end()) - *pt=(*it).second; - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - // - updateTime(); -} - -/*! - * Changes ids of nodes within the nodal connectivity arrays according to a permutation - * array in "Old to New" mode. The node coordinates array is \b not changed by this method. - * This method is a generalization of shiftNodeNumbersInConn(). - * \warning This method performs no check of validity of new ids. **Use it with care !** - * \param [in] newNodeNumbersO2N - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \throw If the nodal connectivity of cells is not defined. - */ -void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - // - int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples()); - int *pt(_conn->getPointer()); - for(int i=0;i=0 && *pt cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); - int tmp=-1; - int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; - std::vector fastFinder(sz,false); - for(const int *work=begin;work!=end;work++) - if(*work>=0 && *workbegin(),*conni=_conn_indx->begin(); - for(int i=0;i=0) - { - for(int j=0;j=0) - { - ref++; - if(fastFinder[nodeId]) - nbOfHit++; - } - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) - cellIdsKept->pushBackSilent(i); - } - cellIdsKeptArr=cellIdsKept.retn(); -} - -void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) -{ - if(nbOfCells<0) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !"); - _conn=DataArrayInt::New(); - _conn->reserve(nbOfCells*3); - _conn_indx=DataArrayInt::New(); - _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0); - declareAsNew(); -} - -/*! - * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). - * - * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. - * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. - * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type - * attached to \a this. - * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). - */ -void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) -{ - int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); - DataArrayInt *c(_conn),*c2(_conn_indx); - if(c && c2) - { - int pos=c2->back(); - if(pos==c->getNumberOfTuples()) - { - c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); - c2->pushBackSilent(pos+sz); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !"); -} - -void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) -{ - if(nodalConn) - nodalConn->incrRef(); - _conn=nodalConn; - if(nodalConnIndex) - nodalConnIndex->incrRef(); - _conn_indx=nodalConnIndex; - declareAsNew(); -} - -/*! - * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. - */ -DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const -{ - const DataArrayInt *ret(_conn); - return const_cast(ret); -} - -/*! - * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it. - */ -DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const -{ - const DataArrayInt *ret(_conn_indx); - return const_cast(ret); -} - -/*! - * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here". - * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity). - * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this. - * - * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this. - * - * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal - * connectivity arrays are different (false) - * \return a new object to be managed by the caller. - * - * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked - */ -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - DataArrayInt *nc=0,*nci=0; - isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci); - MEDCouplingAutoRefCountObjectPtr ncs(nc),ncis(nci); - ret->_conn=ncs; ret->_conn_indx=ncis; - ret->setCoords(getCoords()); - return ret.retn(); -} - -/*! - * This method allows to compute, if needed, the packed nodal connectivity pair. - * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array. - * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn. - * - * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) - * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. - * - * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false - * will be returned. - * - * This method return 3 elements. - * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter - * this pointer can be seen as a new object, that is to managed by the caller. - * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter - * this pointer can be seen as a new object, that is to managed by the caller. - * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then - * output parameters are newly created objects. - * - * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test - */ -bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const -{ - if(isPacked())//performs the checkCoherency - { - const DataArrayInt *c0(_conn),*c1(_conn_indx); - nodalConn=const_cast(c0); nodalConnIndx=const_cast(c1); - nodalConn->incrRef(); nodalConnIndx->incrRef(); - return true; - } - int bg=_conn_indx->front(),end=_conn_indx->back(); - MEDCouplingAutoRefCountObjectPtr nc(_conn->selectByTupleId2(bg,end,1)); - MEDCouplingAutoRefCountObjectPtr nci(_conn_indx->deepCpy()); - nci->applyLin(1,-bg); - nodalConn=nc.retn(); nodalConnIndx=nci.retn(); - return false; -} - -/* - * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) - * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. - * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned. - * \return bool - true if \a this looks packed, false is not. - * - * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test - */ -bool MEDCoupling1DGTUMesh::isPacked() const -{ - checkCoherency(); - return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); - return Merge1DGTUMeshes(tmp); -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector& a) -{ - std::size_t sz=a.size(); - if(sz==0) - return Merge1DGTUMeshesLL(a); - for(std::size_t ii=0;iigetCellModel()); - for(std::size_t ii=0;iigetCellModel())!=cm) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > bb(sz); - std::vector< const MEDCoupling1DGTUMesh * > aa(sz); - int spaceDim=-3; - for(std::size_t i=0;igetCoords(); - if(coo) - spaceDim=coo->getNumberOfComponents(); - } - if(spaceDim==-3) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !"); - for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); - aa[i]=bb[i]; - } - return Merge1DGTUMeshesLL(aa); -} - -/*! - * \throw If presence of a null instance in the input vector \a a. - * \throw If a is empty - */ -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > objs(a.size()); - std::vector ncs(a.size()),ncis(a.size()); - (*it)->getNumberOfCells();//to check that all is OK - const DataArrayDouble *coords=(*it)->getCoords(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - bool tmp; - objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); - it++; - for(int i=1;it!=a.end();i++,it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !"); - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); - (*it)->getNumberOfCells();//to check that all is OK - objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); - if(coords!=(*it)->getCoords()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !"); - } - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh("merge",*cm)); - ret->setCoords(coords); - ret->_conn=DataArrayInt::Aggregate(ncs); - ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); - return ret.retn(); -} - -/*! - * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL) - */ -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > objs(a.size()); - std::vector ncs(a.size()),ncis(a.size()); - std::vector::const_iterator it=a.begin(); - std::vector nbNodesPerElt(a.size()); - int nbOfCells=(*it)->getNumberOfCells(); - bool tmp; - objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); - nbNodesPerElt[0]=0; - int prevNbOfNodes=(*it)->getNumberOfNodes(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - it++; - for(int i=1;it!=a.end();i++,it++) - { - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); - objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); - nbOfCells+=(*it)->getNumberOfCells(); - nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes; - prevNbOfNodes=(*it)->getNumberOfNodes(); - } - std::vector aps(a.size()); - std::copy(a.begin(),a.end(),aps.begin()); - MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh("merge",*cm)); - ret->setCoords(pts); - ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt); - ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); - return ret.retn(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - MEDCouplingAutoRefCountObjectPtr tmp1,tmp2; - const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx); - if(!nodalConn) - { - tmp1=DataArrayInt::New(); tmp1->alloc(0,1); - } - else - tmp1=_conn; - ret->_conn=tmp1; - // - if(!nodalConnI) - { - tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); - } - else - tmp2=_conn_indx; - ret->_conn_indx=tmp2; - // - if(!_coords) - { - MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); - ret->setCoords(coords); - } - else - ret->setCoords(_coords); - return ret.retn(); -} - -/*! - * This method aggregate the bbox of each cell and put it into bbox parameter. - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * For all other cases this input parameter is ignored. - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - */ -DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const -{ - checkFullyDefined(); - int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - for(int i=0;i::max(); - bbox[2*i+1]=-std::numeric_limits::max(); - } - const double *coordsPtr(_coords->getConstPointer()); - const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer()); - for(int i=0;i=0 && nodeId MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector >& parts) -{ - std::vector ret; - if(parts.empty()) - return ret; - ret.insert(ret.end(),parts[0].begin(),parts[0].end()); - int ref(ret.back()); - std::size_t sz(parts.size()),nbh(1); - std::vector b(sz,true); b[0]=false; - while(nbh& nodalConns, const std::vector& offsetInNodeIdsPerElt) -{ - std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size()); - if(sz1!=sz2) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !"); - if(sz1==0) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !"); - int nbOfTuples=0; - for(std::vector::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !"); - if(!(*it)->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !"); - if((*it)->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !"); - nbOfTuples+=(*it)->getNumberOfTuples(); - } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); - int *pt=ret->getPointer(); - int i=0; - for(std::vector::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++) - { - int curNbt=(*it)->getNumberOfTuples(); - const int *inPt=(*it)->begin(); - int offset=offsetInNodeIdsPerElt[i]; - for(int j=0;j gts(m->getAllGeoTypes()); - if(gts.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !"); - int geoType((int)*gts.begin()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin())); - ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription()); - int nbCells(m->getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1); - int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0; - const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin()); - for(int i=0;i=1) - { - c=std::copy(cin+ciin[0]+1,cin+ciin[1],c); - ci[1]=ci[0]+ciin[1]-ciin[0]-1; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setNodalConnectivity(conn,connI); - return ret.retn(); -} diff --git a/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.hxx b/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.hxx deleted file mode 100644 index 9928bc48f..000000000 --- a/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.hxx +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLING1GTUMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLING1GTUMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "CellModel.hxx" - -namespace ParaMEDMEM -{ - class MEDCoupling1GTUUMeshCellIterator; - - class MEDCoupling1GTUMesh : public MEDCouplingPointSet - { - public: - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const MEDCouplingUMesh *m); - MEDCOUPLING_EXPORT const INTERP_KERNEL::CellModel& getCellModel() const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getCellModelEnum() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - MEDCOUPLING_EXPORT std::set getAllGeoTypes() const; - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - MEDCOUPLING_EXPORT std::string getVTKDataSetType() const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - // - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int getNodalConnectivityLength() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; - MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; - MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts); - public: - MEDCOUPLING_EXPORT virtual void allocateCells(int nbOfCells=0) = 0; - MEDCOUPLING_EXPORT virtual void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getNodalConnectivity() const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherencyOfConnectivity() const = 0; - protected: - MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); - MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy); - MEDCoupling1GTUMesh(); - protected: - const INTERP_KERNEL::CellModel *_cm; - }; - - class MEDCoupling1DGTUMesh; - class MEDCouplingCMesh; - - class MEDCoupling1SGTUMesh : public MEDCoupling1GTUMesh - { - public: - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const MEDCouplingUMesh *m); - //! useless constructor only for CORBA -> not swigged - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; - // overload of TimeLabel and RefCountObject - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // overload of MEDCouplingMesh - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED; } - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - // overload of MEDCouplingPointSet - MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); - MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; - MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - MEDCOUPLING_EXPORT void checkFullyDefined() const; - MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; - MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); - MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N); - MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); - MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; - MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; - // overload of MEDCoupling1GTUMesh - MEDCOUPLING_EXPORT void checkCoherencyOfConnectivity() const; - MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); - MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd); - public://specific - MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn); - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const; - MEDCOUPLING_EXPORT int getNumberOfNodesPerCell() const; - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(std::vector& a); - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(std::vector& a); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const; - MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *computeDualMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *sortHexa8EachOther(); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const; - MEDCOUPLING_EXPORT MEDCouplingCMesh *structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps=1e-12) const; - public://serialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - private: - MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); - MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy); - MEDCoupling1SGTUMesh(); - private: - void checkNonDynamicGeoType() const; - static MEDCoupling1SGTUMesh *Merge1SGTUMeshesLL(std::vector& a); - DataArrayInt *simplexizePol0(); - DataArrayInt *simplexizePol1(); - DataArrayInt *simplexizePlanarFace5(); - DataArrayInt *simplexizePlanarFace6(); - MEDCoupling1DGTUMesh *computeDualMesh3D() const; - MEDCoupling1DGTUMesh *computeDualMesh2D() const; - private: - MEDCouplingAutoRefCountObjectPtr _conn; - public: - static const int HEXA8_FACE_PAIRS[6]; - }; - - class MEDCoupling1DGTUMesh : public MEDCoupling1GTUMesh - { - public: - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const MEDCouplingUMesh *m); - //! useless constructor only for CORBA -> not swigged - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(); - MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; - // overload of TimeLabel and RefCountObject - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // overload of MEDCouplingMesh - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED; } - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - // overload of MEDCouplingPointSet - MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); - MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; - MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - MEDCOUPLING_EXPORT void checkFullyDefined() const; - MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; - MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); - MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N); - MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); - MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; - MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; - // overload of MEDCoupling1GTUMesh - MEDCOUPLING_EXPORT void checkCoherencyOfConnectivity() const; - MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); - MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd); - public://specific - MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex); - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() const; - MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const; - MEDCOUPLING_EXPORT bool retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const; - MEDCOUPLING_EXPORT bool isPacked() const; - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(std::vector& a); - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(std::vector& a); - MEDCOUPLING_EXPORT static DataArrayInt *AggregateNodalConnAndShiftNodeIds(const std::vector& nodalConns, const std::vector& offsetInNodeIdsPerElt); - MEDCOUPLING_EXPORT static std::vector BuildAPolygonFromParts(const std::vector< std::vector >& parts); - MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const; - public://serialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - private: - MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); - MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy); - MEDCoupling1DGTUMesh(); - private: - void checkDynamicGeoT2ype() const; - static MEDCoupling1DGTUMesh *Merge1DGTUMeshesLL(std::vector& a); - private: - MEDCouplingAutoRefCountObjectPtr _conn_indx; - MEDCouplingAutoRefCountObjectPtr _conn; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx b/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx deleted file mode 100644 index f49b7bf9d..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx +++ /dev/null @@ -1,1540 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#include "MEDCouplingAMRAttribute.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingIMesh.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -/// @cond INTERNAL -DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair >& fieldNames) -{ - return new DataArrayDoubleCollection(fieldNames); -} - -DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const -{ - return new DataArrayDoubleCollection(*this); -} - -void DataArrayDoubleCollection::allocTuples(int nbOfTuples) -{ - std::size_t sz(_arrs.size()); - for(std::size_t i=0;ireAlloc(nbOfTuples); -} - -void DataArrayDoubleCollection::dellocTuples() -{ - std::size_t sz(_arrs.size()); - for(std::size_t i=0;ireAlloc(0); -} - -void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other) -{ - std::size_t sz(_arrs.size()); - if(sz!=other._arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !"); - for(std::size_t i=0;icpyFrom(*otherArr); - } -} - -void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector >& compNames) -{ - std::size_t sz(_arrs.size()); - if(sz!=compNames.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !"); - for(std::size_t i=0;i& names(compNames[i]); - _arrs[i].first->setInfoOnComponents(names); - } -} - -void DataArrayDoubleCollection::spillNatures(const std::vector& nfs) -{ - std::size_t sz(_arrs.size()); - if(sz!=nfs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !"); - for(std::size_t i=0;i > > DataArrayDoubleCollection::getInfoOnComponents() const -{ - std::size_t sz(_arrs.size()); - std::vector< std::pair < std::string, std::vector > > ret(sz); - for(std::size_t i=0;i >(elt->getName(),elt->getInfoOnComponents()); - } - return ret; -} - -std::vector DataArrayDoubleCollection::getNatures() const -{ - std::size_t sz(_arrs.size()); - std::vector ret(sz); - for(std::size_t i=0;i DataArrayDoubleCollection::retrieveFields() const -{ - std::size_t sz(_arrs.size()); - std::vector ret(sz); - for(std::size_t i=0;i(tmp); - if(ret[i]) - ret[i]->incrRef(); - } - return ret; -} - -const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const -{ - std::vector vec; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - { - const DataArrayDouble *obj((*it).first); - if(obj) - { - if(obj->getName()==name) - return obj; - else - vec.push_back(obj->getName()); - } - } - std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; - std::copy(vec.begin(),vec.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) -{ - std::vector vec; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++) - { - DataArrayDouble *obj((*it).first); - if(obj) - { - if(obj->getName()==name) - return obj; - else - vec.push_back(obj->getName()); - } - } - std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; - std::copy(vec.begin(),vec.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -DataArrayDouble *DataArrayDoubleCollection::at(int pos) -{ - if(pos<0 || pos>=(int)_arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !"); - return _arrs[pos].first; -} - -const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const -{ - if(pos<0 || pos>=(int)_arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !"); - return _arrs[pos].first; -} - -int DataArrayDoubleCollection::size() const -{ - return (int)_arrs.size(); -} - -void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !"); - std::size_t sz(coarse->_arrs.size()); - if(fine->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !"); - for(std::size_t i=0;i_arrs[i].second,coarse->_arrs[i].second); - fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second)); - } -} - -void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !"); - std::size_t sz(coarse->_arrs.size()); - if(fine->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !"); - for(std::size_t i=0;i_arrs[i].second,coarse->_arrs[i].second); - fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second)); - } -} - -void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector& children, const std::vector& fieldsOnFine) -{ - if(!fatherOfFineMesh) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !"); - std::size_t sz(children.size()); - if(fieldsOnFine.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !"); - if(sz<=1) - return ; - std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size()); - for(std::size_t i=0;igetPatchIdFromChildMesh(children[i])!=(int)i) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !"); - for(std::size_t i=1;i_arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !"); - for(std::size_t i=0;i arrs(sz); - for(std::size_t j=0;j_arrs[i].first; - fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs); - } -} - -/*! - * This method updates \a p1dac ghost zone parts using \a p2dac (which is really const). \a p2 is in the neighborhood of \a p1 (which size is defined by \a ghostLev). - */ -void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac) -{ - if(!p1 || !p1dac || !p2 || !p2dac) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !"); - std::size_t sz(p1dac->_arrs.size()); - if(p2dac->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !"); - for(std::size_t i=0;i_arrs[i].first); - DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second); - bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second)); - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative); - } -} - -void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !"); - std::size_t sz(coarse->_arrs.size()); - if(fine->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !"); - for(std::size_t i=0;ifillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev); -} - -void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const -{ - DataArrayDoubleCollection *thisNC(const_cast(this)); - std::size_t sz(_arrs.size()); - if(other._arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !"); - for(std::size_t i=0;ifillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first); -} - -void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const -{ - DataArrayDoubleCollection *thisNC(const_cast(this)); - std::size_t sz(_arrs.size()); - if(other._arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !"); - for(std::size_t i=0;i_arrs[i].first,other._arrs[i].first); -} - -DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair >& fieldNames):_arrs(fieldNames.size()) -{ - std::size_t sz(fieldNames.size()); - std::vector names(sz); - for(std::size_t i=0;i& info(fieldNames[i]); - if(info.second<=0) - { - std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second; - oss << " It has to be >=1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _arrs[i].first=DataArrayDouble::New(); - _arrs[i].first->alloc(0,info.second); - _arrs[i].first->setName(info.first); - names[i]=info.second; - _arrs[i].second=ConservativeVolumic; - } - CheckDiscriminantNames(names); -} - -DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size()) -{ - std::size_t sz(other._arrs.size()); - for(std::size_t i=0;ideepCpy(); - } -} - -std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(DataArrayDoubleCollection)); - ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; -} - -std::vector DataArrayDoubleCollection::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - ret.push_back((const DataArrayDouble *)(*it).first); - return ret; -} - -void DataArrayDoubleCollection::updateTime() const -{ - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - { - const DataArrayDouble *pt((*it).first); - if(pt) - updateTimeWith(*pt); - } -} - -void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector& names) -{ - std::set s(names.begin(),names.end()); - if(s.size()!=names.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !"); -} - -bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n) -{ - CheckValidNature(n); - return n==RevIntegral || n==IntegralGlobConstraint; -} - -void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2) -{ - CheckValidNature(n1); - CheckValidNature(n2); - if(n1!=n2) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !"); -} - -void DataArrayDoubleCollection::CheckValidNature(NatureOfField n) -{ - if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !"); -} - -MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector& ms, const std::vector< std::pair >& fieldNames) -{ - return new MEDCouplingGridCollection(ms,fieldNames); -} - -MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const -{ - return new MEDCouplingGridCollection(*this,newGf,oldGf); -} - -void MEDCouplingGridCollection::alloc(int ghostLev) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev)); - DataArrayDoubleCollection *dadc((*it).second); - if(dadc) - dadc->allocTuples(nbTuples); - else - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !"); - } -} - -void MEDCouplingGridCollection::dealloc() -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - DataArrayDoubleCollection *dadc((*it).second); - if(dadc) - dadc->dellocTuples(); - else - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !"); - } -} - -void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector >& compNames) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - (*it).second->spillInfoOnComponents(compNames); -} - -void MEDCouplingGridCollection::spillNatures(const std::vector& nfs) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - (*it).second->spillNatures(nfs); -} - -std::vector< std::pair > > MEDCouplingGridCollection::getInfoOnComponents() const -{ - if(_map_of_dadc.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !"); - const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !"); - return elt->getInfoOnComponents(); -} - -std::vector MEDCouplingGridCollection::getNatures() const -{ - if(_map_of_dadc.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !"); - const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !"); - return elt->getNatures(); -} - -bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const -{ - int ret(0); - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++) - { - if((*it).first==m) - { - pos=ret; - return true; - } - } - return false; -} - -const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const -{ - if(pos<0 || pos>(int)_map_of_dadc.size()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !"); - return *_map_of_dadc[pos].second; -} - -DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) -{ - if(pos<0 || pos>(int)_map_of_dadc.size()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !"); - return *_map_of_dadc[pos].second; -} - -/*! - * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting - * part of fields of \a this. The fields are expected to be the same between \a other and \a this. - * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure. - */ -void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - std::vector deltaThis,deltaOther; - std::vector< std::pair > rgThis((*it).first->positionRelativeToGodFather(deltaThis)); - std::vector thisSt((*it).first->getImageMesh()->getCellGridStructure()); - std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus(),2*ghostLev)); - for(std::vector< std::pair > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++) - { - std::vector< std::pair > rgOther((*it2).first->positionRelativeToGodFather(deltaOther)); - if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther)) - { - std::vector< std::pair > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther)); - std::vector< std::pair > pThis,pOther; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true); - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true); - std::vector otherSt((*it2).first->getImageMesh()->getCellGridStructure()); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev); - std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus(),2*ghostLev)); - int sz((*it2).second->size()); - for(int i=0;iat(i)); - DataArrayDouble *thisArr((*it).second->at(i)); - MEDCouplingAutoRefCountObjectPtr partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther)); - MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther); - } - } - } - } -} - -void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) - { - if((*it0).first==fatherOfFineMesh) - { - found=true; - int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); - const DataArrayDoubleCollection *coarseDaCol((*it0).second); - DataArrayDoubleCollection *coarseModified(const_cast(coarseDaCol));//coarse values in DataArrayDouble will be altered - DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified); - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !"); - } -} - -void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) - { - if((*it0).first==fatherOfFineMesh) - { - found=true; - int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); - const DataArrayDoubleCollection *fineDaCol((*it).second); - DataArrayDoubleCollection *fineModified(const_cast(fineDaCol));//fine values in DataArrayDouble will be altered - DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified); - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !"); - } -} - -/*! - * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead. - * - * \sa synchronizeFineEachOtherExt - */ -void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair >& ps) const -{ - for(std::vector< std::pair >::const_iterator it=ps.begin();it!=ps.end();it++) - { - int p1,p2; - if(!presenceOf((*it).first->getMesh(),p1)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !"); - if(!presenceOf((*it).second->getMesh(),p2)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !"); - const DataArrayDoubleCollection& col1(getFieldsAt(p1)); - const DataArrayDoubleCollection& col2(getFieldsAt(p2)); - col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather()); - } -} - -/*! - * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless. - * - * \sa synchronizeFineEachOther - */ -void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair >& ps) const -{ - for(std::vector< std::pair >::const_iterator it=ps.begin();it!=ps.end();it++) - { - int p1,p2; - if(!presenceOf((*it).first->getMesh(),p1)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !"); - if(!presenceOf((*it).second->getMesh(),p2)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !"); - const DataArrayDoubleCollection& col1(getFieldsAt(p1)); - const DataArrayDoubleCollection& col2(getFieldsAt(p2)); - col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second); - } -} - -/*! - * The pairs returned share the same direct father. The number of returned elements must be even. - */ -std::vector< std::pair > MEDCouplingGridCollection::findNeighbors(int ghostLev) const -{ - std::vector< std::pair > ret; - std::map > m; - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - m[fatherOfFineMesh].push_back(fineMesh); - } - for(std::map >::const_iterator it0=m.begin();it0!=m.end();it0++) - { - for(std::vector::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) - { - int patchId((*it0).first->getPatchIdFromChildMesh(*it1)); - std::vector neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); - const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId)); - for(std::vector::const_iterator it2=neighs.begin();it2!=neighs.end();it2++) - { - const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2)); - ret.push_back(std::pair(pRef,pLoc)); - } - } - } - if(ret.size()%2!=0) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !"); - return ret; -} - -void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) - { - if((*it0).first==fatherOfFineMesh) - { - found=true; - int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); - const DataArrayDoubleCollection *fineDaCol((*it).second); - DataArrayDoubleCollection *fineModified(const_cast(fineDaCol));//fine values in DataArrayDouble will be altered - DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified); - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !"); - } -} - -void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector& recurseArrs) const -{ - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *a((*it).first); - if(head==a || head->isObjectInTheProgeny(a)) - { - const DataArrayDoubleCollection *gc((*it).second); - recurseArrs.push_back(gc->getFieldWithName(fieldName)); - } - } -} - -MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector& ms, const std::vector< std::pair >& fieldNames):_map_of_dadc(ms.size()) -{ - std::size_t sz(ms.size()); - for(std::size_t i=0;i pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf)); - _map_of_dadc[i].first=newGf->getMeshAtPosition(pos); - const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second); - if(dac) - _map_of_dadc[i].second=dac->deepCpy(); - } -} - -std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDCouplingGridCollection)); - ret+=_map_of_dadc.capacity()*sizeof(std::pair >); - return ret; -} - -std::vector MEDCouplingGridCollection::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - ret.push_back((const DataArrayDoubleCollection *)(*it).second); - return ret; -} - -void MEDCouplingGridCollection::updateTime() const -{ - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *a((*it).first); - if(a) - updateTimeWith(*a); - const DataArrayDoubleCollection *b((*it).second); - if(b) - updateTimeWith(*b); - } -} - -/// @endcond - -MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() -{ - return _gf; -} - -const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const -{ - return _gf; -} - -MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf) -{ - if(!gf) - throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !"); - gf->incrRef(); -} - -void MEDCouplingDataForGodFather::checkGodFatherFrozen() const -{ - _tlc.checkConst(); -} - -bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf) -{ - bool ret(_tlc.keepTrackOfNewTL(gf)); - if(ret) - { - _gf=gf; - if(gf) - gf->incrRef(); - } - return ret; -} - -MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf) -{ - other._tlc.checkConst(); - if(deepCpyGF) - { - const MEDCouplingCartesianAMRMesh *gf(other._gf); - if(gf) - _gf=gf->deepCpy(0); - _tlc.keepTrackOfNewTL(_gf); - } -} - -/*! - * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation. - */ -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev) -{ - return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev); -} - -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames, int ghostLev) -{ - std::size_t sz(fieldNames.size()); - std::vector< std::pair > fieldNames2(sz); - std::vector< std::vector > compNames(sz); - for(std::size_t i=0;i ret(New(gf,fieldNames2,ghostLev)); - ret->spillInfoOnComponents(compNames); - return ret.retn(); -} - -/*! - * Assign the info on components for all DataArrayDouble instance recursively stored in \a this. - * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New. - * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has - * to perfectly fit with those specified in MEDCouplingAMRAttribute::New. - */ -void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector >& compNames) -{ - _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - (*it)->spillInfoOnComponents(compNames); -} - -/*! - * Assign nature for each fields in \a this. - * \param [in] nfs - */ -void MEDCouplingAMRAttribute::spillNatures(const std::vector& nfs) -{ - _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - (*it)->spillNatures(nfs); -} - -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const -{ - return new MEDCouplingAMRAttribute(*this,true); -} - -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const -{ - return new MEDCouplingAMRAttribute(*this,false); -} - -/*! - * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this). - * - */ -int MEDCouplingAMRAttribute::getNumberOfLevels() const -{ - checkGodFatherFrozen(); - return (int)_levs.size(); -} - -/*! - * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh. - * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown. - * - * \return std::vector - DataArrayDouble instances to be deallocated by the caller (using decrRef). - * \sa retrieveFieldOn - */ -std::vector MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - return ddc.retrieveFields(); - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !"); -} - -/*! - * \sa retrieveFieldsOn - */ -const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - return ddc.getFieldWithName(fieldName); - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !"); -} - -DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - return ddc.getFieldWithName(fieldName); - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !"); -} - -/*! - * This method returns a field on an unstructured mesh the most refined as possible without overlap. - * Ghost part are not visible here. - * - * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). - */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - std::vector recurseArrs; - std::size_t lev(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - recurseArrs.push_back(ddc.getFieldWithName(fieldName)); - break; - } - } - lev++; - for(std::size_t i=lev;i<_levs.size();i++) - { - const MEDCouplingGridCollection *gc(_levs[i]); - gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs); - } - return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs); -} - -/*! - * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement. - * The output field also displays ghost cells. - * - * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). - * - * \sa buildCellFieldOnWithoutGhost - */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - const DataArrayDouble *arr(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - arr=ddc.getFieldWithName(fieldName); - } - } - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !"); - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); - ret->setMesh(im); - ret->setArray(const_cast(arr)); - ret->setName(arr->getName()); - return ret.retn(); -} - -/*! - * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement. - * The output field does not display ghost cells. - * - * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). - * - * \sa buildCellFieldOnWithGhost - */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - const DataArrayDouble *arr(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - arr=ddc.getFieldWithName(fieldName); - } - } - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !"); - // - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - std::vector cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); - MEDCouplingAutoRefCountObjectPtr arr2(DataArrayDouble::New()); - arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents()); - std::vector< std::pair > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); - std::vector fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); - MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors); - arr2->copyStringInfoFrom(*arr); - // - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); - ret->setMesh(mesh->getImageMesh()); - ret->setArray(arr2); - ret->setName(arr->getName()); - return ret.retn(); -} - - -std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const -{ - static const char EXT[]=".vthb"; - std::string baseName,extName,zeFileName; - MEDCouplingMesh::SplitExtension(fileName,baseName,extName); - if(extName==EXT) - zeFileName=fileName; - else - { zeFileName=baseName; zeFileName+=EXT; } - // - std::ofstream ofs(fileName.c_str()); - ofs << "\n"; - const MEDCouplingCartesianAMRMesh *gf(getMyGodFather()); - ofs << " getImageMesh()); - std::vector orig(gfm->getOrigin()); - std::vector spacing(gfm->getDXYZ()); - int dim((int)orig.size()); - std::copy(orig.begin(),orig.end(),std::ostream_iterator(ofs," ")); ofs << "\" grid_description=\""; - for(int i=0;i\n"; - // - int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0); - for(int i=0;i patches(gf->retrieveGridsAt(i)); - std::size_t sz(patches.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe(sz); - for(std::size_t j=0;j(ofs," ")); - ofs << "\">\n"; - if(i!=maxLev-1) - { - std::vector factors(patches[0]->getMesh()->getFactors()); - for(int k=0;k::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++) - { - ofs << " (*it)); - const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh()); - if(patchCast) - { - const std::vector< std::pair >& bltr(patchCast->getBLTRRangeRelativeToGF()); - for(int pp=0;ppgetMesh()->getImageMesh()); - std::vector cgs(im->getCellGridStructure()); - for(int pp=0;pppresenceOf((*it)->getMesh(),tmp)) - { - const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp)); - std::vector arrs(ddc.retrieveFields()); - std::size_t nbFields(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe(nbFields),arrs2Safe(nbFields); - std::vector< const MEDCouplingFieldDouble *> fields(nbFields); - std::vector< MEDCouplingAutoRefCountObjectPtr > fieldsSafe(nbFields); - for(std::size_t pp=0;pp im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - std::vector cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); - arrs2Safe[pp]=DataArrayDouble::New(); - arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents()); - std::vector< std::pair > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); - std::vector fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); - MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors); - arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]); - // - fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp]; - fieldsSafe[pp]->setMesh(mesh->getImageMesh()); - fieldsSafe[pp]->setArray(arrs2Safe[pp]); - fieldsSafe[pp]->setName(arrs[pp]->getName()); - } - std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti"; - MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true); - // - ofs << vtiFileName.str() << "\">\n"; - ofs << " \n \n"; - } - } - ofs << " \n"; - } - // - ofs << " \n"; - ofs << "\n"; - return zeFileName; -} - - /*! - * This method is useful just after a remesh after a time step computation to project values in \a this to the new - * mesh \a targetGF. - * - * This method performs a projection from \a this to a target AMR mesh \a targetGF. - * This method performs the projection by trying to transfer the finest information to \a targetGF. - * \b WARNING this method does not update the ghost zone, if any. - * The level0 of \a this god father must have the same structure than those of \a targetGF. - * - * This method makes checks that ghost size of \a this and \a targetGF are the same, and that - * the number of levels in \a this and in \a targetGF are also the same. - */ -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const -{ - if(!targetGF) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !"); - if(_levs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !"); - const MEDCouplingGridCollection *lev0(_levs[0]); - if(!lev0) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !"); - std::vector< std::pair < std::string, std::vector > > fieldNames(lev0->getInfoOnComponents()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev)); - ret->spillNatures(lev0->getNatures()); - ret->alloc(); - int nbLevs(getNumberOfLevels()); - if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !"); - // first step copy level0 - if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !"); - const DataArrayDoubleCollection& col(lev0->getFieldsAt(0)); - DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0)); - colTarget.copyFrom(col); - // then go deeper and deeper - for(int i=1;isynchronizeCoarseToFineByOneLevel(i-1); - MEDCouplingGridCollection *targetCol(ret->_levs[i]); - if(!targetCol) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !"); - const MEDCouplingGridCollection *thisCol(_levs[i]); - if(!thisCol) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !"); - targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol); - } - return ret.retn(); -} - -/*! - * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using - * MEDCouplingAMRAttribute::alloc method. - * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse) - * - * \sa synchronizeFineToCoarseBetween - */ -void MEDCouplingAMRAttribute::synchronizeFineToCoarse() -{ - if(_levs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !"); - std::size_t sz(_levs.size()); - // - while(sz>1) - { - sz--; - synchronizeFineToCoarseByOneLevel((int)sz); - } -} - -/*! - * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level. - * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ... - * until reaching \a toLev level. - * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse). - * - * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev - * \param [in] toLev - an existing level considered as the target level to reach. - * - */ -void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev) -{ - int nbl(getNumberOfLevels()); - if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !"); - if(fromLev==toLev) - return ;//nothing to do - if(fromLevtoLev;i--) - synchronizeFineToCoarseByOneLevel(i); -} - -/*! - * This method synchronizes from coarse to fine arrays and fine to fine each other (if _ghost_lev is >0). This method makes the hypothesis that \a this has been allocated before using - * MEDCouplingAMRAttribute::alloc method. - * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method) - */ -void MEDCouplingAMRAttribute::synchronizeCoarseToFine() -{ - if(_levs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !"); - std::size_t sz(_levs.size()); - // - for(std::size_t i=0;i=nbl || toLev>=nbl) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !"); - if(fromLev==toLev) - return ;//nothing to do - if(fromLev>toLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !"); - for(int i=fromLev;isynchronizeFineEachOther(_ghost_lev,_neighbors[i]); - } - // 3rd - mixed level - for(std::vector< std::pair >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++) - { - const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh())); - DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC); - } - // 4th - same level but with far ancestor. - for(int i=1;isynchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]); - } -} - -/*! - * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here. - * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh). - * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father. - * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead. - * - * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other. - * - */ -void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !"); - int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels()); - if(level<0 || level>=sz-1) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !"); - const std::vector< std::pair >& itemsToFilter(_neighbors[level+1]); - std::vector< std::pair > itemsToSync; itemsToSync.reserve(itemsToFilter.size()); - for(std::vector< std::pair >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++) - { - if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh) - itemsToSync.push_back(std::pair((*it).first,(*it).second)); - } - const MEDCouplingGridCollection *curLev(_levs[level+1]); - if(!curLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !"); - curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync); -} - -/*! - * This method updates \b all the patches at level \a level each other without consideration of their father. - * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf. - */ -void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level) -{ - int maxLev(getNumberOfLevels()); - if(level<0 || level>=maxLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !"); - if(level==0) - return ;//at level 0 only one patch -> no need to update - // 1st step - updates all patches pairs at level \a level sharing the same father - const std::vector< std::pair >& items(_neighbors[level]); - const MEDCouplingGridCollection *curLev(_levs[level]); - if(!curLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !"); - curLev->synchronizeFineEachOther(_ghost_lev,items); - //2nd step - updates all patches pairs at level \a level not sharing the same father - const std::vector< std::pair >& items2(_cross_lev_neighbors[level]); - curLev->synchronizeFineEachOtherExt(_ghost_lev,items2); -} - -/*! - * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1). - * This method is useful to propagate to the ghost zone of childhood the modification. - */ -void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) -{ - int maxLev(getNumberOfLevels()); - if(level<=0 || level>=maxLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !"); - const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); - MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine); - //_cross_lev_neighbors is not needed. -} - -/*! - * This method allocates all DataArrayDouble instances stored recursively in \a this. - * - * \sa dealloc - */ -void MEDCouplingAMRAttribute::alloc() -{ - _tlc.resetState(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - { - MEDCouplingGridCollection *elt(*it); - if(elt) - elt->alloc(_ghost_lev); - else - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !"); - } -} - -/*! - * This method deallocates all DataArrayDouble instances stored recursively in \a this. - * \sa alloc - */ -void MEDCouplingAMRAttribute::dealloc() -{ - _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - { - MEDCouplingGridCollection *elt(*it); - if(elt) - elt->dealloc(); - else - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !"); - } -} - -bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf) -{ - bool ret(MEDCouplingDataForGodFather::changeGodFather(gf)); - return ret; -} - -std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDCouplingAMRAttribute)); - ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; -} - -std::vector MEDCouplingAMRAttribute::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - ret.push_back((const MEDCouplingGridCollection *)*it); - return ret; -} - -void MEDCouplingAMRAttribute::updateTime() const -{//tony -} - -MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev) -{ - //gf non empty, checked by constructor - int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()); - _levs.resize(maxLev); - for(int i=0;i patches(gf->retrieveGridsAt(i)); - std::size_t sz(patches.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe(patches.size()); - for(std::size_t j=0;j ms(sz); - for(std::size_t j=0;jgetMesh(); - } - _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames); - } - // updates cross levels neighbors - _neighbors.resize(_levs.size()); - _cross_lev_neighbors.resize(_levs.size()); - if(_levs.empty()) - throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !"); - std::size_t sz(_levs.size()); - for(std::size_t i=1;ifindNeighbors(_ghost_lev); - if(i!=sz-1) - { - for(std::vector< std::pair >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++) - { - MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors); - std::vector< std::vector < std::pair > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second)); - std::size_t fullLev(i+neighs2.size()); - if(fullLev>=sz) - throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !"); - std::size_t ii(i+1); - for(std::vector< std::vector< std::pair > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++) - _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end()); - } - } - } -} - -MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF):MEDCouplingDataForGodFather(other,deepCpyGF),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors) -{ - std::size_t sz(other._levs.size()); - for(std::size_t i=0;ideepCpy(_gf,other._gf); - } - } - //_cross_lev_neighbors(other._cross_lev_neighbors) - sz=other._neighbors.size(); - for(std::size_t i=0;i >& neigh2(other._neighbors[i]); - std::size_t sz2(neigh2.size()); - std::vector< std::pair >& neigh3(_neighbors[i]); - for(std::size_t j=0;j pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); - neigh3[j].first=_gf->getPatchAtPosition(pp1); - neigh3[j].second=_gf->getPatchAtPosition(pp2); - } - } - // - sz=other._mixed_lev_neighbors.size(); - for(std::size_t i=0;i pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); - _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1); - _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2); - } - // - sz=other._cross_lev_neighbors.size(); - for(std::size_t i=0;i >& neigh2(other._cross_lev_neighbors[i]); - std::size_t sz2(neigh2.size()); - std::vector< std::pair >& neigh3(_cross_lev_neighbors[i]); - for(std::size_t j=0;j pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); - neigh3[j].first=_gf->getPatchAtPosition(pp1); - neigh3[j].second=_gf->getPatchAtPosition(pp2); - } - } -} - -const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - const MEDCouplingGridCollection *elt(*it); - if(elt) - { - int tmp(-1); - if(elt->presenceOf(m,tmp)) - { - return elt->getFieldsAt(tmp); - } - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !"); -} - -void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level) -{ - int nbl(getNumberOfLevels()); - if(level<=0 || level>=nbl) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !"); - const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); - MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse); -} - -void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level) -{ - int nbl(getNumberOfLevels()); - if(level<0 || level>=nbl-1) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !"); - const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]); - MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.hxx b/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.hxx deleted file mode 100644 index 2af4d3b92..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.hxx +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#ifndef __MEDCOUPLINGAMRATTRIBUTE_HXX__ -#define __MEDCOUPLINGAMRATTRIBUTE_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingNatureOfFieldEnum" -#include "MEDCouplingCartesianAMRMesh.hxx" - -namespace ParaMEDMEM -{ - /// @cond INTERNAL - class DataArrayDoubleCollection : public RefCountObject, public TimeLabel - { - public: - static DataArrayDoubleCollection *New(const std::vector< std::pair >& fieldNames); - DataArrayDoubleCollection *deepCpy() const; - void allocTuples(int nbOfTuples); - void dellocTuples(); - void copyFrom(const DataArrayDoubleCollection& other); - void spillInfoOnComponents(const std::vector< std::vector >& compNames); - void spillNatures(const std::vector& nfs); - std::vector< std::pair > > getInfoOnComponents() const; - std::vector getNatures() const; - std::vector retrieveFields() const; - const DataArrayDouble *getFieldWithName(const std::string& name) const; - DataArrayDouble *getFieldWithName(const std::string& name); - DataArrayDouble *at(int pos); - const DataArrayDouble *at(int pos) const; - int size() const; - static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse); - static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); - static void SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector& children, const std::vector& fieldsOnFine); - static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); - static void SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac); - void synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const; - void synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const; - private: - DataArrayDoubleCollection(const std::vector< std::pair >& fieldNames); - DataArrayDoubleCollection(const DataArrayDoubleCollection& other); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - void updateTime() const; - static void CheckDiscriminantNames(const std::vector& names); - static bool IsConservativeNature(NatureOfField n); - static void CheckSameNatures(NatureOfField n1, NatureOfField n2); - static void CheckValidNature(NatureOfField n); - private: - std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > > _arrs; - }; - - class MEDCouplingGridCollection : public RefCountObject, public TimeLabel - { - public: - static MEDCouplingGridCollection *New(const std::vector& ms, const std::vector< std::pair >& fieldNames); - MEDCouplingGridCollection *deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const; - void alloc(int ghostLev); - void dealloc(); - void spillInfoOnComponents(const std::vector< std::vector >& compNames); - void spillNatures(const std::vector& nfs); - std::vector< std::pair > > getInfoOnComponents() const; - std::vector getNatures() const; - bool presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const; - const DataArrayDoubleCollection& getFieldsAt(int pos) const; - DataArrayDoubleCollection& getFieldsAt(int pos); - void copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other); - static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse); - static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); - void synchronizeFineEachOther(int ghostLev, const std::vector< std::pair >& ps) const; - void synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair >& ps) const; - std::vector< std::pair > findNeighbors(int ghostLev) const; - static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); - void fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector& recurseArrs) const; - private: - MEDCouplingGridCollection(const std::vector& ms, const std::vector< std::pair >& fieldNames); - MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - void updateTime() const; - private: - std::vector< std::pair > > _map_of_dadc; - }; - - /// @endcond - - class MEDCouplingDataForGodFather : public RefCountObject - { - friend class MEDCouplingCartesianAMRMesh; - public: - MEDCOUPLING_EXPORT MEDCouplingCartesianAMRMesh *getMyGodFather(); - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getMyGodFather() const; - MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZones() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesAtASpecifiedLevel(int level) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) = 0; - MEDCOUPLING_EXPORT virtual void alloc() = 0; - MEDCOUPLING_EXPORT virtual void dealloc() = 0; - protected: - MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf); - void checkGodFatherFrozen() const; - protected: - virtual bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); - MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF); - protected: - MEDCouplingAutoRefCountObjectPtr _gf; - TimeLabelConstOverseer _tlc; - }; - - class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev); - MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames, int ghostLev); - MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector >& compNames); - MEDCOUPLING_EXPORT void spillNatures(const std::vector& nfs); - MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpyWithoutGodFather() const; - MEDCOUPLING_EXPORT int getNumberOfLevels() const; - MEDCOUPLING_EXPORT std::vector retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const; - MEDCOUPLING_EXPORT const DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT std::string writeVTHB(const std::string& fileName) const; - // - MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const; - // - MEDCOUPLING_EXPORT void synchronizeFineToCoarse(); - MEDCOUPLING_EXPORT void synchronizeFineToCoarseBetween(int fromLev, int toLev); - MEDCOUPLING_EXPORT void synchronizeCoarseToFine(); - MEDCOUPLING_EXPORT void synchronizeCoarseToFineBetween(int fromLev, int toLev); - MEDCOUPLING_EXPORT void synchronizeAllGhostZones(); - MEDCOUPLING_EXPORT void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh); - MEDCOUPLING_EXPORT void synchronizeAllGhostZonesAtASpecifiedLevel(int level); - MEDCOUPLING_EXPORT void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level); - // - MEDCOUPLING_EXPORT void alloc(); - MEDCOUPLING_EXPORT void dealloc(); - MEDCOUPLING_EXPORT bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); - // - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void updateTime() const; - private: - MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev); - MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF); - const DataArrayDoubleCollection& findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const; - void synchronizeFineToCoarseByOneLevel(int level); - void synchronizeCoarseToFineByOneLevel(int level); - private: - int _ghost_lev; - std::vector< MEDCouplingAutoRefCountObjectPtr > _levs; - std::vector< std::vector< std::pair > > _neighbors; - std::vector< std::pair > _mixed_lev_neighbors; - std::vector< std::vector< std::pair > > _cross_lev_neighbors; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/medtool/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx deleted file mode 100644 index 02719b50b..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "InterpKernelException.hxx" - -namespace ParaMEDMEM -{ - template - class MEDCouplingAutoRefCountObjectPtr - { - public: - MEDCouplingAutoRefCountObjectPtr(const MEDCouplingAutoRefCountObjectPtr& other):_ptr(0) { referPtr(other._ptr); } - MEDCouplingAutoRefCountObjectPtr(T *ptr=0):_ptr(ptr) { } - ~MEDCouplingAutoRefCountObjectPtr() { destroyPtr(); } - bool operator==(const MEDCouplingAutoRefCountObjectPtr& other) const { return _ptr==other._ptr; } - bool operator==(const T *other) const { return _ptr==other; } - MEDCouplingAutoRefCountObjectPtr &operator=(const MEDCouplingAutoRefCountObjectPtr& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; } - MEDCouplingAutoRefCountObjectPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; } - T *operator->() { return _ptr ; } - const T *operator->() const { return _ptr; } - T& operator*() { return *_ptr; } - const T& operator*() const { return *_ptr; } - operator T *() { return _ptr; } - operator const T *() const { return _ptr; } - T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; } - private: - void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); } - void destroyPtr() { if(_ptr) _ptr->decrRef(); } - private: - T *_ptr; - }; - - template - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr DynamicCast(typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr& autoSubPtr) throw() - { - T *subPtr(autoSubPtr); - U *ptr(dynamic_cast(subPtr)); - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret(ptr); - if(ptr) - ptr->incrRef(); - return ret; - } - - template - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr DynamicCastSafe(typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr& autoSubPtr) - { - T *subPtr(autoSubPtr); - U *ptr(dynamic_cast(subPtr)); - if(subPtr && !ptr) - throw INTERP_KERNEL::Exception("DynamicCastSafe : U is not a subtype of T !"); - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret(ptr); - if(ptr) - ptr->incrRef(); - return ret; - } -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingCMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingCMesh.cxx deleted file mode 100644 index 597b682a6..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingCMesh.cxx +++ /dev/null @@ -1,923 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) -{ -} - -MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy) -{ - if(deepCopy) - { - if(other._x_array) - _x_array=other._x_array->deepCpy(); - else - _x_array=0; - if(other._y_array) - _y_array=other._y_array->deepCpy(); - else - _y_array=0; - if(other._z_array) - _z_array=other._z_array->deepCpy(); - else - _z_array=0; - } - else - { - _x_array=other._x_array; - if(_x_array) - _x_array->incrRef(); - _y_array=other._y_array; - if(_y_array) - _y_array->incrRef(); - _z_array=other._z_array; - if(_z_array) - _z_array->incrRef(); - } -} - -MEDCouplingCMesh::~MEDCouplingCMesh() -{ - if(_x_array) - _x_array->decrRef(); - if(_y_array) - _y_array->decrRef(); - if(_z_array) - _z_array->decrRef(); -} - -MEDCouplingCMesh *MEDCouplingCMesh::New() -{ - return new MEDCouplingCMesh; -} - -MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName) -{ - MEDCouplingCMesh *ret=new MEDCouplingCMesh; - ret->setName(meshName); - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingCMesh(*this,recDeepCpy); -} - -void MEDCouplingCMesh::updateTime() const -{ - if(_x_array) - updateTimeWith(*_x_array); - if(_y_array) - updateTimeWith(*_y_array); - if(_z_array) - updateTimeWith(*_z_array); -} - -std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingCMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_x_array); - ret.push_back(_y_array); - ret.push_back(_z_array); - return ret; -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - MEDCouplingStructuredMesh::copyTinyStringsFrom(other); - const MEDCouplingCMesh *otherC(dynamic_cast(other)); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); - if(_x_array && otherC->_x_array) - _x_array->copyStringInfoFrom(*otherC->_x_array); - if(_y_array && otherC->_y_array) - _y_array->copyStringInfoFrom(*otherC->_y_array); - if(_z_array && otherC->_z_array) - _z_array->copyStringInfoFrom(*otherC->_z_array); -} - -bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingCMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingCMesh !"; - return false; - } - if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; - std::ostringstream oss; oss.precision(15); - for(int i=0;i<3;i++) - { - if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) - { - oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !"; - reason=oss.str(); - return false; - } - if(thisArr[i]) - if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason)) - { - oss << "Coordinates DataArrayDouble of rank #" << i << " differ :"; - reason.insert(0,oss.str()); - return false; - } - } - return true; -} - -bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingCMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; - for(int i=0;i<3;i++) - { - if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) - return false; - if(thisArr[i]) - if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec)) - return false; - } - return true; -} - -void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !"); -} - -/*! - * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too). - * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, \a this and \a other are the same ! - */ -void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); -} - -void MEDCouplingCMesh::checkCoherency() const -{ - const char msg0[]="Invalid "; - const char msg1[]=" array ! Must contain more than 1 element."; - const char msg2[]=" array ! Must be with only one component."; - getSpaceDimension();// here to check that no holes in arrays ! - if(_x_array) - { - if(_x_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'X' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(_x_array->getNumberOfComponents()!=1) - { - std::ostringstream os; os << msg0 << 'X' << msg2; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - } - if(_y_array) - { - if(_y_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'Y' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(_y_array->getNumberOfComponents()!=1) - { - std::ostringstream os; os << msg0 << 'Y' << msg2; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - } - if(_z_array) - { - if(_z_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'Z' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(_z_array->getNumberOfComponents()!=1) - { - std::ostringstream os; os << msg0 << 'Z' << msg2; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - } -} - -void MEDCouplingCMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - if(_x_array) - _x_array->checkMonotonic(true, eps); - if(_y_array) - _y_array->checkMonotonic(true, eps); - if(_z_array) - _z_array->checkMonotonic(true, eps); -} - -void MEDCouplingCMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -void MEDCouplingCMesh::getNodeGridStructure(int *res) const -{ - std::vector ret(getNodeGridStructure()); - std::copy(ret.begin(),ret.end(),res); -} - -std::vector MEDCouplingCMesh::getNodeGridStructure() const -{ - static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !"; - std::vector ret; - bool isOK(true); - if(_x_array) - { - if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !"); - ret.push_back(_x_array->getNumberOfTuples()); - } - else - isOK=false; - if(_y_array) - { - if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !"); - if(!isOK) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(_y_array->getNumberOfTuples()); - } - else - isOK=false; - if(_z_array) - { - if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !"); - if(!isOK) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(_z_array->getNumberOfTuples()); - } - return ret; -} - -MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - if(dim!=(int)cellPart.size()) - { - std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); - for(int i=0;i tmp(ret->getCoordsAt(i)->selectByTupleId2(cellPart[i].first,cellPart[i].second+1,1)); - ret->setCoordsAt(i,tmp); - } - return ret.retn(); -} - -/*! - * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that. - * This method throws exceptions if the not null arrays defining this are not contiguously at the end. For example X!=0,Y==0,Z!=0 will throw. - */ -int MEDCouplingCMesh::getSpaceDimension() const -{ - return (int)getNodeGridStructure().size(); -} - -void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - int tmp[3]; - int spaceDim=getSpaceDimension(); - getSplitNodeValues(tmp); - const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - int tmp2[3]; - GetPosFromId(nodeId,spaceDim,tmp,tmp2); - for(int j=0;jgetConstPointer()[tmp2[j]]); -} - -std::string MEDCouplingCMesh::simpleRepr() const -{ - std::ostringstream ret; - ret << "Cartesian mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - ret << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n"; - if(_x_array) - { - ret << "X Array :\n"; - _x_array->reprZipWithoutNameStream(ret); - } - if(_y_array) - { - ret << "Y Array :\n"; - _y_array->reprZipWithoutNameStream(ret); - } - if(_z_array) - { - ret << "Z Array :\n"; - _z_array->reprZipWithoutNameStream(ret); - } - return ret.str(); -} - -std::string MEDCouplingCMesh::advancedRepr() const -{ - return simpleRepr(); -} - -/*! - * Returns a DataArrayDouble holding positions of nodes along a given axis. - * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage. - * \param [in] i - an index of axis, a value from [0,1,2]. - * \return const DataArrayDouble * - a pointer to the data array of node coordinates - * referred by \a this mesh. - * \throw If \a i is not one of [0,1,2]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
- * \ref py_mccmesh_getCoordsAt "Here is a Python example". - * \endif - */ -const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const -{ - switch(i) - { - case 0: - return _x_array; - case 1: - return _y_array; - case 2: - return _z_array; - default: - throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - } -} - -/*! - * Returns a DataArrayDouble holding positions of nodes along a given axis. - * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage. - * \param [in] i - an index of axis, a value from [0,1,2]. - * \return const DataArrayDouble * - a pointer to the data array of node coordinates - * referred by \a this mesh. - * \throw If \a i is not one of [0,1,2]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
- * \ref py_mccmesh_getCoordsAt "Here is a Python example". - * \endif - */ -DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) -{ - switch(i) - { - case 0: - return _x_array; - case 1: - return _y_array; - case 2: - return _z_array; - default: - throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - } -} - -/*! - * Sets node coordinates along a given axis. For more info on Cartesian meshes, see - * \ref MEDCouplingCMeshPage. - * \param [in] i - an index of axis, a value in range [0,1,2]. - * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th - * axis. It must be an array of one component. - * \throw If \a arr->getNumberOfComponents() != 1. - * \throw If \a i is not one of [0,1,2]. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) -{ - if(arr) - arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt"); - DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; - if(i<0 || i>2) - throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - if(arr!=*(thisArr[i])) - { - if(*(thisArr[i])) - (*(thisArr[i]))->decrRef(); - (*(thisArr[i]))=const_cast(arr); - if(*(thisArr[i])) - (*(thisArr[i]))->incrRef(); - declareAsNew(); - } -} - -/*! - * Sets node coordinates along some of the tree axes. This method updates all the - * three node coordinates arrays at once. For more info on Cartesian meshes, see - * \ref MEDCouplingCMeshPage. - * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X - * axis. It must be an array of one component or \c NULL. - * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y - * axis. It must be an array of one component or \c NULL. - * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z - * axis. It must be an array of one component or \c NULL. - * \throw If \a coords*->getNumberOfComponents() != 1. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) -{ - if(coordsX) - coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX"); - if(coordsY) - coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY"); - if(coordsZ) - coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ"); - if(_x_array) - _x_array->decrRef(); - _x_array=const_cast(coordsX); - if(_x_array) - _x_array->incrRef(); - if(_y_array) - _y_array->decrRef(); - _y_array=const_cast(coordsY); - if(_y_array) - _y_array->incrRef(); - if(_z_array) - _z_array->decrRef(); - _z_array=const_cast(coordsZ); - if(_z_array) - _z_array->incrRef(); - declareAsNew(); -} - -void MEDCouplingCMesh::getBoundingBox(double *bbox) const -{ - int dim=getSpaceDimension(); - int j=0; - for (int idim=0; idimgetConstPointer(); - int nb=c->getNbOfElems(); - bbox[2*j]=coords[0]; - bbox[2*j+1]=coords[nb-1]; - j++; - } - } -} - -/*! - * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this - * mesh.
- * For 1D cells, the returned field contains lengths.
- * For 2D cells, the returned field contains areas.
- * For 3D cells, the returned field contains volumes. - * \param [in] isAbs - a not used parameter. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells - * and one time . The caller is to delete this field using decrRef() as it is no - * more needed. - */ -MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const -{ - std::string name="MeasureOfMesh_"; - name+=getName(); - int nbelem=getNumberOfCells(); - MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - field->setName(name); - DataArrayDouble* array=DataArrayDouble::New(); - array->alloc(nbelem,1); - double *area_vol=array->getPointer(); - field->setArray(array) ; - array->decrRef(); - field->setMesh(const_cast(this)); - field->synchronizeTimeWithMesh(); - int tmp[3]; - getSplitCellValues(tmp); - int dim=getSpaceDimension(); - const double **thisArr=new const double *[dim]; - const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array}; - for(int i=0;igetConstPointer(); - for(int icell=0;icellgetConstPointer(); - int nbOfNodes=getCoordsAt(i)->getNbOfElems(); - double ref=pos[i]; - const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal(),ref)); - int w2=(int)std::distance(d,w); - if(w2d[0]-eps) - w2=1; - else - return -1; - } - ret+=coeff*(w2-1); - coeff*=nbOfNodes-1; - } - else - return -1; - } - return ret; -} - -void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle) -{ - throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !"); -} - -/*! - * Translates all nodes of \a this mesh by a given vector. Actually, it adds each - * component of the \a vector to all node coordinates of a corresponding axis. - * \param [in] vector - the translation vector whose size must be not less than \a - * this->getSpaceDimension(). - */ -void MEDCouplingCMesh::translate(const double *vector) -{ - if(_x_array) - std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(), - _x_array->getPointer(),std::bind2nd(std::plus(),vector[0])); - if(_y_array) - std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(), - _y_array->getPointer(),std::bind2nd(std::plus(),vector[1])); - if(_z_array) - std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(), - _z_array->getPointer(),std::bind2nd(std::plus(),vector[2])); -} - -/*! - * Applies scaling transformation to all nodes of \a this mesh. - * \param [in] point - coordinates of a scaling center. This array is to be of - * size \a this->getSpaceDimension() at least. - * \param [in] factor - a scale factor. - */ -void MEDCouplingCMesh::scale(const double *point, double factor) -{ - for(int i=0;i<3;i++) - { - DataArrayDouble *c=getCoordsAt(i); - if(c) - { - double *coords=c->getPointer(); - int lgth=c->getNbOfElems(); - std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus(),point[i])); - std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies(),factor)); - std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus(),point[i])); - c->declareAsNew(); - } - } - updateTime(); -} - -MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - //not implemented yet ! - return 0; -} - -/*! - * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh. - * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a - * this->getNumberOfNodes() tuples per \a this->getSpaceDimension() - * components. The caller is to delete this array using decrRef() as it is - * no more needed. - */ -DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const -{ - DataArrayDouble *ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbNodes=getNumberOfNodes(); - ret->alloc(nbNodes,spaceDim); - double *pt=ret->getPointer(); - int tmp[3]; - getSplitNodeValues(tmp); - const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - const double *tabsPtr[3]; - for(int j=0;jgetConstPointer(); - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); - } - int tmp2[3]; - for(int i=0;igetNumberOfCells() tuples per \a this->getSpaceDimension() - * components. The caller is to delete this array using decrRef() as it is - * no more needed. - */ -DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const -{ - DataArrayDouble *ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbCells=getNumberOfCells(); - ret->alloc(nbCells,spaceDim); - double *pt=ret->getPointer(); - int tmp[3]; - getSplitCellValues(tmp); - const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - std::vector tabsPtr[3]; - for(int j=0;jgetNbOfElems()-1; - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); - const double *srcPtr=tabs[j]->getConstPointer(); - tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz); - std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus()); - std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies(),0.5)); - } - int tmp2[3]; - for(int i=0;i& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time=getTime(it,order); - tinyInfo.clear(); - tinyInfoD.clear(); - littleStrings.clear(); - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); - littleStrings.push_back(getTimeUnit()); - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - for(int i=0;i<3;i++) - { - int val=-1; - std::string st; - if(thisArr[i]) - { - val=thisArr[i]->getNumberOfTuples(); - st=thisArr[i]->getInfoOnComponent(0); - } - tinyInfo.push_back(val); - littleStrings.push_back(st); - } - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfoD.push_back(time); -} - -void MEDCouplingCMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - a1->alloc(0,1); - int sum=0; - for(int i=0;i<3;i++) - if(tinyInfo[i]!=-1) - sum+=tinyInfo[i]; - a2->alloc(sum,1); -} - -void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); - a1->alloc(0,1); - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - int sz=0; - for(int i=0;i<3;i++) - { - if(thisArr[i]) - sz+=thisArr[i]->getNumberOfTuples(); - } - a2=DataArrayDouble::New(); - a2->alloc(sz,1); - double *a2Ptr=a2->getPointer(); - for(int i=0;i<3;i++) - if(thisArr[i]) - a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr); -} - -void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; - const double *data=a2->getConstPointer(); - for(int i=0;i<3;i++) - { - if(tinyInfo[i]!=-1) - { - (*(thisArr[i]))=DataArrayDouble::New(); - (*(thisArr[i]))->alloc(tinyInfo[i],1); - (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]); - std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer()); - data+=tinyInfo[i]; - } - } - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); -} - -void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - std::ostringstream extent; - DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - for(int i=0;i<3;i++) - { - if(thisArr[i]) - { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; } - else - { extent << "0 0 "; } - } - ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n"; - ofs << " \n"; - ofs << " \n" << pointData << std::endl; - ofs << " \n"; - ofs << " \n" << cellData << std::endl; - ofs << " \n"; - ofs << " \n"; - for(int i=0;i<3;i++) - { - if(thisArr[i]) - thisArr[i]->writeVTK(ofs,8,"Array",byteData); - else - { - MEDCouplingAutoRefCountObjectPtr coo=DataArrayDouble::New(); coo->alloc(1,1); - coo->setIJ(0,0,0.); - coo->writeVTK(ofs,8,"Array",byteData); - } - } - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - std::ostringstream stream2[3]; - bool isDef[3]; - int nbOfCells=1,nbOfNodes=1; - for(int i=0;i<3;i++) - { - isDef[i]=thisArr[i]!=0; - if(isDef[i]) - { - char tmp='X'+i; - stream2[i] << tmp << " positions array "; - if(!thisArr[i]->isAllocated()) - stream2[i] << "set but not allocated."; - else - { - int nbCompo=thisArr[i]->getNumberOfComponents(); - if(nbCompo==1) - { - int nbTuples=thisArr[i]->getNumberOfTuples(); - if(nbTuples<1) - { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; } - else - { - stream2[i] << "(length=" << nbTuples << ")" << ": "; - thisArr[i]->reprQuickOverviewData(stream2[i],200); - if(nbOfCells!=-1) - { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; } - } - } - else - { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; } - } - } - } - if(!isDef[0] && !isDef[1] && !isDef[2]) - { stream << " No arrays set !"; return; } - if(nbOfCells>=0) - { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; } - for(int i=0;i<3;i++) - { - if(isDef[i]) - stream << std::endl << stream2[i].str(); - } -} - -std::string MEDCouplingCMesh::getVTKFileExtension() const -{ - return std::string("vtr"); -} - -std::string MEDCouplingCMesh::getVTKDataSetType() const -{ - return std::string("RectilinearGrid"); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingCMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingCMesh.hxx deleted file mode 100644 index 81811212f..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingCMesh.hxx +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingStructuredMesh.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingCMesh : public MEDCouplingStructuredMesh - { - public: - MEDCOUPLING_EXPORT static MEDCouplingCMesh *New(); - MEDCOUPLING_EXPORT static MEDCouplingCMesh *New(const std::string& meshName); - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingCMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return CARTESIAN; } - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT const DataArrayDouble *getCoordsAt(int i) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordsAt(int i); - MEDCOUPLING_EXPORT void setCoordsAt(int i, const DataArrayDouble *arr); - MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coordsX, - const DataArrayDouble *coordsY=0, - const DataArrayDouble *coordsZ=0); - // tools - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - //some useful methods - MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; - MEDCOUPLING_EXPORT std::vector getNodeGridStructure() const; - MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const; - //serialisation-unserialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - MEDCouplingCMesh(); - MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy); - ~MEDCouplingCMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - private: - DataArrayDouble *_x_array; - DataArrayDouble *_y_array; - DataArrayDouble *_z_array; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx deleted file mode 100644 index cf8a37b37..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx +++ /dev/null @@ -1,1978 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#include "MEDCouplingCartesianAMRMesh.hxx" -#include "MEDCouplingAMRAttribute.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingIMesh.hxx" -#include "MEDCouplingUMesh.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -/// @cond INTERNAL - -int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithOverlap() const -{ - return _mesh->getNumberOfCellsRecursiveWithOverlap(); -} - -int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithoutOverlap() const -{ - return _mesh->getNumberOfCellsRecursiveWithoutOverlap(); -} - -int MEDCouplingCartesianAMRPatchGen::getMaxNumberOfLevelsRelativeToThis() const -{ - return _mesh->getMaxNumberOfLevelsRelativeToThis(); -} - -MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen constructor : input mesh is NULL !"); - _mesh=mesh; _mesh->incrRef(); -} - -MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father):RefCountObject(other),_mesh(other._mesh) -{ - const MEDCouplingCartesianAMRMeshGen *mesh(other._mesh); - if(mesh) - _mesh=mesh->deepCpy(father); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() const -{ - const MEDCouplingCartesianAMRMeshGen *mesh(_mesh); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe const : the mesh is NULL !"); - return mesh; -} - -MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() -{ - MEDCouplingCartesianAMRMeshGen *mesh(_mesh); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe : the mesh is NULL !"); - return mesh; -} - -std::vector MEDCouplingCartesianAMRPatchGen::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCouplingCartesianAMRMeshGen *)_mesh); - return ret; -} - -/*! - * \param [in] mesh not null pointer of refined mesh replacing the cell range of \a father defined by the bottom left and top right just after. - * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair, - * a the end cell (\b excluded) of the range for the second element of the pair. - */ -MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair >& bottomLeftTopRight):MEDCouplingCartesianAMRPatchGen(mesh),_bl_tr(bottomLeftTopRight) -{ - int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension()); - if(dim!=dimExp) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !"); -} - -MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRPatch::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const -{ - return new MEDCouplingCartesianAMRPatch(*this,father); -} - -void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors) -{ - return getMeshSafe()->addPatch(bottomLeftTopRight,factors); -} - -int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const -{ - return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr); -} - -/*! - * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter - * the must be >= 0. \b WARNING this method only works if \a this and \a other share the same father (no check of this will be done !). - * Call isInMyNeighborhoodExt to deal with 2 patches not sharing directly the same father. - * - * \param [in] other - The other patch - * \param [in] ghostLev - The size of the neighborhood zone. - * - * \throw if \a this or \a other are invalid (end before start). - * \throw if \a ghostLev is \b not >= 0 . - * \throw if \a this and \a other have not the same space dimension. - * - * \sa isInMyNeighborhoodExt - */ -bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !"); - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !"); - const std::vector< std::pair >& thisp(getBLTRRange()); - const std::vector< std::pair >& otherp(other->getBLTRRange()); - return IsInMyNeighborhood(ghostLev==0?0:1,thisp,otherp);//make hypothesis that nb this->_mesh->getFather->getFactors() is >= ghostLev -} - -/*! - * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter - * the must be >= 0. This method works even if \a this and \a other does not share the same father. But the level between their common - * ancestor must be the same. If they don't have the same ancestor an exception will be thrown. - * - * \param [in] other - The other patch - * \param [in] ghostLev - The size of the neighborhood zone. - * - * \throw if \a this or \a other are invalid (end before start). - * \throw if \a ghostLev is \b not >= 0 . - * \throw if \a this and \a other have not the same space dimension. - * \throw if there is not common ancestor of \a this and \a other. - * - * \sa isInMyNeighborhood, isInMyNeighborhoodDiffLev - */ -bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the size of the neighborhood must be >= 0 !"); - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the input patch is NULL !"); - int lev; - const MEDCouplingCartesianAMRMeshGen *com(FindCommonAncestor(this,other,lev));//check that factors are OK - if(lev==0) - return isInMyNeighborhood(other,ghostLev); - std::vector offset(ComputeOffsetFromTwoToOne(com,lev,this,other)); - const std::vector< std::pair >& thisp(getBLTRRange()); - std::vector< std::pair > otherp(other->getBLTRRange()); - otherp=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp,offset); - return IsInMyNeighborhood(ghostLev,thisp,otherp); -} - -/*! - * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter - * the must be >= 0. This method works even if \a this and \a other does not share the same father. - * \a this is expected to be more refined than \a other. That is to say lev of \a this is greater than level of \a other. - * - * \param [in] other - The other patch - * \param [in] ghostLev - The size of the neighborhood zone. - * - * \throw if \a this or \a other are invalid (end before start). - * \throw if \a ghostLev is \b not >= 0 . - * \throw if \a this and \a other have not the same space dimension. - * \throw if there is not common ancestor of \a this and \a other. - * - * \sa isInMyNeighborhoodExt - */ -bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const -{ - std::vector< std::pair > thispp,otherpp; - std::vector factors; - ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,this,other,thispp,otherpp,factors); - return IsInMyNeighborhood(ghostLev>0?1:0,thispp,otherpp);//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors -} - -std::vector< std::pair > MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF() const -{ - std::vector< std::pair > ret(_bl_tr); - const MEDCouplingCartesianAMRMeshGen *mesh(getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid !"); - const MEDCouplingCartesianAMRMeshGen *fath(mesh->getFather()); - if(!fath) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid 2 !"); - std::vector factors(fath->getFactors()); - std::size_t sz(ret.size()); - for(std::size_t ii=0;iigetFather(); - while(fath) - { - int pos(fath->getPatchIdFromChildMesh(oldFather)); - const MEDCouplingCartesianAMRPatch *p(fath->getPatch(pos)); - const std::vector< std::pair >& tmp(p->getBLTRRange()); - const std::vector& factors2(fath->getFactors()); - std::transform(factors.begin(),factors.end(),factors2.begin(),factors.begin(),std::multiplies()); - for(std::size_t ii=0;iigetFather(); - } - return ret; -} - -std::vector MEDCouplingCartesianAMRPatch::computeCellGridSt() const -{ - const MEDCouplingCartesianAMRMeshGen *m(getMesh()); - if(!m) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no mesh held by this !"); - const MEDCouplingCartesianAMRMeshGen *father(m->getFather()); - if(!father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no father help by underlying mesh !"); - const std::vector< std::pair >& bltr(getBLTRRange()); - const std::vector& factors(father->getFactors()); - std::vector ret(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(bltr)); - std::transform(ret.begin(),ret.end(),factors.begin(),ret.begin(),std::multiplies()); - return ret; -} - -bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::vector< std::pair >& p1, const std::vector< std::pair >& p2) -{ - std::size_t thispsize(p1.size()); - if(thispsize!=p2.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !"); - for(std::size_t i=0;i& thispp(p1[i]); - const std::pair& otherpp(p2[i]); - if(thispp.second > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) -{ - if(!p1 || !p2) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev : the input pointers must be not NULL !"); - std::vector< std::vector< std::pair > > ret; - std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches()); - while(!p1Work.empty()) - { - std::vector< std::pair > retTmp; - std::vector p1Work2,p2Work2; - for(std::vector::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++) - { - for(std::vector::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) - { - if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev>0?1:0))//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors - retTmp.push_back(std::pair(*it1,*it2)); - } - std::vector tmp1((*it1)->getMesh()->getPatches()); - p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end()); - } - for(std::vector::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) - { - std::vector tmp2((*it2)->getMesh()->getPatches()); - p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end()); - } - ret.push_back(retTmp); - p1Work=p1Work2; - p2Work=p2Work2; - } - return ret; -} - -/*! - * This method returns all pair of patches (pa,pb) so that pb is in the neighborhood of pa (size of neighborhood is \a ghostLev). - * pa is a refinement (a child) of \b p1 and pb is equal to \a p2. So the returned pair do not have the same level as it is the case for - * FindNeighborsOfSubPatchesOfSameLev. - * - * \sa FindNeighborsOfSubPatchesOfSameLev - */ -void MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& ret) -{ - if(!p1 || !p2) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !"); - std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()); - while(!p1Work.empty()) - { - std::vector p1Work2; - for(std::vector::const_iterator it0=p1Work.begin();it0!=p1Work.end();it0++) - { - if((*it0)->isInMyNeighborhoodDiffLev(p2,ghostLev)) - ret.push_back(std::pair(*it0,p2)); - std::vector tmp2((*it0)->getMesh()->getPatches()); - p1Work2.insert(p1Work2.end(),tmp2.begin(),tmp2.end()); - } - p1Work=p1Work2; - } -} - -/*! - * \a p1 and \a p2 are expected to be neighbors (inside the \a ghostLev zone). This method updates \a dataOnP1 only in the ghost part using a part of \a dataOnP2. - * - * \saUpdateNeighborsOfOneWithTwoExt - */ -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) -{ - const std::vector< std::pair >& p1BLTR(p1->getBLTRRange()); - const std::vector< std::pair >& p2BLTR(p2->getBLTRRange()); - UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2); -} - -/*! - * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father. - * - * \sa UpdateNeighborsOfOneWithTwo - */ -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) -{ - const std::vector< std::pair >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)] - std::vector< std::pair > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)] - int lev(0); - const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev)); - std::vector offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4] - p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)] - UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2); -} - -/*! - * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level ! - */ -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2, bool isConservative) -{ - std::vector< std::pair > p1pp,p2pp; - std::vector factors; - ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,p1,p2,p1pp,p2pp,factors); - // - std::vector dimsP2NotRefined(p2->computeCellGridSt()); - std::vector dimsP2Refined(dimsP2NotRefined); - std::transform(dimsP2NotRefined.begin(),dimsP2NotRefined.end(),factors.begin(),dimsP2Refined.begin(),std::multiplies()); - std::vector< std::pair > p2RefinedAbs(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsP2NotRefined)); - std::vector dimsP2RefinedGhost(dimsP2Refined.size()); - std::transform(dimsP2Refined.begin(),dimsP2Refined.end(),dimsP2RefinedGhost.begin(),std::bind2nd(std::plus(),2*ghostLev)); - MEDCouplingAutoRefCountObjectPtr fineP2(DataArrayDouble::New()); fineP2->alloc(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(dimsP2RefinedGhost),dataOnP2->getNumberOfComponents()); - MEDCouplingIMesh::SpreadCoarseToFineGhost(dataOnP2,dimsP2NotRefined,fineP2,p2RefinedAbs,factors,ghostLev); - if(isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(factors)); - std::transform(fineP2->begin(),fineP2->end(),fineP2->getPointer(),std::bind2nd(std::multiplies(),1./((double)fact))); - } - // - UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1pp,p2pp,dataOnP1,fineP2); -} - -/*! - * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level ! - * This method has 3 outputs. 2 two first are the resp the position of \a p1 and \a p2 relative to \a p1. And \a factToApplyOn2 is the coeff of refinement to be applied on \a p2 to be virtualy - * on the same level as \a p1. - */ -void MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& p1Zone, std::vector< std::pair >& p2Zone, std::vector& factToApplyOn2) -{ - std::vector ancestorsOfThis; - const MEDCouplingCartesianAMRMeshGen *work(p1->getMesh()),*work2(0); - ancestorsOfThis.push_back(work); - while(work) - { - work=work->getFather(); - if(work) - ancestorsOfThis.push_back(work); - } - // - work=p2->getMesh(); - bool found(false); - std::size_t levThis(0),levOther(0); - while(work && !found) - { - work2=work; - work=work->getFather(); - if(work) - { - levOther++; - std::vector::iterator it(std::find(ancestorsOfThis.begin(),ancestorsOfThis.end(),work)); - if(it!=ancestorsOfThis.end()) - { - levThis=std::distance(ancestorsOfThis.begin(),it); - found=true; - } - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : no common ancestor found !"); - if(levThis<=levOther) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : this method is not called correctly !"); - // - const MEDCouplingCartesianAMRMeshGen *comAncestor(ancestorsOfThis[levThis]); - int idThis(comAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-1])),idOther(comAncestor->getPatchIdFromChildMesh(work2)); - const MEDCouplingCartesianAMRPatch *thisp(comAncestor->getPatch(idThis)),*otherp(comAncestor->getPatch(idOther)); - std::vector offset(ComputeOffsetFromTwoToOne(comAncestor,levOther,thisp,otherp)); - p1Zone=thisp->getBLTRRange(); p2Zone=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp->getBLTRRange(),offset); - factToApplyOn2.resize(p1Zone.size()); std::fill(factToApplyOn2.begin(),factToApplyOn2.end(),1); - // - std::size_t nbOfTurn(levThis-levOther); - for(std::size_t i=0;i > tmp0; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1Zone,p2Zone,tmp0,false); - p2Zone=tmp0; - const MEDCouplingCartesianAMRMeshGen *curAncestor(ancestorsOfThis[levThis-i]); - ApplyFactorsOnCompactFrmt(p2Zone,curAncestor->getFactors()); - curAncestor=ancestorsOfThis[levThis-1-i]; - const std::vector& factors(curAncestor->getFactors()); - std::transform(factToApplyOn2.begin(),factToApplyOn2.end(),factors.begin(),factToApplyOn2.begin(),std::multiplies()); - int tmpId(curAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-2-i])); - p1Zone=curAncestor->getPatch(tmpId)->getBLTRRange(); - } -} - -std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch)); - ret+=_bl_tr.capacity()*sizeof(std::pair); - return ret; -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatch::FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev) -{ - const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh); - lev=0; - while(f1!=f2 || f1==0 || f2==0) - { - f1=f1->getFather(); f2=f2->getFather(); - if(f1->getFactors()!=f2->getFactors()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : factors differ !"); - lev++; - } - if(f1!=f2) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : no common ancestor between p1 and p2 !"); - return f1; -} - -std::vector MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) -{ - if(lev<=0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !"); - int zeLev(lev-1); - int dim(p1->getMesh()->getSpaceDimension()); - if(p2->getMesh()->getSpaceDimension()!=dim) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !"); - std::vector< int > ret(dim,0); - for(int i=0;i_mesh),*f2(p2->_mesh); - const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0); - for(int j=0;jgetFather()),*f2tmp(f2->getFather()); - int pid1(f1tmp->getPatchIdFromChildMesh(f1)),pid2(f2tmp->getPatchIdFromChildMesh(f2)); - p1h=f1tmp->getPatch(pid1); p2h=f2tmp->getPatch(pid2); - f1=f1tmp; f2=f2tmp; - } - std::vector< std::pair > p2c(p2h->getBLTRRange()); - for(int k=0;kgetBLTRRange()[k].first; - ret[k]*=f1->getFactors()[k]; - } - } - return ret; -} - -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector& factors, const std::vector< std::pair >&p1 ,const std::vector< std::pair >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) -{//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)] - int dim((int)factors.size()); - std::vector dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2] - std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies());//[12,8] - std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus(),2*ghostLev));//[14,10] - std::vector< std::pair > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)] - std::vector fakeFactors(dim,1); - // - std::vector< std::pair > tmp0,tmp1,tmp2; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)] - ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)] - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)] - std::vector< std::pair > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)] - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)] - ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)] - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)] - // - std::vector< std::pair > dimsFine(p2); - ApplyFactorsOnCompactFrmt(dimsFine,factors); - ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev); - // - MEDCouplingAutoRefCountObjectPtr ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2)); - MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1); -} - -MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRPatchGen(other,father),_bl_tr(other._bl_tr) -{ -} - -/*! - * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference. - * \param [in] factors - the factors per axis. - */ -void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors) -{ - std::size_t sz(factors.size()); - if(sz!=partBeforeFact.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !"); - for(std::size_t i=0;i >& partBeforeFact, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !"); - std::size_t sz(partBeforeFact.size()); - for(std::size_t i=0;igetSpaceDimension(); -} - -void MEDCouplingCartesianAMRMeshGen::setFactors(const std::vector& newFactors) -{ - if(getSpaceDimension()!=(int)newFactors.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : size of input factors is not equal to the space dimension !"); - if(_factors.empty()) - { - _factors=newFactors; - return ; - } - if(_factors==newFactors) - return ; - if(!_patches.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : modification of factors is not allowed when presence of patches !"); - _factors=newFactors; - declareAsNew(); -} - -int MEDCouplingCartesianAMRMeshGen::getMaxNumberOfLevelsRelativeToThis() const -{ - int ret(1); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1); - return ret; -} - -/*! - * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this. - * The patches in \a this are ignored here. - * \sa getNumberOfCellsAtCurrentLevelGhost, getNumberOfCellsRecursiveWithOverlap - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevel() const -{ - return _mesh->getNumberOfCells(); -} - -/*! - * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this enlarged by \a ghostLev size - * to take into account of the ghost cells for future computation. - * The patches in \a this are ignored here. - * - * \sa getNumberOfCellsAtCurrentLevel - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const -{ - MEDCouplingAutoRefCountObjectPtr tmp(_mesh->buildWithGhost(ghostLev)); - return tmp->getNumberOfCells(); -} - -/*! - * This method returns the number of cells including the current level but \b also \b including recursively all cells of other levels - * starting from this. The set of cells which size is returned here are generally overlapping each other. - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const -{ - int ret(_mesh->getNumberOfCells()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - ret+=(*it)->getNumberOfCellsRecursiveWithOverlap(); - } - return ret; -} - -/*! - * This method returns the max number of cells covering all the space without overlapping. - * It returns the number of cells of the mesh with the highest resolution. - * The returned value is equal to the number of cells of mesh returned by buildUnstructured. - * - * \sa buildUnstructured - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const -{ - int ret(_mesh->getNumberOfCells()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - ret-=(*it)->getNumberOfOverlapedCellsForFather(); - ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap(); - } - return ret; -} - -/*! - * This method returns a vector of size equal to getAbsoluteLevelRelativeTo. It allows to find position an absolute position of \a this - * relative to \a ref (that is typically the god father). - * - * \sa getPatchAtPosition - */ -std::vector MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const -{ - if(!ref) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo : input pointer is NULL !"); - std::vector ret; - getPositionRelativeToInternal(ref,ret); - std::reverse(ret.begin(),ret.end()); - return ret; -} - -/*! - * \sa getPositionRelativeTo, getMeshAtPosition - */ -const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatchAtPosition(const std::vector& pos) const -{ - std::size_t sz(pos.size()); - if(sz==0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : empty input -> no patch by definition !"); - int patchId(pos[0]); - const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId)); - if(sz==1) - return elt; - if(!elt || !elt->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !"); - std::vector pos2(pos.begin()+1,pos.end()); - return elt->getMesh()->getPatchAtPosition(pos2); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getMeshAtPosition(const std::vector& pos) const -{ - std::size_t sz(pos.size()); - if(sz==0) - return this; - int patchId(pos[0]); - const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId)); - if(sz==1) - { - if(!elt) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getMeshAtPosition : NULL patch !"); - return elt->getMesh(); - } - if(!elt || !elt->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !"); - std::vector pos2(pos.begin()+1,pos.end()); - return elt->getMesh()->getMeshAtPosition(pos2); -} - -/*! - * This method returns grids relative to god father to specified level \a absoluteLev. - * - * \return std::vector - objects in vector are to be managed (decrRef) by the caller. - */ -std::vector MEDCouplingCartesianAMRMeshGen::retrieveGridsAt(int absoluteLev) const -{ - if(absoluteLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::retrieveGridsAt : absolute level must be >=0 !"); - return getGodFather()->retrieveGridsAt(absoluteLev); -} - -/*! - * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair, - * a the end cell (\b excluded) of the range for the second element of the pair. - * \param [in] factors The factor of refinement per axis (different from 0). - */ -void MEDCouplingCartesianAMRMeshGen::addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors) -{ - checkFactorsAndIfNotSetAssign(factors); - MEDCouplingAutoRefCountObjectPtr mesh(static_cast(_mesh->buildStructuredSubPart(bottomLeftTopRight))); - mesh->refineWithFactor(factors); - MEDCouplingAutoRefCountObjectPtr zeMesh(new MEDCouplingCartesianAMRMeshSub(this,mesh)); - MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight)); - _patches.push_back(elt); - declareAsNew(); -} - -/// @cond INTERNAL - -class InternalPatch : public RefCountObjectOnly -{ -public: - InternalPatch():_nb_of_true(0) { } - int getDimension() const { return (int)_part.size(); } - double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); } - int getNumberOfCells() const { return (int)_crit.size(); } - void setNumberOfTrue(int nboft) { _nb_of_true=nboft; } - std::vector& getCriterion() { return _crit; } - const std::vector& getConstCriterion() const { return _crit; } - void setPart(const std::vector< std::pair >& part) { _part=part; } - std::vector< std::pair >& getPart() { return _part; } - const std::vector< std::pair >& getConstPart() const { return _part; } - bool presenceOfTrue() const { return _nb_of_true>0; } - std::vector computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); } - std::vector< std::vector > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); } - double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); } - void zipToFitOnCriterion(int minPatchLgth); - void updateNumberOfTrue() const; - MEDCouplingAutoRefCountObjectPtr extractPart(const std::vector< std::pair >&partInGlobal) const; - MEDCouplingAutoRefCountObjectPtr deepCpy() const; -protected: - ~InternalPatch() { } -private: - mutable int _nb_of_true; - std::vector _crit; - //! _part is global - std::vector< std::pair > _part; -}; - -void InternalPatch::zipToFitOnCriterion(int minPatchLgth) -{ - std::vector cgs(computeCGS()); - std::vector newCrit; - std::vector< std::pair > newPart,newPart2; - int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(minPatchLgth,cgs,_crit,newCrit,newPart)); - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2); - if(newNbOfTrue!=_nb_of_true) - throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !"); - _crit=newCrit; _part=newPart2; -} - -void InternalPatch::updateNumberOfTrue() const -{ - _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true); -} - -MEDCouplingAutoRefCountObjectPtr InternalPatch::extractPart(const std::vector< std::pair >&partInGlobal) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new InternalPatch); - std::vector cgs(computeCGS()); - std::vector< std::pair > newPart; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart); - MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion()); - ret->setPart(partInGlobal); - ret->updateNumberOfTrue(); - return ret; -} - -MEDCouplingAutoRefCountObjectPtr InternalPatch::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new InternalPatch); - (*ret)=*this; - return ret; -} - -void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int largestLength, int& cutPlace) -{ - int minimumPatchLength(bso.getMinimumPatchLength()); - std::vector ratio(largestLength-minimumPatchLength,std::numeric_limits::max()); - int index_min = -1; - double minSemiEfficiencyRatio(std::numeric_limits::max()); - double efficiencyPerAxis[2]; - - for(int i=minimumPatchLength-1;i > rectH(patchToBeSplit->getConstPart()); - if(h==0) - rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+i; - else - rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+i; - MEDCouplingAutoRefCountObjectPtr p(patchToBeSplit->deepCpy()); - p->zipToFitOnCriterion(bso.getMinimumPatchLength()); - efficiencyPerAxis[h]=p->getEfficiencyPerAxis(axisId); - } - ratio[i]=std::max(efficiencyPerAxis[0], efficiencyPerAxis[1]) / std::min(efficiencyPerAxis[0], efficiencyPerAxis[1]); - if(ratio[i]getConstPart()[axisId].first; -} - -bool FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int& cutPlace) -{ - cutPlace=-1; - int minimumPatchLength(bso.getMinimumPatchLength()); - const int dim(patchToBeSplit->getDimension()); - std::vector< std::vector > signatures(patchToBeSplit->computeSignature()); - for(int id=0;id& signature(signatures[id]); - std::vector hole; - std::vector distance; - int len((int)signature.size()); - for(int i=minimumPatchLength-1;igetConstPart()[axisId].first; - return true; - } - } - return false; -} - -bool FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int& cutPlace, int& axisId) -{ - bool cutFound(false); cutPlace=-1;// do not set axisId before to be sure that cutFound was set to true - const std::vector< std::pair >& part(patchToBeSplit->getConstPart()); - int sign,minimumPatchLength(bso.getMinimumPatchLength()); - const int dim(patchToBeSplit->getDimension()); - - std::vector zeroCrossDims(dim,-1); - std::vector zeroCrossVals(dim,-1); - std::vector< std::vector > signatures(patchToBeSplit->computeSignature()); - for (int id=0;id& signature(signatures[id]); - - std::vector derivate_second_order,gradient_absolute,zero_cross,edge,max_cross_list ; - std::vector distance ; - - for(std::size_t i=1;i 0 ) - sign = 1 ; - if (derivate_second_order[i]*derivate_second_order[i+1] == 0 ) - sign = 0 ; - if ( sign==0 || sign==-1 ) - if ( i >= (std::size_t)minimumPatchLength-2 && i <= signature.size()-minimumPatchLength-2 ) - { - zero_cross.push_back(i) ; - edge.push_back(gradient_absolute[i]) ; - } - } - if ( zero_cross.size() > 0 ) - { - int max_cross=*max_element(edge.begin(),edge.end()) ; - for (unsigned int i=0;i=0 ) - { - zeroCrossDims[id] = best_place ; - zeroCrossVals[id] = max_cross ; - } - } - derivate_second_order.clear() ; - gradient_absolute.clear() ; - zero_cross.clear() ; - edge.clear() ; - max_cross_list.clear() ; - distance.clear() ; - } - - if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 ) - { - int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ; - - if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims ) - { - int nl_left(part[0].second-part[0].first); - int nc_left(part[1].second-part[1].first); - if ( nl_left >= nc_left ) - max_cross_dims = 0 ; - else - max_cross_dims = 1 ; - } - else - max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin(); - cutFound=true; - cutPlace=zeroCrossDims[max_cross_dims]; - axisId=max_cross_dims ; - } - return cutFound; -} - -bool TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, int& cutPlace) -{ - if(patchToBeSplit->getEfficiency()<=bso.getEfficiencyGoal()) - { - if(rangeOfAxisId>=2*bso.getMinimumPatchLength()) - { - cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1; - } - else - return false; - } - else - { - if(patchToBeSplit->getNumberOfCells()>bso.getMaximumNbOfCellsInPatch() || rangeOfAxisId>bso.getMaximumPatchLength()) - { - DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutPlace); - } - else - return false; - } - return true; -} - -MEDCouplingAutoRefCountObjectPtr DealWithNoCut(const InternalPatch *patch) -{ - MEDCouplingAutoRefCountObjectPtr ret(const_cast(patch)); - ret->incrRef(); - return ret; -} - -void DealWithCut(double minPatchLgth, const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector >& listOfPatches) -{ - MEDCouplingAutoRefCountObjectPtr leftPart,rightPart; - std::vector< std::pair > rect(patchToBeSplit->getConstPart()); - std::vector< std::pair > leftRect(rect),rightRect(rect); - leftRect[axisId].second=cutPlace+1; - rightRect[axisId].first=cutPlace+1; - leftPart=patchToBeSplit->extractPart(leftRect); - rightPart=patchToBeSplit->extractPart(rightRect); - leftPart->zipToFitOnCriterion(minPatchLgth); rightPart->zipToFitOnCriterion(minPatchLgth); - listOfPatches.push_back(leftPart); - listOfPatches.push_back(rightPart); -} - -/// @endcond - -void MEDCouplingCartesianAMRMeshGen::removeAllPatches() -{ - _patches.clear(); - declareAsNew(); -} - -void MEDCouplingCartesianAMRMeshGen::removePatch(int patchId) -{ - checkPatchId(patchId); - int sz((int)_patches.size()),j(0); - std::vector< MEDCouplingAutoRefCountObjectPtr > patches(sz-1); - for(int i=0;i(_patches[patchId]->getMesh()))->detachFromFather(); - _patches=patches; - declareAsNew(); -} - -int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const -{ - return (int)_patches.size(); -} - -/*! - * This method is a generic algorithm to create patches in \a this (by destroying the patches if any). - * This method uses \a criterion array as a field on cells on this level. - * This method only create patches at level 0 relative to \a this. - * - * This generic algorithm can be degenerated into three child ones, depending on the arguments given; in particular depending - * on whether they are equal to 0 or not. - * 1/ If minimumPatchLength = maximumPatchLength = maximumPatchVolume = 0, then we have the Berger-Rigoutsos algorithm. - * This algorithm was developed in 1991 and seems appropriate for sequential programming. - * 2/ If maximumPatchLength = 0, then we have the Livne algorithm. - * This algorithm was developed in 2004 and is an improvement of the Berger-Rigoutsos algorithm. - * 3/ If maximumPatchVolume = 0, the we have the lmin-lmax algorithm. - * This algorithm was developed by Arthur TALPAERT in 2014 and is an improvement of the Livne algorithm. It is especially - * appropriate for parallel computing, where one patch would be given to one CPU. See Arthur TALPAERT's 2014 CANUM poster - * for more information. - * - */ -void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector& criterion, const std::vector& factors) -{ - int nbCells(getNumberOfCellsAtCurrentLevel()); - if(nbCells!=(int)criterion.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the number of tuples of criterion array must be equal to the number of cells at the current level !"); - _patches.clear(); - std::vector cgs(_mesh->getCellGridStructure()); - std::vector< MEDCouplingAutoRefCountObjectPtr > listOfPatches,listOfPatchesOK; - // - MEDCouplingAutoRefCountObjectPtr p(new InternalPatch); - p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(bso.getMinimumPatchLength(),cgs,criterion,p->getCriterion(),p->getPart())); - if(p->presenceOfTrue()) - listOfPatches.push_back(p); - while(!listOfPatches.empty()) - { - std::vector< MEDCouplingAutoRefCountObjectPtr > listOfPatchesTmp; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++) - { - // - int axisId,largestLength,cutPlace; - MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,largestLength); - if((*it)->getEfficiency()>=bso.getEfficiencyThreshold() && ((*it)->getNumberOfCells()>bso.getMaximumNbOfCellsInPatch() || largestLength>bso.getMaximumPatchLength())) - { - DissectBigPatch(bso,*it,axisId,largestLength,cutPlace); - DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); - continue; - }//action 1 - if(FindHole(bso,*it,axisId,cutPlace))//axisId overwritten here if FindHole equal to true ! - { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2 - if(FindInflection(bso,*it,cutPlace,axisId))//axisId overwritten here if cutFound equal to true ! - { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3 - if(TryAction4(bso,*it,axisId,largestLength,cutPlace)) - { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4 - else - listOfPatchesOK.push_back(DealWithNoCut(*it)); - } - listOfPatches=listOfPatchesTmp; - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++) - addPatch((*it)->getConstPart(),factors); - declareAsNew(); -} - -/*! - * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion array as a field on cells on this level. - * This method only create patches at level 0 relative to \a this. - */ -void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors) -{ - if(!criterion || !criterion->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !"); - std::vector crit(criterion->toVectorOfBool());//check that criterion has one component. - createPatchesFromCriterion(bso,crit,factors); - declareAsNew(); -} - -void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector& factors, double eps) -{ - if(!criterion) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : null criterion pointer !"); - std::vector inp(criterion->toVectorOfBool(eps)); - createPatchesFromCriterion(bso,inp,factors); -} - -int MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const -{ - int ret(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ret++) - { - if((*it)->getMesh()==mesh) - return ret; - } - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh : no such a mesh in my direct progeny !"); -} - -std::vector< const MEDCouplingCartesianAMRPatch *> MEDCouplingCartesianAMRMeshGen::getPatches() const -{ - std::size_t sz(_patches.size()); - std::vector< const MEDCouplingCartesianAMRPatch *> ret(sz); - for(std::size_t i=0;iisInMyNeighborhood(p2,ghostLev); -} - -/*! - * This method creates a new cell field array on given \a patchId patch in \a this starting from a coarse cell field on \a this \a cellFieldOnThis. - * This method can be seen as a fast projection from the cell field \a cellFieldOnThis on \c this->getImageMesh() to a refined part of \a this - * defined by the patch with id \a patchId. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \return DataArrayDouble * - The array of the cell field on the requested patch - * - * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) - * \throw if \a cellFieldOnThis is NULL or not allocated - * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine - */ -DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents()); - ret->copyStringInfoFrom(*cellFieldOnThis); - MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors()); - return ret.retn(); -} - -/*! - * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance - * it fills the value into the \a cellFieldOnPatch data. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. - * - * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors()); - if(isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies(),1./((double)fact))); - } -} - -/*! - * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the - * potential neighbor patches covered by the ghost cells of patch with id \a patchId. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. - * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) - * - * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev); - if(isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies(),1./((double)fact))); - } -} - -/*! - * This method is equivalent to fillCellFieldOnPatchGhost except that here \b ONLY \b the \b ghost \b zone will be updated - * in \a cellFieldOnPatch. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled \b only \b in \b the \b ghost \b zone. - * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyOnGhostZone : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::SpreadCoarseToFineGhostZone(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev); -} - -/*! - * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called. - * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. - * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) - * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const. - * - * \sa fillCellFieldOnPatchOnlyGhostAdv - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector& arrsOnPatches, bool isConservative) const -{ - int nbp(getNumberOfPatches()); - if(nbp!=(int)arrsOnPatches.size()) - { - std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - DataArrayDouble *theFieldToFill(const_cast(arrsOnPatches[patchId])); - // first, do as usual - fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev,isConservative); - fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches); -} - -/*! - * This method updates the patch with id \a patchId considering the only the all the patches in \a this to fill ghost zone. - * So \b warning, the DataArrayDouble instance \a arrsOnPatches[patchId] is non const. - * - * \sa getPatchIdsInTheNeighborhoodOf - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector& arrsOnPatches) const -{ - int nbp(getNumberOfPatches()); - if(nbp!=(int)arrsOnPatches.size()) - { - std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId)); - DataArrayDouble *theFieldToFill(const_cast(arrsOnPatches[patchId])); - std::vector ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); - for(std::vector::const_iterator it=ids.begin();it!=ids.end();it++) - { - const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it)); - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]); - } -} - -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const -{ - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor); -} - -/*! - * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. - * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId. - * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied. - * - * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) - * \throw if \a cellFieldOnPatch is NULL or not allocated - * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative) const -{ - if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis); - if(!isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - MEDCouplingStructuredMesh::MultiplyPartOf(_mesh->getCellGridStructure(),patch->getBLTRRange(),1./((double)fact),cellFieldOnThis); - } -} - -/*! - * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this - * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. - * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId. - * \param [in] ghostLev The size of ghost zone (must be >= 0 !) - * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied. - * - * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) - * \throw if \a cellFieldOnPatch is NULL or not allocated - * \sa fillCellFieldComingFromPatch - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative) const -{ - if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev); - if(!isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - MEDCouplingStructuredMesh::MultiplyPartOfByGhost(_mesh->getCellGridStructure(),patch->getBLTRRange(),ghostLev,1./((double)fact),cellFieldOnThis); - } -} - -/*! - * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is - * defined by ghostLev. - * - * \param [in] patchId - the id of the considered patch. - * \param [in] ghostLev - the size of the neighborhood. - * \return DataArrayInt * - the newly allocated array containing the list of patches in the neighborhood of the considered patch. This array is to be deallocated by the caller. - */ -DataArrayInt *MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const -{ - int nbp(getNumberOfPatches()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - } - return ret.retn(); -} - -MEDCouplingUMesh *MEDCouplingCartesianAMRMeshGen::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr part(_mesh->buildUnstructured()); - std::vector bs(_mesh->getNumberOfCells(),false); - std::vector cgs(_mesh->getCellGridStructure()); - std::vector< MEDCouplingAutoRefCountObjectPtr > msSafe(_patches.size()+1); - std::size_t ii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) - { - MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); - msSafe[ii+1]=(*it)->getMesh()->buildUnstructured(); - } - MEDCouplingAutoRefCountObjectPtr eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); - msSafe[0]=static_cast(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); - std::vector< const MEDCouplingUMesh * > ms(msSafe.size()); - for(std::size_t i=0;i cells; - std::vector< MEDCouplingAutoRefCountObjectPtr > cellsSafe; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *patch(*it); - if(patch) - { - MEDCouplingAutoRefCountObjectPtr cell(patch->getMesh()->getImageMesh()->asSingleCell()); - MEDCouplingAutoRefCountObjectPtr cell1SGT(cell->build1SGTUnstructured()); - cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT); - } - } - return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells); -} - -MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly() const -{ - std::vector patches; - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *patch(*it); - if(patch) - { - MEDCouplingAutoRefCountObjectPtr patchMesh(patch->getMesh()->getImageMesh()->build1SGTUnstructured()); - patchesSafe.push_back(patchMesh); patches.push_back(patchMesh); - } - } - return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(patches); -} - -/*! - * This method works same as buildUnstructured except that arrays are given in input to build a field on cell in output. - * \return MEDCouplingFieldDouble * - a newly created instance the caller has reponsability to deal with. - * \sa buildUnstructured - */ -MEDCouplingFieldDouble *MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector& recurseArrs) const -{ - if(recurseArrs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost : array is empty ! Should never happen !"); - // - std::vector bs(_mesh->getNumberOfCells(),false); - std::vector cgs(_mesh->getCellGridStructure()); - std::vector< MEDCouplingAutoRefCountObjectPtr > msSafe(_patches.size()+1); - std::size_t ii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) - { - MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); - std::vector tmpArrs(extractSubTreeFromGlobalFlatten((*it)->getMesh(),recurseArrs)); - msSafe[ii+1]=(*it)->getMesh()->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,tmpArrs); - } - MEDCouplingAutoRefCountObjectPtr eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); - // - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); - MEDCouplingAutoRefCountObjectPtr arr2(extractGhostFrom(ghostSz,recurseArrs[0])); - arr2=arr2->selectByTupleIdSafe(eltsOff->begin(),eltsOff->end()); - ret->setArray(arr2); - ret->setName(arr2->getName()); - MEDCouplingAutoRefCountObjectPtr part(_mesh->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr mesh(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); - ret->setMesh(mesh); - msSafe[0]=ret; - // - std::vector< const MEDCouplingFieldDouble * > ms(msSafe.size()); - for(std::size_t i=0;ibuildWithGhost(ghostSz). - */ -DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const -{ - std::vector st(_mesh->getCellGridStructure()); - std::vector< std::pair > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st)); - std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus(),2*ghostSz)); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(p,ghostSz); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p)); - return ret.retn(); -} - -/*! - * This method returns all the patches in \a this not equal to \a patchId that are in neighborhood of patch with id \a patchId. - * - * \sa fillCellFieldOnPatchOnlyGhostAdv - */ -std::vector MEDCouplingCartesianAMRMeshGen::getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const -{ - std::vector ret; - int nbp(getNumberOfPatches()); - // - for(int i=0;igetName() << "\"," << getSpaceDimension() << ",["; - std::vector ngs(getImageMesh()->getNodeGridStructure()); - std::vector orig(getImageMesh()->getOrigin()),dxyz(getImageMesh()->getDXYZ()); - std::copy(ngs.begin(),ngs.end(),std::ostream_iterator(oss,",")); - oss << "],["; - std::copy(orig.begin(),orig.end(),std::ostream_iterator(oss,",")); - oss << "],["; - std::copy(dxyz.begin(),dxyz.end(),std::ostream_iterator(oss,",")); - oss << "])\n"; - dumpPatchesOf("amr",oss); - return oss.str(); -} - -MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other):RefCountObject(other),_mesh(other._mesh),_patches(other._patches),_factors(other._factors) -{ - const MEDCouplingIMesh *mesh(other._mesh); - if(mesh) - _mesh=static_cast(mesh->deepCpy()); - std::size_t sz(other._patches.size()); - for(std::size_t i=0;ideepCpy(this); - } -} - -MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) -{ - _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); -} - -MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : The input mesh is null !"); - mesh->checkCoherency(); - _mesh=mesh; _mesh->incrRef(); -} - -void MEDCouplingCartesianAMRMeshGen::checkPatchId(int patchId) const -{ - int sz(getNumberOfPatches()); - if(patchId<0 || patchId>=sz) - { - std::ostringstream oss; oss << "MEDCouplingCartesianAMRMeshGen::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign(const std::vector& factors) -{ - if(getSpaceDimension()!=(int)factors.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !"); - if(_factors.empty()) - { - _factors=factors; - } - else - { - if(_factors!=factors) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors "); - } -} - -void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr >& grids) const -{ - if(lev==0) - { - const MEDCouplingCartesianAMRMesh *thisc(dynamic_cast(this));//tony - MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingCartesianAMRPatchGF(const_cast(thisc))); - grids.push_back(DynamicCastSafe(elt)); - } - else if(lev==1) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *pt(*it); - if(pt) - { - MEDCouplingAutoRefCountObjectPtr tmp1(*it); - grids.push_back(DynamicCastSafe(tmp1)); - } - } - } - else - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *pt(*it); - if(pt) - pt->getMesh()->retrieveGridsAtInternal(lev-1,grids); - } - } -} - -int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector& factors) -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : the ghost size must be >=0 !"); - if(factors.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : no factors defined !"); - int ghostLevInPatchRef; - if(ghostLev==0) - ghostLevInPatchRef=0; - else - { - ghostLevInPatchRef=(ghostLev-1)/factors[0]+1; - for(std::size_t i=0;i MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector& all) const -{ - int maxLev(getMaxNumberOfLevelsRelativeToThis()); - std::vector ret; - std::vector meshes(1,this); - std::size_t kk(0); - for(int i=0;i meshesTmp; - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++) - { - if((*it)==head || head->isObjectInTheProgeny(*it)) - ret.push_back(all[kk]); - kk++; - std::vector< const MEDCouplingCartesianAMRPatch *> ps((*it)->getPatches()); - for(std::vector< const MEDCouplingCartesianAMRPatch *>::const_iterator it0=ps.begin();it0!=ps.end();it0++) - { - const MEDCouplingCartesianAMRMeshGen *mesh((*it0)->getMesh()); - meshesTmp.push_back(mesh); - } - } - meshes=meshesTmp; - } - if(kk!=all.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten : the size of input vector is not compatible with number of leaves in this !"); - return ret; -} - -void MEDCouplingCartesianAMRMeshGen::dumpPatchesOf(const std::string& varName, std::ostream& oss) const -{ - std::size_t j(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *patch(*it); - if(patch) - { - std::ostringstream oss2; oss2 << varName << ".addPatch(["; - const std::vector< std::pair >& bltr(patch->getBLTRRange()); - std::size_t sz(bltr.size()); - for(std::size_t i=0;i(oss2,",")); - oss2 << "])\n"; - oss << oss2.str(); - std::ostringstream oss3; oss3 << varName << "[" << j++ << "]"; - patch->getMesh()->dumpPatchesOf(oss3.str(),oss); - } - } -} - -std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDCouplingCartesianAMRMeshGen); -} - -std::vector MEDCouplingCartesianAMRMeshGen::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCouplingIMesh *)_mesh); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - ret.push_back((const MEDCouplingCartesianAMRPatch*)*it); - return ret; -} - -void MEDCouplingCartesianAMRMeshGen::updateTime() const -{ - if((const MEDCouplingIMesh *)_mesh) - updateTimeWith(*_mesh); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *elt(*it); - if(!elt) - continue; - const MEDCouplingCartesianAMRMeshGen *mesh(elt->getMesh()); - if(mesh) - updateTimeWith(*mesh); - } -} - -MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh),_father(father) -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh) constructor : empty father !"); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getFather() const -{ - return _father; -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getGodFather() const -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getGodFather : Impossible to find a god father because there is a hole in chain !"); - return _father->getGodFather(); -} - -/*! - * This method returns the level of \a this. 0 for god father. 1 for children of god father ... - */ -int MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel() const -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel : Impossible to find a god father because there is a hole in chain !"); - return _father->getAbsoluteLevel()+1; -} - -void MEDCouplingCartesianAMRMeshSub::detachFromFather() -{ - _father=0; - declareAsNew(); -} - -std::vector< std::pair > MEDCouplingCartesianAMRMeshSub::positionRelativeToGodFather(std::vector& st) const -{ - st=_father->getFactors(); - std::size_t dim(st.size()); - std::vector prev(st); - int id(_father->getPatchIdFromChildMesh(this)); - const MEDCouplingCartesianAMRPatch *p(_father->getPatch(id)); - std::vector< std::pair > ret(p->getBLTRRange()); - std::vector delta(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(ret)),start(dim); - std::transform(delta.begin(),delta.end(),prev.begin(),delta.begin(),std::multiplies()); - for(std::size_t i=0;i()); - const MEDCouplingCartesianAMRMeshGen *it(_father); - while(!dynamic_cast(it)) - { - const MEDCouplingCartesianAMRMeshSub *itc(static_cast(it)); - int id2(itc->_father->getPatchIdFromChildMesh(itc)); - const MEDCouplingCartesianAMRPatch *p2(itc->_father->getPatch(id2)); - const std::vector< std::pair >& start2(p2->getBLTRRange()); - std::vector tmp(dim); - for(std::size_t i=0;i_father->getFactors(); - std::transform(st.begin(),st.end(),prev.begin(),st.begin(),std::multiplies()); - std::transform(st.begin(),st.end(),tmp.begin(),tmp.begin(),std::multiplies()); - std::transform(start.begin(),start.end(),tmp.begin(),start.begin(),std::plus()); - it=itc->_father; - } - for(std::size_t i=0;igetAbsoluteLevelRelativeTo(ref)+1; -} - -MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRMeshGen(other),_father(father) -{ -} - -MEDCouplingCartesianAMRMeshSub *MEDCouplingCartesianAMRMeshSub::deepCpy(MEDCouplingCartesianAMRMeshGen *fath) const -{ - return new MEDCouplingCartesianAMRMeshSub(*this,fath); -} - -/*! - * \sa getPositionRelativeTo - */ -void MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const -{ - if(this==ref) - return ; - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal : ref is not in the progeny of this !"); - int myId(_father->getPatchIdFromChildMesh(this)); - ret.push_back(myId); - _father->getPositionRelativeToInternal(ref,ret); -} - -MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) -{ - return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); -} - -MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(MEDCouplingIMesh *mesh) -{ - return new MEDCouplingCartesianAMRMesh(mesh); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getFather() const -{ - //I'm god father ! No father ! - return 0; -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getGodFather() const -{ - return this; -} - -int MEDCouplingCartesianAMRMesh::getAbsoluteLevel() const -{ - return 0; -} - -void MEDCouplingCartesianAMRMesh::detachFromFather() -{//not a bug - do nothing -} - -std::vector< std::pair > MEDCouplingCartesianAMRMesh::positionRelativeToGodFather(std::vector& st) const -{ - st=_mesh->getCellGridStructure(); - return MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st); -} - -int MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const -{ - if(this==ref) - return 0; - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo : ref is not in the progeny of this !"); -} - -std::vector MEDCouplingCartesianAMRMesh::retrieveGridsAt(int absoluteLev) const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > rets; - retrieveGridsAtInternal(absoluteLev,rets); - std::vector< MEDCouplingCartesianAMRPatchGen * > ret(rets.size()); - for(std::size_t i=0;i& bso, const DataArrayDouble *criterion, const std::vector< std::vector >& factors, double eps) -{ - std::size_t nbOfLevs(bso.size()); - if(nbOfLevs!=factors.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : size of vectors must be the same !"); - if(nbOfLevs==0) - return ; - if(!bso[0]) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : pointers in 1st arg must be not NULL !"); - createPatchesFromCriterion(*bso[0],criterion,factors[0],eps); - for(std::size_t i=1;i elts(retrieveGridsAt((int)(i))); - std::size_t sz(elts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > elts2(sz); - std::vector< MEDCouplingAutoRefCountObjectPtr > elts3(sz); - for(std::size_t ii=0;ii > fieldNames(1); fieldNames[0].first=TMP_STR; fieldNames[0].second=1; - MEDCouplingAutoRefCountObjectPtr att(MEDCouplingAMRAttribute::New(this,fieldNames,0)); - att->alloc(); - DataArrayDouble *tmpDa(const_cast(att->getFieldOn(this,TMP_STR))); - tmpDa->cpyFrom(*criterion); - att->synchronizeCoarseToFine(); - for(std::size_t ii=0;iigetFieldOn(const_cast(elts[ii]->getMesh()),TMP_STR)); - elts3[ii]=const_cast(critOnLeaf); elts3[ii]->incrRef(); - } - att=0; - for(std::size_t ii=0;ii(elts[ii]->getMesh())->createPatchesFromCriterion(*bso[i],elts3[ii],factors[i],eps); - } -} - -void MEDCouplingCartesianAMRMesh::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const -{ - -} - -MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other):MEDCouplingCartesianAMRMeshGen(other) -{ -} - -MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):MEDCouplingCartesianAMRMeshGen(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop) -{ -} - -MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh) -{ -} - -std::vector MEDCouplingCartesianAMRMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingCartesianAMRMeshGen::getDirectChildrenWithNull()); - return ret; -} - -MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh() -{ -} diff --git a/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx deleted file mode 100644 index f67e08064..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#ifndef __MEDCOUPLINGCARTESIANAMRMESH_HXX__ -#define __MEDCOUPLINGCARTESIANAMRMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "BoxSplittingOptions.hxx" -#include "InterpKernelException.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingIMesh; - class MEDCouplingUMesh; - class DataArrayInt; - class DataArrayByte; - class DataArrayDouble; - class MEDCoupling1SGTUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingCartesianAMRMesh; - class MEDCouplingCartesianAMRMeshGen; - - /// @cond INTERNAL - - /*! - * This class does not inherit from TimeLabel so only const method should exist. - */ - class MEDCouplingCartesianAMRPatchGen : public RefCountObject - { - public: - MEDCOUPLING_EXPORT virtual MEDCouplingCartesianAMRPatchGen *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const = 0; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; - MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getMesh() const { return _mesh; } - protected: - MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father); - MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh); - const MEDCouplingCartesianAMRMeshGen *getMeshSafe() const; - MEDCouplingCartesianAMRMeshGen *getMeshSafe(); - private: - std::vector getDirectChildrenWithNull() const; - protected: - MEDCouplingAutoRefCountObjectPtr _mesh; - }; - - /*! - * This class does not inherit from TimeLabel so only const method should exist. - */ - class MEDCouplingCartesianAMRPatch : public MEDCouplingCartesianAMRPatchGen - { - public: - MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair >& bottomLeftTopRight); - MEDCouplingCartesianAMRPatch *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - // direct forward to _mesh - MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors); - // end of direct forward to _mesh - MEDCOUPLING_EXPORT int getNumberOfOverlapedCellsForFather() const; - MEDCOUPLING_EXPORT bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; - MEDCOUPLING_EXPORT bool isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; - MEDCOUPLING_EXPORT bool isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; - // basic set/get - MEDCOUPLING_EXPORT const std::vector< std::pair >& getBLTRRange() const { return _bl_tr; } - MEDCOUPLING_EXPORT std::vector< std::pair > getBLTRRangeRelativeToGF() const; - MEDCOUPLING_EXPORT std::vector computeCellGridSt() const; - MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair >& p1, const std::vector< std::pair >& p2); - // - static std::vector< std::vector< std::pair > > FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); - static void FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& ret); - static void UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); - static void UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); - static void UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2, bool isConservative); - private: - static void ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& p1Zone, std::vector< std::pair >& p2Zone, std::vector& factToApplyOn2); - private: - std::size_t getHeapMemorySizeWithoutChildren() const; - static const MEDCouplingCartesianAMRMeshGen *FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev); - static std::vector ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); - static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector& factors, const std::vector< std::pair >&p1 ,const std::vector< std::pair >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); - public: - static void ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors); - static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); - private: - MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father); - private: - //! bottom left/top right cell range relative to \a _father - std::vector< std::pair > _bl_tr; - }; - - /*! - * This class does not inherit from TimeLabel so only const method should exist. - */ - class MEDCouplingCartesianAMRPatchGF : public MEDCouplingCartesianAMRPatchGen - { - public: - MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh); - MEDCouplingCartesianAMRPatchGF *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - private: - std::size_t getHeapMemorySizeWithoutChildren() const; - private: - MEDCouplingCartesianAMRPatchGF(const MEDCouplingCartesianAMRPatchGF& other, MEDCouplingCartesianAMRMeshGen *father); - }; - - /// @endcond - - /*! - * This class is the base class dedicated to AMR using Adaptative Hierarchical Overlapped image Grid. - * This class does \b NOT inherit from MEDCouplingMesh because this class overlaps image grid structured meshes to perform adaptative mesh refinement. - * But this class aggregates MEDCouplingMesh instances ! - */ - class MEDCouplingCartesianAMRMeshGen : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT virtual MEDCouplingCartesianAMRMeshGen *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const = 0; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT const std::vector& getFactors() const { return _factors; } - MEDCOUPLING_EXPORT void setFactors(const std::vector& newFactors); - MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; - MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevel() const; - MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; - MEDCOUPLING_EXPORT const MEDCouplingIMesh *getImageMesh() const { return _mesh; } - // - MEDCOUPLING_EXPORT virtual const MEDCouplingCartesianAMRMeshGen *getFather() const = 0; - MEDCOUPLING_EXPORT virtual const MEDCouplingCartesianAMRMeshGen *getGodFather() const = 0; - MEDCOUPLING_EXPORT virtual int getAbsoluteLevel() const = 0; - MEDCOUPLING_EXPORT virtual void detachFromFather() = 0; - MEDCOUPLING_EXPORT virtual std::vector< std::pair > positionRelativeToGodFather(std::vector& st) const = 0; - MEDCOUPLING_EXPORT virtual int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const = 0; - MEDCOUPLING_EXPORT std::vector getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatchAtPosition(const std::vector& pos) const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getMeshAtPosition(const std::vector& pos) const; - MEDCOUPLING_EXPORT virtual std::vector retrieveGridsAt(int absoluteLev) const; - MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors); - MEDCOUPLING_EXPORT void removeAllPatches(); - MEDCOUPLING_EXPORT void removePatch(int patchId); - MEDCOUPLING_EXPORT int getNumberOfPatches() const; - MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector& criterion, const std::vector& factors); - MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors); - MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector& factors, double eps); - MEDCOUPLING_EXPORT int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const; - MEDCOUPLING_EXPORT std::vector< const MEDCouplingCartesianAMRPatch *> getPatches() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const; - MEDCOUPLING_EXPORT bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const; - MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const; - // coarse to fine - MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const; - MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const; - MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const; - // coarse to fine + fine to fine - MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector& arrsOnPatches, bool isConservative=true) const; - // fine to fine - MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector& arrsOnPatches) const; - MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; - // fine to coarse - MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const; - MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const; - // - MEDCOUPLING_EXPORT DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const; - // - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const; - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector& recurseArrs) const; - MEDCOUPLING_EXPORT DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT std::vector getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const; - MEDCOUPLING_EXPORT std::string buildPythonDumpOfThis() const; - protected: - MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other); - MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); - MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh); - void checkPatchId(int patchId) const; - void checkFactorsAndIfNotSetAssign(const std::vector& factors); - void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr >& grids) const; - static int GetGhostLevelInFineRef(int ghostLev, const std::vector& factors); - std::vector extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector& all) const; - void dumpPatchesOf(const std::string& varName, std::ostream& oss) const; - public: - virtual void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const = 0; - protected: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void updateTime() const; - protected: - MEDCouplingAutoRefCountObjectPtr _mesh; - std::vector< MEDCouplingAutoRefCountObjectPtr > _patches; - std::vector _factors; - }; - - class MEDCouplingCartesianAMRMeshSub : public MEDCouplingCartesianAMRMeshGen - { - public: - MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh); - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getFather() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getGodFather() const; - MEDCOUPLING_EXPORT int getAbsoluteLevel() const; - MEDCOUPLING_EXPORT void detachFromFather(); - MEDCOUPLING_EXPORT std::vector< std::pair > positionRelativeToGodFather(std::vector& st) const; - MEDCOUPLING_EXPORT int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; - private: - MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father); - MEDCouplingCartesianAMRMeshSub *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const; - protected: - MEDCouplingCartesianAMRMeshGen *_father; - }; - - class MEDCouplingCartesianAMRMesh : public MEDCouplingCartesianAMRMeshGen - { - public: - MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); - MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *New(MEDCouplingIMesh *mesh); - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getFather() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getGodFather() const; - MEDCOUPLING_EXPORT int getAbsoluteLevel() const; - MEDCOUPLING_EXPORT void detachFromFather(); - MEDCOUPLING_EXPORT std::vector< std::pair > positionRelativeToGodFather(std::vector& st) const; - MEDCOUPLING_EXPORT int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; - MEDCOUPLING_EXPORT std::vector retrieveGridsAt(int absoluteLev) const; - MEDCouplingCartesianAMRMesh *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - MEDCOUPLING_EXPORT void createPatchesFromCriterionML(const std::vector& bso, const DataArrayDouble *criterion, const std::vector< std::vector >& factors, double eps); - private: - void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const; - MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other); - MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); - MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh); - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - ~MEDCouplingCartesianAMRMesh(); - }; -} - -#endif - diff --git a/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx deleted file mode 100644 index 601ea910d..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx +++ /dev/null @@ -1,936 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingCurveLinearMesh.hxx" -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include "VolSurfUser.txx" -#include "PointLocatorAlgos.txx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh():_coords(0),_structure(0) -{ -} - -MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_structure(other._structure) -{ - if(deepCopy) - { - if((const DataArrayDouble *)other._coords) - _coords=other._coords->deepCpy(); - } - else - _coords=other._coords; -} - -MEDCouplingCurveLinearMesh::~MEDCouplingCurveLinearMesh() -{ -} - -MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New() -{ - return new MEDCouplingCurveLinearMesh; -} - -MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New(const std::string& meshName) -{ - MEDCouplingCurveLinearMesh *ret=new MEDCouplingCurveLinearMesh; - ret->setName(meshName); - return ret; -} - -MEDCouplingMesh *MEDCouplingCurveLinearMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingCurveLinearMesh(*this,recDeepCpy); -} - -void MEDCouplingCurveLinearMesh::updateTime() const -{ - if((const DataArrayDouble *)_coords) - updateTimeWith(*_coords); -} - -std::size_t MEDCouplingCurveLinearMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren()); - ret+=_structure.capacity()*sizeof(int); - return ret; -} - -std::vector MEDCouplingCurveLinearMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const DataArrayDouble *)_coords); - return ret; -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingCurveLinearMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingStructuredMesh::copyTinyStringsFrom(other); - if((DataArrayDouble *)_coords && (const DataArrayDouble *)otherC->_coords) - _coords->copyStringInfoFrom(*otherC->_coords); -} - -bool MEDCouplingCurveLinearMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingCurveLinearMesh !"; - return false; - } - if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - std::ostringstream oss; oss.precision(15); - if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords)) - { - oss << "Only one CurveLinearMesh between the two this and other has its coordinates defined !"; - reason=oss.str(); - return false; - } - if((const DataArrayDouble *)_coords) - { - if(!_coords->isEqualIfNotWhy(*(otherC->_coords),prec,reason)) - { - oss << "Coordinates DataArrayDouble of differ :"; - reason.insert(0,oss.str()); - return false; - } - if(_structure!=otherC->_structure) - { reason="CurveLinearMesh structures differ !"; return false; } - } - return true; -} - -bool MEDCouplingCurveLinearMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords)) - return false; - if((const DataArrayDouble *)_coords) - { - if(!_coords->isEqualWithoutConsideringStr(*(otherC->_coords),prec)) - return false; - if(_structure!=otherC->_structure) - return false; - } - return true; -} - -void MEDCouplingCurveLinearMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalWith : Meshes are not the same !"); -} - -/*! - * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCurveLinearMesh instance too). - * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCurveLinearMesh, \a this and \a other are the same ! - */ -void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); -} - -void MEDCouplingCurveLinearMesh::checkCoherency() const -{ - std::size_t sz=_structure.size(),i=0,nbOfNodes=1; - if(sz<1) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : structure should have a lgth of size 1 at least !"); - for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,i++) - { - if((*it)<1) - { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : At pos #" << i << " of structure value is " << *it << "should be >= 1 !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - nbOfNodes*=*it; - } - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not set !"); - if(!_coords->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not allocated !"); - if(_coords->getNumberOfComponents()<1) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array should have >= 1 components !"); - if(_coords->getNumberOfTuples()!=(int)nbOfNodes) - { - std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : structure said that number of nodes should be equal to " << nbOfNodes << " but number of tuples in array is equal to " << _coords->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCouplingCurveLinearMesh::checkCoherency1(double eps) const -{ - checkCoherency(); -} - -void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -int MEDCouplingCurveLinearMesh::getNumberOfCells() const -{ - checkCoherency(); - return MEDCouplingStructuredMesh::getNumberOfCells(); -} - -int MEDCouplingCurveLinearMesh::getNumberOfNodes() const -{ - checkCoherency(); - return MEDCouplingStructuredMesh::getNumberOfNodes(); -} - -void MEDCouplingCurveLinearMesh::getNodeGridStructure(int *res) const -{ - std::copy(_structure.begin(),_structure.end(),res); -} - -/*! - * MEDCouplingCurveLinearMesh has the property to define 2 space dimensions. One coming from its coordinates. The other coming from the node structure. - * Normally they should be equal ! This method returns the space dimension from coordinates. If the other one is requested call getSpaceDimensionOnNodeStruct. - * - * \sa MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct - */ -int MEDCouplingCurveLinearMesh::getSpaceDimension() const -{ - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getSpaceDimension : no array set ! impossible to deduce a space dimension !"); - return _coords->getNumberOfComponents(); -} - -void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCoordinatesOfNode : Coordinates not set !"); - int nbOfCompo=_coords->getNumberOfComponents(); - if(nodeId>=0 && nodeId<_coords->getNumberOfTuples()) - coo.insert(coo.end(),_coords->begin()+nodeId*nbOfCompo,_coords->begin()+(nodeId+1)*nbOfCompo); - else - { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::getCoordinatesOfNode : nodeId has to be in [0," << _coords->getNumberOfTuples() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } -} - -std::string MEDCouplingCurveLinearMesh::simpleRepr() const -{ - std::ostringstream ret; - ret << "Curve linear mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - ret << "The nodal stucture of curve linear mesh is : ["; - std::copy(_structure.begin(),_structure.end(),std::ostream_iterator(ret,",")); ret << "]\n"; - ret << "The coords array is this : "; - if((const DataArrayDouble *)_coords) - _coords->reprZipWithoutNameStream(ret); - else - ret << "no array specified !"; - return ret.str(); -} - -std::string MEDCouplingCurveLinearMesh::advancedRepr() const -{ - return simpleRepr(); -} - -DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() -{ - return _coords; -} - -const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const -{ - return _coords; -} - -void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) -{ - if(coords!=(const DataArrayDouble *)_coords) - { - _coords=const_cast(coords); - if(coords) - coords->incrRef(); - declareAsNew(); - } -} - -void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) -{ - std::size_t sz=std::distance(gridStructBg,gridStructEnd); - if(sz>=1 && sz<=3) - { - _structure.resize(0); - _structure.insert(_structure.end(),gridStructBg,gridStructEnd); - } - else - { - std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::setNodeGridStructure : size of input nodal grid structure (" << sz << ") should be in 1, 2 or 3 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -std::vector MEDCouplingCurveLinearMesh::getNodeGridStructure() const -{ - return _structure; -} - -MEDCouplingStructuredMesh *MEDCouplingCurveLinearMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - std::vector dims(getMeshDimension()); - if(dim!=(int)cellPart.size()) - { - std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector< std::pair > nodePartFormat(cellPart); - for(std::vector< std::pair >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) - (*it).second++; - MEDCouplingAutoRefCountObjectPtr tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); - MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); - const DataArrayDouble *coo(ret->getCoords()); - if(coo) - { - MEDCouplingAutoRefCountObjectPtr coo2(coo->selectByTupleIdSafe(tmp1->begin(),tmp1->end())); - ret->setCoords(coo2); - } - for(int i=0;isetNodeGridStructure(&dims[0],&dims[0]+dims.size()); - return ret.retn(); -} - -void MEDCouplingCurveLinearMesh::getBoundingBox(double *bbox) const -{ - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBoundingBox : Coordinates not set !"); - _coords->getMinMaxPerComponent(bbox); -} - -MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureField(bool isAbs) const -{ - checkCoherency(); - int meshDim=getMeshDimension(); - std::string name="MeasureOfMesh_"; name+=getName(); - MEDCouplingAutoRefCountObjectPtr field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - field->setName(name); field->setMesh(const_cast(this)); field->synchronizeTimeWithMesh(); - switch(meshDim) - { - case 3: - { getMeasureFieldMeshDim3(isAbs,field); return field.retn(); } - case 2: - { getMeasureFieldMeshDim2(isAbs,field); return field.retn(); } - case 1: - { getMeasureFieldMeshDim1(isAbs,field); return field.retn(); } - default: - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureField : mesh dimension must be in [1,2,3] !"); - } -} - -/*! - * \param [in,out] f field feeded with good values. - * \sa MEDCouplingCurveLinearMesh::getMeasureField - */ -void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const -{ - int nbnodes=getNumberOfNodes(); - int spaceDim=getSpaceDimension(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); - if(nbnodes==0) - { arr->alloc(0,1); return; } - if(spaceDim==1) - { - arr->alloc(nbnodes-1,1); - std::transform(_coords->begin()+1,_coords->end(),_coords->begin(),arr->getPointer(),std::minus()); - if(isAbs) - arr->abs(); - } - else - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayDouble::New(); tmp->alloc(nbnodes-1,spaceDim); - std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),tmp->getPointer(),std::minus()); - MEDCouplingAutoRefCountObjectPtr tmp2=tmp->magnitude(); field->setArray(tmp2); - } -} - -/*! - * \param [in,out] f field feeded with good values. - * \sa MEDCouplingCurveLinearMesh::getMeasureField - */ -void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const -{ - int nbcells=getNumberOfCells(); - int spaceDim=getSpaceDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); - arr->alloc(nbcells,1); - double *pt=arr->getPointer(); - const double *coords=_coords->begin(); - int nX=_structure[0]-1; - int conn[4]; - for(int i=0;i(INTERP_KERNEL::NORM_QUAD4,conn,4,coords,spaceDim); - } - if(isAbs) - arr->abs(); -} - -/*! - * \param [in,out] f field feeded with good values. - * \sa MEDCouplingCurveLinearMesh::getMeasureField - */ -void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const -{ - int nbcells=getNumberOfCells(); - int spaceDim=getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3 : with meshDim 3 only space dimension 3 is possible !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); - arr->alloc(nbcells,1); - double *pt=arr->getPointer(); - const double *coords=_coords->begin(); - int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1); - int nY1=_structure[0]*_structure[1]; - int conn[8]; - for(int i=0;i(INTERP_KERNEL::NORM_HEXA8,conn,8,coords,3); - } - if(isAbs) - arr->abs(); -} - -/*! - * not implemented yet ! - */ -MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureFieldOnNode(bool isAbs) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldOnNode : not implemented yet !"); -} - -MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::buildOrthogonalField() const -{ - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - array->alloc(nbOfCells,3); - double *vals=array->getPointer(); - for(int i=0;isetArray(array); - array->decrRef(); - ret->setMesh(this); - return ret; -} - -/// @cond INTERNAL - -namespace ParaMEDMEM -{ - template - class DummyClsMCL - { - public: - static const int MY_SPACEDIM=SPACEDIMM; - static const int MY_MESHDIM=8; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; - // begin - // useless, but for windows compilation ... - const double* getCoordinatesPtr() const { return 0; } - const int* getConnectivityPtr() const { return 0; } - const int* getConnectivityIndexPtr() const { return 0; } - INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; } - // end - }; -} - -/// @endcond - -int MEDCouplingCurveLinearMesh::getCellContainingPoint(const double *pos, double eps) const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - const double *coords=_coords->getConstPointer(); - int nodeId=-1; - _coords->distanceToTuple(pos,pos+spaceDim,nodeId); - if(nodeId<0) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : internal problem 1 !"); - int conn[8]; - int nbOfNodes=getNumberOfNodes(); - if(nbOfNodes==1) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : No cells in this !"); - switch(getMeshDimension()) - { - case 1: - if(spaceDim==1) - { - if(nodeId>0) - { - conn[0]=nodeId-1; conn[1]=nodeId; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) - return nodeId-1; - } - if(nodeId >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) - return nodeId; - } - } - case 2: - if(spaceDim==2) - { - int ny=nodeId/_structure[0],nx=nodeId-ny*_structure[0]; - if(nx>0 && ny>0) - { - conn[0]=nx-1+_structure[0]*(ny-1); conn[1]=nx-1+_structure[0]*ny; conn[2]=nx+_structure[0]*ny; conn[3]=nx+_structure[0]*(ny-1); - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) - return nx-1+(ny-1)*_structure[0]; - } - if(nx<_structure[0]-1 && ny>0) - { - conn[0]=nx+_structure[0]*(ny-1); conn[1]=nx+_structure[0]*ny; conn[2]=nx+1+_structure[0]*ny; conn[3]=nx+1+_structure[0]*(ny-1); - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) - return nx+(ny-1)*_structure[0]; - } - if(nx>0 && ny<_structure[1]-1) - { - conn[0]=nx-1+_structure[0]*ny; conn[1]=nx-1+_structure[0]*(ny+1); conn[2]=nx+_structure[0]*(ny+1); conn[3]=nx+_structure[0]*ny; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) - return nx-1+ny*_structure[0]; - } - if(nx<_structure[0]-1 && ny<_structure[1]-1) - { - conn[0]=nx+_structure[0]*ny; conn[1]=nx+_structure[0]*(ny+1); conn[2]=nx+1+_structure[0]*(ny+1); conn[3]=nx+1+_structure[0]*ny; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) - return nx+ny*_structure[0]; - } - } - case 3: - { - if(spaceDim==3) - { - int nY=_structure[0]*_structure[1]; - int nz=nodeId/_structure[1]; int ny=(nodeId-nz*nY)/_structure[0]; int nx=(nodeId-nz*nY)-_structure[0]*ny; - if(nx>0 && ny>0 && nz>0) - { - conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1); - conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx-1+(ny-1)*_structure[0]+(nz-1)*nY; - } - if(nx<_structure[0]-1 && ny>0 && nz>0) - { - conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1); - conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx+(ny-1)*_structure[0]+(nz-1)*nY; - } - if(nx>0 && ny<_structure[1]-1 && nz>0) - { - conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1); - conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx-1+ny*_structure[0]+(nz-1)*nY; - } - if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz>0) - { - conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1); - conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx+ny*_structure[0]+(nz-1)*nY; - } - if(nx>0 && ny>0 && nz<_structure[2]-1) - { - conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1); - conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx-1+(ny-1)*_structure[0]+nz*nY; - } - if(nx<_structure[0]-1 && ny>0 && nz<_structure[2]-1) - { - conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1); - conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx+(ny-1)*_structure[0]+nz*nY; - } - if(nx>0 && ny<_structure[1]-1 && nz<_structure[2]-1) - { - conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1); - conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx-1+ny*_structure[0]+nz*nY; - } - if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz<_structure[2]-1) - { - conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1); - conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz; - if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) - return nx+ny*_structure[0]+nz*nY; - } - } - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : mesh dimension managed are 1, 2 or 3 !"); - } -} - -void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vector, double angle) -{ - if(!((DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : no coordinates set !"); - int spaceDim=getSpaceDimension(); - int nbNodes=_coords->getNumberOfTuples(); - double *coords=_coords->getPointer(); - if(spaceDim==3) - MEDCouplingPointSet::Rotate3DAlg(center,vector,angle,nbNodes,coords); - else if(spaceDim==2) - MEDCouplingPointSet::Rotate2DAlg(center,angle,nbNodes,coords); - else - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : invalid space dim for rotation must be 2 or 3"); - _coords->declareAsNew(); - updateTime(); -} - -void MEDCouplingCurveLinearMesh::translate(const double *vector) -{ - if(!vector) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : NULL input point !"); - if(!((DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : no coordinates set !"); - double *coords=_coords->getPointer(); - int nbNodes=getNumberOfNodes(); - int dim=getSpaceDimension(); - for(int i=0; ideclareAsNew(); - updateTime(); -} - -void MEDCouplingCurveLinearMesh::scale(const double *point, double factor) -{ - if(!point) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : NULL input point !"); - if(!((DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : no coordinates set !"); - double *coords=_coords->getPointer(); - int nbNodes=_coords->getNumberOfTuples(); - int dim=_coords->getNumberOfComponents(); - for(int i=0;i()); - std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies(),factor)); - std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus()); - } - _coords->declareAsNew(); - updateTime(); -} - -MEDCouplingMesh *MEDCouplingCurveLinearMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::mergeMyselfWith : not available for CurveLinear Mesh !"); -} - -DataArrayDouble *MEDCouplingCurveLinearMesh::getCoordinatesAndOwner() const -{ - DataArrayDouble *ret=const_cast((const DataArrayDouble *)_coords); - if(ret) - ret->incrRef(); - return ret; -} - -DataArrayDouble *MEDCouplingCurveLinearMesh::getBarycenterAndOwner() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - int nbOfCells=getNumberOfCells(); - ret->alloc(nbOfCells,spaceDim); - ret->copyStringInfoFrom(*getCoords()); - switch(meshDim) - { - case 3: - { getBarycenterAndOwnerMeshDim3(ret); return ret.retn(); } - case 2: - { getBarycenterAndOwnerMeshDim2(ret); return ret.retn(); } - case 1: - { getBarycenterAndOwnerMeshDim1(ret); return ret.retn(); } - default: - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwner : mesh dimension must be in [1,2,3] !"); - } -} - -DataArrayDouble *MEDCouplingCurveLinearMesh::computeIsoBarycenterOfNodesPerCell() const -{ - return MEDCouplingCurveLinearMesh::getBarycenterAndOwner(); -} - -/*! - * \param [in,out] bary Barycenter array feeded with good values. - * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner - */ -void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const -{ - int nbOfCells=getNumberOfCells(); - double *ptToFill=bary->getPointer(); - const double *coor=_coords->getConstPointer(); - if(getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3 : with meshDim 3 only space dimension 3 is possible !"); - int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1); - int nY1=_structure[0]*_structure[1]; - int conn[8]; - for(int i=0;i(INTERP_KERNEL::NORM_HEXA8,conn,8,coor,3,ptToFill); - ptToFill+=3; - } -} - -/*! - * \param [in,out] bary Barycenter array feeded with good values. - * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner - */ -void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const -{ - int nbcells=getNumberOfCells(); - int spaceDim=getSpaceDimension(); - double *ptToFill=bary->getPointer(); - const double *coor=_coords->getConstPointer(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !"); - int nX=_structure[0]-1; - int conn[4]; - for(int i=0;i(INTERP_KERNEL::NORM_QUAD4,conn,4,coor,spaceDim,ptToFill); - ptToFill+=spaceDim; - } -} - -/*! - * \param [in,out] bary Barycenter array feeded with good values. - * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner - */ -void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const -{ - int spaceDim=getSpaceDimension(); - std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),bary->getPointer(),std::plus()); - std::transform(bary->begin(),bary->end(),bary->getPointer(),std::bind2nd(std::multiplies(),0.5)); -} - -void MEDCouplingCurveLinearMesh::renumberCells(const int *old2NewBg, bool check) -{ - throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CurveLinear Mesh !"); -} - -void MEDCouplingCurveLinearMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time=getTime(it,order); - tinyInfo.clear(); - tinyInfoD.clear(); - littleStrings.clear(); - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); - littleStrings.push_back(getTimeUnit()); - // - std::vector littleStrings2; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationStrInformation(littleStrings2); - littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); - // - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfo.push_back((int)_structure.size()); - for(std::vector::const_iterator itt=_structure.begin();itt!=_structure.end();itt++) - tinyInfo.push_back(*itt); - std::vector tinyInfo2; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationIntInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - // - tinyInfoD.push_back(time); -} - -void MEDCouplingCurveLinearMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - a1->alloc(tinyInfo[2],1); - std::vector tinyInfo2(tinyInfo.begin()+3+tinyInfo[2],tinyInfo.end()); - a2->resizeForUnserialization(tinyInfo2); -} - -void MEDCouplingCurveLinearMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); - a1->alloc((int)_structure.size(),1); - int *ptr=a1->getPointer(); - for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,ptr++) - *ptr=(*it); - int sz=0; - if((const DataArrayDouble *)_coords) - if(_coords->isAllocated()) - sz=_coords->getNbOfElems(); - a2=DataArrayDouble::New(); - a2->alloc(sz,1); - if(sz!=0 && (const DataArrayDouble *)_coords) - std::copy(_coords->begin(),_coords->end(),a2->getPointer()); -} - -void MEDCouplingCurveLinearMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); - int sz=tinyInfo[2]; - _structure.resize(sz); - for(int i=0;isz+3) - { - _coords=DataArrayDouble::New(); - std::vector tinyInfo2(tinyInfo.begin()+3+sz,tinyInfo.end()); - _coords->resizeForUnserialization(tinyInfo2); - std::copy(a2->begin(),a2->end(),_coords->getPointer()); - std::vector littleStrings2(littleStrings.begin()+3,littleStrings.end()); - _coords->finishUnserialization(tinyInfo2,littleStrings2); - } -} - -void MEDCouplingCurveLinearMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - std::ostringstream extent; - int meshDim=(int)_structure.size(); - if(meshDim<=0 || meshDim>3) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::writeVTKLL : meshDim invalid ! must be in [1,2,3] !"); - for(int i=0;i<3;i++) - { int val=i\n"; - ofs << " \n"; - ofs << " \n" << pointData << std::endl; - ofs << " \n"; - ofs << " \n" << cellData << std::endl; - ofs << " \n"; - ofs << " \n"; - if(getSpaceDimension()==3) - _coords->writeVTK(ofs,8,"Points",byteData); - else - { - MEDCouplingAutoRefCountObjectPtr coo=_coords->changeNbOfComponents(3,0.); - coo->writeVTK(ofs,8,"Points",byteData); - } - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingCurveLinearMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingCurveLinearMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; - stream << " Nodal structure : ["; - for(std::size_t i=0;i<_structure.size();i++) - { - char tmp='X'+i; - stream << " " << tmp << "=" << _structure[i]; - if(i!=_structure.size()-1) - stream << ", "; - } - stream << " ]."; - const DataArrayDouble *coo(_coords); - if(!coo) - { stream << std::endl << "No coordinates set !"; return ; } - if(!coo->isAllocated()) - { stream << std::endl << "Coordinates set but not allocated !"; return ; } - int nbOfCompo(coo->getNumberOfComponents()); - int nbOfCompoExp(-1); - try - { - nbOfCompoExp=getSpaceDimension(); - } - catch(INTERP_KERNEL::Exception& e) - { - } - if(nbOfCompo!=nbOfCompoExp) - { stream << std::endl << "Coordinates set and allocated but mismatch number of components !"; return ; } - stream << std::endl << "Coordinates ( number of tuples = " << coo->getNumberOfTuples() << " ) : "; - coo->reprQuickOverviewData(stream,200); -} - -std::string MEDCouplingCurveLinearMesh::getVTKFileExtension() const -{ - return std::string("vts"); -} - -std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const -{ - return std::string("StructuredGrid"); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx deleted file mode 100644 index 341075947..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingStructuredMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingCurveLinearMesh : public MEDCouplingStructuredMesh - { - public: - MEDCOUPLING_EXPORT static MEDCouplingCurveLinearMesh *New(); - MEDCOUPLING_EXPORT static MEDCouplingCurveLinearMesh *New(const std::string& meshName); - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return CURVE_LINEAR; } - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoords(); - MEDCOUPLING_EXPORT const DataArrayDouble *getCoords() const; - MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coords); - MEDCOUPLING_EXPORT void setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd); - MEDCOUPLING_EXPORT std::vector getNodeGridStructure() const; - MEDCOUPLING_EXPORT MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const; - // tools - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - //some useful methods - MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; - //serialisation-unserialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - void getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const; - void getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const; - void getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const; - void getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const; - void getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const; - void getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const; - private: - MEDCouplingCurveLinearMesh(); - MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCpy); - ~MEDCouplingCurveLinearMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - private: - MEDCouplingAutoRefCountObjectPtr _coords; - std::vector _structure; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.cxx b/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.cxx deleted file mode 100644 index bbc7021d0..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.cxx +++ /dev/null @@ -1,622 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingDefinitionTime.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include - -using namespace ParaMEDMEM; - -const double MEDCouplingDefinitionTime::EPS_DFT=1e-15; - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(const MEDCouplingFieldDouble *f, int meshId, const std::vector& arrId, int fieldId) -{ - static const char msg[]="TimeSlice::New : mismatch of arrays number of a fieldDouble and its policy !!! Internal error !!!"; - if(!f) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : empty field !"); - switch(f->getTimeDiscretization()) - { - case ONE_TIME: - { - if(arrId.size()!=1) - throw INTERP_KERNEL::Exception(msg); - return new MEDCouplingDefinitionTimeSliceInst(f,meshId,arrId[0],fieldId); - } - case CONST_ON_TIME_INTERVAL: - { - if(arrId.size()!=1) - throw INTERP_KERNEL::Exception(msg); - return new MEDCouplingDefinitionTimeSliceCstOnTI(f,meshId,arrId[0],fieldId); - } - case LINEAR_TIME: - { - if(arrId.size()!=2) - throw INTERP_KERNEL::Exception(msg); - return new MEDCouplingDefinitionTimeSliceLT(f,meshId,arrId[0],arrId[1],fieldId); - } - case NO_TIME: - throw INTERP_KERNEL::Exception("Invalide time discretization ! NO_TIME ! Impossible to build a definition time slice !"); - default: - throw INTERP_KERNEL::Exception("Invalide time discretization : Not recognized !"); - } -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(TypeOfTimeDiscretization type, const std::vector& tiI, const std::vector& tiD) -{ - switch(type) - { - case ONE_TIME: - return MEDCouplingDefinitionTimeSliceInst::New(tiI,tiD); - case CONST_ON_TIME_INTERVAL: - return MEDCouplingDefinitionTimeSliceCstOnTI::New(tiI,tiD); - case LINEAR_TIME: - return MEDCouplingDefinitionTimeSliceLT::New(tiI,tiD); - default: - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : unrecognized time discretization type !"); - } -} - -bool MEDCouplingDefinitionTimeSlice::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(_mesh_id!=other._mesh_id) - return false; - if(_array_id!=other._array_id) - return false; - if(_field_id!=other._field_id) - return false; - return true; -} - -int MEDCouplingDefinitionTimeSlice::getStartId() const -{ - return _array_id; -} - -int MEDCouplingDefinitionTimeSlice::getEndId() const -{ - return _array_id; -} - -void MEDCouplingDefinitionTimeSlice::appendRepr(std::ostream& stream) const -{ - stream << " *** MeshId : " << _mesh_id << " ArrayId : " << _array_id; -} - -MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):_mesh_id(meshId),_array_id(arrId),_field_id(fieldId) -{ - int tmp1,tmp2; - double t1=f->getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - if(t2 MEDCouplingDefinitionTimeSlice::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const -{ - double t1=getStartTime(); - double t2=getEndTime(); - double o1=other->getStartTime(); - double o2=other->getEndTime(); - return o1>t1-eps && o2getStartTime(); - double o2=other->getEndTime(); - return (o1t2-eps && o2>t2-eps); -} - -bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const -{ - double t2=getEndTime(); - double o1=other->getStartTime(); - double o2=other->getEndTime(); - return (o1>t2-eps && o2>t2-eps); -} - -bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const -{ - double t1=getStartTime(); - double o1=other->getStartTime(); - double o2=other->getEndTime(); - return (o1& tiI, const std::vector& tiD) -{ - MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst; - ret->unserialize(tiI,tiD); - return ret; -} - -void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const -{ - tiI.resize(3); - tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; - tiD.resize(1); - tiD[0]=_instant; -} - -void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector& tiI, const std::vector& tiD) -{ - _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; - _instant=tiD[0]; -} - -TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const -{ - return ONE_TIME; -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const -{ - return new MEDCouplingDefinitionTimeSliceInst(*this); -} - -bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) - return false; - const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast(&other); - if(!otherC) - return false; - return fabs(otherC->_instant-_instant)& ret) const -{ - ret.resize(1); - ret[0]=_instant; -} - -void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - meshId=_mesh_id; - arrId=_array_id; - arrIdInField=0; - fieldId=_field_id; -} - -bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const -{ - return fabs(tmp-_instant)getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - double eps=f->getTimeTolerance(); - if(fabs(t1-t2)>eps) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this"); - _instant=t1; -} - -MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector& tiI, const std::vector& tiD) -{ - MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI; - ret->unserialize(tiI,tiD); - return ret; -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const -{ - return new MEDCouplingDefinitionTimeSliceCstOnTI(*this); -} - -bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) - return false; - const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast(&other); - if(!otherC) - return false; - if(fabs(otherC->_start-_start)>eps) - return false; - return fabs(otherC->_end-_end)& ret) const -{ - ret.resize(1); - ret[0]=(_start+_end)/2.; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - meshId=_mesh_id; - arrId=_array_id; - arrIdInField=0; - fieldId=_field_id; -} - -bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const -{ - return _start-epstmp; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const -{ - stream << "Constant on time interval [" << _start << "," << _end << "]"; - MEDCouplingDefinitionTimeSlice::appendRepr(stream); -} - -double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const -{ - return _start; -} - -double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const -{ - return _end; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const -{ - tiI.resize(3); - tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; - tiD.resize(2); - tiD[0]=_start; tiD[1]=_end; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector& tiI, const std::vector& tiD) -{ - _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; - _start=tiD[0]; _end=tiD[1]; -} - -TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const -{ - return CONST_ON_TIME_INTERVAL; -} - -MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId) -{ - int tmp1,tmp2; - double t1=f->getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - _start=t1; - _end=t2; -} - -MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector& tiI, const std::vector& tiD) -{ - MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT; - ret->unserialize(tiI,tiD); - return ret; -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const -{ - return new MEDCouplingDefinitionTimeSliceLT(*this); -} - -bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) - return false; - const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast(&other); - if(!otherC) - return false; - if(_array_id_end!=otherC->_array_id_end) - return false; - if(fabs(otherC->_start-_start)>eps) - return false; - return fabs(otherC->_end-_end)& ret) const -{ - ret.resize(2); - ret[0]=_start; - ret[1]=_end; -} - -void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - if(fabs(tm-_start)tmp; -} - -void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const -{ - stream << "Linear on time interval [" << _start << "," << _end << "]"; - MEDCouplingDefinitionTimeSlice::appendRepr(stream); - stream << " EndArrayId : " << _array_id_end; -} - -double MEDCouplingDefinitionTimeSliceLT::getStartTime() const -{ - return _start; -} - -double MEDCouplingDefinitionTimeSliceLT::getEndTime() const -{ - return _end; -} - -int MEDCouplingDefinitionTimeSliceLT::getEndId() const -{ - return _array_id_end; -} - -void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const -{ - tiI.resize(4); - tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end; - tiD.resize(2); - tiD[0]=_start; tiD[1]=_end; -} - -void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector& tiI, const std::vector& tiD) -{ - _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; _array_id_end=tiI[3]; - _start=tiD[0]; _end=tiD[1]; -} - -TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const -{ - return LINEAR_TIME; -} - -MEDCouplingDefinitionTimeSliceLT::MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId),_array_id_end(arr2Id) -{ - int tmp1,tmp2; - double t1=f->getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - _start=t1; - _end=t2; -} - -MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT) -{ -} - -MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector& fs, const std::vector& meshRefs, const std::vector >& arrRefs) -{ - std::size_t sz=fs.size(); - if(sz!=arrRefs.size()) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !"); - _slices.resize(sz); - for(std::size_t i=0;igetTimeTolerance(); - for(std::size_t i=1;iisAfterMe(_slices[i],_eps)) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructors : the sequences of fields does NOT defines a stricly ascendant monotonic time sequence !"); - // double t1=ref->getEndTime(); - // double t2=_slices[i]->getStartTime(); - // if(fabs(t1-t2)<_eps) - // if(ref->getEndId() != _slices[i]->getStartId()) - // throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : 2 slices refers to the same time and underlying arrays differs !"); - ref=_slices[i]; - } -} - -std::size_t MEDCouplingDefinitionTime::getHeapMemorySizeWithoutChildren() const -{ - return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int)); -} - -std::vector MEDCouplingDefinitionTime::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other) -{ - std::size_t sz=other._slices.size(); - _slices.resize(sz); - for(std::size_t i=0;icopy(); -} - -bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const -{ - std::size_t sz=_slices.size(); - if(sz!=other._slices.size()) - return false; - for(std::size_t i=0;iisEqual(*other._slices[i],_eps)) - return false; - return true; -} - -void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - std::vector meshIds; - std::vector arrIds; - std::vector arrIdsInField; - std::vector fieldIds; - getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds); - meshId=meshIds.back(); - arrId=arrIds.back(); - arrIdInField=arrIdsInField.back(); - fieldId=fieldIds.back(); -} - -void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - std::vector meshIds; - std::vector arrIds; - std::vector arrIdsInField; - std::vector fieldIds; - getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds); - meshId=meshIds.front(); - arrId=arrIds.front(); - arrIdInField=arrIdsInField.front(); - fieldId=fieldIds.front(); -} - -void MEDCouplingDefinitionTime::getIdsOnTime(double tm, std::vector& meshIds, std::vector& arrIds, std::vector& arrIdsInField, std::vector& fieldIds) const -{ - std::vector ids; - int id=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++) - if((*it)->isContaining(tm,_eps)) - ids.push_back(id); - if(ids.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !"); - std::size_t sz=ids.size(); - if(sz>2) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !"); - // - meshIds.resize(sz); - arrIds.resize(sz); - arrIdsInField.resize(sz); - fieldIds.resize(sz); - for(std::size_t i=0;igetIdsOnTime(tm,_eps,meshIds[i],arrIds[i],arrIdsInField[i],fieldIds[i]); -} - -std::vector MEDCouplingDefinitionTime::getHotSpotsTime() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_slices.begin();it!=_slices.end();it++) - { - std::vector tmp; - (*it)->getHotSpotsTime(tmp); - if(!ret.empty()) - { - if(fabs(ret.back()-tmp.front())>_eps) - ret.insert(ret.end(),tmp.begin(),tmp.end()); - else - ret.insert(ret.end(),tmp.begin()+1,tmp.end()); - } - else - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const -{ - stream << "Time definition :\n"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_slices.begin();it!=_slices.end();it++) - { - stream << " - "; - (*it)->appendRepr(stream); - stream << std::endl; - } -} - -void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector& tinyInfoI, std::vector& tinyInfoD) const -{ - int sz=(int)_slices.size(); - tinyInfoD.resize(1); - tinyInfoD[0]=_eps; - tinyInfoI.resize(3*sz+2); - tinyInfoI[0]=sz; - std::vector coreData; - for(int i=0;i tmp1; - std::vector tmp2; - tinyInfoI[i+2]=(int)_slices[i]->getTimeType(); - _slices[i]->getTinySerializationInformation(tmp1,tmp2); - tinyInfoI[i+sz+2]=(int)tmp1.size(); - tinyInfoI[i+2*sz+2]=(int)tmp2.size(); - coreData.insert(coreData.end(),tmp1.begin(),tmp1.end()); - tinyInfoD.insert(tinyInfoD.end(),tmp2.begin(),tmp2.end()); - } - tinyInfoI[1]=(int)coreData.size(); - tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end()); -} - -void MEDCouplingDefinitionTime::unserialize(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - int sz=tinyInfoI[0]; - _slices.resize(sz); - _eps=tinyInfoD[0]; - int offset1=0; - int offset2=1; - for(int i=0;i tmp1(tinyInfoI.begin()+3*sz+2+offset1,tinyInfoI.begin()+3*sz+2+offset1+sz1); - std::vector tmp2(tinyInfoD.begin()+offset2,tinyInfoD.begin()+offset2+sz2); - MEDCouplingDefinitionTimeSlice *pt=MEDCouplingDefinitionTimeSlice::New(ty,tmp1,tmp2); - _slices[i]=pt; - offset1+=sz1; - offset2+=sz2; - } -} - diff --git a/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.hxx b/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.hxx deleted file mode 100644 index ab2536b70..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.hxx +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGDEFINITIONTIME_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGDEFINITIONTIME_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDCouplingFieldDouble; - - class MEDCouplingDefinitionTimeSlice : public RefCountObject - { - public: - MEDCOUPLING_EXPORT static MEDCouplingDefinitionTimeSlice *New(const MEDCouplingFieldDouble *f, int meshId, const std::vector& arrId, int fieldId); - MEDCOUPLING_EXPORT static MEDCouplingDefinitionTimeSlice *New(TypeOfTimeDiscretization type, const std::vector& tiI, const std::vector& tiD); - MEDCOUPLING_EXPORT int getArrayId() const { return _array_id; } - MEDCOUPLING_EXPORT virtual MEDCouplingDefinitionTimeSlice *copy() const = 0; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - MEDCOUPLING_EXPORT virtual void getHotSpotsTime(std::vector& ret) const = 0; - MEDCOUPLING_EXPORT virtual void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const = 0; - MEDCOUPLING_EXPORT virtual bool isContaining(double tmp, double eps) const = 0; - MEDCOUPLING_EXPORT virtual int getStartId() const; - MEDCOUPLING_EXPORT virtual int getEndId() const; - MEDCOUPLING_EXPORT virtual void appendRepr(std::ostream& stream) const; - MEDCOUPLING_EXPORT virtual double getStartTime() const = 0; - MEDCOUPLING_EXPORT virtual double getEndTime() const = 0; - MEDCOUPLING_EXPORT virtual void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const = 0; - MEDCOUPLING_EXPORT virtual TypeOfTimeDiscretization getTimeType() const = 0; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT bool isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - MEDCOUPLING_EXPORT bool isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - MEDCOUPLING_EXPORT bool isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - MEDCOUPLING_EXPORT bool isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - protected: - MEDCOUPLING_EXPORT MEDCouplingDefinitionTimeSlice() { } - MEDCOUPLING_EXPORT MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); - protected: - int _mesh_id; - int _array_id; - int _field_id; - }; - - class MEDCouplingDefinitionTimeSliceInst : public MEDCouplingDefinitionTimeSlice - { - public: - static MEDCouplingDefinitionTimeSliceInst *New(const std::vector& tiI, const std::vector& tiD); - MEDCouplingDefinitionTimeSlice *copy() const; - bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - void getHotSpotsTime(std::vector& ret) const; - void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - bool isContaining(double tmp, double eps) const; - void appendRepr(std::ostream& stream) const; - double getStartTime() const; - double getEndTime() const; - void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const; - void unserialize(const std::vector& tiI, const std::vector& tiD); - TypeOfTimeDiscretization getTimeType() const; - public: - MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); - protected: - MEDCouplingDefinitionTimeSliceInst() { } - protected: - double _instant; - }; - - class MEDCouplingDefinitionTimeSliceCstOnTI : public MEDCouplingDefinitionTimeSlice - { - public: - static MEDCouplingDefinitionTimeSliceCstOnTI *New(const std::vector& tiI, const std::vector& tiD); - MEDCouplingDefinitionTimeSlice *copy() const; - bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - void getHotSpotsTime(std::vector& ret) const; - void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - bool isContaining(double tmp, double eps) const; - void appendRepr(std::ostream& stream) const; - double getStartTime() const; - double getEndTime() const; - void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const; - void unserialize(const std::vector& tiI, const std::vector& tiD); - TypeOfTimeDiscretization getTimeType() const; - public: - MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); - protected: - MEDCouplingDefinitionTimeSliceCstOnTI() { } - protected: - double _start; - double _end; - }; - - class MEDCouplingDefinitionTimeSliceLT : public MEDCouplingDefinitionTimeSlice - { - public: - static MEDCouplingDefinitionTimeSliceLT *New(const std::vector& tiI, const std::vector& tiD); - MEDCouplingDefinitionTimeSlice *copy() const; - bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - void getHotSpotsTime(std::vector& ret) const; - void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - bool isContaining(double tmp, double eps) const; - void appendRepr(std::ostream& stream) const; - double getStartTime() const; - double getEndTime() const; - int getEndId() const; - void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const; - void unserialize(const std::vector& tiI, const std::vector& tiD); - TypeOfTimeDiscretization getTimeType() const; - public: - MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId); - protected: - MEDCouplingDefinitionTimeSliceLT() { } - protected: - int _array_id_end; - double _start; - double _end; - }; - - class MEDCouplingDefinitionTime - { - public: - MEDCOUPLING_EXPORT MEDCouplingDefinitionTime(); - MEDCOUPLING_EXPORT MEDCouplingDefinitionTime(const std::vector& fs, const std::vector& meshRefs, const std::vector >& arrRefs); - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void assign(const MEDCouplingDefinitionTime& other); - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingDefinitionTime& other) const; - MEDCOUPLING_EXPORT double getTimeResolution() const { return _eps; } - MEDCOUPLING_EXPORT void getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - MEDCOUPLING_EXPORT void getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - MEDCOUPLING_EXPORT void getIdsOnTime(double tm, std::vector& meshIds, std::vector& arrIds, std::vector& arrIdsInField, std::vector& fieldIds) const; - MEDCOUPLING_EXPORT std::vector getHotSpotsTime() const; - MEDCOUPLING_EXPORT void appendRepr(std::ostream& stream) const; - public: - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoI, std::vector& tinyInfoD) const; - MEDCOUPLING_EXPORT void unserialize(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - private: - double _eps; - std::vector< MEDCouplingAutoRefCountObjectPtr > _slices; - static const double EPS_DFT; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx deleted file mode 100644 index 3df24b33b..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ /dev/null @@ -1,961 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "CellModel.hxx" - -#include "InterpolationUtils.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -/*! - * Build an extruded mesh instance from 3D and 2D unstructured mesh lying on the \b same \b coords. - * @param mesh3D 3D unstructured mesh. - * @param mesh2D 2D unstructured mesh lying on the same coordinates than mesh3D. \b Warning mesh2D is \b not \b const - * because the mesh is aggregated and potentially modified by rotate or translate method. - * @param cell2DId Id of cell in mesh2D mesh where the computation of 1D mesh will be done. - */ -MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) -{ - return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId); -} - -/*! - * This constructor is here only for unserialisation process. - * This constructor is normally completely useless for end user. - */ -MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New() -{ - return new MEDCouplingExtrudedMesh; -} - -MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const -{ - return EXTRUDED; -} - -std::size_t MEDCouplingExtrudedMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingExtrudedMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_mesh2D); - ret.push_back(_mesh1D); - ret.push_back(_mesh3D_ids); - return ret; -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingMesh::copyTinyStringsFrom(other); - _mesh2D->copyTinyStringsFrom(otherC->_mesh2D); - _mesh1D->copyTinyStringsFrom(otherC->_mesh1D); -} - -MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) -try:_mesh2D(const_cast(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId) -{ - if(_mesh2D!=0) - _mesh2D->incrRef(); - computeExtrusion(mesh3D); - setName(mesh3D->getName()); -} -catch(INTERP_KERNEL::Exception& e) -{ - if(_mesh2D) - _mesh2D->decrRef(); - if(_mesh1D) - _mesh1D->decrRef(); - if(_mesh3D_ids) - _mesh3D_ids->decrRef(); - throw e; -} - -MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1) -{ -} - -MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id) -{ - if(deepCopy) - { - _mesh2D=other._mesh2D->clone(true); - _mesh1D=other._mesh1D->clone(true); - _mesh3D_ids=other._mesh3D_ids->deepCpy(); - } - else - { - _mesh2D=other._mesh2D; - if(_mesh2D) - _mesh2D->incrRef(); - _mesh1D=other._mesh1D; - if(_mesh1D) - _mesh1D->incrRef(); - _mesh3D_ids=other._mesh3D_ids; - if(_mesh3D_ids) - _mesh3D_ids->incrRef(); - } -} - -int MEDCouplingExtrudedMesh::getNumberOfCells() const -{ - return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells(); -} - -int MEDCouplingExtrudedMesh::getNumberOfNodes() const -{ - return _mesh2D->getNumberOfNodes(); -} - -int MEDCouplingExtrudedMesh::getSpaceDimension() const -{ - return 3; -} - -int MEDCouplingExtrudedMesh::getMeshDimension() const -{ - return 3; -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingExtrudedMesh(*this,recDeepCpy); -} - -bool MEDCouplingExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); - std::ostringstream oss; - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingExtrudedMesh !"; - return false; - } - if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason)) - { - reason.insert(0,"Mesh2D unstructured meshes differ : "); - return false; - } - if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason)) - { - reason.insert(0,"Mesh1D unstructured meshes differ : "); - return false; - } - if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason)) - { - reason.insert(0,"Mesh3D ids DataArrayInt instances differ : "); - return false; - } - if(_cell_2D_id!=otherC->_cell_2D_id) - { - oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " << otherC->_cell_2D_id; - reason=oss.str(); - return false; - } - return true; -} - -bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec)) - return false; - if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec)) - return false; - if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids)) - return false; - if(_cell_2D_id!=otherC->_cell_2D_id) - return false; - return true; -} - -void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !"); -} - -void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !"); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const -{ - const int *ids=_mesh3D_ids->getConstPointer(); - int nbOf3DCells=_mesh3D_ids->getNumberOfTuples(); - const int *where=std::find(ids,ids+nbOf3DCells,cellId); - if(where==ids+nbOf3DCells) - throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !"); - int nbOfCells2D=_mesh2D->getNumberOfCells(); - int locId=((int)std::distance(ids,where))%nbOfCells2D; - INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId); - return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType(); -} - -std::set MEDCouplingExtrudedMesh::getAllGeoTypes() const -{ - std::set ret2D(_mesh2D->getAllGeoTypes()); - std::set ret; - for(std::set::const_iterator it=ret2D.begin();it!=ret2D.end();it++) - ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType()); - return ret; -} - -DataArrayInt *MEDCouplingExtrudedMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - INTERP_KERNEL::NormalizedCellType revExtTyp=cm.getReverseExtrudedType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - if(revExtTyp==INTERP_KERNEL::NORM_ERROR) - { - ret->alloc(0,1); - return ret.retn(); - } - MEDCouplingAutoRefCountObjectPtr tmp=_mesh2D->giveCellsWithType(revExtTyp); - int nbOfLevs=_mesh1D->getNumberOfCells(); - int nbOfCells2D=_mesh2D->getNumberOfCells(); - int nbOfTuples=tmp->getNumberOfTuples(); - ret->alloc(nbOfLevs*nbOfTuples,1); - int *pt=ret->getPointer(); - for(int i=0;ibegin(),tmp->end(),pt,std::bind2nd(std::plus(),i*nbOfCells2D)); - MEDCouplingAutoRefCountObjectPtr ret2=ret->renumberR(_mesh3D_ids->begin()); - ret2->sort(); - return ret2.retn(); -} - -DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfNodesPerCell() const -{ - MEDCouplingAutoRefCountObjectPtr ret2D=_mesh2D->computeNbOfNodesPerCell(); - int nbOfLevs=_mesh1D->getNumberOfCells(); - int nbOfCells2D=_mesh2D->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1); - int *pt=ret3D->getPointer(); - for(int i=0;ibegin(),ret2D->end(),pt); - ret3D->applyLin(2,0,0); - return ret3D->renumberR(_mesh3D_ids->begin()); -} - -DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfFacesPerCell() const -{ - MEDCouplingAutoRefCountObjectPtr ret2D=_mesh2D->computeNbOfNodesPerCell(); - int nbOfLevs=_mesh1D->getNumberOfCells(); - int nbOfCells2D=_mesh2D->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1); - int *pt=ret3D->getPointer(); - for(int i=0;ibegin(),ret2D->end(),pt); - ret3D->applyLin(2,2,0); - return ret3D->renumberR(_mesh3D_ids->begin()); -} - -DataArrayInt *MEDCouplingExtrudedMesh::computeEffectiveNbOfNodesPerCell() const -{ - return computeNbOfNodesPerCell(); -} - -int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - int ret=0; - int nbOfCells2D=_mesh2D->getNumberOfCells(); - for(int i=0;igetTypeOfCell(i); - if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type) - ret++; - } - return ret*_mesh1D->getNumberOfCells(); -} - -void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int nbOfCells2D=_mesh2D->getNumberOfCells(); - int nbOfNodes2D=_mesh2D->getNumberOfNodes(); - int locId=cellId%nbOfCells2D; - int lev=cellId/nbOfCells2D; - std::vector tmp,tmp2; - _mesh2D->getNodeIdsOfCell(locId,tmp); - tmp2=tmp; - std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus(),nbOfNodes2D*lev)); - std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus(),nbOfNodes2D*(lev+1))); - conn.insert(conn.end(),tmp.begin(),tmp.end()); - conn.insert(conn.end(),tmp2.begin(),tmp2.end()); -} - -void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - int nbOfNodes2D=_mesh2D->getNumberOfNodes(); - int locId=nodeId%nbOfNodes2D; - int lev=nodeId/nbOfNodes2D; - std::vector tmp,tmp2; - _mesh2D->getCoordinatesOfNode(locId,tmp); - tmp2=tmp; - int spaceDim=_mesh1D->getSpaceDimension(); - const double *z=_mesh1D->getCoords()->getConstPointer(); - std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus()); - std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus()); - coo.insert(coo.end(),tmp.begin(),tmp.end()); - coo.insert(coo.end(),tmp2.begin(),tmp2.end()); -} - -std::string MEDCouplingExtrudedMesh::simpleRepr() const -{ - std::ostringstream ret; - ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; - ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; - ret << "1D Mesh info : _____________________\n\n\n"; - ret << _mesh1D->simpleRepr(); - ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n"; - return ret.str(); -} - -std::string MEDCouplingExtrudedMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh (unit) : " << tt << " (" << getTimeUnit() << ")\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; - ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; - ret << "1D Mesh info : _____________________\n\n\n"; - ret << _mesh1D->advancedRepr(); - ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n"; - ret << "3D cell ids per level :\n"; - return ret.str(); -} - -void MEDCouplingExtrudedMesh::checkCoherency() const -{ -} - -void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const -{ - checkCoherency(); -} - -void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const -{ - double bbox2D[6]; - _mesh2D->getBoundingBox(bbox2D); - const double *nodes1D=_mesh1D->getCoords()->getConstPointer(); - int nbOfNodes1D=_mesh1D->getNumberOfNodes(); - double bbox1DMin[3],bbox1DMax[3],tmp[3]; - std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits::max()); - std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits::max())); - for(int i=0;i(std::min)); - std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast(std::max)); - } - std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus()); - int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3)); - bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0]; - bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1]; - bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2]; - bbox[2*id+1]+=tmp[id]; -} - -void MEDCouplingExtrudedMesh::updateTime() const -{ - if(_mesh2D) - { - updateTimeWith(*_mesh2D); - } - if(_mesh1D) - { - updateTimeWith(*_mesh1D); - } -} - -void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) -{ - throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh"); -} - -MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const -{ - MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMesh(_mesh1D,0); - const int *renum=_mesh3D_ids->getConstPointer(); - ret->renumberCells(renum,false); - ret->setName(getName()); - return ret; -} - -MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const -{ - return build3DUnstructuredMesh(); -} - -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const -{ - std::string name="MeasureOfMesh_"; - name+=getName(); - MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true); - MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true); - const double *ret2DPtr=ret2D->getArray()->getConstPointer(); - const double *ret1DPtr=ret1D->getArray()->getConstPointer(); - int nbOf2DCells=_mesh2D->getNumberOfCells(); - int nbOf1DCells=_mesh1D->getNumberOfCells(); - int nbOf3DCells=nbOf2DCells*nbOf1DCells; - const int *renum=_mesh3D_ids->getConstPointer(); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - ret->synchronizeTimeWithMesh(); - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(nbOf3DCells,1); - double *retPtr=da->getPointer(); - for(int i=0;isetArray(da); - da->decrRef(); - ret->setName(name); - ret2D->decrRef(); - ret1D->decrRef(); - return ret; -} - -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const -{ - //not implemented yet - return 0; -} - -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !"); -} - -int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getCellContainingPoint : not implemented yet !"); -} - -MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh() -{ - if(_mesh2D) - _mesh2D->decrRef(); - if(_mesh1D) - _mesh1D->decrRef(); - if(_mesh3D_ids) - _mesh3D_ids->decrRef(); -} - -void MEDCouplingExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D) -{ - const char errMsg1[]="2D mesh is empty unable to compute extrusion !"; - const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method"; - const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !"; - if(_mesh2D==0 || mesh3D==0) - throw INTERP_KERNEL::Exception(errMsg1); - if(_mesh2D->getCoords()!=mesh3D->getCoords()) - throw INTERP_KERNEL::Exception(errMsg2); - if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0) - throw INTERP_KERNEL::Exception(errMsg3); - if(!_mesh3D_ids) - _mesh3D_ids=DataArrayInt::New(); - if(!_mesh1D) - _mesh1D=MEDCouplingUMesh::New(); - computeExtrusionAlg(mesh3D); -} - -void MEDCouplingExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, - const int *desc3D, const int *descIndx3D, - const int *revDesc3D, const int *revDescIndx3D, - bool computeMesh1D) -{ - int nbOf2DCells=_mesh2D->getNumberOfCells(); - int start=revDescIndx3D[idIn3DDesc]; - int end=revDescIndx3D[idIn3DDesc+1]; - if(end-start!=1) - { - std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " << idIn3DDesc; - ost << " shared by more than 1 3D cell !!!"; - throw INTERP_KERNEL::Exception(ost.str().c_str()); - } - int current3DCell=revDesc3D[start]; - int current2DCell=idIn3DDesc; - int *mesh3DIDs=_mesh3D_ids->getPointer(); - mesh3DIDs[newId]=current3DCell; - const int *conn2D=subMesh->getNodalConnectivity()->getConstPointer(); - const int *conn2DIndx=subMesh->getNodalConnectivityIndex()->getConstPointer(); - for(int i=1;i conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); - std::sort(conn.begin(),conn.end()); - if(computeMesh1D) - computeBaryCenterOfFace(conn,i-1); - current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn, - desc3D,descIndx3D,conn2D,conn2DIndx); - start=revDescIndx3D[current2DCell]; - end=revDescIndx3D[current2DCell+1]; - if(end-start!=2) - { - std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!"; - ost << " : Impossible or call tryToShareSameCoords method !"; - throw INTERP_KERNEL::Exception(ost.str().c_str()); - } - if(revDesc3D[start]!=current3DCell) - current3DCell=revDesc3D[start]; - else - current3DCell=revDesc3D[start+1]; - mesh3DIDs[i*nbOf2DCells+newId]=current3DCell; - } - if(computeMesh1D) - { - std::vector conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); - std::sort(conn.begin(),conn.end()); - computeBaryCenterOfFace(conn,nbOf1DLev-1); - current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn, - desc3D,descIndx3D,conn2D,conn2DIndx); - conn.clear(); - conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); - std::sort(conn.begin(),conn.end()); - computeBaryCenterOfFace(conn,nbOf1DLev); - } -} - -int MEDCouplingExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector& connSorted, - const int *desc3D, const int *descIndx3D, - const int *conn2D, const int *conn2DIndx) -{ - int start=descIndx3D[current3DCell]; - int end=descIndx3D[current3DCell+1]; - bool found=false; - for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++) - { - if(*candidate2D!=current2DCell) - { - std::vector conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]); - std::sort(conn2.begin(),conn2.end()); - std::list intersect; - std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(), - std::insert_iterator< std::list >(intersect,intersect.begin())); - if(intersect.empty()) - return *candidate2D; - } - } - std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " << current2DCell; - ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !"; - throw INTERP_KERNEL::Exception(ost.str().c_str()); -} - -void MEDCouplingExtrudedMesh::computeBaryCenterOfFace(const std::vector& nodalConnec, int lev1DId) -{ - double *zoneToUpdate=_mesh1D->getCoords()->getPointer()+lev1DId*3; - std::fill(zoneToUpdate,zoneToUpdate+3,0.); - const double *coords=_mesh2D->getCoords()->getConstPointer(); - for(std::vector::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++) - std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus()); - std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies(),(double)(1./(int)nodalConnec.size()))); -} - -int MEDCouplingExtrudedMesh::FindCorrespCellByNodalConn(const std::vector& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr) -{ - std::vector::const_iterator iter=nodalConnec.begin(); - std::set s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]); - iter++; - for(;iter!=nodalConnec.end();iter++) - { - std::set s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]); - std::set s3; - std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set >(s3,s3.end())); - s1=s3; - } - if(s1.size()==1) - return *(s1.begin()); - std::ostringstream ostr; - ostr << "Cell with nodal connec : "; - std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator(ostr," ")); - ostr << " is not part of mesh"; - throw INTERP_KERNEL::Exception(ostr.str().c_str()); -} - -/*! - * This method is callable on 1Dmeshes (meshDim==1 && spaceDim==3) returned by MEDCouplingExtrudedMesh::getMesh1D typically. - * These 1Dmeshes (meshDim==1 && spaceDim==3) have a special semantic because these meshes do not specify a static location but a translation along a path. - * This method checks that 'm1' and 'm2' are compatible, if not an exception is thrown. In case these meshes ('m1' and 'm2') are compatible 2 corresponding meshes - * are created ('m1r' and 'm2r') that can be used for interpolation. - * @param m1 input mesh with meshDim==1 and spaceDim==3 - * @param m2 input mesh with meshDim==1 and spaceDim==3 - * @param eps tolerance acceptable to determine compatibility - * @param m1r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1 - * @param m2r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1 - * @param v is the output normalized vector of the common direction of 'm1' and 'm2' - * @throw in case that m1 and m2 are not compatible each other. - */ -void MEDCouplingExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, - MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) -{ - if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !"); - m1r=m1->clone(true); - m2r=m2->clone(true); - m1r->changeSpaceDimension(1); - m2r->changeSpaceDimension(1); - std::vector c; - std::vector ref,ref2; - m1->getNodeIdsOfCell(0,c); - m1->getCoordinatesOfNode(c[0],ref); - m1->getCoordinatesOfNode(c[1],ref2); - std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus()); - double n=INTERP_KERNEL::norm<3>(v); - std::transform(v,v+3,v,std::bind2nd(std::multiplies(),1/n)); - m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer()); - m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer()); -} - -void MEDCouplingExtrudedMesh::rotate(const double *center, const double *vector, double angle) -{ - _mesh2D->rotate(center,vector,angle); - _mesh1D->rotate(center,vector,angle); -} - -void MEDCouplingExtrudedMesh::translate(const double *vector) -{ - _mesh2D->translate(vector); - _mesh1D->translate(vector); -} - -void MEDCouplingExtrudedMesh::scale(const double *point, double factor) -{ - _mesh2D->scale(point,factor); - _mesh1D->scale(point,factor); -} - -std::vector MEDCouplingExtrudedMesh::getDistributionOfTypes() const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const -{ - // not implemented yet ! - return 0; -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - // not implemented yet ! - return 0; -} - -DataArrayInt *MEDCouplingExtrudedMesh::simplexize(int policy) -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !"); -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - // not implemented yet ! - return 0; -} - -DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const -{ - DataArrayDouble *arr2D=_mesh2D->getCoords(); - DataArrayDouble *arr1D=_mesh1D->getCoords(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfNodes(),3); - int nbOf1DLev=_mesh1D->getNumberOfNodes(); - int nbOf2DNodes=_mesh2D->getNumberOfNodes(); - const double *ptSrc=arr2D->getConstPointer(); - double *pt=ret->getPointer(); - std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt); - for(int i=1;igetConstPointer()+3*i,arr1D->getConstPointer()+3*(i+1),vec); - std::transform(arr1D->getConstPointer()+3*(i-1),arr1D->getConstPointer()+3*i,vec,vec,std::minus()); - for(int j=0;j()); - } - return ret; -} - -DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getBarycenterAndOwner : not yet implemented !"); -} - -DataArrayDouble *MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell() const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell: not yet implemented !"); -} - -void MEDCouplingExtrudedMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - MEDCouplingAutoRefCountObjectPtr m(buildUnstructured()); - m->getReverseNodalConnectivity(revNodal,revNodalIndx); -} - -void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) -{ - _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1); - int nbOf1DLev=mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells(); - _mesh1D->setMeshDimension(1); - _mesh1D->allocateCells(nbOf1DLev); - int tmpConn[2]; - for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn); - } - _mesh1D->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbOf1DLev+1,3); - _mesh1D->setCoords(myCoords); - myCoords->decrRef(); - DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx; - desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); - MEDCouplingUMesh *subMesh=mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - DataArrayInt *revNodal2D,*revNodalIndx2D; - revNodal2D=DataArrayInt::New(); revNodalIndx2D=DataArrayInt::New(); - subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D); - const int *nodal2D=_mesh2D->getNodalConnectivity()->getConstPointer(); - const int *nodal2DIndx=_mesh2D->getNodalConnectivityIndex()->getConstPointer(); - const int *revNodal2DPtr=revNodal2D->getConstPointer(); - const int *revNodalIndx2DPtr=revNodalIndx2D->getConstPointer(); - const int *descP=desc->getConstPointer(); - const int *descIndxP=descIndx->getConstPointer(); - const int *revDescP=revDesc->getConstPointer(); - const int *revDescIndxP=revDescIndx->getConstPointer(); - // - int nbOf2DCells=_mesh2D->getNumberOfCells(); - for(int i=0;i nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]); - try - { - idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n"; - ostr << e.what(); - throw INTERP_KERNEL::Exception(ostr.str().c_str()); - } - build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id); - } - // - revNodal2D->decrRef(); - revNodalIndx2D->decrRef(); - subMesh->decrRef(); - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); -} - -void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - std::vector tinyInfo1; - std::vector ls1; - std::vector ls3; - _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1); - std::vector tinyInfo2; - std::vector ls2; - std::vector ls4; - _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2); - tinyInfo.clear(); littleStrings.clear(); - tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end()); - littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end()); - tinyInfo.push_back(_cell_2D_id); - tinyInfo.push_back((int)tinyInfo1.size()); - tinyInfo.push_back(_mesh3D_ids->getNbOfElems()); - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); -} - -void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - std::size_t sz=tinyInfo.size(); - int sz1=tinyInfo[sz-2]; - std::vector ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); - std::vector ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); - MEDCouplingUMesh *um=MEDCouplingUMesh::New(); - DataArrayInt *a1tmp=DataArrayInt::New(); - DataArrayDouble *a2tmp=DataArrayDouble::New(); - int la1=0,la2=0; - std::vector ls1,ls2; - um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); - la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); - a1tmp->decrRef(); a2tmp->decrRef(); - a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); - um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2); - la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); - a1tmp->decrRef(); a2tmp->decrRef(); - um->decrRef(); - // - a1->alloc(la1+tinyInfo[sz-1],1); - a2->alloc(la2,1); - littleStrings.resize(ls1.size()+ls2.size()+2); -} - -void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); a2=DataArrayDouble::New(); - DataArrayInt *a1_1=0,*a1_2=0; - DataArrayDouble *a2_1=0,*a2_2=0; - _mesh2D->serialize(a1_1,a2_1); - _mesh1D->serialize(a1_2,a2_2); - a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1); - int *ptri=a1->getPointer(); - ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri); - a1_1->decrRef(); - ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri); - a1_2->decrRef(); - std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri); - a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1); - double *ptrd=a2->getPointer(); - ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd); - a2_1->decrRef(); - std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd); - a2_2->decrRef(); -} - -void MEDCouplingExtrudedMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) -{ - setName(littleStrings[littleStrings.size()-2]); - setDescription(littleStrings.back()); - std::size_t sz=tinyInfo.size(); - int sz1=tinyInfo[sz-2]; - _cell_2D_id=tinyInfo[sz-3]; - std::vector ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); - std::vector ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); - DataArrayInt *a1tmp=DataArrayInt::New(); - DataArrayDouble *a2tmp=DataArrayDouble::New(); - const int *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - _mesh2D=MEDCouplingUMesh::New(); - std::vector ls1,ls2; - _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); - std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); - std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); - a2Ptr+=a2tmp->getNbOfElems(); - a1Ptr+=a1tmp->getNbOfElems(); - ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size()); - std::vector d1(1); - _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2); - a1tmp->decrRef(); a2tmp->decrRef(); - // - ls2.clear(); - ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2); - _mesh1D=MEDCouplingUMesh::New(); - a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); - _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1); - std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); - std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); - a1Ptr+=a1tmp->getNbOfElems(); - _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2); - a1tmp->decrRef(); a2tmp->decrRef(); - // - _mesh3D_ids=DataArrayInt::New(); - int szIds=(int)std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems()); - _mesh3D_ids->alloc(szIds,1); - std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer()); -} - -void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - m->writeVTKLL(ofs,cellData,pointData,byteData); -} - -void MEDCouplingExtrudedMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingExtrudedMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; -} - -std::string MEDCouplingExtrudedMesh::getVTKFileExtension() const -{ - return _mesh2D->getVTKFileExtension(); -} - -std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const -{ - return _mesh2D->getVTKDataSetType(); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx deleted file mode 100644 index c72f42cf4..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGEXTRUDEDMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGEXTRUDEDMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMesh.hxx" - -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - class MEDCouplingExtrudedMesh : public MEDCouplingMesh - { - public: - MEDCOUPLING_EXPORT static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId); - MEDCOUPLING_EXPORT static MEDCouplingExtrudedMesh *New(); - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCouplingExtrudedMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - MEDCOUPLING_EXPORT std::set getAllGeoTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT MEDCouplingUMesh *getMesh2D() const { return _mesh2D; } - MEDCOUPLING_EXPORT MEDCouplingUMesh *getMesh1D() const { return _mesh1D; } - MEDCOUPLING_EXPORT DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; } - MEDCOUPLING_EXPORT MEDCouplingUMesh *build3DUnstructuredMesh() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT static int FindCorrespCellByNodalConn(const std::vector& nodalConnec, - const int *revNodalPtr, const int *revNodalIndxPtr); - MEDCOUPLING_EXPORT static void Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, - MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v); - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - //Serialization unserialisation - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId); - MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy); - MEDCouplingExtrudedMesh(); - void computeExtrusion(const MEDCouplingUMesh *mesh3D); - void computeExtrusionAlg(const MEDCouplingUMesh *mesh3D); - void build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, - const int *desc3D, const int *descIndx3D, - const int *revDesc3D, const int *revDescIndx3D, - bool computeMesh1D); - int findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector& connSorted, - const int *desc3D, const int *descIndx3D, - const int *conn2D, const int *conn2DIndx); - void computeBaryCenterOfFace(const std::vector& nodalConnec, int lev1DId); - ~MEDCouplingExtrudedMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - private: - MEDCouplingUMesh *_mesh2D; - MEDCouplingUMesh *_mesh1D; - //! New to old 3D cell Ids Array - DataArrayInt *_mesh3D_ids; - int _cell_2D_id; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingField.cxx b/medtool/src/MEDCoupling/MEDCouplingField.cxx deleted file mode 100644 index cb69a6de7..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingField.cxx +++ /dev/null @@ -1,635 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingField.hxx" -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingFieldDiscretization.hxx" - -#include - -using namespace ParaMEDMEM; - -bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualIfNotWhy : other instance is NULL !"); - std::ostringstream oss; oss.precision(15); - if(_name!=other->_name) - { - oss << "Field names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; - reason=oss.str(); - return false; - } - if(_desc!=other->_desc) - { - oss << "Field descriptions differ : this description = \"" << _desc << "\" and other description = \"" << other->_desc << "\" !"; - reason=oss.str(); - return false; - } - if(_nature!=other->_nature) - { - oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::GetRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::GetRepr(other->_nature) << "\" !"; - reason=oss.str(); - return false; - } - if(!_type->isEqualIfNotWhy(other->_type,valsPrec,reason)) - { - reason.insert(0,"Spatial discretizations differ :"); - return false; - } - if(_mesh==0 && other->_mesh==0) - return true; - if(_mesh==0 || other->_mesh==0) - { - reason="Only one field between the two this and other has its underlying mesh defined !"; - return false; - } - if(_mesh==other->_mesh) - return true; - bool ret=_mesh->isEqualIfNotWhy(other->_mesh,meshPrec,reason); - if(!ret) - reason.insert(0,"Underlying meshes of fields differ for the following reason : "); - return ret; -} - -/*! - * Checks if \a this and another MEDCouplingField are fully equal. - * \param [in] other - the field to compare with \a this one. - * \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh. - * \param [in] valsPrec - precision used to compare field values. - * \return bool - \c true if the two fields are equal, \c false else. - * \throw If \a other is NULL. - */ -bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const -{ - std::string tmp; - return isEqualIfNotWhy(other,meshPrec,valsPrec,tmp); -} - -/*! - * Checks if \a this and another MEDCouplingField are equal. The textual - * information like names etc. is not considered. - * \param [in] other - the field to compare with \a this one. - * \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh. - * \param [in] valsPrec - precision used to compare field values. - * \return bool - \c true if the two fields are equal, \c false else. - * \throw If \a other is NULL. - * \throw If the spatial discretization of \a this field is NULL. - */ -bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : input field is NULL !"); - if(!_type) - throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : spatial discretization of this is NULL !"); - if(!_type->isEqualWithoutConsideringStr(other->_type,valsPrec)) - return false; - if(_nature!=other->_nature) - return false; - if(_mesh==0 && other->_mesh==0) - return true; - if(_mesh==0 || other->_mesh==0) - return false; - if(_mesh==other->_mesh) - return true; - return _mesh->isEqualWithoutConsideringStr(other->_mesh,meshPrec); -} - -/*! - * This method states if 'this' and 'other' are compatibles each other before performing any treatment. - * This method is good for methods like : mergeFields. - * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. - */ -bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingField::areCompatibleForMerge : input field is NULL !"); - if(!_type->isEqual(other->_type,1.)) - return false; - if(_nature!=other->_nature) - return false; - if(_mesh==other->_mesh) - return true; - return _mesh->areCompatibleForMerge(other->_mesh); -} - -/*! - * This method is more strict than MEDCouplingField::areCompatibleForMerge method. - * This method is used for operation on fields to operate a first check before attempting operation. - */ -bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !"); - if(!_type->isEqual(other->_type,1.e-12)) - return false; - if(_nature!=other->_nature) - return false; - return _mesh==other->_mesh; -} - -/*! - * This method is less strict than MEDCouplingField::areStrictlyCompatible method. - * The difference is that the nature is not checked. - * This method is used for multiplication and division on fields to operate a first check before attempting operation. - */ -bool MEDCouplingField::areStrictlyCompatibleForMulDiv(const MEDCouplingField *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !"); - if(!_type->isEqual(other->_type,1.e-12)) - return false; - return _mesh==other->_mesh; -} - - -void MEDCouplingField::updateTime() const -{ - if(_mesh) - updateTimeWith(*_mesh); - if(_type) - updateTimeWith(*_type); -} - -std::size_t MEDCouplingField::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret=0; - ret+=_name.capacity(); - ret+=_desc.capacity(); - return ret; -} - -std::vector MEDCouplingField::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_mesh); - ret.push_back((const MEDCouplingFieldDiscretization *)_type); - return ret; -} - -/*! - * Returns a type of \ref MEDCouplingSpatialDisc "spatial discretization" of \a this - * field in terms of enum ParaMEDMEM::TypeOfField. - * \return ParaMEDMEM::TypeOfField - the type of \a this field. - * \throw If the geometric type is empty. - */ -TypeOfField MEDCouplingField::getTypeOfField() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingField::getTypeOfField : spatial discretization is null !"); - return _type->getEnum(); -} - -/*! - * Returns the nature of \a this field. This information is very important during - * interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. - * In other context than the two mentioned above, this attribute is unimportant. This - * attribute is not stored in the MED file. - * For more information of the semantics and the influence of this attribute to the - * result of interpolation, see - * - \ref NatureOfField - * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature" - */ -NatureOfField MEDCouplingField::getNature() const -{ - return _nature; -} - -/*! - * Sets the nature of \a this field. This information is very important during - * interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. - * In other context than the two mentioned above, this attribute is unimportant. This - * attribute is not stored in the MED file. - * For more information of the semantics and the influence of this attribute to the - * result of interpolation, see - * - \ref NatureOfField - * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature" - * - * \param [in] nat - the nature of \a this field. - * \throw If \a nat has an invalid value. - */ -void MEDCouplingField::setNature(NatureOfField nat) -{ - MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized - _nature=nat; -} - -/*! - * Returns coordinates of field location points that depend on - * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field. - * - For a field on nodes, returns coordinates of nodes. - * - For a field on cells, returns barycenters of cells. - * - For a field on gauss points, returns coordinates of gauss points. - * - * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - */ -DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No mesh set !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No spatial discretization set !"); - return _type->getLocalizationOfDiscValues(_mesh); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh whose - * cells are constructed around field location points (getLocalizationOfDiscr()) of \a this - * field. (In case of a field on cells, the dual mesh coincides with the underlying mesh).
- * For 1D cells, the returned field contains lengths.
- * For 2D cells, the returned field contains areas.
- * For 3D cells, the returned field contains volumes. - * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell - * orientation, i.e. the volume is always positive. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. - * The caller is to delete this array using decrRef() as - * it is no more needed. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the spatial discretization of \a this field is not well defined. - */ - -MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : No spatial discretization set !"); - return _type->getMeasureField(_mesh,isAbs); -} - -/*! - * Sets the underlying mesh of \a this field. - * For examples of field construction, see \ref MEDCouplingFirstSteps3. - * \param [in] mesh - the new underlying mesh. - */ -void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) -{ - if(mesh!=_mesh) - { - if(_mesh) - _mesh->decrRef(); - _mesh=mesh; - declareAsNew(); - if(_mesh) - { - _mesh->incrRef(); - updateTimeWith(*_mesh); - } - } -} - -/*! - * Sets localization of Gauss points for a given geometric type of cell. - * \param [in] type - the geometric type of cell for which the Gauss localization is set. - * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector - * must be \c nbOfNodesPerCell * \c dimOfType. - * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector - * must be _wg_.size() * \c dimOfType. - * \param [in] wg - the weights of Gauss points. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \throw If size of any vector do not match the \a type. - */ -void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnType method !"); - _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg); -} - -/*! - * Sets localization of Gauss points for given cells specified by their ids. - * \param [in] begin - an array of cell ids of interest. - * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. - * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector - * must be \c nbOfNodesPerCell * \c dimOfType. - * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector - * must be _wg_.size() * \c dimOfType. - * \param [in] wg - the weights of Gauss points. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \throw If size of any vector do not match the type of cell # \a begin[0]. - * \throw If type of any cell in \a begin differs from that of cell # \a begin[0]. - * \throw If the range [_begin_,_end_) is empty. - */ -void MEDCouplingField::setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnCells method !"); - _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg); -} - -/*! - * Clears data on Gauss points localization. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL. - */ -void MEDCouplingField::clearGaussLocalizations() -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !"); - _type->clearGaussLocalizations(); -} - -/*! - * Returns a reference to the Gauss localization object by its id. - * \warning This method is not const, so the returned object can be modified without any - * problem. - * \param [in] locId - the id of the Gauss localization object of interest. - * It must be in range 0 <= locId < getNbOfGaussLocalization() . - * \return \ref ParaMEDMEM::MEDCouplingGaussLocalization "MEDCouplingGaussLocalization" & - the - * Gauss localization object. - * \throw If \a this field is not on Gauss points. - * \throw If \a locId is not within the valid range. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); - return _type->getGaussLocalization(locId); -} - -/*! - * Returns an id of the Gauss localization object corresponding to a given cell type. - * \param [in] type - the cell type of interest. - * \return int - the id of the Gauss localization object. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If no Gauss localization object found for the given cell \a type. - * \throw If more than one Gauss localization object found for the given cell \a type. - */ -int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneType method !"); - return _type->getGaussLocalizationIdOfOneType(type); -} - -/*! - * Returns ids of Gauss localization objects corresponding to a given cell type. - * \param [in] type - the cell type of interest. - * \return std::set - ids of the Gauss localization object. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL - */ -std::set MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !"); - return _type->getGaussLocalizationIdsOfOneType(type); -} - -/*! - * Returns number of Gauss localization objects available. Implicitly all ids in - * [0,getNbOfGaussLocalization()) are valid Gauss localization ids. - * \return int - the number of available Gauss localization objects. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL. - */ -int MEDCouplingField::getNbOfGaussLocalization() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !"); - return _type->getNbOfGaussLocalization(); -} - -/*! - * Returns an id of the Gauss localization object corresponding to a type of a given cell. - * \param [in] cellId - an id of the cell of interest. - * \return int - the id of the Gauss localization object. - * \throw If \a this field is not on Gauss points. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If no Gauss localization object found for the given cell. - */ -int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !"); - return _type->getGaussLocalizationIdOfOneCell(cellId); -} - -/*! - * Returns ids of cells that share the same Gauss localization given by its id. - * \param [in] locId - the id of the Gauss localization object of interest. - * It must be in range 0 <= locId < getNbOfGaussLocalization() . - * \param [in,out] cellIds - a vector returning ids of found cells. It is cleared before - * filling in. It remains empty if no cells found. - * \throw If \a this field is not on Gauss points. - * \throw If \a locId is not within the valid range. - * \throw If the spatial discretization of \a this field is NULL. - */ -void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const -{ - cellIds.clear(); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !"); - _type->getCellIdsHavingGaussLocalization(locId,cellIds); -} - -/*! - * Returns a reference to the Gauss localization object by its id. - * \warning This method is const, so the returned object is not apt for modification. - * \param [in] locId - the id of the Gauss localization object of interest. - * It must be in range 0 <= locId < getNbOfGaussLocalization() . - * \return const \ref MEDCouplingGaussLocalization & - the Gauss localization object. - * \throw If \a this field is not on Gauss points. - * \throw If \a locId is not within the valid range. - * \throw If the spatial discretization of \a this field is NULL. - */ -const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); - return _type->getGaussLocalization(locId); -} - -MEDCouplingField::~MEDCouplingField() -{ - if(_mesh) - _mesh->decrRef(); -} - -MEDCouplingField::MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature):_nature(nature),_mesh(0),_type(type) -{ -} - -MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0),_type(MEDCouplingFieldDiscretization::New(type)) -{ -} - -MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature), - _mesh(0),_type(0) -{ - if(other._mesh) - { - _mesh=other._mesh; - _mesh->incrRef(); - } - if(deepCopy) - _type=other._type->clone(); - else - _type=other._type; -} - -/*! - * Returns a new MEDCouplingMesh constituted by some cells of the underlying mesh of \a - * this field, and returns ids of entities (nodes, cells, Gauss points) lying on the - * specified cells. The cells to include to the result mesh are specified by an array of - * cell ids. The new mesh shares the coordinates array with the underlying mesh. - * \param [in] start - an array of cell ids to include to the result mesh. - * \param [in] end - specifies the end of the array \a start, so that - * the last value of \a start is \a end[ -1 ]. - * \param [out] di - a new instance of DataArrayInt holding the ids of entities (nodes, - * cells, Gauss points). The caller is to delete this array using decrRef() as it - * is no more needed. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \sa buildSubMeshDataRange() - */ -MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshData method !"); - return _type->buildSubMeshData(_mesh,start,end,di); -} - -/*! - * This method returns a submesh of 'mesh' instance constituting cell ids defined by a range given by the 3 following inputs \a begin, \a end and \a step. - * - * \param [out] beginOut Valid only if \a di is NULL - * \param [out] endOut Valid only if \a di is NULL - * \param [out] stepOut Valid only if \a di is NULL - * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. - * - * \sa MEDCouplingField::buildSubMeshData - */ -MEDCouplingMesh *MEDCouplingField::buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshDataRange method !"); - return _type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,di); -} - -/*! - * This method returns tuples ids implied by the mesh selection of the cell ids contained in array defined as an interval [start;end). - * \return a newly allocated DataArrayInt instance containing tuples ids. - */ -DataArrayInt *MEDCouplingField::computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call computeTupleIdsToSelectFromCellIds method !"); - return _type->computeTupleIdsToSelectFromCellIds(_mesh,startCellIds,endCellIds); -} - -/*! - * Returns number of tuples expected regarding the spatial discretization of \a this - * field and number of entities in the underlying mesh. This method behaves exactly as MEDCouplingFieldDouble::getNumberOfTuples. - * \return int - the number of expected tuples. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - */ -int MEDCouplingField::getNumberOfTuplesExpected() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfTuplesExpected method !"); - if(_mesh) - return _type->getNumberOfTuples(_mesh); - else - throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpected : Empty mesh !"); -} - -void MEDCouplingField::setDiscretization(MEDCouplingFieldDiscretization *newDisc) -{ - bool needUpdate=(const MEDCouplingFieldDiscretization *)_type!=newDisc; - _type=newDisc; - if(newDisc) - newDisc->incrRef(); - if(needUpdate) - declareAsNew(); -} - -/*! - * Returns number of mesh entities in the underlying mesh of \a this field regarding the - * spatial discretization. - * \return int - the number of mesh entities porting the field values. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - */ -int MEDCouplingField::getNumberOfMeshPlacesExpected() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfMeshPlacesExpected method !"); - if(_mesh) - return _type->getNumberOfMeshPlaces(_mesh); - else - throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfMeshPlacesExpected : Empty mesh !"); -} - -/*! - * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason). - */ -void MEDCouplingField::copyTinyStringsFrom(const MEDCouplingField *other) -{ - if(other) - { - setName(other->_name); - setDescription(other->_desc); - } -} - -/*! - * This method computes the number of tuples a DataArrayDouble instance should have to build a correct MEDCouplingFieldDouble instance starting from a - * submesh of a virtual mesh on which a substraction per type had been applied regarding the spatial discretization in \a this. - * - * For spatial discretization \b not equal to ON_GAUSS_NE this method will make the hypothesis that any positive entity id in \a code \a idsPerType is valid. - * So in those cases attribute \a _mesh of \a this is ignored. - * - * For spatial discretization equal to ON_GAUSS_NE \a _mesh attribute will be taken into account. - * - * The input code is those implemented in MEDCouplingUMesh::splitProfilePerType. - * - * \param [in] code - a code with format described above. - * \param [in] idsPerType - a list of subparts - * \throw If \a this has no spatial discretization set. - * \throw If input code point to invalid zones in spatial discretization. - * \throw If spatial discretization in \a this requires a mesh and those mesh is invalid (null,...) - */ -int MEDCouplingField::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - const MEDCouplingFieldDiscretization *t(_type); - if(!t) - throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpectedRegardingCode : no spatial discretization set !"); - return t->getNumberOfTuplesExpectedRegardingCode(code,idsPerType); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingField.hxx b/medtool/src/MEDCoupling/MEDCouplingField.hxx deleted file mode 100644 index 9154f56c2..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingField.hxx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGFIELD_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELD_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingNatureOfField.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDouble; - class MEDCouplingMesh; - class MEDCouplingFieldDouble; - class MEDCouplingGaussLocalization; - - class MEDCouplingField : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; - MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMulDiv(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingField *other); - MEDCOUPLING_EXPORT void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; } - MEDCOUPLING_EXPORT ParaMEDMEM::MEDCouplingMesh *getMesh() { return const_cast(_mesh); } - MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } - MEDCOUPLING_EXPORT std::string getDescription() const { return _desc; } - MEDCOUPLING_EXPORT void setDescription(const std::string& desc) { _desc=desc; } - MEDCOUPLING_EXPORT std::string getName() const { return _name; } - MEDCOUPLING_EXPORT TypeOfField getTypeOfField() const; - MEDCOUPLING_EXPORT NatureOfField getNature() const; - MEDCOUPLING_EXPORT virtual void setNature(NatureOfField nat); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscr() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDiscretization *getDiscretization() const { return _type; } - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *getDiscretization() { return _type; } - MEDCOUPLING_EXPORT void setDiscretization(MEDCouplingFieldDiscretization *newDisc); - MEDCOUPLING_EXPORT int getNumberOfTuplesExpected() const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlacesExpected() const; - // Gauss point specific methods - MEDCOUPLING_EXPORT void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void clearGaussLocalizations(); - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization& getGaussLocalization(int locId); - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT int getNbOfGaussLocalization() const; - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneCell(int cellId) const; - MEDCOUPLING_EXPORT void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const; - MEDCOUPLING_EXPORT const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // for MED file RW - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - protected: - MEDCOUPLING_EXPORT MEDCouplingField(TypeOfField type); - MEDCOUPLING_EXPORT MEDCouplingField(const MEDCouplingField& other, bool deepCopy=true); - MEDCOUPLING_EXPORT MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature=NoNature); - MEDCOUPLING_EXPORT virtual ~MEDCouplingField(); - protected: - std::string _name; - std::string _desc; - NatureOfField _nature; - const MEDCouplingMesh *_mesh; - MEDCouplingAutoRefCountObjectPtr _type; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx deleted file mode 100644 index 0be106c75..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ /dev/null @@ -1,3061 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "CellModel.hxx" -#include "InterpolationUtils.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "InterpKernelGaussCoords.hxx" -#include "InterpKernelMatrixTools.hxx" - -#include -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -const double MEDCouplingFieldDiscretization::DFLT_PRECISION=1.e-12; - -const char MEDCouplingFieldDiscretizationP0::REPR[]="P0"; - -const TypeOfField MEDCouplingFieldDiscretizationP0::TYPE=ON_CELLS; - -const char MEDCouplingFieldDiscretizationP1::REPR[]="P1"; - -const TypeOfField MEDCouplingFieldDiscretizationP1::TYPE=ON_NODES; - -const int MEDCouplingFieldDiscretizationPerCell::DFT_INVALID_LOCID_VALUE=-1; - -const char MEDCouplingFieldDiscretizationGauss::REPR[]="GAUSS"; - -const TypeOfField MEDCouplingFieldDiscretizationGauss::TYPE=ON_GAUSS_PT; - -const char MEDCouplingFieldDiscretizationGaussNE::REPR[]="GSSNE"; - -const TypeOfField MEDCouplingFieldDiscretizationGaussNE::TYPE=ON_GAUSS_NE; - -const char MEDCouplingFieldDiscretizationKriging::REPR[]="KRIGING"; - -const TypeOfField MEDCouplingFieldDiscretizationKriging::TYPE=ON_NODES_KR; - -// doc is here http://www.code-aster.org/V2/doc/default/fr/man_r/r3/r3.01.01.pdf -const double MEDCouplingFieldDiscretizationGaussNE::FGP_POINT1[1]={0.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG2[2]={1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG3[3]={0.5555555555555556,0.8888888888888888,0.5555555555555556}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG4[4]={0.347854845137454,0.347854845137454,0.652145154862546,0.652145154862546}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_TRI3[3]={0.16666666666666666,0.16666666666666666,0.16666666666666666}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_TRI6[6]={0.0549758718227661,0.0549758718227661,0.0549758718227661,0.11169079483905,0.11169079483905,0.11169079483905}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_TRI7[7]={0.062969590272413,0.062969590272413,0.062969590272413,0.066197076394253,0.066197076394253,0.066197076394253,0.1125}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD4[4]={1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD9[9]={0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_TETRA4[4]={0.041666666666666664,0.041666666666666664,0.041666666666666664,0.041666666666666664}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_TETRA10[10]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA6[6]={0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA15[15]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA20[20]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA27[27]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA5[5]={0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA13[13]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG2[2]={-1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG3[3]={-1.,1.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG4[4]={-1.,1.,-0.3333333333333333,0.3333333333333333}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_TRI3[6]={0.,0.,1.,0.,0.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_TRI6[12]={0.,0.,1.,0.,0.,1.,0.5,0.,0.5,0.5,0.,0.5}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_TRI7[14]={0.,0.,1.,0.,0.,1.,0.5,0.,0.5,0.5,0.,0.5,0.3333333333333333,0.3333333333333333}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_QUAD4[8]={-1.,-1.,1.,-1.,1.,1.,-1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_QUAD8[16]={-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_QUAD9[18]={-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_TETRA4[12]={0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_TETRA10[30]={0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.5,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_PENTA6[18]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_PENTA15[45]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.,-1.,0.5,0.5,-1.,0.,0.5,-1.,0.5,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA8[24]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA20[60]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA27[81]={-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA5[15]={1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,-1.,0.,0.,0.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA13[39]={1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,-0.5,0.,-0.5,-0.5,0.,-0.5,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.,-0.5,0.5,-0.5,0.,0.5,0.,0.5,0.5}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG2[2]={0.577350269189626,-0.577350269189626}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG3[3]={-0.774596669241,0.,0.774596669241}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG4[4]={0.339981043584856,-0.339981043584856,0.861136311594053,-0.861136311594053}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI3[6]={0.16666666666666667,0.16666666666666667,0.6666666666666667,0.16666666666666667,0.16666666666666667,0.6666666666666667}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI6[12]={0.091576213509771,0.091576213509771,0.816847572980458,0.091576213509771,0.091576213509771,0.816847572980458,0.445948490915965,0.10810301816807,0.445948490915965,0.445948490915965,0.10810301816807,0.445948490915965}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI7[14]={0.3333333333333333,0.3333333333333333,0.470142064105115,0.470142064105115,0.05971587178977,0.470142064105115,0.470142064105115,0.05971587178977,0.101286507323456,0.101286507323456,0.797426985353088,0.101286507323456,0.101286507323456,0.797426985353088}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD4[8]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD8[16]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD9[18]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TETRA4[12]={0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.1381966011250105}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TETRA10[30]={0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.5,0.,0.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PENTA6[18]={-0.5773502691896258,0.5,0.5,-0.5773502691896258,0.,0.5,-0.5773502691896258,0.5,0.,0.5773502691896258,0.5,0.5,0.5773502691896258,0.,0.5,0.5773502691896258,0.5,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PENTA15[45]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.,-1.,0.5,0.5,-1.,0.,0.5,-1.,0.5,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA8[24]={-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA20[60]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA27[81]={-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA5[15]={0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA13[39]={1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,0.999999999999,0.5,-0.5,0.,-0.5,-0.5,0.,-0.5,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.,-0.5,0.5,-0.5,0.,0.5,0.,0.5,0.5};//to check 0.99999... to avoid nan ! on node #4 of PYRA13 - -MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION) -{ -} - -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField type) -{ - switch(type) - { - case MEDCouplingFieldDiscretizationP0::TYPE: - return new MEDCouplingFieldDiscretizationP0; - case MEDCouplingFieldDiscretizationP1::TYPE: - return new MEDCouplingFieldDiscretizationP1; - case MEDCouplingFieldDiscretizationGauss::TYPE: - return new MEDCouplingFieldDiscretizationGauss; - case MEDCouplingFieldDiscretizationGaussNE::TYPE: - return new MEDCouplingFieldDiscretizationGaussNE; - case MEDCouplingFieldDiscretizationKriging::TYPE: - return new MEDCouplingFieldDiscretizationKriging; - default: - throw INTERP_KERNEL::Exception("Choosen discretization is not implemented yet."); - } -} - -TypeOfField MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(const std::string& repr) -{ - if(repr==MEDCouplingFieldDiscretizationP0::REPR) - return MEDCouplingFieldDiscretizationP0::TYPE; - if(repr==MEDCouplingFieldDiscretizationP1::REPR) - return MEDCouplingFieldDiscretizationP1::TYPE; - if(repr==MEDCouplingFieldDiscretizationGauss::REPR) - return MEDCouplingFieldDiscretizationGauss::TYPE; - if(repr==MEDCouplingFieldDiscretizationGaussNE::REPR) - return MEDCouplingFieldDiscretizationGaussNE::TYPE; - if(repr==MEDCouplingFieldDiscretizationKriging::REPR) - return MEDCouplingFieldDiscretizationKriging::TYPE; - throw INTERP_KERNEL::Exception("Representation does not match with any field discretization !"); -} - -std::string MEDCouplingFieldDiscretization::GetTypeOfFieldRepr(TypeOfField type) -{ - if(type==MEDCouplingFieldDiscretizationP0::TYPE) - return MEDCouplingFieldDiscretizationP0::REPR; - if(type==MEDCouplingFieldDiscretizationP1::TYPE) - return MEDCouplingFieldDiscretizationP1::REPR; - if(type==MEDCouplingFieldDiscretizationGauss::TYPE) - return MEDCouplingFieldDiscretizationGauss::REPR; - if(type==MEDCouplingFieldDiscretizationGaussNE::TYPE) - return MEDCouplingFieldDiscretizationGaussNE::REPR; - if(type==MEDCouplingFieldDiscretizationKriging::TYPE) - return MEDCouplingFieldDiscretizationKriging::REPR; - throw INTERP_KERNEL::Exception("GetTypeOfFieldRepr : Representation does not match with any field discretization !"); -} - -bool MEDCouplingFieldDiscretization::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const -{ - std::string reason; - return isEqualIfNotWhy(other,eps,reason); -} - -bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const -{ - return isEqual(other,eps); -} - -/*! - * This method is an alias of MEDCouplingFieldDiscretization::clone. It is only here for coherency with all the remaining of MEDCoupling. - * \sa MEDCouplingFieldDiscretization::clone. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::deepCpy() const -{ - return clone(); -} - -/*! - * For all field discretization excepted GaussPts the [ \a startCellIds, \a endCellIds ) has no impact on the cloned instance. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePart(const int *startCellIds, const int *endCellIds) const -{ - return clone(); -} - -/*! - * For all field discretization excepted GaussPts the slice( \a beginCellId, \a endCellIds, \a stepCellId ) has no impact on the cloned instance. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const -{ - return clone(); -} - -/*! - * Excepted for MEDCouplingFieldDiscretizationPerCell no underlying TimeLabel object : nothing to do in generally. - */ -void MEDCouplingFieldDiscretization::updateTime() const -{ -} - -std::size_t MEDCouplingFieldDiscretization::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDCouplingFieldDiscretization::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * Computes normL1 of DataArrayDouble instance arr. - * @param res output parameter expected to be of size arr->getNumberOfComponents(); - * @throw when the field discretization fails on getMeasure fields (gauss points for example) - */ -void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const -{ - MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,true); - int nbOfCompo=arr->getNumberOfComponents(); - int nbOfElems=getNumberOfTuples(mesh); - std::fill(res,res+nbOfCompo,0.); - const double *arrPtr=arr->getConstPointer(); - const double *volPtr=vol->getArray()->getConstPointer(); - double deno=0.; - for(int i=0;i(),1./deno)); -} - -/*! - * Computes normL2 of DataArrayDouble instance arr. - * @param res output parameter expected to be of size arr->getNumberOfComponents(); - * @throw when the field discretization fails on getMeasure fields (gauss points for example) - */ -void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const -{ - MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,true); - int nbOfCompo=arr->getNumberOfComponents(); - int nbOfElems=getNumberOfTuples(mesh); - std::fill(res,res+nbOfCompo,0.); - const double *arrPtr=arr->getConstPointer(); - const double *volPtr=vol->getArray()->getConstPointer(); - double deno=0.; - for(int i=0;i(),1./deno)); - std::transform(res,res+nbOfCompo,res,std::ptr_fun(std::sqrt)); -} - -/*! - * Computes integral of DataArrayDouble instance arr. - * @param res output parameter expected to be of size arr->getNumberOfComponents(); - * @throw when the field discretization fails on getMeasure fields (gauss points for example) - */ -void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::integral : mesh is NULL !"); - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::integral : input array is NULL !"); - MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,isWAbs); - int nbOfCompo=arr->getNumberOfComponents(); - int nbOfElems=getNumberOfTuples(mesh); - if(nbOfElems!=arr->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretization::integral : field is not correct ! number of tuples in array is " << arr->getNumberOfTuples(); - oss << " whereas number of tuples expected is " << nbOfElems << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::fill(res,res+nbOfCompo,0.); - const double *arrPtr=arr->getConstPointer(); - const double *volPtr=vol->getArray()->getConstPointer(); - INTERP_KERNEL::AutoPtr tmp=new double[nbOfCompo]; - for (int i=0;i(),volPtr[i])); - std::transform((double *)tmp,(double *)tmp+nbOfCompo,res,res,std::plus()); - } -} - -/*! - * This method is strictly equivalent to MEDCouplingFieldDiscretization::buildSubMeshData except that it is optimized for input defined as a range of cell ids. - * - * \param [out] beginOut Valid only if \a di is NULL - * \param [out] endOut Valid only if \a di is NULL - * \param [out] stepOut Valid only if \a di is NULL - * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. - * - * \sa MEDCouplingFieldDiscretization::buildSubMeshData - */ -MEDCouplingMesh *MEDCouplingFieldDiscretization::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const -{ - MEDCouplingAutoRefCountObjectPtr da=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); - return buildSubMeshData(mesh,da->begin(),da->end(),di); -} - -void MEDCouplingFieldDiscretization::getSerializationIntArray(DataArrayInt *& arr) const -{ - arr=0; -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ -} - -void MEDCouplingFieldDiscretization::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr) -{ - arr=0; -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr) -{ -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::finishUnserialization(const std::vector& tinyInfo) -{ -} - -/*! - * This method is typically the first step of renumbering. The implementation is empty it is not a bug only gauss is impacted - * virtualy by this method. - */ -void MEDCouplingFieldDiscretization::renumberCells(const int *old2NewBg, bool check) -{ -} - -double MEDCouplingFieldDiscretization::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const -{ - throw INTERP_KERNEL::Exception("getIJK Invalid ! only for GaussPoint and GaussNE discretizations !"); -} - -void MEDCouplingFieldDiscretization::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::clearGaussLocalizations() -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -int MEDCouplingFieldDiscretization::getNbOfGaussLocalization() const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneCell(int cellId) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -std::set MEDCouplingFieldDiscretization::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const std::string& msg) -{ - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr : input array is NULL !"); - int oldNbOfElems=arr->getNumberOfTuples(); - int nbOfComp=arr->getNumberOfComponents(); - int newNbOfTuples=newNbOfEntity; - MEDCouplingAutoRefCountObjectPtr arrCpy=arr->deepCpy(); - const double *ptSrc=arrCpy->getConstPointer(); - arr->reAlloc(newNbOfTuples); - double *ptToFill=arr->getPointer(); - std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits::max()); - INTERP_KERNEL::AutoPtr tmp=new double[nbOfComp]; - for(int i=0;i=0)//if newNb<0 the node is considered as out. - { - if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to(),std::numeric_limits::max())) - ==ptToFill+(newNb+1)*nbOfComp) - std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp); - else - { - std::transform(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp,(double *)tmp,std::minus()); - std::transform((double *)tmp,((double *)tmp)+nbOfComp,(double *)tmp,std::ptr_fun(fabs)); - //if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp)) - if(*std::max_element((double *)tmp,((double *)tmp)+nbOfComp)>eps) - { - std::ostringstream oss; - oss << msg << " " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr - << " have been merged and " << msg << " field on them are different !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } -} - -void MEDCouplingFieldDiscretization::RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const std::string& msg) -{ - int nbOfComp=arr->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr arrCpy=arr->deepCpy(); - const double *ptSrc=arrCpy->getConstPointer(); - arr->reAlloc(new2OldSz); - double *ptToFill=arr->getPointer(); - for(int i=0;i(other); - bool ret=otherC!=0; - if(!ret) - reason="Spatial discrtization of this is ON_CELLS, which is not the case of other."; - return ret; -} - -int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuples : NULL input mesh !"); - return mesh->getNumberOfCells(); -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret=0; - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk; - } - return ret; -} - -int MEDCouplingFieldDiscretizationP0::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfMeshPlaces : NULL input mesh !"); - return mesh->getNumberOfCells(); -} - -DataArrayInt *MEDCouplingFieldDiscretizationP0::getOffsetArr(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getOffsetArr : NULL input mesh !"); - int nbOfTuples=mesh->getNumberOfCells(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples+1,1); - ret->iota(0); - return ret; -} - -void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::renumberArraysForCell : NULL input mesh !"); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); - for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) - { - if(*it) - (*it)->renumberInPlace(array); - } - if(check) - free(const_cast(array)); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationP0::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getLocalizationOfDiscValues : NULL input mesh !"); - return mesh->getBarycenterAndOwner(); -} - -void MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); - tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); - std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); - MEDCouplingAutoRefCountObjectPtr tmp2(tmp->deepCpy()); - cellRestriction=tmp.retn(); - trueTupleRestriction=tmp2.retn(); -} - -void MEDCouplingFieldDiscretizationP0::reprQuickOverview(std::ostream& stream) const -{ - stream << "P0 spatial discretization."; -} - -void MEDCouplingFieldDiscretizationP0::checkCompatibilityWithNature(NatureOfField nat) const -{ -} - -void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - if(!mesh || !da) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::checkCoherencyBetween : NULL input mesh or DataArray !"); - if(mesh->getNumberOfCells()!=da->getNumberOfTuples()) - { - std::ostringstream message; - message << "Field on cells invalid because there are " << mesh->getNumberOfCells(); - message << " cells in mesh and " << da->getNumberOfTuples() << " tuples in field !"; - throw INTERP_KERNEL::Exception(message.str().c_str()); - } -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getMeasureField : mesh instance specified is NULL !"); - return mesh->getMeasureField(isAbs); -} - -void MEDCouplingFieldDiscretizationP0::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getValueOn : NULL input mesh !"); - int id=mesh->getCellContainingPoint(loc,_precision); - if(id==-1) - throw INTERP_KERNEL::Exception("Specified point is detected outside of mesh : unable to apply P0::getValueOn !"); - arr->getTuple(id,res); -} - -void MEDCouplingFieldDiscretizationP0::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - const MEDCouplingCMesh *meshC=dynamic_cast(mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("P0::getValueOnPos is only accessible for structured meshes !"); - int id=meshC->getCellIdFromPos(i,j,k); - arr->getTuple(id,res); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationP0::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getValueOnMulti : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr eltsArr,eltsIndexArr; - mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,eltsArr,eltsIndexArr); - const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); - int spaceDim=mesh->getSpaceDimension(); - int nbOfComponents=arr->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfPoints,nbOfComponents); - double *ptToFill=ret->getPointer(); - for(int i=0;i=1) - arr->getTuple(elts[eltsIndex[i]],ptToFill); - else - { - std::ostringstream oss; oss << "Point #" << i << " with coordinates : ("; - std::copy(loc+i*spaceDim,loc+(i+1)*spaceDim,std::ostream_iterator(oss,", ")); - oss << ") detected outside mesh : unable to apply P0::getValueOnMulti ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret.retn(); -} - -/*! - * Nothing to do. It's not a bug. - */ -void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const -{ -} - -void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ - RenumberEntitiesFromO2NArr(epsOnVals,old2New,newSz,arr,"Cell"); -} - -void MEDCouplingFieldDiscretizationP0::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ - RenumberEntitiesFromN2OArr(new2old,newSz,arr,"Cell"); -} - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationP0::buildSubMeshData to return parameter \b di. - * Here for P0 it's very simple ! - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc((int)std::distance(startCellIds,endCellIds),1); - std::copy(startCellIds,endCellIds,ret->getPointer()); - return ret.retn(); -} - -/*! - * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). - * @param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh. - * Example : The first cell id of returned mesh has the (*di)[0] id in 'mesh' - * - * \sa MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshData : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); - MEDCouplingAutoRefCountObjectPtr diSafe=DataArrayInt::New(); - diSafe->alloc((int)std::distance(start,end),1); - std::copy(start,end,diSafe->getPointer()); - di=diSafe.retn(); - return ret.retn(); -} - -/*! - * This method is strictly equivalent to MEDCouplingFieldDiscretizationP0::buildSubMeshData except that it is optimized for input defined as a range of cell ids. - * - * \param [out] beginOut Valid only if \a di is NULL - * \param [out] endOut Valid only if \a di is NULL - * \param [out] stepOut Valid only if \a di is NULL - * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. - * - * \sa MEDCouplingFieldDiscretizationP0::buildSubMeshData - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); - di=0; beginOut=beginCellIds; endOut=endCellIds; stepOut=stepCellIds; - return ret.retn(); -} - -int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getNumberOfTuples : NULL input mesh !"); - return mesh->getNumberOfNodes(); -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret=0; - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk; - } - return ret; -} - -int MEDCouplingFieldDiscretizationOnNodes::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getNumberOfMeshPlaces : NULL input mesh !"); - return mesh->getNumberOfNodes(); -} - -/*! - * Nothing to do here. - */ -void MEDCouplingFieldDiscretizationOnNodes::renumberArraysForCell(const MEDCouplingMesh *, const std::vector& arrays, - const int *old2NewBg, bool check) -{ -} - -DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::getOffsetArr(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getOffsetArr : NULL input mesh !"); - int nbOfTuples=mesh->getNumberOfNodes(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples+1,1); - ret->iota(0); - return ret; -} - -DataArrayDouble *MEDCouplingFieldDiscretizationOnNodes::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getLocalizationOfDiscValues : NULL input mesh !"); - return mesh->getCoordinatesAndOwner(); -} - -void MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr ret1=mesh->getCellIdsFullyIncludedInNodeIds(tupleIdsBg,tupleIdsEnd); - const MEDCouplingUMesh *meshc=dynamic_cast(mesh); - if(!meshc) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds : trying to subpart field on nodes by node ids ! Your mesh has to be unstructured !"); - MEDCouplingAutoRefCountObjectPtr meshPart=static_cast(meshc->buildPartOfMySelf(ret1->begin(),ret1->end(),true)); - MEDCouplingAutoRefCountObjectPtr ret2=meshPart->computeFetchedNodeIds(); - cellRestriction=ret1.retn(); - trueTupleRestriction=ret2.retn(); -} - -void MEDCouplingFieldDiscretizationOnNodes::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - if(!mesh || !da) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::checkCoherencyBetween : NULL input mesh or DataArray !"); - if(mesh->getNumberOfNodes()!=da->getNumberOfTuples()) - { - std::ostringstream message; - message << "Field on nodes invalid because there are " << mesh->getNumberOfNodes(); - message << " nodes in mesh and " << da->getNumberOfTuples() << " tuples in field !"; - throw INTERP_KERNEL::Exception(message.str().c_str()); - } -} - -/*! - * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). - * @param di is an array returned that specifies entity ids (here nodes ids) in mesh 'mesh' of entity in returned submesh. - * Example : The first node id of returned mesh has the (*di)[0] id in 'mesh' - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::buildSubMeshData : NULL input mesh !"); - DataArrayInt *diTmp=0; - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartAndReduceNodes(start,end,diTmp); - MEDCouplingAutoRefCountObjectPtr diTmpSafe(diTmp); - MEDCouplingAutoRefCountObjectPtr di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); - di=di2.retn(); - return ret.retn(); -} - -/*! - * This method is strictly equivalent to MEDCouplingFieldDiscretizationNodes::buildSubMeshData except that it is optimized for input defined as a range of cell ids. - * - * \param [out] beginOut Valid only if \a di is NULL - * \param [out] endOut Valid only if \a di is NULL - * \param [out] stepOut Valid only if \a di is NULL - * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. - * - * \sa MEDCouplingFieldDiscretizationNodes::buildSubMeshData - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::buildSubMeshDataRange : NULL input mesh !"); - DataArrayInt *diTmp=0; - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,diTmp); - if(diTmp) - { - MEDCouplingAutoRefCountObjectPtr diTmpSafe(diTmp); - MEDCouplingAutoRefCountObjectPtr di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); - di=di2.retn(); - } - return ret.retn(); -} - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData to return parameter \b di. - * Here for P1 only nodes fetched by submesh of mesh[startCellIds:endCellIds) is returned ! - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::computeTupleIdsToSelectFromCellIds : NULL input mesh !"); - const MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr umesh2=static_cast(umesh->buildPartOfMySelf(startCellIds,endCellIds,true)); - return umesh2->computeFetchedNodeIds(); -} - -void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnNodes(double epsOnVals, const int *old2NewPtr, int newNbOfNodes, DataArrayDouble *arr) const -{ - RenumberEntitiesFromO2NArr(epsOnVals,old2NewPtr,newNbOfNodes,arr,"Node"); -} - -/*! - * Nothing to do it's not a bug. - */ -void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ -} - -/*! - * Nothing to do it's not a bug. - */ -void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ -} - -void MEDCouplingFieldDiscretizationOnNodes::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - const MEDCouplingCMesh *meshC=dynamic_cast(mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("OnNodes::getValueOnPos(i,j,k) is only accessible for structured meshes !"); - int id=meshC->getNodeIdFromPos(i,j,k); - arr->getTuple(id,res); -} - -TypeOfField MEDCouplingFieldDiscretizationP1::getEnum() const -{ - return TYPE; -} - -/*! - * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. - * - * \sa MEDCouplingFieldDiscretization::deepCpy. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationP1::clone() const -{ - return new MEDCouplingFieldDiscretizationP1; -} - -std::string MEDCouplingFieldDiscretizationP1::getStringRepr() const -{ - return std::string(REPR); -} - -const char *MEDCouplingFieldDiscretizationP1::getRepr() const -{ - return REPR; -} - -bool MEDCouplingFieldDiscretizationP1::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const -{ - if(!other) - { - reason="other spatial discretization is NULL, and this spatial discretization (P1) is defined."; - return false; - } - const MEDCouplingFieldDiscretizationP1 *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason="Spatial discrtization of this is ON_NODES, which is not the case of other."; - return ret; -} - -void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfField nat) const -{ - if(nat!=ConservativeVolumic) - throw INTERP_KERNEL::Exception("Invalid nature for P1 field : expected ConservativeVolumic !"); -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getMeasureField : mesh instance specified is NULL !"); - return mesh->getMeasureFieldOnNode(isAbs); -} - -void MEDCouplingFieldDiscretizationP1::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getValueOn : NULL input mesh !"); - int id=mesh->getCellContainingPoint(loc,_precision); - if(id==-1) - throw INTERP_KERNEL::Exception("Specified point is detected outside of mesh : unable to apply P1::getValueOn !"); - INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(id); - if(type!=INTERP_KERNEL::NORM_SEG2 && type!=INTERP_KERNEL::NORM_TRI3 && type!=INTERP_KERNEL::NORM_TETRA4) - throw INTERP_KERNEL::Exception("P1 getValueOn is not specified for not simplex cells !"); - getValueInCell(mesh,id,arr,loc,res); -} - -/*! - * This method localizes a point defined by 'loc' in a cell with id 'cellId' into mesh 'mesh'. - * The result is put into res expected to be of size at least arr->getNumberOfComponents() - */ -void MEDCouplingFieldDiscretizationP1::getValueInCell(const MEDCouplingMesh *mesh, int cellId, const DataArrayDouble *arr, const double *loc, double *res) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getValueInCell : NULL input mesh !"); - std::vector conn; - std::vector coo; - mesh->getNodeIdsOfCell(cellId,conn); - for(std::vector::const_iterator iter=conn.begin();iter!=conn.end();iter++) - mesh->getCoordinatesOfNode(*iter,coo); - int spaceDim=mesh->getSpaceDimension(); - std::size_t nbOfNodes=conn.size(); - std::vector vec(nbOfNodes); - for(std::size_t i=0;i tmp=new double[nbOfNodes]; - INTERP_KERNEL::barycentric_coords(vec,loc,tmp); - int sz=arr->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp2=new double[sz]; - std::fill(res,res+sz,0.); - for(std::size_t i=0;igetTuple(conn[i],(double *)tmp2); - std::transform((double *)tmp2,((double *)tmp2)+sz,(double *)tmp2,std::bind2nd(std::multiplies(),tmp[i])); - std::transform(res,res+sz,(double *)tmp2,res,std::plus()); - } -} - -DataArrayDouble *MEDCouplingFieldDiscretizationP1::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getValueOnMulti : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr eltsArr,eltsIndexArr; - mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,eltsArr,eltsIndexArr); - const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); - int spaceDim=mesh->getSpaceDimension(); - int nbOfComponents=arr->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfPoints,nbOfComponents); - double *ptToFill=ret->getPointer(); - for(int i=0;i=1) - getValueInCell(mesh,elts[eltsIndex[i]],arr,loc+i*spaceDim,ptToFill+i*nbOfComponents); - else - { - std::ostringstream oss; oss << "Point #" << i << " with coordinates : ("; - std::copy(loc+i*spaceDim,loc+(i+1)*spaceDim,std::ostream_iterator(oss,", ")); - oss << ") detected outside mesh : unable to apply P1::getValueOnMulti ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationP1::reprQuickOverview(std::ostream& stream) const -{ - stream << "P1 spatial discretization."; -} - -MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0) -{ -} - -MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell() -{ - if(_discr_per_cell) - _discr_per_cell->decrRef(); -} - -/*! - * This constructor deep copies ParaMEDMEM::DataArrayInt instance from other (if any). - */ -MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds):_discr_per_cell(0) -{ - DataArrayInt *arr=other._discr_per_cell; - if(arr) - { - if(startCellIds==0 && endCellIds==0) - _discr_per_cell=arr->deepCpy(); - else - _discr_per_cell=arr->selectByTupleIdSafe(startCellIds,endCellIds); - } -} - -MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, int beginCellIds, int endCellIds, int stepCellIds):_discr_per_cell(0) -{ - DataArrayInt *arr=other._discr_per_cell; - if(arr) - { - _discr_per_cell=arr->selectByTupleId2(beginCellIds,endCellIds,stepCellIds); - } -} - -void MEDCouplingFieldDiscretizationPerCell::updateTime() const -{ - if(_discr_per_cell) - updateTimeWith(*_discr_per_cell); -} - -std::size_t MEDCouplingFieldDiscretizationPerCell::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingFieldDiscretization::getHeapMemorySizeWithoutChildren()); - return ret; -} - -std::vector MEDCouplingFieldDiscretizationPerCell::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingFieldDiscretization::getDirectChildrenWithNull()); - ret.push_back(_discr_per_cell); - return ret; -} - -void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has no discretization per cell !"); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween : NULL input mesh or DataArray !"); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - if(nbOfTuples!=mesh->getNumberOfCells()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has a discretization per cell but it's not matching the underlying mesh !"); -} - -bool MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const -{ - if(!other) - { - reason="other spatial discretization is NULL, and this spatial discretization (PerCell) is defined."; - return false; - } - const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); - if(!otherC) - { - reason="Spatial discretization of this is ON_GAUSS, which is not the case of other."; - return false; - } - if(_discr_per_cell==0) - return otherC->_discr_per_cell==0; - if(otherC->_discr_per_cell==0) - return false; - bool ret=_discr_per_cell->isEqualIfNotWhy(*otherC->_discr_per_cell,reason); - if(!ret) - reason.insert(0,"Field discretization per cell DataArrayInt given the discid per cell :"); - return ret; -} - -bool MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const -{ - const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_discr_per_cell==0) - return otherC->_discr_per_cell==0; - if(otherC->_discr_per_cell==0) - return false; - return _discr_per_cell->isEqualWithoutConsideringStr(*otherC->_discr_per_cell); -} - -/*! - * This method is typically the first step of renumbering. The impact on _discr_per_cell is necessary here. - * virtualy by this method. - */ -void MEDCouplingFieldDiscretizationPerCell::renumberCells(const int *old2NewBg, bool check) -{ - int nbCells=_discr_per_cell->getNumberOfTuples(); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells); - // - DataArrayInt *dpc=_discr_per_cell->renumber(array); - _discr_per_cell->decrRef(); - _discr_per_cell=dpc; - // - if(check) - free(const_cast(array)); -} - -void MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary : NULL input mesh !"); - if(!_discr_per_cell) - { - _discr_per_cell=DataArrayInt::New(); - int nbTuples=mesh->getNumberOfCells(); - _discr_per_cell->alloc(nbTuples,1); - int *ptr=_discr_per_cell->getPointer(); - std::fill(ptr,ptr+nbTuples,DFT_INVALID_LOCID_VALUE); - } -} - -void MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells() const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells : no discretization defined !"); - MEDCouplingAutoRefCountObjectPtr test=_discr_per_cell->getIdsEqual(DFT_INVALID_LOCID_VALUE); - if(test->getNumberOfTuples()!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells : presence of orphan cells !"); -} - -/*! - * This method is useful when 'this' describes a field discretization with several gauss discretization on a \b same cell type. - * For example same NORM_TRI3 cells having 6 gauss points and others with 12 gauss points. - * This method returns 2 arrays with same size : the return value and 'locIds' output parameter. - * For a given i into [0,locIds.size) ret[i] represents the set of cell ids of i_th set an locIds[i] represents the set of discretisation of the set. - * The return vector contains a set of newly created instance to deal with. - * The returned vector represents a \b partition of cells ids with a gauss discretization set. - * - * If no descretization is set in 'this' and exception will be thrown. - */ -std::vector MEDCouplingFieldDiscretizationPerCell::splitIntoSingleGaussDicrPerCellType(std::vector& locIds) const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::splitIntoSingleGaussDicrPerCellType : no descretization set !"); - return _discr_per_cell->partitionByDifferentValues(locIds); -} - -const DataArrayInt *MEDCouplingFieldDiscretizationPerCell::getArrayOfDiscIds() const -{ - return _discr_per_cell; -} - -void MEDCouplingFieldDiscretizationPerCell::setArrayOfDiscIds(const DataArrayInt *adids) -{ - if(adids!=_discr_per_cell) - { - if(_discr_per_cell) - _discr_per_cell->decrRef(); - _discr_per_cell=const_cast(adids); - if(_discr_per_cell) - _discr_per_cell->incrRef(); - declareAsNew(); - } -} - -MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss() -{ -} - -MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds, const int *endCellIds):MEDCouplingFieldDiscretizationPerCell(other,startCellIds,endCellIds),_loc(other._loc) -{ -} - -MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, int beginCellIds, int endCellIds, int stepCellIds):MEDCouplingFieldDiscretizationPerCell(other,beginCellIds,endCellIds,stepCellIds),_loc(other._loc) -{ -} - -TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const -{ - return TYPE; -} - -bool MEDCouplingFieldDiscretizationGauss::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const -{ - if(!other) - { - reason="other spatial discretization is NULL, and this spatial discretization (Gauss) is defined."; - return false; - } - const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); - if(!otherC) - { - reason="Spatial discrtization of this is ON_GAUSS, which is not the case of other."; - return false; - } - if(!MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(other,eps,reason)) - return false; - if(_loc.size()!=otherC->_loc.size()) - { - reason="Gauss spatial discretization : localization sizes differ"; - return false; - } - std::size_t sz=_loc.size(); - for(std::size_t i=0;i_loc[i],eps)) - { - std::ostringstream oss; oss << "Gauss spatial discretization : Localization #" << i << " differ from this to other."; - reason=oss.str(); - return false; - } - return true; -} - -bool MEDCouplingFieldDiscretizationGauss::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const -{ - const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(other,eps)) - return false; - if(_loc.size()!=otherC->_loc.size()) - return false; - std::size_t sz=_loc.size(); - for(std::size_t i=0;i_loc[i],eps)) - return false; - return true; -} - -/*! - * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. - * - * \sa MEDCouplingFieldDiscretization::deepCpy. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clone() const -{ - return new MEDCouplingFieldDiscretizationGauss(*this); -} - -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePart(const int *startCellIds, const int *endCellIds) const -{ - return new MEDCouplingFieldDiscretizationGauss(*this,startCellIds,endCellIds); -} - -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const -{ - return new MEDCouplingFieldDiscretizationGauss(*this,beginCellIds,endCellIds,stepCellIds); -} - -std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const -{ - std::ostringstream oss; oss << REPR << "." << std::endl; - if(_discr_per_cell) - { - if(_discr_per_cell->isAllocated()) - { - oss << "Discretization per cell : "; - std::copy(_discr_per_cell->begin(),_discr_per_cell->end(),std::ostream_iterator(oss,", ")); - oss << std::endl; - } - } - oss << "Presence of " << _loc.size() << " localizations." << std::endl; - int i=0; - for(std::vector::const_iterator it=_loc.begin();it!=_loc.end();it++,i++) - { - oss << "+++++ Localization #" << i << " +++++" << std::endl; - oss << (*it).getStringRepr(); - oss << "++++++++++" << std::endl; - } - return oss.str(); -} - -std::size_t MEDCouplingFieldDiscretizationGauss::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingFieldDiscretizationPerCell::getHeapMemorySizeWithoutChildren()); - ret+=_loc.capacity()*sizeof(MEDCouplingGaussLocalization); - for(std::vector::const_iterator it=_loc.begin();it!=_loc.end();it++) - ret+=(*it).getMemorySize(); - return ret; -} - -const char *MEDCouplingFieldDiscretizationGauss::getRepr() const -{ - return REPR; -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(!_discr_per_cell || !_discr_per_cell->isAllocated() || _discr_per_cell->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode"); - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret=0; - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk; - } - if(ret!=_discr_per_cell->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input code points to " << ret << " cells whereas discretization percell array lgth is " << _discr_per_cell->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getNumberOfTuples(0);//0 is not an error ! It is to be sure that input mesh is not used -} - -int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const -{ - int ret=0; - if (_discr_per_cell == 0) - throw INTERP_KERNEL::Exception("Discretization is not initialized!"); - const int *dcPtr=_discr_per_cell->getConstPointer(); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - int maxSz=(int)_loc.size(); - for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++) - { - if(*w>=0 && *wgetNumberOfCells(); -} - -/*! - * This method is redevelopped for performance reasons, but it is equivalent to a call to MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField - * and a call to DataArrayDouble::computeOffsets2 on the returned array. - */ -DataArrayInt *MEDCouplingFieldDiscretizationGauss::getOffsetArr(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getOffsetArr : NULL input mesh !"); - int nbOfTuples=mesh->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples+1,1); - int *retPtr=ret->getPointer(); - const int *start=_discr_per_cell->getConstPointer(); - if(_discr_per_cell->getNumberOfTuples()!=nbOfTuples) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getOffsetArr : mismatch between the mesh and the discretization ids array length !"); - int maxPossible=(int)_loc.size(); - retPtr[0]=0; - for(int i=0;i=0 && *start& arrays, - const int *old2NewBg, bool check) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::renumberArraysForCell : NULL input mesh !"); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); - int nbOfCells=_discr_per_cell->getNumberOfTuples(); - int nbOfTuples=getNumberOfTuples(0); - const int *dcPtr=_discr_per_cell->getConstPointer(); - int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. - int *array3=new int[nbOfCells];//store for each cell in present dcp array (already renumbered) the offset needed by each cell in new numbering. - array3[0]=0; - for(int i=1;i::const_iterator it=arrays.begin();it!=arrays.end();it++) - if(*it) - (*it)->renumberInPlace(array2); - delete [] array2; - if(check) - free(const_cast(array)); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues : NULL input mesh !"); - checkNoOrphanCells(); - MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured();//in general do nothing - int nbOfTuples=getNumberOfTuples(mesh); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=mesh->getSpaceDimension(); - ret->alloc(nbOfTuples,spaceDim); - std::vector< int > locIds; - std::vector parts=splitIntoSingleGaussDicrPerCellType(locIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > parts2(parts.size()); - std::copy(parts.begin(),parts.end(),parts2.begin()); - MEDCouplingAutoRefCountObjectPtr offsets=buildNbOfGaussPointPerCellField(); - offsets->computeOffsets(); - const int *ptrOffsets=offsets->getConstPointer(); - const double *coords=umesh->getCoords()->getConstPointer(); - const int *connI=umesh->getNodalConnectivityIndex()->getConstPointer(); - const int *conn=umesh->getNodalConnectivity()->getConstPointer(); - double *valsToFill=ret->getPointer(); - for(std::size_t i=0;i& wg=cli.getWeights(); - calculator.addGaussInfo(typ,INTERP_KERNEL::CellModel::GetCellModel(typ).getDimension(), - &cli.getGaussCoords()[0],(int)wg.size(),&cli.getRefCoords()[0], - INTERP_KERNEL::CellModel::GetCellModel(typ).getNumberOfNodes()); - // - int nbt=parts2[i]->getNumberOfTuples(); - for(const int *w=parts2[i]->getConstPointer();w!=parts2[i]->getConstPointer()+nbt;w++) - calculator.calculateCoords(cli.getType(),coords,spaceDim,conn+connI[*w]+1,valsToFill+spaceDim*(ptrOffsets[*w])); - } - ret->copyStringInfoFrom(*umesh->getCoords()); - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); - std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); - tmp->sort(true); - tmp=tmp->buildUnique(); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=buildNbOfGaussPointPerCellField(); - nbOfNodesPerCell->computeOffsets2(); - nbOfNodesPerCell->searchRangesInListOfIds(tmp,cellRestriction,trueTupleRestriction); -} - -/*! - * Empty : not a bug - */ -void MEDCouplingFieldDiscretizationGauss::checkCompatibilityWithNature(NatureOfField nat) const -{ -} - -void MEDCouplingFieldDiscretizationGauss::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - int val=-1; - if(_discr_per_cell) - val=_discr_per_cell->getNumberOfTuples(); - tinyInfo.push_back(val); - tinyInfo.push_back((int)_loc.size()); - if(_loc.empty()) - tinyInfo.push_back(-1); - else - tinyInfo.push_back(_loc[0].getDimension()); - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) - (*iter).pushTinySerializationIntInfo(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) - (*iter).pushTinySerializationDblInfo(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::getSerializationIntArray(DataArrayInt *& arr) const -{ - arr=0; - if(_discr_per_cell) - arr=_discr_per_cell; -} - -void MEDCouplingFieldDiscretizationGauss::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr) -{ - int val=tinyInfo[0]; - if(val>=0) - { - _discr_per_cell=DataArrayInt::New(); - _discr_per_cell->alloc(val,1); - } - else - _discr_per_cell=0; - arr=_discr_per_cell; - commonUnserialization(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr) -{ - static const char MSG[]="MEDCouplingFieldDiscretizationGauss::checkForUnserialization : expect to have one not null DataArrayInt !"; - int val=tinyInfo[0]; - if(val>=0) - { - if(!arr) - throw INTERP_KERNEL::Exception(MSG); - arr->checkNbOfTuplesAndComp(val,1,MSG); - _discr_per_cell=const_cast(arr); - _discr_per_cell->incrRef(); - } - else - _discr_per_cell=0; - commonUnserialization(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::finishUnserialization(const std::vector& tinyInfo) -{ - double *tmp=new double[tinyInfo.size()]; - std::copy(tinyInfo.begin(),tinyInfo.end(),tmp); - const double *work=tmp; - for(std::vector::iterator iter=_loc.begin();iter!=_loc.end();iter++) - work=(*iter).fillWithValues(work); - delete [] tmp; -} - -double MEDCouplingFieldDiscretizationGauss::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const -{ - int offset=getOffsetOfCell(cellId); - return da->getIJ(offset+nodeIdInCell,compoId); -} - -void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - if(!mesh || !da) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween : NULL input mesh or DataArray !"); - MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(mesh,da); - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) - (*iter).checkCoherency(); - int nbOfDesc=(int)_loc.size(); - int nbOfCells=mesh->getNumberOfCells(); - const int *dc=_discr_per_cell->getConstPointer(); - for(int i=0;i=nbOfDesc) - { - std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has an undefined gauss location ! Should never happend !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(dc[i]<0) - { - std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has no gauss location !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(mesh->getTypeOfCell(i)!=_loc[dc[i]].getType()) - { - std::ostringstream oss; oss << "Types of mesh and gauss location mismatch for cell # " << i; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - int nbOfTuples=getNumberOfTuples(mesh); - if(nbOfTuples!=da->getNumberOfTuples()) - { - std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : mesh instance specified is NULL !"); - MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isAbs); - const double *volPtr=vol->getArray()->begin(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_GAUSS_PT); - ret->setMesh(mesh); - ret->setDiscretization(const_cast(this)); - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : no discr per cell array not defined ! spatial localization is incorrect !"); - _discr_per_cell->checkAllocated(); - if(_discr_per_cell->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : no discr per cell array defined but with nb of components different from 1 !"); - if(_discr_per_cell->getNumberOfTuples()!=vol->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : no discr per cell array defined but mismatch between nb of cells of mesh and size of spatial disr array !"); - MEDCouplingAutoRefCountObjectPtr offset=getOffsetArr(mesh); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); arr->alloc(getNumberOfTuples(mesh),1); - ret->setArray(arr); - double *arrPtr=arr->getPointer(); - const int *offsetPtr=offset->getConstPointer(); - int maxGaussLoc=(int)_loc.size(); - std::vector locIds; - std::vector ids=splitIntoSingleGaussDicrPerCellType(locIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > ids2(ids.size()); std::copy(ids.begin(),ids.end(),ids2.begin()); - for(std::size_t i=0;i=0 && locId weights=new double[nbOfGaussPt]; - double sum=std::accumulate(loc.getWeights().begin(),loc.getWeights().end(),0.); - std::transform(loc.getWeights().begin(),loc.getWeights().end(),(double *)weights,std::bind2nd(std::multiplies(),1./sum)); - for(const int *cellId=curIds->begin();cellId!=curIds->end();cellId++) - for(int j=0;jgetIJ(0,0) << " ! Must be in [0," << maxGaussLoc << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationGauss::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGauss::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const -{ - throw INTERP_KERNEL::Exception("getValueOnMulti : Not implemented yet for gauss points !"); -} - -MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshData : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); - di=diSafe.retn(); - return ret.retn(); -} - -/*! - * This method is strictly equivalent to MEDCouplingFieldDiscretizationGauss::buildSubMeshData except that it is optimized for input defined as a range of cell ids. - * - * \param [out] beginOut Valid only if \a di is NULL - * \param [out] endOut Valid only if \a di is NULL - * \param [out] stepOut Valid only if \a di is NULL - * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. - * - * \sa MEDCouplingFieldDiscretizationGauss::buildSubMeshData - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const -{ - if(stepCellIds!=1)//even for stepCellIds==-1 the output will not be a range - return MEDCouplingFieldDiscretization::buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,di); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : NULL input mesh !"); - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : no discretization array set !"); - di=0; beginOut=0; endOut=0; stepOut=stepCellIds; - const char msg[]="MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : cell #"; - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - const int *w=_discr_per_cell->begin(); - int nbMaxOfLocId=(int)_loc.size(); - for(int i=0;i=0 && *w=endCellIds) - break; - } - else - { std::ostringstream oss; oss << msg << i << " has invalid id (" << *w << ") ! Should be in [0," << nbMaxOfLocId << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } - else - { std::ostringstream oss; oss << msg << i << " is detected as orphan !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); - return ret.retn(); -} - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationGauss::buildSubMeshData to return parameter \b di. - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : null mesh !"); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=buildNbOfGaussPointPerCellField();//check of _discr_per_cell not NULL pointer - int nbOfCells=mesh->getNumberOfCells(); - if(_discr_per_cell->getNumberOfTuples()!=nbOfCells) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : mismatch of nb of tuples of cell ids array and number of cells !"); - nbOfNodesPerCell->computeOffsets2(); - MEDCouplingAutoRefCountObjectPtr sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); - return sel->buildExplicitArrByRanges(nbOfNodesPerCell); -} - -/*! - * No implementation needed ! - */ -void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const -{ -} - -void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Number of cells has changed and becomes higher with some cells that have been split ! Unable to conserve the Gauss field !"); -} - -void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType(const MEDCouplingMesh *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType : NULL input mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if((int)cm.getDimension()!=mesh->getMeshDimension()) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType : mismatch of dimensions ! MeshDim==" << mesh->getMeshDimension(); - oss << " whereas Type '" << cm.getRepr() << "' has dimension " << cm.getDimension() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - buildDiscrPerCellIfNecessary(mesh); - int id=(int)_loc.size(); - MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); - _loc.push_back(elt); - int *ptr=_discr_per_cell->getPointer(); - int nbCells=mesh->getNumberOfCells(); - for(int i=0;igetTypeOfCell(i)==type) - ptr[i]=id; - zipGaussLocalizations(); -} - -void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells : NULL input mesh !"); - buildDiscrPerCellIfNecessary(mesh); - if(std::distance(begin,end)<1) - throw INTERP_KERNEL::Exception("Size of [begin,end) must be equal or greater than 1 !"); - INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(*begin); - MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); - int id=(int)_loc.size(); - int *ptr=_discr_per_cell->getPointer(); - for(const int *w=begin+1;w!=end;w++) - { - if(mesh->getTypeOfCell(*w)!=type) - { - std::ostringstream oss; oss << "The cell with id " << *w << " has been detected to be incompatible in the [begin,end) array specified !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - // - for(const int *w2=begin;w2!=end;w2++) - ptr[*w2]=id; - // - _loc.push_back(elt); - zipGaussLocalizations(); -} - -void MEDCouplingFieldDiscretizationGauss::clearGaussLocalizations() -{ - if(_discr_per_cell) - { - _discr_per_cell->decrRef(); - _discr_per_cell=0; - } - _loc.clear(); -} - -void MEDCouplingFieldDiscretizationGauss::setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc) -{ - if(locId<0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::setGaussLocalization : localization id has to be >=0 !"); - int sz=(int)_loc.size(); - MEDCouplingGaussLocalization gLoc(INTERP_KERNEL::NORM_ERROR); - if(locId>=sz) - _loc.resize(locId+1,gLoc); - _loc[locId]=loc; -} - -void MEDCouplingFieldDiscretizationGauss::resizeLocalizationVector(int newSz) -{ - if(newSz<0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::resizeLocalizationVector : new size has to be >=0 !"); - MEDCouplingGaussLocalization gLoc(INTERP_KERNEL::NORM_ERROR); - _loc.resize(newSz,gLoc); -} - -MEDCouplingGaussLocalization& MEDCouplingFieldDiscretizationGauss::getGaussLocalization(int locId) -{ - checkLocalizationId(locId); - return _loc[locId]; -} - -int MEDCouplingFieldDiscretizationGauss::getNbOfGaussLocalization() const -{ - return (int)_loc.size(); -} - -int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cellId) const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("No Gauss localization still set !"); - int locId=_discr_per_cell->begin()[cellId]; - if(locId<0) - throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !"); - return locId; -} - -int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - std::set ret=getGaussLocalizationIdsOfOneType(type); - if(ret.empty()) - throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !"); - if(ret.size()>1) - throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !"); - return *ret.begin(); -} - -std::set MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("No Gauss localization still set !"); - std::set ret; - int id=0; - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++,id++) - if((*iter).getType()==type) - ret.insert(id); - return ret; -} - -void MEDCouplingFieldDiscretizationGauss::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const -{ - if(locId<0 || locId>=(int)_loc.size()) - throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - const int *ptr=_discr_per_cell->getConstPointer(); - for(int i=0;i=(int)_loc.size()) - throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); -} - -int MEDCouplingFieldDiscretizationGauss::getOffsetOfCell(int cellId) const -{ - int ret=0; - const int *start=_discr_per_cell->getConstPointer(); - for(const int *w=start;w!=start+cellId;w++) - ret+=_loc[*w].getNumberOfGaussPt(); - return ret; -} - -/*! - * This method do the assumption that there is no orphan cell. If there is an exception is thrown. - * This method makes the assumption too that '_discr_per_cell' is defined. If not an exception is thrown. - * This method returns a newly created array with number of tuples equals to '_discr_per_cell->getNumberOfTuples' and number of components equal to 1. - * The i_th tuple in returned array is the number of gauss point if the corresponding cell. - */ -DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField() const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : no discretization array set !"); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - const int *w=_discr_per_cell->begin(); - ret->alloc(nbOfTuples,1); - int *valsToFill=ret->getPointer(); - int nbMaxOfLocId=(int)_loc.size(); - for(int i=0;i=0 && *wbegin(); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - INTERP_KERNEL::AutoPtr tmp=new int[_loc.size()]; - std::fill((int *)tmp,(int *)tmp+_loc.size(),-2); - for(const int *w=start;w!=start+nbOfTuples;w++) - if(*w>=0) - tmp[*w]=1; - int fid=0; - for(int i=0;i<(int)_loc.size();i++) - if(tmp[i]!=-2) - tmp[i]=fid++; - if(fid==(int)_loc.size()) - return; - // zip needed - int *start2=_discr_per_cell->getPointer(); - for(int *w2=start2;w2!=start2+nbOfTuples;w2++) - if(*w2>=0) - *w2=tmp[*w2]; - std::vector tmpLoc; - for(int i=0;i<(int)_loc.size();i++) - if(tmp[i]!=-2) - tmpLoc.push_back(_loc[i]); - _loc=tmpLoc; -} - -void MEDCouplingFieldDiscretizationGauss::commonUnserialization(const std::vector& tinyInfo) -{ - int nbOfLoc=tinyInfo[1]; - _loc.clear(); - int dim=tinyInfo[2]; - int delta=-1; - if(nbOfLoc>0) - delta=((int)tinyInfo.size()-3)/nbOfLoc; - for(int i=0;i tmp(tinyInfo.begin()+3+i*delta,tinyInfo.begin()+3+(i+1)*delta); - MEDCouplingGaussLocalization elt=MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(dim,tmp); - _loc.push_back(elt); - } -} - -MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE() -{ -} - -TypeOfField MEDCouplingFieldDiscretizationGaussNE::getEnum() const -{ - return TYPE; -} - -/*! - * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. - * - * \sa MEDCouplingFieldDiscretization::deepCpy. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGaussNE::clone() const -{ - return new MEDCouplingFieldDiscretizationGaussNE(*this); -} - -std::string MEDCouplingFieldDiscretizationGaussNE::getStringRepr() const -{ - return std::string(REPR); -} - -const char *MEDCouplingFieldDiscretizationGaussNE::getRepr() const -{ - return REPR; -} - -bool MEDCouplingFieldDiscretizationGaussNE::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const -{ - if(!other) - { - reason="other spatial discretization is NULL, and this spatial discretization (GaussNE) is defined."; - return false; - } - const MEDCouplingFieldDiscretizationGaussNE *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason="Spatial discrtization of this is ON_GAUSS_NE, which is not the case of other."; - return ret; -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret(0); - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk*(int)cm.getNumberOfNodes(); - } - return ret; -} - -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples : NULL input mesh !"); - int ret=0; - int nbOfCells=mesh->getNumberOfCells(); - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); - ret+=cm.getNumberOfNodes(); - } - return ret; -} - -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfMeshPlaces : NULL input mesh !"); - return mesh->getNumberOfCells(); -} - -DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::getOffsetArr(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getOffsetArr : NULL input mesh !"); - int nbOfTuples=mesh->getNumberOfCells(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples+1,1); - int *retPtr=ret->getPointer(); - retPtr[0]=0; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); - retPtr[i+1]=retPtr[i]+cm.getNumberOfNodes(); - } - return ret; -} - -void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell : NULL input mesh !"); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); - int nbOfCells=mesh->getNumberOfCells(); - int nbOfTuples=getNumberOfTuples(mesh); - int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. - int *array3=new int[nbOfCells];//store for each cell in after renumbering the offset needed by each cell in new numbering. - array3[0]=0; - for(int i=1;igetTypeOfCell((int)std::distance(array,std::find(array,array+nbOfCells,i-1))); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - array3[i]=array3[i-1]+cm.getNumberOfNodes(); - } - int j=0; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - for(int k=0;k<(int)cm.getNumberOfNodes();k++,j++) - array2[j]=array3[array[i]]+k; - } - delete [] array3; - for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) - if(*it) - (*it)->renumberInPlace(array2); - delete [] array2; - if(check) - free(const_cast(array)); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured();//in general do nothing - int nbOfTuples=getNumberOfTuples(umesh); - int spaceDim=mesh->getSpaceDimension(); - ret->alloc(nbOfTuples,spaceDim); - const double *coords=umesh->getCoords()->begin(); - const int *connI=umesh->getNodalConnectivityIndex()->getConstPointer(); - const int *conn=umesh->getNodalConnectivity()->getConstPointer(); - int nbCells=umesh->getNumberOfCells(); - double *retPtr=ret->getPointer(); - for(int i=0;i=0) - retPtr=std::copy(coords+(*w)*spaceDim,coords+((*w)+1)*spaceDim,retPtr); - return ret.retn(); -} - -/*! - * Reimplemented from MEDCouplingFieldDiscretization::integral for performance reason. The default implementation is valid too for GAUSS_NE spatial discretization. - */ -void MEDCouplingFieldDiscretizationGaussNE::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const -{ - if(!mesh || !arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::integral : input mesh or array is null !"); - int nbOfCompo=arr->getNumberOfComponents(); - std::fill(res,res+nbOfCompo,0.); - // - MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isWAbs); - std::set types=mesh->getAllGeoTypes(); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); - nbOfNodesPerCell->computeOffsets2(); - const double *arrPtr=arr->begin(),*volPtr=vol->getArray()->begin(); - for(std::set::const_iterator it=types.begin();it!=types.end();it++) - { - std::size_t wArrSz=-1; - const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); - INTERP_KERNEL::AutoPtr wArr2=new double[wArrSz]; - double sum=std::accumulate(wArr,wArr+wArrSz,0.); - std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies(),1./sum)); - MEDCouplingAutoRefCountObjectPtr ids=mesh->giveCellsWithType(*it); - MEDCouplingAutoRefCountObjectPtr ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); - const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); - int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); - for(int i=0;i tmp=DataArrayInt::New(); tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); - std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); - tmp->sort(true); - tmp=tmp->buildUnique(); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); - nbOfNodesPerCell->computeOffsets2(); - nbOfNodesPerCell->searchRangesInListOfIds(tmp,cellRestriction,trueTupleRestriction); -} - -void MEDCouplingFieldDiscretizationGaussNE::checkCompatibilityWithNature(NatureOfField nat) const -{ -} - -double MEDCouplingFieldDiscretizationGaussNE::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getIJK : NULL input mesh !"); - int offset=0; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - offset+=cm.getNumberOfNodes(); - } - return da->getIJ(offset+nodeIdInCell,compoId); -} - -void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - int nbOfTuples=getNumberOfTuples(mesh); - if(nbOfTuples!=da->getNumberOfTuples()) - { - std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getMeasureField : mesh instance specified is NULL !"); - MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isAbs); - const double *volPtr=vol->getArray()->begin(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_GAUSS_NE); - ret->setMesh(mesh); - // - std::set types=mesh->getAllGeoTypes(); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); - int nbTuples=nbOfNodesPerCell->accumulate(0); - nbOfNodesPerCell->computeOffsets2(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); arr->alloc(nbTuples,1); - ret->setArray(arr); - double *arrPtr=arr->getPointer(); - for(std::set::const_iterator it=types.begin();it!=types.end();it++) - { - std::size_t wArrSz=-1; - const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); - INTERP_KERNEL::AutoPtr wArr2=new double[wArrSz]; - double sum=std::accumulate(wArr,wArr+wArrSz,0.); - std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies(),1./sum)); - MEDCouplingAutoRefCountObjectPtr ids=mesh->giveCellsWithType(*it); - MEDCouplingAutoRefCountObjectPtr ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); - const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); - int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); - for(int i=0;isynchronizeTimeWithSupport(); - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationGaussNE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGaussNE::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const -{ - throw INTERP_KERNEL::Exception("getValueOnMulti : Not implemented for Gauss NE !"); -} - -MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); - di=diSafe.retn(); - return ret.retn(); -} - -/*! - * This method is strictly equivalent to MEDCouplingFieldDiscretizationGauss::buildSubMeshData except that it is optimized for input defined as a range of cell ids. - * - * \param [out] beginOut Valid only if \a di is NULL - * \param [out] endOut Valid only if \a di is NULL - * \param [out] stepOut Valid only if \a di is NULL - * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. - * - * \sa MEDCouplingFieldDiscretizationGauss::buildSubMeshData - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const -{ - if(stepCellIds!=1)//even for stepCellIds==-1 the output will not be a range - return MEDCouplingFieldDiscretization::buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,di); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange : NULL input mesh !"); - int nbOfCells=mesh->getNumberOfCells(); - di=0; beginOut=0; endOut=0; stepOut=stepCellIds; - const char msg[]="MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange : cell #"; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - { std::ostringstream oss; oss << msg << i << " presence of dynamic cell (polygons and polyedrons) ! Not implemented !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - int delta=cm.getNumberOfNodes(); - if(i=endCellIds) - break; - } - MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); - return ret.retn(); -} - - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData to return parameter \b di. - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds : null mesh !"); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); - nbOfNodesPerCell->computeOffsets2(); - MEDCouplingAutoRefCountObjectPtr sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); - return sel->buildExplicitArrByRanges(nbOfNodesPerCell); -} - -/*! - * No implementation needed ! - */ -void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const -{ -} - -void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGaussNE::reprQuickOverview(std::ostream& stream) const -{ - stream << "Gauss points on nodes per element spatial discretization."; -} - -MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other):MEDCouplingFieldDiscretization(other) -{ -} - -TypeOfField MEDCouplingFieldDiscretizationKriging::getEnum() const -{ - return TYPE; -} - -const char *MEDCouplingFieldDiscretizationKriging::getRepr() const -{ - return REPR; -} - -/*! - * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. - * - * \sa MEDCouplingFieldDiscretization::deepCpy. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationKriging::clone() const -{ - return new MEDCouplingFieldDiscretizationKriging; -} - -std::string MEDCouplingFieldDiscretizationKriging::getStringRepr() const -{ - return std::string(REPR); -} - -void MEDCouplingFieldDiscretizationKriging::checkCompatibilityWithNature(NatureOfField nat) const -{ - if(nat!=ConservativeVolumic) - throw INTERP_KERNEL::Exception("Invalid nature for Kriging field : expected ConservativeVolumic !"); -} - -bool MEDCouplingFieldDiscretizationKriging::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const -{ - if(!other) - { - reason="other spatial discretization is NULL, and this spatial discretization (Kriginig) is defined."; - return false; - } - const MEDCouplingFieldDiscretizationKriging *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason="Spatial discrtization of this is ON_NODES_KR, which is not the case of other."; - return ret; -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationKriging::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getMeasureField : mesh instance specified is NULL !"); - throw INTERP_KERNEL::Exception("getMeasureField on FieldDiscretizationKriging : not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationKriging::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const -{ - MEDCouplingAutoRefCountObjectPtr res2=MEDCouplingFieldDiscretizationKriging::getValueOnMulti(arr,mesh,loc,1); - std::copy(res2->begin(),res2->end(),res); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints) const -{ - if(!arr || !arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getValueOnMulti : input array is null or not allocated !"); - int nbOfRows(getNumberOfMeshPlaces(mesh)); - if(arr->getNumberOfTuples()!=nbOfRows) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationKriging::getValueOnMulti : input array does not have correct number of tuples ! Excepted " << nbOfRows << " having " << arr->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbCols(-1),nbCompo(arr->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr m(computeEvaluationMatrixOnGivenPts(mesh,loc,nbOfTargetPoints,nbCols)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - ret->alloc(nbOfTargetPoints,nbCompo); - INTERP_KERNEL::matrixProduct(m->begin(),nbOfTargetPoints,nbCols,arr->begin(),nbOfRows,nbCompo,ret->getPointer()); - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationKriging::reprQuickOverview(std::ostream& stream) const -{ - stream << "Kriging spatial discretization."; -} - -/*! - * Returns the matrix of size nbRows = \a nbOfTargetPoints and \a nbCols = \a nbCols. This matrix is useful if - * - * \return the new result matrix to be deallocated by the caller. - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints, int& nbCols) const -{ - int isDrift(-1),nbRows(-1); - MEDCouplingAutoRefCountObjectPtr matrixInv(computeInverseMatrix(mesh,isDrift,nbRows)); - // - MEDCouplingAutoRefCountObjectPtr coords=getLocalizationOfDiscValues(mesh); - int nbOfPts(coords->getNumberOfTuples()),dimension(coords->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr locArr=DataArrayDouble::New(); - locArr->useArray(loc,false,CPP_DEALLOC,nbOfTargetPoints,dimension); - nbCols=nbOfPts; - // - MEDCouplingAutoRefCountObjectPtr matrix2=coords->buildEuclidianDistanceDenseMatrixWith(locArr); - operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfTargetPoints*nbOfPts,matrix2->getPointer()); - // - MEDCouplingAutoRefCountObjectPtr matrix3=DataArrayDouble::New(); - matrix3->alloc(nbOfTargetPoints*nbRows,1); - double *work=matrix3->getPointer(); - const double *workCst(matrix2->begin()),*workCst2(loc); - for(int i=0;i ret(DataArrayDouble::New()); - ret->alloc(nbOfTargetPoints,nbRows); - INTERP_KERNEL::matrixProduct(matrix3->begin(),nbOfTargetPoints,nbRows,matrixInv->begin(),nbRows,nbRows,ret->getPointer()); - MEDCouplingAutoRefCountObjectPtr ret2(DataArrayDouble::New()); - ret2->alloc(nbOfTargetPoints*nbOfPts,1); - workCst=ret->begin(); work=ret2->getPointer(); - for(int i=0;i matrixWithDrift(computeMatrix(mesh,isDrift,matSz)); - MEDCouplingAutoRefCountObjectPtr matrixInv(DataArrayDouble::New()); - matrixInv->alloc(matSz*matSz,1); - INTERP_KERNEL::inverseMatrix(matrixWithDrift->getConstPointer(),matSz,matrixInv->getPointer()); - return matrixInv.retn(); -} - -/*! - * This method computes the kriging matrix. - * \return the new result matrix to be deallocated by the caller. - * \sa computeInverseMatrix - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::computeMatrix : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr coords(getLocalizationOfDiscValues(mesh)); - int nbOfPts(coords->getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr matrix(coords->buildEuclidianDistanceDenseMatrix()); - operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfPts*nbOfPts,matrix->getPointer()); - // Drift - MEDCouplingAutoRefCountObjectPtr matrixWithDrift(performDrift(matrix,coords,isDrift)); - matSz=nbOfPts+isDrift; - return matrixWithDrift.retn(); -} - -/*! - * This method computes coefficients to apply to each representing points of \a mesh, that is to say the nodes of \a mesh given a field array \a arr whose - * number of tuples should be equal to the number of representing points in \a mesh. - * - * \param [in] mesh is the sources of nodes on which kriging will be done regarding the parameters and the value of \c this->getSpaceDimension() - * \param [in] arr input field DataArrayDouble whose number of tuples must be equal to the number of nodes in \a mesh - * \param [out] isDrift return if drift coefficients are present in the returned vector of coefficients. If different from 0 there is presence of drift coefficients. - * Whatever the value of \a isDrift the number of tuples of returned DataArrayDouble will be equal to \c arr->getNumberOfTuples() + \a isDrift. - * \return a newly allocated array containing coefficients including or not drift coefficient at the end depending the value of \a isDrift parameter. - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const -{ - int nbRows(-1); - MEDCouplingAutoRefCountObjectPtr matrixInv(computeInverseMatrix(mesh,isDrift,nbRows)); - MEDCouplingAutoRefCountObjectPtr KnewiK(DataArrayDouble::New()); - KnewiK->alloc(nbRows*1,1); - MEDCouplingAutoRefCountObjectPtr arr2(PerformDriftOfVec(arr,isDrift)); - INTERP_KERNEL::matrixProduct(matrixInv->getConstPointer(),nbRows,nbRows,arr2->getConstPointer(),arr2->getNumberOfTuples(),1,KnewiK->getPointer()); - return KnewiK.retn(); -} - -/*! - * Apply \f f(x) on each element x in \a matrixPtr. \a matrixPtr is expected to be a dense matrix represented by a chunck of memory of size at least equal to \a nbOfElems. - * - * \param [in] spaceDimension space dimension of the input mesh on which the Kriging has to be performed - * \param [in] nbOfElems is the result of the product of nb of rows and the nb of columns of matrix \a matrixPtr - * \param [in,out] matrixPtr is the dense matrix whose on each values the operation will be applied - */ -void MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix(int spaceDimension, int nbOfElems, double *matrixPtr) const -{ - switch(spaceDimension) - { - case 1: - { - OperateOnDenseMatrixH3(nbOfElems,matrixPtr); - break; - } - case 2: - { - OperateOnDenseMatrixH2Ln(nbOfElems,matrixPtr); - break; - } - case 3: - { - //nothing here : it is not a bug g(h)=h with spaceDim 3. - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix : only dimension 1, 2 and 3 implemented !"); - } -} - -void MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3(int nbOfElems, double *matrixPtr) -{ - for(int i=0;iisAllocated() || matr->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : invalid input dense matrix ! Must be allocated not NULL and with exactly one component !"); - if(!arr || !arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : invalid input array of coordiantes ! Must be allocated and not NULL !"); - int spaceDimension(arr->getNumberOfComponents()),nbOfPts(arr->getNumberOfTuples()),nbOfEltInMatrx(matr->getNumberOfTuples()); - delta=spaceDimension+1; - int nbOfCols(nbOfEltInMatrx/nbOfPts); - if(nbOfEltInMatrx%nbOfPts!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : size of input dense matrix and input arrays mismatch ! NbOfElems in matrix % nb of tuples in array must be equal to 0 !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfPts*(nbOfCols+delta)); - double *retPtr(ret->getPointer()); - const double *mPtr(matr->begin()),*aPtr(arr->begin()); - for(int i=0;iisAllocated() || arr->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec : input array must be not NULL allocated and with one component !"); - if(isDrift<0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec : isDrift parameter must be >=0 !"); - MEDCouplingAutoRefCountObjectPtr arr2(DataArrayDouble::New()); - arr2->alloc((arr->getNumberOfTuples()+isDrift)*1,1); - double *work(std::copy(arr->begin(),arr->end(),arr2->getPointer())); - std::fill(work,work+isDrift,0.); - return arr2.retn(); -} - -/*! - * Starting from a square matrix \a matr, this method returns a newly allocated dense square matrix whose \a matr is included in returned matrix - * in the top left corner, and in the remaining returned matrix the parameters to take into account about the kriging drift. - * For the moment only linear srift is implemented. - * - * \param [in] arr the position of points were input mesh geometry is considered for Kriging - * \param [in] matr input matrix whose drift part will be added - * \param [out] delta the difference between the size of the output matrix and the input matrix \a matr. - * \return a newly allocated matrix bigger than input matrix \a matr. - * \sa MEDCouplingFieldDiscretizationKriging::PerformDriftRect - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) const -{ - int spaceDimension=arr->getNumberOfComponents(); - delta=spaceDimension+1; - int szOfMatrix=arr->getNumberOfTuples(); - if(szOfMatrix*szOfMatrix!=matr->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::performDrift : invalid size"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc((szOfMatrix+delta)*(szOfMatrix+delta),1); - const double *srcWork=matr->getConstPointer(); - const double *srcWork2=arr->getConstPointer(); - double *destWork=ret->getPointer(); - for(int i=0;i arrNoI=arr->toNoInterlace(); - srcWork2=arrNoI->getConstPointer(); - for(int i=0;i -#include - -namespace ParaMEDMEM -{ - class DataArray; - class DataArrayInt; - class MEDCouplingMesh; - class DataArrayDouble; - class MEDCouplingFieldDouble; - - class MEDCouplingFieldDiscretization : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldDiscretization *New(TypeOfField type); - MEDCOUPLING_EXPORT double getPrecision() const { return _precision; } - MEDCOUPLING_EXPORT void setPrecision(double val) { _precision=val; } - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT static TypeOfField GetTypeOfFieldFromStringRepr(const std::string& repr); - MEDCOUPLING_EXPORT static std::string GetTypeOfFieldRepr(TypeOfField type); - MEDCOUPLING_EXPORT virtual TypeOfField getEnum() const = 0; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *deepCpy() const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clone() const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT virtual std::string getStringRepr() const = 0; - MEDCOUPLING_EXPORT virtual const char *getRepr() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const; - MEDCOUPLING_EXPORT virtual void normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const; - MEDCOUPLING_EXPORT virtual void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const = 0; - MEDCOUPLING_EXPORT virtual void checkCompatibilityWithNature(NatureOfField nat) const = 0; - MEDCOUPLING_EXPORT virtual void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check) = 0; - MEDCOUPLING_EXPORT virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const = 0; - MEDCOUPLING_EXPORT virtual void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const = 0; - MEDCOUPLING_EXPORT virtual void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const = 0; - MEDCOUPLING_EXPORT virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const = 0; - MEDCOUPLING_EXPORT virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const = 0; - MEDCOUPLING_EXPORT virtual void getSerializationIntArray(DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void finishUnserialization(const std::vector& tinyInfo); - MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); - MEDCOUPLING_EXPORT virtual void checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr); - MEDCOUPLING_EXPORT virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT virtual void clearGaussLocalizations(); - MEDCOUPLING_EXPORT virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId); - MEDCOUPLING_EXPORT virtual int getNbOfGaussLocalization() const; - MEDCOUPLING_EXPORT virtual int getGaussLocalizationIdOfOneCell(int cellId) const; - MEDCOUPLING_EXPORT virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT virtual std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT virtual void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const; - MEDCOUPLING_EXPORT virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual ~MEDCouplingFieldDiscretization(); - protected: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization(); - MEDCOUPLING_EXPORT static void RenumberEntitiesFromO2NArr(double epsOnVals, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const std::string& msg); - MEDCOUPLING_EXPORT static void RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const std::string& msg); - protected: - double _precision; - static const double DFLT_PRECISION; - }; - - class MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - public: - static const char REPR[]; - static const TypeOfField TYPE; - }; - - class MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - public: - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - }; - - class MEDCouplingFieldDiscretizationP1 : public MEDCouplingFieldDiscretizationOnNodes - { - public: - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - public: - static const char REPR[]; - static const TypeOfField TYPE; - protected: - MEDCOUPLING_EXPORT void getValueInCell(const MEDCouplingMesh *mesh, int cellId, const DataArrayDouble *arr, const double *loc, double *res) const; - }; - - /*! - * This class abstracts MEDCouplingFieldDiscretization that needs an information on each cell to perform their job. - * All classes that inherits from this are more linked to mesh. - */ - class MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT const DataArrayInt *getArrayOfDiscIds() const; - MEDCOUPLING_EXPORT void setArrayOfDiscIds(const DataArrayInt *adids); - MEDCOUPLING_EXPORT void checkNoOrphanCells() const; - MEDCOUPLING_EXPORT std::vector splitIntoSingleGaussDicrPerCellType(std::vector< int >& locIds) const; - protected: - MEDCouplingFieldDiscretizationPerCell(); - MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds); - MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, int beginCellIds, int endCellIds, int stepCellIds); - ~MEDCouplingFieldDiscretizationPerCell(); - void updateTime() const; - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; - void renumberCells(const int *old2NewBg, bool check); - protected: - void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *mesh); - protected: - DataArrayInt *_discr_per_cell; - static const int DFT_INVALID_LOCID_VALUE; - }; - - class MEDCouplingFieldDiscretizationGauss : public MEDCouplingFieldDiscretizationPerCell - { - public: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGauss(); - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfo); - MEDCOUPLING_EXPORT void getSerializationIntArray(DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); - MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr); - MEDCOUPLING_EXPORT double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void setGaussLocalizationOnType(const MEDCouplingMesh *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void clearGaussLocalizations(); - MEDCOUPLING_EXPORT void setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc); - MEDCOUPLING_EXPORT void resizeLocalizationVector(int newSz); - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization& getGaussLocalization(int locId); - MEDCOUPLING_EXPORT int getNbOfGaussLocalization() const; - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneCell(int cellId) const; - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const; - MEDCOUPLING_EXPORT const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; - MEDCOUPLING_EXPORT DataArrayInt *buildNbOfGaussPointPerCellField() const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - protected: - MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds=0, const int *endCellIds=0); - MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, int beginCellIds, int endCellIds, int stepCellIds); - void zipGaussLocalizations(); - int getOffsetOfCell(int cellId) const; - void checkLocalizationId(int locId) const; - void commonUnserialization(const std::vector& tinyInfo); - public: - static const char REPR[]; - static const TypeOfField TYPE; - private: - std::vector _loc; - }; - - /*! - * Gauss with points of values located on nodes of element. This is a specialization of MEDCouplingFieldDiscretizationGauss. - */ - class MEDCouplingFieldDiscretizationGaussNE : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE(); - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT static const double *GetWeightArrayFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); - MEDCOUPLING_EXPORT static const double *GetRefCoordsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); - MEDCOUPLING_EXPORT static const double *GetLocsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); - protected: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other); - public: - static const char REPR[]; - static const TypeOfField TYPE; - static const double FGP_POINT1[1]; - static const double FGP_SEG2[2]; - static const double FGP_SEG3[3]; - static const double FGP_SEG4[4]; - static const double FGP_TRI3[3]; - static const double FGP_TRI6[6]; - static const double FGP_TRI7[7]; - static const double FGP_QUAD4[4]; - static const double FGP_QUAD8[8]; - static const double FGP_QUAD9[9]; - static const double FGP_TETRA4[4]; - static const double FGP_TETRA10[10];//to check - static const double FGP_PENTA6[6]; - static const double FGP_PENTA15[15];//to check - static const double FGP_HEXA8[8]; - static const double FGP_HEXA20[20];//to check - static const double FGP_HEXA27[27]; - static const double FGP_PYRA5[5]; - static const double FGP_PYRA13[13];//to check - static const double REF_SEG2[2]; - static const double REF_SEG3[3]; - static const double REF_SEG4[4]; - static const double REF_TRI3[6]; - static const double REF_TRI6[12]; - static const double REF_TRI7[14]; - static const double REF_QUAD4[8]; - static const double REF_QUAD8[16]; - static const double REF_QUAD9[18]; - static const double REF_TETRA4[12]; - static const double REF_TETRA10[30]; - static const double REF_PENTA6[18]; - static const double REF_PENTA15[45]; - static const double REF_HEXA8[24]; - static const double REF_HEXA20[60]; - static const double REF_HEXA27[81]; - static const double REF_PYRA5[15]; - static const double REF_PYRA13[39]; - static const double LOC_SEG2[2]; - static const double LOC_SEG3[3]; - static const double LOC_SEG4[4]; - static const double LOC_TRI3[6]; - static const double LOC_TRI6[12]; - static const double LOC_TRI7[14]; - static const double LOC_QUAD4[8]; - static const double LOC_QUAD8[16]; - static const double LOC_QUAD9[18]; - static const double LOC_TETRA4[12]; - static const double LOC_TETRA10[30];//to check - static const double LOC_PENTA6[18]; - static const double LOC_PENTA15[45];//to check - static const double LOC_HEXA8[24]; - static const double LOC_HEXA20[60];//to check - static const double LOC_HEXA27[81]; - static const double LOC_PYRA5[15]; - static const double LOC_PYRA13[39];//to check - }; - - class MEDCouplingFieldDiscretizationKriging : public MEDCouplingFieldDiscretizationOnNodes - { - public: - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - public://specific part - MEDCOUPLING_EXPORT DataArrayDouble *computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints, int& nbCols) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeInverseMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const; - MEDCOUPLING_EXPORT void operateOnDenseMatrix(int spaceDimension, int nbOfElems, double *matrixPtr) const; - MEDCOUPLING_EXPORT DataArrayDouble *performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) const; - MEDCOUPLING_EXPORT static void OperateOnDenseMatrixH3(int nbOfElems, double *matrixPtr); - MEDCOUPLING_EXPORT static void OperateOnDenseMatrixH2Ln(int nbOfElems, double *matrixPtr); - MEDCOUPLING_EXPORT static DataArrayDouble *PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta); - MEDCOUPLING_EXPORT static DataArrayDouble *PerformDriftOfVec(const DataArrayDouble *arr, int isDrift); - public: - static const char REPR[]; - static const TypeOfField TYPE; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/medtool/src/MEDCoupling/MEDCouplingFieldDouble.cxx deleted file mode 100644 index 23d1314c6..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ /dev/null @@ -1,3356 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingNatureOfField.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - - -/*! - * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization. - * For more info, see \ref MEDCouplingFirstSteps3. - * \param [in] type - the type of spatial discretization of the created field, one of - * (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_NODES "ON_NODES", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). - * \param [in] td - the type of time discretization of the created field, one of - * (\ref ParaMEDMEM::NO_TIME "NO_TIME", - * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", - * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", - * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - */ -MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td) -{ - return new MEDCouplingFieldDouble(type,td); -} - -/*! - * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a - * spatial type and supporting mesh copied from a given - * \ref MEDCouplingFieldTemplatesPage "field template". - * For more info, see \ref MEDCouplingFirstSteps3. - * \warning This method does not deeply copy neither the mesh nor the spatial - * discretization. Only a shallow copy (reference) is done for the mesh and the spatial - * discretization! - * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining - * the spatial discretization and the supporting mesh. - * \param [in] td - the type of time discretization of the created field, one of - * (\ref ParaMEDMEM::NO_TIME "NO_TIME", - * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", - * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", - * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td) -{ - return new MEDCouplingFieldDouble(ft,td); -} - -/*! - * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3. - * \param [in] unit \a unit (string) in which time is measured. - */ -void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit) -{ - _time_discr->setTimeUnit(unit); -} - -/*! - * Returns a time unit of \a this field. - * \return a string describing units in which time is measured. - */ -std::string MEDCouplingFieldDouble::getTimeUnit() const -{ - return _time_discr->getTimeUnit(); -} - -/*! - * This method if possible the time information (time unit, time iteration, time unit and time value) with its support - * that is to say its mesh. - * - * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is - * NO_TIME. - */ -void MEDCouplingFieldDouble::synchronizeTimeWithSupport() -{ - _time_discr->synchronizeTimeWith(_mesh); -} - -/*! - * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data - * of \a this field is copied either deep or shallow depending on \a recDeepCpy - * parameter. But the underlying mesh is always shallow copied. - * Data that can be copied either deeply or shallow are: - * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s) - * of field values, - * - \ref MEDCouplingSpatialDisc "a spatial discretization". - * - * \c clone(false) is rather dedicated for advanced users that want to limit the amount - * of memory. It allows the user to perform methods like operator+(), operator*() - * etc. with \a this and the returned field. If the user wants to duplicate deeply the - * underlying mesh he should call cloneWithMesh() method or deepCpy() instead. - * \warning The underlying \b mesh of the returned field is **always the same** - * (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter. - * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is - * deep, else all data arrays of \a this field are shared by the new field. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \sa cloneWithMesh() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const -{ - return new MEDCouplingFieldDouble(*this,recDeepCpy); -} - -/*! - * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data - * of \a this field is copied either deep or shallow depending on \a recDeepCpy - * parameter. But the underlying mesh is always deep copied. - * Data that can be copied either deeply or shallow are: - * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s) - * of field values, - * - \ref MEDCouplingSpatialDisc "a spatial discretization". - * - * This method behaves exactly like clone() except that here the underlying **mesh is - * always deeply duplicated**, whatever the value \a recDeepCpy parameter. - * The result of \c cloneWithMesh(true) is exactly the same as that of deepCpy(). - * So the resulting field can not be used together with \a this one in the methods - * like operator+(), operator*() etc. To avoid deep copying the underlying mesh, - * the user can call clone(). - * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is - * deep, else all data arrays of \a this field are shared by the new field. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \sa clone() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const -{ - MEDCouplingAutoRefCountObjectPtr ret=clone(recDeepCpy); - if(_mesh) - { - MEDCouplingAutoRefCountObjectPtr mCpy=_mesh->deepCpy(); - ret->setMesh(mCpy); - } - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including - * the mesh**. - * The result of this method is exactly the same as that of \c cloneWithMesh(true). - * So the resulting field can not be used together with \a this one in the methods - * like operator+(), operator*() etc. To avoid deep copying the underlying mesh, - * the user can call clone(). - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \sa cloneWithMesh() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const -{ - return cloneWithMesh(true); -} - -/*! - * Creates a new MEDCouplingFieldDouble of given - * \ref MEDCouplingTemporalDisc "temporal discretization". The result field either - * shares the data array(s) with \a this field, or holds a deep copy of it, depending on - * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**. - * \param [in] td - the type of time discretization of the created field, one of - * (\ref ParaMEDMEM::NO_TIME "NO_TIME", - * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", - * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", - * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). - * \param [in] deepCopy - if \c true, the copy of the underlying data arrays is - * deep, else all data arrays of \a this field are shared by the new field. - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."
- * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example." - * \endif - * \sa clone() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const -{ - MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy); - MEDCouplingAutoRefCountObjectPtr disc; - if(_type) - disc=_type->clone(); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()); - ret->setMesh(getMesh()); - ret->setName(getName()); - ret->setDescription(getDescription()); - return ret.retn(); -} - -/*! - * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping ! - * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach - * to each cell the average of values on nodes constituting this cell. - * - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. - * \throw If \a this spatial discretization is empty or not ON_NODES. - * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). - * - * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization. - * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P1P0" method. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const -{ - checkCoherency(); - TypeOfField tf(getTypeOfField()); - if(tf!=ON_NODES) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !"); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP0); - ret->setDiscretization(nsp); - const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call - int nbCells(m->getNumberOfCells()); - std::vector arrs(getArrays()); - std::size_t sz(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); - for(std::size_t j=0;jgetNumberOfComponents()); - outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo); - outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); - outArrs[j]=outArrsSafe[j]; - double *pt(outArrsSafe[j]->getPointer()); - const double *srcPt(arrs[j]->begin()); - for(int i=0;i nodeIds; - m->getNodeIdsOfCell(i,nodeIds); - std::fill(pt,pt+nbCompo,0.); - std::size_t nbNodesInCell(nodeIds.size()); - for(std::size_t k=0;k()); - if(nbNodesInCell!=0) - std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies(),1./((double)nbNodesInCell))); - else - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - ret->setArrays(outArrs); - return ret.retn(); -} - -/*! - * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping ! - * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach - * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.). - * - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. - * \throw If \a this spatial discretization is empty or not ON_CELLS. - * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). - * - * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization. - * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P0P1" method. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const -{ - checkCoherency(); - TypeOfField tf(getTypeOfField()); - if(tf!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !"); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP1); - ret->setDiscretization(nsp); - const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call - MEDCouplingAutoRefCountObjectPtr rn(DataArrayInt::New()),rni(DataArrayInt::New()); - m->getReverseNodalConnectivity(rn,rni); - MEDCouplingAutoRefCountObjectPtr rni2(rni->deltaShiftIndex()); - MEDCouplingAutoRefCountObjectPtr rni3(rni2->convertToDblArr()); rni2=0; - std::vector arrs(getArrays()); - std::size_t sz(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); - for(std::size_t j=0;j tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end())); - outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0; - outArrsSafe[j]->divideEqual(rni3); - outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); - outArrs[j]=outArrsSafe[j]; - } - ret->setArrays(outArrs); - return ret.retn(); -} - -/*! - * Copies tiny info (component names, name and description) from an \a other field to - * \a this one. - * \warning The underlying mesh is not renamed (for safety reason). - * \param [in] other - the field to copy the tiny info from. - * \throw If \a this->getNumberOfComponents() != \a other->getNumberOfComponents() - */ -void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other) -{ - MEDCouplingField::copyTinyStringsFrom(other); - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(otherC) - { - _time_discr->copyTinyStringsFrom(*otherC->_time_discr); - } -} - -/*! - * Copies only times, order and iteration from an \a other field to - * \a this one. The underlying mesh is not impacted by this method. - * Arrays are not impacted neither. - * \param [in] other - the field to tiny attributes from. - * \throw If \a this->getNumberOfComponents() != \a other->getNumberOfComponents() - */ -void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) -{ - if(other) - { - _time_discr->copyTinyAttrFrom(*other->_time_discr); - } -} - -void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) -{ - copyTinyStringsFrom(other); - copyTinyAttrFrom(other); -} - -/*! - * Returns a string describing \a this field. This string is outputted by \c print - * Python command. The string includes info on - * - name, - * - description, - * - \ref MEDCouplingSpatialDisc "spatial discretization", - * - \ref MEDCouplingTemporalDisc "time discretization", - * - \ref NatureOfField, - * - components, - * - mesh. - * - * \return std::string - the string describing \a this field. - */ -std::string MEDCouplingFieldDouble::simpleRepr() const -{ - std::ostringstream ret; - ret << "FieldDouble with name : \"" << getName() << "\"\n"; - ret << "Description of field is : \"" << getDescription() << "\"\n"; - if(_type) - { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; } - else - { ret << "FieldDouble has no spatial discretization !\n"; } - if(_time_discr) - { ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; } - else - { ret << "FieldDouble has no time discretization !\n"; } - ret << "FieldDouble nature of field is : \"" << MEDCouplingNatureOfField::GetReprNoThrow(_nature) << "\"\n"; - if(getArray()) - { - if(getArray()->isAllocated()) - { - int nbOfCompo=getArray()->getNumberOfComponents(); - ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; - ret << "FieldDouble default array has following info on components : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - { - ret << "Array set but not allocated !\n"; - } - } - if(_mesh) - ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); - else - ret << "Mesh support information : No mesh set !\n"; - return ret.str(); -} - -/*! - * Returns a string describing \a this field. The string includes info on - * - name, - * - description, - * - \ref MEDCouplingSpatialDisc "spatial discretization", - * - \ref MEDCouplingTemporalDisc "time discretization", - * - components, - * - mesh, - * - contents of data arrays. - * - * \return std::string - the string describing \a this field. - */ -std::string MEDCouplingFieldDouble::advancedRepr() const -{ - std::ostringstream ret; - ret << "FieldDouble with name : \"" << getName() << "\"\n"; - ret << "Description of field is : \"" << getDescription() << "\"\n"; - if(_type) - { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; } - else - { ret << "FieldDouble has no space discretization set !\n"; } - if(_time_discr) - { ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; } - else - { ret << "FieldDouble has no time discretization set !\n"; } - if(getArray()) - ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; - if(_mesh) - ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr(); - else - ret << "Mesh support information : No mesh set !\n"; - std::vector arrays; - _time_discr->getArrays(arrays); - int arrayId=0; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++) - { - ret << "Array #" << arrayId << " :\n__________\n"; - if(*iter) - (*iter)->reprWithoutNameStream(ret); - else - ret << "Array empty !"; - ret << "\n"; - } - return ret.str(); -} - -std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const -{ - std::vector fs(1,this); - return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary); -} - -bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !"); - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - { - reason="field given in input is not castable in MEDCouplingFieldDouble !"; - return false; - } - if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason)) - return false; - if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason)) - { - reason.insert(0,"In FieldDouble time discretizations differ :"); - return false; - } - return true; -} - -/*! - * Checks equality of \a this and \a other field. Only numeric data is considered, - * i.e. names, description etc are not compared. - * \param [in] other - the field to compare with. - * \param [in] meshPrec - a precision used to compare node coordinates of meshes. - * \param [in] valsPrec - a precision used to compare data arrays of the two fields. - * \return bool - \c true if the two fields are equal, \c false else. - * \throw If \a other == NULL. - * \throw If the spatial discretization of \a this field is NULL. - */ -bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const -{ - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) - return false; - if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec)) - return false; - return true; -} - -/*! - * This method states if \a this and 'other' are compatibles each other before performing any treatment. - * This method is good for methods like : mergeFields. - * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. - */ -bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areCompatibleForMerge(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areCompatible(otherC->_time_discr)) - return false; - return true; -} - -/*! - * This method is more strict than MEDCouplingField::areCompatibleForMerge method. - * This method is used for operation on fields to operate a first check before attempting operation. - */ -bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const -{ - std::string tmp; - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp)) - return false; - return true; -} - -/*! - * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that - * number of components between \a this and 'other' can be different here (for operator*). - */ -bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr)) - return false; - return true; -} - -/*! - * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that - * number of components between \a this and 'other' can be different here (for operator/). - */ -bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr)) - return false; - return true; -} - -/*! - * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible, - * except that \a this and other can have different number of components. - */ -bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const -{ - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - if(!_time_discr->areCompatibleForMeld(other->_time_discr)) - return false; - return true; -} - -/*! - * Permutes values of \a this field according to a given permutation array for cells - * renumbering. The underlying mesh is deeply copied and its cells are also permuted. - * The number of cells remains the same; for that the permutation array \a old2NewBg - * should not contain equal ids. - * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **. - * - * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is - * to be equal to \a this->getMesh()->getNumberOfCells(). - * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation - * array, so that its maximal cell id to correspond to (be less than) the number - * of cells in mesh. This new array is then used for the renumbering. If \a - * check == \c false, \a old2NewBg is used as is, that is less secure as validity - * of ids in \a old2NewBg is not checked. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a check == \c true and \a old2NewBg contains equal ids. - * \throw If mesh nature does not allow renumbering (e.g. structured mesh). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".
- * \ref py_mcfielddouble_renumberCells "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) -{ - renumberCellsWithoutMesh(old2NewBg,check); - MEDCouplingAutoRefCountObjectPtr m=_mesh->deepCpy(); - m->renumberCells(old2NewBg,check); - setMesh(m); - updateTime(); -} - -/*! - * Permutes values of \a this field according to a given permutation array for cells - * renumbering. The underlying mesh is \b not permuted. - * The number of cells remains the same; for that the permutation array \a old2NewBg - * should not contain equal ids. - * This method performs a part of job of renumberCells(). The reasonable use of this - * method is only for multi-field instances lying on the same mesh to avoid a - * systematic duplication and renumbering of _mesh attribute. - * \warning Use this method with a lot of care! - * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is - * to be equal to \a this->getMesh()->getNumberOfCells(). - * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation - * array, so that its maximal cell id to correspond to (be less than) the number - * of cells in mesh. This new array is then used for the renumbering. If \a - * check == \c false, \a old2NewBg is used as is, that is less secure as validity - * of ids in \a old2NewBg is not checked. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a check == \c true and \a old2NewBg contains equal ids. - * \throw If mesh nature does not allow renumbering (e.g. structured mesh). - */ -void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); - // - _type->renumberCells(old2NewBg,check); - std::vector arrays; - _time_discr->getArrays(arrays); - std::vector arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin()); - _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check); - // - updateTime(); -} - -/*! - * Permutes values of \a this field according to a given permutation array for node - * renumbering. The underlying mesh is deeply copied and its nodes are also permuted. - * The number of nodes can change, contrary to renumberCells(). - * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is - * to be equal to \a this->getMesh()->getNumberOfNodes(). - * \param [in] eps - a precision used to compare field values at merged nodes. If - * the values differ more than \a eps, an exception is thrown. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a check == \c true and \a old2NewBg contains equal ids. - * \throw If mesh nature does not allow renumbering (e.g. structured mesh). - * \throw If values at merged nodes deffer more than \a eps. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".
- * \ref py_mcfielddouble_renumberNodes "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) -{ - const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !"); - int nbOfNodes=meshC->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; - renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps); - meshC2->renumberNodes(old2NewBg,newNbOfNodes); - setMesh(meshC2); -} - -/*! - * Permutes values of \a this field according to a given permutation array for nodes - * renumbering. The underlying mesh is \b not permuted. - * The number of nodes can change, contrary to renumberCells(). - * A given epsilon specifies a threshold of error in case of two nodes are merged but - * the difference of values on these nodes are higher than \a eps. - * This method performs a part of job of renumberNodes(), excluding node renumbering - * in mesh. The reasonable use of this - * method is only for multi-field instances lying on the same mesh to avoid a - * systematic duplication and renumbering of _mesh attribute. - * \warning Use this method with a lot of care! - * \warning In case of an exception thrown, the contents of the data array can be - * partially modified until the exception occurs. - * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is - * to be equal to \a this->getMesh()->getNumberOfNodes(). - * \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering. - * \param [in] eps - a precision used to compare field values at merged nodes. If - * the values differ more than \a eps, an exception is thrown. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If values at merged nodes deffer more than \a eps. - */ -void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter); -} - -/*! - * Returns all tuple ids of \a this scalar field that fit the range [\a vmin, - * \a vmax]. This method calls DataArrayDouble::getIdsInRange(). - * \param [in] vmin - a lower boundary of the range. Tuples with values less than \a - * vmin are not included in the result array. - * \param [in] vmax - an upper boundary of the range. Tuples with values more than \a - * vmax are not included in the result array. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of selected - * tuples. The caller is to delete this array using decrRef() as it is no - * more needed. - * \throw If the data array is not set. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !"); - return getArray()->getIdsInRange(vmin,vmax); -} - -/*! - * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()). - * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. - * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field. - * Parameter \a part specifies **cell ids whatever the spatial discretization of this** ( - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_NODES "ON_NODES", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). - * - * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6]. - * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
- * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
- * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
- * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). - * - * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6]. - * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field - * will contain 6 tuples and \a this field will lie on this restricted mesh. - * - * \param [in] part - an array of cell ids to include to the result field. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
- * \ref py_mcfielddouble_subpart1 "Here is a Python example". - * \endif - * \sa MEDCouplingFieldDouble::buildSubPartRange - */ - -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const -{ - if(part==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); - return buildSubPart(part->begin(),part->end()); -} - -/*! - * Builds a newly created field, that the caller will have the responsability to deal with. - * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkCoherency() returns without any exception thrown), **no check of this will be done**. - * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field. - * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this ( - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_NODES "ON_NODES", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). - * - * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6]. - * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples. - *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh(). - *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh(). - *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). - * - * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6]. - * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field - * will contain 6 tuples and \a this field will lie on this restricted mesh. - * - * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd ) - * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd ) - * \return a newly allocated field the caller should deal with. - * - * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
- * \ref py_mcfielddouble_subpart1 "Here a Python example." - * \endif - * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); - MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); - MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePart(partBg,partEnd))); - ret->setMesh(m); - std::vector arrays; - _time_discr->getArrays(arrays); - std::vector arrs; - std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe; - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - DataArrayDouble *arr=0; - if(*iter) - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - arrs.push_back(arr); arrsSafe.push_back(arr); - } - ret->_time_discr->setArrays(arrs,0); - return ret.retn(); -} - -/*! - * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is - * given using a range given \a begin, \a end and \a step to optimize the part computation. - * - * \sa MEDCouplingFieldDouble::buildSubPart - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - int beginOut,endOut,stepOut; - MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect); - MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); - MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePartRange(begin,end,step))); - ret->setMesh(m); - std::vector arrays; - _time_discr->getArrays(arrays); - std::vector arrs; - std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - DataArrayDouble *arr=0; - if(*iter) - { - if(arrSelect) - { - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - } - else - arr=(*iter)->selectByTupleId2(beginOut,endOut,stepOut); - } - arrs.push_back(arr); arrsSafe.push_back(arr); - } - ret->_time_discr->setArrays(arrs,0); - return ret.retn(); -} - -/*! - * Returns a type of \ref MEDCouplingTemporalDisc "time discretization" of \a this field. - * \return ParaMEDMEM::TypeOfTimeDiscretization - an enum item describing the time - * discretization type. - */ -TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const -{ - return _time_discr->getEnum(); -} - -MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type), - _time_discr(MEDCouplingTimeDiscretization::New(td)) -{ -} - -/*! - * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! ** - */ -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft,false), - _time_discr(MEDCouplingTimeDiscretization::New(td)) -{ -} - -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy), - _time_discr(other._time_discr->performCpy(deepCopy)) -{ -} - -MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td) -{ -} - -MEDCouplingFieldDouble::~MEDCouplingFieldDouble() -{ - delete _time_discr; -} - -/*! - * Checks if \a this field is correctly defined, else an exception is thrown. - * \throw If the mesh is not set. - * \throw If the data array is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a this->getTimeTolerance() < 0. - * \throw If the temporal discretization data is incorrect. - * \throw If mesh data does not correspond to field data. - */ -void MEDCouplingFieldDouble::checkCoherency() const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::checkCoherency : no spatial discretization !"); - _time_discr->checkCoherency(); - _type->checkCoherencyBetween(_mesh,getArray()); -} - -/*! - * Accumulate values of a given component of \a this field. - * \param [in] compId - the index of the component of interest. - * \return double - a sum value of *compId*-th component. - * \throw If the data array is not set. - * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is - * not respected. - */ -double MEDCouplingFieldDouble::accumulate(int compId) const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); - return getArray()->accumulate(compId); -} - -/*! - * Accumulates values of each component of \a this array. - * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated - * by the caller, that is filled by this method with sum value for each - * component. - * \throw If the data array is not set. - */ -void MEDCouplingFieldDouble::accumulate(double *res) const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); - getArray()->accumulate(res); -} - -/*! - * Returns the maximal value within \a this scalar field. Values of all arrays stored - * in \a this->_time_discr are checked. - * \return double - the maximal value among all values of \a this field. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If the data array is not set. - * \throw If there is an empty data array in \a this field. - */ -double MEDCouplingFieldDouble::getMaxValue() const -{ - std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); - bool isExistingArr=false; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - if(*iter) - { - isExistingArr=true; - int loc; - ret=std::max(ret,(*iter)->getMaxValue(loc)); - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !"); - return ret; -} - -/*! - * Returns the maximal value and all its locations within \a this scalar field. - * Only the first of available data arrays is checked. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of - * tuples holding the maximal value. The caller is to delete it using - * decrRef() as it is no more needed. - * \return double - the maximal value among all values of the first array of \a this filed. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If there is an empty data array in \a this field. - */ -double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const -{ - std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); - bool isExistingArr=false; - tupleIds=0; - MEDCouplingAutoRefCountObjectPtr ret1; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - if(*iter) - { - isExistingArr=true; - DataArrayInt *tmp; - ret=std::max(ret,(*iter)->getMaxValue2(tmp)); - MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); - if(!((const DataArrayInt *)ret1)) - ret1=tmpSafe; - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !"); - tupleIds=ret1.retn(); - return ret; -} - -/*! - * Returns the minimal value within \a this scalar field. Values of all arrays stored - * in \a this->_time_discr are checked. - * \return double - the minimal value among all values of \a this field. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If the data array is not set. - * \throw If there is an empty data array in \a this field. - */ -double MEDCouplingFieldDouble::getMinValue() const -{ - std::vector arrays; - _time_discr->getArrays(arrays); - double ret=std::numeric_limits::max(); - bool isExistingArr=false; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - if(*iter) - { - isExistingArr=true; - int loc; - ret=std::min(ret,(*iter)->getMinValue(loc)); - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !"); - return ret; -} - -/*! - * Returns the minimal value and all its locations within \a this scalar field. - * Only the first of available data arrays is checked. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of - * tuples holding the minimal value. The caller is to delete it using - * decrRef() as it is no more needed. - * \return double - the minimal value among all values of the first array of \a this filed. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If there is an empty data array in \a this field. - */ -double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const -{ - std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); - bool isExistingArr=false; - tupleIds=0; - MEDCouplingAutoRefCountObjectPtr ret1; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - if(*iter) - { - isExistingArr=true; - DataArrayInt *tmp; - ret=std::max(ret,(*iter)->getMinValue2(tmp)); - MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); - if(!((const DataArrayInt *)ret1)) - ret1=tmpSafe; - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !"); - tupleIds=ret1.retn(); - return ret; -} - -/*! - * Returns the average value of \a this scalar field. - * \return double - the average value over all values of the data array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If the data array is not set or it is empty. - */ -double MEDCouplingFieldDouble::getAverageValue() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !"); - return getArray()->getAverageValue(); -} - -/*! - * This method returns the euclidean norm of \a this field. - * \f[ - * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]} - * \f] - * \throw If the data array is not set. - */ -double MEDCouplingFieldDouble::norm2() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !"); - return getArray()->norm2(); -} - -/*! - * This method returns the max norm of \a this field. - * \f[ - * \max_{0 \leq i < nbOfEntity}{abs(val[i])} - * \f] - * \throw If the data array is not set. - */ -double MEDCouplingFieldDouble::normMax() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); - return getArray()->normMax(); -} - -/*! - * Computes the weighted average of values of each component of \a this field, the weights being the - * values returned by buildMeasureField(). - * \param [out] res - pointer to an array of result sum values, of size at least \a - * this->getNumberOfComponents(), that is to be allocated by the caller. - * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by - * buildMeasureField(). It makes this method slower. If you are sure that all - * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == - * \c false to speed up the method. - * \throw If the mesh is not set. - * \throw If the data array is not set. - */ -void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); - MEDCouplingAutoRefCountObjectPtr w=buildMeasureField(isWAbs); - double deno=w->getArray()->accumulate(0); - MEDCouplingAutoRefCountObjectPtr arr=getArray()->deepCpy(); - arr->multiplyEqual(w->getArray()); - arr->accumulate(res); - int nCompo = getArray()->getNumberOfComponents(); - std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies(),1./deno)); -} - -/*! - * Computes the weighted average of values of a given component of \a this field, the weights being the - * values returned by buildMeasureField(). - * \param [in] compId - an index of the component of interest. - * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by - * buildMeasureField(). It makes this method slower. If you are sure that all - * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == - * \c false to speed up the method. - * \throw If the mesh is not set. - * \throw If the data array is not set. - * \throw If \a compId is not valid. - A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). - */ -double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const -{ - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - getWeightedAverageValue(res,isWAbs); - return res[compId]; -} - -/*! - * Returns the \c normL1 of values of a given component of \a this field: - * \f[ - * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|} - * \f] - * \param [in] compId - an index of the component of interest. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a compId is not valid. - A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). - */ -double MEDCouplingFieldDouble::normL1(int compId) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - _type->normL1(_mesh,getArray(),res); - return res[compId]; -} - -/*! - * Returns the \c normL1 of values of each component of \a this field: - * \f[ - * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|} - * \f] - * \param [out] res - pointer to an array of result values, of size at least \a - * this->getNumberOfComponents(), that is to be allocated by the caller. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - */ -void MEDCouplingFieldDouble::normL1(double *res) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !"); - _type->normL1(_mesh,getArray(),res); -} - -/*! - * Returns the \c normL2 of values of a given component of \a this field: - * \f[ - * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}} - * \f] - * \param [in] compId - an index of the component of interest. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a compId is not valid. - A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). - */ -double MEDCouplingFieldDouble::normL2(int compId) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - _type->normL2(_mesh,getArray(),res); - return res[compId]; -} - -/*! - * Returns the \c normL2 of values of each component of \a this field: - * \f[ - * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}} - * \f] - * \param [out] res - pointer to an array of result values, of size at least \a - * this->getNumberOfComponents(), that is to be allocated by the caller. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - */ -void MEDCouplingFieldDouble::normL2(double *res) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !"); - _type->normL2(_mesh,getArray(),res); -} - -/*! - * Computes a sum of values of a given component of \a this field multiplied by - * values returned by buildMeasureField(). - * This method is useful to check the conservativity of interpolation method. - * \param [in] compId - an index of the component of interest. - * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by - * buildMeasureField() that makes this method slower. If a user is sure that all - * cells of the underlying mesh have correct orientation, he can put \a isWAbs == - * \c false that speeds up this method. - * \throw If the mesh is not set. - * \throw If the data array is not set. - * \throw If \a compId is not valid. - A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). - */ -double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - _type->integral(_mesh,getArray(),isWAbs,res); - return res[compId]; -} - -/*! - * Computes a sum of values of each component of \a this field multiplied by - * values returned by buildMeasureField(). - * This method is useful to check the conservativity of interpolation method. - * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by - * buildMeasureField() that makes this method slower. If a user is sure that all - * cells of the underlying mesh have correct orientation, he can put \a isWAbs == - * \c false that speeds up this method. - * \param [out] res - pointer to an array of result sum values, of size at least \a - * this->getNumberOfComponents(), that is to be allocated by the caller. - * \throw If the mesh is not set. - * \throw If the data array is not set. - * \throw If the spatial discretization of \a this field is NULL. - */ -void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !"); - _type->integral(_mesh,getArray(),isWAbs,res); -} - -/*! - * Returns a value at a given cell of a structured mesh. The cell is specified by its - * (i,j,k) index. - * \param [in] i - a index of node coordinates array along X axis. The cell is - * located between the i-th and ( i + 1 )-th nodes along X axis. - * \param [in] j - a index of node coordinates array along Y axis. The cell is - * located between the j-th and ( j + 1 )-th nodes along Y axis. - * \param [in] k - a index of node coordinates array along Z axis. The cell is - * located between the k-th and ( k + 1 )-th nodes along Z axis. - * \param [out] res - pointer to an array returning a feild value, of size at least - * \a this->getNumberOfComponents(), that is to be allocated by the caller. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \throw If the mesh is not a structured one. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOnPos "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const -{ - const DataArrayDouble *arr=_time_discr->getArray(); - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !"); - _type->getValueOnPos(arr,_mesh,i,j,k,res); -} - -/*! - * Returns a value of \a this at a given point using spatial discretization. - * \param [in] spaceLoc - the point of interest. - * \param [out] res - pointer to an array returning a feild value, of size at least - * \a this->getNumberOfComponents(), that is to be allocated by the caller. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \throw If \a spaceLoc is out of the spatial discretization. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOn "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const -{ - const DataArrayDouble *arr=_time_discr->getArray(); - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !"); - _type->getValueOn(arr,_mesh,spaceLoc,res); -} - -/*! - * Returns values of \a this at given points using spatial discretization. - * \param [in] spaceLoc - coordinates of points of interest in full-interlace - * mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ). - * \param [in] nbOfPoints - number of points of interest. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding field - * values relating to the input points. This array is of size \a nbOfPoints - * tuples per \a this->getNumberOfComponents() components. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \throw If any point in \a spaceLoc is out of the spatial discretization. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example". - * \endif - */ -DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const -{ - const DataArrayDouble *arr=_time_discr->getArray(); - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !"); - return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints); -} - -/*! - * Returns a value of \a this field at a given point at a given time using spatial discretization. - * If the time is not covered by \a this->_time_discr, an exception is thrown. - * \param [in] spaceLoc - the point of interest. - * \param [in] time - the time of interest. - * \param [out] res - pointer to an array returning a feild value, of size at least - * \a this->getNumberOfComponents(), that is to be allocated by the caller. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * \throw If \a spaceLoc is out of the spatial discretization. - * \throw If \a time is not covered by \a this->_time_discr. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOn_time "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const -{ - std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time); - if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !"); - std::vector res2; - for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) - { - int sz=(int)res2.size(); - res2.resize(sz+(*iter)->getNumberOfComponents()); - _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]); - } - _time_discr->getValueForTime(time,res2,res); -} - -/*! - * Apply a linear function to a given component of \a this field, so that - * a component value (x) becomes \f$ a * x + b \f$. - * \param [in] a - the first coefficient of the function. - * \param [in] b - the second coefficient of the function. - * \param [in] compoId - the index of component to modify. - * \throw If the data array(s) is(are) not set. - */ -void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId) -{ - _time_discr->applyLin(a,b,compoId); -} - -/*! - * Apply a linear function to all components of \a this field, so that - * values (x) becomes \f$ a * x + b \f$. - * \param [in] a - the first coefficient of the function. - * \param [in] b - the second coefficient of the function. - * \throw If the data array(s) is(are) not set. - */ -void MEDCouplingFieldDouble::applyLin(double a, double b) -{ - _time_discr->applyLin(a,b); -} - -/*! - * This method sets \a this to a uniform scalar field with one component. - * All tuples will have the same value 'value'. - * An exception is thrown if no underlying mesh is defined. - */ -MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !"); - int nbOfTuple=_type->getNumberOfTuples(_mesh); - _time_discr->setOrCreateUniformValueOnAllComponents(nbOfTuple,value); - return *this; -} - -/*! - * Creates data array(s) of \a this field by using a C function for value generation. - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is to compute a field value basing on coordinates of value - * location point. - * \throw If the mesh is not set. - * \throw If \a func returns \c false. - * \throw If the spatial discretization of \a this field is NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic(loc,nbOfComp,func); -} - -/*! - * Creates data array(s) of \a this field by using a function for value generation.
- * The function is applied to coordinates of value location points. For example, if - * \a this field is on cells, the function is applied to cell barycenters. - * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * The function can include arbitrary named variables - * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of - * variables are sorted in \b alphabetical \b order to associate a variable name with a - * component. For example, in the expression "2*x+z", "x" stands for the component #0 - * and "z" stands for the component #1 (\b not #2)!
- * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then - * - "2*x + z" produces (5.,5.,5.,5.) - * - "2*x + 0*y + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) - * - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is used to compute a field value basing on coordinates of value - * location point. For example, if \a this field is on cells, the function - * is applied to cell barycenters. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".
- * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic(loc,nbOfComp,func); -} - -/*! - * Creates data array(s) of \a this field by using a function for value generation.
- * The function is applied to coordinates of value location points. For example, if - * \a this field is on cells, the function is applied to cell barycenters.
- * This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" - * by the way how variable - * names, used in the function, are associated with components of coordinates of field - * location points; here, a variable name corresponding to a component is retrieved from - * a corresponding node coordinates array (where it is set via - * DataArrayDouble::setInfoOnComponent()).
- * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z", - * coordinates of a 3D point are (1.,3.,7.), then - * - "2*x + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) - * - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is used to compute a field value basing on coordinates of value - * location point. For example, if \a this field is on cells, the function - * is applied to cell barycenters. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".
- * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& func) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic2 !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic2(loc,nbOfComp,func); -} - -/*! - * Creates data array(s) of \a this field by using a function for value generation.
- * The function is applied to coordinates of value location points. For example, if - * \a this field is on cells, the function is applied to cell barycenters.
- * This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" - * by the way how variable - * names, used in the function, are associated with components of coordinates of field - * location points; here, a component index of a variable is defined by a - * rank of the variable within the input array \a varsOrder.
- * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr. - * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, names of - * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a - * 3D point are (1.,3.,7.), then - * - "2*x + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) - * - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is used to compute a field value basing on coordinates of value - * location point. For example, if \a this field is on cells, the function - * is applied to cell barycenters. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".
- * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic3 !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func); -} - -/*! - * Modifies values of \a this field by applying a C function to each tuple of all - * data arrays. - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is to compute a field value basing on a current field value. - * \throw If \a func returns \c false. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) -{ - _time_discr->applyFunc(nbOfComp,func); -} - -/*! - * Fill \a this field with a given value.
- * This method is a specialization of other overloaded methods. When \a nbOfComp == 1 - * this method is equivalent to ParaMEDMEM::MEDCouplingFieldDouble::operator=(). - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] val - the value to assign to every atomic value of \a this field. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the mesh is not set. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc_val "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !"); - int nbOfTuple=_type->getNumberOfTuples(_mesh); - _time_discr->setUniformValue(nbOfTuple,nbOfComp,val); -} - -/*! - * Modifies values of \a this field by applying a function to each tuple of all - * data arrays. - * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * The function can include arbitrary named variables - * (e.g. "x","y" or "va44") to refer to components of a field value. Names of - * variables are sorted in \b alphabetical \b order to associate a variable name with a - * component. For example, in the expression "2*x+z", "x" stands for the component #0 - * and "z" stands for the component #1 (\b not #2)!
- * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then - * - "2*x + z" produces (5.,5.,5.,5.) - * - "2*x + 0*y + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) - * - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is to compute a field value basing on a current field value. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) -{ - _time_discr->applyFunc(nbOfComp,func); -} - - -/*! - * Modifies values of \a this field by applying a function to each tuple of all - * data arrays. - * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()" - * by the way how variable - * names, used in the function, are associated with components of field values; - * here, a variable name corresponding to a component is retrieved from - * component information of an array (where it is set via - * DataArrayDouble::setInfoOnComponent()).
- * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then - * - "2*x + z" produces (5.,5.,5.,5.) - * - "2*x + 0*y + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) - * - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is to compute a new field value basing on a current field value. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc2 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) -{ - _time_discr->applyFunc2(nbOfComp,func); -} - -/*! - * Modifies values of \a this field by applying a function to each tuple of all - * data arrays. - * This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()" - * by the way how variable - * names, used in the function, are associated with components of field values; - * here, a component index of a variable is defined by a - * rank of the variable within the input array \a varsOrder.
- * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr. - * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, names of - * components are given in \a varsOrder: ["x", "y","z"], components of a - * 3D vector are (1.,3.,7.), then - * - "2*x + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) - * - * \param [in] nbOfComp - the number of components for \a this field to have. - * \param [in] func - the function used to compute values of \a this field. - * This function is to compute a new field value basing on a current field value. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc3 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) -{ - _time_discr->applyFunc3(nbOfComp,varsOrder,func); -} - -/*! - * Modifies values of \a this field by applying a function to each atomic value of all - * data arrays. The function computes a new single value basing on an old single value. - * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * The function can include **only one** arbitrary named variable - * (e.g. "x","y" or "va44") to refer to a field atomic value.
- * In a general case, a value resulting from the function evaluation is assigned to - * a single field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, components of a field value are (1.,3.,7.), then - * - "2*x - 1" produces (1.,5.,13.) - * - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.) - * - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.) - * - * \param [in] func - the function used to compute values of \a this field. - * This function is to compute a field value basing on a current field value. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(const std::string& func) -{ - _time_discr->applyFunc(func); -} - -/*! - * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. - * The field will contain exactly the same number of components after the call. - * Use is not warranted for the moment ! - */ -void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func) -{ - _time_discr->applyFuncFast32(func); -} - -/*! - * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. - * The field will contain exactly the same number of components after the call. - * Use is not warranted for the moment ! - */ -void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func) -{ - _time_discr->applyFuncFast64(func); -} - -/*! - * Returns number of components in the data array. For more info on the data arrays, - * see \ref arrays. - * \return int - the number of components in the data array. - * \throw If the data array is not set. - */ -int MEDCouplingFieldDouble::getNumberOfComponents() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !"); - return getArray()->getNumberOfComponents(); -} - -/*! - * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is - * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour. - * - * Returns number of tuples in \a this field, that depends on - * - the number of entities in the underlying mesh - * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number - * of Gauss points if \a this->getTypeOfField() == - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT"). - * - * The returned value does \b not \b depend on the number of tuples in the data array - * (which has to be equal to the returned value), \b contrary to - * getNumberOfComponents() and getNumberOfValues() that retrieve information from the - * data array (Sorry, it is confusing !). - * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method. - * - * \warning No checkCoherency() is done here. - * For more info on the data arrays, see \ref arrays. - * \return int - the number of tuples. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the spatial discretization is not fully defined. - * \sa MEDCouplingField::getNumberOfTuplesExpected - */ -int MEDCouplingFieldDouble::getNumberOfTuples() const -{ - //std::cerr << " ******* MEDCouplingFieldDouble::getNumberOfTuples is deprecated : use MEDCouplingField::getNumberOfTuplesExpected instead ! ******" << std::endl; - if(!_mesh) - throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !"); - return _type->getNumberOfTuples(_mesh); -} - -/*! - * Returns number of atomic double values in the data array of \a this field. - * For more info on the data arrays, see \ref arrays. - * \return int - (number of tuples) * (number of components) of the - * data array. - * \throw If the data array is not set. - */ -int MEDCouplingFieldDouble::getNumberOfValues() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !"); - return getArray()->getNbOfElems(); -} - -/*! - * Sets own modification time by the most recently modified element of data (the mesh, - * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage. - */ -void MEDCouplingFieldDouble::updateTime() const -{ - MEDCouplingField::updateTime(); - updateTimeWith(*_time_discr); -} - -std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingField::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingFieldDouble::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingField::getDirectChildrenWithNull()); - if(_time_discr) - { - std::vector ret2(_time_discr->getDirectChildrenWithNull()); - ret.insert(ret.end(),ret2.begin(),ret2.end()); - } - return ret; -} - -/*! - * Sets \ref NatureOfField. - * \param [in] nat - an item of enum ParaMEDMEM::NatureOfField. - */ -void MEDCouplingFieldDouble::setNature(NatureOfField nat) -{ - MEDCouplingField::setNature(nat); - if(_type) - _type->checkCompatibilityWithNature(nat); -} - -/*! - * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh. - * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME) - */ -void MEDCouplingFieldDouble::synchronizeTimeWithMesh() -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !"); - int it=-1,ordr=-1; - double val=_mesh->getTime(it,ordr); - std::string timeUnit(_mesh->getTimeUnit()); - setTime(val,it,ordr); - setTimeUnit(timeUnit); -} - -/*! - * Returns a value of \a this field of type either - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" or - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". - * \param [in] cellId - an id of cell of interest. - * \param [in] nodeIdInCell - a node index within the cell. - * \param [in] compoId - an index of component. - * \return double - the field value corresponding to the specified parameters. - * \throw If the data array is not set. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a this field if of type other than - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" or - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". - */ -double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !"); - return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId); -} - -/*! - * Sets the data array. - * \param [in] array - the data array holding values of \a this field. It's size - * should correspond to the mesh and - * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field - * (see getNumberOfTuples()), but this size is not checked here. - */ -void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) -{ - _time_discr->setArray(array,this); -} - -/*! - * Sets the data array holding values corresponding to an end of a time interval - * for which \a this field is defined. - * \param [in] array - the data array holding values of \a this field. It's size - * should correspond to the mesh and - * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field - * (see getNumberOfTuples()), but this size is not checked here. - */ -void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array) -{ - _time_discr->setEndArray(array,this); -} - -/*! - * Sets all data arrays needed to define the field values. - * \param [in] arrs - a vector of DataArrayDouble's holding values of \a this - * field. Size of each array should correspond to the mesh and - * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field - * (see getNumberOfTuples()), but this size is not checked here. - * \throw If number of arrays in \a arrs does not correspond to type of - * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field. - */ -void MEDCouplingFieldDouble::setArrays(const std::vector& arrs) -{ - _time_discr->setArrays(arrs,this); -} - -void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - tinyInfo.clear(); - _time_discr->getTinySerializationStrInformation(tinyInfo); - tinyInfo.push_back(_name); - tinyInfo.push_back(_desc); - tinyInfo.push_back(getTimeUnit()); -} - -/*! - * This method retrieves some critical values to resize and prepare remote instance. - * The first two elements returned in tinyInfo correspond to the parameters to give in constructor. - * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. - */ -void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !"); - tinyInfo.clear(); - tinyInfo.push_back((int)_type->getEnum()); - tinyInfo.push_back((int)_time_discr->getEnum()); - tinyInfo.push_back((int)_nature); - _time_discr->getTinySerializationIntInformation(tinyInfo); - std::vector tinyInfo2; - _type->getTinySerializationIntInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size()); -} - -/*! - * This method retrieves some critical values to resize and prepare remote instance. - * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. - */ -void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !"); - tinyInfo.clear(); - _time_discr->getTinySerializationDbleInformation(tinyInfo); - std::vector tinyInfo2; - _type->getTinySerializationDbleInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it -} - -/*! - * This method has to be called to the new instance filled by CORBA, MPI, File... - * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied. - * @param dataInt out parameter. If not null the pointer is already owned by \a this after the call of this method. In this case no decrRef must be applied. - * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by \a this after the call of this method. - * No decrRef must be applied to every instances in returned vector. - * \sa checkForUnserialization - */ -void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); - dataInt=0; - std::vector tinyInfoITmp(tinyInfoI); - int sz=tinyInfoITmp.back(); - tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); - _time_discr->resizeForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); - _type->resizeForUnserialization(tinyInfoITmp3,dataInt); -} - -/*! - * This method is extremely close to resizeForUnserialization except that here the arrays in \a dataInt and in \a arrays are attached in \a this - * after having checked that size is correct. This method is used in python pickeling context to avoid copy of data. - * \sa resizeForUnserialization - */ -void MEDCouplingFieldDouble::checkForUnserialization(const std::vector& tinyInfoI, const DataArrayInt *dataInt, const std::vector& arrays) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); - std::vector tinyInfoITmp(tinyInfoI); - int sz=tinyInfoITmp.back(); - tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); - _time_discr->checkForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); - _type->checkForUnserialization(tinyInfoITmp3,dataInt); -} - -void MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); - std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); - // - std::vector tmp(tinyInfoD); - int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it - tmp.pop_back(); - std::vector tmp1(tmp.begin(),tmp.end()-sz); - std::vector tmp2(tmp.end()-sz,tmp.end()); - // - _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS); - _nature=(NatureOfField)tinyInfoI[2]; - _type->finishUnserialization(tmp2); - int nbOfElemS=(int)tinyInfoS.size(); - _name=tinyInfoS[nbOfElemS-3]; - _desc=tinyInfoS[nbOfElemS-2]; - setTimeUnit(tinyInfoS[nbOfElemS-1]); -} - -/*! - * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller. - * The values returned must be consulted only in readonly mode. - */ -void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector& arrays) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !"); - _time_discr->getArrays(arrays); - _type->getSerializationIntArray(dataInt); -} - -/*! - * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if - * a current and the \a other meshes are different with use of specified equality - * criteria, and then an exception is thrown. - * \param [in] other - the mesh to use as the field support if this mesh can be - * considered equal to the current mesh. - * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For - * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which - * is used for mesh comparison. - * \param [in] precOnMesh - a precision used to compare nodes of the two meshes. - * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith(). - * \param [in] eps - a precision used at node renumbering (if needed) to compare field - * values at merged nodes. If the values differ more than \a eps, an - * exception is thrown. - * \throw If the mesh is not set. - * \throw If \a other == NULL. - * \throw If any of the meshes is not well defined. - * \throw If the two meshes do not match. - * \throw If field values at merged nodes (if any) deffer more than \a eps. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".
- * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) -{ - if(_mesh==0 || other==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !"); - DataArrayInt *cellCor=0,*nodeCor=0; - other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor); - MEDCouplingAutoRefCountObjectPtr cellCor2(cellCor),nodeCor2(nodeCor); - if(cellCor) - renumberCellsWithoutMesh(cellCor->getConstPointer(),false); - if(nodeCor) - renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); - setMesh(other); -} - -/*! - * Subtracts another field from \a this one in case when the two fields have different - * supporting meshes. The subtraction is performed provided that the tho meshes can be - * considered equal with use of specified equality criteria, else an exception is thrown. - * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if - * necessary) and field values are subtracted. No interpolation is done here, only an - * analysis of two underlying mesh is done to see if the meshes are geometrically - * equivalent.
- * The job of this method consists in calling - * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then - * \a this -= \a f.
- * This method requires that \a f and \a this are coherent (checkCoherency()) and that \a f - * and \a this are coherent for a merge.
- * "DM" in the method name stands for "different meshes". - * \param [in] f - the field to subtract from this. - * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For - * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which - * is used for mesh comparison. - * \param [in] precOnMesh - a precision used to compare nodes of the two meshes. - * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith(). - * \param [in] eps - a precision used at node renumbering (if needed) to compare field - * values at merged nodes. If the values differ more than \a eps, an - * exception is thrown. - * \throw If \a f == NULL. - * \throw If any of the meshes is not set or is not well defined. - * \throw If the two meshes do not match. - * \throw If the two fields are not coherent for merge. - * \throw If field values at merged nodes (if any) deffer more than \a eps. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".
- * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example". - * \endif - * \sa changeUnderlyingMesh(). - */ -void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) -{ - checkCoherency(); - if(!f) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !"); - f->checkCoherency(); - if(!areCompatibleForMerge(f)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !"); - changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps); - operator-=(*f); -} - -/*! - * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the - * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged. - * \param [in] eps - a precision used to compare nodes of the two meshes. - * \param [in] epsOnVals - a precision used to compare field - * values at merged nodes. If the values differ more than \a epsOnVals, an - * exception is thrown. - * \return bool - \c true if some nodes have been merged and hence \a this field lies - * on another mesh. - * \throw If the mesh is of type not inheriting from MEDCouplingPointSet. - * \throw If the mesh is not well defined. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the data array is not set. - * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. - */ -bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) -{ - const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - bool ret; - int ret2; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes(eps,ret,ret2); - if(!ret)//no nodes have been merged. - return ret; - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); - setMesh(meshC2); - return true; -} - -/*! - * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the - * underlying mesh is replaced by a new mesh instance where the coincident nodes are - * merged.
- * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter. - * \param [in] eps - a precision used to compare nodes of the two meshes. - * \param [in] epsOnVals - a precision used to compare field - * values at merged nodes. If the values differ more than \a epsOnVals, an - * exception is thrown. - * \return bool - \c true if some nodes have been merged and hence \a this field lies - * on another mesh. - * \throw If the mesh is of type not inheriting from MEDCouplingPointSet. - * \throw If the mesh is not well defined. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the data array is not set. - * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. - */ -bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) -{ - const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes2 !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - bool ret; - int ret2; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes2(eps,ret,ret2); - if(!ret)//no nodes have been merged. - return ret; - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); - setMesh(meshC2); - return true; -} - -/*! - * Removes from the underlying mesh nodes not used in any cell. If some nodes are - * removed, the underlying mesh is replaced by a new mesh instance where the unused - * nodes are removed.
- * \param [in] epsOnVals - a precision used to compare field - * values at merged nodes. If the values differ more than \a epsOnVals, an - * exception is thrown. - * \return bool - \c true if some nodes have been removed and hence \a this field lies - * on another mesh. - * \throw If the mesh is of type not inheriting from MEDCouplingPointSet. - * \throw If the mesh is not well defined. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the data array is not set. - * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. - */ -bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) -{ - const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - int oldNbOfNodes=meshC2->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipCoordsTraducer(); - if(meshC2->getNumberOfNodes()!=oldNbOfNodes) - { - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); - setMesh(meshC2); - return true; - } - return false; -} - -/*! - * Removes duplicates of cells from the understanding mesh. If some cells are - * removed, the underlying mesh is replaced by a new mesh instance where the cells - * duplicates are removed.
- * \param [in] compType - specifies a cell comparison technique. Meaning of its - * valid values [0,1,2] is explained in the description of - * MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method. - * \param [in] epsOnVals - a precision used to compare field - * values at merged cells. If the values differ more than \a epsOnVals, an - * exception is thrown. - * \return bool - \c true if some cells have been removed and hence \a this field lies - * on another mesh. - * \throw If the mesh is not an instance of MEDCouplingUMesh. - * \throw If the mesh is not well defined. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the data array is not set. - * \throw If field values at merged cells (if any) deffer more than \a epsOnVals. - */ -bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) -{ - const MEDCouplingUMesh *meshC=dynamic_cast(_mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingUMesh *)meshC->deepCpy()); - int oldNbOfCells=meshC2->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipConnectivityTraducer(compType); - if(meshC2->getNumberOfCells()!=oldNbOfCells) - { - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter); - setMesh(meshC2); - return true; - } - return false; -} - -/*! - * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists. - * For the moment, this method is implemented for fields on cells. - * - * \return a newly allocated field double containing the result that the user should deallocate. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const -{ - const MEDCouplingMesh *mesh=getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !"); - if(getTypeOfField()!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !"); - const MEDCouplingAutoRefCountObjectPtr umesh(mesh->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr ret=clone(false); - ret->setMesh(umesh); - DataArrayInt *cellIds=0; - MEDCouplingAutoRefCountObjectPtr mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIds2=cellIds; - ret->setMesh(mesh2); - MEDCouplingAutoRefCountObjectPtr tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end()); - std::vector arrays; - _time_discr->getArrays(arrays); - int i=0; - std::vector newArr(arrays.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > newArr2(arrays.size()); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++) - { - if(*iter) - { - newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - newArr[i]=newArr2[i]; - } - } - ret->setArrays(newArr); - return ret.retn(); -} - -/*! - * Divides every cell of the underlying mesh into simplices (triangles in 2D and - * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new - * mesh instance containing the simplices.
- * \param [in] policy - specifies a pattern used for splitting. For its description, see - * MEDCouplingUMesh::simplexize(). - * \return bool - \c true if some cells have been divided and hence \a this field lies - * on another mesh. - * \throw If \a policy has an invalid value. For valid values, see the description of - * MEDCouplingUMesh::simplexize(). - * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh. - * \throw If the mesh is not well defined. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If the data array is not set. - */ -bool MEDCouplingFieldDouble::simplexize(int policy) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !"); - int oldNbOfCells=_mesh->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr meshC2(_mesh->deepCpy()); - MEDCouplingAutoRefCountObjectPtr arr=meshC2->simplexize(policy); - int newNbOfCells=meshC2->getNumberOfCells(); - if(oldNbOfCells==newNbOfCells) - return false; - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter); - setMesh(meshC2); - return true; -} - -/*! - * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of - * every tensor of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose - * each tuple is calculated from the tuple (t) of \a this field as - * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. - * This new field lies on the same mesh as \a this one. The caller is to delete - * this field using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() != 6. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !"); - MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("DoublyContractedProduct"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble filled with the determinant of a square - * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components. - * The case of 6 components corresponds to that of the upper triangular matrix. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose - * each tuple is the determinant of matrix of the corresponding tuple of \a this - * field. This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !"); - MEDCouplingTimeDiscretization *td=_time_discr->determinant(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Determinant"); - ret->setMesh(getMesh()); - return ret.retn(); -} - - -/*! - * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of - * an upper triangular matrix defined by every tuple of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, - * having 3 components, whose each tuple contains the eigenvalues of the matrix of - * corresponding tuple of \a this field. This new field lies on the same mesh as - * \a this one. The caller is to delete this field using decrRef() as it is no - * more needed. - * \throw If \a this->getNumberOfComponents() != 6. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !"); - MEDCouplingTimeDiscretization *td=_time_discr->eigenValues(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("EigenValues"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of - * an upper triangular matrix defined by every tuple of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, - * having 9 components, whose each tuple contains the eigenvectors of the matrix of - * corresponding tuple of \a this field. This new field lies on the same mesh as - * \a this one. The caller is to delete this field using decrRef() as it is no - * more needed. - * \throw If \a this->getNumberOfComponents() != 6. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !"); - MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("EigenVectors"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of - * a matrix defined by every tuple of \a this field having either 4, 6 or 9 - * components. The case of 6 components corresponds to that of the upper triangular - * matrix. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, - * having the same number of components as \a this one, whose each tuple - * contains the inverse matrix of the matrix of corresponding tuple of \a this - * field. This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !"); - MEDCouplingTimeDiscretization *td=_time_discr->inverse(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Inversion"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble filled with the trace of - * a matrix defined by every tuple of \a this field having either 4, 6 or 9 - * components. The case of 6 components corresponds to that of the upper triangular - * matrix. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, - * having 1 component, whose each tuple is the trace of the matrix of - * corresponding tuple of \a this field. - * This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !"); - MEDCouplingTimeDiscretization *td=_time_discr->trace(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Trace"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of - * a stress tensor defined by every tuple of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, - * having same number of components and tuples as \a this field, - * whose each tuple contains the stress deviator tensor of the stress tensor of - * corresponding tuple of \a this field. This new field lies on the same mesh as - * \a this one. The caller is to delete this field using decrRef() as it is no - * more needed. - * \throw If \a this->getNumberOfComponents() != 6. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !"); - MEDCouplingTimeDiscretization *td=_time_discr->deviator(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Deviator"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble filled with the magnitude of - * every vector of \a this field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, - * having one component, whose each tuple is the magnitude of the vector - * of corresponding tuple of \a this field. This new field lies on the - * same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !"); - MEDCouplingTimeDiscretization *td=_time_discr->magnitude(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Magnitude"); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among - * values of every tuple of \a this field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If the spatial discretization of \a this field is NULL. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !"); - MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - std::ostringstream oss; - oss << "Max_" << getName(); - ret->setName(oss.str()); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Changes number of components in \a this field. If \a newNbOfComp is less - * than \a this->getNumberOfComponents() then each tuple - * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then - * each tuple is populated with \a dftValue to have \a newNbOfComp components. - * \param [in] newNbOfComp - number of components for the new field to have. - * \param [in] dftValue - value assigned to new values added to \a this field. - * \throw If \a this is not allocated. - */ -void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) -{ - _time_discr->changeNbOfComponents(newNbOfComp,dftValue); -} - -/*! - * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field. - * The new MEDCouplingFieldDouble has the same number of tuples but includes components - * specified by \a compoIds parameter. So that getNbOfElems() of the result field - * can be either less, same or more than \a this->getNumberOfValues(). - * \param [in] compoIds - sequence of zero based indices of components to include - * into the new field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If a component index (\a i) is not valid: - * \a i < 0 || \a i >= \a this->getNumberOfComponents(). - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !"); - MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName(getName()); - ret->setMesh(getMesh()); - return ret.retn(); -} - - -/*! - * Copy all components in a specified order from another field. - * The number of tuples in \a this and the other field can be different. - * \param [in] f - the field to copy data from. - * \param [in] compoIds - sequence of zero based indices of components, data of which is - * to be copied. - * \throw If the two fields have different number of data arrays. - * \throw If a data array is set in one of fields and is not set in the other. - * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). - * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). - */ -void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) -{ - _time_discr->setSelectedComponents(f->_time_discr,compoIds); -} - -/*! - * Sorts value within every tuple of \a this field. - * \param [in] asc - if \a true, the values are sorted in ascending order, else, - * in descending order. - * \throw If a data array is not allocated. - */ -void MEDCouplingFieldDouble::sortPerTuple(bool asc) -{ - _time_discr->sortPerTuple(asc); -} - -/*! - * Creates a new MEDCouplingFieldDouble by concatenating two given fields. - * Values of - * the first field precede values of the second field within the result field. - * \param [in] f1 - the first field. - * \param [in] f2 - the second field. - * \return MEDCouplingFieldDouble * - the result field. It is a new instance of - * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() - * as it is no more needed. - * \throw If the fields are not compatible for the merge. - * \throw If the spatial discretization of \a f1 is NULL. - * \throw If the time discretization of \a f1 is NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
- * \ref py_mcfielddouble_MergeFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1->areCompatibleForMerge(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation."); - const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh()); - if(!f1->_time_discr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !"); - if(!f1->_type) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setName(f1->getName()); - ret->setDescription(f1->getDescription()); - if(m1) - { - MEDCouplingAutoRefCountObjectPtr m=m1->mergeMyselfWith(m2); - ret->setMesh(m); - } - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble by concatenating all given fields. - * Values of the *i*-th field precede values of the (*i*+1)-th field within the result. - * If there is only one field in \a a, a deepCopy() (except time information of mesh and - * field) of the field is returned. - * Generally speaking the first field in \a a is used to assign tiny attributes of the - * returned field. - * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate. - * \return MEDCouplingFieldDouble * - the result field. It is a new instance of - * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() - * as it is no more needed. - * \throw If \a a is empty. - * \throw If the fields are not compatible for the merge. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
- * \ref py_mcfielddouble_MergeFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector& a) -{ - if(a.size()<1) - throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > ms(a.size()); - std::vector< const MEDCouplingUMesh *> ms2(a.size()); - std::vector< const MEDCouplingTimeDiscretization *> tds(a.size()); - std::vector::const_iterator it=a.begin(); - const MEDCouplingFieldDouble *ref=(*it++); - if(!ref) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !"); - for(;it!=a.end();it++) - if(!ref->areCompatibleForMerge(*it)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation."); - for(int i=0;i<(int)a.size();i++) - { - if(a[i]->getMesh()) - { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; } - else - { ms[i]=0; ms2[i]=0; } - tds[i]=a[i]->_time_discr; - } - MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds); - td->copyTinyAttrFrom(*(a[0]->_time_discr)); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); - ret->setName(a[0]->getName()); - ret->setDescription(a[0]->getDescription()); - if(ms2[0]) - { - MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::MergeUMeshes(ms2); - m->copyTinyInfoFrom(ms2[0]); - ret->setMesh(m); - } - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields. - * The number of components in the result field is a sum of the number of components of - * given fields. The number of tuples in the result field is same as that of each of given - * arrays. - * Number of tuples in the given fields must be the same. - * \param [in] f1 - a field to include in the result field. - * \param [in] f2 - another field to include in the result field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the fields are not compatible for a meld (areCompatibleForMeld()). - * \throw If any of data arrays is not allocated. - * \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1->areCompatibleForMeld(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, - * so that the i-th tuple of the result field is a sum of products of j-th components of - * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). - * Number of tuples and components in the given fields must be the same. - * \param [in] f1 - a given field. - * \param [in] f2 - another given field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !"); - if(!f1->areStrictlyCompatibleForMulDiv(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret; -} - -/*! - * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, - * so that - * the i-th tuple of the result field is a 3D vector which is a cross - * product of two vectors defined by the i-th tuples of given fields. - * Number of tuples in the given fields must be the same. - * Number of components in the given fields must be 3. - * \param [in] f1 - a given field. - * \param [in] f2 - another given field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If \a f1->getNumberOfComponents() != 3 - * \throw If \a f2->getNumberOfComponents() != 3 - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !"); - if(!f1->areStrictlyCompatibleForMulDiv(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields. - * Number of tuples and components in the given fields must be the same. - * \param [in] f1 - a field to compare values with another one. - * \param [in] f2 - another field to compare values with the first one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
- * \ref py_mcfielddouble_MaxFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !"); - if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields. - * Number of tuples and components in the given fields must be the same. - * \param [in] f1 - a field to compare values with another one. - * \param [in] f2 - another field to compare values with the first one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
- * \ref py_mcfielddouble_MaxFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !"); - if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Returns a copy of \a this field in which sign of all values is reversed. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble - * containing the same number of tuples and components as \a this field. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If a data array is not allocated. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !"); - MEDCouplingTimeDiscretization *td=_time_discr->negate(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setMesh(getMesh()); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of - * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ). - * Number of tuples and components in the given fields must be the same. - * \param [in] f1 - a field to sum up. - * \param [in] f2 - another field to sum up. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !"); - if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Adds values of another MEDCouplingFieldDouble to values of \a this one - * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual(). - * The two fields must have same number of tuples, components and same underlying mesh. - * \param [in] other - the field to add to \a this one. - * \return const MEDCouplingFieldDouble & - a reference to \a this field. - * \throw If \a other is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) -{ - if(!areStrictlyCompatible(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation."); - _time_discr->addEqual(other._time_discr); - return *this; -} - -/*! - * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of - * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ). - * Number of tuples and components in the given fields must be the same. - * \param [in] f1 - a field to subtract from. - * \param [in] f2 - a field to subtract. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !"); - if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Subtract values of another MEDCouplingFieldDouble from values of \a this one - * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual(). - * The two fields must have same number of tuples, components and same underlying mesh. - * \param [in] other - the field to subtract from \a this one. - * \return const MEDCouplingFieldDouble & - a reference to \a this field. - * \throw If \a other is NULL. - * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they - * differ not only in values. - */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) -{ - if(!areStrictlyCompatible(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation."); - _time_discr->substractEqual(other._time_discr); - return *this; -} - -/*! - * Returns a new MEDCouplingFieldDouble containing product values of - * two given fields. There are 2 valid cases. - * 1. The fields have same number of tuples and components. Then each value of - * the result field (_f_) is a product of the corresponding values of _f1_ and - * _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ]. - * 2. The fields have same number of tuples and one field, say _f2_, has one - * component. Then - * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ]. - * - * The two fields must have same number of tuples and same underlying mesh. - * \param [in] f1 - a factor field. - * \param [in] f2 - another factor field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not compatible for multiplication (areCompatibleForMul()), - * i.e. they differ not only in values and possibly number of components. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !"); - if(!f1->areCompatibleForMul(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Multiply values of another MEDCouplingFieldDouble to values of \a this one - * using DataArrayDouble::multiplyEqual(). - * The two fields must have same number of tuples and same underlying mesh. - * There are 2 valid cases. - * 1. The fields have same number of components. Then each value of - * \a other is multiplied to the corresponding value of \a this field, i.e. - * _this_ [ i, j ] *= _other_ [ i, j ]. - * 2. The _other_ field has one component. Then - * _this_ [ i, j ] *= _other_ [ i, 0 ]. - * - * The two fields must have same number of tuples and same underlying mesh. - * \param [in] other - an field to multiply to \a this one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If \a other is NULL. - * \throw If the fields are not strictly compatible for multiplication - * (areCompatibleForMul()), - * i.e. they differ not only in values and possibly in number of components. - */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) -{ - if(!areCompatibleForMul(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation."); - _time_discr->multiplyEqual(other._time_discr); - _nature = NoNature; - return *this; -} - -/*! - * Returns a new MEDCouplingFieldDouble containing division of two given fields. - * There are 2 valid cases. - * 1. The fields have same number of tuples and components. Then each value of - * the result field (_f_) is a division of the corresponding values of \a f1 and - * \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ]. - * 2. The fields have same number of tuples and _f2_ has one component. Then - * _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ]. - * - * \param [in] f1 - a numerator field. - * \param [in] f2 - a denominator field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set. - * The caller is to delete this result field using decrRef() as it is no more - * needed. - * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not compatible for division (areCompatibleForDiv()), - * i.e. they differ not only in values and possibly in number of components. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !"); - if(!f1->areCompatibleForDiv(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Divide values of \a this field by values of another MEDCouplingFieldDouble - * using DataArrayDouble::divideEqual(). - * The two fields must have same number of tuples and same underlying mesh. - * There are 2 valid cases. - * 1. The fields have same number of components. Then each value of - * \a this field is divided by the corresponding value of \a other one, i.e. - * _this_ [ i, j ] /= _other_ [ i, j ]. - * 2. The \a other field has one component. Then - * _this_ [ i, j ] /= _other_ [ i, 0 ]. - * - * \warning No check of division by zero is performed! - * \param [in] other - an field to divide \a this one by. - * \throw If \a other is NULL. - * \throw If the fields are not compatible for division (areCompatibleForDiv()), - * i.e. they differ not only in values and possibly in number of components. - */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) -{ - if(!areCompatibleForDiv(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation."); - _time_discr->divideEqual(other._time_discr); - _nature = NoNature; - return *this; -} - -/*! - * Directly called by MEDCouplingFieldDouble::operator^. - * - * \sa MEDCouplingFieldDouble::operator^ - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !"); - if(!f1->areCompatibleForMul(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->pow(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - return ret.retn(); -} - -/*! - * Directly call MEDCouplingFieldDouble::PowFields static method. - * - * \sa MEDCouplingFieldDouble::PowFields - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const -{ - return PowFields(this,&other); -} - -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other) -{ - if(!areCompatibleForDiv(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation."); - _time_discr->powEqual(other._time_discr); - _nature = NoNature; - return *this; -} - -/*! - * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName. - * If \a fs is empty no file is written. - * The result file is valid provided that no exception is thrown. - * \warning All the fields must be named and lie on the same non NULL mesh. - * \param [in] fileName - the name of a VTK file to write in. - * \param [in] fs - the fields to write. - * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode) - * \throw If \a fs[ 0 ] == NULL. - * \throw If the fields lie not on the same mesh. - * \throw If the mesh is not set. - * \throw If any of the fields has no name. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".
- * \ref py_mcfielddouble_WriteVTK "Here is a Python example". - * \endif - */ -std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary) -{ - if(fs.empty()) - return std::string(); - std::size_t nfs=fs.size(); - if(!fs[0]) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !"); - const MEDCouplingMesh *m=fs[0]->getMesh(); - if(!m) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !"); - for(std::size_t i=1;igetMesh()!=m) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are not lying on a same mesh ! Expected by VTK ! MEDCouplingFieldDouble::setMesh or MEDCouplingFieldDouble::changeUnderlyingMesh can help to that."); - if(!m) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !"); - std::string ret(m->getVTKFileNameOf(fileName)); - MEDCouplingAutoRefCountObjectPtr byteArr; - if(isBinary) - { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } - std::ostringstream coss,noss; - for(std::size_t i=0;igetName()); - if(name.empty()) - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - TypeOfField typ=cur->getTypeOfField(); - if(typ==ON_CELLS) - cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr); - else if(typ==ON_NODES) - cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr); - else - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !"); - } - m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr); - return ret; -} - -void MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingFieldDouble C++ instance at " << this << ". Name : \"" << _name << "\"." << std::endl; - const char *nat=0; - try - { - nat=MEDCouplingNatureOfField::GetRepr(_nature); - stream << "Nature of field : " << nat << ".\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { } - const MEDCouplingFieldDiscretization *fd(_type); - if(!fd) - stream << "No spatial discretization set !"; - else - fd->reprQuickOverview(stream); - stream << std::endl; - if(!_mesh) - stream << "\nNo mesh support defined !"; - else - { - std::ostringstream oss; - _mesh->reprQuickOverview(oss); - std::string tmp(oss.str()); - stream << "\nMesh info : " << tmp.substr(0,tmp.find('\n')); - } - if(_time_discr) - { - const DataArrayDouble *arr=_time_discr->getArray(); - if(arr) - { - stream << "\n\nArray info : "; - arr->reprQuickOverview(stream); - } - else - { - stream << "\n\nNo data array set !"; - } - } -} diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/medtool/src/MEDCoupling/MEDCouplingFieldDouble.hxx deleted file mode 100644 index 065718a65..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDDOUBLE_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELDDOUBLE_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingField.hxx" -#include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingMemArray.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingFieldTemplate; - - class MEDCouplingFieldDouble : public MEDCouplingField - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); - MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit); - MEDCOUPLING_EXPORT std::string getTimeUnit() const; - MEDCOUPLING_EXPORT void synchronizeTimeWithSupport(); - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingField *other); - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingFieldDouble *other); - MEDCOUPLING_EXPORT void copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other); - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT std::string writeVTK(const std::string& fileName, bool isBinary=true) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT bool areCompatibleForMerge(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMul(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForDiv(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT void renumberCellsWithoutMesh(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT void renumberNodes(const int *old2NewBg, double eps=1e-15); - MEDCOUPLING_EXPORT void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15); - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *nodeToCellDiscretization() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cellToNodeDiscretization() const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getTimeDiscretization() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void setNature(NatureOfField nat); - MEDCOUPLING_EXPORT void setTimeTolerance(double val) { _time_discr->setTimeTolerance(val); } - MEDCOUPLING_EXPORT double getTimeTolerance() const { return _time_discr->getTimeTolerance(); } - MEDCOUPLING_EXPORT void setIteration(int it) { _time_discr->setIteration(it); } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _time_discr->setEndIteration(it); } - MEDCOUPLING_EXPORT void setOrder(int order) { _time_discr->setOrder(order); } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _time_discr->setEndOrder(order); } - MEDCOUPLING_EXPORT void setTimeValue(double val) { _time_discr->setTimeValue(val); } - MEDCOUPLING_EXPORT void setEndTimeValue(double val) { _time_discr->setEndTimeValue(val); } - MEDCOUPLING_EXPORT void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); } - MEDCOUPLING_EXPORT void synchronizeTimeWithMesh(); - MEDCOUPLING_EXPORT void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); } - MEDCOUPLING_EXPORT void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); } - MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { return _time_discr->getStartTime(iteration,order); } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { return _time_discr->getEndTime(iteration,order); } - MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return getArray()->getIJ(tupleId,compoId); } - MEDCOUPLING_EXPORT double getIJK(int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT void setArray(DataArrayDouble *array); - MEDCOUPLING_EXPORT void setEndArray(DataArrayDouble *array); - MEDCOUPLING_EXPORT void setArrays(const std::vector& arrs); - MEDCOUPLING_EXPORT const DataArrayDouble *getArray() const { return _time_discr->getArray(); } - MEDCOUPLING_EXPORT DataArrayDouble *getArray() { return _time_discr->getArray(); } - MEDCOUPLING_EXPORT const DataArrayDouble *getEndArray() const { return _time_discr->getEndArray(); } - MEDCOUPLING_EXPORT DataArrayDouble *getEndArray() { return _time_discr->getEndArray(); } - MEDCOUPLING_EXPORT std::vector getArrays() const { std::vector ret; _time_discr->getArrays(ret); return ret; } - MEDCOUPLING_EXPORT double accumulate(int compId) const; - MEDCOUPLING_EXPORT void accumulate(double *res) const; - MEDCOUPLING_EXPORT double getMaxValue() const; - MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT double getMinValue() const; - MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT double getAverageValue() const; - MEDCOUPLING_EXPORT double norm2() const; - MEDCOUPLING_EXPORT double normMax() const; - MEDCOUPLING_EXPORT void getWeightedAverageValue(double *res, bool isWAbs=true) const; - MEDCOUPLING_EXPORT double getWeightedAverageValue(int compId, bool isWAbs=true) const; - MEDCOUPLING_EXPORT double normL1(int compId) const; - MEDCOUPLING_EXPORT void normL1(double *res) const; - MEDCOUPLING_EXPORT double normL2(int compId) const; - MEDCOUPLING_EXPORT void normL2(double *res) const; - MEDCOUPLING_EXPORT double integral(int compId, bool isWAbs) const; - MEDCOUPLING_EXPORT void integral(bool isWAbs, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT void getValueOn(const double *spaceLoc, double *res) const; - MEDCOUPLING_EXPORT void getValueOn(const double *spaceLoc, double time, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const double *spaceLoc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT void applyLin(double a, double b); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble &operator=(double value); - MEDCOUPLING_EXPORT void fillFromAnalytic(int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT void fillFromAnalytic(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void fillFromAnalytic2(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, double val); - MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc2(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc(const std::string& func); - MEDCOUPLING_EXPORT void applyFuncFast32(const std::string& func); - MEDCOUPLING_EXPORT void applyFuncFast64(const std::string& func); - MEDCOUPLING_EXPORT int getNumberOfComponents() const; - MEDCOUPLING_EXPORT int getNumberOfTuples() const; - MEDCOUPLING_EXPORT int getNumberOfValues() const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays); - MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector& tinyInfoI, const DataArrayInt *dataInt, const std::vector& arrays); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt, std::vector& arrays) const; - // - MEDCOUPLING_EXPORT void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15); - MEDCOUPLING_EXPORT void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15); - MEDCOUPLING_EXPORT bool mergeNodes(double eps, double epsOnVals=1e-15); - MEDCOUPLING_EXPORT bool mergeNodes2(double eps, double epsOnVals=1e-15); - MEDCOUPLING_EXPORT bool zipCoords(double epsOnVals=1e-15); - MEDCOUPLING_EXPORT bool zipConnectivity(int compType, double epsOnVals=1e-15); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *extractSlice3D(const double *origin, const double *vec, double eps) const; - MEDCOUPLING_EXPORT bool simplexize(int policy); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *doublyContractedProduct() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *determinant() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *eigenValues() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *eigenVectors() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *inverse() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *trace() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deviator() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *magnitude() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *maxPerTuple() const; - MEDCOUPLING_EXPORT void changeNbOfComponents(int newNbOfComp, double dftValue=0.); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds); - MEDCOUPLING_EXPORT void sortPerTuple(bool asc); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MergeFields(const std::vector& a); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return DotFields(this,&other); } - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return CrossProductFields(this,&other); } - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return MaxFields(this,&other); } - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return MinFields(this,&other); } - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *negate() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return AddFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return SubstractFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return MultiplyFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return DivideFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator^(const MEDCouplingFieldDouble& other) const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator^=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT static std::string WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary=true); - public: - MEDCOUPLING_EXPORT const MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() const { return _time_discr; } - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() { return _time_discr; } - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - protected: - ~MEDCouplingFieldDouble(); - private: - MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); - MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); - MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); - private: - MEDCouplingTimeDiscretization *_time_discr; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.cxx b/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.cxx deleted file mode 100644 index 20d5f283f..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.cxx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingFieldOverTime.hxx" -#include "MEDCouplingMesh.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDCouplingFieldOverTime *MEDCouplingFieldOverTime::New(const std::vector& fs) -{ - return new MEDCouplingFieldOverTime(fs); -} - -double MEDCouplingFieldOverTime::getTimeTolerance() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - if(_fs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::getTimeTolerance : empty set !"); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)!=0) - return (*it)->getTimeTolerance(); - throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::getTimeTolerance : only empty fields in this !"); -} - -void MEDCouplingFieldOverTime::checkCoherency() const -{ - MEDCouplingMultiFields::checkCoherency(); - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((*it)->getTimeDiscretization()==NO_TIME) - { - std::ostringstream oss; oss << "MEDCouplingFieldOverTime::checkCoherency : At rank #" << std::distance(_fs.begin(),it) << " the field has no time !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(_fs.empty()) - return ; - it=_fs.begin(); - const MEDCouplingFieldDouble& ref=*(*(it++)); - int tt1,tt2; - double reft=ref.getEndTime(tt1,tt2); - double eps=getTimeTolerance(); - int id=1; - for(;it!=_fs.end();it++,id++) - { - if(!ref.getMesh()->areCompatibleForMerge((*it)->getMesh())) - { - std::ostringstream oss; oss << "Field slice at rank #" << id << " is not compatible with the first !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - double curt=(*it)->getStartTime(tt1,tt2); - if(curtgetEndTime(tt1,tt2); - } -} - -std::string MEDCouplingFieldOverTime::simpleRepr() const -{ - std::ostringstream ret; - ret << "MEDCouplingFieldOverTime with name : \"" << getName() << "\"\n"; - ret << "Description of MEDCouplingFieldOverTime is : \"" << getDescription() << "\"\n"; - ret << "Number of discretization : " << _fs.size() << "\n"; - ret << "Number of different meshes : "; - std::vector ms; - std::vector refms; - try - { - ms=getDifferentMeshes(refms); - ret << ms.size() << "\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { ret << "Current instance is INVALID !\n"; } - try - { - MEDCouplingDefinitionTime dt=getDefinitionTimeZone(); - dt.appendRepr(ret); - } - catch(INTERP_KERNEL::Exception& /*e*/) - { ret << "Definition zone is INVALID !\n"; } - return ret.str(); -} - -bool MEDCouplingFieldOverTime::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - if(!MEDCouplingMultiFields::isEqual(other,meshPrec,valsPrec)) - return false; - const MEDCouplingFieldOverTime *otherC=dynamic_cast(other); - if(!otherC) - return false; - // to implement - return true; -} - -bool MEDCouplingFieldOverTime::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - if(!MEDCouplingMultiFields::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) - return false; - const MEDCouplingFieldOverTime *otherC=dynamic_cast(other); - if(!otherC) - return false; - // to implement - return true; -} - -std::vector MEDCouplingFieldOverTime::getMeshes() const -{ - checkCoherency(); - return MEDCouplingMultiFields::getMeshes(); -} - -std::vector MEDCouplingFieldOverTime::getDifferentMeshes(std::vector& refs) const -{ - checkCoherency(); - return MEDCouplingMultiFields::getDifferentMeshes(refs); -} - -std::vector MEDCouplingFieldOverTime::getArrays() const -{ - checkCoherency(); - return MEDCouplingMultiFields::getArrays(); -} - -std::vector MEDCouplingFieldOverTime::getDifferentArrays(std::vector< std::vector >& refs) const -{ - checkCoherency(); - return MEDCouplingMultiFields::getDifferentArrays(refs); -} - -MEDCouplingDefinitionTime MEDCouplingFieldOverTime::getDefinitionTimeZone() const -{ - std::vector< std::vector > tmp; - getDifferentArrays(tmp); - std::vector tmp2(_fs.begin(),_fs.end()); - std::vector tmp3; - getDifferentMeshes(tmp3); - return MEDCouplingDefinitionTime(tmp2,tmp3,tmp); -} - -MEDCouplingFieldOverTime::MEDCouplingFieldOverTime(const std::vector& fs):MEDCouplingMultiFields(fs) -{ - checkCoherency(); -} - -MEDCouplingFieldOverTime::MEDCouplingFieldOverTime() -{ -} diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.hxx b/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.hxx deleted file mode 100644 index 4d4351ca7..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDOVERTIME_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELDOVERTIME_HXX__ - -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingDefinitionTime.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingFieldOverTime : public MEDCouplingMultiFields - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldOverTime *New(const std::vector& fs); - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT double getTimeTolerance() const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - //void getIdsToFetch(double time, int& fieldId, int& arrId, int& meshId) const; - //void setFieldOnId(int fieldId, MEDCouplingFieldDouble *f); - //void dispatchPointers(); - MEDCOUPLING_EXPORT std::vector getMeshes() const; - MEDCOUPLING_EXPORT std::vector getDifferentMeshes(std::vector& refs) const; - MEDCOUPLING_EXPORT std::vector getArrays() const; - MEDCOUPLING_EXPORT std::vector getDifferentArrays(std::vector< std::vector >& refs) const; - MEDCOUPLING_EXPORT MEDCouplingDefinitionTime getDefinitionTimeZone() const; - protected: - MEDCOUPLING_EXPORT MEDCouplingFieldOverTime(); - private: - MEDCouplingFieldOverTime(const std::vector& fs); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.cxx b/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.cxx deleted file mode 100644 index 4bb5a3974..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.cxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble& f) -{ - return new MEDCouplingFieldTemplate(f); -} - -/*! - * The user should \b not use this method. Only useful for CORBA serialization/unserialization. - */ -MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(TypeOfField type) -{ - return new MEDCouplingFieldTemplate(type); -} - -MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f):MEDCouplingField(f,false) -{ - forceTimeOfThis(f); - checkCoherency(); -} - -MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(TypeOfField type):MEDCouplingField(type) -{ -} - -void MEDCouplingFieldTemplate::checkCoherency() const -{ - if(_mesh==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldTemplate::checkCoherency : Empty mesh !"); -} - -std::string MEDCouplingFieldTemplate::simpleRepr() const -{ - std::ostringstream ret; - ret << "FieldTemplate with name : \"" << getName() << "\"\n"; - ret << "Description of field is : \"" << getDescription() << "\"\n"; - if(_type) - { ret << "FieldTemplate space discretization is : " << _type->getStringRepr() << "\n"; } - else - { ret << "FieldTemplate has no spatial discretization !\n"; } - ret << "FieldTemplate nature of field is : \"" << MEDCouplingNatureOfField::GetReprNoThrow(_nature) << "\"\n"; - if(_mesh) - ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); - else - ret << "Mesh support information : No mesh set !\n"; - return ret.str(); -} - -std::string MEDCouplingFieldTemplate::advancedRepr() const -{ - return simpleRepr(); -} - -void MEDCouplingFieldTemplate::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !"); - tinyInfo.clear(); - tinyInfo.push_back((int)_type->getEnum()); - tinyInfo.push_back((int)_nature); - std::vector tinyInfo2; - _type->getTinySerializationIntInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size()); -} - -void MEDCouplingFieldTemplate::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !"); - tinyInfo.clear(); - _type->getTinySerializationDbleInformation(tinyInfo); -} - -void MEDCouplingFieldTemplate::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - tinyInfo.clear(); - tinyInfo.push_back(_name); - tinyInfo.push_back(_desc); -} - -void MEDCouplingFieldTemplate::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); - dataInt=0; - std::vector tinyInfoITmp(tinyInfoI.begin()+2,tinyInfoI.end()); - _type->resizeForUnserialization(tinyInfoITmp,dataInt); -} - -void MEDCouplingFieldTemplate::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); - _nature=(NatureOfField)tinyInfoI[1]; - _type->finishUnserialization(tinyInfoD); - _name=tinyInfoS[0]; - _desc=tinyInfoS[1]; -} - -void MEDCouplingFieldTemplate::serialize(DataArrayInt *&dataInt) const -{ - _type->getSerializationIntArray(dataInt); -} - -void MEDCouplingFieldTemplate::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingFieldTemplate C++ instance at " << this << ". Name : \"" << _name << "\"." << std::endl; - const char *nat=0; - try - { - nat=MEDCouplingNatureOfField::GetRepr(_nature); - stream << "Nature of field template : " << nat << ".\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { } - const MEDCouplingFieldDiscretization *fd(_type); - if(!fd) - stream << "No spatial discretization set !"; - else - fd->reprQuickOverview(stream); - stream << std::endl; - if(!_mesh) - stream << "\nNo mesh support defined !"; - else - { - std::ostringstream oss; - _mesh->reprQuickOverview(oss); - std::string tmp(oss.str()); - stream << "\nMesh info : " << tmp.substr(0,tmp.find('\n')); - } -} diff --git a/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx b/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx deleted file mode 100644 index 6fa402cf6..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDTEMPLATE_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELDTEMPLATE_HXX__ - -#include "MEDCouplingField.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingFieldDouble; - /*! - * \brief A field template can be seen as a field without the array of values. - * - * A field template aggregates a MEDCouplingMesh and a spatial discretization object (instance of - * MEDCouplingFieldDiscretization). - * - * MEDCouplingFieldTemplate is the most appropriate type for the preparation of matrix using - * MEDCouplingRemapper::prepareEx, since it contains the minimal information requireds to prepare - * the interpolation matrix. - */ - class MEDCouplingFieldTemplate : public MEDCouplingField - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f); - MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(TypeOfField type); - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - // - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt) const; - // - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - private: - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f); - MEDCouplingFieldTemplate(TypeOfField type); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.cxx deleted file mode 100644 index 4af4bd6c3..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.cxx +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingGaussLocalization.hxx" -#include "CellModel.hxx" - -#include -#include -#include -#include -#include - -ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& w) -try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w) -{ - checkCoherency(); -} -catch(INTERP_KERNEL::Exception& e) -{ - _type=INTERP_KERNEL::NORM_ERROR; - _ref_coord.clear(); - _gauss_coord.clear(); - _weight.clear(); - throw e; -} - -ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) -try:_type(typ) -{ - INTERP_KERNEL::CellModel::GetCellModel(_type); -} -catch(INTERP_KERNEL::Exception& e) -{ - _type=INTERP_KERNEL::NORM_ERROR; - throw e; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setType(INTERP_KERNEL::NormalizedCellType typ) -{ - INTERP_KERNEL::CellModel::GetCellModel(typ);//throws if not found. This is a check - _type=typ; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); - int nbNodes=cm.getNumberOfNodes(); - int dim=cm.getDimension(); - if(!cm.isDynamic()) - { - if((int)_ref_coord.size()!=nbNodes*dim) - { - std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(_gauss_coord.size()!=dim*_weight.size()) - { - std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const -{ - if(_weight.empty()) - return -1; - return (int)_gauss_coord.size()/(int)_weight.size(); -} - -int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const -{ - int dim=getDimension(); - if(dim==0) - return -1; - return (int)_ref_coord.size()/dim; -} - -std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const -{ - std::ostringstream oss; - oss << "CellType : " << INTERP_KERNEL::CellModel::GetCellModel(_type).getRepr() << std::endl; - oss << "Ref coords : "; std::copy(_ref_coord.begin(),_ref_coord.end(),std::ostream_iterator(oss,", ")); oss << std::endl; - oss << "Localization coords : "; std::copy(_gauss_coord.begin(),_gauss_coord.end(),std::ostream_iterator(oss,", ")); oss << std::endl; - oss << "Weight : "; std::copy(_weight.begin(),_weight.end(),std::ostream_iterator(oss,", ")); oss << std::endl; - return oss.str(); -} - -std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getMemorySize() const -{ - std::size_t ret=0; - ret+=_ref_coord.capacity()*sizeof(double); - ret+=_gauss_coord.capacity()*sizeof(double); - ret+=_weight.capacity()*sizeof(double); - return ret; -} - -bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const -{ - if(_type!=other._type) - return false; - if(!AreAlmostEqual(_ref_coord,other._ref_coord,eps)) - return false; - if(!AreAlmostEqual(_gauss_coord,other._gauss_coord,eps)) - return false; - if(!AreAlmostEqual(_weight,other._weight,eps)) - return false; - return true; -} - -double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); - int nbNodes=cm.getNumberOfNodes(); - int dim=cm.getDimension(); - if(ptIdInCell<0 || ptIdInCell>=nbNodes) - throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); - if(comp<0 || comp>=dim) - throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); - return _ref_coord[ptIdInCell*dim+comp]; -} - -double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const -{ - int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); - return _gauss_coord[gaussPtIdInCell*dim+comp]; -} - -double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const -{ - checkCoherencyOfRequest(gaussPtIdInCell,0); - return _weight[gaussPtIdInCell]; -} - -/*! - * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. - * push at the end of tinyInfo its basic serialization info. The size of pushed data is always the same. - * @param tinyInfo inout parameter. - */ -void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector& tinyInfo) const -{ - tinyInfo.push_back((int)_type); - tinyInfo.push_back(getNumberOfPtsInRefCell()); - tinyInfo.push_back(getNumberOfGaussPt()); -} - -/*! - * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. - * push at the end of tinyInfo its basic serialization info. The size of pushed data is \b NOT always the same contrary to pushTinySerializationIntInfo. - * @param tinyInfo inout parameter. - */ -void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector& tinyInfo) const -{ - tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end()); - tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end()); - tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end()); -} - -/*! - * This method operates the exact inverse operation than ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo method. This is one of the last step of unserialization process. - * This method should be called on an object resized by buildNewInstanceFromTinyInfo static method. - * This method takes in argument a pointer 'vals' that point to the begin of double data pushed remotely by pushTinySerializationDblInfo method. - * This method returns the pointer 'vals' with an offset of size what it has been read in this method. - */ -const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals) -{ - const double *work=vals; - std::copy(work,work+_ref_coord.size(),_ref_coord.begin()); - work+=_ref_coord.size(); - std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin()); - work+=_gauss_coord.size(); - std::copy(work,work+_weight.size(),_weight.begin()); - work+=_weight.size(); - return work; -} - -/*! - * This method sets the comp_th component of ptIdInCell_th point coordinate of reference element of type this->_type. - * @throw if not 0<=ptIdInCell=nbNodes) - throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); - if(comp<0 || comp>=dim) - throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); - _ref_coord[ptIdInCell*dim+comp]=newVal; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) -{ - int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); - _gauss_coord[gaussPtIdInCell*dim+comp]=newVal; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) -{ - checkCoherencyOfRequest(gaussPtIdInCell,0); - _weight[gaussPtIdInCell]=newVal; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoords(const std::vector& refCoo) -{ - _ref_coord=refCoo; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoords(const std::vector& gsCoo) -{ - _gauss_coord=gsCoo; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setWeights(const std::vector& w) -{ - _weight=w; -} - -/*! - * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo. - */ -ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData) -{ - std::vector v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]); - return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3); -} - -int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); - int dim=cm.getDimension(); - int nbGsPts=getNumberOfGaussPt(); - if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts) - throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !"); - if(comp<0 || comp>=dim) - throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); - return dim; -} - -bool ParaMEDMEM::MEDCouplingGaussLocalization::AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps) -{ - std::size_t sz=v1.size(); - if(sz!=v2.size()) - return false; - std::vector tmp(sz); - std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus()); - std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun(fabs)); - return *std::max_element(tmp.begin(),tmp.end()) - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - - class MEDCouplingGaussLocalization - { - public: - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& w); - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ); - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const { return _type; } - MEDCOUPLING_EXPORT void setType(INTERP_KERNEL::NormalizedCellType typ); - MEDCOUPLING_EXPORT int getNumberOfGaussPt() const { return (int)_weight.size(); } - MEDCOUPLING_EXPORT int getDimension() const; - MEDCOUPLING_EXPORT int getNumberOfPtsInRefCell() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT std::size_t getMemorySize() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const; - MEDCOUPLING_EXPORT void pushTinySerializationIntInfo(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void pushTinySerializationDblInfo(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT const double *fillWithValues(const double *vals); - // - MEDCOUPLING_EXPORT const std::vector& getRefCoords() const { return _ref_coord; } - MEDCOUPLING_EXPORT double getRefCoord(int ptIdInCell, int comp) const; - MEDCOUPLING_EXPORT const std::vector& getGaussCoords() const { return _gauss_coord; } - MEDCOUPLING_EXPORT double getGaussCoord(int gaussPtIdInCell, int comp) const; - MEDCOUPLING_EXPORT const std::vector& getWeights() const { return _weight; } - MEDCOUPLING_EXPORT double getWeight(int gaussPtIdInCell, double newVal) const; - MEDCOUPLING_EXPORT void setRefCoord(int ptIdInCell, int comp, double newVal); - MEDCOUPLING_EXPORT void setGaussCoord(int gaussPtIdInCell, int comp, double newVal); - MEDCOUPLING_EXPORT void setWeight(int gaussPtIdInCell, double newVal); - MEDCOUPLING_EXPORT void setRefCoords(const std::vector& refCoo); - MEDCOUPLING_EXPORT void setGaussCoords(const std::vector& gsCoo); - MEDCOUPLING_EXPORT void setWeights(const std::vector& w); - // - MEDCOUPLING_EXPORT static MEDCouplingGaussLocalization BuildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData); - MEDCOUPLING_EXPORT static bool AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps); - private: - int checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const; - private: - INTERP_KERNEL::NormalizedCellType _type; - std::vector _ref_coord; - std::vector _gauss_coord; - std::vector _weight; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingIMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingIMesh.cxx deleted file mode 100644 index e7a4ae0ac..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingIMesh.cxx +++ /dev/null @@ -1,1495 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingIMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1) -{ - _origin[0]=0.; _origin[1]=0.; _origin[2]=0.; - _dxyz[0]=0.; _dxyz[1]=0.; _dxyz[2]=0.; - _structure[0]=0; _structure[1]=0; _structure[2]=0; -} - -MEDCouplingIMesh::MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_space_dim(other._space_dim),_axis_unit(other._axis_unit) -{ - _origin[0]=other._origin[0]; _origin[1]=other._origin[1]; _origin[2]=other._origin[2]; - _dxyz[0]=other._dxyz[0]; _dxyz[1]=other._dxyz[1]; _dxyz[2]=other._dxyz[2]; - _structure[0]=other._structure[0]; _structure[1]=other._structure[1]; _structure[2]=other._structure[2]; -} - -MEDCouplingIMesh::~MEDCouplingIMesh() -{ -} - -MEDCouplingIMesh *MEDCouplingIMesh::New() -{ - return new MEDCouplingIMesh; -} - -MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCouplingIMesh); - ret->setName(meshName); - ret->setSpaceDimension(spaceDim); - ret->setNodeStruct(nodeStrctStart,nodeStrctStop); - ret->setOrigin(originStart,originStop); - ret->setDXYZ(dxyzStart,dxyzStop); - return ret.retn(); -} - -MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingIMesh(*this,recDeepCpy); -} - -/*! - * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis. - * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone. - * - * \param [in] ghostLev - the ghost level expected - * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller. - * \throw if \a ghostLev < 0. - */ -MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !"); - checkCoherency(); - int spaceDim(getSpaceDimension()); - double origin[3],dxyz[3]; - int structure[3]; - for(int i=0;i ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim)); - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop) -{ - checkSpaceDimension(); - int sz((int)std::distance(nodeStrctStart,nodeStrctStop)); - if(sz!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setNodeStruct : input vector of node structure has not the right size ! Or change space dimension before calling it !"); - std::copy(nodeStrctStart,nodeStrctStop,_structure); - declareAsNew(); -} - -std::vector MEDCouplingIMesh::getNodeStruct() const -{ - checkSpaceDimension(); - return std::vector(_structure,_structure+_space_dim); -} - -void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop) -{ - checkSpaceDimension(); - int sz((int)std::distance(originStart,originStop)); - if(sz!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setOrigin : input vector of origin vector has not the right size ! Or change space dimension before calling it !"); - std::copy(originStart,originStop,_origin); - declareAsNew(); -} - -std::vector MEDCouplingIMesh::getOrigin() const -{ - checkSpaceDimension(); - return std::vector(_origin,_origin+_space_dim); -} - -void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop) -{ - checkSpaceDimension(); - int sz((int)std::distance(dxyzStart,dxyzStop)); - if(sz!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setDXYZ : input vector of dxyz vector has not the right size ! Or change space dimension before calling it !"); - std::copy(dxyzStart,dxyzStop,_dxyz); - declareAsNew(); -} - -std::vector MEDCouplingIMesh::getDXYZ() const -{ - checkSpaceDimension(); - return std::vector(_dxyz,_dxyz+_space_dim); -} - -void MEDCouplingIMesh::setAxisUnit(const std::string& unitName) -{ - _axis_unit=unitName; - declareAsNew(); -} - -std::string MEDCouplingIMesh::getAxisUnit() const -{ - return _axis_unit; -} - -/*! - * This method returns the measure of any cell in \a this. - * This specific method of image grid mesh utilizes the fact that any cell in \a this have the same measure. - * The value returned by this method is those used to feed the returned field in the MEDCouplingIMesh::getMeasureField. - * - * \sa getMeasureField - */ -double MEDCouplingIMesh::getMeasureOfAnyCell() const -{ - checkCoherency(); - int dim(getSpaceDimension()); - double ret(1.); - for(int i=0;i ret(MEDCouplingCMesh::New()); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception& ) { } - int spaceDim(getSpaceDimension()); - std::vector infos(buildInfoOnComponents()); - for(int i=0;i arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]); - arr->iota(); arr->applyLin(_dxyz[i],_origin[i]); - ret->setCoordsAt(i,arr); - } - return ret.retn(); -} - -/*! - * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain - * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension(). - * The origin of \a this will be not touched only spacing and node structure will be changed. - * This method can be useful for AMR users. - */ -void MEDCouplingIMesh::refineWithFactor(const std::vector& factors) -{ - if((int)factors.size()!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !"); - checkCoherency(); - std::vector structure(_structure,_structure+3); - std::vector dxyz(_dxyz,_dxyz+3); - for(int i=0;i<_space_dim;i++) - { - if(factors[i]<=0) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int factAbs(std::abs(factors[i])); - double fact2(1./(double)factors[i]); - structure[i]=(_structure[i]-1)*factAbs+1; - dxyz[i]=fact2*_dxyz[i]; - } - std::copy(structure.begin(),structure.end(),_structure); - std::copy(dxyz.begin(),dxyz.end(),_dxyz); - declareAsNew(); -} - -/*! - * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this. - * - * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell. - * - * \throw if \a this does not pass the \c checkCoherency test. - */ -MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const -{ - checkCoherency(); - int spaceDim(getSpaceDimension()),nodeSt[3]; - double dxyz[3]; - for(int i=0;i=2) - { - nodeSt[i]=2; - dxyz[i]=(_structure[i]-1)*_dxyz[i]; - } - else - { - nodeSt[i]=_structure[i]; - dxyz[i]=_dxyz[i]; - } - } - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim)); - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) - * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh - * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. - * - * \param [in] coarseSt The cell structure of coarse mesh. - * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh - * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. - * \param [in] facts The refinement coefficient per axis. - * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. - * - * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine - */ -void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) -{ - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !"); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTuplesFine(fineDA->getNumberOfTuples()); - if(nbOfTuplesInFineExp==0) - { - if(nbTuplesFine==0) - return ; - else - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !"); - } - if(nbTuplesFine%nbOfTuplesInFineExp!=0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !"); - int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); - if(nbTuplesFine!=fact*nbOfTuplesInFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom - double *outPtr(coarseDA->getPointer()); - const double *inPtr(fineDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first),fact0(facts[0]); - for(int i=0;i()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - break; - } - case 2: - { - int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]); - for(int j=0;j()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - } - kk+=coarseSt[0]; - } - break; - } - case 3: - { - int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); - for(int k=0;k()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - } - } - } - kk+=coarseSt[0]*coarseSt[1]; - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !"); - } -} - -/*! - * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) - * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh - * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. - * - * \param [in] coarseSt The cell structure of coarse mesh. - * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh - * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. - * \param [in] facts The refinement coefficient per axis. - * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. - * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. - * - * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost - */ -void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !"); - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !"); - std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); - std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); - if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - double *outPtr(coarseDA->getPointer()); - const double *inPtr(fineDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]); - inPtr+=ghostSize*nbCompo; - for(int i=0;i()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - break; - } - case 2: - { - int nxwg(coarseSt[0]+2*ghostSize); - int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]); - inPtr+=(dims[0]*fact0+2*ghostSize)*ghostSize*nbCompo; - for(int j=0;j()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - inPtr+=ghostSize*nbCompo; - } - kk+=nxwg; - } - break; - } - case 3: - { - int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)); - int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); - inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo; - for(int k=0;k()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - inPtr+=ghostSize*nbCompo; - } - } - inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo; - } - kk+=nxywg; - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !"); - } -} - -/*! - * This method spreads the values of coarse data \a coarseDA into \a fineDA. - * - * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. - * \param [in] coarseSt The cell structure of coarse mesh. - * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh - * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. - * \param [in] facts The refinement coefficient per axis. - * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse - */ -void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts) -{ - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !"); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTuplesFine(fineDA->getNumberOfTuples()); - if(nbTuplesFine%nbOfTuplesInFineExp!=0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !"); - int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); - if(nbTuplesFine!=fact*nbOfTuplesInFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom - double *outPtr(fineDA->getPointer()); - const double *inPtr(coarseDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first),fact0(facts[0]); - for(int i=0;i& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !"); - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !"); - std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); - std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); - if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - double *outPtr(fineDA->getPointer()); - const double *inPtr(coarseDA->begin()); - // - switch(meshDim) - { - case 1: - { - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]); - int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)); - int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !"); - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !"); - std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); - std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); - if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - double *outPtr(fineDA->getPointer()); - const double *inPtr(coarseDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i MEDCouplingIMesh::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - const MEDCouplingIMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingStructuredMesh::copyTinyStringsFrom(other); - declareAsNew(); -} - -bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingIMesh *otherC(dynamic_cast(other)); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingIMesh !"; - return false; - } - if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason)) - return false; - if(_axis_unit!=otherC->_axis_unit) - { - reason="The units of axis are not the same !"; - return false; - } - return true; -} - -bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingIMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - std::string tmp; - return isEqualWithoutConsideringStrInternal(other,prec,tmp); -} - -bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - const MEDCouplingIMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_space_dim!=otherC->_space_dim) - { - std::ostringstream oss; - oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !"; - return false; - } - checkSpaceDimension(); - for(int i=0;i<_space_dim;i++) - { - if(fabs(_origin[i]-otherC->_origin[i])>prec) - { - std::ostringstream oss; - oss << "The origin of this and other differs at " << i << " !"; - reason=oss.str(); - return false; - } - } - for(int i=0;i<_space_dim;i++) - { - if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec) - { - std::ostringstream oss; - oss << "The delta of this and other differs at " << i << " !"; - reason=oss.str(); - return false; - } - } - for(int i=0;i<_space_dim;i++) - { - if(_structure[i]!=otherC->_structure[i]) - { - std::ostringstream oss; - oss << "The structure of this and other differs at " << i << " !"; - reason=oss.str(); - return false; - } - } - return true; -} - -void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !"); -} - -/*! - * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too). - * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same ! - */ -void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); -} - -void MEDCouplingIMesh::checkCoherency() const -{ - checkSpaceDimension(); - for(int i=0;i<_space_dim;i++) - if(_structure[i]<1) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCouplingIMesh::checkCoherency1(double eps) const -{ - checkCoherency(); -} - -void MEDCouplingIMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -void MEDCouplingIMesh::getNodeGridStructure(int *res) const -{ - checkSpaceDimension(); - std::copy(_structure,_structure+_space_dim,res); -} - -std::vector MEDCouplingIMesh::getNodeGridStructure() const -{ - checkSpaceDimension(); - std::vector ret(_structure,_structure+_space_dim); - return ret; -} - -MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - if(dim!=(int)cellPart.size()) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - double retOrigin[3]={0.,0.,0.}; - int retStruct[3]={0,0,0}; - MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); - for(int i=0;i=_structure[i]) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(myDelta<0 || myDelta>_structure[i]) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : Along dimension #" << i << " the number of nodes is " << _structure[i] << ", and you are requesting for " << myDelta << " nodes wide range !" << std::endl; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retOrigin[i]=_origin[i]+startNode*_dxyz[i]; - retStruct[i]=myDelta; - } - ret->setNodeStruct(retStruct,retStruct+dim); - ret->setOrigin(retOrigin,retOrigin+dim); - ret->checkCoherency(); - return ret.retn(); -} - -/*! - * Return the space dimension of \a this. - */ -int MEDCouplingIMesh::getSpaceDimension() const -{ - return _space_dim; -} - -void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - int tmp[3]; - int spaceDim(getSpaceDimension()); - getSplitNodeValues(tmp); - int tmp2[3]; - GetPosFromId(nodeId,spaceDim,tmp,tmp2); - for(int j=0;j3) - return ret.str(); - ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator(ret," ")); ret << "\n"; - ret << "The origin position is [" << _axis_unit << "]: "; - std::copy(_origin,_origin+spaceDim,std::ostream_iterator(ret," ")); ret << "\n"; - ret << "The intervals along axis are : "; - std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator(ret," ")); ret << "\n"; - return ret.str(); -} - -std::string MEDCouplingIMesh::advancedRepr() const -{ - return simpleRepr(); -} - -void MEDCouplingIMesh::getBoundingBox(double *bbox) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - for(int idim=0; idim1) - coeff=_structure[idim]-1; - bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff; - } -} - -/*! - * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this - * mesh.
- * For 1D cells, the returned field contains lengths.
- * For 2D cells, the returned field contains areas.
- * For 3D cells, the returned field contains volumes. - * \param [in] isAbs - a not used parameter. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells - * and one time . The caller is to delete this field using decrRef() as it is no - * more needed. - */ -MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const -{ - checkCoherency(); - std::string name="MeasureOfMesh_"; - name+=getName(); - int nbelem(getNumberOfCells()); - MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); - field->setName(name); - DataArrayDouble* array(DataArrayDouble::New()); - array->alloc(nbelem,1); - array->fillWithValue(getMeasureOfAnyCell()); - field->setArray(array) ; - array->decrRef(); - field->setMesh(const_cast(this)); - field->synchronizeTimeWithMesh(); - return field; -} - -/*! - * not implemented yet ! - */ -MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !"); - //return 0; -} - -int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const -{ - int dim(getSpaceDimension()),ret(0),coeff(1); - for(int i=0;i=0 && tmpgetSpaceDimension(). - */ -void MEDCouplingIMesh::translate(const double *vector) -{ - checkSpaceDimension(); - int dim(getSpaceDimension()); - std::transform(_origin,_origin+dim,vector,_origin,std::plus()); - declareAsNew(); -} - -/*! - * Applies scaling transformation to all nodes of \a this mesh. - * \param [in] point - coordinates of a scaling center. This array is to be of - * size \a this->getSpaceDimension() at least. - * \param [in] factor - a scale factor. - */ -void MEDCouplingIMesh::scale(const double *point, double factor) -{ - checkSpaceDimension(); - int dim(getSpaceDimension()); - std::transform(_origin,_origin+dim,point,_origin,std::minus()); - std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies(),factor)); - std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies(),factor)); - std::transform(_origin,_origin+dim,point,_origin,std::plus()); - declareAsNew(); -} - -MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - //not implemented yet ! - return 0; -} - -/*! - * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh. - * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a - * this->getNumberOfNodes() tuples per \a this->getSpaceDimension() - * components. The caller is to delete this array using decrRef() as it is - * no more needed. - */ -DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes()); - ret->alloc(nbNodes,spaceDim); - double *pt(ret->getPointer()); - ret->setInfoOnComponents(buildInfoOnComponents()); - int tmp2[3],tmp[3]; - getSplitNodeValues(tmp); - for(int i=0;igetNumberOfCells() tuples per \a this->getSpaceDimension() - * components. The caller is to delete this array using decrRef() as it is - * no more needed. - */ -DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3]; - ret->alloc(nbCells,spaceDim); - double *pt(ret->getPointer()),shiftOrigin[3]; - std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies(),0.5)); - std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus()); - getSplitCellValues(tmp); - ret->setInfoOnComponents(buildInfoOnComponents()); - for(int i=0;i& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time(getTime(it,order)); - tinyInfo.clear(); - tinyInfoD.clear(); - littleStrings.clear(); - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); - littleStrings.push_back(getTimeUnit()); - littleStrings.push_back(getAxisUnit()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfo.push_back(_space_dim); - tinyInfo.insert(tinyInfo.end(),_structure,_structure+3); - tinyInfoD.push_back(time); - tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3); - tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3); -} - -void MEDCouplingIMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - a1->alloc(0,1); - a2->alloc(0,1); -} - -void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); - a1->alloc(0,1); - a2=DataArrayDouble::New(); - a2->alloc(0,1); -} - -void MEDCouplingIMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setAxisUnit(littleStrings[3]); - setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); - _space_dim=tinyInfo[2]; - _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5]; - _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3]; - _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6]; - declareAsNew(); -} - -void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - checkCoherency(); - std::ostringstream extent,origin,spacing; - for(int i=0;i<3;i++) - { - if(i<_space_dim) - { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; } - else - { extent << "0 0 "; origin << "0 "; spacing << "0 "; } - } - ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n"; - ofs << " \n"; - ofs << " \n" << pointData << std::endl; - ofs << " \n"; - ofs << " \n" << cellData << std::endl; - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << "."; - if(_space_dim<0 || _space_dim>3) - return ; - stream << "\n"; - std::ostringstream stream0,stream1; - int nbNodes(1),nbCells(0); - bool isPb(false); - for(int i=0;i<_space_dim;i++) - { - char tmp('X'+i); - int tmpNodes(_structure[i]); - stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ")."; - if(i!=_space_dim-1) - stream1 << std::endl; - if(tmpNodes>=1) - nbNodes*=tmpNodes; - else - isPb=true; - if(tmpNodes>=2) - nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1); - } - if(!isPb) - { - stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes; - stream << stream0.str(); - if(_space_dim>0) - stream << std::endl; - } - stream << stream1.str(); -} - -std::string MEDCouplingIMesh::getVTKFileExtension() const -{ - return std::string("vti"); -} - -std::string MEDCouplingIMesh::getVTKDataSetType() const -{ - return std::string("ImageData"); -} - -std::vector MEDCouplingIMesh::buildInfoOnComponents() const -{ - checkSpaceDimension(); - int dim(getSpaceDimension()); - std::vector ret(dim); - for(int i=0;i3) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !"); -} - -int MEDCouplingIMesh::FindIntRoot(int val, int order) -{ - if(order==0) - return 1; - if(val<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !"); - if(order==1) - return val; - if(order!=2 && order!=3) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !"); - double valf((double)val); - if(order==2) - { - double retf(sqrt(valf)); - int ret((int)retf); - if(ret*ret!=val) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !"); - return ret; - } - else//order==3 - { - double retf(std::pow(val,0.3333333333333333)); - int ret((int)retf),ret2(ret+1); - if(ret*ret*ret!=val && ret2*ret2*ret2!=val) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !"); - if(ret*ret*ret==val) - return ret; - else - return ret2; - } -} - -void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - double *outPtrWork(outPtr); - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); - int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! - for(int jg=0;jg= ghostlev - for(int i=0;i& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - double *outPtr2(outPtr); - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); - int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! - for(int jg=0;jg= ghostlev - outPtr2+=fact0*nbCompo*dims[0]; - for(int ig=0;ig getNodeStruct() const; - MEDCOUPLING_EXPORT void setOrigin(const double *originStart, const double *originStop); - MEDCOUPLING_EXPORT std::vector getOrigin() const; - MEDCOUPLING_EXPORT void setDXYZ(const double *dxyzStart, const double *dxyzStop); - MEDCOUPLING_EXPORT std::vector getDXYZ() const; - MEDCOUPLING_EXPORT void setAxisUnit(const std::string& unitName); - MEDCOUPLING_EXPORT std::string getAxisUnit() const; - MEDCOUPLING_EXPORT double getMeasureOfAnyCell() const; - MEDCOUPLING_EXPORT MEDCouplingCMesh *convertToCartesian() const; - MEDCOUPLING_EXPORT void refineWithFactor(const std::vector& factors); - MEDCOUPLING_EXPORT MEDCouplingIMesh *asSingleCell() const; - MEDCOUPLING_EXPORT static void CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA); - MEDCOUPLING_EXPORT static void CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize); - MEDCOUPLING_EXPORT static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts); - MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - // - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingIMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingIMesh *buildWithGhost(int ghostLev) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return IMAGE_GRID; } - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - // tools - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - //some useful methods - MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; - MEDCOUPLING_EXPORT std::vector getNodeGridStructure() const; - MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const; - //serialisation-unserialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - MEDCouplingIMesh(); - MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCpy); - ~MEDCouplingIMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - bool isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const; - std::vector buildInfoOnComponents() const; - void checkSpaceDimension() const; - static void CheckSpaceDimension(int spaceDim); - static int FindIntRoot(int val, int order); - static void SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - static void SpreadCoarseToFineGhostZone2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - private: - int _space_dim; - double _origin[3]; - double _dxyz[3]; - int _structure[3]; - std::string _axis_unit; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingMatrix.cxx b/medtool/src/MEDCoupling/MEDCouplingMatrix.cxx deleted file mode 100644 index 4f0172dc4..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMatrix.cxx +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#include "MEDCouplingMatrix.hxx" - -#include "InterpKernelMatrixTools.hxx" - -using namespace ParaMEDMEM; - -DenseMatrix *DenseMatrix::New(int nbRows, int nbCols) -{ - return new DenseMatrix(nbRows,nbCols); -} - -DenseMatrix *DenseMatrix::New(DataArrayDouble *array, int nbRows, int nbCols) -{ - return new DenseMatrix(array,nbRows,nbCols); -} - -DenseMatrix *DenseMatrix::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr arr(getData()->deepCpy()); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(arr,getNumberOfRows(),getNumberOfCols())); - return ret.retn(); -} - -DenseMatrix *DenseMatrix::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(const_cast(getData()),getNumberOfRows(),getNumberOfCols())); - return ret.retn(); -} - -std::size_t DenseMatrix::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(DenseMatrix); -} - -std::vector DenseMatrix::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const DataArrayDouble *)_data); - return ret; -} - -void DenseMatrix::updateTime() const -{ - const DataArrayDouble *pt(_data); - if(pt) - updateTimeWith(*pt); -} - -/*! - * This method scratch \a this to use a new input. The shape of \a this can be modified freely without any constraints. - * - * \param [in] array - The array containing data that is expected to be taken as new data. - * \param [in] nbRows - The new number of rows (>0 or -1). If -1, the current number of rows will be taken. - * \param [in] nbCols - The new number of columns (>0 or -1). If -1, the current number of cols will be taken. - * - * \sa reShape - */ -void DenseMatrix::reBuild(DataArrayDouble *array, int nbRows, int nbCols) -{ - int nbr(getNumberOfRowsExt(nbRows)),nbc(getNumberOfColsExt(nbCols)); - CheckArraySizes(array,nbr,nbc); - DataArrayDouble *data(_data); - if(data!=array) - { - _data=array; _data->incrRef(); - declareAsNew(); - } - if(nbr!=_nb_rows) - { - _nb_rows=nbr; - declareAsNew(); - } - if(nbc!=_nb_cols) - { - _nb_cols=nbc; - declareAsNew(); - } -} - -/*! - * This method does \b not change the content of the data in \a this. It only changes the shape (with a same number of elements in the matrix). - * If the number of elements needs to be changed call reBuild method instead. - * - * \param [in] nbRows - The new number of rows (>0) - * \param [in] nbCols - The new number of columns (>0) - * \throw if the \c nbRows*nbCols is not equal to \c this->getNbOfElems() - * \sa reBuild - */ -void DenseMatrix::reShape(int nbRows, int nbCols) -{ - if(nbRows<0 || nbCols<0) - throw INTERP_KERNEL::Exception("DenseMatrix::reShape : number of rows and number of cols must be > 0 both !"); - if(nbRows*nbCols!=getNbOfElems()) - throw INTERP_KERNEL::Exception("DenseMatrix::reShape : This method is designed to change only the shape ! Number of elements must remain the same !"); - if(_nb_rows!=nbRows) - { - _nb_rows=nbRows; - declareAsNew(); - } - if(_nb_cols!=nbCols) - { - _nb_cols=nbCols; - declareAsNew(); - } -} - -void DenseMatrix::transpose() -{ - const MemArray& mem(getData()->accessToMemArray()); - double *pt(mem.toNoInterlace(getNumberOfCols())); - std::copy(pt,pt+getNbOfElems(),getData()->getPointer());//declareAsNew done here automatically by getPointer - free(pt); - std::swap(_nb_rows,_nb_cols); - updateTime(); -} - -bool DenseMatrix::isEqual(const DenseMatrix& other, double eps) const -{ - std::string tmp; - return isEqualIfNotWhy(other,eps,tmp); -} - -bool DenseMatrix::isEqualIfNotWhy(const DenseMatrix& other, double eps, std::string& reason) const -{ - if(_nb_rows!=other._nb_rows) - { - std::ostringstream oss; oss << "Number of rows differs (" << _nb_rows << "!=" << other._nb_rows << ") !"; - reason+=oss.str(); - return false; - } - if(_nb_cols!=other._nb_cols) - { - std::ostringstream oss; oss << "Number of cols differs (" << _nb_cols << "!=" << other._nb_cols << ") !"; - reason+=oss.str(); - return false; - } - std::string tmp1; - if(!_data->isEqualIfNotWhy(*other._data,eps,tmp1)) - { - reason+="Data differs : "+tmp1; - return false; - } - return true; -} - -DataArrayDouble *DenseMatrix::matVecMult(const DataArrayDouble *vec) const -{ - return MatVecMult(this,vec); -} - -DataArrayDouble *DenseMatrix::MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec) -{ - if(!mat || !vec) - throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : input matrix or vec is NULL !"); - vec->checkAllocated(); - if(vec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : input vector must have only one component !"); - if(vec->getNumberOfTuples()!=mat->getNumberOfCols()) - throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : Number of columns of this must be equal to number of tuples of vec !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(mat->getNumberOfRows(),1); - INTERP_KERNEL::matrixProduct(mat->getData()->begin(),mat->getNumberOfRows(),mat->getNumberOfCols(),vec->begin(),vec->getNumberOfTuples(),1,ret->getPointer()); - return ret.retn(); -} - -DenseMatrix *DenseMatrix::Add(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::Add : input matrices must be not NULL !"); - CheckSameSize(a1,a2); - MEDCouplingAutoRefCountObjectPtr data(DataArrayDouble::Add(a1->getData(),a2->getData())); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(data,a1->getNumberOfRows(),a1->getNumberOfCols())); - return ret.retn(); -} - -void DenseMatrix::addEqual(const DenseMatrix *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DenseMatrix::addEqual : other must be not NULL !"); - CheckSameSize(this,other); - getData()->addEqual(other->getData()); -} - -DenseMatrix *DenseMatrix::Substract(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::Substract : input matrices must be not NULL !"); - CheckSameSize(a1,a2); - MEDCouplingAutoRefCountObjectPtr data(DataArrayDouble::Substract(a1->getData(),a2->getData())); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(data,a1->getNumberOfRows(),a1->getNumberOfCols())); - return ret.retn(); -} - -void DenseMatrix::substractEqual(const DenseMatrix *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DenseMatrix::substractEqual : other must be not NULL !"); - CheckSameSize(this,other); - getData()->substractEqual(other->getData()); -} - -DenseMatrix *DenseMatrix::Multiply(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::Multiply : input matrices must be not NULL !"); - CheckCompatibleSizeForMul(a1,a2); - int nbr(a1->getNumberOfRows()),nbc(a2->getNumberOfCols()); - MEDCouplingAutoRefCountObjectPtr data(DataArrayDouble::New()); data->alloc(nbr*nbc,1); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(data,a1->getNumberOfRows(),a2->getNumberOfCols())); - INTERP_KERNEL::matrixProduct(a1->getData()->begin(),a1->getNumberOfRows(),a1->getNumberOfCols(),a2->getData()->begin(),a2->getNumberOfRows(),a2->getNumberOfCols(),data->getPointer()); - return ret.retn(); -} - -DenseMatrix *DenseMatrix::Multiply(const DenseMatrix *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2 || !a2->isAllocated()) - throw INTERP_KERNEL::Exception("DenseMatrix::Multiply #2 : input matrices must be not NULL and a2 allocated !"); - if(a2->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DenseMatrix::Multiply #2 : The 2nd member must have exactly one component !"); - MEDCouplingAutoRefCountObjectPtr a2Bis(DenseMatrix::New(const_cast(a2),a2->getNumberOfTuples(),1)); - return DenseMatrix::Multiply(a1,a2Bis); -} - -DenseMatrix::~DenseMatrix() -{ -} - -DenseMatrix::DenseMatrix(int nbRows, int nbCols):_nb_rows(nbRows),_nb_cols(nbCols),_data(DataArrayDouble::New()) -{ - if(_nb_rows<0 || _nb_cols<0) - throw INTERP_KERNEL::Exception("constructor of DenseMatrix : number of rows and number of cols must be > 0 both !"); - int nbOfTuples(_nb_rows*_nb_cols); - _data->alloc(nbOfTuples,1); -} - -DenseMatrix::DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols):_nb_rows(nbRows),_nb_cols(nbCols) -{ - CheckArraySizes(array,_nb_rows,_nb_cols); - _data=array; _data->incrRef(); -} - -int DenseMatrix::getNumberOfRowsExt(int nbRows) const -{ - if(nbRows<-1) - throw INTERP_KERNEL::Exception("DenseMatrix::getNumberOfRowsExt : invalid input must be >= -1 !"); - if(nbRows==-1) - return _nb_rows; - else - return nbRows; -} - -int DenseMatrix::getNumberOfColsExt(int nbCols) const -{ - if(nbCols<-1) - throw INTERP_KERNEL::Exception("DenseMatrix::getNumberOfColsExt : invalid input must be >= -1 !"); - if(nbCols==-1) - return _nb_cols; - else - return nbCols; -} - -void DenseMatrix::checkValidData() const -{ - if(!getData()) - throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data is NULL !"); - if(!getData()->isAllocated()) - throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data is not allocated !"); - if(getData()->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data has not 1 component !"); -} - -void DenseMatrix::CheckArraySizes(DataArrayDouble *array, int nbRows, int nbCols) -{ - if(nbRows<0 || nbCols<0) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : number of rows and number of cols must be > 0 both !"); - if(!array || !array->isAllocated()) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : input array is empty or not allocated !"); - if(array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : input array must have exactly one component !"); - std::size_t nbr((std::size_t)nbRows),nbc((std::size_t)nbCols); - if(nbr*nbc!=array->getNbOfElems()) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : the number of elems in input array is not equal to the product of nbRows and nbCols !"); -} - -void DenseMatrix::CheckSameSize(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : a1 or a2 is NULL !"); - a1->checkValidData(); a2->checkValidData(); - if(a1->getNumberOfRows()!=a2->getNumberOfRows()) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : number of rows mismatches !"); - if(a1->getNumberOfCols()!=a2->getNumberOfCols()) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : number of columns mismatches !"); - -} - -void DenseMatrix::CheckCompatibleSizeForMul(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckCompatibleSizeForMul : a1 or a2 is NULL !"); - a1->checkValidData(); a2->checkValidData(); - if(a1->getNumberOfCols()!=a2->getNumberOfRows()) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckCompatibleSizeForMul : number of cols of a1 must be equal to number of rows of a2 !"); -} - diff --git a/medtool/src/MEDCoupling/MEDCouplingMatrix.hxx b/medtool/src/MEDCoupling/MEDCouplingMatrix.hxx deleted file mode 100644 index 93c7f6502..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMatrix.hxx +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay - -#ifndef __PARAMEDMEM_MEDCOUPLINGMATRIX_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMATRIX_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -namespace ParaMEDMEM -{ - /*! - * The aim of this class is \b NOT to reimplement all linear algebra but only to store a dense matrix. - * It only provides basic set/get and basic operations and bindings to linear algebra libraries (numpy/scipy) and a compatible format to Petsc. - */ - class DenseMatrix : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static DenseMatrix *New(int nbRows, int nbCols); - MEDCOUPLING_EXPORT static DenseMatrix *New(DataArrayDouble *array, int nbRows, int nbCols); - MEDCOUPLING_EXPORT DenseMatrix *deepCpy() const; - MEDCOUPLING_EXPORT DenseMatrix *shallowCpy() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void updateTime() const; - // - MEDCOUPLING_EXPORT int getNumberOfRows() const { return _nb_rows; } - MEDCOUPLING_EXPORT int getNumberOfCols() const { return _nb_cols; } - MEDCOUPLING_EXPORT int getNbOfElems() const { return _nb_rows*_nb_cols; } - MEDCOUPLING_EXPORT void reBuild(DataArrayDouble *array, int nbRows=-1, int nbCols=-1); - MEDCOUPLING_EXPORT void reShape(int nbRows, int nbCols); - MEDCOUPLING_EXPORT void transpose(); - // - MEDCOUPLING_EXPORT bool isEqual(const DenseMatrix& other, double eps) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DenseMatrix& other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT DataArrayDouble *matVecMult(const DataArrayDouble *vec) const; - MEDCOUPLING_EXPORT static DataArrayDouble *MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec); - MEDCOUPLING_EXPORT static DenseMatrix *Add(const DenseMatrix *a1, const DenseMatrix *a2); - MEDCOUPLING_EXPORT void addEqual(const DenseMatrix *other); - MEDCOUPLING_EXPORT static DenseMatrix *Substract(const DenseMatrix *a1, const DenseMatrix *a2); - MEDCOUPLING_EXPORT void substractEqual(const DenseMatrix *other); - MEDCOUPLING_EXPORT static DenseMatrix *Multiply(const DenseMatrix *a1, const DenseMatrix *a2); - MEDCOUPLING_EXPORT static DenseMatrix *Multiply(const DenseMatrix *a1, const DataArrayDouble *a2); - // - MEDCOUPLING_EXPORT const DataArrayDouble *getData() const { return _data; } - MEDCOUPLING_EXPORT DataArrayDouble *getData() { return _data; } - private: - ~DenseMatrix(); - DenseMatrix(int nbRows, int nbCols); - DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols); - int getNumberOfRowsExt(int nbRows) const; - int getNumberOfColsExt(int nbCols) const; - void checkValidData() const; - static void CheckArraySizes(DataArrayDouble *array, int nbRows, int nbCols); - static void CheckSameSize(const DenseMatrix *a1, const DenseMatrix *a2); - static void CheckCompatibleSizeForMul(const DenseMatrix *a1, const DenseMatrix *a2); - private: - int _nb_rows; - int _nb_cols; - MEDCouplingAutoRefCountObjectPtr _data; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingMemArray.cxx b/medtool/src/MEDCoupling/MEDCouplingMemArray.cxx deleted file mode 100644 index 998ac654e..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMemArray.cxx +++ /dev/null @@ -1,11865 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingMemArray.txx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "BBTree.txx" -#include "GenMathFormulae.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "InterpKernelExprParser.hxx" - -#include -#include -#include -#include -#include -#include - -typedef double (*MYFUNCPTR)(double); - -using namespace ParaMEDMEM; - -template -void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const -{ - const double *coordsPtr=getConstPointer(); - BBTreePts myTree(bbox,0,0,nbNodes,prec); - std::vector isDone(nbNodes); - for(int i=0;i intersectingElems; - myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems); - if(intersectingElems.size()>1) - { - std::vector commonNodes; - for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) - if(*it!=i) - if(*it>=limitNodeId) - { - commonNodes.push_back(*it); - isDone[*it]=true; - } - if(!commonNodes.empty()) - { - cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1); - c->pushBackSilent(i); - c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); - } - } - } - } -} - -template -void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts& myTree, const double *pos, int nbOfTuples, double eps, - DataArrayInt *c, DataArrayInt *cI) -{ - for(int i=0;i intersectingElems; - myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems); - std::vector commonNodes; - for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) - commonNodes.push_back(*it); - cI->pushBackSilent(cI->back()+(int)commonNodes.size()); - c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); - } -} - -template -void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res) -{ - double distOpt(dist); - const double *p(pos); - int *r(res); - for(int i=0;i::max()) - { - distOpt=std::max(ret,1e-4); - *r=elem; - break; - } - else - { distOpt=2*distOpt; continue; } - } - } -} - -std::size_t DataArray::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz1=_name.capacity(); - std::size_t sz2=_info_on_compo.capacity(); - std::size_t sz3=0; - for(std::vector::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) - sz3+=(*it).capacity(); - return sz1+sz2+sz3; -} - -std::vector DataArray::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * Sets the attribute \a _name of \a this array. - * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. - * \param [in] name - new array name - */ -void DataArray::setName(const std::string& name) -{ - _name=name; -} - -/*! - * Copies textual data from an \a other DataArray. The copied data are - * - the name attribute, - * - the information of components. - * - * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos". - * - * \param [in] other - another instance of DataArray to copy the textual data from. - * \throw If number of components of \a this array differs from that of the \a other. - */ -void DataArray::copyStringInfoFrom(const DataArray& other) -{ - if(_info_on_compo.size()!=other._info_on_compo.size()) - throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !"); - _name=other._name; - _info_on_compo=other._info_on_compo; -} - -void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) -{ - int nbOfCompoOth=other.getNumberOfComponents(); - std::size_t newNbOfCompo=compoIds.size(); - for(std::size_t i=0;i=nbOfCompoOth || compoIds[i]<0) - { - std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::size_t i=0;i& compoIds, const DataArray& other) -{ - int nbOfCompo=getNumberOfComponents(); - std::size_t partOfCompoToSet=compoIds.size(); - if((int)partOfCompoToSet!=other.getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !"); - for(std::size_t i=0;i=nbOfCompo || compoIds[i]<0) - { - std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::size_t i=0;i::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++) - stream << "\"" << *iter << "\" "; - stream << "\n"; -} - -std::string DataArray::cppRepr(const std::string& varName) const -{ - std::ostringstream ret; - reprCppStream(varName,ret); - return ret.str(); -} - -/*! - * Sets information on all components. To know more on format of this information - * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \param [in] info - a vector of strings. - * \throw If size of \a info differs from the number of components of \a this. - */ -void DataArray::setInfoOnComponents(const std::vector& info) -{ - if(getNumberOfComponents()!=(int)info.size()) - { - std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _info_on_compo=info; -} - -/*! - * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true - * type of \a this and \a aBase. - * - * \throw If \a aBase and \a this do not have the same type. - * - * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3. - */ -void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!aBase) - throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !"); - DataArrayDouble *this1(dynamic_cast(this)); - DataArrayInt *this2(dynamic_cast(this)); - DataArrayChar *this3(dynamic_cast(this)); - const DataArrayDouble *a1(dynamic_cast(aBase)); - const DataArrayInt *a2(dynamic_cast(aBase)); - const DataArrayChar *a3(dynamic_cast(aBase)); - if(this1 && a1) - { - this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); - return ; - } - if(this2 && a2) - { - this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); - return ; - } - if(this3 && a3) - { - this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); - return ; - } - throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !"); -} - -std::vector DataArray::getVarsOnComponent() const -{ - int nbOfCompo=(int)_info_on_compo.size(); - std::vector ret(nbOfCompo); - for(int i=0;i DataArray::getUnitsOnComponent() const -{ - int nbOfCompo=(int)_info_on_compo.size(); - std::vector ret(nbOfCompo); - for(int i=0;i=0) - return _info_on_compo[i]; - else - { - std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Returns the var part of the full information of the \a i-th component. - * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then - * \c getVarOnComponent(0) returns "SIGXY". - * If a unit part of information is not detected by presence of - * two square brackets, then the full information is returned. - * To read more about the component information format, see - * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \param [in] i - the index (zero based) of the component of interest. - * \return std::string - a string containing the var information, or the full info. - * \throw If \a i is not a valid component index. - */ -std::string DataArray::getVarOnComponent(int i) const -{ - if(i<(int)_info_on_compo.size() && i>=0) - { - return GetVarNameFromInfo(_info_on_compo[i]); - } - else - { - std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Returns the unit part of the full information of the \a i-th component. - * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then - * \c getUnitOnComponent(0) returns " N/m^2". - * If a unit part of information is not detected by presence of - * two square brackets, then an empty string is returned. - * To read more about the component information format, see - * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \param [in] i - the index (zero based) of the component of interest. - * \return std::string - a string containing the unit information, if any, or "". - * \throw If \a i is not a valid component index. - */ -std::string DataArray::getUnitOnComponent(int i) const -{ - if(i<(int)_info_on_compo.size() && i>=0) - { - return GetUnitFromInfo(_info_on_compo[i]); - } - else - { - std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Returns the var part of the full component information. - * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY". - * If a unit part of information is not detected by presence of - * two square brackets, then the whole \a info is returned. - * To read more about the component information format, see - * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \param [in] info - the full component information. - * \return std::string - a string containing only var information, or the \a info. - */ -std::string DataArray::GetVarNameFromInfo(const std::string& info) -{ - std::size_t p1=info.find_last_of('['); - std::size_t p2=info.find_last_of(']'); - if(p1==std::string::npos || p2==std::string::npos) - return info; - if(p1>p2) - return info; - if(p1==0) - return std::string(); - std::size_t p3=info.find_last_not_of(' ',p1-1); - return info.substr(0,p3+1); -} - -/*! - * Returns the unit part of the full component information. - * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2". - * If a unit part of information is not detected by presence of - * two square brackets, then an empty string is returned. - * To read more about the component information format, see - * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \param [in] info - the full component information. - * \return std::string - a string containing only unit information, if any, or "". - */ -std::string DataArray::GetUnitFromInfo(const std::string& info) -{ - std::size_t p1=info.find_last_of('['); - std::size_t p2=info.find_last_of(']'); - if(p1==std::string::npos || p2==std::string::npos) - return std::string(); - if(p1>p2) - return std::string(); - return info.substr(p1+1,p2-p1-1); -} - -/*! - * This method put in info format the result of the merge of \a var and \a unit. - * The standard format for that is "var [unit]". - * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo. - */ -std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) -{ - std::ostringstream oss; - oss << var << " [" << unit << "]"; - return oss.str(); -} - -/*! - * Returns a new DataArray by concatenating all given arrays, so that (1) the number - * of tuples in the result array is a sum of the number of tuples of given arrays and (2) - * the number of component in the result array is same as that of each of given arrays. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type. - * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar). - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arrs are NULL. - * \throw If all not null arrays in \a arrs have not the same type. - * \throw If getNumberOfComponents() of arrays within \a arrs. - */ -DataArray *DataArray::Aggregate(const std::vector& arrs) -{ - std::vector arr2; - for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) - if(*it) - arr2.push_back(*it); - if(arr2.empty()) - throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !"); - std::vector arrd; - std::vector arri; - std::vector arrc; - for(std::vector::const_iterator it=arr2.begin();it!=arr2.end();it++) - { - const DataArrayDouble *a=dynamic_cast(*it); - if(a) - { arrd.push_back(a); continue; } - const DataArrayInt *b=dynamic_cast(*it); - if(b) - { arri.push_back(b); continue; } - const DataArrayChar *c=dynamic_cast(*it); - if(c) - { arrc.push_back(c); continue; } - throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !"); - } - if(arr2.size()==arrd.size()) - return DataArrayDouble::Aggregate(arrd); - if(arr2.size()==arri.size()) - return DataArrayInt::Aggregate(arri); - if(arr2.size()==arrc.size()) - return DataArrayChar::Aggregate(arrc); - throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !"); -} - -/*! - * Sets information on a component specified by an index. - * To know more on format of this information - * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \warning Don't pass NULL as \a info! - * \param [in] i - the index (zero based) of the component of interest. - * \param [in] info - the string containing the information. - * \throw If \a i is not a valid component index. - */ -void DataArray::setInfoOnComponent(int i, const std::string& info) -{ - if(i<(int)_info_on_compo.size() && i>=0) - _info_on_compo[i]=info; - else - { - std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Sets information on all components. This method can change number of components - * at certain conditions; if the conditions are not respected, an exception is thrown. - * The number of components can be changed in \a this only if \a this is not allocated. - * The condition of number of components must not be changed. - * - * To know more on format of the component information see - * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". - * \param [in] info - a vector of component infos. - * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated() - */ -void DataArray::setInfoAndChangeNbOfCompo(const std::vector& info) -{ - if(getNumberOfComponents()!=(int)info.size()) - { - if(!isAllocated()) - _info_on_compo=info; - else - { - std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " and this is already allocated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - _info_on_compo=info; -} - -void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const -{ - if(getNumberOfTuples()!=nbOfTuples) - { - std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const -{ - if(getNumberOfComponents()!=nbOfCompo) - { - std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const -{ - if(getNbOfElems()!=nbOfElems) - { - std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const -{ - if(getNumberOfTuples()!=other.getNumberOfTuples()) - { - std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(getNumberOfComponents()!=other.getNumberOfComponents()) - { - std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const -{ - checkNbOfTuples(nbOfTuples,msg); - checkNbOfComps(nbOfCompo,msg); -} - -/*! - * Simply this method checks that \b value is in [0,\b ref). - */ -void DataArray::CheckValueInRange(int ref, int value, const std::string& msg) -{ - if(value<0 || value>=ref) - { - std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method checks that [\b start, \b end) is compliant with ref length \b value. - * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported. - */ -void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg) -{ - if(start<0 || start>=value) - { - if(value!=start || end!=start) - { - std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(end<0 || end>value) - { - std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg) -{ - if(value<0 || value>ref) - { - std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, - * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh... - * - * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work. - * - * \param [in] start - the start of the input slice of the whole work to perform splitted into slices. - * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices. - * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices. - * \param [in] sliceId - the slice id considered - * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced) - * \param [out] startSlice - the start of the slice considered - * \param [out] stopSlice - the stop of the slice consided - * - * \throw If \a step == 0 - * \throw If \a nbOfSlices not > 0 - * \throw If \a sliceId not in [0,nbOfSlices) - */ -void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) -{ - if(nbOfSlices<=0) - { - std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(sliceId<0 || sliceId>=nbOfSlices) - { - std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice"); - int minNbOfElemsPerSlice=nbElems/nbOfSlices; - startSlice=start+minNbOfElemsPerSlice*step*sliceId; - if(sliceId 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return (end-1-begin)/step+1; -} - -int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg) -{ - if(step==0) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !"); - if(end0) - { - std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(begin 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(begin!=end) - return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1; - else - return 0; -} - -int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) -{ - if(step!=0) - { - if(step>0) - { - if(begin<=value && value=value && value>end) - { - if((begin-value)%(-step)==0) - return (begin-value)/(-step); - else - return -1; - } - else - return -1; - } - } - else - return -1; -} - -/*! - * Returns a new instance of DataArrayDouble. The caller is to delete this array - * using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::New() -{ - return new DataArrayDouble; -} - -/*! - * Checks if raw data is allocated. Read more on the raw data - * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. - * \return bool - \a true if the raw data is allocated, \a false else. - */ -bool DataArrayDouble::isAllocated() const -{ - return getConstPointer()!=0; -} - -/*! - * Checks if raw data is allocated and throws an exception if it is not the case. - * \throw If the raw data is not allocated. - */ -void DataArrayDouble::checkAllocated() const -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); -} - -/*! - * This method desallocated \a this without modification of informations relative to the components. - * After call of this method, DataArrayDouble::isAllocated will return false. - * If \a this is already not allocated, \a this is let unchanged. - */ -void DataArrayDouble::desallocate() -{ - _mem.destroy(); -} - -std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - sz*=sizeof(double); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - -/*! - * Returns the only one value in \a this, if and only if number of elements - * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. - * \return double - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -double DataArrayDouble::doubleValue() const -{ - if(isAllocated()) - { - if(getNbOfElems()==1) - { - return *getConstPointer(); - } - else - throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !"); -} - -/*! - * Checks the number of tuples. - * \return bool - \a true if getNumberOfTuples() == 0, \a false else. - * \throw If \a this is not allocated. - */ -bool DataArrayDouble::empty() const -{ - checkAllocated(); - return getNumberOfTuples()==0; -} - -/*! - * Returns a full copy of \a this. For more info on copying data arrays see - * \ref MEDCouplingArrayBasicsCopyDeep. - * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to - * delete this array using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::deepCpy() const -{ - return new DataArrayDouble(*this); -} - -/*! - * Returns either a \a deep or \a shallow copy of this array. For more info see - * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. - * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. - * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy - * == \a true) or \a this instance (if \a dCpy == \a false). - */ -DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const -{ - if(dCpy) - return deepCpy(); - else - { - incrRef(); - return const_cast(this); - } -} - -/*! - * Copies all the data from another DataArrayDouble. For more info see - * \ref MEDCouplingArrayBasicsCopyDeepAssign. - * \param [in] other - another instance of DataArrayDouble to copy data from. - * \throw If the \a other is not allocated. - */ -void DataArrayDouble::cpyFrom(const DataArrayDouble& other) -{ - other.checkAllocated(); - int nbOfTuples=other.getNumberOfTuples(); - int nbOfComp=other.getNumberOfComponents(); - allocIfNecessary(nbOfTuples,nbOfComp); - std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; - double *pt=getPointer(); - const double *ptI=other.getConstPointer(); - for(std::size_t i=0;igetNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -void DataArrayDouble::iota(double init) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); - double *ptr=getPointer(); - int ntuples=getNumberOfTuples(); - for(int i=0;igetNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -bool DataArrayDouble::isUniform(double val, double eps) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - const double *w=getConstPointer(); - const double *end2=w+nbOfTuples; - const double vmin=val-eps; - const double vmax=val+eps; - for(;w!=end2;w++) - if(*wvmax) - return false; - return true; -} - -/*! - * Sorts values of the array. - * \param [in] asc - \a true means ascending order, \a false, descending. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - */ -void DataArrayDouble::sort(bool asc) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !"); - _mem.sort(asc); - declareAsNew(); -} - -/*! - * Reverse the array values. - * \throw If \a this->getNumberOfComponents() < 1. - * \throw If \a this is not allocated. - */ -void DataArrayDouble::reverse() -{ - checkAllocated(); - _mem.reverse(getNumberOfComponents()); - declareAsNew(); -} - -/*! - * Checks that \a this array is consistently **increasing** or **decreasing** in value, - * with at least absolute difference value of |\a eps| at each step. - * If not an exception is thrown. - * \param [in] increasing - if \a true, the array values should be increasing. - * \param [in] eps - minimal absolute difference between the neighbor values at which - * the values are considered different. - * \throw If sequence of values is not strictly monotonic in agreement with \a - * increasing arg. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this is not allocated. - */ -void DataArrayDouble::checkMonotonic(bool increasing, double eps) const -{ - if(!isMonotonic(increasing,eps)) - { - if (increasing) - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); - else - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); - } -} - -/*! - * Checks that \a this array is consistently **increasing** or **decreasing** in value, - * with at least absolute difference value of |\a eps| at each step. - * \param [in] increasing - if \a true, array values should be increasing. - * \param [in] eps - minimal absolute difference between the neighbor values at which - * the values are considered different. - * \return bool - \a true if values change in accordance with \a increasing arg. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this is not allocated. - */ -bool DataArrayDouble::isMonotonic(bool increasing, double eps) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !"); - int nbOfElements=getNumberOfTuples(); - const double *ptr=getConstPointer(); - if(nbOfElements==0) - return true; - double ref=ptr[0]; - double absEps=fabs(eps); - if(increasing) - { - for(int i=1;i(ref-absEps)) - return false; - ref=ptr[i]; - } - return true; - } -} - -/*! - * Returns a textual and human readable representation of \a this instance of - * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python. - * \return std::string - text describing \a this DataArrayDouble. - * - * \sa reprNotTooLong, reprZip - */ -std::string DataArrayDouble::repr() const -{ - std::ostringstream ret; - reprStream(ret); - return ret.str(); -} - -std::string DataArrayDouble::reprZip() const -{ - std::ostringstream ret; - reprZipStream(ret); - return ret.str(); -} - -/*! - * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not - * printed out to avoid to consume too much space in interpretor. - * \sa repr - */ -std::string DataArrayDouble::reprNotTooLong() const -{ - std::ostringstream ret; - reprNotTooLongStream(ret); - return ret.str(); -} - -void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const -{ - static const char SPACE[4]={' ',' ',' ',' '}; - checkAllocated(); - std::string idt(indent,' '); - ofs.precision(17); - ofs << idt << "::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) - if(!(*it).empty()) - areAllEmpty=false; - if(!areAllEmpty) - for(std::size_t i=0;i<_info_on_compo.size();i++) - ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\""; - // - if(byteArr) - { - ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">"; - INTERP_KERNEL::AutoPtr tmp(new float[getNbOfElems()]); - float *pt(tmp); - // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp); - for(const double *src=begin();src!=end();src++,pt++) - *pt=float(*src); - const char *data(reinterpret_cast((float *)tmp)); - std::size_t sz(getNbOfElems()*sizeof(float)); - byteArr->insertAtTheEnd(data,data+sz); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else - { - ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt; - std::copy(begin(),end(),std::ostream_iterator(ofs," ")); - } - ofs << std::endl << idt << "\n"; -} - -void DataArrayDouble::reprStream(std::ostream& stream) const -{ - stream << "Name of double array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayDouble::reprZipStream(std::ostream& stream) const -{ - stream << "Name of double array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const -{ - stream << "Name of double array : \"" << _name << "\"\n"; - reprNotTooLongWithoutNameStream(stream); -} - -void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.repr(getNumberOfComponents(),stream); -} - -void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.reprZip(getNumberOfComponents(),stream); -} - -void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.reprNotTooLong(getNumberOfComponents(),stream); -} - -void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); - const double *data=getConstPointer(); - stream.precision(17); - stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl; - if(nbTuples*nbComp>=1) - { - stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={"; - std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator(stream,",")); - stream << data[nbTuples*nbComp-1] << "};" << std::endl; - stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl; - } - else - stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl; - stream << varName << "->setName(\"" << getName() << "\");" << std::endl; -} - -/*! - * Method that gives a quick overvien of \a this for python. - */ -void DataArrayDouble::reprQuickOverview(std::ostream& stream) const -{ - static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; - stream << "DataArrayDouble C++ instance at " << this << ". "; - if(isAllocated()) - { - int nbOfCompo=(int)_info_on_compo.size(); - if(nbOfCompo>=1) - { - int nbOfTuples=getNumberOfTuples(); - stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; - reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); - } - else - stream << "Number of components : 0."; - } - else - stream << "*** No data allocated ****"; -} - -void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const -{ - const double *data=begin(); - int nbOfTuples=getNumberOfTuples(); - int nbOfCompo=(int)_info_on_compo.size(); - std::ostringstream oss2; oss2 << "["; - oss2.precision(17); - std::string oss2Str(oss2.str()); - bool isFinished=true; - for(int i=0;i1) - { - oss2 << "("; - for(int j=0;j=0 !"); - checkAllocated(); - _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); - declareAsNew(); -} - -/*! - * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this - * array to the new one. - * \return DataArrayInt * - the new instance of DataArrayInt. - */ -DataArrayInt *DataArrayDouble::convertToIntArr() const -{ - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - int *dest=ret->getPointer(); - // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest); - for(const double *src=begin();src!=end();src++,dest++) - *dest=(int)*src; - ret->copyStringInfoFrom(*this); - return ret; -} - -/*! - * Returns a new DataArrayDouble holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::fromNoInterlace() const -{ - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !"); - double *tab=_mem.fromNoInterlace(getNumberOfComponents()); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Returns a new DataArrayDouble holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::toNoInterlace() const -{ - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !"); - double *tab=_mem.toNoInterlace(getNumberOfComponents()); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Permutes values of \a this array as required by \a old2New array. The values are - * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains - * the same as in \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old value. - */ -void DataArrayDouble::renumberInPlace(const int *old2New) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - double *tmp=new double[nbTuples*nbOfCompo]; - const double *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -void DataArrayDouble::renumberInPlaceR(const int *new2Old) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - double *tmp=new double[nbTuples*nbOfCompo]; - const double *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * giving a new position for i-th old value. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a copy of \a this array with values permuted as required by \a new2Old array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of - * tuples in the result array remains the same as in \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is - * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. - * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all - * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which - * \a old2New[ i ] is negative, is missing from the result array. - * For more info on renumbering see \ref numbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old tuple and giving negative position for - * for i-th old tuple that should be omitted. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(newNbOfTuple,nbOfCompo); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;i=0) - std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * For more info on renumbering see \ref numbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const -{ - return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples()); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * This method is equivalent to selectByTupleId() except that it prevents coping data - * from behind the end of \a this array. - * For more info on renumbering see \ref numbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). - */ -DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - if(*w>=0 && *wgetNumberOfTuples) !"); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayDouble contains every - * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th - * tuple. Indices of the selected tuples are the same as ones returned by the Python - * command \c range( \a bg, \a end2, \a step ). - * This method is equivalent to selectByTupleIdSafe() except that the input array is - * not constructed explicitly. - * For more info on renumbering see \ref numbering. - * \param [in] bg - index of the first tuple to copy from \a this array. - * \param [in] end2 - index of the tuple before which the tuples to copy are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \sa DataArrayDouble::substr. - */ -DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : "); - ret->alloc(newNbOfTuples,nbComp); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer()+bg*nbComp; - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges - * of tuples specified by \a ranges parameter. - * For more info on renumbering see \ref numbering. - * \param [in] ranges - std::vector of std::pair's each of which defines a range - * of tuples in [\c begin,\c end) format. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a end < \a begin. - * \throw If \a end > \a this->getNumberOfTuples(). - * \throw If \a this is not allocated. - */ -DataArray *DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(0,nbOfComp); - ret->copyStringInfoFrom(*this); - return ret; - } - int ref=ranges.front().first; - int nbOfTuples=0; - bool isIncreasing=true; - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - { - if((*it).first<=(*it).second) - { - if((*it).first>=0 && (*it).second<=nbOfTuplesThis) - { - nbOfTuples+=(*it).second-(*it).first; - if(isIncreasing) - isIncreasing=ref<=(*it).first; - ref=(*it).second; - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(isIncreasing && nbOfTuplesThis==nbOfTuples) - return deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const double *src=getConstPointer(); - double *work=ret->getPointer(); - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayDouble contains all - * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before - * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). - * This method is a specialization of selectByTupleId2(). - * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. - * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. - * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a tupleIdBg < 0. - * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). - \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). - * \sa DataArrayDouble::selectByTupleId2 - */ -DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(trueEnd-tupleIdBg,nbComp); - ret->copyStringInfoFrom(*this); - std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret.retn(); -} - -/*! - * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less - * than \a this->getNumberOfComponents() then the result array is shorten as each tuple - * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is - * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp - * components. - * \param [in] newNbOfComp - number of components for the new array to have. - * \param [in] dftValue - value assigned to new values added to the new array. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const double *oldc=getConstPointer(); - double *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - return ret.retn(); -} - -/*! - * Changes the number of components within \a this array so that its raw data **does - * not** change, instead splitting this data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \param [in] newNbOfComp - number of components for \a this array to have. - * \throw If \a this is not allocated - * \throw If getNbOfElems() % \a newNbOfCompo != 0. - * \throw If \a newNbOfCompo is lower than 1. - * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). - * \warning This method erases all (name and unit) component info set before! - */ -void DataArrayDouble::rearrange(int newNbOfCompo) -{ - checkAllocated(); - if(newNbOfCompo<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !"); - std::size_t nbOfElems=getNbOfElems(); - if(nbOfElems%newNbOfCompo!=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !"); - if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); - _info_on_compo.clear(); - _info_on_compo.resize(newNbOfCompo); - declareAsNew(); -} - -/*! - * Changes the number of components within \a this array to be equal to its number - * of tuples, and inversely its number of tuples to become equal to its number of - * components. So that its raw data **does not** change, instead splitting this - * data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! - * \throw If \a this is not allocated. - * \sa rearrange() - */ -void DataArrayDouble::transpose() -{ - checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - rearrange(nbOfTuples); -} - -/*! - * Returns a copy of \a this array composed of selected components. - * The new DataArrayDouble has the same number of tuples but includes components - * specified by \a compoIds parameter. So that getNbOfElems() of the result array - * can be either less, same or more than \a this->getNbOfElems(). - * \param [in] compoIds - sequence of zero based indices of components to include - * into the new array. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If a component index (\a i) is not valid: - * \a i < 0 || \a i >= \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example". - * \endif - */ -DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - std::size_t newNbOfCompo=compoIds.size(); - int oldNbOfCompo=getNumberOfComponents(); - for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) - if((*it)<0 || (*it)>=oldNbOfCompo) - { - std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfTuples=getNumberOfTuples(); - ret->alloc(nbOfTuples,(int)newNbOfCompo); - ret->copyPartOfStringInfoFrom(*this,compoIds); - const double *oldc=getConstPointer(); - double *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double)); - double *w=newArr; - const double *inp1=getConstPointer(); - const double *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;igetNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this. - * - * \param [in] other - the array having the same number of components than \a this. - * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has. - * \sa DataArrayDouble::findCommonTuples - */ -bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !"); - checkAllocated(); other->checkAllocated(); - if(getNumberOfComponents()!=other->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !"); - MEDCouplingAutoRefCountObjectPtr a=DataArrayDouble::Aggregate(this,other); - DataArrayInt *c=0,*ci=0; - a->findCommonTuples(prec,getNumberOfTuples(),c,ci); - MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); - int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples); - MEDCouplingAutoRefCountObjectPtr ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1); - tupleIds=ret1.retn(); - return newNbOfTuples==getNumberOfTuples(); -} - -/*! - * Searches for tuples coincident within \a prec tolerance. Each tuple is considered - * as coordinates of a point in getNumberOfComponents()-dimensional space. The - * distance separating two points is computed with the infinite norm. - * - * Indices of coincident tuples are stored in output arrays. - * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2". - * - * This method is typically used by MEDCouplingPointSet::findCommonNodes() and - * MEDCouplingUMesh::mergeNodes(). - * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are - * considered not coincident. - * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident - * tuples have id strictly lower than \a limitTupleId then they are not returned. - * \param [out] comm - the array holding ids (== indices) of coincident tuples. - * \a comm->getNumberOfComponents() == 1. - * \a comm->getNumberOfTuples() == \a commIndex->back(). - * \param [out] commIndex - the array dividing all indices stored in \a comm into - * groups of (indices of) coincident tuples. Its every value is a tuple - * index where a next group of tuples begins. For example the second - * group of tuples in \a comm is described by following range of indices: - * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1 - * gives the number of groups of coincident tuples. - * \throw If \a this is not allocated. - * \throw If the number of components is not in [1,2,3,4]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". - * - * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". - * \endif - * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe - */ -void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work - throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4."); - - int nbOfTuples=getNumberOfTuples(); - // - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); - switch(nbOfCompo) - { - case 4: - findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - case 3: - findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - case 2: - findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - case 1: - findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - default: - throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !"); - } - comm=c.retn(); - commIndex=cI.retn(); -} - -/*! - * - * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance. - * \a nbTimes should be at least equal to 1. - * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. - * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1. - */ -DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !"); - if(nbTimes<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !"); - int nbTuples=getNumberOfTuples(); - const double *inPtr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1); - double *retPtr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * This methods returns the minimal distance between the two set of points \a this and \a other. - * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown. - * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3. - * - * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance - * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance - * \return the minimal distance between the two set of points \a this and \a other. - * \sa DataArrayDouble::findClosestTupleId - */ -double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const -{ - MEDCouplingAutoRefCountObjectPtr part1=findClosestTupleId(other); - int nbOfCompo(getNumberOfComponents()); - int otherNbTuples(other->getNumberOfTuples()); - const double *thisPt(begin()),*otherPt(other->begin()); - const int *part1Pt(part1->begin()); - double ret=std::numeric_limits::max(); - for(int i=0;igetNumberOfTuples() tuples and one components. - * \sa DataArrayDouble::minimalDistanceTo - */ -DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !"); - checkAllocated(); other->checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if(nbOfCompo!=other->getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo; - oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfTuples=other->getNumberOfTuples(); - int thisNbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); - double bounds[6]; - getMinMaxPerComponent(bounds); - switch(nbOfCompo) - { - case 3: - { - double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4])); - double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta); - double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.); - BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); - FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); - break; - } - case 2: - { - double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])); - double delta=std::max(xDelta,yDelta); - double characSize=sqrt(delta/(double)thisNbOfTuples); - BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); - FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); - break; - } - case 1: - { - double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples; - BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); - FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); - break; - } - default: - throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3."); - } - return ret.retn(); -} - -/*! - * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ). - * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this - * how many bounding boxes in \a otherBBoxFrmt. - * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components. - * - * \param [in] otherBBoxFrmt - It is an array . - * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched. - * \sa MEDCouplingPointSet::getBoundingBoxForBBTree - * \throw If \a this and \a otherBBoxFrmt have not the same number of components. - * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format). - */ -DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const -{ - if(!otherBBoxFrmt) - throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !"); - if(!isAllocated() || !otherBBoxFrmt->isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !"); - int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples()); - if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(nbOfComp%2!=0) - { - std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1); - const double *thisBBPtr(begin()); - int *retPtr(ret->getPointer()); - switch(nbOfComp/2) - { - case 3: - { - BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); - for(int i=0;i bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); - for(int i=0;i bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); - for(int i=0;i c(c0),cI(cI0); - int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples); - return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); -} - -/*! - * Copy all components in a specified order from another DataArrayDouble. - * Both numerical and textual data is copied. The number of tuples in \a this and - * the other array can be different. - * \param [in] a - the array to copy data from. - * \param [in] compoIds - sequence of zero based indices of components, data of which is - * to be copied. - * \throw If \a a is NULL. - * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). - * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example". - * \endif - */ -void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !"); - checkAllocated(); - copyPartOfStringInfoFrom2(compoIds,*a); - std::size_t partOfCompoSz=compoIds.size(); - int nbOfCompo=getNumberOfComponents(); - int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples()); - const double *ac=a->getConstPointer(); - double *nc=getPointer(); - for(int i=0;igetNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues1"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const double *srcPt=a->getConstPointer(); - double *pt=getPointer()+bgTuples*nbComp+bgComp; - if(assignTech) - { - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign values of \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \param [in] strictCompoCompare - this parameter is checked only if the - * *mode of usage* is the first; if it is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() != (endComp - bgComp) . - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() != (endComp - bgComp). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues2"; - checkAllocated(); - a->checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - int newNbOfComp=(int)std::distance(bgComp,endComp); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - double *pt=getPointer(); - const double *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; - } - } - } - else - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - const double *srcPt2=srcPt; - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt2++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; - } - } - } -} - -/*! - * Assign a given value to values at specified tuples and components of \a this array. - * The tuples and components to assign to are defined by C arrays of indices. - * \param [in] a - the value to assign. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (\a pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (\a pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - double *pt=getPointer(); - for(const int *w=bgTuples;w!=endTuples;w++) - for(const int *z=bgComp;z!=endComp;z++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(std::size_t)(*w)*nbComp+(*z)]=a; - } -} - -/*! - * Copy all values from another DataArrayDouble (\a a) into specified tuples and - * components of \a this array. Textual data is not copied. - * The tuples to assign to are defined by a C array of indices. - * The components to assign to are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * There are two *modes of usage*: - * - If \a a->getNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \param [in] strictCompoCompare - this parameter is checked only in the first - * *mode of usage*; if \a strictCompoCompare is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues3"; - checkAllocated(); - a->checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - double *pt=getPointer()+bgComp; - const double *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;j(pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayDouble::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - double *pt=getPointer()+bgComp; - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;jgetNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - */ -void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues4"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=(int)std::distance(bgComp,endComp); - int nbComp=getNumberOfComponents(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const double *srcPt=a->getConstPointer(); - double *pt=getPointer()+bgTuples*nbComp; - if(assignTech) - { - for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 2. - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * the corresponding (\a this or \a a) array. - */ -void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - double *valsToSet=getPointer(); - const double *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) - { - if(tuple[1]>=0 && tuple[1]=0 && tuple[0]begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples - * of \a this array. Textual data is not copied. Both arrays must have equal number of - * components. - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by \a tuplesSelec->getNumberOfTuples(). - * The tuples to copy are defined by values of a DataArrayInt. - * All components of selected tuples are copied. - * \param [in] tupleIdStart - index of the first tuple of \a this array to assign - * values to. - * \param [in] aBase - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If \a tuplesSelec is NULL. - * \throw If \a tuplesSelec is not allocated. - * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 1. - * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * \a aBase array. - */ -void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - if(!aBase || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !"); - const DataArrayDouble *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - double *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !"); - const double *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) - { - if(*tuple>=0 && *tuplebegin(),tuple); - oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples - * of \a this array. Textual data is not copied. Both arrays must have equal number of - * components. - * The tuples to copy are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by number of tuples to copy. - * All components of selected tuples are copied. - * \param [in] tupleIdStart - index of the first tuple of \a this array to assign - * values to. - * \param [in] aBase - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a aBase. - * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy - * are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). - * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). - * \throw If parameters specifying tuples to copy, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for the array \a aBase. - */ -void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - if(!aBase) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !"); - const DataArrayDouble *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !"); - checkAllocated(); - a->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - double *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const double *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. - */ -double DataArrayDouble::getIJSafe(int tupleId, int compoId) const -{ - checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(compoId<0 || compoId>=getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _mem[tupleId*_info_on_compo.size()+compoId]; -} - -/*! - * Returns the first value of \a this. - * \return double - the last value of \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -double DataArrayDouble::front() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); -} - -/*! - * Returns the last value of \a this. - * \return double - the last value of \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -double DataArrayDouble::back() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !"); - return *(getConstPointer()+nbOfTuples-1); -} - -void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) -{ - if(newArray!=arrayToSet) - { - if(arrayToSet) - arrayToSet->decrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - -/*! - * Sets a C array to be used as raw data of \a this. The previously set info - * of components is retained and re-sized. - * For more info see \ref MEDCouplingArraySteps1. - * \param [in] array - the C array to be used as raw data of \a this. - * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. - * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, - * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, - * \c free(\c array ) will be called. - * \param [in] nbOfTuple - new number of tuples in \a this. - * \param [in] nbOfCompo - new number of components in \a this. - */ -void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); -} - -/*! - * Checks if 0.0 value is present in \a this array. If it is the case, an exception - * is thrown. - * \throw If zero is found in \a this array. - */ -void DataArrayDouble::checkNoNullValues() const -{ - const double *tmp=getConstPointer(); - std::size_t nbOfElems=getNbOfElems(); - const double *where=std::find(tmp,tmp+nbOfElems,0.); - if(where!=tmp+nbOfElems) - throw INTERP_KERNEL::Exception("A value 0.0 have been detected !"); -} - -/*! - * Computes minimal and maximal value in each component. An output array is filled - * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate - * enough memory before calling this method. - * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents(). - * It is filled as follows:
- * \a bounds[0] = \c min_of_component_0
- * \a bounds[1] = \c max_of_component_0
- * \a bounds[2] = \c min_of_component_1
- * \a bounds[3] = \c max_of_component_1
- * ... - */ -void DataArrayDouble::getMinMaxPerComponent(double *bounds) const -{ - checkAllocated(); - int dim=getNumberOfComponents(); - for (int idim=0; idim::max(); - bounds[idim*2+1]=-std::numeric_limits::max(); - } - const double *ptr=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;iptr[i*dim+idim]) - { - bounds[idim*2]=ptr[i*dim+idim]; - } - if(bounds[idim*2+1]getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components - * - * \throw If \a this is not allocated yet. - */ -DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const -{ - checkAllocated(); - const double *dataPtr=getConstPointer(); - int nbOfCompo=getNumberOfComponents(); - int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr bbox=DataArrayDouble::New(); - bbox->alloc(nbTuples,2*nbOfCompo); - double *bboxPtr=bbox->getPointer(); - for(int i=0;icheckAllocated(); - int nbOfCompo=getNumberOfComponents(); - int otherNbOfCompo=other->getNumberOfComponents(); - if(nbOfCompo!=otherNbOfCompo) - throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !"); - int nbOfTuplesOther=other->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); - switch(nbOfCompo) - { - case 3: - { - BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps); - FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); - break; - } - case 2: - { - BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps); - FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); - break; - } - case 1: - { - BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps); - FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); - break; - } - default: - throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3."); - } - c=cArr.retn(); cI=cIArr.retn(); -} - -/*! - * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box - * around origin of 'radius' 1. - * - * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed. - */ -void DataArrayDouble::recenterForMaxPrecision(double eps) -{ - checkAllocated(); - int dim=getNumberOfComponents(); - std::vector bounds(2*dim); - getMinMaxPerComponent(&bounds[0]); - for(int i=0;ieps) - applyLin(1./delta,-offset/delta,i); - else - applyLin(1.,-offset,i); - } -} - -/*! - * Returns the maximal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the maximal value. - * \return double - the maximal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getMaxValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - const double *loc=std::max_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the maximal value within \a this array that is allowed to have more than - * one component. - * \return double - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::getMaxValueInArray() const -{ - checkAllocated(); - const double *loc=std::max_element(begin(),end()); - return *loc; -} - -/*! - * Returns the maximal value and all its locations within \a this one-dimensional array. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of - * tuples holding the maximal value. The caller is to delete it using - * decrRef() as it is no more needed. - * \return double - the maximal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const -{ - int tmp; - tupleIds=0; - double ret=getMaxValue(tmp); - tupleIds=getIdsInRange(ret,ret); - return ret; -} - -/*! - * Returns the minimal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the minimal value. - * \return double - the minimal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getMinValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - const double *loc=std::min_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the minimal value within \a this array that is allowed to have more than - * one component. - * \return double - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::getMinValueInArray() const -{ - checkAllocated(); - const double *loc=std::min_element(begin(),end()); - return *loc; -} - -/*! - * Returns the minimal value and all its locations within \a this one-dimensional array. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of - * tuples holding the minimal value. The caller is to delete it using - * decrRef() as it is no more needed. - * \return double - the minimal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const -{ - int tmp; - tupleIds=0; - double ret=getMinValue(tmp); - tupleIds=getIdsInRange(ret,ret); - return ret; -} - -/*! - * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value. - * This method only works for single component array. - * - * \return a value in [ 0, \c this->getNumberOfTuples() ) - * - * \throw If \a this is not allocated - * - */ -int DataArrayDouble::count(double value, double eps) const -{ - int ret=0; - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); - const double *vals=begin(); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;igetNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getAverageValue() const -{ - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - double ret=std::accumulate(vals,vals+nbOfTuples,0.); - return ret/nbOfTuples; -} - -/*! - * Returns the Euclidean norm of the vector defined by \a this array. - * \return double - the value of the Euclidean norm, i.e. - * the square root of the inner product of vector. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::norm2() const -{ - checkAllocated(); - double ret=0.; - std::size_t nbOfElems=getNbOfElems(); - const double *pt=getConstPointer(); - for(std::size_t i=0;iret) - ret=val; - } - return ret; -} - -/*! - * Returns the minimum norm (absolute value) of the vector defined by \a this array. - * This method works even if the number of components is diferent from one. - * If the number of elements in \a this is 0, std::numeric_limits::max() is returned. - * \return double - the value of the minimum norm, i.e. - * the minimal absolute value among values of \a this array (whatever its number of components). - * \throw If \a this is not allocated. - */ -double DataArrayDouble::normMin() const -{ - checkAllocated(); - double ret(std::numeric_limits::max()); - std::size_t nbOfElems(getNbOfElems()); - const double *pt(getConstPointer()); - for(std::size_t i=0;igetNumberOfComponents(), allocated - * by the caller, that is filled by this method with sum value for each - * component. - * \throw If \a this is not allocated. - */ -void DataArrayDouble::accumulate(double *res) const -{ - checkAllocated(); - const double *ptr=getConstPointer(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - std::fill(res,res+nbComps,0.); - for(int i=0;i()); -} - -/*! - * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and - * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown. - * - * - * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to - * \a tupleEnd. If not an exception will be thrown. - * - * \param [in] tupleBg start pointer (included) of input external tuple - * \param [in] tupleEnd end pointer (not included) of input external tuple - * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple - * \return the min distance. - * \sa MEDCouplingUMesh::distanceToPoint - */ -double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const -{ - checkAllocated(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - if(nbComps!=(int)std::distance(tupleBg,tupleEnd)) - { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(nbTuple==0) - throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !"); - double ret0=std::numeric_limits::max(); - tupleId=-1; - const double *work=getConstPointer(); - for(int i=0;i=ret0) - continue; - else - { ret0=val; tupleId=i; } - } - return sqrt(ret0); -} - -/*! - * Accumulate values of the given component of \a this array. - * \param [in] compId - the index of the component of interest. - * \return double - a sum value of \a compId-th component. - * \throw If \a this is not allocated. - * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is - * not respected. - */ -double DataArrayDouble::accumulate(int compId) const -{ - checkAllocated(); - const double *ptr=getConstPointer(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !"); - double ret=0.; - for(int i=0;igetNumberOfTuples). - * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation. - * - * \param [in] bgOfIndex - begin (included) of the input index array. - * \param [in] endOfIndex - end (excluded) of the input index array. - * \return DataArrayDouble * - the new instance having the same number of components than \a this. - * - * \throw If bgOfIndex or end is NULL. - * \throw If input index array is not ascendingly sorted. - * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples). - * \throw If std::distance(bgOfIndex,endOfIndex)==0. - */ -DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const -{ - if(!bgOfIndex || !endOfIndex) - throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !"); - checkAllocated(); - int nbCompo=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - int sz=(int)std::distance(bgOfIndex,endOfIndex); - if(sz<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !"); - sz--; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo); - const int *w=bgOfIndex; - if(*w<0 || *w>=nbOfTuples) - throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !"); - const double *srcPt=begin()+(*w)*nbCompo; - double *tmp=ret->getPointer(); - for(int i=0;i=w[0]) - { - for(int j=w[0];j=0 && j()); - else - { - std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted."; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Converts each 2D point defined by the tuple of \a this array from the Polar to the - * Cartesian coordinate system. The two components of the tuple of \a this array are - * considered to contain (1) radius and (2) angle of the point in the Polar CS. - * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple - * contains X and Y coordinates of the point in the Cartesian CS. The caller - * is to delete this array using decrRef() as it is no more needed. The array - * does not contain any textual info on components. - * \throw If \a this->getNumberOfComponents() != 2. - */ -DataArrayDouble *DataArrayDouble::fromPolarToCart() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=2) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,2); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); - for(int i=0;igetNumberOfComponents() != 3. - */ -DataArrayDouble *DataArrayDouble::fromCylToCart() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=3) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),3); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); - for(int i=0;isetInfoOnComponent(2,getInfoOnComponent(2)); - return ret; -} - -/*! - * Converts each 3D point defined by the tuple of \a this array from the Spherical to - * the Cartesian coordinate system. The three components of the tuple of \a this array - * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the - * point in the Cylindrical CS. - * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple - * contains X, Y and Z coordinates of the point in the Cartesian CS. The info - * on the third component is copied from \a this array. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() != 3. - */ -DataArrayDouble *DataArrayDouble::fromSpherToCart() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=3) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),3); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); - for(int i=0;i(t) of \a this array as follows: - * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. - * The caller is to delete this result array using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() != 6. - */ -DataArrayDouble *DataArrayDouble::doublyContractedProduct() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;igetNumberOfComponents() is not in [4,6,9]. - */ -DataArrayDouble *DataArrayDouble::determinant() const -{ - checkAllocated(); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - switch(getNumberOfComponents()) - { - case 6: - for(int i=0;idecrRef(); - throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !"); - } -} - -/*! - * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of - * \a this array, which contains 6 components. - * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3 - * components, whose each tuple contains the eigenvalues of the matrix of - * corresponding tuple of \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this->getNumberOfComponents() != 6. - */ -DataArrayDouble *DataArrayDouble::eigenValues() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,3); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;igetNumberOfComponents() != 6. - */ -DataArrayDouble *DataArrayDouble::eigenVectors() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,9); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;igetNumberOfComponents() is not in [4,6,9]. - */ -DataArrayDouble *DataArrayDouble::inverse() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4) - throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,nbOfComp); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - if(nbOfComp==6) - for(int i=0;igetNumberOfComponents() is not in [4,6,9]. - */ -DataArrayDouble *DataArrayDouble::trace() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4) - throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - if(nbOfComp==6) - for(int i=0;igetNumberOfComponents() != 6. - */ -DataArrayDouble *DataArrayDouble::deviator() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,6); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;ialloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;i ret(DataArrayDouble::New()); - ret->alloc(nbOfTuple,1); - const double *src(getConstPointer()); - double *dest(ret->getPointer()); - for(int i=0;i ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;i ret0=DataArrayDouble::New(); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); - int nbOfTuple=getNumberOfTuples(); - ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret0->getPointer(); int *dest1=ret1->getPointer(); - for(int i=0;igetNumberOfTuples() * \c this->getNumberOfTuples() tuples. - * \n This returned array contains the euclidian distance for each tuple in \a this. - * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0. - * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble) - * - * \warning use this method with care because it can leads to big amount of consumed memory ! - * - * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with. - * - * \throw If \a this is not allocated. - * - * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith - */ -DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - const double *inData=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples*nbOfTuples,1); - double *outData=ret->getPointer(); - for(int i=0;igetNumberOfTuples() * \c other->getNumberOfTuples() tuples. - * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. - * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns. - * \n Output rectangular matrix is sorted along rows. - * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble) - * - * \warning use this method with care because it can leads to big amount of consumed memory ! - * - * \param [in] other DataArrayDouble instance having same number of components than \a this. - * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with. - * - * \throw If \a this is not allocated, or if \a other is null or if \a other is not allocated, or if number of components of \a other and \a this differs. - * - * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix - */ -DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !"); - checkAllocated(); - other->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int otherNbOfComp=other->getNumberOfComponents(); - if(nbOfComp!=otherNbOfComp) - { - std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfTuples=getNumberOfTuples(); - int otherNbOfTuples=other->getNumberOfTuples(); - const double *inData=getConstPointer(); - const double *inDataOther=other->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(otherNbOfTuples*nbOfTuples,1); - double *outData=ret->getPointer(); - for(int i=0;i()); - declareAsNew(); -} - -/*! - * Converts every value of \a this array to its absolute value. - * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs - * should be called instead. - * - * \throw If \a this is not allocated. - * \sa DataArrayDouble::computeAbs - */ -void DataArrayDouble::abs() -{ - checkAllocated(); - double *ptr(getPointer()); - std::size_t nbOfElems(getNbOfElems()); - std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(fabs)); - declareAsNew(); -} - -/*! - * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. - * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method. - * - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples and component as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \sa DataArrayDouble::abs - */ -DataArrayDouble *DataArrayDouble::computeAbs() const -{ - checkAllocated(); - DataArrayDouble *newArr(DataArrayDouble::New()); - int nbOfTuples(getNumberOfTuples()); - int nbOfComp(getNumberOfComponents()); - newArr->alloc(nbOfTuples,nbOfComp); - std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(fabs)); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * Apply a linear function to a given component of \a this array, so that - * an array element (x) becomes \f$ a * x + b \f$. - * \param [in] a - the first coefficient of the function. - * \param [in] b - the second coefficient of the function. - * \param [in] compoId - the index of component to modify. - * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ). - */ -void DataArrayDouble::applyLin(double a, double b, int compoId) -{ - checkAllocated(); - double *ptr(getPointer()+compoId); - int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); - if(compoId<0 || compoId>=nbOfComp) - { - std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;istd::numeric_limits::min()) - { - *ptr=numerator/(*ptr); - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - declareAsNew(); -} - -/*! - * Returns a full copy of \a this array except that sign of all elements is reversed. - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples and component as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::negate() const -{ - checkAllocated(); - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *cptr=getConstPointer(); - std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * Modify all elements of \a this array, so that - * an element _x_ becomes val ^ x . Contrary to DataArrayInt::applyPow - * all values in \a this have to be >= 0 if val is \b not integer. - * \param [in] val - the value used to apply pow on all array elements. - * \throw If \a this is not allocated. - * \warning If an exception is thrown because of presence of 0 element in \a this - * array and \a val is \b not integer, all elements processed before detection of the zero element remain - * modified. - */ -void DataArrayDouble::applyPow(double val) -{ - checkAllocated(); - double *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - int val2=(int)val; - bool isInt=((double)val2)==val; - if(!isInt) - { - for(std::size_t i=0;i=0) - *ptr=pow(*ptr,val); - else - { - std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - for(std::size_t i=0;i= 0 !"); - double *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - for(std::size_t i=0;ialloc(nbOfTuples,nbOfComp); - const double *ptr=getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !"; - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return newArr; -} - -/*! - * Returns a new DataArrayDouble created from \a this one by applying a function to every - * tuple of \a this array. Textual data is not copied. - * For more info see \ref MEDCouplingArrayApplyFunc1. - * \param [in] nbOfComp - number of components in the result array. - * \param [in] func - the expression defining how to transform a tuple of \a this array. - * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". - * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples as \a this array and \a nbOfComp components. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \throw If computing \a func fails. - */ -DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const -{ - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - std::vector varsV(vars.begin(),vars.end()); - return applyFunc3(nbOfComp,varsV,func,isSafe); -} - -/*! - * Returns a new DataArrayDouble created from \a this one by applying a function to every - * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size). - * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster. - * - * For more info see \ref MEDCouplingArrayApplyFunc0. - * \param [in] func - the expression defining how to transform a tuple of \a this array. - * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". - * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples and components as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \sa applyFuncOnThis - * \throw If \a this is not allocated. - * \throw If computing \a func fails. - */ -DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const -{ - int nbOfComp(getNumberOfComponents()); - if(nbOfComp<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !"); - checkAllocated(); - int nbOfTuples(getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr newArr(DataArrayDouble::New()); - newArr->alloc(nbOfTuples,nbOfComp); - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>1) - { - std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(vars.empty()) - { - expr.prepareFastEvaluator(); - newArr->rearrange(1); - newArr->fillWithValue(expr.evaluateDouble()); - newArr->rearrange(nbOfComp); - return newArr.retn(); - } - std::vector vars2(vars.begin(),vars.end()); - double buff,*ptrToFill(newArr->getPointer()); - const double *ptr(begin()); - std::vector stck; - expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); - expr.prepareFastEvaluator(); - if(!isSafe) - { - for(int i=0;i 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * - * \sa applyFunc - */ -void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe) -{ - int nbOfComp(getNumberOfComponents()); - if(nbOfComp<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !"); - checkAllocated(); - int nbOfTuples(getNumberOfTuples()); - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>1) - { - std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(vars.empty()) - { - expr.prepareFastEvaluator(); - std::vector compInfo(getInfoOnComponents()); - rearrange(1); - fillWithValue(expr.evaluateDouble()); - rearrange(nbOfComp); - setInfoOnComponents(compInfo); - return ; - } - std::vector vars2(vars.begin(),vars.end()); - double buff,*ptrToFill(getPointer()); - const double *ptr(begin()); - std::vector stck; - expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); - expr.prepareFastEvaluator(); - if(!isSafe) - { - for(int i=0;i 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \throw If \a func contains vars that are not in \a this->getInfoOnComponent(). - * \throw If computing \a func fails. - */ -DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const -{ - return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe); -} - -/*! - * Returns a new DataArrayDouble created from \a this one by applying a function to every - * tuple of \a this array. Textual data is not copied. - * For more info see \ref MEDCouplingArrayApplyFunc3. - * \param [in] nbOfComp - number of components in the result array. - * \param [in] varsOrder - sequence of vars defining their order. - * \param [in] func - the expression defining how to transform a tuple of \a this array. - * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". - * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \throw If \a func contains vars not in \a varsOrder. - * \throw If computing \a func fails. - */ -DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe) const -{ - if(nbOfComp<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !"); - std::vector varsOrder2(varsOrder); - int oldNbOfComp(getNumberOfComponents()); - for(int i=(int)varsOrder.size();i vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>oldNbOfComp) - { - std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; - oss << vars.size() << " variables : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr newArr(DataArrayDouble::New()); - newArr->alloc(nbOfTuples,nbOfComp); - INTERP_KERNEL::AutoPtr buff(new double[oldNbOfComp]); - double *buffPtr(buff),*ptrToFill; - std::vector stck; - for(int iComp=0;iCompgetPointer()+iComp; - if(!isSafe) - { - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } - return newArr.retn(); -} - -void DataArrayDouble::applyFuncFast32(const std::string& func) -{ - checkAllocated(); - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - char *funcStr=expr.compileX86(); - MYFUNCPTR funcPtr; - *((void **)&funcPtr)=funcStr;//he he... - // - double *ptr=getPointer(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - int nbOfElems=nbOfTuples*nbOfComp; - for(int i=0;igetNumberOfComponents() != 1. - * - * \sa DataArrayDouble::getIdsNotInRange - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
- * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !"); - const double *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;i=vmin && *cptr<=vmax) - ret->pushBackSilent(i); - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional - * array whose values are not within a given range. Textual data is not copied. - * \param [in] vmin - a lowest not acceptable value (excluded). - * \param [in] vmax - a greatest not acceptable value (excluded). - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this->getNumberOfComponents() != 1. - * - * \sa DataArrayDouble::getIdsInRange - */ -DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !"); - const double *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;ivmax) - ret->pushBackSilent(i); - return ret.retn(); -} - -/*! - * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number - * of tuples in the result array is a sum of the number of tuples of given arrays and (2) - * the number of component in the result array is same as that of each of given arrays. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If both \a a1 and \a a2 are NULL. - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). - */ -DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - std::vector tmp(2); - tmp[0]=a1; tmp[1]=a2; - return Aggregate(tmp); -} - -/*! - * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number - * of tuples in the result array is a sum of the number of tuples of given arrays and (2) - * the number of component in the result array is same as that of each of given arrays. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it - * not the object itself. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If getNumberOfComponents() of arrays within \a arr. - */ -DataArrayDouble *DataArrayDouble::Aggregate(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !"); - std::vector::const_iterator it=a.begin(); - int nbOfComp=(*it)->getNumberOfComponents(); - int nbt=(*it++)->getNumberOfTuples(); - for(int i=1;it!=a.end();it++,i++) - { - if((*it)->getNumberOfComponents()!=nbOfComp) - throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !"); - nbt+=(*it)->getNumberOfTuples(); - } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbt,nbOfComp); - double *pt=ret->getPointer(); - for(it=a.begin();it!=a.end();it++) - pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); - ret->copyStringInfoFrom(*(a[0])); - return ret.retn(); -} - -/*! - * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If both \a a1 and \a a2 are NULL. - * \throw If any given array is not allocated. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - */ -DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=a2; - return Meld(arr); -} - -/*! - * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If any given array is not allocated. - * \throw If getNumberOfTuples() of arrays within \a arr is different. - */ -DataArrayDouble *DataArrayDouble::Meld(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !"); - std::vector::const_iterator it; - for(it=a.begin();it!=a.end();it++) - (*it)->checkAllocated(); - it=a.begin(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::vector nbc(a.size()); - std::vector pts(a.size()); - nbc[0]=(*it)->getNumberOfComponents(); - pts[0]=(*it++)->getConstPointer(); - for(int i=1;it!=a.end();it++,i++) - { - if(nbOfTuples!=(*it)->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,totalNbOfComp); - double *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - -/*! - * Returns a new DataArrayDouble containing a dot product of two given arrays, so that - * the i-th tuple of the result array is a sum of products of j-th components of i-th - * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$). - * Info on components and name is copied from the first of the given arrays. - * Number of tuples and components in the given arrays must be the same. - * \param [in] a1 - a given array. - * \param [in] a2 - another given array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If any given array is not allocated. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() - */ -DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !"); - a1->checkAllocated(); - a2->checkAllocated(); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,1); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - for(int i=0;isetInfoOnComponent(0,a1->getInfoOnComponent(0)); - ret->setName(a1->getName()); - return ret; -} - -/*! - * Returns a new DataArrayDouble containing a cross product of two given arrays, so that - * the i-th tuple of the result array contains 3 components of a vector which is a cross - * product of two vectors defined by the i-th tuples of given arrays. - * Info on components is copied from the first of the given arrays. - * Number of tuples in the given arrays must be the same. - * Number of components in the given arrays must be 3. - * \param [in] a1 - a given array. - * \param [in] a2 - another given array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != 3 - * \throw If \a a2->getNumberOfComponents() != 3 - */ -DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !"); - if(nbOfComp!=3) - throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,3); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - for(int i=0;icopyStringInfoFrom(*a1); - return ret; -} - -/*! - * Returns a new DataArrayDouble containing maximal values of two given arrays. - * Info on components is copied from the first of the given arrays. - * Number of tuples and components in the given arrays must be the same. - * \param [in] a1 - an array to compare values with another one. - * \param [in] a2 - another array to compare values with the first one. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() - */ -DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - int nbElem=nbOfTuple*nbOfComp; - for(int i=0;icopyStringInfoFrom(*a1); - return ret; -} - -/*! - * Returns a new DataArrayDouble containing minimal values of two given arrays. - * Info on components is copied from the first of the given arrays. - * Number of tuples and components in the given arrays must be the same. - * \param [in] a1 - an array to compare values with another one. - * \param [in] a2 - another array to compare values with the first one. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() - */ -DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - int nbElem=nbOfTuple*nbOfComp; - for(int i=0;icopyStringInfoFrom(*a1); - return ret; -} - -/*! - * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2, - * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - an array to sum up. - * \param [in] a2 - another array to sum up. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayDouble *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const double *aMinPtr=aMin->getConstPointer(); - const double *aMaxPtr=aMax->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayDouble::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - double *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - return ret.retn(); -} - -/*! - * Adds values of another DataArrayDouble to values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is added to the corresponding value of \a this array, i.e.: - * _a_ [ i, j ] += _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] += _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] += _a2_ [ 0, j ]. - * - * \param [in] other - an array to add to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayDouble::addEqual(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual !"; - checkAllocated(); - other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::plus()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a subtraction of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - an array to subtract from. - * \param [in] a2 - an array to subtract. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a2Ptr=a2->getConstPointer(); - const double *a1Ptr=a1->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - double *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception - return 0; - } -} - -/*! - * Subtract values of another DataArrayDouble from values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is subtracted from the corresponding value of \a this array, i.e.: - * _a_ [ i, j ] -= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] -= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] -= _a2_ [ 0, j ]. - * - * \param [in] other - an array to subtract from \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayDouble::substractEqual(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual !"; - checkAllocated(); - other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::minus()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayDouble that is a product of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a product of the corresponding values of \a a1 and - * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - a factor array. - * \param [in] a2 - another factor array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayDouble *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const double *aMinPtr=aMin->getConstPointer(); - const double *aMaxPtr=aMax->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayDouble::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - double *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - return ret.retn(); -} - -/*! - * Multiply values of another DataArrayDouble to values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is multiplied to the corresponding value of \a this array, i.e. - * _this_ [ i, j ] *= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _this_ [ i, j ] *= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _this_ [ i, j ] *= _a2_ [ 0, j ]. - * - * \param [in] other - an array to multiply to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !"; - checkAllocated(); - other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayDouble that is a division of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a division of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \warning No check of division by zero is performed! - * \param [in] a1 - a numerator array. - * \param [in] a2 - a denominator array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a2Ptr=a2->getConstPointer(); - const double *a1Ptr=a1->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - double *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception - return 0; - } -} - -/*! - * Divide values of \a this array by values of another DataArrayDouble. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a this array is divided by the corresponding value of \a other one, i.e.: - * _a_ [ i, j ] /= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] /= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] /= _a2_ [ 0, j ]. - * - * \warning No check of division by zero is performed! - * \param [in] other - an array to divide \a this one by. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayDouble::divideEqual(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !"; - checkAllocated(); - other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::divides()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3 - * valid cases. - * - * \param [in] a1 - an array to pow up. - * \param [in] a2 - another array to sum up. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. - * \throw If there is a negative value in \a a1. - */ -DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple!=nbOfTuple2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !"); - if(nbOfComp!=1 || nbOfComp2!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); - const double *ptr1(a1->begin()),*ptr2(a2->begin()); - double *ptr=ret->getPointer(); - for(int i=0;i=0) - { - *ptr=pow(*ptr1,*ptr2); - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret.retn(); -} - -/*! - * Apply pow on values of another DataArrayDouble to values of \a this one. - * - * \param [in] other - an array to pow to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() - * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1 - * \throw If there is a negative value in \a this. - */ -void DataArrayDouble::powEqual(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !"); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple!=nbOfTuple2) - throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !"); - if(nbOfComp!=1 || nbOfComp2!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !"); - double *ptr=getPointer(); - const double *ptrc=other->begin(); - for(int i=0;i=0) - *ptr=pow(*ptr,*ptrc); - else - { - std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - declareAsNew(); -} - -/*! - * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. - * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true. - * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown. - * - * \throw if \a this is not allocated. - * \throw if \a this has not exactly one component. - */ -std::vector DataArrayDouble::toVectorOfBool(double eps) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !"); - int nbt(getNumberOfTuples()); - std::vector ret(nbt); - const double *pt(begin()); - for(int i=0;i& tinyInfo) const -{ - tinyInfo.resize(2); - if(isAllocated()) - { - tinyInfo[0]=getNumberOfTuples(); - tinyInfo[1]=getNumberOfComponents(); - } - else - { - tinyInfo[0]=-1; - tinyInfo[1]=-1; - } -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * Server side. - */ -void DataArrayDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - if(isAllocated()) - { - int nbOfCompo=getNumberOfComponents(); - tinyInfo.resize(nbOfCompo+1); - tinyInfo[0]=getName(); - for(int i=0;i& tinyInfoI) -{ - int nbOfTuple=tinyInfoI[0]; - int nbOfComp=tinyInfoI[1]; - if(nbOfTuple!=-1 || nbOfComp!=-1) - { - alloc(nbOfTuple,nbOfComp); - return true; - } - return false; -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - */ -void DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS) -{ - setName(tinyInfoS[0]); - if(isAllocated()) - { - int nbOfCompo=getNumberOfComponents(); - for(int i=0;iincrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayDoubleIterator::~DataArrayDoubleIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() -{ - if(_tuple_id<_nb_tuple) - { - _tuple_id++; - DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp); - _pt+=_nb_comp; - return ret; - } - else - return 0; -} - -DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) -{ -} - - -std::string DataArrayDoubleTuple::repr() const -{ - std::ostringstream oss; oss.precision(17); oss << "("; - for(int i=0;i<_nb_of_compo-1;i++) - oss << _pt[i] << ", "; - oss << _pt[_nb_of_compo-1] << ")"; - return oss.str(); -} - -double DataArrayDoubleTuple::doubleValue() const -{ - if(_nb_of_compo==1) - return *_pt; - throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !"); -} - -/*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false. - * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or - * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. - */ -DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const -{ - if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) - { - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); - return ret; - } - else - { - std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo; - oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Returns a new instance of DataArrayInt. The caller is to delete this array - * using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::New() -{ - return new DataArrayInt; -} - -/*! - * Checks if raw data is allocated. Read more on the raw data - * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. - * \return bool - \a true if the raw data is allocated, \a false else. - */ -bool DataArrayInt::isAllocated() const -{ - return getConstPointer()!=0; -} - -/*! - * Checks if raw data is allocated and throws an exception if it is not the case. - * \throw If the raw data is not allocated. - */ -void DataArrayInt::checkAllocated() const -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); -} - -/*! - * This method desallocated \a this without modification of informations relative to the components. - * After call of this method, DataArrayInt::isAllocated will return false. - * If \a this is already not allocated, \a this is let unchanged. - */ -void DataArrayInt::desallocate() -{ - _mem.destroy(); -} - -std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - sz*=sizeof(int); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - -/*! - * Returns the only one value in \a this, if and only if number of elements - * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. - * \return double - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -int DataArrayInt::intValue() const -{ - if(isAllocated()) - { - if(getNbOfElems()==1) - { - return *getConstPointer(); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !"); -} - -/*! - * Returns an integer value characterizing \a this array, which is useful for a quick - * comparison of many instances of DataArrayInt. - * \return int - the hash value. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getHashCode() const -{ - checkAllocated(); - std::size_t nbOfElems=getNbOfElems(); - int ret=nbOfElems*65536; - int delta=3; - if(nbOfElems>48) - delta=nbOfElems/8; - int ret0=0; - const int *pt=begin(); - for(std::size_t i=0;i(this); - } -} - -/*! - * Copies all the data from another DataArrayInt. For more info see - * \ref MEDCouplingArrayBasicsCopyDeepAssign. - * \param [in] other - another instance of DataArrayInt to copy data from. - * \throw If the \a other is not allocated. - */ -void DataArrayInt::cpyFrom(const DataArrayInt& other) -{ - other.checkAllocated(); - int nbOfTuples=other.getNumberOfTuples(); - int nbOfComp=other.getNumberOfComponents(); - allocIfNecessary(nbOfTuples,nbOfComp); - std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; - int *pt=getPointer(); - const int *ptI=other.getConstPointer(); - for(std::size_t i=0;igetNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -void DataArrayInt::iota(int init) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); - int *ptr=getPointer(); - int ntuples=getNumberOfTuples(); - for(int i=0;igetNumberOfTuples() << "\">"; - if(std::string(type)=="Int32") - { - const char *data(reinterpret_cast(begin())); - std::size_t sz(getNbOfElems()*sizeof(int)); - byteArr->insertAtTheEnd(data,data+sz); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else if(std::string(type)=="Int8") - { - INTERP_KERNEL::AutoPtr tmp(new char[getNbOfElems()]); - std::copy(begin(),end(),(char *)tmp); - byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems()); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else if(std::string(type)=="UInt8") - { - INTERP_KERNEL::AutoPtr tmp(new unsigned char[getNbOfElems()]); - std::copy(begin(),end(),(unsigned char *)tmp); - byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems()); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !"); - } - else - { - ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt; - std::copy(begin(),end(),std::ostream_iterator(ofs," ")); - } - ofs << std::endl << idt << "
\n"; -} - -void DataArrayInt::reprStream(std::ostream& stream) const -{ - stream << "Name of int array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayInt::reprZipStream(std::ostream& stream) const -{ - stream << "Name of int array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const -{ - stream << "Name of int array : \"" << _name << "\"\n"; - reprNotTooLongWithoutNameStream(stream); -} - -void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - _mem.repr(getNumberOfComponents(),stream); -} - -void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - _mem.reprZip(getNumberOfComponents(),stream); -} - -void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.reprNotTooLong(getNumberOfComponents(),stream); -} - -void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); - const int *data=getConstPointer(); - stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl; - if(nbTuples*nbComp>=1) - { - stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={"; - std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator(stream,",")); - stream << data[nbTuples*nbComp-1] << "};" << std::endl; - stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl; - } - else - stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl; - stream << varName << "->setName(\"" << getName() << "\");" << std::endl; -} - -/*! - * Method that gives a quick overvien of \a this for python. - */ -void DataArrayInt::reprQuickOverview(std::ostream& stream) const -{ - static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; - stream << "DataArrayInt C++ instance at " << this << ". "; - if(isAllocated()) - { - int nbOfCompo=(int)_info_on_compo.size(); - if(nbOfCompo>=1) - { - int nbOfTuples=getNumberOfTuples(); - stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; - reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); - } - else - stream << "Number of components : 0."; - } - else - stream << "*** No data allocated ****"; -} - -void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const -{ - const int *data=begin(); - int nbOfTuples=getNumberOfTuples(); - int nbOfCompo=(int)_info_on_compo.size(); - std::ostringstream oss2; oss2 << "["; - std::string oss2Str(oss2.str()); - bool isFinished=true; - for(int i=0;i1) - { - oss2 << "("; - for(int j=0;jgetNumberOfComponents() != 1 - * \throw If any value of \a this can't be used as a valid index for - * [\a indArrBg, \a indArrEnd). - * - * \sa replaceOneValByInThis - */ -void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer()); - for(int i=0;i=0 && *ptgetNumberOfComponents() != 1. - * \throw If \a arrEnd - arrBg < 2. - * \throw If any value of \a this is not less than \a arrEnd[-1]. - */ -void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, - DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - std::size_t nbOfCast=std::distance(arrBg,arrEnd); - if(nbOfCast<2) - throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !"); - nbOfCast--; - const int *work=getConstPointer(); - typedef std::reverse_iterator rintstart; - rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2 - rintstart end2(arrBg); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr ret3=DataArrayInt::New(); - ret1->alloc(nbOfTuples,1); - ret2->alloc(nbOfTuples,1); - int *ret1Ptr=ret1->getPointer(); - int *ret2Ptr=ret2->getPointer(); - std::set castsDetected; - for(int i=0;i(), work[i])); - std::size_t pos=std::distance(bg,res); - std::size_t pos2=nbOfCast-pos; - if(pos2alloc((int)castsDetected.size(),1); - std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer()); - castArr=ret1.retn(); - rankInsideCast=ret2.retn(); - castsPresent=ret3.retn(); -} - -/*! - * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ). - * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ). - * This method works only if \a this is allocated and single component. If not an exception will be thrown. - * - * \param [out] strt - the start of the range (included) if true is returned. - * \param [out] sttoopp - the end of the range (not included) if true is returned. - * \param [out] stteepp - the step of the range if true is returned. - * \return the verdict of the check. - * - * \sa DataArray::GetNumberOfItemGivenBES - */ -bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !"); - int nbTuples(getNumberOfTuples()); - if(nbTuples==0) - { strt=0; sttoopp=0; stteepp=1; return true; } - const int *pt(begin()); - strt=*pt; - if(nbTuples==1) - { sttoopp=strt+1; stteepp=1; return true; } - strt=*pt; sttoopp=pt[nbTuples-1]; - if(strt==sttoopp) - return false; - if(sttoopp>strt) - { - sttoopp++; - int a(sttoopp-1-strt),tmp(strt); - if(a%(nbTuples-1)!=0) - return false; - stteepp=a/(nbTuples-1); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If any value of \a this array is not a valid index for \a indArrBg array. - * \throw If any value of \a indArrBg is not a valid index for \a this array. - */ -DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbElemsIn=(int)std::distance(indArrBg,indArrEnd); - int nbOfTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); - ret->fillWithValue(-1); - int *tmp=ret->getPointer(); - for(int i=0;i=0 && *pt=0 && pos - * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNbOfElem,1); - int nbOfOldNodes=getNumberOfTuples(); - const int *old2New=getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i!=nbOfOldNodes;i++) - { - int newp(old2New[i]); - if(newp!=-1) - { - if(newp>=0 && newp ret=DataArrayInt::New(); - ret->alloc(newNbOfElem,1); - int nbOfOldNodes=getNumberOfTuples(); - const int *old2New=getConstPointer(); - int *pt=ret->getPointer(); - for(int i=nbOfOldNodes-1;i>=0;i--) - { - int newp(old2New[i]); - if(newp!=-1) - { - if(newp>=0 && newp ret=DataArrayInt::New(); - ret->alloc(oldNbOfElem,1); - const int *new2Old=getConstPointer(); - int *pt=ret->getPointer(); - std::fill(pt,pt+oldNbOfElem,-1); - int nbOfNewElems=getNumberOfTuples(); - for(int i=0;i=0 && v a=deepCpy(); - MEDCouplingAutoRefCountObjectPtr b=other.deepCpy(); - a->sort(); - b->sort(); - return a->isEqualWithoutConsideringStr(*b); -} - -/*! - * This method compares content of input vector \a v and \a this. - * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned. - * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown. - * - * \param [in] v - the vector of 'flags' to be compared with \a this. - * - * \throw If \a this is not sorted ascendingly. - * \throw If \a this has not exactly one component. - * \throw If \a this is not allocated. - */ -bool DataArrayInt::isFittingWith(const std::vector& v) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); - const int *w(begin()),*end2(end()); - int refVal=-std::numeric_limits::max(); - int i=0; - std::vector::const_iterator it(v.begin()); - for(;it!=v.end();it++,i++) - { - if(*it) - { - if(w!=end2) - { - if(*w++==i) - { - if(i>refVal) - refVal=i; - else - { - std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - return false; - } - else - return false; - } - } - return w==end2; -} - -/*! - * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val - * put True to the corresponding entry in \a vec. - * \a vec is expected to be with the same size than the number of tuples of \a this. - */ -void DataArrayInt::switchOnTupleEqualTo(int val, std::vector& vec) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples!=(int)vec.size()) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !"); - const int *pt(begin()); - for(int i=0;igetNumberOfComponents() != 1. - */ -void DataArrayInt::sort(bool asc) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !"); - _mem.sort(asc); - declareAsNew(); -} - -/*! - * Computes for each tuple the sum of number of components values in the tuple and return it. - * - * \return DataArrayInt * - the new instance of DataArrayInt containing the - * same number of tuples as \a this array and one component. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::sumPerTuple() const -{ - checkAllocated(); - int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - ret->alloc(nbOfTuple,1); - const int *src(getConstPointer()); - int *dest(ret->getPointer()); - for(int i=0;igetNumberOfComponents() < 1. - * \throw If \a this is not allocated. - */ -void DataArrayInt::reverse() -{ - checkAllocated(); - _mem.reverse(getNumberOfComponents()); - declareAsNew(); -} - -/*! - * Checks that \a this array is consistently **increasing** or **decreasing** in value. - * If not an exception is thrown. - * \param [in] increasing - if \a true, the array values should be increasing. - * \throw If sequence of values is not strictly monotonic in agreement with \a - * increasing arg. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this is not allocated. - */ -void DataArrayInt::checkMonotonic(bool increasing) const -{ - if(!isMonotonic(increasing)) - { - if (increasing) - throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !"); - else - throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !"); - } -} - -/*! - * Checks that \a this array is consistently **increasing** or **decreasing** in value. - * \param [in] increasing - if \a true, array values should be increasing. - * \return bool - \a true if values change in accordance with \a increasing arg. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this is not allocated. - */ -bool DataArrayInt::isMonotonic(bool increasing) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !"); - int nbOfElements=getNumberOfTuples(); - const int *ptr=getConstPointer(); - if(nbOfElements==0) - return true; - int ref=ptr[0]; - if(increasing) - { - for(int i=1;i=ref) - ref=ptr[i]; - else - return false; - } - } - else - { - for(int i=1;iref) - ref=ptr[i]; - else - return false; - } - } - else - { - for(int i=1;i other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0). If such a permutation is - * not possible because some element in \a other is not in \a this, an exception is thrown. - * \param [in] other - an array to compute permutation to. - * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array - * from \a this to \a other. The caller is to delete this array using decrRef() as it is - * no more needed. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a other->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples(). - * \throw If \a other includes a value which is not in \a this array. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". - * - * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !"); - int nbTuple=getNumberOfTuples(); - other.checkAllocated(); - if(nbTuple!=other.getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuple,1); - ret->fillWithValue(-1); - const int *pt=getConstPointer(); - std::map mm; - for(int i=0;igetPointer(); - for(int i=0;i::const_iterator it=mm.find(pt[i]); - if(it==mm.end()) - { - std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retToFill[i]=(*it).second; - } - return ret.retn(); -} - -/*! - * Sets a C array to be used as raw data of \a this. The previously set info - * of components is retained and re-sized. - * For more info see \ref MEDCouplingArraySteps1. - * \param [in] array - the C array to be used as raw data of \a this. - * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. - * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, - * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, - * \c free(\c array ) will be called. - * \param [in] nbOfTuple - new number of tuples in \a this. - * \param [in] nbOfCompo - new number of components in \a this. - */ -void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo); - declareAsNew(); -} - -/*! - * Returns a new DataArrayInt holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::fromNoInterlace() const -{ - checkAllocated(); - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !"); - int *tab=_mem.fromNoInterlace(getNumberOfComponents()); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Returns a new DataArrayInt holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::toNoInterlace() const -{ - checkAllocated(); - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !"); - int *tab=_mem.toNoInterlace(getNumberOfComponents()); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Permutes values of \a this array as required by \a old2New array. The values are - * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains - * the same as in \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old value. - */ -void DataArrayInt::renumberInPlace(const int *old2New) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - int *tmp=new int[nbTuples*nbOfCompo]; - const int *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -void DataArrayInt::renumberInPlaceR(const int *new2Old) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - int *tmp=new int[nbTuples*nbOfCompo]; - const int *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * giving a new position for i-th old value. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::renumber(const int *old2New) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a copy of \a this array with values permuted as required by \a new2Old array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of - * tuples in the result array remains the same as in \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is - * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. - * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all - * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which - * \a old2New[ i ] is negative, is missing from the result array. - * For more info on renumbering see \ref numbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old tuple and giving negative position for - * for i-th old tuple that should be omitted. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNbOfTuple,nbOfCompo); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;i=0) - std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * For more info on renumbering see \ref numbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * This method is equivalent to selectByTupleId() except that it prevents coping data - * from behind the end of \a this array. - * For more info on renumbering see \ref numbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). - */ -DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - if(*w>=0 && *wgetNumberOfTuples) !"); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayInt contains every - * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th - * tuple. Indices of the selected tuples are the same as ones returned by the Python - * command \c range( \a bg, \a end2, \a step ). - * This method is equivalent to selectByTupleIdSafe() except that the input array is - * not constructed explicitly. - * For more info on renumbering see \ref numbering. - * \param [in] bg - index of the first tuple to copy from \a this array. - * \param [in] end2 - index of the tuple before which the tuples to copy are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \sa DataArrayInt::substr. - */ -DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); - ret->alloc(newNbOfTuples,nbComp); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer()+bg*nbComp; - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges - * of tuples specified by \a ranges parameter. - * For more info on renumbering see \ref numbering. - * \param [in] ranges - std::vector of std::pair's each of which defines a range - * of tuples in [\c begin,\c end) format. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a end < \a begin. - * \throw If \a end > \a this->getNumberOfTuples(). - * \throw If \a this is not allocated. - */ -DataArray *DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(0,nbOfComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); - } - int ref=ranges.front().first; - int nbOfTuples=0; - bool isIncreasing=true; - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - { - if((*it).first<=(*it).second) - { - if((*it).first>=0 && (*it).second<=nbOfTuplesThis) - { - nbOfTuples+=(*it).second-(*it).first; - if(isIncreasing) - isIncreasing=ref<=(*it).first; - ref=(*it).second; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(isIncreasing && nbOfTuplesThis==nbOfTuples) - return deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const int *src=getConstPointer(); - int *work=ret->getPointer(); - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode. - * This map, if applied to \a this array, would make it sorted. For example, if - * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array - * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call - * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11]. - * This method is useful for renumbering (in MED file for example). For more info - * on renumbering see \ref numbering. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If there are equal values in \a this array. - */ -DataArrayInt *DataArrayInt::checkAndPreparePermutation() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !"); - int nbTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(pt2,true,C_DEALLOC,nbTuples,1); - return ret; -} - -/*! - * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second - * input array \a ids2. - * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative. - * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or - * inversely. - * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method. - * - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If either ids1 or ids2 is null not allocated or not with one components. - * - */ -DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) -{ - if(!ids1 || !ids2) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !"); - if(!ids1->isAllocated() || !ids2->isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !"); - if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !"); - if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr p1(ids1->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(ids2->deepCpy()); - p1->sort(true); p2->sort(true); - if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !"); - p1=ids1->checkAndPreparePermutation(); - p2=ids2->checkAndPreparePermutation(); - p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples()); - p2=p2->selectByTupleIdSafe(p1->begin(),p1->end()); - return p2.retn(); -} - -/*! - * Returns two arrays describing a surjective mapping from \a this set of values (\a A) - * onto a set of values of size \a targetNb (\a B). The surjective function is - * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a - * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so - * that this->getIJ( tid, 0 ) == id.
- * The first of out arrays returns indices of elements of \a this array, grouped by their - * place in the set \a B. The second out array is the index of the first one; it shows how - * many elements of \a A are mapped into each element of \a B.
- * For more info on - * mapping and its usage in renumbering see \ref numbering.
- * \b Example: - * - \a this: [0,3,2,3,2,2,1,2] - * - \a targetNb: 4 - * - \a arr: [0, 6, 2,4,5,7, 1,3] - * - \a arrI: [0,1,2,6,8] - * - * This result means:
- * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and - * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);
- * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and - * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : - * \a arrI[ 2+1 ]]);
etc. - * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more - * than the maximal value of \a A. - * \param [out] arr - a new instance of DataArrayInt returning indices of - * elements of \a this, grouped by their place in the set \a B. The caller is to delete - * this array using decrRef() as it is no more needed. - * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal - * elements of \a this. The caller is to delete this array using decrRef() as it - * is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If any value in \a this is more or equal to \a targetNb. - */ -void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !"); - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr retI(DataArrayInt::New()); - retI->alloc(targetNb+1,1); - const int *input=getConstPointer(); - std::vector< std::vector > tmp(targetNb); - for(int i=0;i=0 && tmp2getPointer(); - *retIPtr=0; - for(std::vector< std::vector >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++) - retIPtr[1]=retIPtr[0]+(int)((*it1).size()); - if(nbOfTuples!=retI->getIJ(targetNb,0)) - throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !"); - ret->alloc(nbOfTuples,1); - int *retPtr=ret->getPointer(); - for(std::vector< std::vector >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++) - retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr); - arr=ret.retn(); - arrI=retI.retn(); -} - - -/*! - * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed - * from a zip representation of a surjective format (returned e.g. by - * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()" - * for example). The result array minimizes the permutation.
- * For more info on renumbering see \ref numbering.
- * \b Example:
- * - \a nbOfOldTuples: 10 - * - \a arr : [0,3, 5,7,9] - * - \a arrIBg : [0,2,5] - * - \a newNbOfTuples: 7 - * - result array : [0,1,2,0,3,4,5,4,6,4] - * - * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr. - * \param [in] arr - the array of tuple indices grouped by \a arrIBg array. - * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of - * (indices of) equal values. Its every element (except the last one) points to - * the first element of a group of equal values. - * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a - * arrIBg is \a arrIEnd[ -1 ]. - * \param [out] newNbOfTuples - number of tuples after surjection application. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ). - */ -DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfOldTuples,1); - int *pt=ret->getPointer(); - std::fill(pt,pt+nbOfOldTuples,-1); - int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1; - const int *cIPtr=arrIBg; - for(int i=0;i=0 && arr[j] - * \b Example:
- * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0] - * - result: [10,0,5,6,1,7,11,2,8,9,3,4] - * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] - * - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::buildPermArrPerLevel() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !"); - int nbOfTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - std::map m; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); - int *opt=ret->getPointer(); - for(int i=0;i::iterator it=m.find(val); - if(it!=m.end()) - { - *opt=(*it).second; - (*it).second++; - } - else - { - *opt=0; - m.insert(std::pair(val,1)); - } - } - int sum=0; - for(std::map::iterator it=m.begin();it!=m.end();it++) - { - int vt=(*it).second; - (*it).second=sum; - sum+=vt; - } - pt=getConstPointer(); - opt=ret->getPointer(); - for(int i=0;igetNumberOfTuples()) - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa isIdentity2 - */ -bool DataArrayInt::isIdentity() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - return false; - int nbOfTuples(getNumberOfTuples()); - const int *pt=getConstPointer(); - for(int i=0;igetNumberOfTuples()) and if \a this has \a sizeExpected tuples in it. - * - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa isIdentity - */ -bool DataArrayInt::isIdentity2(int sizeExpected) const -{ - bool ret0(isIdentity()); - if(!ret0) - return false; - return getNumberOfTuples()==sizeExpected; -} - -/*! - * Checks if all values in \a this array are equal to \a val. - * \param [in] val - value to check equality of array values to. - * \return bool - \a true if all values are \a val. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1 - */ -bool DataArrayInt::isUniform(int val) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - const int *w=getConstPointer(); - const int *end2=w+nbOfTuples; - for(;w!=end2;w++) - if(*w!=val) - return false; - return true; -} - -/*! - * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this - * array to the new one. - * \return DataArrayDouble * - the new instance of DataArrayInt. - */ -DataArrayDouble *DataArrayInt::convertToDblArr() const -{ - checkAllocated(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - std::size_t nbOfVals=getNbOfElems(); - const int *src=getConstPointer(); - double *dest=ret->getPointer(); - std::copy(src,src+nbOfVals,dest); - ret->copyStringInfoFrom(*this); - return ret; -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayInt contains all - * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before - * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). - * This method is a specialization of selectByTupleId2(). - * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. - * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. - * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a tupleIdBg < 0. - * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). - \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). - * \sa DataArrayInt::selectByTupleId2 - */ -DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(trueEnd-tupleIdBg,nbComp); - ret->copyStringInfoFrom(*this); - std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret.retn(); -} - -/*! - * Changes the number of components within \a this array so that its raw data **does - * not** change, instead splitting this data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \param [in] newNbOfComp - number of components for \a this array to have. - * \throw If \a this is not allocated - * \throw If getNbOfElems() % \a newNbOfCompo != 0. - * \throw If \a newNbOfCompo is lower than 1. - * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). - * \warning This method erases all (name and unit) component info set before! - */ -void DataArrayInt::rearrange(int newNbOfCompo) -{ - checkAllocated(); - if(newNbOfCompo<1) - throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !"); - std::size_t nbOfElems=getNbOfElems(); - if(nbOfElems%newNbOfCompo!=0) - throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !"); - if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); - _info_on_compo.clear(); - _info_on_compo.resize(newNbOfCompo); - declareAsNew(); -} - -/*! - * Changes the number of components within \a this array to be equal to its number - * of tuples, and inversely its number of tuples to become equal to its number of - * components. So that its raw data **does not** change, instead splitting this - * data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! - * \throw If \a this is not allocated. - * \sa rearrange() - */ -void DataArrayInt::transpose() -{ - checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - rearrange(nbOfTuples); -} - -/*! - * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less - * than \a this->getNumberOfComponents() then the result array is shorten as each tuple - * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is - * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp - * components. - * \param [in] newNbOfComp - number of components for the new array to have. - * \param [in] dftValue - value assigned to new values added to the new array. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const int *oldc=getConstPointer(); - int *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - return ret.retn(); -} - -/*! - * Changes number of tuples in the array. If the new number of tuples is smaller - * than the current number the array is truncated, otherwise the array is extended. - * \param [in] nbOfTuples - new number of tuples. - * \throw If \a this is not allocated. - * \throw If \a nbOfTuples is negative. - */ -void DataArrayInt::reAlloc(int nbOfTuples) -{ - if(nbOfTuples<0) - throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !"); - checkAllocated(); - _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); - declareAsNew(); -} - - -/*! - * Returns a copy of \a this array composed of selected components. - * The new DataArrayInt has the same number of tuples but includes components - * specified by \a compoIds parameter. So that getNbOfElems() of the result array - * can be either less, same or more than \a this->getNbOfElems(). - * \param [in] compoIds - sequence of zero based indices of components to include - * into the new array. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If a component index (\a i) is not valid: - * \a i < 0 || \a i >= \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - int newNbOfCompo=(int)compoIds.size(); - int oldNbOfCompo=getNumberOfComponents(); - for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) - DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component"); - int nbOfTuples=getNumberOfTuples(); - ret->alloc(nbOfTuples,newNbOfCompo); - ret->copyPartOfStringInfoFrom(*this,compoIds); - const int *oldc=getConstPointer(); - int *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int)); - int *w=newArr; - const int *inp1=getConstPointer(); - const int *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;igetNumberOfComponents(). - * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". - * \endif - */ -void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !"); - checkAllocated(); - a->checkAllocated(); - copyPartOfStringInfoFrom2(compoIds,*a); - std::size_t partOfCompoSz=compoIds.size(); - int nbOfCompo=getNumberOfComponents(); - int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples()); - const int *ac=a->getConstPointer(); - int *nc=getPointer(); - for(int i=0;igetNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::setPartOfValues1"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - int *pt=getPointer()+bgTuples*nbComp+bgComp; - const int *srcPt=a->getConstPointer(); - if(assignTech) - { - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign values of \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \param [in] strictCompoCompare - this parameter is checked only if the - * *mode of usage* is the first; if it is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() != (endComp - bgComp) . - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() != (endComp - bgComp). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::setPartOfValues2"; - checkAllocated(); - a->checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - int newNbOfComp=(int)std::distance(bgComp,endComp); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - int *pt=getPointer(); - const int *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; - } - } - } - else - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - const int *srcPt2=srcPt; - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt2++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; - } - } - } -} - -/*! - * Assign a given value to values at specified tuples and components of \a this array. - * The tuples and components to assign to are defined by C arrays of indices. - * \param [in] a - the value to assign. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (\a pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (\a pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int *pt=getPointer(); - for(const int *w=bgTuples;w!=endTuples;w++) - for(const int *z=bgComp;z!=endComp;z++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(std::size_t)(*w)*nbComp+(*z)]=a; - } -} - -/*! - * Copy all values from another DataArrayInt (\a a) into specified tuples and - * components of \a this array. Textual data is not copied. - * The tuples to assign to are defined by a C array of indices. - * The components to assign to are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * There are two *modes of usage*: - * - If \a a->getNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \param [in] strictCompoCompare - this parameter is checked only in the first - * *mode of usage*; if \a strictCompoCompare is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::setPartOfValues3"; - checkAllocated(); - a->checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - int *pt=getPointer()+bgComp; - const int *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;j(pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayInt::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int *pt=getPointer()+bgComp; - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;jcheckAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=(int)std::distance(bgComp,endComp); - int nbComp=getNumberOfComponents(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const int *srcPt=a->getConstPointer(); - int *pt=getPointer()+bgTuples*nbComp; - if(assignTech) - { - for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 2. - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * the corresponding (\a this or \a a) array. - */ -void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int *valsToSet=getPointer(); - const int *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) - { - if(tuple[1]>=0 && tuple[1]=0 && tuple[0]begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples - * of \a this array. Textual data is not copied. Both arrays must have equal number of - * components. - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by \a tuplesSelec->getNumberOfTuples(). - * The tuples to copy are defined by values of a DataArrayInt. - * All components of selected tuples are copied. - * \param [in] tupleIdStart - index of the first tuple of \a this array to assign - * values to. - * \param [in] aBase - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If \a tuplesSelec is NULL. - * \throw If \a tuplesSelec is not allocated. - * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 1. - * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * \a aBase array. - */ -void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - if(!aBase || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !"); - const DataArrayInt *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - int *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !"); - const int *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) - { - if(*tuple>=0 && *tuplebegin(),tuple); - oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples - * of \a this array. Textual data is not copied. Both arrays must have equal number of - * components. - * The tuples to copy are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by number of tuples to copy. - * All components of selected tuples are copied. - * \param [in] tupleIdStart - index of the first tuple of \a this array to assign - * values to. - * \param [in] aBase - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a aBase. - * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy - * are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). - * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). - * \throw If parameters specifying tuples to copy, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for the array \a aBase. - */ -void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - if(!aBase) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !"); - const DataArrayInt *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !"); - checkAllocated(); - a->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - const char msg[]="DataArrayInt::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const int *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. - */ -int DataArrayInt::getIJSafe(int tupleId, int compoId) const -{ - checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(compoId<0 || compoId>=getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _mem[tupleId*_info_on_compo.size()+compoId]; -} - -/*! - * Returns the first value of \a this. - * \return int - the last value of \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -int DataArrayInt::front() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); -} - -/*! - * Returns the last value of \a this. - * \return int - the last value of \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -int DataArrayInt::back() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !"); - return *(getConstPointer()+nbOfTuples-1); -} - -/*! - * Assign pointer to one array to a pointer to another appay. Reference counter of - * \a arrayToSet is incremented / decremented. - * \param [in] newArray - the pointer to array to assign to \a arrayToSet. - * \param [in,out] arrayToSet - the pointer to array to assign to. - */ -void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet) -{ - if(newArray!=arrayToSet) - { - if(arrayToSet) - arrayToSet->decrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - -DataArrayIntIterator *DataArrayInt::iterator() -{ - return new DataArrayIntIterator(this); -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a - * given one. The ids are sorted in the ascending order. - * \param [in] val - the value to find within \a this. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa DataArrayInt::getIdsEqualTuple - */ -DataArrayInt *DataArrayInt::getIdsEqual(int val) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); - const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not - * equal to a given one. - * \param [in] val - the value to ignore within \a this. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); - const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd ) - * This method is an extension of DataArrayInt::getIdsEqual method. - * - * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this. - * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd). - * \throw If \a this->getNumberOfComponents() is equal to 0. - * \sa DataArrayInt::getIdsEqual - */ -DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const -{ - std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd)); - checkAllocated(); - if(getNumberOfComponents()!=(int)nbOfCompoExp) - { - std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(nbOfCompoExp==0) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - const int *bg(begin()),*end2(end()),*work(begin()); - while(work!=end2) - { - work=std::search(work,end2,tupleBg,tupleEnd); - if(work!=end2) - { - std::size_t pos(std::distance(bg,work)); - if(pos%nbOfCompoExp==0) - ret->pushBackSilent(pos/nbOfCompoExp); - work++; - } - } - return ret.retn(); -} - -/*! - * Assigns \a newValue to all elements holding \a oldValue within \a this - * one-dimensional array. - * \param [in] oldValue - the value to replace. - * \param [in] newValue - the value to assign. - * \return int - number of replacements performed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - */ -int DataArrayInt::changeValue(int oldValue, int newValue) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !"); - int *start=getPointer(); - int *end2=start+getNbOfElems(); - int ret=0; - for(int *val=start;val!=end2;val++) - { - if(*val==oldValue) - { - *val=newValue; - ret++; - } - } - return ret; -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to - * one of given values. - * \param [in] valsBg - an array of values to find within \a this array. - * \param [in] valsEnd - specifies the end of the array \a valsBg, so that - * the last value of \a valsBg is \a valsEnd[ -1 ]. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const -{ - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !"); - std::set vals2(valsBg,valsEnd); - const int *cptr=getConstPointer(); - std::vector res; - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not - * equal to any of given values. - * \param [in] valsBg - an array of values to ignore within \a this array. - * \param [in] valsEnd - specifies the end of the array \a valsBg, so that - * the last value of \a valsBg is \a valsEnd[ -1 ]. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const -{ - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !"); - std::set vals2(valsBg,valsEnd); - const int *cptr=getConstPointer(); - std::vector res; - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with - * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case). - * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. - * If any the tuple id is returned. If not -1 is returned. - * - * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of - * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. - * - * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this. - * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple. - */ -int DataArrayInt::locateTuple(const std::vector& tupl) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if(nbOfCompo==0) - throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !"); - if(nbOfCompo!=(int)tupl.size()) - { - std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const int *cptr=getConstPointer(); - std::size_t nbOfVals=getNbOfElems(); - for(const int *work=cptr;work!=cptr+nbOfVals;) - { - work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end()); - if(work!=cptr+nbOfVals) - { - if(std::distance(cptr,work)%nbOfCompo!=0) - work++; - else - return std::distance(cptr,work)/nbOfCompo; - } - } - return -1; -} - -/*! - * This method searches the sequence specified in input parameter \b vals in \b this. - * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown). - * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple. - * \sa DataArrayInt::locateTuple - */ -int DataArrayInt::search(const std::vector& vals) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if(nbOfCompo!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !"); - const int *cptr=getConstPointer(); - std::size_t nbOfVals=getNbOfElems(); - const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end()); - if(loc!=cptr+nbOfVals) - return std::distance(cptr,loc); - return -1; -} - -/*! - * This method expects to be called when number of components of this is equal to one. - * This method returns the tuple id, if it exists, of the first tuple equal to \b value. - * If not any tuple contains \b value -1 is returned. - * \sa DataArrayInt::presenceOfValue - */ -int DataArrayInt::locateValue(int value) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); - const int *cptr=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - const int *ret=std::find(cptr,cptr+nbOfTuples,value); - if(ret!=cptr+nbOfTuples) - return std::distance(cptr,ret); - return -1; -} - -/*! - * This method expects to be called when number of components of this is equal to one. - * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals. - * If not any tuple contains one of the values contained in 'vals' false is returned. - * \sa DataArrayInt::presenceOfValue - */ -int DataArrayInt::locateValue(const std::vector& vals) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); - std::set vals2(vals.begin(),vals.end()); - const int *cptr=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(const int *w=cptr;w!=cptr+nbOfTuples;w++) - if(vals2.find(*w)!=vals2.end()) - return std::distance(cptr,w); - return -1; -} - -/*! - * This method returns the number of values in \a this that are equals to input parameter \a value. - * This method only works for single component array. - * - * \return a value in [ 0, \c this->getNumberOfTuples() ) - * - * \throw If \a this is not allocated - * - */ -int DataArrayInt::count(int value) const -{ - int ret=0; - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); - const int *vals=begin(); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;i& tupl) const -{ - return locateTuple(tupl)!=-1; -} - - -/*! - * Returns \a true if a given value is present within \a this one-dimensional array. - * \param [in] value - the value to find within \a this array. - * \return bool - \a true in case if \a value is present within \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa locateValue() - */ -bool DataArrayInt::presenceOfValue(int value) const -{ - return locateValue(value)!=-1; -} - -/*! - * This method expects to be called when number of components of this is equal to one. - * This method returns true if it exists a tuple so that the value is contained in \b vals. - * If not any tuple contains one of the values contained in 'vals' false is returned. - * \sa DataArrayInt::locateValue - */ -bool DataArrayInt::presenceOfValue(const std::vector& vals) const -{ - return locateValue(vals)!=-1; -} - -/*! - * Accumulates values of each component of \a this array. - * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated - * by the caller, that is filled by this method with sum value for each - * component. - * \throw If \a this is not allocated. - */ -void DataArrayInt::accumulate(int *res) const -{ - checkAllocated(); - const int *ptr=getConstPointer(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - std::fill(res,res+nbComps,0); - for(int i=0;i()); -} - -int DataArrayInt::accumulate(int compId) const -{ - checkAllocated(); - const int *ptr=getConstPointer(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !"); - int ret=0; - for(int i=0;igetNumberOfTuples). - * - * \param [in] bgOfIndex - begin (included) of the input index array. - * \param [in] endOfIndex - end (excluded) of the input index array. - * \return DataArrayInt * - the new instance having the same number of components than \a this. - * - * \throw If bgOfIndex or end is NULL. - * \throw If input index array is not ascendingly sorted. - * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples). - * \throw If std::distance(bgOfIndex,endOfIndex)==0. - */ -DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const -{ - if(!bgOfIndex || !endOfIndex) - throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !"); - checkAllocated(); - int nbCompo=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - int sz=(int)std::distance(bgOfIndex,endOfIndex); - if(sz<1) - throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !"); - sz--; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(sz,nbCompo); - const int *w=bgOfIndex; - if(*w<0 || *w>=nbOfTuples) - throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !"); - const int *srcPt=begin()+(*w)*nbCompo; - int *tmp=ret->getPointer(); - for(int i=0;i=w[0]) - { - for(int j=w[0];j=0 && j()); - else - { - std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted."; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number - * of tuples in the result array is a1->getNumberOfTuples() + a2->getNumberOfTuples() - - * offsetA2 and (2) - * the number of component in the result array is same as that of each of given arrays. - * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \param [in] offsetA2 - number of tuples of \a a2 to skip. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). - */ -DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp); - int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer()); - std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt); - ret->copyStringInfoFrom(*a1); - return ret; -} - -/*! - * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number - * of tuples in the result array is a sum of the number of tuples of given arrays and (2) - * the number of component in the result array is same as that of each of given arrays. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it - * not the object itself. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If getNumberOfComponents() of arrays within \a arr. - */ -DataArrayInt *DataArrayInt::Aggregate(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - int nbOfComp=(*it)->getNumberOfComponents(); - int nbt=(*it++)->getNumberOfTuples(); - for(int i=1;it!=a.end();it++,i++) - { - if((*it)->getNumberOfComponents()!=nbOfComp) - throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !"); - nbt+=(*it)->getNumberOfTuples(); - } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbt,nbOfComp); - int *pt=ret->getPointer(); - for(it=a.begin();it!=a.end();it++) - pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); - ret->copyStringInfoFrom(*(a[0])); - return ret.retn(); -} - -/*! - * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays. - * A packed index array is an allocated array with one component, and at least one tuple. The first element - * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic. - * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes. - * - * \return DataArrayInt * - a new object to be managed by the caller. - */ -DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector& arrs) -{ - int retSz=1; - for(std::vector::const_iterator it4=arrs.begin();it4!=arrs.end();it4++) - { - if(*it4) - { - (*it4)->checkAllocated(); - if((*it4)->getNumberOfComponents()!=1) - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTupl=(*it4)->getNumberOfTuples(); - if(nbTupl<1) - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if((*it4)->front()!=0) - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retSz+=nbTupl-1; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(arrs.empty()) - throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(retSz,1); - int *pt=ret->getPointer(); *pt++=0; - for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) - pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus(),pt[-1])); - ret->copyStringInfoFrom(*(arrs[0])); - return ret.retn(); -} - -/*! - * Returns the maximal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the maximal value. - * \return int - the maximal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -int DataArrayInt::getMaxValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); - const int *vals=getConstPointer(); - const int *loc=std::max_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the maximal value within \a this array that is allowed to have more than - * one component. - * \return int - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getMaxValueInArray() const -{ - checkAllocated(); - const int *loc=std::max_element(begin(),end()); - return *loc; -} - -/*! - * Returns the minimal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the minimal value. - * \return int - the minimal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -int DataArrayInt::getMinValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); - const int *vals=getConstPointer(); - const int *loc=std::min_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the minimal value within \a this array that is allowed to have more than - * one component. - * \return int - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getMinValueInArray() const -{ - checkAllocated(); - const int *loc=std::min_element(begin(),end()); - return *loc; -} - -/*! - * Returns in a single walk in \a this the min value and the max value in \a this. - * \a this is expected to be single component array. - * - * \param [out] minValue - the min value in \a this. - * \param [out] maxValue - the max value in \a this. - * - * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue - */ -void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !"); - int nbTuples(getNumberOfTuples()); - const int *pt(begin()); - minValue=std::numeric_limits::max(); maxValue=-std::numeric_limits::max(); - for(int i=0;imaxValue) - maxValue=*pt; - } -} - -/*! - * Converts every value of \a this array to its absolute value. - * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs - * should be called instead. - * - * \throw If \a this is not allocated. - * \sa DataArrayInt::computeAbs - */ -void DataArrayInt::abs() -{ - checkAllocated(); - int *ptr(getPointer()); - std::size_t nbOfElems(getNbOfElems()); - std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(std::abs)); - declareAsNew(); -} - -/*! - * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. - * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method. - * - * \return DataArrayInt * - the new instance of DataArrayInt containing the - * same number of tuples and component as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \sa DataArrayInt::abs - */ -DataArrayInt *DataArrayInt::computeAbs() const -{ - checkAllocated(); - DataArrayInt *newArr(DataArrayInt::New()); - int nbOfTuples(getNumberOfTuples()); - int nbOfComp(getNumberOfComponents()); - newArr->alloc(nbOfTuples,nbOfComp); - std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(std::abs)); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * Apply a liner function to a given component of \a this array, so that - * an array element (x) becomes \f$ a * x + b \f$. - * \param [in] a - the first coefficient of the function. - * \param [in] b - the second coefficient of the function. - * \param [in] compoId - the index of component to modify. - * \throw If \a this is not allocated. - */ -void DataArrayInt::applyLin(int a, int b, int compoId) -{ - checkAllocated(); - int *ptr=getPointer()+compoId; - int nbOfComp=getNumberOfComponents(); - int nbOfTuple=getNumberOfTuples(); - for(int i=0;ialloc(nbOfTuples,nbOfComp); - const int *cptr=getConstPointer(); - std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * Modify all elements of \a this array, so that - * an element _x_ becomes \f$ numerator / x \f$. - * \warning If an exception is thrown because of presence of 0 element in \a this - * array, all elements processed before detection of the zero element remain - * modified. - * \param [in] numerator - the numerator used to modify array elements. - * \throw If \a this is not allocated. - * \throw If there is an element equal to 0 in \a this array. - */ -void DataArrayInt::applyInv(int numerator) -{ - checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - for(std::size_t i=0;i(),val)); - declareAsNew(); -} - -/*! - * Modify all elements of \a this array, so that - * an element _x_ becomes x % val . - * \param [in] val - the divisor used to modify array elements. - * \throw If \a this is not allocated. - * \throw If \a val <= 0. - */ -void DataArrayInt::applyModulus(int val) -{ - if(val<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !"); - checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus(),val)); - declareAsNew(); -} - -/*! - * This method works only on data array with one component. - * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that - * this[*id] in [\b vmin,\b vmax) - * - * \param [in] vmin begin of range. This value is included in range (included). - * \param [in] vmax end of range. This value is \b not included in range (excluded). - * \return a newly allocated data array that the caller should deal with. - * - * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative - */ -DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !"); - const int *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;i=vmin && *cptrpushBackSilent(i); - return ret.retn(); -} - -/*! - * This method works only on data array with one component. - * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that - * this[*id] \b not in [\b vmin,\b vmax) - * - * \param [in] vmin begin of range. This value is \b not included in range (excluded). - * \param [in] vmax end of range. This value is included in range (included). - * \return a newly allocated data array that the caller should deal with. - * - * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative - */ -DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !"); - const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;i=vmax) - ret->pushBackSilent(i); - return ret.retn(); -} - -/*! - * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0. - * - * \return a newly allocated data array that the caller should deal with. - * \sa DataArrayInt::getIdsInRange - */ -DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !"); - const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * This method works only on data array with one component. - * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown. - * - * \param [in] vmin begin of range. This value is included in range (included). - * \param [in] vmax end of range. This value is \b not included in range (excluded). - * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */ -bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !"); - int nbOfTuples=getNumberOfTuples(); - bool ret=true; - const int *cptr=getConstPointer(); - for(int i=0;i=vmin && *cptr val % x . - * \warning If an exception is thrown because of presence of an element <= 0 in \a this - * array, all elements processed before detection of the zero element remain - * modified. - * \param [in] val - the divident used to modify array elements. - * \throw If \a this is not allocated. - * \throw If there is an element equal to or less than 0 in \a this array. - */ -void DataArrayInt::applyRModulus(int val) -{ - checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - for(std::size_t i=0;i0) - { - *ptr=val%(*ptr); - } - else - { - std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - declareAsNew(); -} - -/*! - * Modify all elements of \a this array, so that - * an element _x_ becomes val ^ x . - * \param [in] val - the value used to apply pow on all array elements. - * \throw If \a this is not allocated. - * \throw If \a val < 0. - */ -void DataArrayInt::applyPow(int val) -{ - checkAllocated(); - if(val<0) - throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !"); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - if(val==0) - { - std::fill(ptr,ptr+nbOfElems,1); - return ; - } - for(std::size_t i=0;i=0) - { - int tmp=1; - for(int j=0;j<*ptr;j++) - tmp*=val; - *ptr=tmp; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - declareAsNew(); -} - -/*! - * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If both \a a1 and \a a2 are NULL. - * \throw If any given array is not allocated. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - */ -DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=a2; - return Meld(arr); -} - -/*! - * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If any given array is not allocated. - * \throw If getNumberOfTuples() of arrays within \a arr is different. - */ -DataArrayInt *DataArrayInt::Meld(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !"); - std::vector::const_iterator it; - for(it=a.begin();it!=a.end();it++) - (*it)->checkAllocated(); - it=a.begin(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::vector nbc(a.size()); - std::vector pts(a.size()); - nbc[0]=(*it)->getNumberOfComponents(); - pts[0]=(*it++)->getConstPointer(); - for(int i=1;it!=a.end();it++,i++) - { - if(nbOfTuples!=(*it)->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,totalNbOfComp); - int *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - -/*! - * Returns a new DataArrayInt which is a minimal partition of elements of \a groups. - * The i-th item of the result array is an ID of a set of elements belonging to a - * unique set of groups, which the i-th element is a part of. This set of elements - * belonging to a unique set of groups is called \a family, so the result array contains - * IDs of families each element belongs to. - * - * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ], - * then there are 3 families: - * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ), - * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ), - * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ),
- * and the result array contains IDs of families [ 1,3,3,0,2 ].
Note a family ID 0 which - * stands for the element #3 which is in none of groups. - * - * \param [in] groups - sequence of groups of element IDs. - * \param [in] newNb - total number of elements; it must be more than max ID of element - * in \a groups. - * \param [out] fidsOfGroups - IDs of families the elements of each group belong to. - * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families - * each element with ID from range [0, \a newNb ) belongs to. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ). - */ -DataArrayInt *DataArrayInt::MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) -{ - std::vector groups2; - for(std::vector::const_iterator it4=groups.begin();it4!=groups.end();it4++) - if(*it4) - groups2.push_back(*it4); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNb,1); - int *retPtr=ret->getPointer(); - std::fill(retPtr,retPtr+newNb,0); - int fid=1; - for(std::vector::const_iterator iter=groups2.begin();iter!=groups2.end();iter++) - { - const int *ptr=(*iter)->getConstPointer(); - std::size_t nbOfElem=(*iter)->getNbOfElems(); - int sfid=fid; - for(int j=0;j=0 && ptr[i]getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb; - oss << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(found) - fid++; - } - } - fidsOfGroups.clear(); - fidsOfGroups.resize(groups2.size()); - int grId=0; - for(std::vector::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++) - { - std::set tmp; - const int *ptr=(*iter)->getConstPointer(); - std::size_t nbOfElem=(*iter)->getNbOfElems(); - for(const int *p=ptr;p!=ptr+nbOfElem;p++) - tmp.insert(retPtr[*p]); - fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end()); - } - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt which contains all elements of given one-dimensional - * arrays. The result array does not contain any duplicates and its values - * are sorted in ascending order. - * \param [in] arr - sequence of DataArrayInt's to unite. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If any \a arr[i] is not allocated. - * \throw If \a arr[i]->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::BuildUnion(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - (*it)->checkAllocated(); - if((*it)->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !"); - } - // - std::set r; - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - const int *pt=(*it)->getConstPointer(); - int nbOfTuples=(*it)->getNumberOfTuples(); - r.insert(pt,pt+nbOfTuples); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - return ret; -} - -/*! - * Returns a new DataArrayInt which contains elements present in each of given one-dimensional - * arrays. The result array does not contain any duplicates and its values - * are sorted in ascending order. - * \param [in] arr - sequence of DataArrayInt's to intersect. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If any \a arr[i] is not allocated. - * \throw If \a arr[i]->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::BuildIntersection(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - (*it)->checkAllocated(); - if((*it)->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !"); - } - // - std::set r; - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - const int *pt=(*it)->getConstPointer(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::set s1(pt,pt+nbOfTuples); - if(it!=a.begin()) - { - std::set r2; - std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end())); - r=r2; - } - else - r=s1; - } - DataArrayInt *ret(DataArrayInt::New()); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - return ret; -} - -/// @cond INTERNAL -namespace ParaMEDMEMImpl -{ - class OpSwitchedOn - { - public: - OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { } - void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; } - private: - int *_pt; - int _cnt; - }; - - class OpSwitchedOff - { - public: - OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { } - void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; } - private: - int *_pt; - int _cnt; - }; -} -/// @endcond - -/*! - * This method returns the list of ids in ascending mode so that v[id]==true. - */ -DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector& v) -{ - int sz((int)std::count(v.begin(),v.end(),true)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer())); - return ret.retn(); -} - -/*! - * This method returns the list of ids in ascending mode so that v[id]==false. - */ -DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector& v) -{ - int sz((int)std::count(v.begin(),v.end(),false)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer())); - return ret.retn(); -} - -/*! - * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). - * This method is not available into python because no available optimized data structure available to map std::vector< std::vector >. - * - * \param [in] v the input data structure to be translate into skyline format. - * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array. - * \param [out] dataIndex the second element of the skyline format. - */ -void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex) -{ - int sz((int)v.size()); - MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); - ret1->alloc(sz+1,1); - int *pt(ret1->getPointer()); *pt=0; - for(int i=0;ialloc(ret1->back(),1); - pt=ret0->getPointer(); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a - * nbOfElement ). - */ -DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !"); - std::vector tmp(nbOfElement); - const int *pt=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(const int *w=pt;w!=pt+nbOfTuples;w++) - if(*w>=0 && *walloc(nbOfRetVal,1); - int j=0; - int *retPtr=ret->getPointer(); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa DataArrayInt::buildSubstractionOptimized() - */ -DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - other->checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !"); - if(other->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !"); - const int *pt=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - std::set s1(pt,pt+nbOfTuples); - pt=other->getConstPointer(); - nbOfTuples=other->getNumberOfTuples(); - std::set s2(pt,pt+nbOfTuples); - std::vector r; - std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector >(r)); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - return ret; -} - -/*! - * \a this is expected to have one component and to be sorted ascendingly (as for \a other). - * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead. - * - * \param [in] other an array with one component and expected to be sorted ascendingly. - * \ret list of ids in \a this but not in \a other. - * \sa DataArrayInt::buildSubstraction - */ -DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const -{ - static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !"; - if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !"); - checkAllocated(); other->checkAllocated(); - if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); - if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); - const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()); - const int *work1(pt1Bg),*work2(pt2Bg); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(;work1!=pt1End;work1++) - { - if(work2!=pt2End && *work1==*work2) - work2++; - else - ret->pushBackSilent(*work1); - } - return ret.retn(); -} - - -/*! - * Returns a new DataArrayInt which contains all elements of \a this and a given - * one-dimensional arrays. The result array does not contain any duplicates - * and its values are sorted in ascending order. - * \param [in] other - an array to unite with \a this one. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this or \a other is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a other->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const -{ - std::vectorarrs(2); - arrs[0]=this; arrs[1]=other; - return BuildUnion(arrs); -} - - -/*! - * Returns a new DataArrayInt which contains elements present in both \a this and a given - * one-dimensional arrays. The result array does not contain any duplicates - * and its values are sorted in ascending order. - * \param [in] other - an array to intersect with \a this one. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this or \a other is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a other->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const -{ - std::vectorarrs(2); - arrs[0]=this; arrs[1]=other; - return BuildIntersection(arrs); -} - -/*! - * This method can be applied on allocated with one component DataArrayInt instance. - * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance. - * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19] - * - * \return a newly allocated array that contain the result of the unique operation applied on \a this. - * \throw if \a this is not allocated or if \a this has not exactly one component. - * \sa DataArrayInt::buildUniqueNotSorted - */ -DataArrayInt *DataArrayInt::buildUnique() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr tmp=deepCpy(); - int *data=tmp->getPointer(); - int *last=std::unique(data,data+nbOfTuples); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(std::distance(data,last),1); - std::copy(data,last,ret->getPointer()); - return ret.retn(); -} - -/*! - * This method can be applied on allocated with one component DataArrayInt instance. - * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted. - * - * \return a newly allocated array that contain the result of the unique operation applied on \a this. - * - * \throw if \a this is not allocated or if \a this has not exactly one component. - * - * \sa DataArrayInt::buildUnique - */ -DataArrayInt *DataArrayInt::buildUniqueNotSorted() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !"); - int minVal,maxVal; - getMinMaxValues(minVal,maxVal); - std::vector b(maxVal-minVal+1,false); - const int *ptBg(begin()),*endBg(end()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(const int *pt=ptBg;pt!=endBg;pt++) - { - if(!b[*pt-minVal]) - { - ret->pushBackSilent(*pt); - b[*pt-minVal]=true; - } - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt which contains size of every of groups described by \a this - * "index" array. Such "index" array is returned for example by - * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity - * "MEDCouplingUMesh::buildDescendingConnectivity" and - * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex - * "MEDCouplingUMesh::getNodalConnectivityIndex" etc. - * This method preforms the reverse operation of DataArrayInt::computeOffsets2. - * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples - * equals to \a this->getNumberOfComponents() - 1, and number of components is 1. - * The caller is to delete this array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 2. - * - * \b Example:
- * - this contains [1,3,6,7,7,9,15] - * - result array contains [2,3,1,0,2,6], - * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc. - * - * \sa DataArrayInt::computeOffsets2 - */ -DataArrayInt *DataArrayInt::deltaShiftIndex() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<2) - throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !"); - const int *ptr=getConstPointer(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples-1,1); - int *out=ret->getPointer(); - std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus()); - return ret; -} - -/*! - * Modifies \a this one-dimensional array so that value of each element \a x - * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$. - * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples - * and components remains the same.
- * This method is useful for allToAllV in MPI with contiguous policy. This method - * differs from computeOffsets2() in that the number of tuples is \b not changed by - * this one. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * - * \b Example:
- * - Before \a this contains [3,5,1,2,0,8] - * - After \a this contains [0,3,8,9,11,11]
- * Note that the last element 19 = 11 + 8 is missing because size of \a this - * array is retained and thus there is no space to store the last element. - */ -void DataArrayInt::computeOffsets() -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples==0) - return ; - int *work=getPointer(); - int tmp=work[0]; - work[0]=0; - for(int i=1;i0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number - * components remains the same and number of tuples is inceamented by one.
- * This method is useful for allToAllV in MPI with contiguous policy. This method - * differs from computeOffsets() in that the number of tuples is changed by this one. - * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * - * \b Example:
- * - Before \a this contains [3,5,1,2,0,8] - * - After \a this contains [0,3,8,9,11,11,19]
- * \sa DataArrayInt::deltaShiftIndex - */ -void DataArrayInt::computeOffsets2() -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int)); - if(nbOfTuples==0) - return ; - const int *work=getConstPointer(); - ret[0]=0; - for(int i=0;igetNumberOfComponents() ranges, all ids in \a listOfIds - * filling completely one of the ranges in \a this. - * - * \param [in] listOfIds a list of ids that has to be sorted ascendingly. - * \param [out] rangeIdsFetched the range ids fetched - * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So - * \a idsInInputListThatFetch is a part of input \a listOfIds. - * - * \sa DataArrayInt::computeOffsets2 - * - * \b Example:
- * - \a this : [0,3,7,9,15,18] - * - \a listOfIds contains [0,1,2,3,7,8,15,16,17] - * - \a rangeIdsFetched result array: [0,2,4] - * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17] - * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch. - *
- */ -void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const -{ - if(!listOfIds) - throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !"); - listOfIds->checkAllocated(); checkAllocated(); - if(listOfIds->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !"); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !"); - MEDCouplingAutoRefCountObjectPtr ret0=DataArrayInt::New(); ret0->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc(0,1); - const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1); - const int *tupPtr(listOfIds->begin()),*offPtr(offBg); - while(tupPtr!=tupEnd && offPtr!=offEnd) - { - if(*tupPtr==*offPtr) - { - int i=offPtr[0]; - while(ipushBackSilent((int)std::distance(offBg,offPtr)); - ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr); - offPtr++; - } - } - else - { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; } - } - rangeIdsFetched=ret0.retn(); - idsInInputListThatFetch=ret1.retn(); -} - -/*! - * Returns a new DataArrayInt whose contents is computed from that of \a this and \a - * offsets arrays as follows. \a offsets is a one-dimensional array considered as an - * "index" array of a "iota" array, thus, whose each element gives an index of a group - * beginning within the "iota" array. And \a this is a one-dimensional array - * considered as a selector of groups described by \a offsets to include into the result array. - * \throw If \a offsets is NULL. - * \throw If \a offsets is not allocated. - * \throw If \a offsets->getNumberOfComponents() != 1. - * \throw If \a offsets is not monotonically increasing. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If any element of \a this is not a valid index for \a offsets array. - * - * \b Example:
- * - \a this: [0,2,3] - * - \a offsets: [0,3,6,10,14,20] - * - result array: [0,1,2,6,7,8,9,10,11,12,13] ==
- * \c range(0,3) + \c range(6,10) + \c range(10,14) ==
- * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + - * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + - * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ]) - */ -DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const -{ - if(!offsets) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !"); - offsets->checkAllocated(); - if(offsets->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !"); - int othNbTuples=offsets->getNumberOfTuples()-1; - int nbOfTuples=getNumberOfTuples(); - int retNbOftuples=0; - const int *work=getConstPointer(); - const int *offPtr=offsets->getConstPointer(); - for(int i=0;i=0 && val=0) - retNbOftuples+=delta; - else - { - std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val; - oss << " whereas offsets array is of size " << othNbTuples+1 << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(retNbOftuples,1); - int *retPtr=ret->getPointer(); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() == 0. - * \throw If \a this is not monotonically increasing. - * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this. - * - * \b Example:
- * - \a bg , \a stop and \a step : (0,5,2) - * - \a this: [0,3,6,10,14,20] - * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] ==
- */ -DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !"); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples==0) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !"); - const int *ids(begin()); - int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg); - for(int i=0;i=0 && pos ret(DataArrayInt::New()); ret->alloc(sz,1); - int *retPtr(ret->getPointer()); - pos=bg; - for(int i=0;igetIJ(i,0) and put the result - * in tuple **i** of returned DataArrayInt. - * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range. - * - * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)] - * The return DataArrayInt will contain : **[0,4,1,2,2,3]** - * - * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is - * for lower value included and 2nd component is the upper value of corresponding range **excluded**. - * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception - * is thrown if no ranges in \a ranges contains value in \a this. - * - * \sa DataArrayInt::findIdInRangeForEachTuple - */ -DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const -{ - if(!ranges) - throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !"); - if(ranges->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !"); - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !"); - int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,1); - int nbOfRanges=ranges->getNumberOfTuples(); - const int *rangesPtr=ranges->getConstPointer(); - int *retPtr=ret->getPointer(); - const int *inPtr=getConstPointer(); - for(int i=0;i=rangesPtr[2*j] && valgetIJ(i,0) and put the result - * in tuple **i** of returned DataArrayInt. - * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range. - * - * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)] - * The return DataArrayInt will contain : **[1,2,4,0,2,2]** - * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method. - * - * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is - * for lower value included and 2nd component is the upper value of corresponding range **excluded**. - * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception - * is thrown if no ranges in \a ranges contains value in \a this. - * \sa DataArrayInt::findRangeIdForEachTuple - */ -DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const -{ - if(!ranges) - throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !"); - if(ranges->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !"); - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !"); - int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,1); - int nbOfRanges=ranges->getNumberOfTuples(); - const int *rangesPtr=ranges->getConstPointer(); - int *retPtr=ret->getPointer(); - const int *inPtr=getConstPointer(); - for(int i=0;i=rangesPtr[2*j] && valgetIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0). - * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified ! - * If this method has correctly worked, \a this will be able to be considered as a linked list. - * This method does nothing if number of tuples is lower of equal to 1. - * - * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration. - * - * \sa MEDCouplingUMesh::orderConsecutiveCells1D - */ -void DataArrayInt::sortEachPairToMakeALinkedList() -{ - checkAllocated(); - if(getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples<=1) - return ; - int *conn(getPointer()); - for(int i=1;i1) - { - if(conn[2]==conn[3]) - { - std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0]) - std::swap(conn[2],conn[3]); - //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0]) - if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0]) - { - std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(conn[0]==conn[1] || conn[2]==conn[3]) - throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !"); - int tmp[4]; - std::set s; - s.insert(conn,conn+4); - if(s.size()!=3) - throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !"); - if(std::count(conn,conn+4,conn[0])==2) - { - tmp[0]=conn[1]; - tmp[1]=conn[0]; - tmp[2]=conn[0]; - if(conn[2]==conn[0]) - { tmp[3]=conn[3]; } - else - { tmp[3]=conn[2];} - std::copy(tmp,tmp+4,conn); - } - } - } -} - -/*! - * - * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance. - * \a nbTimes should be at least equal to 1. - * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. - * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1. - */ -DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !"); - if(nbTimes<1) - throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !"); - int nbTuples=getNumberOfTuples(); - const int *inPtr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1); - int *retPtr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * This method returns all different values found in \a this. This method throws if \a this has not been allocated. - * But the number of components can be different from one. - * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this. - */ -DataArrayInt *DataArrayInt::getDifferentValues() const -{ - checkAllocated(); - std::set ret; - ret.insert(begin(),end()); - MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); - std::copy(ret.begin(),ret.end(),ret2->getPointer()); - return ret2.retn(); -} - -/*! - * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of - * them it tells which tuple id have this id. - * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ). - * This method returns two arrays having same size. - * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method. - * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]] - */ -std::vector DataArrayInt::partitionByDifferentValues(std::vector& differentIds) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !"); - int id=0; - std::map m,m2,m3; - for(const int *w=begin();w!=end();w++) - m[*w]++; - differentIds.resize(m.size()); - std::vector ret(m.size()); - std::vector retPtr(m.size()); - for(std::map::const_iterator it=m.begin();it!=m.end();it++,id++) - { - m2[(*it).first]=id; - ret[id]=DataArrayInt::New(); - ret[id]->alloc((*it).second,1); - retPtr[id]=ret[id]->getPointer(); - differentIds[id]=(*it).first; - } - id=0; - for(const int *w=begin();w!=end();w++,id++) - { - retPtr[m2[*w]][m3[*w]++]=id; - } - return ret; -} - -/*! - * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each). - * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible. - * - * \param [in] nbOfSlices - number of slices expected. - * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks. - * - * \sa DataArray::GetSlice - * \throw If \a this is not allocated or not with exactly one component. - * \throw If an element in \a this if < 0. - */ -std::vector< std::pair > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const -{ - if(!isAllocated() || getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !"); - if(nbOfSlices<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !"); - int sum(accumulate(0)),nbOfTuples(getNumberOfTuples()); - int sumPerSlc(sum/nbOfSlices),pos(0); - const int *w(begin()); - std::vector< std::pair > ret(nbOfSlices); - for(int i=0;i p(pos,-1); - int locSum(0); - while(locSumgetNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayInt *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const int *aMinPtr=aMin->getConstPointer(); - const int *aMaxPtr=aMax->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayInt::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - int *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - return ret.retn(); -} - -/*! - * Adds values of another DataArrayInt to values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is added to the corresponding value of \a this array, i.e.: - * _a_ [ i, j ] += _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] += _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] += _a2_ [ 0, j ]. - * - * \param [in] other - an array to add to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayInt::addEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual !"; - checkAllocated(); other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::plus()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a subtraction of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - an array to subtract from. - * \param [in] a2 - an array to subtract. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception - return 0; - } -} - -/*! - * Subtract values of another DataArrayInt from values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is subtracted from the corresponding value of \a this array, i.e.: - * _a_ [ i, j ] -= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] -= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] -= _a2_ [ 0, j ]. - * - * \param [in] other - an array to subtract from \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayInt::substractEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual !"; - checkAllocated(); other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::minus()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayInt that is a product of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a product of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - a factor array. - * \param [in] a2 - another factor array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayInt *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const int *aMinPtr=aMin->getConstPointer(); - const int *aMaxPtr=aMax->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayInt::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - int *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - return ret.retn(); -} - - -/*! - * Multiply values of another DataArrayInt to values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is multiplied to the corresponding value of \a this array, i.e.: - * _a_ [ i, j ] *= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] *= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] *= _a2_ [ 0, j ]. - * - * \param [in] other - an array to multiply to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayInt::multiplyEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !"; - checkAllocated(); other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - - -/*! - * Returns a new DataArrayInt that is a division of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a division of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \warning No check of division by zero is performed! - * \param [in] a1 - a numerator array. - * \param [in] a2 - a denominator array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception - return 0; - } -} - -/*! - * Divide values of \a this array by values of another DataArrayInt. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a this array is divided by the corresponding value of \a other one, i.e.: - * _a_ [ i, j ] /= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] /= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] /= _a2_ [ 0, j ]. - * - * \warning No check of division by zero is performed! - * \param [in] other - an array to divide \a this one by. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayInt::divideEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !"; - checkAllocated(); other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::divides()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - - -/*! - * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a division of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \warning No check of division by zero is performed! - * \param [in] a1 - a dividend array. - * \param [in] a2 - a divisor array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception - return 0; - } -} - -/*! - * Modify \a this array so that each value becomes a modulus of division of this value by - * a value of another DataArrayInt. There are 3 valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a this array is divided by the corresponding value of \a other one, i.e.: - * _a_ [ i, j ] %= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] %= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] %= _a2_ [ 0, j ]. - * - * \warning No check of division by zero is performed! - * \param [in] other - a divisor array. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayInt::modulusEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !"; - checkAllocated(); other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::modulus()); - } - else if(nbOfComp2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3 - * valid cases. - * - * \param [in] a1 - an array to pow up. - * \param [in] a2 - another array to sum up. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. - * \throw If there is a negative value in \a a2. - */ -DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple!=nbOfTuple2) - throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !"); - if(nbOfComp!=1 || nbOfComp2!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1); - const int *ptr1(a1->begin()),*ptr2(a2->begin()); - int *ptr=ret->getPointer(); - for(int i=0;i=0) - { - int tmp=1; - for(int j=0;j<*ptr2;j++) - tmp*=*ptr1; - *ptr=tmp; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret.retn(); -} - -/*! - * Apply pow on values of another DataArrayInt to values of \a this one. - * - * \param [in] other - an array to pow to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() - * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1 - * \throw If there is a negative value in \a other. - */ -void DataArrayInt::powEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !"); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple!=nbOfTuple2) - throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !"); - if(nbOfComp!=1 || nbOfComp2!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !"); - int *ptr=getPointer(); - const int *ptrc=other->begin(); - for(int i=0;i=0) - { - int tmp=1; - for(int j=0;j<*ptrc;j++) - tmp*=*ptr; - *ptr=tmp; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - declareAsNew(); -} - -/*! - * Returns a C array which is a renumbering map in "Old to New" mode for the input array. - * This map, if applied to \a start array, would make it sorted. For example, if - * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is - * [5,6,0,3,2,7,1,4]. - * \param [in] start - pointer to the first element of the array for which the - * permutation map is computed. - * \param [in] end - pointer specifying the end of the array \a start, so that - * the last value of \a start is \a end[ -1 ]. - * \return int * - the result permutation array that the caller is to delete as it is no - * more needed. - * \throw If there are equal values in the input array. - */ -int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end) -{ - std::size_t sz=std::distance(start,end); - int *ret=(int *)malloc(sz*sizeof(int)); - int *work=new int[sz]; - std::copy(start,end,work); - std::sort(work,work+sz); - if(std::unique(work,work+sz)!=work+sz) - { - delete [] work; - free(ret); - throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !"); - } - std::map m; - for(int *workPt=work;workPt!=work+sz;workPt++) - m[*workPt]=(int)std::distance(work,workPt); - int *iter2=ret; - for(const int *iter=start;iter!=end;iter++,iter2++) - *iter2=m[*iter]; - delete [] work; - return ret; -} - -/*! - * Returns a new DataArrayInt containing an arithmetic progression - * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step ) - * function. - * \param [in] begin - the start value of the result sequence. - * \param [in] end - limiting value, so that every value of the result array is less than - * \a end. - * \param [in] step - specifies the increment or decrement. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a step == 0. - * \throw If \a end < \a begin && \a step > 0. - * \throw If \a end > \a begin && \a step < 0. - */ -DataArrayInt *DataArrayInt::Range(int begin, int end, int step) -{ - int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); - int *ptr=ret->getPointer(); - if(step>0) - { - for(int i=begin;iend;i+=step,ptr++) - *ptr=i; - } - return ret.retn(); -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * Server side. - */ -void DataArrayInt::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - tinyInfo.resize(2); - if(isAllocated()) - { - tinyInfo[0]=getNumberOfTuples(); - tinyInfo[1]=getNumberOfComponents(); - } - else - { - tinyInfo[0]=-1; - tinyInfo[1]=-1; - } -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * Server side. - */ -void DataArrayInt::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - if(isAllocated()) - { - int nbOfCompo=getNumberOfComponents(); - tinyInfo.resize(nbOfCompo+1); - tinyInfo[0]=getName(); - for(int i=0;i& tinyInfoI) -{ - int nbOfTuple=tinyInfoI[0]; - int nbOfComp=tinyInfoI[1]; - if(nbOfTuple!=-1 || nbOfComp!=-1) - { - alloc(nbOfTuple,nbOfComp); - return true; - } - return false; -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * This method returns if a feeding is needed. - */ -void DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS) -{ - setName(tinyInfoS[0]); - if(isAllocated()) - { - int nbOfCompo=tinyInfoI[1]; - for(int i=0;iincrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayIntIterator::~DataArrayIntIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayIntTuple *DataArrayIntIterator::nextt() -{ - if(_tuple_id<_nb_tuple) - { - _tuple_id++; - DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp); - _pt+=_nb_comp; - return ret; - } - else - return 0; -} - -DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) -{ -} - -std::string DataArrayIntTuple::repr() const -{ - std::ostringstream oss; oss << "("; - for(int i=0;i<_nb_of_compo-1;i++) - oss << _pt[i] << ", "; - oss << _pt[_nb_of_compo-1] << ")"; - return oss.str(); -} - -int DataArrayIntTuple::intValue() const -{ - if(_nb_of_compo==1) - return *_pt; - throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !"); -} - -/*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false. - * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or - * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. - */ -DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const -{ - if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) - { - DataArrayInt *ret=DataArrayInt::New(); - ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); - return ret; - } - else - { - std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo; - oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} diff --git a/medtool/src/MEDCoupling/MEDCouplingMemArray.hxx b/medtool/src/MEDCoupling/MEDCouplingMemArray.hxx deleted file mode 100644 index 201b7601e..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMemArray.hxx +++ /dev/null @@ -1,947 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "InterpKernelException.hxx" -#include "BBTreePts.txx" - -#include -#include -#include - -namespace ParaMEDMEM -{ - template - class MEDCouplingPointer - { - public: - MEDCouplingPointer():_internal(0),_external(0) { } - void null() { _internal=0; _external=0; } - bool isNull() const { return _internal==0 && _external==0; } - void setInternal(T *pointer); - void setExternal(const T *pointer); - const T *getConstPointer() const { if(_internal) return _internal; else return _external; } - const T *getConstPointerLoc(std::size_t offset) const { if(_internal) return _internal+offset; else return _external+offset; } - T *getPointer() { if(_internal) return _internal; if(_external) throw INTERP_KERNEL::Exception("Trying to write on an external pointer."); else return 0; } - private: - T *_internal; - const T *_external; - }; - - template - class MemArray - { - public: - typedef void (*Deallocator)(void *,void *); - public: - MemArray():_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0) { } - MemArray(const MemArray& other); - bool isNull() const { return _pointer.isNull(); } - const T *getConstPointerLoc(std::size_t offset) const { return _pointer.getConstPointerLoc(offset); } - const T *getConstPointer() const { return _pointer.getConstPointer(); } - std::size_t getNbOfElem() const { return _nb_of_elem; } - std::size_t getNbOfElemAllocated() const { return _nb_of_elem_alloc; } - T *getPointer() { return _pointer.getPointer(); } - MemArray &operator=(const MemArray& other); - T operator[](std::size_t id) const { return _pointer.getConstPointer()[id]; } - T& operator[](std::size_t id) { return _pointer.getPointer()[id]; } - bool isEqual(const MemArray& other, T prec, std::string& reason) const; - void repr(int sl, std::ostream& stream) const; - bool reprHeader(int sl, std::ostream& stream) const; - void reprZip(int sl, std::ostream& stream) const; - void reprNotTooLong(int sl, std::ostream& stream) const; - void fillWithValue(const T& val); - T *fromNoInterlace(int nbOfComp) const; - T *toNoInterlace(int nbOfComp) const; - void sort(bool asc); - void reverse(int nbOfComp); - void alloc(std::size_t nbOfElements); - void reserve(std::size_t newNbOfElements); - void reAlloc(std::size_t newNbOfElements); - void useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem); - void useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem); - void writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - void pushBack(T elem); - T popBack(); - void pack() const; - bool isDeallocatorCalled() const { return _ownership; } - Deallocator getDeallocator() const { return _dealloc; } - void setSpecificDeallocator(Deallocator dealloc) { _dealloc=dealloc; } - void setParameterForDeallocator(void *param) { _param_for_deallocator=param; } - void *getParameterForDeallocator() const { return _param_for_deallocator; } - void destroy(); - ~MemArray() { destroy(); } - public: - static void CPPDeallocator(void *pt, void *param); - static void CDeallocator(void *pt, void *param); - private: - static void DestroyPointer(T *pt, Deallocator dealloc, void *param); - static Deallocator BuildFromType(DeallocType type); - private: - std::size_t _nb_of_elem; - std::size_t _nb_of_elem_alloc; - bool _ownership; - MEDCouplingPointer _pointer; - Deallocator _dealloc; - void *_param_for_deallocator; - }; - - class DataArrayInt; - class DataArrayByte; - - class DataArray : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void setName(const std::string& name); - MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other); - MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds); - MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other); - MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const; - MEDCOUPLING_EXPORT std::string cppRepr(const std::string& varName) const; - MEDCOUPLING_EXPORT std::string getName() const { return _name; } - MEDCOUPLING_EXPORT const std::vector &getInfoOnComponents() const { return _info_on_compo; } - MEDCOUPLING_EXPORT std::vector &getInfoOnComponents() { return _info_on_compo; } - MEDCOUPLING_EXPORT void setInfoOnComponents(const std::vector& info); - MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info); - MEDCOUPLING_EXPORT std::vector getVarsOnComponent() const; - MEDCOUPLING_EXPORT std::vector getUnitsOnComponent() const; - MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const; - MEDCOUPLING_EXPORT std::string getVarOnComponent(int i) const; - MEDCOUPLING_EXPORT std::string getUnitOnComponent(int i) const; - MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const std::string& info); - MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); } - MEDCOUPLING_EXPORT void setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT virtual DataArray *deepCpy() const = 0; - MEDCOUPLING_EXPORT virtual bool isAllocated() const = 0; - MEDCOUPLING_EXPORT virtual void checkAllocated() const = 0; - MEDCOUPLING_EXPORT virtual void desallocate() = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfTuples() const = 0; - MEDCOUPLING_EXPORT virtual std::size_t getNbOfElems() const = 0; - MEDCOUPLING_EXPORT virtual std::size_t getNbOfElemAllocated() const = 0; - MEDCOUPLING_EXPORT virtual void alloc(int nbOfTuple, int nbOfCompo=1) = 0; - MEDCOUPLING_EXPORT virtual void reAlloc(int newNbOfTuple) = 0; - MEDCOUPLING_EXPORT virtual void renumberInPlace(const int *old2New) = 0; - MEDCOUPLING_EXPORT virtual void renumberInPlaceR(const int *new2Old) = 0; - MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) = 0; - MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleRanges(const std::vector >& ranges) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *keepSelectedComponents(const std::vector& compoIds) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleId2(int bg, int end2, int step) const = 0; - MEDCOUPLING_EXPORT virtual void rearrange(int newNbOfCompo) = 0; - MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const; - MEDCOUPLING_EXPORT static void GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice); - MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg); - MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg); - MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step); - MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info); - MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info); - MEDCOUPLING_EXPORT static std::string BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit); - MEDCOUPLING_EXPORT static DataArray *Aggregate(const std::vector& arrs); - MEDCOUPLING_EXPORT virtual void reprStream(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprZipStream(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT virtual void reprZipWithoutNameStream(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprCppStream(const std::string& varName, std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const = 0; - protected: - DataArray() { } - ~DataArray() { } - protected: - static void CheckValueInRange(int ref, int value, const std::string& msg); - static void CheckValueInRangeEx(int value, int start, int end, const std::string& msg); - static void CheckClosingParInRange(int ref, int value, const std::string& msg); - protected: - std::string _name; - std::vector _info_on_compo; - }; -} - -#include "MEDCouplingMemArray.txx" - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDoubleIterator; - class DataArrayDouble : public DataArray - { - public: - MEDCOUPLING_EXPORT static DataArrayDouble *New(); - MEDCOUPLING_EXPORT bool isAllocated() const; - MEDCOUPLING_EXPORT void checkAllocated() const; - MEDCOUPLING_EXPORT void desallocate(); - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } - MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT double doubleValue() const; - MEDCOUPLING_EXPORT bool empty() const; - MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void cpyFrom(const DataArrayDouble& other); - MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); - MEDCOUPLING_EXPORT void pushBackSilent(double val); - MEDCOUPLING_EXPORT void pushBackValsSilent(const double *valsBg, const double *valsEnd); - MEDCOUPLING_EXPORT double popBackSilent(); - MEDCOUPLING_EXPORT void pack() const; - MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void fillWithZero(); - MEDCOUPLING_EXPORT void fillWithValue(double val); - MEDCOUPLING_EXPORT void iota(double init=0.); - MEDCOUPLING_EXPORT bool isUniform(double val, double eps) const; - MEDCOUPLING_EXPORT void sort(bool asc=true); - MEDCOUPLING_EXPORT void reverse(); - MEDCOUPLING_EXPORT void checkMonotonic(bool increasing, double eps) const; - MEDCOUPLING_EXPORT bool isMonotonic(bool increasing, double eps) const; - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; - MEDCOUPLING_EXPORT std::string reprNotTooLong() const; - MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const; - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; - MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); - MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; - MEDCOUPLING_EXPORT DataArrayDouble *fromNoInterlace() const; - MEDCOUPLING_EXPORT DataArrayDouble *toNoInterlace() const; - MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); - MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); - MEDCOUPLING_EXPORT DataArrayDouble *renumber(const int *old2New) const; - MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const; - MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const; - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const DataArrayInt & di) const; - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId2(int bg, int end2, int step) const; - MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const; - MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const; - MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); - MEDCOUPLING_EXPORT void transpose(); - MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const; - MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other); - MEDCOUPLING_EXPORT bool areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const; - MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; - MEDCOUPLING_EXPORT double minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const; - MEDCOUPLING_EXPORT DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const; - MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const; - MEDCOUPLING_EXPORT DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const; - MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds); - MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); - MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } - MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } - MEDCOUPLING_EXPORT double front() const; - MEDCOUPLING_EXPORT double back() const; - MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const; - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } - MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); declareAsNew(); } - MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet); - MEDCOUPLING_EXPORT const double *getConstPointer() const { return _mem.getConstPointer(); } - MEDCOUPLING_EXPORT DataArrayDoubleIterator *iterator(); - MEDCOUPLING_EXPORT const double *begin() const { return getConstPointer(); } - MEDCOUPLING_EXPORT const double *end() const { return getConstPointer()+getNbOfElems(); } - MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - MEDCOUPLING_EXPORT void writeOnPlace(std::size_t id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } - MEDCOUPLING_EXPORT void checkNoNullValues() const; - MEDCOUPLING_EXPORT void getMinMaxPerComponent(double *bounds) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const; - MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; - MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps); - MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const; - MEDCOUPLING_EXPORT double getMaxValueInArray() const; - MEDCOUPLING_EXPORT double getMinValue(int& tupleId) const; - MEDCOUPLING_EXPORT double getMinValueInArray() const; - MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT int count(double value, double eps) const; - MEDCOUPLING_EXPORT double getAverageValue() const; - MEDCOUPLING_EXPORT double norm2() const; - MEDCOUPLING_EXPORT double normMax() const; - MEDCOUPLING_EXPORT double normMin() const; - MEDCOUPLING_EXPORT void accumulate(double *res) const; - MEDCOUPLING_EXPORT double accumulate(int compId) const; - MEDCOUPLING_EXPORT DataArrayDouble *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const; - MEDCOUPLING_EXPORT double distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const; - MEDCOUPLING_EXPORT DataArrayDouble *fromPolarToCart() const; - MEDCOUPLING_EXPORT DataArrayDouble *fromCylToCart() const; - MEDCOUPLING_EXPORT DataArrayDouble *fromSpherToCart() const; - MEDCOUPLING_EXPORT DataArrayDouble *doublyContractedProduct() const; - MEDCOUPLING_EXPORT DataArrayDouble *determinant() const; - MEDCOUPLING_EXPORT DataArrayDouble *eigenValues() const; - MEDCOUPLING_EXPORT DataArrayDouble *eigenVectors() const; - MEDCOUPLING_EXPORT DataArrayDouble *inverse() const; - MEDCOUPLING_EXPORT DataArrayDouble *trace() const; - MEDCOUPLING_EXPORT DataArrayDouble *deviator() const; - MEDCOUPLING_EXPORT DataArrayDouble *magnitude() const; - MEDCOUPLING_EXPORT DataArrayDouble *sumPerTuple() const; - MEDCOUPLING_EXPORT DataArrayDouble *maxPerTuple() const; - MEDCOUPLING_EXPORT DataArrayDouble *maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const; - MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrix() const; - MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const; - MEDCOUPLING_EXPORT void sortPerTuple(bool asc); - MEDCOUPLING_EXPORT void abs(); - MEDCOUPLING_EXPORT DataArrayDouble *computeAbs() const; - MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT void applyLin(double a, double b); - MEDCOUPLING_EXPORT void applyInv(double numerator); - MEDCOUPLING_EXPORT void applyPow(double val); - MEDCOUPLING_EXPORT void applyRPow(double val); - MEDCOUPLING_EXPORT DataArrayDouble *negate() const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT void applyFuncOnThis(const std::string& func, bool isSafe=true); - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT void applyFuncFast32(const std::string& func); - MEDCOUPLING_EXPORT void applyFuncFast64(const std::string& func); - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayDouble *Meld(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Meld(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayDouble *Dot(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Max(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void powEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT void updateTime() const { } - MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } - MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } - MEDCOUPLING_EXPORT std::vector toVectorOfBool(double eps) const; - public: - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector& tinyInfoI); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); - public: - template - void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const; - template - static void FindClosestTupleIdAlg(const BBTreePts& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res); - template - static void FindTupleIdsNearTuplesAlg(const BBTreePts& myTree, const double *pos, int nbOfTuples, double eps, - DataArrayInt *c, DataArrayInt *cI); - private: - ~DataArrayDouble() { } - DataArrayDouble() { } - private: - MemArray _mem; - }; - - class DataArrayDoubleTuple; - - class DataArrayDoubleIterator - { - public: - MEDCOUPLING_EXPORT DataArrayDoubleIterator(DataArrayDouble *da); - MEDCOUPLING_EXPORT ~DataArrayDoubleIterator(); - MEDCOUPLING_EXPORT DataArrayDoubleTuple *nextt(); - private: - DataArrayDouble *_da; - double *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayDoubleTuple - { - public: - MEDCOUPLING_EXPORT DataArrayDoubleTuple(double *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const double *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT double *getPointer() { return _pt; } - MEDCOUPLING_EXPORT double doubleValue() const; - MEDCOUPLING_EXPORT DataArrayDouble *buildDADouble(int nbOfTuples, int nbOfCompo) const; - private: - double *_pt; - int _nb_of_compo; - }; - - class DataArrayIntIterator; - - class DataArrayInt : public DataArray - { - public: - MEDCOUPLING_EXPORT static DataArrayInt *New(); - MEDCOUPLING_EXPORT bool isAllocated() const; - MEDCOUPLING_EXPORT void checkAllocated() const; - MEDCOUPLING_EXPORT void desallocate(); - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } - MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int intValue() const; - MEDCOUPLING_EXPORT int getHashCode() const; - MEDCOUPLING_EXPORT bool empty() const; - MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void cpyFrom(const DataArrayInt& other); - MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); - MEDCOUPLING_EXPORT void pushBackSilent(int val); - MEDCOUPLING_EXPORT void pushBackValsSilent(const int *valsBg, const int *valsEnd); - MEDCOUPLING_EXPORT int popBackSilent(); - MEDCOUPLING_EXPORT void pack() const; - MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT bool isFittingWith(const std::vector& v) const; - MEDCOUPLING_EXPORT void switchOnTupleEqualTo(int val, std::vector& vec) const; - MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT DataArrayInt *sumPerTuple() const; - MEDCOUPLING_EXPORT void sort(bool asc=true); - MEDCOUPLING_EXPORT void reverse(); - MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT void fillWithZero(); - MEDCOUPLING_EXPORT void fillWithValue(int val); - MEDCOUPLING_EXPORT void iota(int init=0); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; - MEDCOUPLING_EXPORT std::string reprNotTooLong() const; - MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const; - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd); - MEDCOUPLING_EXPORT void replaceOneValByInThis(int valToBeReplaced, int replacedBy); - MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const; - MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd, - DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const; - MEDCOUPLING_EXPORT bool isRange(int& strt, int& sttoopp, int& stteepp) const; - MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; - MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; - MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const; - MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); - MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; - MEDCOUPLING_EXPORT DataArrayInt *fromNoInterlace() const; - MEDCOUPLING_EXPORT DataArrayInt *toNoInterlace() const; - MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); - MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); - MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const; - MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const; - MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; - MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId2(int bg, int end, int step) const; - MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const; - MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const; - MEDCOUPLING_EXPORT static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2); - MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const; - MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples); - MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const; - MEDCOUPLING_EXPORT bool isIdentity() const; - MEDCOUPLING_EXPORT bool isIdentity2(int sizeExpected) const; - MEDCOUPLING_EXPORT bool isUniform(int val) const; - MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const; - MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); - MEDCOUPLING_EXPORT void transpose(); - MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const; - MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void meldWith(const DataArrayInt *other); - MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds); - MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); - MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } - MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } - MEDCOUPLING_EXPORT int getIJSafe(int tupleId, int compoId) const; - MEDCOUPLING_EXPORT int front() const; - MEDCOUPLING_EXPORT int back() const; - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } - MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); declareAsNew(); } - MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet); - MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); } - MEDCOUPLING_EXPORT DataArrayIntIterator *iterator(); - MEDCOUPLING_EXPORT const int *begin() const { return getConstPointer(); } - MEDCOUPLING_EXPORT const int *end() const { return getConstPointer()+getNbOfElems(); } - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(int val) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(int val) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualList(const int *valsBg, const int *valsEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqualList(const int *valsBg, const int *valsEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const; - MEDCOUPLING_EXPORT int changeValue(int oldValue, int newValue); - MEDCOUPLING_EXPORT int locateTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT int locateValue(int value) const; - MEDCOUPLING_EXPORT int locateValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT int search(const std::vector& vals) const; - MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT bool presenceOfValue(int value) const; - MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT int count(int value) const; - MEDCOUPLING_EXPORT void accumulate(int *res) const; - MEDCOUPLING_EXPORT int accumulate(int compId) const; - MEDCOUPLING_EXPORT DataArrayInt *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const; - MEDCOUPLING_EXPORT int getMaxValue(int& tupleId) const; - MEDCOUPLING_EXPORT int getMaxValueInArray() const; - MEDCOUPLING_EXPORT int getMinValue(int& tupleId) const; - MEDCOUPLING_EXPORT int getMinValueInArray() const; - MEDCOUPLING_EXPORT void getMinMaxValues(int& minValue, int& maxValue) const; - MEDCOUPLING_EXPORT void abs(); - MEDCOUPLING_EXPORT DataArrayInt *computeAbs() const; - MEDCOUPLING_EXPORT void applyLin(int a, int b, int compoId); - MEDCOUPLING_EXPORT void applyLin(int a, int b); - MEDCOUPLING_EXPORT void applyInv(int numerator); - MEDCOUPLING_EXPORT DataArrayInt *negate() const; - MEDCOUPLING_EXPORT void applyDivideBy(int val); - MEDCOUPLING_EXPORT void applyModulus(int val); - MEDCOUPLING_EXPORT void applyRModulus(int val); - MEDCOUPLING_EXPORT void applyPow(int val); - MEDCOUPLING_EXPORT void applyRPow(int val); - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(int vmin, int vmax) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(int vmin, int vmax) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsStrictlyNegative() const; - MEDCOUPLING_EXPORT bool checkAllIdsInRange(int vmin, int vmax) const; - MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); - MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *AggregateIndexes(const std::vector& arrs); - MEDCOUPLING_EXPORT static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT static DataArrayInt *Meld(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); - MEDCOUPLING_EXPORT static DataArrayInt *BuildUnion(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOn(const std::vector& v); - MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOff(const std::vector& v); - MEDCOUPLING_EXPORT static void PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex); - MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const; - MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const; - MEDCOUPLING_EXPORT DataArrayInt *buildUniqueNotSorted() const; - MEDCOUPLING_EXPORT DataArrayInt *deltaShiftIndex() const; - MEDCOUPLING_EXPORT void computeOffsets(); - MEDCOUPLING_EXPORT void computeOffsets2(); - MEDCOUPLING_EXPORT void searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const; - MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const; - MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrOfSliceOnScaledArr(int begin, int stop, int step) const; - MEDCOUPLING_EXPORT DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const; - MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const; - MEDCOUPLING_EXPORT void sortEachPairToMakeALinkedList(); - MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const; - MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const; - MEDCOUPLING_EXPORT std::vector partitionByDifferentValues(std::vector& differentIds) const; - MEDCOUPLING_EXPORT std::vector< std::pair > splitInBalancedSlices(int nbOfSlices) const; - MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - MEDCOUPLING_EXPORT void writeOnPlace(std::size_t id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } - MEDCOUPLING_EXPORT static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void substractEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void powEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT void updateTime() const { } - MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } - MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } - public: - MEDCOUPLING_EXPORT static int *CheckAndPreparePermutation(const int *start, const int *end); - MEDCOUPLING_EXPORT static DataArrayInt *Range(int begin, int end, int step); - public: - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector& tinyInfoI); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); - private: - ~DataArrayInt() { } - DataArrayInt() { } - private: - MemArray _mem; - }; - - class DataArrayIntTuple; - - class DataArrayIntIterator - { - public: - MEDCOUPLING_EXPORT DataArrayIntIterator(DataArrayInt *da); - MEDCOUPLING_EXPORT ~DataArrayIntIterator(); - MEDCOUPLING_EXPORT DataArrayIntTuple *nextt(); - private: - DataArrayInt *_da; - int *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayIntTuple - { - public: - MEDCOUPLING_EXPORT DataArrayIntTuple(int *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const int *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT int *getPointer() { return _pt; } - MEDCOUPLING_EXPORT int intValue() const; - MEDCOUPLING_EXPORT DataArrayInt *buildDAInt(int nbOfTuples, int nbOfCompo) const; - private: - int *_pt; - int _nb_of_compo; - }; - - class DataArrayChar : public DataArray - { - public: - MEDCOUPLING_EXPORT virtual DataArrayChar *buildEmptySpecializedDAChar() const = 0; - MEDCOUPLING_EXPORT bool isAllocated() const; - MEDCOUPLING_EXPORT void checkAllocated() const; - MEDCOUPLING_EXPORT void desallocate(); - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } - MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int getHashCode() const; - MEDCOUPLING_EXPORT bool empty() const; - MEDCOUPLING_EXPORT void cpyFrom(const DataArrayChar& other); - MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); - MEDCOUPLING_EXPORT void pushBackSilent(char val); - MEDCOUPLING_EXPORT void pushBackValsSilent(const char *valsBg, const char *valsEnd); - MEDCOUPLING_EXPORT char popBackSilent(); - MEDCOUPLING_EXPORT void pack() const; - MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT bool isEqual(const DataArrayChar& other) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayChar& other) const; - MEDCOUPLING_EXPORT void reverse(); - MEDCOUPLING_EXPORT void fillWithZero(); - MEDCOUPLING_EXPORT void fillWithValue(char val); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; - MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); - MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; - MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); - MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); - MEDCOUPLING_EXPORT DataArrayChar *renumber(const int *old2New) const; - MEDCOUPLING_EXPORT DataArrayChar *renumberR(const int *new2Old) const; - MEDCOUPLING_EXPORT DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; - MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayChar *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId2(int bg, int end, int step) const; - MEDCOUPLING_EXPORT bool isUniform(char val) const; - MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); - MEDCOUPLING_EXPORT DataArrayChar *substr(int tupleIdBg, int tupleIdEnd=-1) const; - MEDCOUPLING_EXPORT DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const; - MEDCOUPLING_EXPORT DataArrayChar *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void meldWith(const DataArrayChar *other); - MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); - MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const; - MEDCOUPLING_EXPORT void getTuple(int tupleId, char *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } - MEDCOUPLING_EXPORT char getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } - MEDCOUPLING_EXPORT char getIJSafe(int tupleId, int compoId) const; - MEDCOUPLING_EXPORT char front() const; - MEDCOUPLING_EXPORT char back() const; - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } - MEDCOUPLING_EXPORT char *getPointer() { return _mem.getPointer(); declareAsNew(); } - MEDCOUPLING_EXPORT const char *getConstPointer() const { return _mem.getConstPointer(); } - MEDCOUPLING_EXPORT const char *begin() const { return getConstPointer(); } - MEDCOUPLING_EXPORT const char *end() const { return getConstPointer()+getNbOfElems(); } - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(char val) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(char val) const; - MEDCOUPLING_EXPORT int search(const std::vector& vals) const; - MEDCOUPLING_EXPORT int locateTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT int locateValue(char value) const; - MEDCOUPLING_EXPORT int locateValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT bool presenceOfValue(char value) const; - MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT char getMaxValue(int& tupleId) const; - MEDCOUPLING_EXPORT char getMaxValueInArray() const; - MEDCOUPLING_EXPORT char getMinValue(int& tupleId) const; - MEDCOUPLING_EXPORT char getMinValueInArray() const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(char vmin, char vmax) const; - MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2); - MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2); - MEDCOUPLING_EXPORT static DataArrayChar *Meld(const std::vector& arr); - MEDCOUPLING_EXPORT void useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void updateTime() const { } - MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } - MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } - public: - //MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - //MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - //MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector& tinyInfoI); - //MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); - protected: - DataArrayChar() { } - protected: - MemArray _mem; - }; - - class DataArrayByteIterator; - - class DataArrayByte : public DataArrayChar - { - public: - MEDCOUPLING_EXPORT static DataArrayByte *New(); - MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const; - MEDCOUPLING_EXPORT DataArrayByteIterator *iterator(); - MEDCOUPLING_EXPORT DataArrayByte *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayByte *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT char byteValue() const; - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; - MEDCOUPLING_EXPORT std::vector toVectorOfBool() const; - private: - ~DataArrayByte() { } - DataArrayByte() { } - }; - - class DataArrayByteTuple; - - class DataArrayByteIterator - { - public: - MEDCOUPLING_EXPORT DataArrayByteIterator(DataArrayByte *da); - MEDCOUPLING_EXPORT ~DataArrayByteIterator(); - MEDCOUPLING_EXPORT DataArrayByteTuple *nextt(); - private: - DataArrayByte *_da; - char *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayByteTuple - { - public: - MEDCOUPLING_EXPORT DataArrayByteTuple(char *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const char *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT char *getPointer() { return _pt; } - MEDCOUPLING_EXPORT char byteValue() const; - MEDCOUPLING_EXPORT DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const; - private: - char *_pt; - int _nb_of_compo; - }; - - class DataArrayAsciiCharIterator; - - class DataArrayAsciiChar : public DataArrayChar - { - public: - MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(); - MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(const std::string& st); - MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(const std::vector& vst, char defaultChar); - MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const; - MEDCOUPLING_EXPORT DataArrayAsciiCharIterator *iterator(); - MEDCOUPLING_EXPORT DataArrayAsciiChar *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayAsciiChar *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT char asciiCharValue() const; - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; - private: - ~DataArrayAsciiChar() { } - DataArrayAsciiChar() { } - DataArrayAsciiChar(const std::string& st); - DataArrayAsciiChar(const std::vector& vst, char defaultChar); - }; - - class DataArrayAsciiCharTuple; - - class DataArrayAsciiCharIterator - { - public: - MEDCOUPLING_EXPORT DataArrayAsciiCharIterator(DataArrayAsciiChar *da); - MEDCOUPLING_EXPORT ~DataArrayAsciiCharIterator(); - MEDCOUPLING_EXPORT DataArrayAsciiCharTuple *nextt(); - private: - DataArrayAsciiChar *_da; - char *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayAsciiCharTuple - { - public: - MEDCOUPLING_EXPORT DataArrayAsciiCharTuple(char *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const char *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT char *getPointer() { return _pt; } - MEDCOUPLING_EXPORT char asciiCharValue() const; - MEDCOUPLING_EXPORT DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const; - private: - char *_pt; - int _nb_of_compo; - }; - - template - void DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last) - { - int nbCompo(getNumberOfComponents()); - if(nbCompo==1) - _mem.insertAtTheEnd(first,last); - else if(nbCompo==0) - { - _info_on_compo.resize(1); - _mem.insertAtTheEnd(first,last); - } - else - throw INTERP_KERNEL::Exception("DataArrayDouble::insertAtTheEnd : not available for DataArrayDouble with number of components different than 1 !"); - } - - template - void DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last) - { - int nbCompo(getNumberOfComponents()); - if(nbCompo==1) - _mem.insertAtTheEnd(first,last); - else if(nbCompo==0) - { - _info_on_compo.resize(1); - _mem.insertAtTheEnd(first,last); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::insertAtTheEnd : not available for DataArrayInt with number of components different than 1 !"); - } - - template - void DataArrayChar::insertAtTheEnd(InputIterator first, InputIterator last) - { - int nbCompo(getNumberOfComponents()); - if(nbCompo==1) - _mem.insertAtTheEnd(first,last); - else if(nbCompo==0) - { - _info_on_compo.resize(1); - _mem.insertAtTheEnd(first,last); - } - else - throw INTERP_KERNEL::Exception("DataArrayChar::insertAtTheEnd : not available for DataArrayChar with number of components different than 1 !"); - } -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingMemArray.txx b/medtool/src/MEDCoupling/MEDCouplingMemArray.txx deleted file mode 100644 index 693e6e4f0..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMemArray.txx +++ /dev/null @@ -1,495 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ -#define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ - -#include "MEDCouplingMemArray.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" -#include "InterpolationUtils.hxx" - -#include -#include -#include - -namespace ParaMEDMEM -{ - template - void MEDCouplingPointer::setInternal(T *pointer) - { - _internal=pointer; - _external=0; - } - - template - void MEDCouplingPointer::setExternal(const T *pointer) - { - _external=pointer; - _internal=0; - } - - template - MemArray::MemArray(const MemArray& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0) - { - if(!other._pointer.isNull()) - { - _nb_of_elem_alloc=other._nb_of_elem; - T *pointer=(T*)malloc(_nb_of_elem_alloc*sizeof(T)); - std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer); - useArray(pointer,true,C_DEALLOC,other._nb_of_elem); - } - } - - template - void MemArray::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem) - { - destroy(); - _nb_of_elem=nbOfElem; - _nb_of_elem_alloc=nbOfElem; - if(ownership) - _pointer.setInternal(const_cast(array)); - else - _pointer.setExternal(array); - _ownership=ownership; - _dealloc=BuildFromType(type); - } - - template - void MemArray::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem) - { - destroy(); - _nb_of_elem=nbOfElem; - _nb_of_elem_alloc=nbOfElem; - _pointer.setInternal(const_cast(array)); - _ownership=false; - _dealloc=CPPDeallocator; - } - - template - void MemArray::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers) - { - if(id+sizeOfOthers>=_nb_of_elem_alloc) - reserve(2*_nb_of_elem+sizeOfOthers+1); - T *pointer=_pointer.getPointer(); - pointer[id]=element0; - std::copy(others,others+sizeOfOthers,pointer+id+1); - _nb_of_elem=std::max(_nb_of_elem,id+sizeOfOthers+1); - } - - template - template - void MemArray::insertAtTheEnd(InputIterator first, InputIterator last) - { - T *pointer=_pointer.getPointer(); - while(first!=last) - { - if(_nb_of_elem>=_nb_of_elem_alloc) - { - reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); - pointer=_pointer.getPointer(); - } - pointer[_nb_of_elem++]=*first++; - } - } - - template - void MemArray::pushBack(T elem) - { - if(_nb_of_elem>=_nb_of_elem_alloc) - reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); - T *pt=getPointer(); - pt[_nb_of_elem++]=elem; - } - - template - T MemArray::popBack() - { - if(_nb_of_elem>0) - { - const T *pt=getConstPointer(); - return pt[--_nb_of_elem]; - } - throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !"); - } - - template - void MemArray::pack() const - { - (const_cast * >(this))->reserve(_nb_of_elem); - } - - template - bool MemArray::isEqual(const MemArray& other, T prec, std::string& reason) const - { - std::ostringstream oss; oss.precision(15); - if(_nb_of_elem!=other._nb_of_elem) - { - oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem; - reason=oss.str(); - return false; - } - const T *pt1=_pointer.getConstPointer(); - const T *pt2=other._pointer.getConstPointer(); - if(pt1==0 && pt2==0) - return true; - if(pt1==0 || pt2==0) - { - oss << "coarse data pointer is defined for only one DataArray instance !"; - reason=oss.str(); - return false; - } - if(pt1==pt2) - return true; - for(std::size_t i=0;i<_nb_of_elem;i++) - if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec) - { - oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i]; - reason=oss.str(); - return false; - } - return true; - } - - /*! - * \param [in] sl is typically the number of components - * \return True if a not null pointer is present, False if not. - */ - template - bool MemArray::reprHeader(int sl, std::ostream& stream) const - { - stream << "Number of tuples : "; - if(!_pointer.isNull()) - { - if(sl!=0) - stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc; - else - stream << "Empty Data"; - } - else - stream << "No data"; - stream << "\n"; - stream << "Data content :\n"; - bool ret=!_pointer.isNull(); - if(!ret) - stream << "No data !\n"; - return ret; - } - - /*! - * \param [in] sl is typically the number of components - */ - template - void MemArray::repr(int sl, std::ostream& stream) const - { - if(reprHeader(sl,stream)) - { - const T *data=getConstPointer(); - if(_nb_of_elem!=0 && sl!=0) - { - std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); - for(std::size_t i=0;i(stream," ")); - stream << "\n"; - data+=sl; - } - } - else - stream << "Empty Data\n"; - } - } - - /*! - * \param [in] sl is typically the number of components - */ - template - void MemArray::reprZip(int sl, std::ostream& stream) const - { - stream << "Number of tuples : "; - if(!_pointer.isNull()) - { - if(sl!=0) - stream << _nb_of_elem/sl; - else - stream << "Empty Data"; - } - else - stream << "No data"; - stream << "\n"; - stream << "Data content : "; - const T *data=getConstPointer(); - if(!_pointer.isNull()) - { - if(_nb_of_elem!=0 && sl!=0) - { - std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); - for(std::size_t i=0;i(stream," ")); - stream << "| "; - data+=sl; - } - stream << "\n"; - } - else - stream << "Empty Data\n"; - } - else - stream << "No data !\n"; - } - - /*! - * \param [in] sl is typically the number of components - */ - template - void MemArray::reprNotTooLong(int sl, std::ostream& stream) const - { - if(reprHeader(sl,stream)) - { - const T *data=getConstPointer(); - if(_nb_of_elem!=0 && sl!=0) - { - std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); - if(nbOfTuples<=1000) - { - for(std::size_t i=0;i(stream," ")); - stream << "\n"; - data+=sl; - } - } - else - {// too much tuples -> print the 3 first tuples and 3 last. - stream << "Tuple #0 : "; - std::copy(data,data+sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #1 : "; - std::copy(data+sl,data+2*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #2 : "; - std::copy(data+2*sl,data+3*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "...\n"; - stream << "Tuple #" << nbOfTuples-3 << " : "; - std::copy(data+(nbOfTuples-3)*sl,data+(nbOfTuples-2)*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #" << nbOfTuples-2 << " : "; - std::copy(data+(nbOfTuples-2)*sl,data+(nbOfTuples-1)*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #" << nbOfTuples-1 << " : "; - std::copy(data+(nbOfTuples-1)*sl,data+nbOfTuples*sl,std::ostream_iterator(stream," ")); stream << "\n"; - } - } - else - stream << "Empty Data\n"; - } - } - - template - void MemArray::fillWithValue(const T& val) - { - T *pt=_pointer.getPointer(); - std::fill(pt,pt+_nb_of_elem,val); - } - - template - T *MemArray::fromNoInterlace(int nbOfComp) const - { - if(nbOfComp<1) - throw INTERP_KERNEL::Exception("MemArray::fromNoInterlace : number of components must be > 0 !"); - const T *pt=_pointer.getConstPointer(); - std::size_t nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); - T *w=ret; - for(std::size_t i=0;i - T *MemArray::toNoInterlace(int nbOfComp) const - { - if(nbOfComp<1) - throw INTERP_KERNEL::Exception("MemArray::toNoInterlace : number of components must be > 0 !"); - const T *pt=_pointer.getConstPointer(); - std::size_t nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); - T *w=ret; - for(int i=0;i - void MemArray::sort(bool asc) - { - T *pt=_pointer.getPointer(); - if(asc) - std::sort(pt,pt+_nb_of_elem); - else - { - typename std::reverse_iterator it1(pt+_nb_of_elem); - typename std::reverse_iterator it2(pt); - std::sort(it1,it2); - } - } - - template - void MemArray::reverse(int nbOfComp) - { - if(nbOfComp<1) - throw INTERP_KERNEL::Exception("MemArray::reverse : only supported with 'this' array with ONE or more than ONE component !"); - T *pt=_pointer.getPointer(); - if(nbOfComp==1) - { - std::reverse(pt,pt+_nb_of_elem); - return ; - } - else - { - T *pt2=pt+_nb_of_elem-nbOfComp; - std::size_t nbOfTuples=_nb_of_elem/nbOfComp; - for(std::size_t i=0;i - void MemArray::alloc(std::size_t nbOfElements) - { - destroy(); - _nb_of_elem=nbOfElements; - _nb_of_elem_alloc=nbOfElements; - _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T))); - _ownership=true; - _dealloc=CDeallocator; - } - - /*! - * This method performs systematically an allocation of \a newNbOfElements elements in \a this. - * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray::reAlloc method. - * So after the call of this method \a _nb_of_elem will be equal tostd::min(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to - * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation. - * So after the call of this method the accessible content is perfectly set. - * - * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. - */ - template - void MemArray::reserve(std::size_t newNbOfElements) - { - if(_nb_of_elem_alloc==newNbOfElements) - return ; - T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); - std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); - if(_ownership) - DestroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external - _pointer.setInternal(pointer); - _nb_of_elem=std::min(_nb_of_elem,newNbOfElements); - _nb_of_elem_alloc=newNbOfElements; - _ownership=true; - _dealloc=CDeallocator; - _param_for_deallocator=0; - } - - /*! - * This method performs systematically an allocation of \a newNbOfElements elements in \a this. - * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min(_nb_of_elem,newNbOfElements) come from the . - * The remaing part of the new allocated chunk are available but not set previouly ! - * - * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. - */ - template - void MemArray::reAlloc(std::size_t newNbOfElements) - { - if(_nb_of_elem==newNbOfElements) - return ; - T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); - std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); - if(_ownership) - DestroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external - _pointer.setInternal(pointer); - _nb_of_elem=newNbOfElements; - _nb_of_elem_alloc=newNbOfElements; - _ownership=true; - _dealloc=CDeallocator; - _param_for_deallocator=0; - } - - template - void MemArray::CPPDeallocator(void *pt, void *param) - { - delete [] reinterpret_cast(pt); - } - - template - void MemArray::CDeallocator(void *pt, void *param) - { - free(pt); - } - - template - typename MemArray::Deallocator MemArray::BuildFromType(DeallocType type) - { - switch(type) - { - case CPP_DEALLOC: - return CPPDeallocator; - case C_DEALLOC: - return CDeallocator; - default: - throw INTERP_KERNEL::Exception("Invalid deallocation requested ! Unrecognized enum DeallocType !"); - } - } - - template - void MemArray::DestroyPointer(T *pt, typename MemArray::Deallocator dealloc, void *param) - { - if(dealloc) - dealloc(pt,param); - } - - template - void MemArray::destroy() - { - if(_ownership) - DestroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external - _pointer.null(); - _ownership=false; - _dealloc=NULL; - _param_for_deallocator=NULL; - _nb_of_elem=0; - _nb_of_elem_alloc=0; - } - - template - MemArray &MemArray::operator=(const MemArray& other) - { - alloc(other._nb_of_elem); - std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer()); - return *this; - } -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/medtool/src/MEDCoupling/MEDCouplingMemArrayChar.cxx deleted file mode 100644 index 59d29b2aa..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMemArrayChar.cxx +++ /dev/null @@ -1,2602 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingMemArray.txx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -/*! - * Checks if raw data is allocated. Read more on the raw data - * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. - * \return bool - \a true if the raw data is allocated, \a false else. - */ -bool DataArrayChar::isAllocated() const -{ - return getConstPointer()!=0; -} - -/*! - * Checks if raw data is allocated and throws an exception if it is not the case. - * \throw If the raw data is not allocated. - */ -void DataArrayChar::checkAllocated() const -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayChar::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); -} - -/*! - * This method desallocated \a this without modification of informations relative to the components. - * After call of this method, DataArrayChar::isAllocated will return false. - * If \a this is already not allocated, \a this is let unchanged. - */ -void DataArrayChar::desallocate() -{ - _mem.destroy(); -} - -std::size_t DataArrayChar::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - -/*! - * Returns an integer value characterizing \a this array, which is useful for a quick - * comparison of many instances of DataArrayInt. - * \return int - the hash value. - * \throw If \a this is not allocated. - */ -int DataArrayChar::getHashCode() const -{ - checkAllocated(); - std::size_t nbOfElems=getNbOfElems(); - int ret=nbOfElems*65536; - int delta=3; - if(nbOfElems>48) - delta=nbOfElems/8; - int ret0=0; - const char *pt=begin(); - for(std::size_t i=0;igetNumberOfComponents() < 1. - * \throw If \a this is not allocated. - */ -void DataArrayChar::reverse() -{ - checkAllocated(); - _mem.reverse(getNumberOfComponents()); - declareAsNew(); -} - -/*! - * Assign zero to all values in \a this array. To know more on filling arrays see - * \ref MEDCouplingArrayFill. - * \throw If \a this is not allocated. - */ -void DataArrayChar::fillWithZero() -{ - checkAllocated(); - _mem.fillWithValue(0); - declareAsNew(); -} - -/*! - * Assign \a val to all values in \a this array. To know more on filling arrays see - * \ref MEDCouplingArrayFill. - * \param [in] val - the value to fill with. - * \throw If \a this is not allocated. - */ -void DataArrayChar::fillWithValue(char val) -{ - checkAllocated(); - _mem.fillWithValue(val); - declareAsNew(); -} - -/*! - * Returns a textual and human readable representation of \a this instance of - * DataArrayChar. This text is shown when a DataArrayChar is printed in Python. - * \return std::string - text describing \a this DataArrayChar. - */ -std::string DataArrayChar::repr() const -{ - std::ostringstream ret; - reprStream(ret); - return ret.str(); -} - -std::string DataArrayChar::reprZip() const -{ - std::ostringstream ret; - reprZipStream(ret); - return ret.str(); -} - -/*! - * Changes number of tuples in the array. If the new number of tuples is smaller - * than the current number the array is truncated, otherwise the array is extended. - * \param [in] nbOfTuples - new number of tuples. - * \throw If \a this is not allocated. - * \throw If \a nbOfTuples is negative. - */ -void DataArrayChar::reAlloc(int nbOfTuples) -{ - if(nbOfTuples<0) - throw INTERP_KERNEL::Exception("DataArrayChar::reAlloc : input new number of tuples should be >=0 !"); - checkAllocated(); - _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); - declareAsNew(); -} - -/*! - * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this - * array to the new one. - * \return DataArrayInt * - the new instance of DataArrayChar. - */ -DataArrayInt *DataArrayChar::convertToIntArr() const -{ - checkAllocated(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - std::size_t nbOfVals=getNbOfElems(); - const char *src=getConstPointer(); - int *dest=ret->getPointer(); - std::copy(src,src+nbOfVals,dest); - ret->copyStringInfoFrom(*this); - return ret; -} - -/*! - * Permutes values of \a this array as required by \a old2New array. The values are - * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains - * the same as in \this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old value. - */ -void DataArrayChar::renumberInPlace(const int *old2New) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - char *tmp=new char[nbTuples*nbOfCompo]; - const char *iptr=getConstPointer(); - for(int i=0;igetNumberOfTuples() - * giving a previous position of i-th new value. - */ -void DataArrayChar::renumberInPlaceR(const int *new2Old) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - char *tmp=new char[nbTuples*nbOfCompo]; - const char *iptr=getConstPointer(); - for(int i=0;igetNumberOfTuples() - * giving a new position for i-th old value. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayChar *DataArrayChar::renumber(const int *old2New) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const char *iptr=getConstPointer(); - char *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a copy of \a this array with values permuted as required by \a new2Old array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of - * tuples in the result array remains the same as in \this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayChar *DataArrayChar::renumberR(const int *new2Old) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const char *iptr=getConstPointer(); - char *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is - * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. - * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all - * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which - * \a old2New[ i ] is negative, is missing from the result array. - * For more info on renumbering see \ref numbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old tuple and giving negative position for - * for i-th old tuple that should be omitted. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayChar *DataArrayChar::renumberAndReduce(const int *old2New, int newNbOfTuple) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(newNbOfTuple,nbOfCompo); - const char *iptr=getConstPointer(); - char *optr=ret->getPointer(); - for(int i=0;i=0) - std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * For more info on renumbering see \ref numbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayChar *DataArrayChar::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const -{ - return selectByTupleIdSafe(new2OldBg,new2OldEnd); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * This method is equivalent to selectByTupleId() except that it prevents coping data - * from behind the end of \a this array. - * For more info on renumbering see \ref numbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). - */ -DataArrayChar *DataArrayChar::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - char *pt=ret->getPointer(); - const char *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - if(*w>=0 && *wgetNumberOfTuples) !"); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayChar contains every - * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th - * tuple. Indices of the selected tuples are the same as ones returned by the Python - * command \c range( \a bg, \a end2, \a step ). - * This method is equivalent to selectByTupleIdSafe() except that the input array is - * not constructed explicitly. - * For more info on renumbering see \ref numbering. - * \param [in] bg - index of the first tuple to copy from \a this array. - * \param [in] end2 - index of the tuple before which the tuples to copy are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If (\a end2 < \a bg) or (\a step <= 0). - * \sa DataArrayChar::substr. - */ -DataArrayChar *DataArrayChar::selectByTupleId2(int bg, int end2, int step) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); - ret->alloc(newNbOfTuples,nbComp); - char *pt=ret->getPointer(); - const char *srcPt=getConstPointer()+bg*nbComp; - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Checks if all values in \a this array are equal to \a val. - * \param [in] val - value to check equality of array values to. - * \return bool - \a true if all values are \a val. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1 - */ -bool DataArrayChar::isUniform(char val) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::isUniform : must be applied on DataArrayChar with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - const char *w=getConstPointer(); - const char *end2=w+nbOfTuples; - for(;w!=end2;w++) - if(*w!=val) - return false; - return true; -} - -/*! - * Changes the number of components within \a this array so that its raw data **does - * not** change, instead splitting this data into tuples changes. - * \param [in] newNbOfComp - number of components for \a this array to have. - * \throw If \a this is not allocated - * \throw If getNbOfElems() % \a newNbOfCompo != 0. - * \throw If \a newNbOfCompo is lower than 1. - * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). - * \warning This method erases all (name and unit) component info set before! - */ -void DataArrayChar::rearrange(int newNbOfCompo) -{ - checkAllocated(); - if(newNbOfCompo<1) - throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : input newNbOfCompo must be > 0 !"); - std::size_t nbOfElems=getNbOfElems(); - if(nbOfElems%newNbOfCompo!=0) - throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : nbOfElems%newNbOfCompo!=0 !"); - if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); - _info_on_compo.clear(); - _info_on_compo.resize(newNbOfCompo); - declareAsNew(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayChar contains all - * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before - * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). - * This method is a specialization of selectByTupleId2(). - * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. - * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. - * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a tupleIdBg < 0. - * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). - \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). - * \sa DataArrayChar::selectByTupleId2 - */ -DataArrayChar *DataArrayChar::substr(int tupleIdBg, int tupleIdEnd) const -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(trueEnd-tupleIdBg,nbComp); - ret->copyStringInfoFrom(*this); - std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret.retn(); -} - -/*! - * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less - * than \a this->getNumberOfComponents() then the result array is shorten as each tuple - * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is - * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp - * components. - * \param [in] newNbOfComp - number of components for the new array to have. - * \param [in] dftValue - value assigned to new values added to the new array. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayChar *DataArrayChar::changeNbOfComponents(int newNbOfComp, char dftValue) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const char *oldc=getConstPointer(); - char *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - return ret.retn(); -} - -/*! - * Returns a copy of \a this array composed of selected components. - * The new DataArrayChar has the same number of tuples but includes components - * specified by \a compoIds parameter. So that getNbOfElems() of the result array - * can be either less, same or more than \a this->getNbOfElems(). - * \param [in] compoIds - sequence of zero based indices of components to include - * into the new array. - * \return DataArrayChar * - the new instance of DataArrayChar that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If a component index (\a i) is not valid: - * \a i < 0 || \a i >= \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". - * \endif - */ -DataArrayChar *DataArrayChar::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(buildEmptySpecializedDAChar()); - int newNbOfCompo=(int)compoIds.size(); - int oldNbOfCompo=getNumberOfComponents(); - for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) - DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component"); - int nbOfTuples=getNumberOfTuples(); - ret->alloc(nbOfTuples,newNbOfCompo); - ret->copyPartOfStringInfoFrom(*this,compoIds); - const char *oldc=getConstPointer(); - char *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - char *newArr=(char *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(char)); - char *w=newArr; - const char *inp1=getConstPointer(); - const char *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;igetNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues1 : DataArrayChar pointer in input is NULL !"); - const char msg[]="DataArrayChar::setPartOfValues1"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - char *pt=getPointer()+bgTuples*nbComp+bgComp; - const char *srcPt=a->getConstPointer(); - if(assignTech) - { - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign values of \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \param [in] strictCompoCompare - this parameter is checked only if the - * *mode of usage* is the first; if it is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() != (endComp - bgComp) . - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() != (endComp - bgComp). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues2 : DataArrayChar pointer in input is NULL !"); - const char msg[]="DataArrayChar::setPartOfValues2"; - checkAllocated(); - a->checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - int newNbOfComp=(int)std::distance(bgComp,endComp); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - char *pt=getPointer(); - const char *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; - } - } - } - else - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - const char *srcPt2=srcPt; - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt2++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; - } - } - } -} - -/*! - * Assign a given value to values at specified tuples and components of \a this array. - * The tuples and components to assign to are defined by C arrays of indices. - * \param [in] a - the value to assign. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (\a pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (\a pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - char *pt=getPointer(); - for(const int *w=bgTuples;w!=endTuples;w++) - for(const int *z=bgComp;z!=endComp;z++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(std::size_t)(*w)*nbComp+(*z)]=a; - } -} - -/*! - * Copy all values from another DataArrayChar (\a a) into specified tuples and - * components of \a this array. Textual data is not copied. - * The tuples to assign to are defined by a C array of indices. - * The components to assign to are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * There are two *modes of usage*: - * - If \a a->getNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \param [in] strictCompoCompare - this parameter is checked only in the first - * *mode of usage*; if \a strictCompoCompare is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues3 : DataArrayChar pointer in input is NULL !"); - const char msg[]="DataArrayChar::setPartOfValues3"; - checkAllocated(); - a->checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - char *pt=getPointer()+bgComp; - const char *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;j(pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayChar::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - char *pt=getPointer()+bgComp; - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;jcheckAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=(int)std::distance(bgComp,endComp); - int nbComp=getNumberOfComponents(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const char *srcPt=a->getConstPointer(); - char *pt=getPointer()+bgTuples*nbComp; - if(assignTech) - { - for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 2. - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * the corresponding (\a this or \a a) array. - */ -void DataArrayChar::setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : DataArrayChar pointer in input is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayChar instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - char *valsToSet=getPointer(); - const char *valsSrc=a->getConstPointer(); - for(const char *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) - { - if(tuple[1]>=0 && tuple[1]=0 && tuple[0]begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Copy some tuples from another DataArrayChar (\a aBase) into contiguous tuples - * of \a this array. Textual data is not copied. Both arrays must have equal number of - * components. - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by \a tuplesSelec->getNumberOfTuples(). - * The tuples to copy are defined by values of a DataArrayChar. - * All components of selected tuples are copied. - * \param [in] tupleIdStart - index of the first tuple of \a this array to assign - * values to. - * \param [in] aBase - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If \a tuplesSelec is NULL. - * \throw If \a tuplesSelec is not allocated. - * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 1. - * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * \a aBase array. - */ -void DataArrayChar::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - if(!aBase || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray is NULL !"); - const DataArrayChar *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayChar !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayChar instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - char *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : invalid number range of values to write !"); - const char *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) - { - if(*tuple>=0 && *tuplebegin(),tuple); - oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Copy some tuples from another DataArrayChar (\a aBase) into contiguous tuples - * of \a this array. Textual data is not copied. Both arrays must have equal number of - * components. - * The tuples to copy are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by number of tuples to copy. - * All components of selected tuples are copied. - * \param [in] tupleIdStart - index of the first tuple of \a this array to assign - * values to. - * \param [in] aBase - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a aBase. - * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy - * are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). - * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). - * \throw If parameters specifying tuples to copy, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for the array \a aBase. - */ -void DataArrayChar::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - if(!aBase) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray is NULL !"); - const DataArrayChar *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayChar !"); - checkAllocated(); - a->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - const char msg[]="DataArrayChar::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - char *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const char *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i \a this->getNumberOfTuples(). - * \throw If \a this is not allocated. - */ -DataArray *DataArrayChar::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(0,nbOfComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); - } - int ref=ranges.front().first; - int nbOfTuples=0; - bool isIncreasing=true; - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - { - if((*it).first<=(*it).second) - { - if((*it).first>=0 && (*it).second<=nbOfTuplesThis) - { - nbOfTuples+=(*it).second-(*it).first; - if(isIncreasing) - isIncreasing=ref<=(*it).first; - ref=(*it).second; - } - else - { - std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(isIncreasing && nbOfTuplesThis==nbOfTuples) - return deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const char *src=getConstPointer(); - char *work=ret->getPointer(); - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - return ret.retn(); -} - -/*! - * Returns a value located at specified tuple and component. - * This method is equivalent to DataArrayChar::getIJ() except that validity of - * parameters is checked. So this method is safe but expensive if used to go through - * all values of \a this. - * \param [in] tupleId - index of tuple of interest. - * \param [in] compoId - index of component of interest. - * \return char - value located by \a tupleId and \a compoId. - * \throw If \a this is not allocated. - * \throw If condition ( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. - */ -char DataArrayChar::getIJSafe(int tupleId, int compoId) const -{ - checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(compoId<0 || compoId>=getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _mem[tupleId*_info_on_compo.size()+compoId]; -} - -/*! - * Returns the first value of \a this. - * \return char - the last value of \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -char DataArrayChar::front() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::front : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayChar::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); -} - -/*! - * Returns the last value of \a this. - * \return char - the last value of \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -char DataArrayChar::back() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayChar::back : number of tuples must be >= 1 !"); - return *(getConstPointer()+nbOfTuples-1); -} - -/*! - * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a - * given one. - * \param [in] val - the value to find within \a this. - * \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayChar::getIdsEqual(char val) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); - const char *cptr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * Creates a new DataArrayChar containing IDs (indices) of tuples holding value \b not - * equal to a given one. - * \param [in] val - the value to ignore within \a this. - * \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - */ -DataArrayInt *DataArrayChar::getIdsNotEqual(char val) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); - const char *cptr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * This method searches the sequence specified in input parameter \b vals in \b this. - * This works only for DataArrayChar having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown). - * This method differs from DataArrayChar::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayChar::locateTuple. - * \sa DataArrayChar::locateTuple - */ -int DataArrayChar::search(const std::vector& vals) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if(nbOfCompo!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::search : works only for DataArrayChar instance with one component !"); - const char *cptr=getConstPointer(); - std::size_t nbOfVals=getNbOfElems(); - const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end()); - if(loc!=cptr+nbOfVals) - return std::distance(cptr,loc); - return -1; -} - -/*! - * This method is an extension of DataArrayChar::locateValue method because this method works for DataArrayChar with - * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case). - * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. - * If any the tuple id is returned. If not -1 is returned. - * - * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of - * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. - * - * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this. - * \sa DataArrayChar::search. - */ -int DataArrayChar::locateTuple(const std::vector& tupl) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if(nbOfCompo==0) - throw INTERP_KERNEL::Exception("DataArrayChar::locateTuple : 0 components in 'this' !"); - if(nbOfCompo!=(int)tupl.size()) - { - std::ostringstream oss; oss << "DataArrayChar::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const char *cptr=getConstPointer(); - std::size_t nbOfVals=getNbOfElems(); - for(const char *work=cptr;work!=cptr+nbOfVals;) - { - work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end()); - if(work!=cptr+nbOfVals) - { - if(std::distance(cptr,work)%nbOfCompo!=0) - work++; - else - return std::distance(cptr,work)/nbOfCompo; - } - } - return -1; -} - -/*! - * This method is an extension of DataArrayChar::presenceOfValue method because this method works for DataArrayChar with - * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case). - * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. - * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of - * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. - * \sa DataArrayChar::locateTuple - */ -bool DataArrayChar::presenceOfTuple(const std::vector& tupl) const -{ - return locateTuple(tupl)!=-1; -} - -/*! - * Returns \a true if a given value is present within \a this one-dimensional array. - * \param [in] value - the value to find within \a this array. - * \return bool - \a true in case if \a value is present within \a this array. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa locateValue() - */ -bool DataArrayChar::presenceOfValue(char value) const -{ - return locateValue(value)!=-1; -} - -/*! - * This method expects to be called when number of components of this is equal to one. - * This method returns true if it exists a tuple so that the value is contained in \b vals. - * If not any tuple contains one of the values contained in 'vals' false is returned. - * \sa DataArrayChar::locateValue - */ -bool DataArrayChar::presenceOfValue(const std::vector& vals) const -{ - return locateValue(vals)!=-1; -} - -/*! - * This method expects to be called when number of components of this is equal to one. - * This method returns the tuple id, if it exists, of the first tuple equal to \b value. - * If not any tuple contains \b value -1 is returned. - * \sa DataArrayChar::presenceOfValue - */ -int DataArrayChar::locateValue(char value) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); - const char *cptr=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - const char *ret=std::find(cptr,cptr+nbOfTuples,value); - if(ret!=cptr+nbOfTuples) - return std::distance(cptr,ret); - return -1; -} - -/*! - * This method expects to be called when number of components of this is equal to one. - * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals. - * If not any tuple contains one of the values contained in 'vals' false is returned. - * \sa DataArrayChar::presenceOfValue - */ -int DataArrayChar::locateValue(const std::vector& vals) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); - std::set vals2(vals.begin(),vals.end()); - const char *cptr=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(const char *w=cptr;w!=cptr+nbOfTuples;w++) - if(vals2.find(*w)!=vals2.end()) - return std::distance(cptr,w); - return -1; -} - -/*! - * Returns the maximal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the maximal value. - * \return char - the maximal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -char DataArrayChar::getMaxValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !"); - const char *vals=getConstPointer(); - const char *loc=std::max_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the maximal value within \a this array that is allowed to have more than - * one component. - * \return char - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -char DataArrayChar::getMaxValueInArray() const -{ - checkAllocated(); - const char *loc=std::max_element(begin(),end()); - return *loc; -} - -/*! - * Returns the minimal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the minimal value. - * \return char - the minimal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -char DataArrayChar::getMinValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !"); - const char *vals=getConstPointer(); - const char *loc=std::min_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the minimal value within \a this array that is allowed to have more than - * one component. - * \return char - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -char DataArrayChar::getMinValueInArray() const -{ - checkAllocated(); - const char *loc=std::min_element(begin(),end()); - return *loc; -} - -/*! - * This method works only on data array with one component. - * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that - * this[*id] in [\b vmin,\b vmax) - * - * \param [in] vmin begin of range. This value is included in range. - * \param [in] vmax end of range. This value is \b not included in range. - * \return a newly allocated data array that the caller should deal with. - */ -DataArrayInt *DataArrayChar::getIdsInRange(char vmin, char vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::getIdsInRange : this must have exactly one component !"); - const char *cptr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;i=vmin && *cptrpushBackSilent(i); - return ret.retn(); -} - -/*! - * Returns a new DataArrayChar by concatenating two given arrays, so that (1) the number - * of tuples in the result array is a1->getNumberOfTuples() + a2->getNumberOfTuples() - - * offsetA2 and (2) - * the number of component in the result array is same as that of each of given arrays. - * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \param [in] offsetA2 - number of tuples of \a a2 to skip. - * \return DataArrayChar * - the new instance of DataArrayChar. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). - */ -DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input DataArrayChar instance is NULL !"); - std::vector v(2); v[0]=a1; v[1]=a2; - return Aggregate(v); -} - -/*! - * Returns a new DataArrayChar by concatenating all given arrays, so that (1) the number - * of tuples in the result array is a sum of the number of tuples of given arrays and (2) - * the number of component in the result array is same as that of each of given arrays. - * Info on components is copied from the first of the given arrays. Number of components - * in the given arrays must be the same. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayChar * - the new instance of DataArrayChar. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If getNumberOfComponents() of arrays within \a arr. - */ -DataArrayChar *DataArrayChar::Aggregate(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input list must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - int nbOfComp=(*it)->getNumberOfComponents(); - int nbt=(*it++)->getNumberOfTuples(); - for(int i=1;it!=a.end();it++,i++) - { - if((*it)->getNumberOfComponents()!=nbOfComp) - throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !"); - nbt+=(*it)->getNumberOfTuples(); - } - MEDCouplingAutoRefCountObjectPtr ret=a[0]->buildEmptySpecializedDAChar(); - ret->alloc(nbt,nbOfComp); - char *pt=ret->getPointer(); - for(it=a.begin();it!=a.end();it++) - pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); - ret->copyStringInfoFrom(*(a[0])); - return ret.retn(); -} - -/*! - * Returns a new DataArrayChar by aggregating two given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \return DataArrayChar * - the new instance of DataArrayChar. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If both \a a1 and \a a2 are NULL. - * \throw If any given array is not allocated. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - */ -DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=a2; - return Meld(arr); -} - -/*! - * Returns a new DataArrayChar by aggregating all given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayChar * - the new instance of DataArrayChar. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If any given array is not allocated. - * \throw If getNumberOfTuples() of arrays within \a arr is different. - */ -DataArrayChar *DataArrayChar::Meld(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayChar::Meld : array must be NON empty !"); - std::vector::const_iterator it; - for(it=a.begin();it!=a.end();it++) - (*it)->checkAllocated(); - it=a.begin(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::vector nbc(a.size()); - std::vector pts(a.size()); - nbc[0]=(*it)->getNumberOfComponents(); - pts[0]=(*it++)->getConstPointer(); - for(int i=1;it!=a.end();it++,i++) - { - if(nbOfTuples!=(*it)->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayChar::meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayChar *ret=a[0]->buildEmptySpecializedDAChar(); - ret->alloc(nbOfTuples,totalNbOfComp); - char *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - -/*! - * Sets a C array to be used as raw data of \a this. The previously set info - * of components is retained and re-sized. - * For more info see \ref MEDCouplingArraySteps1. - * \param [in] array - the C array to be used as raw data of \a this. - * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. - * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, - * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, - * \c free(\c array ) will be called. - * \param [in] nbOfTuple - new number of tuples in \a this. - * \param [in] nbOfCompo - new number of components in \a this. - */ -void DataArrayChar::useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayChar::useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); -} - -/*! - * Returns a new instance of DataArrayByte. The caller is to delete this array - * using decrRef() as it is no more needed. - */ -DataArrayByte *DataArrayByte::New() -{ - return new DataArrayByte; -} - -DataArrayByteIterator *DataArrayByte::iterator() -{ - return new DataArrayByteIterator(this); -} - -/*! - * Returns a full copy of \a this. For more info on copying data arrays see - * \ref MEDCouplingArrayBasicsCopyDeep. - * \return DataArrayByte * - a new instance of DataArrayByte. - */ -DataArrayByte *DataArrayByte::deepCpy() const -{ - return new DataArrayByte(*this); -} - -/*! - * Returns either a \a deep or \a shallow copy of this array. For more info see - * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. - * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. - * \return DataArrayByte * - either a new instance of DataArrayByte (if \a dCpy - * == \a true) or \a this instance (if \a dCpy == \a false). - */ -DataArrayByte *DataArrayByte::performCpy(bool dCpy) const -{ - if(dCpy) - return deepCpy(); - else - { - incrRef(); - return const_cast(this); - } -} - -/*! - * Returns the only one value in \a this, if and only if number of elements - * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. - * \return char - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -char DataArrayByte::byteValue() const -{ - if(isAllocated()) - { - if(getNbOfElems()==1) - { - return *getConstPointer(); - } - else - throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !"); -} - -DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const -{ - return DataArrayByte::New(); -} - -void DataArrayByte::reprStream(std::ostream& stream) const -{ - stream << "Name of byte array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayByte::reprZipStream(std::ostream& stream) const -{ - stream << "Name of byte array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - if(_mem.reprHeader(getNumberOfComponents(),stream)) - { - const char *data=begin(); - int nbOfTuples=getNumberOfTuples(); - int nbCompo=getNumberOfComponents(); - for(int i=0;i(stream," "));//it is not a bug int here not char because it is not ASCII here contrary to DataArrayAsciiChar - stream << "\n"; - } - } -} - -void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - _mem.reprZip(getNumberOfComponents(),stream); -} - -void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); - const char *data=getConstPointer(); - stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl; - if(nbTuples*nbComp>=1) - { - stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={"; - std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator(stream,",")); - stream << data[nbTuples*nbComp-1] << "};" << std::endl; - stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl; - } - else - stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl; - stream << varName << "->setName(\"" << getName() << "\");" << std::endl; -} - -/*! - * Method that gives a quick overvien of \a this for python. - */ -void DataArrayByte::reprQuickOverview(std::ostream& stream) const -{ - static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; - stream << "DataArrayByte C++ instance at " << this << ". "; - if(isAllocated()) - { - int nbOfCompo=(int)_info_on_compo.size(); - if(nbOfCompo>=1) - { - int nbOfTuples=getNumberOfTuples(); - stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; - reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); - } - else - stream << "Number of components : 0."; - } - else - stream << "*** No data allocated ****"; -} - -void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const -{ - const char *data=begin(); - int nbOfTuples=getNumberOfTuples(); - int nbOfCompo=(int)_info_on_compo.size(); - std::ostringstream oss2; oss2 << "["; - std::string oss2Str(oss2.str()); - bool isFinished=true; - for(int i=0;i1) - { - oss2 << "("; - for(int j=0;j(&other); - if(!otherC) - { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; } - return DataArrayChar::isEqualIfNotWhy(other,reason); -} - -/*! - * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. - * \throw if \a this is not allocated. - * \throw if \a this has not exactly one component. - */ -std::vector DataArrayByte::toVectorOfBool() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !"); - int nbt(getNumberOfTuples()); - std::vector ret(nbt,false); - const char *pt(begin()); - for(int i=0;iincrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayByteIterator::~DataArrayByteIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayByteTuple *DataArrayByteIterator::nextt() -{ - if(_tuple_id<_nb_tuple) - { - _tuple_id++; - DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp); - _pt+=_nb_comp; - return ret; - } - else - return 0; -} - -DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) -{ -} - -std::string DataArrayByteTuple::repr() const -{ - std::ostringstream oss; oss << "("; - for(int i=0;i<_nb_of_compo-1;i++) - oss << (int)_pt[i] << ", "; - oss << _pt[_nb_of_compo-1] << ")"; - return oss.str(); -} - -char DataArrayByteTuple::byteValue() const -{ - if(_nb_of_compo==1) - return *_pt; - throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !"); -} - -/*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayByte::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayByte::useArray with ownership set to \b false. - * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or - * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. - */ -DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const -{ - if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) - { - DataArrayByte *ret=DataArrayByte::New(); - ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); - return ret; - } - else - { - std::ostringstream oss; oss << "DataArrayByteTuple::buildDAByte : unable to build a requested DataArrayByte instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo; - oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array - * using decrRef() as it is no more needed. - */ -DataArrayAsciiChar *DataArrayAsciiChar::New() -{ - return new DataArrayAsciiChar; -} - -/*! - * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown. - */ -DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st) -{ - return new DataArrayAsciiChar(st); -} - -/*! - * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown. - */ -DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st) -{ - std::size_t lgth=st.length(); - if(lgth==0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !"); - alloc(1,lgth); - std::copy(st.begin(),st.begin()+lgth,getPointer()); -} - -/*! - * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array - * using decrRef() as it is no more needed. - * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in - * \a vst the remaining locations in memory will be set to character \a defaultChar. - * - * \param [in] defaultChar the default character used to fill not defined locations in \a this - * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained - * in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown. - * - * \throw If input \a vst is empty. - * \throw If all strings in \a vst are empty. - */ -DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector& vst, char defaultChar) -{ - return new DataArrayAsciiChar(vst,defaultChar); -} - -/*! - * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in - * \a vst the remaining locations in memory will be set to character \a defaultChar. - * - * \param [in] defaultChar the default character used to fill not defined locations in \a this - * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained - * in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown. - * - * \throw If input \a vst is empty. - * \throw If all strings in \a vst are empty. - */ -DataArrayAsciiChar::DataArrayAsciiChar(const std::vector& vst, char defaultChar) -{ - if(vst.empty()) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !"); - std::size_t nbCompo=0; - for(std::vector::const_iterator it=vst.begin();it!=vst.end();it++) - nbCompo=std::max(nbCompo,(*it).length()); - if(nbCompo==0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! All strings in not empty vector are empty !"); - int nbTuples=(int)vst.size(); - alloc(nbTuples,(int)nbCompo); - char *pt=getPointer(); - for(int i=0;i(this); - } -} - -/*! - * Returns the only one value in \a this, if and only if number of elements - * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. - * \return char - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -char DataArrayAsciiChar::asciiCharValue() const -{ - if(isAllocated()) - { - if(getNbOfElems()==1) - { - return *getConstPointer(); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !"); -} - -DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const -{ - return DataArrayAsciiChar::New(); -} - -void DataArrayAsciiChar::reprStream(std::ostream& stream) const -{ - stream << "Name of ASCII char array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const -{ - stream << "Name of ASCII char array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - if(_mem.reprHeader(getNumberOfComponents(),stream)) - { - const char *data=begin(); - int nbOfTuples=getNumberOfTuples(); - int nbCompo=getNumberOfComponents(); - for(int i=0;i(stream)); - stream << "\"\n"; - } - } -} - -void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const -{ - reprWithoutNameStream(stream); -} - -void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); - const char *data=getConstPointer(); - stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl; - if(nbTuples*nbComp>=1) - { - stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={"; - std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator(stream,",")); - stream << data[nbTuples*nbComp-1] << "};" << std::endl; - stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl; - } - else - stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl; - stream << varName << "->setName(\"" << getName() << "\");" << std::endl; -} - -/*! - * Method that gives a quick overvien of \a this for python. - */ -void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const -{ - static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; - stream << "DataArrayAsciiChar C++ instance at " << this << ". "; - if(isAllocated()) - { - int nbOfCompo=(int)_info_on_compo.size(); - if(nbOfCompo>=1) - { - int nbOfTuples=getNumberOfTuples(); - stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; - reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); - } - else - stream << "Number of components : 0."; - } - else - stream << "*** No data allocated ****"; -} - -void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const -{ - const char *data=begin(); - int nbOfTuples=getNumberOfTuples(); - int nbOfCompo=(int)_info_on_compo.size(); - std::ostringstream oss2; oss2 << "["; - std::string oss2Str(oss2.str()); - bool isFinished=true; - for(int i=0;i(&other); - if(!otherC) - { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; } - return DataArrayChar::isEqualIfNotWhy(other,reason); -} - -DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0) -{ - if(_da) - { - _da->incrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt() -{ - if(_tuple_id<_nb_tuple) - { - _tuple_id++; - DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp); - _pt+=_nb_comp; - return ret; - } - else - return 0; -} - -DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) -{ -} - -std::string DataArrayAsciiCharTuple::repr() const -{ - std::ostringstream oss; - std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator(oss)); - return oss.str(); -} - -char DataArrayAsciiCharTuple::asciiCharValue() const -{ - if(_nb_of_compo==1) - return *_pt; - throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !"); -} - -/*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayAsciiChar::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayAsciiChar::useArray with ownership set to \b false. - * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or - * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. - */ -DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const -{ - if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) - { - DataArrayAsciiChar *ret=DataArrayAsciiChar::New(); - ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); - return ret; - } - else - { - std::ostringstream oss; oss << "DataArrayAsciiCharTuple::buildDAAsciiChar : unable to build a requested DataArrayAsciiChar instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo; - oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} diff --git a/medtool/src/MEDCoupling/MEDCouplingMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingMesh.cxx deleted file mode 100644 index 3de265f1f..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMesh.cxx +++ /dev/null @@ -1,762 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingMesh::MEDCouplingMesh():_time(0.),_iteration(-1),_order(-1) -{ -} - -MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):RefCountObject(other),_name(other._name),_description(other._description), - _time(other._time),_iteration(other._iteration), - _order(other._order),_time_unit(other._time_unit) -{ -} - -std::size_t MEDCouplingMesh::getHeapMemorySizeWithoutChildren() const -{ - return _name.capacity()+_description.capacity()+_time_unit.capacity(); -} - -/*! - * This method is only for ParaMEDMEM in ParaFIELD constructor. - */ -bool MEDCouplingMesh::isStructured() const -{ - return getType()==CARTESIAN; -} - -bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::isEqualIfNotWhy : other instance is NULL !"); - std::ostringstream oss; oss.precision(15); - if(_name!=other->_name) - { - oss << "Mesh names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; - reason=oss.str(); - return false; - } - if(_description!=other->_description) - { - oss << "Mesh descriptions differ : this description = \"" << _description << "\" and other description = \"" << other->_description << "\" !"; - reason=oss.str(); - return false; - } - if(_iteration!=other->_iteration) - { - oss << "Mesh iterations differ : this iteration = \"" << _iteration << "\" and other iteration = \"" << other->_iteration << "\" !"; - reason=oss.str(); - return false; - } - if(_order!=other->_order) - { - oss << "Mesh orders differ : this order = \"" << _order << "\" and other order = \"" << other->_order << "\" !"; - reason=oss.str(); - return false; - } - if(_time_unit!=other->_time_unit) - { - oss << "Mesh time units differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; - reason=oss.str(); - return false; - } - if(fabs(_time-other->_time)>=1e-12) - { - oss << "Mesh times differ : this time = \"" << _time << "\" and other time = \"" << other->_time << "\" !"; - reason=oss.str(); - return false; - } - return true; -} - -/*! - * Checks if \a this and another MEDCouplingMesh are fully equal. - * \param [in] other - an instance of MEDCouplingMesh to compare with \a this one. - * \param [in] prec - precision value used to compare node coordinates. - * \return bool - \c true if the two meshes are equal, \c false else. - */ -bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const -{ - std::string tmp; - return isEqualIfNotWhy(other,prec,tmp); -} - -/*! - * This method checks geo equivalence between two meshes : \a this and \a other. - * If no exception is thrown \a this and \a other are geometrically equivalent regarding \a levOfCheck level. - * This method is typically used to change the mesh of a field "safely" depending the \a levOfCheck level considered. - * - * In case of success cell \c other[i] is equal to the cell \c this[cellCor[i]]. - * In case of success node \c other->getCoords()[i] is equal to the node \c this->getCoords()[nodeCor[i]]. - * - * If \a cellCor is null (or Py_None) it means that for all #i cell in \a other is equal to cell # i in \a this. - * - * If \a nodeCor is null (or Py_None) it means that for all #i node in \a other is equal to node # i in \a this. - * - * So null (or Py_None) returned in \a cellCor and/or \a nodeCor means identity array. This is for optimization reason to avoid to build useless arrays - * for some \a levOfCheck (for example 0). - * - * **Warning a not null output does not mean that it is not identity !** - * - * \param [in] other - the mesh to be compared with \a this. - * \param [in] levOfCheck - input that specifies the level of check specified. The possible values are listed below. - * \param [in] prec - input that specifies precision for double float data used for comparison in meshes. - * \param [out] cellCor - output array not always informed (depending \a levOfCheck param) that gives the corresponding array for cells from \a other to \a this. - * \param [out] nodeCor - output array not always informed (depending \a levOfCheck param) that gives the corresponding array for nodes from \a other to \a this. - * - * Possible values for levOfCheck : - * - 0 for strict equality. This is the strongest level. \a cellCor and \a nodeCor params are never informed. - * - 10,11,12 (10+x) for less strict equality. Two meshes are compared geometrically. In case of success \a cellCor and \a nodeCor are informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) - * - 20,21,22 (20+x), for less strict equality. Two meshes are compared geometrically. The difference with the previous version is that nodes(coordinates) are expected to be the same between this and other. In case of success \a cellCor is informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) - * - 1 for fast 'equality'. This is a lazy level. Just number of cells and number of nodes are considered here and 3 cells (begin,middle,end) - * - 2 for deep 'equality' as 0 option except that no control is done on all strings in mesh. - * - * So the most strict level of check is 0 (equality). The least strict is 12. If the level of check 12 throws, the 2 meshes \a this and \a other are not similar enough - * to be compared. An interpolation using MEDCouplingRemapper class should be then used. - */ -void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - cellCor=0; - nodeCor=0; - if(this==other) - return ; - switch(levOfCheck) - { - case 0: - { - if(!isEqual(other,prec)) - throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal !"); - return ; - } - case 10: - case 11: - case 12: - { - checkDeepEquivalWith(other,levOfCheck-10,prec,cellCor,nodeCor); - return ; - } - case 20: - case 21: - case 22: - { - checkDeepEquivalOnSameNodesWith(other,levOfCheck-20,prec,cellCor); - return ; - } - case 1: - { - checkFastEquivalWith(other,prec); - return; - } - case 2: - { - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal without considering strings !"); - return ; - } - default: - throw INTERP_KERNEL::Exception("checkGeoFitWith : Invalid levOfCheck specified ! Value must be in 0,1,2,10,11 or 12."); - } -} - -/*! - * Finds cells whose all nodes are in a given array of node ids. - * \param [in] partBg - the array of node ids. - * \param [in] partEnd - end of \a partBg, i.e. a pointer to a (last+1)-th element - * of \a partBg. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * cells. The caller is to delete this array using decrRef() as it is no - * more needed. - */ -DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const -{ - std::vector crest; - std::set p(partBg,partEnd); - int nbOfCells=getNumberOfCells(); - for(int i=0;i conn; - getNodeIdsOfCell(i,conn); - bool cont=true; - for(std::vector::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++) - if(p.find(*iter)==p.end()) - cont=false; - if(cont) - crest.push_back(i); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)crest.size(),1); - std::copy(crest.begin(),crest.end(),ret->getPointer()); - return ret; -} - -/*! - * This method checks fastly that \a this and \a other are equal. All common checks are done here. - */ -void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::checkFastEquivalWith : input mesh is null !"); - if(getMeshDimension()!=other->getMeshDimension()) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !"); - if(getSpaceDimension()!=other->getSpaceDimension()) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Space dimensions are not equal !"); - if(getNumberOfCells()!=other->getNumberOfCells()) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : number of cells are not equal !"); -} - -/*! - * This method is very poor and looks only if \a this and \a other are candidate for merge of fields lying repectively on them. - */ -bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::areCompatibleForMerge : input mesh is null !"); - if(getMeshDimension()!=other->getMeshDimension()) - return false; - if(getSpaceDimension()!=other->getSpaceDimension()) - return false; - return true; -} - -/*! - * This method is equivalent to MEDCouplingMesh::buildPart method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds. - * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method. - * If the input range is equal all cells in \a this, \a this is returned ! - * - * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order. - * - * \sa MEDCouplingMesh::buildPart - */ -MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const -{ - if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1) - { - MEDCouplingMesh *ret(const_cast(this)); - ret->incrRef(); - return ret; - } - else - { - MEDCouplingAutoRefCountObjectPtr cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); - return buildPart(cellIds->begin(),cellIds->end()); - } -} - -/*! - * This method is equivalent to MEDCouplingMesh::buildPartAndReduceNodes method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds. - * - * \sa MEDCouplingMesh::buildPartAndReduceNodes - */ -MEDCouplingMesh *MEDCouplingMesh::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const -{ - MEDCouplingAutoRefCountObjectPtr cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); - return buildPartAndReduceNodes(cellIds->begin(),cellIds->end(),arr); -} - -/*! - * This method builds a field lying on \a this with 'nbOfComp' components. - * 'func' is a pointer that points to a function that takes 2 arrays in parameter and returns a boolean. - * The first array is a in-param of size this->getSpaceDimension and the second an out param of size 'nbOfComp'. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. - * Contrary to other fillFromAnalytic methods this method requests a C++ function pointer as input. - * The 'func' is a callback that takes as first parameter an input array of size 'this->getSpaceDimension()', - * the second parameter is a pointer on a valid zone of size at least equal to 'nbOfComp' values. And too finish - * the returned value is a boolean that is equal to False in case of invalid evaluation (log(0) for example...) - * - * \param t type of field returned and specifies where the evaluation of func will be done. - * \param nbOfComp number of components of returned field. - * \param func pointer to a function that should return false if the evaluation failed. (division by 0. for example) - * \return field with counter = 1. - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic(nbOfComp,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::copyTinyStringsFrom : input mesh is null !"); - _name=other->_name; - _description=other->_description; - _time_unit=other->_time_unit; -} - -/*! - * This method copies all attributes that are \b NOT arrays in this. - * All tiny attributes not usefully for state of \a this are ignored. - */ -void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) -{ - _time=other->_time; - _iteration=other->_iteration; - _order=other->_order; - copyTinyStringsFrom(other); -} - -/*! - * \anchor mcmesh_fillFromAnalytic - * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of - * components, lying on \a this mesh, with contents got by applying a specified - * function to coordinates of field location points (defined by the given field type). - * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell - * barycenters.
- * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr. The function can include arbitrary named variables - * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of - * variables are sorted in \b alphabetical \b order to associate a variable name with a - * component. For example, in the expression "2*x+z", "x" stands for the component #0 - * and "z" stands for the component #1 (\b not #2)!
- * In a general case, a value resulting from the function evaluation is assigned to all - * components of the field. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, coordinates of a - * point are (1.,3.,7.), then - * - "2*x + z" produces (5.,5.,5.,5.) - * - "2*x + 0*y + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) - * - * \param [in] t - the field type. It defines, apart from other things, points to - * coordinates of which the function is applied to get field values. - * \param [in] nbOfComp - the number of components in the result field. - * \param [in] func - a string defining the expression which is evaluated to get - * field values. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the nodal connectivity of cells is not defined. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".
- * \ref py_mcmesh_fillFromAnalytic "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic(nbOfComp,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of - * components, lying on \a this mesh, with contents got by applying a specified - * function to coordinates of field location points (defined by the given field type). - * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell - * barycenters. This method differs from - * \ref MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const "fillFromAnalytic()" - * by the way how variable - * names, used in the function, are associated with components of coordinates of field - * location points; here, a variable name corresponding to a component is retrieved from - * a corresponding node coordinates array (where it is set via - * DataArrayDouble::setInfoOnComponent()).
- * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * In a general case, a value resulting from the function evaluation is assigned to all - * components of a field value. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of - * spatial components are "x", "y" and "z", coordinates of a - * point are (1.,3.,7.), then - * - "2*x + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) - * - * \param [in] t - the field type. It defines, apart from other things, the points to - * coordinates of which the function is applied to get field values. - * \param [in] nbOfComp - the number of components in the result field. - * \param [in] func - a string defining the expression which is evaluated to get - * field values. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the node coordinates are not defined. - * \throw If the nodal connectivity of cells is not defined. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".
- * \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic2(nbOfComp,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of - * components, lying on \a this mesh, with contents got by applying a specified - * function to coordinates of field location points (defined by the given field type). - * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell - * barycenters. This method differs from \ref \ref mcmesh_fillFromAnalytic - * "fillFromAnalytic()" by the way how variable - * names, used in the function, are associated with components of coordinates of field - * location points; here, a component index of a variable is defined by a - * rank of the variable within the input array \a varsOrder.
- * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr. - * In a general case, a value resulting from the function evaluation is assigned to all - * components of the field. But there is a possibility to have its own expression for - * each component within one function. For this purpose, there are predefined variable - * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to - * the component #0 etc). A factor of such a variable is added to the - * corresponding component only.
- * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of - * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a - * point are (1.,3.,7.), then - * - "2*x + z" produces (9.,9.,9.,9.) - * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) - * - * \param [in] t - the field type. It defines, apart from other things, the points to - * coordinates of which the function is applied to get field values. - * \param [in] nbOfComp - the number of components in the result field. - * \param [in] varsOrder - the vector defining names of variables used to refer to - * components of coordinates of field location points. A variable named - * varsOrder[0] refers to the component #0 etc. - * \param [in] func - a string defining the expression which is evaluated to get - * field values. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the node coordinates are not defined. - * \throw If the nodal connectivity of cells is not defined. - * \throw If computing \a func fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".
- * \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic3(nbOfComp,varsOrder,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingMesh by concatenating two given meshes, if possible. - * Cells and nodes of - * the first mesh precede cells and nodes of the second mesh within the result mesh. - * The meshes must be of the same mesh type, else, an exception is thrown. The method - * MergeMeshes(), accepting a vector of input meshes, has no such a limitation. - * \param [in] mesh1 - the first mesh. - * \param [in] mesh2 - the second mesh. - * \return MEDCouplingMesh * - the result mesh. It is a new instance of - * MEDCouplingMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If the meshes are of different mesh type. - */ -MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) -{ - if(!mesh1) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : first parameter is an empty mesh !"); - if(!mesh2) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : second parameter is an empty mesh !"); - return mesh1->mergeMyselfWith(mesh2); -} - -/*! - * Creates a new MEDCouplingMesh by concatenating all given meshes, if possible. - * Cells and nodes of - * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh. - * This method performs a systematic conversion to unstructured meshes before - * performing aggregation contrary to the other MergeMeshes() - * with two parameters that works only on the same type of meshes. So here it is possible - * to mix different type of meshes. - * \param [in] meshes - a vector of meshes to concatenate. - * \return MEDCouplingMesh * - the result mesh. It is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If \a meshes.size() == 0. - * \throw If \a size[ *i* ] == NULL. - * \throw If the coordinates is not set in none of the meshes. - * \throw If \a meshes[ *i* ]->getMeshDimension() < 0. - * \throw If the \a meshes are of different dimension (getMeshDimension()). - */ -MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector& meshes) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > ms1(meshes.size()); - std::vector< const MEDCouplingUMesh * > ms2(meshes.size()); - for(std::size_t i=0;ibuildUnstructured(); - ms1[i]=cur; ms2[i]=cur; - } - else - { - std::ostringstream oss; oss << "MEDCouplingMesh::MergeMeshes(std::vector& meshes) : mesh at pos #" << i << " of input vector of size " << meshes.size() << " is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return MEDCouplingUMesh::MergeUMeshes(ms2); -} - -/*! - * For example if \a type is INTERP_KERNEL::NORM_TRI3 , INTERP_KERNEL::NORM_POLYGON is returned. - * If \a type is INTERP_KERNEL::NORM_HEXA8 , INTERP_KERNEL::NORM_POLYHED is returned. - * - * \param [in] type the geometric type for which the corresponding dynamic type, is asked. - * \return the corresponding dynamic type, able to store the input \a type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -INTERP_KERNEL::NormalizedCellType MEDCouplingMesh::GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return cm.getCorrespondingPolyType(); -} - -/*! - * \param [in] type the geometric type for which the number of nodes consituting it, is asked. - * \return number of nodes consituting the input geometric type \a type. - * - * \throw if type is dynamic as \c INTERP_KERNEL::NORM_POLYHED , \c INTERP_KERNEL::NORM_POLYGON , \c INTERP_KERNEL::NORM_QPOLYG - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -int MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::GetNumberOfNodesOfGeometricType : the input geometric type is dynamic ! Impossible to return a fixed number of nodes constituting it !"); - return (int) cm.getNumberOfNodes(); -} - -/*! - * \param [in] type the geometric type for which the status static/dynamic is asked. - * \return true for static geometric type, false for dynamic geometric type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -bool MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return !cm.isDynamic(); -} - -bool MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return !cm.isQuadratic(); -} - -/*! - * \param [in] type the geometric type for which the dimension is asked. - * \return the dimension associated to the input geometric type \a type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return (int) cm.getDimension(); -} - -/*! - * \param [in] type the geometric type for which the representation is asked. - * \return the string representation corresponding to the input geometric type \a type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return cm.getRepr(); -} - -/*! - * Finds cells in contact with a ball (i.e. a point with precision). - * \warning This method is suitable if the caller intends to evaluate only one - * point, for more points getCellsContainingPoints() is recommended as it is - * faster. - * \param [in] pos - array of coordinates of the ball central point. - * \param [in] eps - ball radius. - * \param [in,out] elts - vector returning ids of the found cells. It is cleared - * before inserting ids. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". - * \endif - */ -void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const -{ - int ret=getCellContainingPoint(pos,eps); - elts.push_back(ret); -} - -/*! - * Finds cells in contact with several balls (i.e. points with precision). - * This method is an extension of getCellContainingPoint() and - * getCellsContainingPoint() for the case of multiple points. - * \param [in] pos - an array of coordinates of points in full interlace mode : - * X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a - * this->getSpaceDimension() * \a nbOfPoints - * \param [in] nbOfPoints - number of points to locate within \a this mesh. - * \param [in] eps - radius of balls (i.e. the precision). - * \param [out] elts - vector returning ids of found cells. - * \param [out] eltsIndex - an array, of length \a nbOfPoints + 1, - * dividing cell ids in \a elts into groups each referring to one - * point. Its every element (except the last one) is an index pointing to the - * first id of a group of cells. For example cells in contact with the *i*-th - * point are described by following range of indices: - * [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are - * \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ... - * Number of cells in contact with the *i*-th point is - * \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". - * \endif - */ -void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const -{ - eltsIndex=DataArrayInt::New(); elts=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1); - int *eltsIndexPtr(eltsIndex->getPointer()); - int spaceDim(getSpaceDimension()); - const double *work(pos); - for(int i=0;i=0) - { - elts->pushBackSilent(ret); - eltsIndexPtr[i+1]=eltsIndexPtr[i]+1; - } - else - eltsIndexPtr[i+1]=eltsIndexPtr[i]; - } -} - -/*! - * Writes \a this mesh into a VTK format file named as specified. - * \param [in] fileName - the name of the file to write in. If the extension is OK the fileName will be used directly. - * If extension is invalid or no extension the right extension will be appended. - * \return - the real fileName - * \throw If \a fileName is not a writable file. - * \sa getVTKFileNameOf - */ -std::string MEDCouplingMesh::writeVTK(const std::string& fileName, bool isBinary) const -{ - std::string ret(getVTKFileNameOf(fileName)); - // - std::string cda,pda; - MEDCouplingAutoRefCountObjectPtr byteArr; - if(isBinary) - { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } - writeVTKAdvanced(ret,cda,pda,byteArr); - return ret; -} - -/*! - * This method takes in input a file name \a fileName and considering the VTK extension of \a this (depending on the type of \a this) - * returns a right file name. If the input \a fileName has a valid extension the returned string is equal to \a fileName. - * - * \sa getVTKFileExtension - */ -std::string MEDCouplingMesh::getVTKFileNameOf(const std::string& fileName) const -{ - std::string ret; - std::string part0,part1; - SplitExtension(fileName,part0,part1); - std::string ext("."); ext+=getVTKFileExtension(); - if(part1==ext) - ret=fileName; - else - ret=fileName+ext; - return ret; -} - -/// @cond INTERNAL -void MEDCouplingMesh::writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const -{ - std::ofstream ofs(fileName.c_str()); - ofs << "\n"; - writeVTKLL(ofs,cda,pda,byteData); - if(byteData) - { - ofs << "\n_1234"; - ofs << std::flush; ofs.close(); - std::ofstream ofs2(fileName.c_str(),std::ios_base::binary | std::ios_base::app); - ofs2.write(byteData->begin(),byteData->getNbOfElems()); ofs2 << std::flush; ofs2.close(); - std::ofstream ofs3(fileName.c_str(),std::ios_base::app); ofs3 << "\n\n\n"; ofs3.close(); - } - else - { - ofs << "\n"; - ofs.close(); - } -} - -void MEDCouplingMesh::SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension) -{ - std::size_t pos(fileName.find_last_of('.')); - if(pos==std::string::npos) - { - baseName=fileName; - extension.clear(); - return ; - } - baseName=fileName.substr(0,pos); - extension=fileName.substr(pos); -} -/// @endcond diff --git a/medtool/src/MEDCoupling/MEDCouplingMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingMesh.hxx deleted file mode 100644 index b4a20e705..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMesh.hxx +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - typedef enum - { - UNSTRUCTURED = 5, - CARTESIAN = 7, - EXTRUDED = 8, - CURVE_LINEAR = 9, - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, - IMAGE_GRID = 12 - } MEDCouplingMeshType; - // -- WARNING this enum must be synchronized with MEDCouplingCommon.i file ! -- - - class DataArrayInt; - class DataArrayByte; - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - class MEDCouplingMesh : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } - MEDCOUPLING_EXPORT std::string getName() const { return _name; } - MEDCOUPLING_EXPORT void setDescription(const std::string& descr) { _description=descr; } - MEDCOUPLING_EXPORT std::string getDescription() const { return _description; } - MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } - MEDCOUPLING_EXPORT void setTime(double val, int iteration, int order) { _time=val; _iteration=iteration; _order=order; } - MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit) { _time_unit=unit; } - MEDCOUPLING_EXPORT std::string getTimeUnit() const { return _time_unit; } - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *deepCpy() const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMeshType getType() const = 0; - MEDCOUPLING_EXPORT bool isStructured() const; - MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT virtual void copyTinyInfoFrom(const MEDCouplingMesh *other); - // comparison methods - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; - MEDCOUPLING_EXPORT virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const = 0; - MEDCOUPLING_EXPORT virtual void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const = 0; - MEDCOUPLING_EXPORT virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - // - MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherency1(double eps=1e-12) const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherency2(double eps=1e-12) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfCells() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfNodes() const = 0; - MEDCOUPLING_EXPORT virtual int getSpaceDimension() const = 0; - MEDCOUPLING_EXPORT virtual int getMeshDimension() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getCoordinatesAndOwner() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getBarycenterAndOwner() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeNbOfNodesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeEffectiveNbOfNodesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeNbOfFacesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; - MEDCOUPLING_EXPORT virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0; - MEDCOUPLING_EXPORT virtual std::set getAllGeoTypes() const = 0; - MEDCOUPLING_EXPORT virtual void getNodeIdsOfCell(int cellId, std::vector& conn) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT virtual void getCoordinatesOfNode(int nodeId, std::vector& coo) const = 0; - MEDCOUPLING_EXPORT virtual std::string simpleRepr() const = 0; - MEDCOUPLING_EXPORT virtual std::string advancedRepr() const = 0; - // tools - MEDCOUPLING_EXPORT virtual std::vector getDistributionOfTypes() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const = 0; - MEDCOUPLING_EXPORT virtual void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const = 0; - MEDCOUPLING_EXPORT virtual void getBoundingBox(double *bbox) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const = 0; - MEDCOUPLING_EXPORT virtual int getCellContainingPoint(const double *pos, double eps) const = 0; - MEDCOUPLING_EXPORT virtual void getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; - MEDCOUPLING_EXPORT virtual void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0; - MEDCOUPLING_EXPORT virtual void rotate(const double *center, const double *vector, double angle) = 0; - MEDCOUPLING_EXPORT virtual void translate(const double *vector) = 0; - MEDCOUPLING_EXPORT virtual void scale(const double *point, double factor) = 0; - MEDCOUPLING_EXPORT virtual void renumberCells(const int *old2NewBg, bool check=true) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT virtual MEDCouplingUMesh *buildUnstructured() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *simplexize(int policy) = 0; - MEDCOUPLING_EXPORT virtual void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const = 0; - MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingMesh *MergeMeshes(std::vector& meshes); - MEDCOUPLING_EXPORT static bool IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static bool IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static INTERP_KERNEL::NormalizedCellType GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static int GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - //serialisation-unserialization - MEDCOUPLING_EXPORT virtual void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const = 0; - MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const = 0; - MEDCOUPLING_EXPORT virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0; - MEDCOUPLING_EXPORT virtual void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) = 0; - MEDCOUPLING_EXPORT std::string writeVTK(const std::string& fileName, bool isBinary=true) const; - MEDCOUPLING_EXPORT std::string getVTKFileNameOf(const std::string& fileName) const; - MEDCOUPLING_EXPORT virtual std::string getVTKFileExtension() const = 0; - /// @cond INTERNAL - MEDCOUPLING_EXPORT void writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const; - MEDCOUPLING_EXPORT static void SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension); - /// @endcond - MEDCOUPLING_EXPORT virtual void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const = 0; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - protected: - MEDCOUPLING_EXPORT MEDCouplingMesh(); - MEDCOUPLING_EXPORT MEDCouplingMesh(const MEDCouplingMesh& other); - MEDCOUPLING_EXPORT virtual std::string getVTKDataSetType() const = 0; - MEDCOUPLING_EXPORT virtual ~MEDCouplingMesh() { } - private: - std::string _name; - std::string _description; - double _time; - int _iteration; - int _order; - std::string _time_unit; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingMultiFields.cxx b/medtool/src/MEDCoupling/MEDCouplingMultiFields.cxx deleted file mode 100644 index f493405d8..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMultiFields.cxx +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingMultiFields *MEDCouplingMultiFields::New(const std::vector& fs) -{ - return new MEDCouplingMultiFields(fs); -} - -MEDCouplingMultiFields *MEDCouplingMultiFields::New() -{ - return new MEDCouplingMultiFields; -} - -MEDCouplingMultiFields *MEDCouplingMultiFields::deepCpy() const -{ - return new MEDCouplingMultiFields(*this); -} - -bool MEDCouplingMultiFields::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - std::size_t sz=_fs.size(); - if(sz!=other->_fs.size()) - return false; - for(std::size_t i=0;i_fs[i]; - if(f1!=f2) - { - if(f1==0 || f2==0) - return false; - if(!_fs[i]->isEqual(other->_fs[i],meshPrec,valsPrec)) - return false; - } - } - std::vector refs1,refs2; - std::vector ms1=getDifferentMeshes(refs1); - std::vector ms2=other->getDifferentMeshes(refs2); - if(ms1.size()!=ms2.size()) - return false; - if(refs1!=refs2) - return false; - std::vector< std::vector > refs3,refs4; - std::vector das1=getDifferentArrays(refs3); - std::vector das2=getDifferentArrays(refs4); - if(das1.size()!=das2.size()) - return false; - if(refs3!=refs4) - return false; - return true; -} - -std::string MEDCouplingMultiFields::getName() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getName(); - return std::string(); -} - -std::string MEDCouplingMultiFields::getDescription() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getDescription(); - return std::string(); -} - -std::string MEDCouplingMultiFields::getTimeUnit() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getTimeUnit(); - return std::string(); -} - -double MEDCouplingMultiFields::getTimeResolution() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getTimeTolerance(); - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getTimeResolution : no not null field !"); -} - -std::string MEDCouplingMultiFields::simpleRepr() const -{ - std::ostringstream ret; - ret << "MEDCouplingMultiFields with name : \"" << getName() << "\"\n"; - ret << "Description of MEDCouplingMultiFields is : \"" << getDescription() << "\"\n"; - ret << "Number of discretization : " << _fs.size() << "\n"; - ret << "Number of different meshes : "; - std::vector ms; - std::vector refms; - try - { - ms=getDifferentMeshes(refms); - ret << ms.size() << "\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { ret << "Current instance is INVALID !\n"; } - return ret.str(); -} - -std::string MEDCouplingMultiFields::advancedRepr() const -{ - return simpleRepr(); -} - -bool MEDCouplingMultiFields::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - std::size_t sz=_fs.size(); - if(sz!=other->_fs.size()) - return false; - for(std::size_t i=0;iisEqualWithoutConsideringStr(other->_fs[i],meshPrec,valsPrec)) - return false; - return true; -} - -const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldWithId(int id) const -{ - if(id>=(int)_fs.size() || id < 0) - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getFieldWithId : invalid id outside boundaries !"); - return _fs[id]; -} - -std::vector MEDCouplingMultiFields::getFields() const -{ - std::vector ret(_fs.size()); - std::copy(_fs.begin(),_fs.end(),ret.begin()); - return ret; -} - -int MEDCouplingMultiFields::getNumberOfFields() const -{ - return (int)_fs.size(); -} - -const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldAtPos(int id) const -{ - if(id<0 || id>=(int)_fs.size()) - { - std::ostringstream oss; oss << "MEDCouplingMultiFields::getFieldAtPos : Invalid given pos : should be >=0 and < " << _fs.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _fs[id]; -} - -void MEDCouplingMultiFields::updateTime() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - (*it)->updateTime(); - it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - updateTimeWith(*(*it)); -} - -std::size_t MEDCouplingMultiFields::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDCouplingMultiFields::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++) - ret.push_back((const MEDCouplingFieldDouble *)*it); - return ret; -} - -std::vector MEDCouplingMultiFields::getMeshes() const -{ - std::vector ms; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++) - { - const MEDCouplingMesh *m=0; - if((const MEDCouplingFieldDouble *)(*it)) - m=(*it)->getMesh(); - ms.push_back(const_cast(m)); - } - return ms; -} - -std::vector MEDCouplingMultiFields::getDifferentMeshes(std::vector& refs) const -{ - refs.resize(_fs.size()); - std::vector ms; - int id=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++) - { - const MEDCouplingMesh *m=0; - if((const MEDCouplingFieldDouble *)(*it)) - m=(*it)->getMesh(); - if(m) - { - std::vector::iterator it2=std::find(ms.begin(),ms.end(),m); - if(it2==ms.end()) - { - ms.push_back(const_cast(m)); - refs[id]=(int)ms.size()-1; - } - else - refs[id]=(int)std::distance(ms.begin(),it2); - } - else - refs[id]=-1; - } - return ms; -} - -std::vector MEDCouplingMultiFields::getArrays() const -{ - std::vector tmp; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++) - { - std::vector tmp2=(*it)->getArrays(); - tmp.insert(tmp.end(),tmp2.begin(),tmp2.end()); - } - return tmp; -} - -std::vector MEDCouplingMultiFields::getDifferentArrays(std::vector< std::vector >& refs) const -{ - refs.resize(_fs.size()); - int id=0; - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++) - { - std::vector tmp2; - if((const MEDCouplingFieldDouble *)(*it)) - { - tmp2=(*it)->getArrays(); - refs[id].resize(tmp2.size()); - } - else - refs[id].clear(); - int id2=0; - for(std::vector::const_iterator it2=tmp2.begin();it2!=tmp2.end();it2++,id2++) - { - if(*it2) - { - std::vector::iterator it3=std::find(ret.begin(),ret.end(),*it2); - if(it3==ret.end()) - { - ret.push_back(*it2); - refs[id][id2]=(int)ret.size()-1; - } - else - refs[id][id2]=(int)std::distance(ret.begin(),it3); - } - else - refs[id][id2]=-1; - } - } - return ret; -} - -void MEDCouplingMultiFields::checkCoherency() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - { - if((const MEDCouplingFieldDouble *)(*it)==0) - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::checkCoherency : There is an empty Field in array..."); - (*it)->checkCoherency(); - } -} - -MEDCouplingMultiFields::MEDCouplingMultiFields(const std::vector& fs):_fs(fs.size()) -{ - int id=0; - for(std::vector< MEDCouplingFieldDouble * >::const_iterator it=fs.begin();it!=fs.end();it++,id++) - { - if(*it) - (*it)->incrRef(); - else - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields constructor : empty field found in vector !"); - (*it)->checkCoherency(); - _fs[id]=*it; - } -} - - -/*! - * Performs deepCpy. - */ -MEDCouplingMultiFields::MEDCouplingMultiFields(const MEDCouplingMultiFields& other):RefCountObject(other) -{ - std::size_t sz=other._fs.size(); - _fs.resize(sz); - std::vector refs; - std::vector< std::vector > refs2; - std::vector ms=other.getDifferentMeshes(refs); - std::size_t msLgh=ms.size(); - std::vector< MEDCouplingAutoRefCountObjectPtr > ms2(msLgh); - for(std::size_t i=0;ideepCpy(); - std::vector das=other.getDifferentArrays(refs2); - std::size_t dasLgth=das.size(); - std::vector< MEDCouplingAutoRefCountObjectPtr > das2(dasLgth); - for(std::size_t i=0;ideepCpy(); - for(std::size_t i=0;igetTimeDiscretization()); - tmp->decrRef(); - if(refs[i]!=-1) - _fs[i]->setMesh(ms2[refs[i]]); - std::size_t nbOfArr=refs2[i].size(); - std::vector tmp2(nbOfArr); - for(std::size_t j=0;jsetArrays(tmp2); - std::vector tinyInfo; - std::vector tinyInfo2; - other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tinyInfo); - other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tinyInfo2); - _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tinyInfo,tinyInfo2); - } - } -} - -MEDCouplingMultiFields::MEDCouplingMultiFields() -{ -} - -void MEDCouplingMultiFields::getTinySerializationInformation(std::vector& tinyInfo, std::vector& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const -{ - std::vector refs; - std::vector ms=getDifferentMeshes(refs); - nbOfDiffMeshes=(int)ms.size(); - std::vector< std::vector > refs2; - std::vector fs=getDifferentArrays(refs2); - nbOfDiffArr=(int)fs.size(); - // - std::size_t sz=refs.size();//==_fs.size() - int sz2=0; - for(std::size_t i=0;i doubleDaInd(sz); - std::vector timeDiscrInt; - tinyInfo.resize(sz2+5*sz+3); - tinyInfo[0]=(int)sz; - tinyInfo[1]=sz2; - for(std::size_t i=0;i tmp; - std::vector tmp2; - _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tmp); - _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tmp2); - tinyInfo[3*sz+3+i]=(int)tmp.size(); - tinyInfo[4*sz+3+i]=(int)tmp2.size(); - tinyInfo2.insert(tinyInfo2.end(),tmp.begin(),tmp.end()); - timeDiscrInt.insert(timeDiscrInt.end(),tmp2.begin(),tmp2.end()); - } - int sz3=(int)timeDiscrInt.size(); - tinyInfo[2]=sz3; - // - for(std::size_t i=0;igetTimeDiscretization(); - int k=0; - for(std::size_t i=0;i::const_iterator it=refs2[i].begin();it!=refs2[i].end();it++,k++) - tinyInfo[5*sz+k+3]=*it; - tinyInfo.insert(tinyInfo.end(),timeDiscrInt.begin(),timeDiscrInt.end());//tinyInfo has lgth==sz3+sz2+5*sz+3 -} - -void MEDCouplingMultiFields::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, - const std::vector& ft, const std::vector& ms, - const std::vector& das) -{ - int sz=tinyInfoI[0]; - _fs.resize(sz); - int sz2=tinyInfoI[1]; - // dealing with ft with no mesh set. - for(int i=0;isetMesh(ms[meshId]); - } - // dealing with fieldtemplate->fielddouble - int k=0; - int offI=0; - int offD=0; - for(int i=0;i tmp(sz3); - for(int j=0;jsetArrays(tmp); - // time discr tiny info - int lgthI=tinyInfoI[4*sz+3+i]; - int lgthD=tinyInfoI[3*sz+3+i]; - // - std::vector tdInfoI(tinyInfoI.begin()+sz2+5*sz+3+offI,tinyInfoI.begin()+sz2+5*sz+3+offI+lgthI); - std::vector tdInfoD(tinyInfoD.begin()+offD,tinyInfoD.begin()+offD+lgthD); - _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tdInfoI,tdInfoD); - // - offI+=lgthI; - offD+=lgthD; - } -} diff --git a/medtool/src/MEDCoupling/MEDCouplingMultiFields.hxx b/medtool/src/MEDCoupling/MEDCouplingMultiFields.hxx deleted file mode 100644 index b092bc60d..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingMultiFields.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGMULTIFIELDS_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMULTIFIELDS_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - class DataArrayDouble; - class MEDCouplingFieldDouble; - class MEDCouplingFieldTemplate; - - class MEDCouplingMultiFields : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static MEDCouplingMultiFields *New(const std::vector& fs); - MEDCOUPLING_EXPORT static MEDCouplingMultiFields *New(); - MEDCOUPLING_EXPORT MEDCouplingMultiFields *deepCpy() const; - MEDCOUPLING_EXPORT std::string getName() const; - MEDCOUPLING_EXPORT std::string getDescription() const; - MEDCOUPLING_EXPORT std::string getTimeUnit() const; - MEDCOUPLING_EXPORT double getTimeResolution() const; - MEDCOUPLING_EXPORT virtual std::string simpleRepr() const; - MEDCOUPLING_EXPORT virtual std::string advancedRepr() const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble *getFieldWithId(int id) const; - MEDCOUPLING_EXPORT std::vector getFields() const; - MEDCOUPLING_EXPORT int getNumberOfFields() const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble *getFieldAtPos(int id) const; - MEDCOUPLING_EXPORT virtual std::vector getMeshes() const; - MEDCOUPLING_EXPORT virtual std::vector getDifferentMeshes(std::vector& refs) const; - MEDCOUPLING_EXPORT virtual std::vector getArrays() const; - MEDCOUPLING_EXPORT virtual std::vector getDifferentArrays(std::vector< std::vector >& refs) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfo, std::vector& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, - const std::vector& ft, const std::vector& ms, - const std::vector& das); - MEDCOUPLING_EXPORT virtual void checkCoherency() const; - protected: - MEDCOUPLING_EXPORT MEDCouplingMultiFields(const std::vector& fs); - MEDCOUPLING_EXPORT MEDCouplingMultiFields(const MEDCouplingMultiFields& other); - MEDCOUPLING_EXPORT MEDCouplingMultiFields(); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _fs; - }; -} - -#endif - diff --git a/medtool/src/MEDCoupling/MEDCouplingNatureOfField.cxx b/medtool/src/MEDCoupling/MEDCouplingNatureOfField.cxx deleted file mode 100644 index 26f05c670..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingNatureOfField.cxx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingNatureOfField.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - const char *MEDCouplingNatureOfField::REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]= - { "NoNature", - "ConservativeVolumic", - "Integral", - "IntegralGlobConstraint", - "RevIntegral"}; - - const int MEDCouplingNatureOfField::POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]={17,26,32,35,37}; - - const char *MEDCouplingNatureOfField::GetRepr(NatureOfField nat) - { - const int *pos=std::find(POS_OF_NATUREOFFIELD,POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES,(int)nat); - if(pos==POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES) - { - std::ostringstream oss; oss << "MEDCouplingNatureOfField::getRepr : Unrecognized nature of field ! "; - oss << GetAllPossibilitiesStr() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t pos2=std::distance(POS_OF_NATUREOFFIELD,pos); - return REPR_OF_NATUREOFFIELD[pos2]; - } - - std::string MEDCouplingNatureOfField::GetReprNoThrow(NatureOfField nat) - { - const int *pos=std::find(POS_OF_NATUREOFFIELD,POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES,(int)nat); - if(pos==POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES) - return std::string("Unrecognized nature of field !"); - std::size_t pos2=std::distance(POS_OF_NATUREOFFIELD,pos); - return std::string(REPR_OF_NATUREOFFIELD[pos2]); - } - - std::string MEDCouplingNatureOfField::GetAllPossibilitiesStr() - { - std::ostringstream oss; oss << "Possibilities are : "; - for(int i=0;i -class MEDCouplingNormalizedCartesianMesh -{ -public: - static const int MY_SPACEDIM=SPACEDIM; - static const int MY_MESHDIM=SPACEDIM; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -public: - MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh); - //void getBoundingBox(double *boundingBox) const; - //INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; - //int getNumberOfNodesOfElement(int eltId) const; - //int getNumberOfNodes() const; - unsigned long getNumberOfElements() const; - unsigned long nbCellsAlongAxis(int axis) const; - const double * getCoordsAlongAxis(int axis) const; - ~MEDCouplingNormalizedCartesianMesh(); -private: - const ParaMEDMEM::MEDCouplingCMesh *_mesh; -}; - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx b/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx deleted file mode 100644 index 2fe1f85c1..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : MEDCouplingNormalizedCartesianMesh.txx -// Created : Mon Aug 17 12:00:38 2009 -// Author : Edward AGAPOV (eap) -// - -#include "MEDCouplingNormalizedCartesianMesh.hxx" -#include "MEDCouplingCMesh.hxx" - -template -MEDCouplingNormalizedCartesianMesh::MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) -{ - if(_mesh) - _mesh->incrRef(); -} - -template -MEDCouplingNormalizedCartesianMesh::~MEDCouplingNormalizedCartesianMesh() -{ - if(_mesh) - _mesh->decrRef(); -} - -template -unsigned long MEDCouplingNormalizedCartesianMesh::getNumberOfElements() const -{ - return _mesh->getNumberOfCells(); -} - -template -unsigned long MEDCouplingNormalizedCartesianMesh::nbCellsAlongAxis(int axis) const -{ - return _mesh->getCoordsAt(axis)->getNumberOfTuples() - 1; -} - -template -const double * MEDCouplingNormalizedCartesianMesh::getCoordsAlongAxis(int axis) const -{ - return _mesh->getCoordsAt(axis)->getConstPointer(); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx deleted file mode 100644 index d3e8ce6b3..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ - -#include "NormalizedUnstructuredMesh.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingPointSet; -} - -template -class MEDCouplingNormalizedUnstructuredMesh -{ -public: - static const int MY_SPACEDIM=SPACEDIM; - static const int MY_MESHDIM=MESHDIM; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -public: - MEDCouplingNormalizedUnstructuredMesh(const ParaMEDMEM::MEDCouplingPointSet *mesh); - void getBoundingBox(double *boundingBox) const; - INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; - int getNumberOfNodesOfElement(int eltId) const; - int getNumberOfElements() const; - int getNumberOfNodes() const; - const int *getConnectivityPtr() const; - const double *getCoordinatesPtr() const; - const int *getConnectivityIndexPtr() const; - void releaseTempArrays(); - ~MEDCouplingNormalizedUnstructuredMesh(); -private: - void prepare(); -private: - const ParaMEDMEM::MEDCouplingPointSet *_mesh; - int *_conn_for_interp; - int *_conn_index_for_interp; -}; - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx b/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx deleted file mode 100644 index 5e8cfb985..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ -#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ - -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingMemArray.hxx" - -#include - -template -MEDCouplingNormalizedUnstructuredMesh::MEDCouplingNormalizedUnstructuredMesh(const ParaMEDMEM::MEDCouplingPointSet *mesh):_mesh(mesh) -{ - if(_mesh) - _mesh->incrRef(); - prepare(); -} - -template -void MEDCouplingNormalizedUnstructuredMesh::getBoundingBox(double *boundingBox) const -{ - for(int i=0;i::max(); - boundingBox[SPACEDIM+i]=-std::numeric_limits::max(); - } - const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); - const double *ptr=array->getConstPointer(); - int nbOfPts=array->getNbOfElems()/SPACEDIM; - for(int j=0;j*work) - boundingBox[j]=*work; - if(boundingBox[j+SPACEDIM]<*work) - boundingBox[j+SPACEDIM]=*work; - } - } -} - -template -INTERP_KERNEL::NormalizedCellType MEDCouplingNormalizedUnstructuredMesh::getTypeOfElement(int eltId) const -{ - return _mesh->getTypeOfCell(eltId); -} - -template -int MEDCouplingNormalizedUnstructuredMesh::getNumberOfNodesOfElement(int eltId) const -{ - return _mesh->getNumberOfNodesInCell(eltId); -} - -template -int MEDCouplingNormalizedUnstructuredMesh::getNumberOfElements() const -{ - return _mesh->getNumberOfCells(); -} - -template -int MEDCouplingNormalizedUnstructuredMesh::getNumberOfNodes() const -{ - return _mesh->getNumberOfNodes(); -} - -template -const int *MEDCouplingNormalizedUnstructuredMesh::getConnectivityPtr() const -{ - return _conn_for_interp; -} - -template -const double *MEDCouplingNormalizedUnstructuredMesh::getCoordinatesPtr() const -{ - const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); - return array->getConstPointer(); -} - -template -const int *MEDCouplingNormalizedUnstructuredMesh::getConnectivityIndexPtr() const -{ - return _conn_index_for_interp; -} - -template -void MEDCouplingNormalizedUnstructuredMesh::releaseTempArrays() -{ - delete [] _conn_for_interp; - delete [] _conn_index_for_interp; - _conn_for_interp=0; - _conn_index_for_interp=0; -} - -template -MEDCouplingNormalizedUnstructuredMesh::~MEDCouplingNormalizedUnstructuredMesh() -{ - if(_mesh) - _mesh->decrRef(); - releaseTempArrays(); -} - -template -void MEDCouplingNormalizedUnstructuredMesh::prepare() -{ - const ParaMEDMEM::MEDCouplingUMesh *m1(dynamic_cast(_mesh)); - if(m1) - { - int nbOfCell=m1->getNumberOfCells(); - int initialConnSize=m1->getNodalConnectivity()->getNbOfElems(); - _conn_for_interp=new int[initialConnSize-nbOfCell]; - _conn_index_for_interp=new int[nbOfCell+1]; - _conn_index_for_interp[0]=0; - const int *work_conn=m1->getNodalConnectivity()->getConstPointer()+1; - const int *work_conn_index=m1->getNodalConnectivityIndex()->getConstPointer(); - int *work_conn_for_interp=_conn_for_interp; - int *work_conn_index_for_interp=_conn_index_for_interp; - for(int i=0;i(_mesh)); - if(m2) - { - int nbOfCell(m2->getNumberOfCells()); - _conn_index_for_interp=new int[nbOfCell+1]; - const int *conni(m2->getNodalConnectivityIndex()->begin()); - std::copy(conni,conni+nbOfCell+1,_conn_index_for_interp); - _conn_for_interp=new int[m2->getNodalConnectivity()->getNumberOfTuples()]; - std::copy(m2->getNodalConnectivity()->begin(),m2->getNodalConnectivity()->end(),_conn_for_interp); - return ; - } - const ParaMEDMEM::MEDCoupling1SGTUMesh *m3(dynamic_cast(_mesh)); - if(m3) - { - int nbOfCell(m3->getNumberOfCells()),nbNodesPerCell(m3->getNumberOfNodesPerCell()); - _conn_index_for_interp=new int[nbOfCell+1]; _conn_index_for_interp[0]=0; - int *work(_conn_index_for_interp); - for(int i=0;igetNodalConnectivity()->getNumberOfTuples()]; - std::copy(m3->getNodalConnectivity()->begin(),m3->getNodalConnectivity()->end(),_conn_for_interp); - return ; - } - throw INTERP_KERNEL::Exception("MEDCouplingNormalizedUnstructuredMesh::prepare : Unrecognized unstructured mesh ! Type must be in MEDCouplingUMesh, MEDCoupling1DGTUMesh, MEDCoupling1SGTUMesh !"); -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingPartDefinition.cxx b/medtool/src/MEDCoupling/MEDCouplingPartDefinition.cxx deleted file mode 100644 index 7523d938b..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingPartDefinition.cxx +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#include "MEDCouplingPartDefinition.hxx" - -using namespace ParaMEDMEM; - -PartDefinition *PartDefinition::New(int start, int stop, int step) -{ - return SlicePartDefinition::New(start,stop,step); -} - -PartDefinition *PartDefinition::New(DataArrayInt *listOfIds) -{ - return DataArrayPartDefinition::New(listOfIds); -} - -PartDefinition *PartDefinition::Unserialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - if(tinyInt.empty()) - { - MEDCouplingAutoRefCountObjectPtr ret(DataArrayPartDefinition::New(bigArraysI.back())); - bigArraysI.pop_back(); - return ret.retn(); - } - else if(tinyInt.size()==3) - { - MEDCouplingAutoRefCountObjectPtr ret(SlicePartDefinition::New(tinyInt[0],tinyInt[1],tinyInt[2])); - tinyInt.erase(tinyInt.begin(),tinyInt.begin()+3); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception("PartDefinition::Unserialize"); -} - -PartDefinition::~PartDefinition() -{ -} - -DataArrayPartDefinition *DataArrayPartDefinition::New(DataArrayInt *listOfIds) -{ - return new DataArrayPartDefinition(listOfIds); -} - -bool DataArrayPartDefinition::isEqual(const PartDefinition *other, std::string& what) const -{ - if(!other) - { - what="DataArrayPartDefinition::isEqual : other is null, this is not null !"; - return false; - } - const DataArrayPartDefinition *otherC(dynamic_cast(other)); - if(!otherC) - { - what="DataArrayPartDefinition::isEqual : other is not DataArrayPartDefinition !"; - return false; - } - const DataArrayInt *arr0(_arr),*arr1(otherC->_arr); - if(!arr0 && !arr1) - return true; - if((arr0 && !arr1) || (!arr0 && arr1)) - { - what="DataArrayPartDefinition::isEqual : array is not defined both in other and this !"; - return false; - } - std::string what1; - bool ret(arr0->isEqualIfNotWhy(*arr1,what1)); - if(!ret) - { - what=std::string("DataArrayPartDefinition::isEqual : arrays are not equal :\n")+what1; - return false; - } - return true; -} - -DataArrayPartDefinition *DataArrayPartDefinition::deepCpy() const -{ - const DataArrayInt *arr(_arr); - if(!arr) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::deepCpy : array is null !"); - return DataArrayPartDefinition::New(const_cast(arr)); -} - -int DataArrayPartDefinition::getNumberOfElems() const -{ - checkInternalArrayOK(); - return _arr->getNumberOfTuples(); -} - -PartDefinition *DataArrayPartDefinition::operator+(const PartDefinition& other) const -{ - const PartDefinition *otherPt(&other); - if(!otherPt) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); - const DataArrayPartDefinition *other1(dynamic_cast(otherPt)); - if(other1) - return add1(other1); - const SlicePartDefinition *other2(dynamic_cast(otherPt)); - if(other2) - return add2(other2); - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : unrecognized type in input !"); -} - -std::string DataArrayPartDefinition::getRepr() const -{ - std::ostringstream oss; oss << "DataArray Part : "; - const DataArrayInt *arr(_arr); - if(arr) - arr->reprQuickOverview(oss); - else - oss << "No Data !"; - return oss.str(); -} - -/*! - * This method operates FoG where F is \a this and G is \a other. - * Example : if \a other is SlicePart(4,14,1) and if \a this is DataArrayPartDefinition([0,1,2,3,6,7,8,9]) -> DataArrayPartDefinition([4,5,6,7,11,12,13]) will be returned - */ -PartDefinition *DataArrayPartDefinition::composeWith(const PartDefinition *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::composeWith : input PartDef must be not NULL !"); - checkCoherency(); - other->checkCoherency(); - const SlicePartDefinition *spd(dynamic_cast(other)); - if(spd) - {//special case for optim - int a(0),b(0),c(0); - spd->getSlice(a,b,c); - if(c==1) - { - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::New()); - arr->alloc(_arr->getNumberOfTuples(),1); - std::transform(_arr->begin(),_arr->end(),arr->getPointer(),std::bind2nd(std::plus(),a)); - return DataArrayPartDefinition::New(arr); - } - } - // - MEDCouplingAutoRefCountObjectPtr arr1(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr arr2(arr1->selectByTupleIdSafe(_arr->begin(),_arr->end())); - return DataArrayPartDefinition::New(arr2); -} - -void DataArrayPartDefinition::checkCoherency() const -{ - CheckInternalArrayOK(_arr); -} - -/*! - * This method tries to simplify \a this if possible. - * - * \return a new reference (equal to this) to be decrRefed. - */ -PartDefinition *DataArrayPartDefinition::tryToSimplify() const -{ - checkCoherency(); - int a(0),b(0),c(0); - if(_arr->isRange(a,b,c)) - { - return SlicePartDefinition::New(a,b,c); - } - else - { - PartDefinition *ret(const_cast(this)); - ret->incrRef(); - return ret; - } -} - -void DataArrayPartDefinition::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - bigArraysI.push_back(_arr); -} - -DataArrayInt *DataArrayPartDefinition::toDAI() const -{ - checkInternalArrayOK(); - const DataArrayInt *arr(_arr); - DataArrayInt *arr2(const_cast(arr)); - arr2->incrRef(); - return arr2; -} - -DataArrayPartDefinition::DataArrayPartDefinition(DataArrayInt *listOfIds) -{ - CheckInternalArrayOK(listOfIds); - _arr=listOfIds; - _arr->incrRef(); -} - -void DataArrayPartDefinition::checkInternalArrayOK() const -{ - CheckInternalArrayOK(_arr); -} - -void DataArrayPartDefinition::CheckInternalArrayOK(const DataArrayInt *listOfIds) -{ - if(!listOfIds || !listOfIds->isAllocated() || listOfIds->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::CheckInternalArrayOK : Input list must be not null allocated and with one components !"); -} - -void DataArrayPartDefinition::updateTime() const -{ - if((const DataArrayInt *)_arr) - updateTimeWith(*_arr); -} - -std::size_t DataArrayPartDefinition::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(DataArrayPartDefinition); -} - -std::vector DataArrayPartDefinition::getDirectChildrenWithNull() const -{ - std::vector ret(1,(const DataArrayInt *)_arr); - return ret; -} - -DataArrayPartDefinition *DataArrayPartDefinition::add1(const DataArrayPartDefinition *other) const -{ - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); -} - -DataArrayPartDefinition *DataArrayPartDefinition::add2(const SlicePartDefinition *other) const -{ - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); -} - -DataArrayPartDefinition::~DataArrayPartDefinition() -{ -} - -SlicePartDefinition *SlicePartDefinition::New(int start, int stop, int step) -{ - return new SlicePartDefinition(start,stop,step); -} - -bool SlicePartDefinition::isEqual(const PartDefinition *other, std::string& what) const -{ - if(!other) - { - what="SlicePartDefinition::isEqual : other is null, this is not null !"; - return false; - } - const SlicePartDefinition *otherC(dynamic_cast(other)); - if(!otherC) - { - what="SlicePartDefinition::isEqual : other is not SlicePartDefinition !"; - return false; - } - bool ret((_start==otherC->_start) && (_stop==otherC->_stop) && (_step==otherC->_step)); - if(!ret) - { - what="SlicePartDefinition::isEqual : values are not the same !"; - return false; - } - return true; -} - -SlicePartDefinition *SlicePartDefinition::deepCpy() const -{ - return SlicePartDefinition::New(_start,_stop,_step); -} - -DataArrayInt *SlicePartDefinition::toDAI() const -{ - return DataArrayInt::Range(_start,_stop,_step); -} - -int SlicePartDefinition::getNumberOfElems() const -{ - return DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getNumberOfElems"); -} - -PartDefinition *SlicePartDefinition::operator+(const PartDefinition& other) const -{ - const PartDefinition *otherPt(&other); - if(!otherPt) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); - const DataArrayPartDefinition *other1(dynamic_cast(otherPt)); - if(other1) - return add1(other1); - const SlicePartDefinition *other2(dynamic_cast(otherPt)); - if(other2) - return add2(other2); - throw INTERP_KERNEL::Exception("SlicePartDefinition::operator+ : unrecognized type in input !"); -} - -/*! - * This method operates FoG where F is \a this and G is \a other. - * Example : if \a this is SlicePart(4,6,1) and if \a other is DataArrayPartDefinition([12,13,17,18,22,28,34,44]) -> DataArrayPartDefinition([22,28]) will be returned - */ -PartDefinition *SlicePartDefinition::composeWith(const PartDefinition *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("SlicePartDefinition::composeWith : input PartDef must be not NULL !"); - checkCoherency(); - other->checkCoherency(); - MEDCouplingAutoRefCountObjectPtr arr(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr arr1(arr->selectByTupleId2(_start,_stop,_step)); - return DataArrayPartDefinition::New(arr1); -} - -/*! - * Do nothing it is not a bug. - */ -void SlicePartDefinition::checkCoherency() const -{ -} - -/*! - * Return \a this (because it cannot be simplified) - * - * \return a new reference (equal to this) to be decrRefed. - */ -PartDefinition *SlicePartDefinition::tryToSimplify() const -{ - PartDefinition *ret(const_cast(this)); - ret->incrRef(); - return ret; -} - -void SlicePartDefinition::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - tinyInt.push_back(_start); - tinyInt.push_back(_stop); - tinyInt.push_back(_step); -} - -std::string SlicePartDefinition::getRepr() const -{ - std::ostringstream oss; - oss << "Slice is defined with : start=" << _start << " stop=" << _stop << " step=" << _step; - return oss.str(); -} - -int SlicePartDefinition::getEffectiveStop() const -{ - int nbElems(DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getEffectiveStop")); - return _start+nbElems*_step; -} - -void SlicePartDefinition::getSlice(int& start, int& stop, int& step) const -{ - start=_start; - stop=_stop; - step=_step; -} - -SlicePartDefinition::SlicePartDefinition(int start, int stop, int step):_start(start),_stop(stop),_step(step) -{ -} - -/*! - * No child ! It is the leaf ! So no implementation. - */ -void SlicePartDefinition::updateTime() const -{ -} - -std::size_t SlicePartDefinition::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(SlicePartDefinition); -} - -std::vector SlicePartDefinition::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -DataArrayPartDefinition *SlicePartDefinition::add1(const DataArrayPartDefinition *other) const -{ - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); -} - -PartDefinition *SlicePartDefinition::add2(const SlicePartDefinition *other) const -{ - if(_step==other->_step && getEffectiveStop()==other->_start) - { - return SlicePartDefinition::New(_start,other->_stop,_step); - } - else - { - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); - } -} - -SlicePartDefinition::~SlicePartDefinition() -{ -} diff --git a/medtool/src/MEDCoupling/MEDCouplingPartDefinition.hxx b/medtool/src/MEDCoupling/MEDCouplingPartDefinition.hxx deleted file mode 100644 index 49bc3d379..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingPartDefinition.hxx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ - class PartDefinition : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static PartDefinition *New(int start, int stop, int step); - MEDCOUPLING_EXPORT static PartDefinition *New(DataArrayInt *listOfIds); - MEDCOUPLING_EXPORT static PartDefinition *Unserialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - MEDCOUPLING_EXPORT virtual bool isEqual(const PartDefinition *other, std::string& what) const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *deepCpy() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *toDAI() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfElems() const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *operator+(const PartDefinition& other) const = 0; - MEDCOUPLING_EXPORT virtual std::string getRepr() const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *composeWith(const PartDefinition *other) const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *tryToSimplify() const = 0; - MEDCOUPLING_EXPORT virtual void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const = 0; - protected: - virtual ~PartDefinition(); - }; - - class SlicePartDefinition; - - class DataArrayPartDefinition : public PartDefinition - { - public: - MEDCOUPLING_EXPORT static DataArrayPartDefinition *New(DataArrayInt *listOfIds); - MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const; - MEDCOUPLING_EXPORT DataArrayPartDefinition *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; - MEDCOUPLING_EXPORT int getNumberOfElems() const; - MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; - MEDCOUPLING_EXPORT std::string getRepr() const; - MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const; - MEDCOUPLING_EXPORT void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - private: - DataArrayPartDefinition(DataArrayInt *listOfIds); - void checkInternalArrayOK() const; - static void CheckInternalArrayOK(const DataArrayInt *listOfIds); - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; - DataArrayPartDefinition *add2(const SlicePartDefinition *other) const; - virtual ~DataArrayPartDefinition(); - private: - MEDCouplingAutoRefCountObjectPtr _arr; - }; - - class SlicePartDefinition : public PartDefinition - { - public: - MEDCOUPLING_EXPORT static SlicePartDefinition *New(int start, int stop, int step); - MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const; - MEDCOUPLING_EXPORT SlicePartDefinition *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; - MEDCOUPLING_EXPORT int getNumberOfElems() const; - MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; - MEDCOUPLING_EXPORT std::string getRepr() const; - MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const; - MEDCOUPLING_EXPORT void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - //specific method - MEDCOUPLING_EXPORT int getEffectiveStop() const; - MEDCOUPLING_EXPORT void getSlice(int& start, int& stop, int& step) const; - private: - SlicePartDefinition(int start, int stop, int step); - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; - PartDefinition *add2(const SlicePartDefinition *other) const; - virtual ~SlicePartDefinition(); - private: - int _start; - int _stop; - int _step; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingPointSet.cxx b/medtool/src/MEDCoupling/MEDCouplingPointSet.cxx deleted file mode 100644 index 4793b7993..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingPointSet.cxx +++ /dev/null @@ -1,1695 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "PlanarIntersector.txx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "DirectedBoundingBox.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingPointSet::MEDCouplingPointSet():_coords(0) -{ -} - -MEDCouplingPointSet::MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy):MEDCouplingMesh(other),_coords(0) -{ - if(other._coords) - _coords=other._coords->performCpy(deepCopy); -} - -MEDCouplingPointSet::~MEDCouplingPointSet() -{ - if(_coords) - _coords->decrRef(); -} - -int MEDCouplingPointSet::getNumberOfNodes() const -{ - if(_coords) - return _coords->getNumberOfTuples(); - else - throw INTERP_KERNEL::Exception("Unable to get number of nodes because no coordinates specified !"); -} - -int MEDCouplingPointSet::getSpaceDimension() const -{ - if(_coords) - return _coords->getNumberOfComponents(); - else - throw INTERP_KERNEL::Exception("Unable to get space dimension because no coordinates specified !"); -} - -void MEDCouplingPointSet::updateTime() const -{ - if(_coords) - { - updateTimeWith(*_coords); - } -} - -std::size_t MEDCouplingPointSet::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingPointSet::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_coords); - return ret; -} - -void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) -{ - if( coords != _coords ) - { - if (_coords) - _coords->decrRef(); - _coords=const_cast(coords); - if(_coords) - _coords->incrRef(); - declareAsNew(); - } -} - -/*! - * Returns a pointer to the array of point coordinates held by \a this. - * \return DataArrayDouble * - the pointer to the array of point coordinates. The - * caller is to delete this array using decrRef() as it is no more needed. - */ -DataArrayDouble *MEDCouplingPointSet::getCoordinatesAndOwner() const -{ - if(_coords) - _coords->incrRef(); - return _coords; -} - -/*! - * Copies string attributes from an \a other mesh. The copied strings are - * - mesh name - * - mesh description - * - time units - * - textual data of the coordinates array (name and components info) - * - * \param [in] other - the mesh to copy string attributes from. - */ -void MEDCouplingPointSet::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - MEDCouplingMesh::copyTinyStringsFrom(other); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::copyTinyStringsFrom : meshes have not same type !"); - if(_coords && otherC->_coords) - _coords->copyStringInfoFrom(*otherC->_coords); -} - -bool MEDCouplingPointSet::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::isEqualIfNotWhy : null mesh instance in input !"); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingPointSet !"; - return false; - } - if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!areCoordsEqualIfNotWhy(*otherC,prec,reason)) - return false; - return true; -} - -/*! - * Checks equality of point coordinates with coordinates of an \a other mesh. - * None textual data is considered. - * \param [in] other - the mesh to compare coordinates with \a this one. - * \param [in] prec - precision value to compare coordinates. - * \return bool - \a true if coordinates of points are equal, \a false else. - */ -bool MEDCouplingPointSet::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!areCoordsEqualWithoutConsideringStr(*otherC,prec)) - return false; - return true; -} - -bool MEDCouplingPointSet::areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const -{ - if(_coords==0 && other._coords==0) - return true; - if(_coords==0 || other._coords==0) - { - reason="Only one PointSet between the two this and other has coordinate defined !"; - return false; - } - if(_coords==other._coords) - return true; - bool ret=_coords->isEqualIfNotWhy(*other._coords,prec,reason); - if(!ret) - reason.insert(0,"Coordinates DataArray do not match : "); - return ret; -} - -/*! - * Checks equality of point coordinates with \a other point coordinates. - * Textual data (name and components info) \b is compared as well. - * \param [in] other - the point coordinates to compare with \a this one. - * \param [in] prec - precision value to compare coordinates. - * \return bool - \a true if coordinates of points are equal, \a false else. - */ -bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, double prec) const -{ - std::string tmp; - return areCoordsEqualIfNotWhy(other,prec,tmp); -} - -/*! - * Checks equality of point coordinates with \a other point coordinates. - * None textual data is considered. - * \param [in] other - the point coordinates to compare with \a this one. - * \param [in] prec - precision value to compare coordinates. - * \return bool - \a true if coordinates of points are equal, \a false else. - */ -bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const -{ - if(_coords==0 && other._coords==0) - return true; - if(_coords==0 || other._coords==0) - return false; - if(_coords==other._coords) - return true; - return _coords->isEqualWithoutConsideringStr(*other._coords,prec); -} - -/*! - * Returns coordinates of \a nodeId-th node. - * \param [in] nodeId - the ID of the node of interest. - * \param [in, out] coo - the array filled with coordinates of the \a nodeId-th - * node. This array is not cleared before filling in, the coordinates are - * appended to its end. - * \throw If the coordinates array is not set. - * \throw If \a nodeId is not a valid index for the coordinates array. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getcoordinatesofnode "Here is a C++ example".
- * \ref py_mcpointset_getcoordinatesofnode "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCoordinatesOfNode : no coordinates array set !"); - int nbNodes=getNumberOfNodes(); - if(nodeId>=0 && nodeIdgetConstPointer(); - int spaceDim=getSpaceDimension(); - coo.insert(coo.end(),cooPtr+spaceDim*nodeId,cooPtr+spaceDim*(nodeId+1)); - } - else - { - std::ostringstream oss; oss << "MEDCouplingPointSet::getCoordinatesOfNode : request of nodeId \"" << nodeId << "\" but it should be in [0,"<< nbNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Finds nodes equal within \a precision and returns an array describing the - * permutation to remove duplicated nodes. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [in] limitNodeId - limit node id. If all nodes within a group of coincident - * nodes have id strictly lower than \a limitTupleId then they are not - * returned. Put -1 to this parameter to have all nodes returned. - * \param [out] areNodesMerged - is set to \a true if any coincident nodes found. - * \param [out] newNbOfNodes - returns number of unique nodes. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref numbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - */ -DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const -{ - DataArrayInt *comm,*commI; - findCommonNodes(precision,limitNodeId,comm,commI); - int oldNbOfNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); - areNodesMerged=(oldNbOfNodes!=newNbOfNodes); - comm->decrRef(); - commI->decrRef(); - return ret.retn(); -} - -/*! - * Finds nodes coincident within \a prec tolerance. - * Ids of coincident nodes are stored in output arrays in the \ref numbering-indirect format. - * \param [in] prec - minimal absolute distance (using infinite norm) between two nodes at which they are - * considered not coincident. - * \param [in] limitNodeId - limit node id. If all nodes within a group of coincident - * nodes have id strictly lower than \a limitTupleId then they are not - * returned. Put -1 to this parameter to have all nodes treated. - * \param [out] comm - the array holding ids of coincident nodes. - * \a comm->getNumberOfComponents() == 1. - * \a comm->getNumberOfTuples() == \a commIndex->back(). The caller - * is to delete this array using decrRef() as it is no more needed. - * \param [out] commIndex - the array dividing all ids stored in \a comm into - * groups of (ids of) coincident nodes (\ref numbering-indirect). Its every value is a tuple - * index where a next group of nodes begins. For example the second - * group of nodes in \a comm is described by following range of indices: - * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1 - * gives the number of groups of coincident nodes. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_findcommonnodes "Here is a C++ example".
- * \ref py_mcpointset_findcommonnodes "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findCommonNodes : no coords specified !"); - _coords->findCommonTuples(prec,limitNodeId,comm,commIndex); -} - -/*! - * Finds nodes located at distances lower that \a eps from a given point. - * \param [in] pos - pointer to coordinates of the point. This array is expected to - * be of length \a this->getSpaceDimension() at least, else the - * behavior is not warranted. - * \param [in] eps - the lowest distance between a point and a node (using infinite norm) at which the node is - * not returned by this method. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of nodes - * close to the point. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getnodeidsnearpoint "Here is a C++ example".
- * \ref py_mcpointset_getnodeidsnearpoint "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const -{ - DataArrayInt *c=0,*cI=0; - getNodeIdsNearPoints(pos,1,eps,c,cI); - MEDCouplingAutoRefCountObjectPtr cITmp(cI); - return c; -} - -/*! - * Finds nodes located at distances lower that \a eps from given points. - * \param [in] pos - pointer to coordinates of the points. This array is expected to - * be of length \a nbOfPoints * \a this->getSpaceDimension() at least, else the - * behavior is not warranted. - * \param [in] nbOfPoints - number of points whose coordinates are given by \a pos - * parameter. - * \param [in] eps - the lowest distance between (using infinite norm) a point and a node at which the node is - * not returned by this method. - * \param [out] c - array (\ref numbering-indirect) returning ids of nodes located closer than \a eps to the - * given points. The caller - * is to delete this array using decrRef() as it is no more needed. - * \param [out] cI - for each i-th given point, the array specifies tuples of \a c - * holding ids of nodes close to the i-th point (\ref numbering-indirect).
The i-th value of \a cI is an - * index of tuple of \a c holding id of a first (if any) node close to the - * i-th given point. Difference between the i-th and (i+1)-th value of \a cI - * (i.e. \a cI[ i+1 ] - \a cI[ i ]) defines number of nodes close to the i-th - * point (that can be zero!). For example, the group of nodes close to the - * second point is described by following range of indices [ \a cI[1], \a cI[2] ). - * The caller is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getnodeidsnearpoints "Here is a C++ example".
- * \ref py_mcpointset_getnodeidsnearpoints "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !"); - int spaceDim=getSpaceDimension(); - MEDCouplingAutoRefCountObjectPtr points=DataArrayDouble::New(); - points->useArray(pos,false,CPP_DEALLOC,nbOfPoints,spaceDim); - _coords->computeTupleIdsNearTuples(points,eps,c,cI); -} - -/*! - * @param comm in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect). - * @param commI in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect). - * @return the old to new correspondance array. - */ -DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, - int& newNbOfNodes) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !"); - return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); -} - -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::renumberNodes : no coords specified !"); - MEDCouplingAutoRefCountObjectPtr newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes); - renumberNodesInConn(newNodeNumbers); - setCoords(newCoords);//let it here not before renumberNodesInConn because old number of nodes is sometimes used... -} - -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. In contrast to renumberNodes(), location - * of merged nodes (whose new ids coincide) is changed to be at their barycenter. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is - * actually one more than the maximal id in \a newNodeNumbers. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) -{ - DataArrayDouble *newCoords=DataArrayDouble::New(); - std::vector div(newNbOfNodes); - int spaceDim=getSpaceDimension(); - newCoords->alloc(newNbOfNodes,spaceDim); - newCoords->copyStringInfoFrom(*_coords); - newCoords->fillWithZero(); - int oldNbOfNodes=getNumberOfNodes(); - double *ptToFill=newCoords->getPointer(); - const double *oldCoordsPtr=_coords->getConstPointer(); - for(int i=0;i()); - div[newNodeNumbers[i]]++; - } - for(int i=0;i(),1./(double)div[i])); - setCoords(newCoords); - newCoords->decrRef(); - renumberNodesInConn(newNodeNumbers); -} - -/*! - * Computes the minimum box bounding all nodes. The edges of the box are parallel to - * the Cartesian coordinate axes. The bounding box is described by coordinates of its - * two extremum points with minimal and maximal coordinates. - * \param [out] bbox - array filled with coordinates of extremum points in "no - * interlace" mode, i.e. xMin, xMax, yMin, yMax, zMin, zMax (if in 3D). This - * array, of length 2 * \a this->getSpaceDimension() at least, is to be - * pre-allocated by the caller. - * \throw If the coordinates array is not set. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getBoundingBox "Here is a C++ example".
- * \ref py_mcpointset_getBoundingBox "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::getBoundingBox(double *bbox) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getBoundingBox : Coordinates not set !"); - _coords->getMinMaxPerComponent(bbox); -} - -/*! - * Removes "free" nodes, i.e. nodes not used to define any element. - * \throw If the coordinates array is not set. - * \throw If the elements are not defined. - */ -void MEDCouplingPointSet::zipCoords() -{ - checkFullyDefined(); - DataArrayInt *traducer=zipCoordsTraducer(); - traducer->decrRef(); -} - -/*! \cond HIDDEN_ITEMS */ -struct MEDCouplingCompAbs -{ - bool operator()(double x, double y) { return std::abs(x)getConstPointer(); - int nbOfValues=_coords->getNbOfElems(); - return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs())); -} - -/*! - * This method recenter coordinates of nodes in \b this in order to be centered at the origin to benefit about the advantages of the precision to be around the box - * around origin of 'radius' 1. - * - * \warning this method is non const and alterates coordinates in \b this without modifying. - * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed. - * - */ -void MEDCouplingPointSet::recenterForMaxPrecision(double eps) -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::recenterForMaxPrecision : Coordinates not set !"); - _coords->recenterForMaxPrecision(eps); - updateTime(); -} - -/*! - * Rotates \a this set of nodes by \a angle around either an axis (in 3D) or a point - * (in 2D). - * \param [in] center - coordinates either of an origin of rotation axis (in 3D) or - * of center of rotation (in 2D). This array is to be of size \a - * this->getSpaceDimension() at least. - * \param [in] vector - 3 components of a vector defining direction of the rotation - * axis in 3D. In 2D this parameter is not used. - * \param [in] angle - the rotation angle in radians. - * \throw If the coordinates array is not set. - * \throw If \a this->getSpaceDimension() != 2 && \a this->getSpaceDimension() != 3. - * \throw If \a center == NULL - * \throw If \a vector == NULL && \a this->getSpaceDimension() == 3. - * \throw If Magnitude of \a vector is zero. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_rotate "Here is a C++ example".
- * \ref py_mcpointset_rotate "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::rotate(const double *center, const double *vector, double angle) -{ - int spaceDim=getSpaceDimension(); - if(spaceDim==3) - rotate3D(center,vector,angle); - else if(spaceDim==2) - rotate2D(center,angle); - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::rotate : invalid space dim for rotation must be 2 or 3"); - _coords->declareAsNew(); - updateTime(); -} - -/*! - * Translates \a this set of nodes. - * \param [in] vector - components of a translation vector. This array is to be of - * size \a this->getSpaceDimension() at least. - * \throw If the coordinates array is not set. - * \throw If \a vector == NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_translate "Here is a C++ example".
- * \ref py_mcpointset_translate "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::translate(const double *vector) -{ - if(!vector) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::translate : NULL input vector !"); - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::translate : no coordinates set !"); - double *coords=_coords->getPointer(); - int nbNodes=getNumberOfNodes(); - int dim=getSpaceDimension(); - for(int i=0; ideclareAsNew(); - updateTime(); -} - - -/*! - * Applies scaling transformation to \a this set of nodes. - * \param [in] point - coordinates of a scaling center. This array is to be of - * size \a this->getSpaceDimension() at least. - * \param [in] factor - a scale factor. - * \throw If the coordinates array is not set. - * \throw If \a point == NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_scale "Here is a C++ example".
- * \ref py_mcpointset_scale "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::scale(const double *point, double factor) -{ - if(!point) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::scale : NULL input point !"); - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::scale : no coordinates set !"); - double *coords=_coords->getPointer(); - int nbNodes=getNumberOfNodes(); - int dim=getSpaceDimension(); - for(int i=0;i()); - std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies(),factor)); - std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus()); - } - _coords->declareAsNew(); - updateTime(); -} - -/*! - * Converts \a this set of points to an other dimension by changing number of - * components of point coordinates. If the dimension increases, added components - * are filled with \a dftValue. If the dimension decreases, last components are lost. - * If the new dimension is same as \a this->getSpaceDimension(), nothing is done. - * \param [in] newSpaceDim - the new space dimension. - * \param [in] dftValue - the value to assign to added components of point coordinates - * (if the dimension increases). - * \throw If the coordinates array is not set. - * \throw If \a newSpaceDim < 1. - */ -void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim, double dftValue) -{ - if(getCoords()==0) - throw INTERP_KERNEL::Exception("changeSpaceDimension must be called on an MEDCouplingPointSet instance with coordinates set !"); - if(newSpaceDim<1) - throw INTERP_KERNEL::Exception("changeSpaceDimension must be called a newSpaceDim >=1 !"); - int oldSpaceDim=getSpaceDimension(); - if(newSpaceDim==oldSpaceDim) - return ; - DataArrayDouble *newCoords=getCoords()->changeNbOfComponents(newSpaceDim,dftValue); - setCoords(newCoords); - newCoords->decrRef(); - updateTime(); -} - -/*! - * Substitutes \a this->_coords with \a other._coords provided that coordinates of - * the two point sets match with a specified precision, else an exception is thrown. - * \param [in] other - the other point set whose coordinates array will be used by - * \a this point set in case of their equality. - * \param [in] epsilon - the precision used to compare coordinates. - * \throw If the coordinates array of \a this is not set. - * \throw If the coordinates array of \a other is not set. - * \throw If the coordinates of \a this and \a other do not match. - */ -void MEDCouplingPointSet::tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) -{ - if(_coords==other._coords) - return ; - if(!_coords) - throw INTERP_KERNEL::Exception("Current instance has no coords whereas other has !"); - if(!other._coords) - throw INTERP_KERNEL::Exception("Other instance has no coords whereas current has !"); - if(!_coords->isEqualWithoutConsideringStr(*other._coords,epsilon)) - throw INTERP_KERNEL::Exception("Coords are not the same !"); - setCoords(other._coords); -} - -/*! - * This method duplicates the nodes whose ids are in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) and put the result of their duplication at the end - * of existing node ids. - * - * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only - * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - */ -void MEDCouplingPointSet::duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : no coords set !"); - MEDCouplingAutoRefCountObjectPtr newCoords=_coords->selectByTupleIdSafe(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); - MEDCouplingAutoRefCountObjectPtr newCoords2=DataArrayDouble::Aggregate(_coords,newCoords); - setCoords(newCoords2); -} - -/*! - * Finds nodes located at distance lower that \a eps from a specified plane. - * \param [in] pt - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a normal vector to the plane. Vector magnitude - * must be greater than 10*\a eps. - * \param [in] eps - maximal distance of a node from the plane at which the node is - * considered to lie on the plane. - * \param [in,out] nodes - a vector returning ids of found nodes. This vector is not - * cleared before filling in. - * \throw If the coordinates array is not set. - * \throw If \a pt == NULL. - * \throw If \a vec == NULL. - * \throw If the magnitude of \a vec is zero. - * \throw If \a this->getSpaceDimension() != 3. - */ -void MEDCouplingPointSet::findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const -{ - if(getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : Invalid spacedim to be applied on this ! Must be equal to 3 !"); - if(!pt) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : NULL point pointer specified !"); - if(!vec) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : NULL vector pointer specified !"); - int nbOfNodes=getNumberOfNodes(); - double a=vec[0],b=vec[1],c=vec[2],d=-pt[0]*vec[0]-pt[1]*vec[1]-pt[2]*vec[2]; - double deno=sqrt(a*a+b*b+c*c); - if(deno::min()) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : vector pointer specified has norm equal to 0. !"); - const double *work=_coords->getConstPointer(); - for(int i=0;igetSpaceDimension() at least. - * \param [in] vec - components of a vector defining the line direction. This array - * is to be of size \a this->getSpaceDimension() at least. Vector magnitude - * must be greater than 10*\a eps. - * \param [in] eps - maximal distance of a node from the line at which the node is - * considered to lie on the line. - * \param [in,out] nodes - a vector returning ids of found nodes. This vector is not - * cleared before filling in. - * \throw If the coordinates array is not set. - * \throw If \a pt == NULL. - * \throw If \a vec == NULL. - * \throw If the magnitude of \a vec is zero. - * \throw If ( \a this->getSpaceDimension() != 3 && \a this->getSpaceDimension() != 2 ). - */ -void MEDCouplingPointSet::findNodesOnLine(const double *pt, const double *vec, double eps, std::vector& nodes) const -{ - int spaceDim=getSpaceDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : Invalid spacedim to be applied on this ! Must be equal to 2 or 3 !"); - if(!pt) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : NULL point pointer specified !"); - if(!vec) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : NULL vector pointer specified !"); - int nbOfNodes=getNumberOfNodes(); - double den=0.; - for(int i=0;i vecn=new double[spaceDim]; - for(int i=0;igetConstPointer(); - if(spaceDim==2) - { - for(int i=0;igetSpaceDimension() != \a m2->getSpaceDimension(). - */ -DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) -{ - int spaceDim=m1->getSpaceDimension(); - if(spaceDim!=m2->getSpaceDimension()) - throw INTERP_KERNEL::Exception("Mismatch in SpaceDim during call of MergeNodesArray !"); - return DataArrayDouble::Aggregate(m1->getCoords(),m2->getCoords()); -} - -DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const std::vector& ms) -{ - if(ms.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : input array must be NON EMPTY !"); - std::vector::const_iterator it=ms.begin(); - std::vector coo(ms.size()); - int spaceDim=(*it)->getSpaceDimension(); - coo[0]=(*it++)->getCoords(); - if(!coo[0]->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : first element in coordinates is not allocated !"); - for(int i=1;it!=ms.end();it++,i++) - { - const DataArrayDouble *tmp=(*it)->getCoords(); - if(tmp) - { - if(tmp->isAllocated()) - { - if((*it)->getSpaceDimension()==spaceDim) - coo[i]=tmp; - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Mismatch in SpaceDim !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Presence of a non allocated array !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Empty coords detected !"); - } - return DataArrayDouble::Aggregate(coo); -} - -/*! - * Factory to build new instance of instanciable subclasses of MEDCouplingPointSet. - * This method is used during unserialization process. - */ -MEDCouplingPointSet *MEDCouplingPointSet::BuildInstanceFromMeshType(MEDCouplingMeshType type) -{ - switch(type) - { - case UNSTRUCTURED: - return MEDCouplingUMesh::New(); - case SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED: - return MEDCoupling1SGTUMesh::New(); - case SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED: - return MEDCoupling1DGTUMesh::New(); - default: - throw INTERP_KERNEL::Exception("Invalid type of mesh specified"); - } -} - -/*! - * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process. - */ -void MEDCouplingPointSet::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time=getTime(it,order); - if(_coords) - { - int spaceDim=getSpaceDimension(); - littleStrings.resize(spaceDim+4); - littleStrings[0]=getName(); - littleStrings[1]=getDescription(); - littleStrings[2]=_coords->getName(); - littleStrings[3]=getTimeUnit(); - for(int i=0;igetInfoOnComponent(i); - tinyInfo.clear(); - tinyInfo.push_back(getType()); - tinyInfo.push_back(spaceDim); - tinyInfo.push_back(getNumberOfNodes()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfoD.push_back(time); - } - else - { - littleStrings.resize(3); - littleStrings[0]=getName(); - littleStrings[1]=getDescription(); - littleStrings[2]=getTimeUnit(); - tinyInfo.clear(); - tinyInfo.push_back(getType()); - tinyInfo.push_back(-1); - tinyInfo.push_back(-1); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfoD.push_back(time); - } -} - -/*! - * Third and final step of serialization process. - */ -void MEDCouplingPointSet::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - if(_coords) - { - a2=const_cast(getCoords()); - a2->incrRef(); - } - else - a2=0; -} - -/*! - * Second step of serialization process. - * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. - */ -void MEDCouplingPointSet::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - if(tinyInfo[2]>=0 && tinyInfo[1]>=1) - { - a2->alloc(tinyInfo[2],tinyInfo[1]); - littleStrings.resize(tinyInfo[1]+4); - } - else - { - littleStrings.resize(3); - } -} - -/*! - * Second and final unserialization process. - * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. - */ -void MEDCouplingPointSet::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) -{ - if(tinyInfo[2]>=0 && tinyInfo[1]>=1) - { - setCoords(a2); - setName(littleStrings[0]); - setDescription(littleStrings[1]); - a2->setName(littleStrings[2]); - setTimeUnit(littleStrings[3]); - for(int i=0;isetInfoOnComponent(i,littleStrings[i+4]); - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); - } - else - { - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); - } -} - -void MEDCouplingPointSet::checkCoherency() const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !"); -} - -/*! - * Intersect Bounding Box given 2 Bounding Boxes. - */ -bool MEDCouplingPointSet::intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps) -{ - double* bbtemp = new double[2*dim]; - double deltamax=0.0; - - for (int i=0; i< dim; i++) - { - double delta = bb1[2*i+1]-bb1[2*i]; - if ( delta > deltamax ) - { - deltamax = delta ; - } - } - for (int i=0; i deltamax ) - { - deltamax = delta ; - } - } - for (int i=0; igetPointer(); - int nbNodes=getNumberOfNodes(); - Rotate3DAlg(center,vect,angle,nbNodes,coords); -} - -/*! - * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords' - * around an axe ('center','vect') and with angle 'angle'. - */ -void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords) -{ - if(!center || !vect) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : null vector in input !"); - double sina=sin(angle); - double cosa=cos(angle); - double vectorNorm[3]; - double matrix[9]; - double matrixTmp[9]; - double norm=sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]); - if(norm::min()) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : magnitude of input vector is too close of 0. !"); - std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies(),1/norm)); - //rotation matrix computation - matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa; - matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2]; - matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2]; - matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2]; - std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies(),1-cosa)); - std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus()); - matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1]; - matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0]; - matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.; - std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies(),sina)); - std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus()); - //rotation matrix computed. - double tmp[3]; - for(int i=0; i()); - coords[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0]; - coords[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1]; - coords[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2]; - } -} - -/*! - * This method allows to give for each cell in \a trgMesh, how much it interacts with cells of \a srcMesh. - * The returned array can be seen as a weighted array on the target cells of \a trgMesh input parameter. - * - * \param [in] srcMesh - source mesh - * \param [in] trgMesh - target mesh - * \param [in] eps - precision of the detection - * \return DataArrayInt * - An array that gives for each cell of \a trgMesh, how many cells in \a srcMesh (regarding the precision of detection \a eps) can interacts. - * - * \throw If \a srcMesh and \a trgMesh have not the same space dimension. - */ -DataArrayInt *MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) -{ - if(!srcMesh || !trgMesh) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells : the input meshes must be not NULL !"); - MEDCouplingAutoRefCountObjectPtr sbbox(srcMesh->getBoundingBoxForBBTree()),tbbox(trgMesh->getBoundingBoxForBBTree()); - return tbbox->computeNbOfInteractionsWith(sbbox,eps); -} - -/*! - * Creates a new MEDCouplingMesh containing a part of cells of \a this mesh. The new - * mesh shares a coordinates array with \a this one. The cells to include to the - * result mesh are specified by an array of cell ids. - * \param [in] start - an array of cell ids to include to the result mesh. - * \param [in] end - specifies the end of the array \a start, so that - * the last value of \a start is \a end[ -1 ]. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end) const -{ - return buildPartOfMySelf(start,end,true); -} - -/*! - * Creates a new MEDCouplingMesh containing a part of cells of \a this mesh. The - * cells to include to the result mesh are specified by an array of cell ids. - *
This method additionally returns a renumbering map in "Old to New" mode - * which allows the caller to know the mapping between nodes in \a this and the result mesh. - * \param [in] start - an array of cell ids to include to the result mesh. - * \param [in] end - specifies the end of the array \a start, so that - * the last value of \a start is \a end[ -1 ]. - * \param [out] arr - a new DataArrayInt that is the "Old to New" renumbering - * map. The caller is to delete this array using decrRef() as it is no more needed. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf(start,end,true); - arr=ret->zipCoordsTraducer(); - return ret.retn(); -} - -/*! - * This method specialized the MEDCouplingMesh::buildPartRange. - * This method is equivalent to MEDCouplingMesh::buildPart method except that here the cell ids are specified using slice - * \a beginCellIds \a endCellIds and \a stepCellIds. - * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method. - * If the input range is equal all cells in \a this, \a this is returned ! - * - * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order. - * - * \sa MEDCouplingUMesh::buildPartOfMySelf2 - */ -MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const -{ - if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1) - { - MEDCouplingMesh *ret(const_cast(this)); - ret->incrRef(); - return ret; - } - else - { - return buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true); - } -} - -/*! - * This method specialized the MEDCouplingMesh::buildPartRangeAndReduceNodes - * - * \param [out] beginOut valid only if \a arr not NULL ! - * \param [out] endOut valid only if \a arr not NULL ! - * \param [out] stepOut valid only if \a arr not NULL ! - * \param [out] arr correspondance old to new in node ids. - * - * \sa MEDCouplingUMesh::buildPartOfMySelf2 - */ -MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true); - arr=ret->zipCoordsTraducer(); - return ret.retn(); -} - -/*! - * 'This' is expected to be of spaceDim==2. Idem for 'center' and 'vect' - */ -void MEDCouplingPointSet::rotate2D(const double *center, double angle) -{ - double *coords=_coords->getPointer(); - int nbNodes=getNumberOfNodes(); - Rotate2DAlg(center,angle,nbNodes,coords); -} - -/*! - * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords' - * around the center point 'center' and with angle 'angle'. - */ -void MEDCouplingPointSet::Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords) -{ - double cosa=cos(angle); - double sina=sin(angle); - double matrix[4]; - matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa; - double tmp[2]; - for(int i=0; i()); - coords[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0]; - coords[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1]; - } -} - -/// @cond INTERNAL - -class DummyClsMCPS -{ -public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=2; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -}; - -/// @endcond - -/*! - * res should be an empty vector before calling this method. - * This method returns all the node coordinates included in _coords which ids are in [startConn;endConn) and put it into 'res' vector. - * If spaceDim==3 a projection will be done for each nodes on the middle plane containing these all nodes in [startConn;endConn). - * And after each projected nodes are moved to Oxy plane in order to consider these nodes as 2D nodes. - */ -void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *endConn, std::vector& res) const -{ - const double *coords=_coords->getConstPointer(); - int spaceDim=getSpaceDimension(); - for(const int *it=startConn;it!=endConn;it++) - res.insert(res.end(),coords+spaceDim*(*it),coords+spaceDim*(*it+1)); - if(spaceDim==2) - return ; - if(spaceDim==3) - { - std::vector cpy(res); - int nbNodes=(int)std::distance(startConn,endConn); - INTERP_KERNEL::PlanarIntersector::Projection(&res[0],&cpy[0],nbNodes,nbNodes,1.e-12,0./*max distance*/,-1./*min dot*/,0.,true); - res.resize(2*nbNodes); - for(int i=0;i& res, bool isQuad, double eps) -{ - std::size_t nbOfNodes=res.size()/2; - std::vector nodes(nbOfNodes); - for(std::size_t i=0;iisButterflyAbs(); - delete pol; - return ret; -} - -/*! - * This method compares 2 cells coming from two unstructured meshes : \a this and \a other. - * This method compares 2 cells having the same id 'cellId' in \a this and \a other. - */ -bool MEDCouplingPointSet::areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const -{ - if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) - return false; - std::vector c1,c2; - getNodeIdsOfCell(cellId,c1); - other->getNodeIdsOfCell(cellId,c2); - std::size_t sz=c1.size(); - if(sz!=c2.size()) - return false; - for(std::size_t i=0;i n1,n2; - getCoordinatesOfNode(c1[0],n1); - other->getCoordinatesOfNode(c2[0],n2); - std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus()); - std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun(fabs)); - if(*std::max_element(n1.begin(),n1.end())>prec) - return false; - } - return true; -} - -/*! - * Substitutes node coordinates array of \a this mesh with that of \a other mesh - * (i.e. \a this->_coords with \a other._coords) provided that coordinates of the two - * meshes match with a specified precision, else an exception is thrown and \a this - * remains unchanged. In case of success the nodal connectivity of \a this mesh - * is permuted according to new order of nodes. - * Contrary to tryToShareSameCoords() this method makes a deeper analysis of - * coordinates (and so more expensive) than simple equality. - * \param [in] other - the other mesh whose node coordinates array will be used by - * \a this mesh in case of their equality. - * \param [in] epsilon - the precision used to compare coordinates (using infinite norm). - * \throw If the coordinates array of \a this is not set. - * \throw If the coordinates array of \a other is not set. - * \throw If the coordinates of \a this and \a other do not match. - */ -void MEDCouplingPointSet::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) -{ - const DataArrayDouble *coords=other.getCoords(); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in other !"); - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !"); - int otherNbOfNodes=other.getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr newCoords=MergeNodesArray(&other,this); - _coords->incrRef(); - MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; - setCoords(newCoords); - bool areNodesMerged; - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes); - if(!areNodesMerged) - { - setCoords(oldCoords); - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !"); - } - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes); - const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - setCoords(oldCoords); - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : some nodes in this are not in other !"); - } - setCoords(oldCoords); - renumberNodesInConn(da->getConstPointer()+otherNbOfNodes); - setCoords(coords); -} - -MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelfKeepCoords(begin,end); - if(!keepCoords) - ret->zipCoords(); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelfKeepCoords2(start,end,step); - if(!keepCoords) - ret->zipCoords(); - return ret.retn(); -} - -/*! - Creates a new MEDCouplingUMesh containing some cells of \a this mesh. The cells to - copy are selected basing on specified node ids and the value of \a fullyIn - parameter. If \a fullyIn ==\c true, a cell is copied if its all nodes are in the - array \a begin of node ids. If \a fullyIn ==\c false, a cell is copied if any its - node is in the array of node ids. The created mesh shares the node coordinates array - with \a this mesh. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are copied, else cells whose any node is in the - * array \a begin are copied. - * \return MEDCouplingPointSet * - new instance of MEDCouplingUMesh. The caller is - * to delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any node id in \a begin is not valid. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildPartOfMySelfNode "Here is a C++ example".
- * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - MEDCouplingAutoRefCountObjectPtr cellIdsKept2(cellIdsKept); - return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); -} - -/*! - * Removes duplicates of cells from \a this mesh and returns an array mapping between - * new and old cell ids in "Old to New" mode. Nothing is changed in \a this mesh if no - * equal cells found. - * \warning Cells of the result mesh are \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in] compType - specifies a cell comparison technique. Meaning of its - * valid values [0,1,2] is as follows. - * - 0 : "exact". Two cells are considered equal \c iff they have exactly same nodal - * connectivity and type. This is the strongest policy. - * - 1 : "permuted same orientation". Two cells are considered equal \c iff they - * are based on same nodes and have the same type and orientation. - * - 2 : "nodal". Two cells are considered equal \c iff they - * are based on same nodes and have the same type. This is the weakest - * policy, it can be used by users not sensitive to cell orientation. - * \param [in] startCellId - specifies the cell id at which search for equal cells - * starts. By default it is 0, which means that all cells in \a this will be - * scanned. - * \return DataArrayInt - a new instance of DataArrayInt, of length \a - * this->getNumberOfCells() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int startCellId) -{ - DataArrayInt *commonCells=0,*commonCellsI=0; - findCommonCells(compType,startCellId,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - int newNbOfCells=-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), - commonCellsI->end(),newNbOfCells); - MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2O(newNbOfCells); - MEDCouplingAutoRefCountObjectPtr self=buildPartOfMySelf(ret2->begin(),ret2->end(),true); - shallowCopyConnectivityFrom(self); - return ret.retn(); -} - -/*! - * This const method states if the nodal connectivity of this fetches all nodes in \a this. - * In other words, this method looks is there are no orphan nodes in \a this. - * \sa zipCoordsTraducer, getNodeIdsInUse, computeFetchedNodeIds. - */ -bool MEDCouplingPointSet::areAllNodesFetched() const -{ - checkFullyDefined(); - int nbNodes(getNumberOfNodes()); - std::vector fetchedNodes(nbNodes,false); - computeNodeIdsAlg(fetchedNodes); - return std::find(fetchedNodes.begin(),fetchedNodes.end(),false)==fetchedNodes.end(); -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are - * considered equivalent if (1) \a this mesh contains the same nodes as the \a other - * mesh (with a specified precision) and (2) \a this mesh contains the same cells as - * the \a other mesh (with use of a specified cell comparison technique). The mapping - * from \a other to \a this for nodes and cells is returned via out parameters. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of - * each method in description of MEDCouplingPointSet::zipConnectivityTraducer(). - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : input is null !"); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : other is not a PointSet mesh !"); - MEDCouplingAutoRefCountObjectPtr m=dynamic_cast(mergeMyselfWith(otherC)); - bool areNodesMerged; - int newNbOfNodes; - int oldNbOfNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes); - //mergeNodes - if(!areNodesMerged && oldNbOfNodes != 0) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); - const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),oldNbOfNodes-1)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !"); - m->renumberNodes(da->getConstPointer(),newNbOfNodes); - // - MEDCouplingAutoRefCountObjectPtr nodeCor2=da->substr(oldNbOfNodes); - da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); - // - da=m->zipConnectivityTraducer(cellCompPol); - int nbCells=getNumberOfCells(); - if (nbCells != other->getNumberOfCells()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - int dan(da->getNumberOfTuples()); - if (dan) - { - MEDCouplingAutoRefCountObjectPtr da1(DataArrayInt::New()),da2(DataArrayInt::New()); - da1->alloc(dan/2,1); da2->alloc(dan/2,1); - std::copy(da->getConstPointer(), da->getConstPointer()+dan/2, da1->getPointer()); - std::copy(da->getConstPointer()+dan/2, da->getConstPointer()+dan, da2->getPointer()); - da1->sort(); da2->sort(); - if (!da1->isEqualWithoutConsideringStr(*da2)) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - } - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(nbCells,da->getNbOfElems(),1); - nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn(); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are considered equivalent if (1) they share one - * node coordinates array and (2) they contain the same cells (with use of a specified - * cell comparison technique). The mapping from cells of the \a other to ones of \a this - * is returned via an out parameter. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of - * each method in description of MEDCouplingPointSet::zipConnectivityTraducer(). - * \param [in] prec - a not used parameter. - * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : input is null !"); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : other is not a PointSet mesh !"); - if(_coords!=otherC->_coords) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); - MEDCouplingAutoRefCountObjectPtr m=mergeMyselfWithOnSameCoords(otherC); - MEDCouplingAutoRefCountObjectPtr da=m->zipConnectivityTraducer(cellCompPol); - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); - const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); - } - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - -void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingMesh::checkFastEquivalWith(other,prec); - //other not null checked by the line before - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkFastEquivalWith : fails because other is not a pointset mesh !"); - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return ; - bool status=true; - status&=areCellsFrom2MeshEqual(otherC,0,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); - if(!status) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); -} - -/*! - * Finds cells whose all or some nodes are in a given array of node ids. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are returned only, else cells whose any node is in the - * array \a begin are returned. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * cells. The caller is to delete this array using decrRef() as it is no more - * needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in \a begin is not valid. - * - * \sa MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellIdsLyingOnNodes "Here is a C++ example".
- * \ref py_mcumesh_getCellIdsLyingOnNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - cellIdsKept->setName(getName()); - return cellIdsKept; -} - -/*! - * Finds cells whose all nodes are in a given array of node ids. - * This method is a specialization of MEDCouplingPointSet::getCellIdsLyingOnNodes (true - * as last input argument). - * \param [in] partBg - the array of node ids. - * \param [in] partEnd - a pointer to a (last+1)-th element of \a partBg. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * cells. The caller is to delete this array using decrRef() as it is no - * more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in \a partBg is not valid. - * - * \sa MEDCouplingPointSet::getCellIdsLyingOnNodes - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a C++ example".
- * \ref py_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const -{ - return getCellIdsLyingOnNodes(partBg,partEnd,true); -} - -/*! - * Removes unused nodes (the node coordinates array is shorten) and returns an array - * mapping between new and old node ids in "Old to New" mode. -1 values in the returned - * array mean that the corresponding old node is no more used. - * \return DataArrayInt * - a new instance of DataArrayInt of length \a - * this->getNumberOfNodes() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() -{ - int newNbOfNodes=-1; - MEDCouplingAutoRefCountObjectPtr traducer=getNodeIdsInUse(newNbOfNodes); - renumberNodes(traducer->getConstPointer(),newNbOfNodes); - return traducer.retn(); -} - -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref numbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes(ret->begin(),newNbOfNodes); - return ret.retn(); -} - -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location - * of merged nodes is changed to be at their barycenter. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref numbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes2(ret->getConstPointer(),newNbOfNodes); - return ret; -} diff --git a/medtool/src/MEDCoupling/MEDCouplingPointSet.hxx b/medtool/src/MEDCoupling/MEDCouplingPointSet.hxx deleted file mode 100644 index 21c830d2f..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingPointSet.hxx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGPOINTSET_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGPOINTSET_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMesh.hxx" - -#include "InterpKernelHashMap.hxx" - -#include - -namespace INTERP_KERNEL -{ - class DirectedBoundingBox; -} - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDouble; - - /*! - * This class is abstract and not instanciable. - * ParaMEDMEM::MEDCouplingUMesh class inherits from this class. - * This class aggregates an array '_coords' containing nodes coordinates. - * So all operations on coordinates are managed by this class. - * This is the case for example for following methods : - * rotation, translation, scaling, getNodeIdsNearPoint, boundingbox... - */ - class MEDCouplingPointSet : public MEDCouplingMesh - { - protected: - MEDCOUPLING_EXPORT MEDCouplingPointSet(); - MEDCOUPLING_EXPORT MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy); - MEDCOUPLING_EXPORT ~MEDCouplingPointSet(); - public: - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coords); - MEDCOUPLING_EXPORT const DataArrayDouble *getCoords() const { return _coords; } - MEDCOUPLING_EXPORT DataArrayDouble *getCoords() { return _coords; } - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT bool areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; - MEDCOUPLING_EXPORT bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *deepCpyConnectivityOnly() const = 0; - MEDCOUPLING_EXPORT virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); - MEDCOUPLING_EXPORT virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const = 0; - MEDCOUPLING_EXPORT virtual void computeNodeIdsAlg(std::vector& nodeIdsInUse) const = 0; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; - MEDCOUPLING_EXPORT void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; - MEDCOUPLING_EXPORT virtual void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const = 0; - MEDCOUPLING_EXPORT DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, - int& newNbOfNodes) const; - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT void zipCoords(); - MEDCOUPLING_EXPORT double getCaracteristicDimension() const; - MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps); - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT void changeSpaceDimension(int newSpaceDim, double dftVal=0.); - MEDCOUPLING_EXPORT void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon); - MEDCOUPLING_EXPORT void duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); - MEDCOUPLING_EXPORT virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon); - MEDCOUPLING_EXPORT void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const; - MEDCOUPLING_EXPORT void findNodesOnLine(const double *pt, const double *vec, double eps, std::vector& nodes) const; - MEDCOUPLING_EXPORT static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2); - MEDCOUPLING_EXPORT static DataArrayDouble *MergeNodesArray(const std::vector& ms); - MEDCOUPLING_EXPORT static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type); - MEDCOUPLING_EXPORT static void Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords); - MEDCOUPLING_EXPORT static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps); - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *findBoundaryNodes() const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfNodesInCell(int cellId) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeFetchedNodeIds() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const = 0; - MEDCOUPLING_EXPORT virtual void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const = 0; - MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const int *newNodeNumbersO2N) = 0; - MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N) = 0; - MEDCOUPLING_EXPORT virtual void renumberNodesWithOffsetInConn(int offset) = 0; - MEDCOUPLING_EXPORT virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); - MEDCOUPLING_EXPORT virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); - MEDCOUPLING_EXPORT virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; - MEDCOUPLING_EXPORT virtual void checkFullyDefined() const = 0; - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT virtual DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *computeDiameterField() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *zipCoordsTraducer(); - MEDCOUPLING_EXPORT virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0); - MEDCOUPLING_EXPORT virtual bool areAllNodesFetched() const; - //tools - public: - MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const; - protected: - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps); - MEDCOUPLING_EXPORT static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps); - MEDCOUPLING_EXPORT void rotate2D(const double *center, double angle); - MEDCOUPLING_EXPORT void rotate3D(const double *center, const double *vect, double angle); - MEDCOUPLING_EXPORT void project2DCellOnXY(const int *startConn, const int *endConn, std::vector& res) const; - MEDCOUPLING_EXPORT static bool isButterfly2DCell(const std::vector& res, bool isQuad, double eps); - protected: - DataArrayDouble *_coords; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingRefCountObject.cxx b/medtool/src/MEDCoupling/MEDCouplingRefCountObject.cxx deleted file mode 100644 index 03b31cec3..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingRefCountObject.cxx +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCoupling_version.h" - -#include -#include - -using namespace ParaMEDMEM; - -const char *ParaMEDMEM::MEDCouplingVersionStr() -{ - return MEDCOUPLING_VERSION_STR; -} - -int ParaMEDMEM::MEDCouplingVersion() -{ - return MEDCOUPLING_VERSION; -} - -void ParaMEDMEM::MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas) -{ - int ver=MEDCOUPLING_VERSION; - maj=(ver & 0xFF0000) >> 16; - minor=(ver & 0xFF00) >> 8; - releas=(ver & 0xFF); -} - -int ParaMEDMEM::MEDCouplingSizeOfVoidStar() -{ - return 8*sizeof(std::size_t); -} - -/*! - * If true is returned it is a LittleEndian machine. - * If false it is a BigEndian machine. - * \return the coding mode of integers of the machine. - */ -bool ParaMEDMEM::MEDCouplingByteOrder() -{ - unsigned int x(1); - unsigned char *xc(reinterpret_cast(&x)); - return xc[0]==1; -} - -const char *ParaMEDMEM::MEDCouplingByteOrderStr() -{ - static const char LITTLEENDIAN_STR[]="LittleEndian"; - static const char BIGENDIAN_STR[]="BigEndian"; - if(MEDCouplingByteOrder()) - return LITTLEENDIAN_STR; - else - return BIGENDIAN_STR; -} - -//= - -std::size_t BigMemoryObject::getHeapMemorySize() const -{ - std::size_t ret(getHeapMemorySizeWithoutChildren()); - std::vector v(getDirectChildren()); - std::set s1,s2(v.begin(),v.end()); - return ret+GetHeapMemoryOfSet(s1,s2); -} - -/*! - * This method returns all the progeny of \a this (this is \b not included in returned vector). - * All the progeny means all the subobjects (children), subsubobjects (little children), ... of \a this. - * The elements in returned array are reported only once even if they appear several times in the progeny of \a this. - */ -std::vector BigMemoryObject::getAllTheProgeny() const -{ - std::vector s1(getDirectChildren()); - std::vector ret; - while(!s1.empty()) - { - ret.insert(ret.end(),s1.begin(),s1.end()); - std::vector s3; - for(std::vector::const_iterator it0=s1.begin();it0!=s1.end();it0++) - { - std::vector s2; - if(*it0) - s2=(*it0)->getDirectChildren(); - for(std::vector::const_iterator it1=s2.begin();it1!=s2.end();it1++) - { - if(*it1) - if(std::find(ret.begin(),ret.end(),*it1)==ret.end()) - s3.push_back(*it1); - } - } - s1=s3; - } - return ret; -} - -/*! - * This method scan all the progeny of \a this (\a this excluded) to see if \a obj is part of it. - * If obj is NULL false is returned. - * \sa BigMemoryObject::getAllTheProgeny - */ -bool BigMemoryObject::isObjectInTheProgeny(const BigMemoryObject *obj) const -{ - if(!obj) - return false; - std::vector objs(getAllTheProgeny()); - return std::find(objs.begin(),objs.end(),obj)!=objs.end(); -} - -std::size_t BigMemoryObject::GetHeapMemorySizeOfObjs(const std::vector& objs) -{ - std::size_t ret(0); - std::set s1,s2; - for(std::vector::const_iterator it0=objs.begin();it0!=objs.end();it0++) - { - if(*it0) - if(s1.find(*it0)==s1.end()) - { - std::vector vTmp((*it0)->getDirectChildren()); - s2.insert(vTmp.begin(),vTmp.end()); - ret+=(*it0)->getHeapMemorySizeWithoutChildren(); - s1.insert(*it0); - } - } - return ret+GetHeapMemoryOfSet(s1,s2); -} - -std::size_t BigMemoryObject::GetHeapMemoryOfSet(std::set& s1, std::set& s2) -{ - std::size_t ret(0); - while(!s2.empty()) - { - std::set s3; - for(std::set::const_iterator it=s2.begin();it!=s2.end();it++) - { - if(s1.find(*it)==s1.end()) - { - ret+=(*it)->getHeapMemorySizeWithoutChildren(); - s1.insert(*it); - std::vector v2((*it)->getDirectChildren()); - for(std::vector::const_iterator it2=v2.begin();it2!=v2.end();it2++) - if(s1.find(*it2)==s1.end()) - s3.insert(*it2); - } - } - s2=s3; - } - return ret; -} - -std::string BigMemoryObject::getHeapMemorySizeStr() const -{ - static const char *UNITS[4]={"B","kB","MB","GB"}; - std::size_t m(getHeapMemorySize()); - std::ostringstream oss; oss.precision(3); - std::size_t remain(0); - int i(0); - for(;i<4;i++) - { - if(m<1024) - { - oss << m; - if(remain!=0) - { - std::ostringstream oss2; oss2 << std::fixed << ((double)remain)/1024.; - std::string s(oss2.str()); - s=s.substr(1,4); - std::size_t pos(s.find_last_not_of('0')); - if(pos==4) - oss << s; - else - oss << s.substr(0,pos+1); - } - oss << " " << UNITS[i]; - break; - } - else - { - if(i!=3) - { - remain=(m%1024); - m/=1024; - } - } - } - if(i==4) - oss << m << " " << UNITS[3]; - return oss.str(); -} - -std::vector BigMemoryObject::getDirectChildren() const -{ - std::vector ret; - std::vector retWithNull(getDirectChildrenWithNull()); - for(std::vector::const_iterator it=retWithNull.begin();it!=retWithNull.end();it++) - if(*it) - ret.push_back(*it); - return ret; -} - -BigMemoryObject::~BigMemoryObject() -{ -} - -//= - -RefCountObjectOnly::RefCountObjectOnly():_cnt(1) -{ -} - -RefCountObjectOnly::RefCountObjectOnly(const RefCountObjectOnly& other):_cnt(1) -{ -} - -bool RefCountObjectOnly::decrRef() const -{ - bool ret=((--_cnt)==0); - if(ret) - delete this; - return ret; -} - -void RefCountObjectOnly::incrRef() const -{ - _cnt++; -} - -int RefCountObjectOnly::getRCValue() const -{ - return _cnt; -} - -RefCountObjectOnly::~RefCountObjectOnly() -{ -} - -/*! - * Do nothing here ! It is not a bug ( I hope :) ) because all subclasses that - * copies using operator= should not copy the ref counter of \a other ! - */ -RefCountObjectOnly& RefCountObjectOnly::operator=(const RefCountObjectOnly& other) -{ - return *this; -} - -//= - -RefCountObject::RefCountObject() -{ -} - -RefCountObject::RefCountObject(const RefCountObject& other):RefCountObjectOnly(other) -{ -} - -RefCountObject::~RefCountObject() -{ -} diff --git a/medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx b/medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx deleted file mode 100644 index 897cdc6f7..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGREFCOUNTOBJECT_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGREFCOUNTOBJECT_HXX__ - -#include "MEDCoupling.hxx" - -#include -#include -#include -#include - -namespace ParaMEDMEM -{ - typedef enum - { - C_DEALLOC = 2, - CPP_DEALLOC = 3 - } DeallocType; - - //! The various spatial discretization of a field - typedef enum - { - ON_CELLS = 0, - ON_NODES = 1, - ON_GAUSS_PT = 2, - ON_GAUSS_NE = 3, - ON_NODES_KR = 4 - } TypeOfField; - - //! The various temporal discretization of a field - typedef enum - { - NO_TIME = 4, - ONE_TIME = 5, - LINEAR_TIME = 6, - CONST_ON_TIME_INTERVAL = 7 - } TypeOfTimeDiscretization; - - typedef bool (*FunctionToEvaluate)(const double *pos, double *res); - - MEDCOUPLING_EXPORT const char *MEDCouplingVersionStr(); - MEDCOUPLING_EXPORT int MEDCouplingVersion(); - MEDCOUPLING_EXPORT void MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas); - MEDCOUPLING_EXPORT int MEDCouplingSizeOfVoidStar(); - MEDCOUPLING_EXPORT bool MEDCouplingByteOrder(); - MEDCOUPLING_EXPORT const char *MEDCouplingByteOrderStr(); - - class BigMemoryObject - { - public: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; - MEDCOUPLING_EXPORT std::string getHeapMemorySizeStr() const; - MEDCOUPLING_EXPORT std::vector getDirectChildren() const; - MEDCOUPLING_EXPORT std::vector getAllTheProgeny() const; - MEDCOUPLING_EXPORT bool isObjectInTheProgeny(const BigMemoryObject *obj) const; - MEDCOUPLING_EXPORT static std::size_t GetHeapMemorySizeOfObjs(const std::vector& objs); - MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const = 0; - MEDCOUPLING_EXPORT virtual std::vector getDirectChildrenWithNull() const = 0; - MEDCOUPLING_EXPORT virtual ~BigMemoryObject(); - private: - static std::size_t GetHeapMemoryOfSet(std::set& s1, std::set& s2); - }; - - class RefCountObjectOnly - { - protected: - MEDCOUPLING_EXPORT RefCountObjectOnly(); - MEDCOUPLING_EXPORT RefCountObjectOnly(const RefCountObjectOnly& other); - public: - MEDCOUPLING_EXPORT bool decrRef() const; - MEDCOUPLING_EXPORT void incrRef() const; - MEDCOUPLING_EXPORT int getRCValue() const; - MEDCOUPLING_EXPORT RefCountObjectOnly& operator=(const RefCountObjectOnly& other); - protected: - virtual ~RefCountObjectOnly(); - private: - mutable int _cnt; - }; - - class RefCountObject : public RefCountObjectOnly, public BigMemoryObject - { - protected: - MEDCOUPLING_EXPORT RefCountObject(); - MEDCOUPLING_EXPORT RefCountObject(const RefCountObject& other); - MEDCOUPLING_EXPORT virtual ~RefCountObject(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingRemapper.cxx b/medtool/src/MEDCoupling/MEDCouplingRemapper.cxx deleted file mode 100644 index 8dad02890..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingRemapper.cxx +++ /dev/null @@ -1,1324 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingRemapper.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingNormalizedCartesianMesh.txx" - -#include "Interpolation1D.txx" -#include "Interpolation2DCurve.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3D.txx" -#include "Interpolation3DSurf.hxx" -#include "Interpolation2D1D.txx" -#include "Interpolation3D2D.txx" -#include "InterpolationCU.txx" -#include "InterpolationCC.txx" - -using namespace ParaMEDMEM; - -MEDCouplingRemapper::MEDCouplingRemapper():_src_ft(0),_target_ft(0),_interp_matrix_pol(IK_ONLY_PREFERED),_nature_of_deno(NoNature),_time_deno_update(0) -{ -} - -MEDCouplingRemapper::~MEDCouplingRemapper() -{ - releaseData(false); -} - -/*! - * This method is the second step of the remapping process. The remapping process works in three phases : - * - * - Set remapping options appropriately - * - The computation of remapping matrix - * - Apply the matrix vector multiply to obtain the result of the remapping - * - * This method performs the second step (computation of remapping matrix) which may be CPU-time consuming. This phase is also the most critical (where the most tricky algorithm) in the remapping process. - * Strictly speaking to perform the computation of the remapping matrix the field templates source-side and target-side is required (which is the case of MEDCouplingRemapper::prepareEx). - * So this method is less precise but a more user friendly way to compute a remapping matrix. - * - * \param [in] srcMesh the source mesh - * \param [in] targetMesh the target mesh - * \param [in] method A string obtained by aggregation of the spatial discretisation string representation of source field and target field. The string representation is those returned by MEDCouplingFieldDiscretization::getStringRepr. - * Example : "P0" is for cell discretization. "P1" is for node discretization. So "P0P1" for \a method parameter means from a source cell field (lying on \a srcMesh) to a target node field (lying on \a targetMesh). - * - * \sa MEDCouplingRemapper::prepareEx - */ -int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method) -{ - if(!srcMesh || !targetMesh) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepare : presence of NULL input pointer !"); - std::string srcMethod,targetMethod; - INTERP_KERNEL::Interpolation::CheckAndSplitInterpolationMethod(method,srcMethod,targetMethod); - MEDCouplingAutoRefCountObjectPtr src=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(srcMethod)); - src->setMesh(srcMesh); - MEDCouplingAutoRefCountObjectPtr target=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(targetMethod)); - target->setMesh(targetMesh); - return prepareEx(src,target); -} - -/*! - * This method is the generalization of MEDCouplingRemapper::prepare. Indeed, MEDCouplingFieldTemplate instances gives all required information to compute the remapping matrix. - * This method must be used instead of MEDCouplingRemapper::prepare if Gauss point to Gauss point must be applied. - * - * \param [in] src is the field template source side. - * \param [in] target is the field template target side. - * - * \sa MEDCouplingRemapper::prepare - */ -int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) -{ - if(!src || !target) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareEx : presence of NULL input pointer !"); - if(!src->getMesh() || !target->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareEx : presence of NULL mesh pointer in given field template !"); - releaseData(true); - _src_ft=const_cast(src); _src_ft->incrRef(); - _target_ft=const_cast(target); _target_ft->incrRef(); - if(isInterpKernelOnlyOrNotOnly()) - return prepareInterpKernelOnly(); - else - return prepareNotInterpKernelOnly(); -} - -int MEDCouplingRemapper::prepareInterpKernelOnly() -{ - int meshInterpType=((int)_src_ft->getMesh()->getType()*16)+(int)_target_ft->getMesh()->getType(); - // *** Remember: -// typedef enum -// { -// UNSTRUCTURED = 5, -// CARTESIAN = 7, -// EXTRUDED = 8, -// CURVE_LINEAR = 9, -// SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, -// SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, -// IMAGE_GRID = 12 -// } MEDCouplingMeshType; - - switch(meshInterpType) - { - case 90: // UNSTRUCTURED - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - case 91: // UNSTRUCTURED - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - case 165: // SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - UNSTRUCTURED - case 181: // SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - UNSTRUCTURED - case 170: // SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - case 171: // SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - case 186: // SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - case 187: // SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - case 85: // UNSTRUCTURED - UNSTRUCTURED - return prepareInterpKernelOnlyUU(); - case 167: // SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - CARTESIAN - case 183: // SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - CARTESIAN - case 87: // UNSTRUCTURED - CARTESIAN - return prepareInterpKernelOnlyUC(); - case 122: // CARTESIAN - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED - case 123: // CARTESIAN - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED - case 117: // CARTESIAN - UNSTRUCTURED - return prepareInterpKernelOnlyCU(); - case 119: // CARTESIAN - CARTESIAN - return prepareInterpKernelOnlyCC(); - case 136: // EXTRUDED - EXTRUDED - return prepareInterpKernelOnlyEE(); - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnly : Not managed type of meshes ! Dealt meshes type are : Unstructured<->Unstructured, Unstructured<->Cartesian, Cartesian<->Cartesian, Extruded<->Extruded !"); - } -} - -int MEDCouplingRemapper::prepareNotInterpKernelOnly() -{ - std::string srcm,trgm,method; - method=checkAndGiveInterpolationMethodStr(srcm,trgm); - switch(CheckInterpolationMethodManageableByNotOnlyInterpKernel(method)) - { - case 0: - return prepareNotInterpKernelOnlyGaussGauss(); - default: - { - std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnly : INTERNAL ERROR ! the method \"" << method << "\" declared as managed bu not implemented !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * This method performs the operation source to target using matrix computed in ParaMEDMEM::MEDCouplingRemapper::prepare method. - * If meshes of \b srcField and \b targetField do not match exactly those given into \ref ParaMEDMEM::MEDCouplingRemapper::prepare "prepare method" an exception will be thrown. - * - * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. - * \param [in/out] targetField the destination field with the allocated array in which all tuples will be overwritten. - * \param [in] dftValue is the value that will be assigned in the targetField to each entity of target mesh (entity depending on the method selected on prepare invocation) that is not intercepted by any entity of source mesh. - * For example in "P0P0" case (cell-cell) if a cell in target mesh is not overlapped by any source cell the \a dftValue value will be attached on that cell in the returned \a targetField. In some cases a target - * cell not intercepted by any source cell is a bug so in this case it is advised to set a huge value (1e300 for example) to \a dftValue to quickly point to the problem. But for users doing parallelism a target cell can - * be intercepted by a source cell on a different process. In this case 0. assigned to \a dftValue is more appropriate. - * - * \sa transferField - */ -void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transfer : input field must be both not NULL !"); - transferUnderground(srcField,targetField,true,dftValue); -} - -/*! - * This method is equivalent to ParaMEDMEM::MEDCouplingRemapper::transfer except that here \b targetField is a in/out parameter. - * If an entity (cell for example) in targetField is not fetched by any entity (cell for example) of \b srcField, the value in targetField is - * let unchanged. - * This method requires that \b targetField was fully defined and allocated. If the array is not allocated an exception will be thrown. - * - * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. - * \param [in,out] targetField the destination field with the allocated array in which only tuples whose entities are fetched by interpolation will be overwritten only. - */ -void MEDCouplingRemapper::partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::partialTransfer : input field must be both not NULL !"); - transferUnderground(srcField,targetField,false,std::numeric_limits::max()); -} - -void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::reverseTransfer : input fields must be both not NULL !"); - checkPrepare(); - targetField->checkCoherency(); - if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); - if(srcField->getNature()!=targetField->getNature()) - throw INTERP_KERNEL::Exception("Natures of fields mismatch !"); - if(targetField->getNumberOfTuplesExpected()!=_target_ft->getNumberOfTuplesExpected()) - { - std::ostringstream oss; - oss << "MEDCouplingRemapper::reverseTransfer : in given source field the number of tuples required is " << _target_ft->getNumberOfTuplesExpected() << " (on prepare) and number of tuples in given target field is " << targetField->getNumberOfTuplesExpected(); - oss << " ! It appears that the target support is not the same between the prepare and the transfer !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - DataArrayDouble *array(srcField->getArray()); - int trgNbOfCompo=targetField->getNumberOfComponents(); - if(array) - { - srcField->checkCoherency(); - if(trgNbOfCompo!=srcField->getNumberOfTuplesExpected()) - throw INTERP_KERNEL::Exception("Number of components mismatch !"); - } - else - { - MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); - tmp->alloc(srcField->getNumberOfTuplesExpected(),trgNbOfCompo); - srcField->setArray(tmp); - } - computeDeno(srcField->getNature(),srcField,targetField); - double *resPointer(srcField->getArray()->getPointer()); - const double *inputPointer=targetField->getArray()->getConstPointer(); - computeReverseProduct(inputPointer,trgNbOfCompo,dftValue,resPointer); -} - -/*! - * This method performs the operation source to target using matrix computed in ParaMEDMEM::MEDCouplingRemapper::prepare method. - * If mesh of \b srcField does not match exactly those given into \ref ParaMEDMEM::MEDCouplingRemapper::prepare "prepare method" an exception will be thrown. - * - * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. - * \param [in] dftValue is the value that will be assigned in the targetField to each entity of target mesh (entity depending on the method selected on prepare invocation) that is not intercepted by any entity of source mesh. - * For example in "P0P0" case (cell-cell) if a cell in target mesh is not overlapped by any source cell the \a dftValue value will be attached on that cell in the returned \a targetField. In some cases a target - * cell not intercepted by any source cell is a bug so in this case it is advised to set a huge value (1e300 for example) to \a dftValue to quickly point to the problem. But for users doing parallelism a target cell can - * be intercepted by a source cell on a different process. In this case 0. assigned to \a dftValue is more appropriate. - * \return destination field to be deallocated by the caller. - * - * \sa transfer - */ -MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) -{ - checkPrepare(); - if(!srcField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferField : input srcField is NULL !"); - srcField->checkCoherency(); - if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_target_ft,srcField->getTimeDiscretization()); - ret->setNature(srcField->getNature()); - transfer(srcField,ret,dftValue); - ret->copyAllTinyAttrFrom(srcField);//perform copy of tiny strings after and not before transfer because the array will be created on transfer - return ret; -} - -MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) -{ - if(!targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferField : input targetField is NULL !"); - targetField->checkCoherency(); - checkPrepare(); - if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_src_ft,targetField->getTimeDiscretization()); - ret->setNature(targetField->getNature()); - reverseTransfer(ret,targetField,dftValue); - ret->copyAllTinyAttrFrom(targetField);//perform copy of tiny strings after and not before reverseTransfer because the array will be created on reverseTransfer - return ret; -} - -/*! - * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method - * is here only for automatic CORBA generators. - */ -bool MEDCouplingRemapper::setOptionInt(const std::string& key, int value) -{ - return INTERP_KERNEL::InterpolationOptions::setOptionInt(key,value); -} - -/*! - * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method - * is here only for automatic CORBA generators. - */ -bool MEDCouplingRemapper::setOptionDouble(const std::string& key, double value) -{ - return INTERP_KERNEL::InterpolationOptions::setOptionDouble(key,value); -} - -/*! - * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method - * is here only for automatic CORBA generators. - */ -bool MEDCouplingRemapper::setOptionString(const std::string& key, const std::string& value) -{ - return INTERP_KERNEL::InterpolationOptions::setOptionString(key,value); -} - -/*! - * This method returns the interpolation matrix policy. This policy specifies which interpolation matrix method to keep or prefered. - * If interpolation matrix policy is : - * - * - set to IK_ONLY_PREFERED (0) (the default) : the INTERP_KERNEL only method is prefered. That is to say, if it is possible to treat the case - * regarding spatial discretization of source and target with INTERP_KERNEL only method, INTERP_KERNEL only method will be performed. - * If not, the \b not only INTERP_KERNEL method will be attempt. - * - * - set to NOT_IK_ONLY_PREFERED (1) : the \b NOT only INTERP_KERNEL method is prefered. That is to say, if it is possible to treat the case - * regarding spatial discretization of source and target with \b NOT only INTERP_KERNEL method, \b NOT only INTERP_KERNEL method, will be performed. - * If not, the INTERP_KERNEL only method will be attempt. - * - * - IK_ONLY_FORCED (2) : Only INTERP_KERNEL only method will be launched. - * - * - NOT_IK_ONLY_FORCED (3) : Only \b NOT INTERP_KERNEL only method will be launched. - * - * \sa MEDCouplingRemapper::setInterpolationMatrixPolicy - */ -int MEDCouplingRemapper::getInterpolationMatrixPolicy() const -{ - return _interp_matrix_pol; -} - -/*! - * This method sets a new interpolation matrix policy. The default one is IK_PREFERED (0). The input is of type \c int to be dealt by standard Salome - * CORBA component generators. This method throws an INTERP_KERNEL::Exception if a the input integer is not in the available possibilities, that is to say not in - * [0 (IK_PREFERED) , 1 (NOT_IK_PREFERED), 2 (IK_ONLY_FORCED), 3 (NOT_IK_ONLY_FORCED)]. - * - * If interpolation matrix policy is : - * - * - set to IK_ONLY_PREFERED (0) (the default) : the INTERP_KERNEL only method is prefered. That is to say, if it is possible to treat the case - * regarding spatial discretization of source and target with INTERP_KERNEL only method, INTERP_KERNEL only method will be performed. - * If not, the \b not only INTERP_KERNEL method will be attempt. - * - * - set to NOT_IK_ONLY_PREFERED (1) : the \b NOT only INTERP_KERNEL method is prefered. That is to say, if it is possible to treat the case - * regarding spatial discretization of source and target with \b NOT only INTERP_KERNEL method, \b NOT only INTERP_KERNEL method, will be performed. - * If not, the INTERP_KERNEL only method will be attempt. - * - * - IK_ONLY_FORCED (2) : Only INTERP_KERNEL only method will be launched. - * - * - NOT_IK_ONLY_FORCED (3) : Only \b NOT INTERP_KERNEL only method will be launched. - * - * \input newInterpMatPol the new interpolation matrix method policy. This parameter is of type \c int and not of type \c ParaMEDMEM::InterpolationMatrixPolicy - * for automatic generation of CORBA component. - * - * \sa MEDCouplingRemapper::getInterpolationMatrixPolicy - */ -void MEDCouplingRemapper::setInterpolationMatrixPolicy(int newInterpMatPol) -{ - switch(newInterpMatPol) - { - case 0: - _interp_matrix_pol=IK_ONLY_PREFERED; - break; - case 1: - _interp_matrix_pol=NOT_IK_ONLY_PREFERED; - break; - case 2: - _interp_matrix_pol=IK_ONLY_FORCED; - break; - case 3: - _interp_matrix_pol=NOT_IK_ONLY_FORCED; - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::setInterpolationMatrixPolicy : invalid input integer value ! Should be in [0 (IK_PREFERED) , 1 (NOT_IK_PREFERED), 2 (IK_ONLY_FORCED), 3 (NOT_IK_ONLY_FORCED)] ! For information, the default is IK_PREFERED=0 !"); - } -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyUU() -{ - const MEDCouplingPointSet *src_mesh=static_cast(_src_ft->getMesh()); - const MEDCouplingPointSet *target_mesh=static_cast(_target_ft->getMesh()); - std::string srcMeth,trgMeth; - std::string method(checkAndGiveInterpolationMethodStr(srcMeth,trgMeth)); - const int srcMeshDim=src_mesh->getMeshDimension(); - int srcSpaceDim=-1; - if(srcMeshDim!=-1) - srcSpaceDim=src_mesh->getSpaceDimension(); - const int trgMeshDim=target_mesh->getMeshDimension(); - int trgSpaceDim=-1; - if(trgMeshDim!=-1) - trgSpaceDim=target_mesh->getSpaceDimension(); - if(trgSpaceDim!=srcSpaceDim) - if(trgSpaceDim!=-1 && srcSpaceDim!=-1) - throw INTERP_KERNEL::Exception("Incoherent space dimension detected between target and source."); - int nbCols; - if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==1) - { - MEDCouplingNormalizedUnstructuredMesh<1,1> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation1D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,1> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2DCurve interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else if(srcMeshDim==3 && trgMeshDim==3 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else if(srcMeshDim==3 && trgMeshDim==1 && srcSpaceDim==3) - { - if(getIntersectionType()!=INTERP_KERNEL::PointLocator) - throw INTERP_KERNEL::Exception("Invalid interpolation requested between 3D and 1D ! Select PointLocator as intersection type !"); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else if(srcMeshDim==1 && trgMeshDim==3 && srcSpaceDim==3) - { - if(getIntersectionType()!=INTERP_KERNEL::PointLocator) - throw INTERP_KERNEL::Exception("Invalid interpolation requested between 3D and 1D ! Select PointLocator as intersection type !"); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - } - else if(srcMeshDim==2 && trgMeshDim==1 && srcSpaceDim==2) - { - if(getIntersectionType()==INTERP_KERNEL::PointLocator) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - } - else - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D1D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happened ! For the following 1D Cells are part of edges shared by 2D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "1D Cell #" << (*it).first << " is part of common edge of following 2D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - } - else if(srcMeshDim==1 && trgMeshDim==2 && srcSpaceDim==2) - { - if(getIntersectionType()==INTERP_KERNEL::PointLocator) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - } - else - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D1D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 1D Cells are part of edges shared by 2D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "1D Cell #" << (*it).first << " is part of common edge of following 2D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - } - else if(srcMeshDim==2 && trgMeshDim==3 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 2D Cells are part of edges shared by 3D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "2D Cell #" << (*it).first << " is part of common face of following 3D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - else if(srcMeshDim==3 && trgMeshDim==2 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D2D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 2D Cells are part of edges shared by 3D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "2D Cell #" << (*it).first << " is part of common face of following 3D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - else if(trgMeshDim==-1) - { - if(srcMeshDim==2 && srcSpaceDim==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth); - } - else if(srcMeshDim==3 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth); - } - else if(srcMeshDim==2 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth); - } - else - throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); - } - else if(srcMeshDim==-1) - { - if(trgMeshDim==2 && trgSpaceDim==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth); - } - else if(trgMeshDim==3 && trgSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth); - } - else if(trgMeshDim==2 && trgSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth); - } - else - throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh from -1D sourceMesh"); - } - else - throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension"); - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(nbCols); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyEE() -{ - std::string srcMeth,trgMeth; - std::string methC=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - const MEDCouplingExtrudedMesh *src_mesh=static_cast(_src_ft->getMesh()); - const MEDCouplingExtrudedMesh *target_mesh=static_cast(_target_ft->getMesh()); - if(methC!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyEE : Only P0P0 method implemented for Extruded/Extruded meshes !"); - MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh->getMesh2D()); - MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(target_mesh->getMesh2D()); - INTERP_KERNEL::Interpolation3DSurf interpolation2D(*this); - std::vector > matrix2D; - int nbCols2D=interpolation2D.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,matrix2D,methC); - MEDCouplingUMesh *s1D,*t1D; - double v[3]; - MEDCouplingExtrudedMesh::Project1DMeshes(src_mesh->getMesh1D(),target_mesh->getMesh1D(),getPrecision(),s1D,t1D,v); - MEDCouplingNormalizedUnstructuredMesh<1,1> s1DWrapper(s1D); - MEDCouplingNormalizedUnstructuredMesh<1,1> t1DWrapper(t1D); - std::vector > matrix1D; - INTERP_KERNEL::Interpolation1D interpolation1D(*this); - int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,methC); - s1D->decrRef(); - t1D->decrRef(); - buildFinalInterpolationMatrixByConvolution(matrix1D,matrix2D,src_mesh->getMesh3DIds()->getConstPointer(),nbCols2D,nbCols1D, - target_mesh->getMesh3DIds()->getConstPointer()); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(nbCols2D*nbCols1D); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyUC() -{ - std::string srcMeth,trgMeth; - std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only P0P0 interpolation supported for the moment !"); - const MEDCouplingUMesh *src_mesh=static_cast(_src_ft->getMesh()); - const MEDCouplingCMesh *target_mesh=static_cast(_target_ft->getMesh()); - const int srcMeshDim=src_mesh->getMeshDimension(); - const int srcSpceDim=src_mesh->getSpaceDimension(); - const int trgMeshDim=target_mesh->getMeshDimension(); - if(srcMeshDim!=srcSpceDim || srcMeshDim!=trgMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : space dim of src unstructured should be equal to mesh dim of src unstructured and should be equal also equal to trg cartesian dimension !"); - std::vector > res; - switch(srcMeshDim) - { - case 1: - { - MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(src_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); - break; - } - case 2: - { - MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(src_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); - break; - } - case 3: - { - MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(src_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only dimension 1 2 or 3 supported !"); - } - ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix); - nullifiedTinyCoeffInCrudeMatrixAbs(0.); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyCU() -{ - std::string srcMeth,trgMeth; - std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only P0P0 interpolation supported for the moment !"); - const MEDCouplingCMesh *src_mesh=static_cast(_src_ft->getMesh()); - const MEDCouplingUMesh *target_mesh=static_cast(_target_ft->getMesh()); - const int srcMeshDim=src_mesh->getMeshDimension(); - const int trgMeshDim=target_mesh->getMeshDimension(); - const int trgSpceDim=target_mesh->getSpaceDimension(); - if(trgMeshDim!=trgSpceDim || trgMeshDim!=srcMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : space dim of target unstructured should be equal to mesh dim of target unstructured and should be equal also equal to source cartesian dimension !"); - switch(srcMeshDim) - { - case 1: - { - MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 2: - { - MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 3: - { - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only dimension 1 2 or 3 supported !"); - } - nullifiedTinyCoeffInCrudeMatrixAbs(0.); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyCC() -{ - std::string srcMeth,trgMeth; - std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only P0P0 interpolation supported for the moment !"); - const MEDCouplingCMesh *src_mesh=static_cast(_src_ft->getMesh()); - const MEDCouplingCMesh *target_mesh=static_cast(_target_ft->getMesh()); - const int srcMeshDim=src_mesh->getMeshDimension(); - const int trgMeshDim=target_mesh->getMeshDimension(); - if(trgMeshDim!=srcMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); - switch(srcMeshDim) - { - case 1: - { - MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh); - MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCC myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 2: - { - MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh); - MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCC myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 3: - { - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh); - MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCC myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only dimension 1 2 or 3 supported !"); - } - nullifiedTinyCoeffInCrudeMatrixAbs(0.); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss() -{ - if(getIntersectionType()!=INTERP_KERNEL::PointLocator) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : The intersection type is not supported ! Only PointLocator is supported for Gauss->Gauss interpolation ! Please invoke setIntersectionType(PointLocator) on the MEDCouplingRemapper instance !"); - MEDCouplingAutoRefCountObjectPtr trgLoc=_target_ft->getLocalizationOfDiscr(); - const double *trgLocPtr=trgLoc->begin(); - int trgSpaceDim=trgLoc->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr srcOffsetArr=_src_ft->getDiscretization()->getOffsetArr(_src_ft->getMesh()); - if(trgSpaceDim!=_src_ft->getMesh()->getSpaceDimension()) - { - std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : space dimensions mismatch between source and target !"; - oss << " Target discretization localization has dimension " << trgSpaceDim << ", whereas the space dimension of source is equal to "; - oss << _src_ft->getMesh()->getSpaceDimension() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const int *srcOffsetArrPtr=srcOffsetArr->begin(); - MEDCouplingAutoRefCountObjectPtr srcLoc=_src_ft->getLocalizationOfDiscr(); - const double *srcLocPtr=srcLoc->begin(); - MEDCouplingAutoRefCountObjectPtr eltsArr,eltsIndexArr; - int trgNbOfGaussPts=trgLoc->getNumberOfTuples(); - _matrix.resize(trgNbOfGaussPts); - _src_ft->getMesh()->getCellsContainingPoints(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),eltsArr,eltsIndexArr); - const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); - MEDCouplingAutoRefCountObjectPtr nbOfSrcCellsShTrgPts(eltsIndexArr->deltaShiftIndex()); - MEDCouplingAutoRefCountObjectPtr ids0=nbOfSrcCellsShTrgPts->getIdsNotEqual(0); - for(const int *trgId=ids0->begin();trgId!=ids0->end();trgId++) - { - const double *ptTrg=trgLocPtr+trgSpaceDim*(*trgId); - int srcCellId=elts[eltsIndex[*trgId]]; - double dist=std::numeric_limits::max(); - int srcEntry=-1; - for(int srcId=srcOffsetArrPtr[srcCellId];srcIdgetNumberOfTuples()!=trgNbOfGaussPts) - { - MEDCouplingAutoRefCountObjectPtr orphanTrgIds=nbOfSrcCellsShTrgPts->getIdsEqual(0); - MEDCouplingAutoRefCountObjectPtr orphanTrg=trgLoc->selectByTupleId(orphanTrgIds->begin(),orphanTrgIds->end()); - MEDCouplingAutoRefCountObjectPtr srcIdPerTrg=srcLoc->findClosestTupleId(orphanTrg); - const int *srcIdPerTrgPtr=srcIdPerTrg->begin(); - for(const int *orphanTrgId=orphanTrgIds->begin();orphanTrgId!=orphanTrgIds->end();orphanTrgId++,srcIdPerTrgPtr++) - _matrix[*orphanTrgId][*srcIdPerTrgPtr]=2.; - } - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(srcLoc->getNumberOfTuples()); - declareAsNew(); - return 1; -} - -/*! - * This method checks that the input interpolation \a method is managed by not INTERP_KERNEL only methods. - * If no an INTERP_KERNEL::Exception will be thrown. If yes, a magic number will be returned to switch in the MEDCouplingRemapper::prepareNotInterpKernelOnly method. - */ -int MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method) -{ - if(method=="GAUSSGAUSS") - return 0; - std::ostringstream oss; oss << "MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel : "; - oss << "The method \"" << method << "\" is not manageable by not INTERP_KERNEL only method."; - oss << " Not only INTERP_KERNEL methods dealed are : GAUSSGAUSS !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * This method determines regarding \c _interp_matrix_pol attribute ( set by MEDCouplingRemapper::setInterpolationMatrixPolicy and by default equal - * to IK_ONLY_PREFERED, which method will be applied. If \c true is returned the INTERP_KERNEL only method should be applied to \c false the \b not - * only INTERP_KERNEL method should be applied. - */ -bool MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly() const -{ - std::string srcm,trgm,method; - method=checkAndGiveInterpolationMethodStr(srcm,trgm); - switch(_interp_matrix_pol) - { - case IK_ONLY_PREFERED: - { - try - { - std::string tmp1,tmp2; - INTERP_KERNEL::Interpolation::CheckAndSplitInterpolationMethod(method,tmp1,tmp2); - return true; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { - return false; - } - } - case NOT_IK_ONLY_PREFERED: - { - try - { - CheckInterpolationMethodManageableByNotOnlyInterpKernel(method); - return false; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { - return true; - } - } - case IK_ONLY_FORCED: - return true; - case NOT_IK_ONLY_FORCED: - return false; - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly : internal error ! The interpolation matrix policy is not managed ! Try to change it using MEDCouplingRemapper::setInterpolationMatrixPolicy !"); - } -} - -void MEDCouplingRemapper::updateTime() const -{ -} - -void MEDCouplingRemapper::checkPrepare() const -{ - const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft); - if(!s || !t) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that MEDCouplingRemapper::prepare(Ex) has not been called !"); - if(!s->getMesh() || !t->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that no all field templates have their mesh set !"); -} - -/*! - * This method builds a code considering already set field discretization int \a this : \a _src_ft and \a _target_ft. - * This method returns 3 informations (2 in ouput parameters and 1 in return). - * - * \param [out] srcMeth the string code of the discretization of source field template - * \param [out] trgMeth the string code of the discretization of target field template - * \return the standardized string code (compatible with INTERP_KERNEL) for matrix of numerators (in \a _matrix) - */ -std::string MEDCouplingRemapper::checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const -{ - const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft); - if(!s || !t) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have been set !"); - if(!s->getMesh() || !t->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have their mesh set !"); - srcMeth=_src_ft->getDiscretization()->getRepr(); - trgMeth=_target_ft->getDiscretization()->getRepr(); - return BuildMethodFrom(srcMeth,trgMeth); -} - -std::string MEDCouplingRemapper::BuildMethodFrom(const std::string& meth1, const std::string& meth2) -{ - std::string method(meth1); method+=meth2; - return method; -} - -void MEDCouplingRemapper::releaseData(bool matrixSuppression) -{ - _src_ft=0; - _target_ft=0; - if(matrixSuppression) - { - _matrix.clear(); - _deno_multiply.clear(); - _deno_reverse_multiply.clear(); - } -} - -void MEDCouplingRemapper::transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferUnderground : srcField or targetField is NULL !"); - srcField->checkCoherency(); - checkPrepare(); - if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); - if(srcField->getNature()!=targetField->getNature()) - throw INTERP_KERNEL::Exception("Natures of fields mismatch !"); - if(srcField->getNumberOfTuplesExpected()!=_src_ft->getNumberOfTuplesExpected()) - { - std::ostringstream oss; - oss << "MEDCouplingRemapper::transferUnderground : in given source field the number of tuples required is " << _src_ft->getNumberOfTuplesExpected() << " (on prepare) and number of tuples in given source field is " << srcField->getNumberOfTuplesExpected(); - oss << " ! It appears that the source support is not the same between the prepare and the transfer !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - DataArrayDouble *array(targetField->getArray()); - int srcNbOfCompo(srcField->getNumberOfComponents()); - if(array) - { - targetField->checkCoherency(); - if(srcNbOfCompo!=targetField->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Number of components mismatch !"); - } - else - { - if(!isDftVal) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::partialTransfer : This method requires that the array of target field exists ! Allocate it or call MEDCouplingRemapper::transfer instead !"); - MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); - tmp->alloc(targetField->getNumberOfTuples(),srcNbOfCompo); - targetField->setArray(tmp); - } - computeDeno(srcField->getNature(),srcField,targetField); - double *resPointer(targetField->getArray()->getPointer()); - const double *inputPointer(srcField->getArray()->getConstPointer()); - computeProduct(inputPointer,srcNbOfCompo,isDftVal,dftValue,resPointer); -} - -void MEDCouplingRemapper::computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) -{ - if(nat==NoNature) - return computeDenoFromScratch(nat,srcField,trgField); - else if(nat!=_nature_of_deno) - return computeDenoFromScratch(nat,srcField,trgField); - else if(nat==_nature_of_deno && _time_deno_update!=getTimeOfThis()) - return computeDenoFromScratch(nat,srcField,trgField); -} - -void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) -{ - _nature_of_deno=nat; - _time_deno_update=getTimeOfThis(); - switch(_nature_of_deno) - { - case ConservativeVolumic: - { - ComputeRowSumAndColSum(_matrix,_deno_multiply,_deno_reverse_multiply); - break; - } - case Integral: - { - MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus()); - MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus()); - const double *denoPtr=deno->getArray()->getConstPointer(); - const double *denoRPtr=denoR->getArray()->getConstPointer(); - if(trgField->getMesh()->getMeshDimension()==-1) - { - double *denoRPtr2=denoR->getArray()->getPointer(); - denoRPtr2[0]=std::accumulate(denoPtr,denoPtr+deno->getNumberOfTuples(),0.); - } - if(srcField->getMesh()->getMeshDimension()==-1) - { - double *denoPtr2=deno->getArray()->getPointer(); - denoPtr2[0]=std::accumulate(denoRPtr,denoRPtr+denoR->getNumberOfTuples(),0.); - } - int idx=0; - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - _deno_multiply[idx][(*iter2).first]=denoPtr[(*iter2).first]; - _deno_reverse_multiply[(*iter2).first][idx]=denoRPtr[idx]; - } - deno->decrRef(); - denoR->decrRef(); - break; - } - case IntegralGlobConstraint: - { - ComputeColSumAndRowSum(_matrix,_deno_multiply,_deno_reverse_multiply); - break; - } - case RevIntegral: - { - MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus()); - MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus()); - const double *denoPtr=deno->getArray()->getConstPointer(); - const double *denoRPtr=denoR->getArray()->getConstPointer(); - if(trgField->getMesh()->getMeshDimension()==-1) - { - double *denoRPtr2=denoR->getArray()->getPointer(); - denoRPtr2[0]=std::accumulate(denoPtr,denoPtr+deno->getNumberOfTuples(),0.); - } - if(srcField->getMesh()->getMeshDimension()==-1) - { - double *denoPtr2=deno->getArray()->getPointer(); - denoPtr2[0]=std::accumulate(denoRPtr,denoRPtr+denoR->getNumberOfTuples(),0.); - } - int idx=0; - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - _deno_multiply[idx][(*iter2).first]=denoPtr[idx]; - _deno_reverse_multiply[(*iter2).first][idx]=denoRPtr[(*iter2).first]; - } - deno->decrRef(); - denoR->decrRef(); - break; - } - case NoNature: - throw INTERP_KERNEL::Exception("No nature specified ! Select one !"); - } -} - -void MEDCouplingRemapper::computeProduct(const double *inputPointer, int inputNbOfCompo, bool isDftVal, double dftValue, double *resPointer) -{ - int idx=0; - double *tmp=new double[inputNbOfCompo]; - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - { - if((*iter1).empty()) - { - if(isDftVal) - std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue); - continue; - } - else - std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,0.); - std::map::const_iterator iter3=_deno_multiply[idx].begin(); - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++,iter3++) - { - std::transform(inputPointer+(*iter2).first*inputNbOfCompo,inputPointer+((*iter2).first+1)*inputNbOfCompo,tmp,std::bind2nd(std::multiplies(),(*iter2).second/(*iter3).second)); - std::transform(tmp,tmp+inputNbOfCompo,resPointer+idx*inputNbOfCompo,resPointer+idx*inputNbOfCompo,std::plus()); - } - } - delete [] tmp; -} - -void MEDCouplingRemapper::computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer) -{ - std::vector isReached(_deno_reverse_multiply.size(),false); - int idx=0; - double *tmp=new double[inputNbOfCompo]; - std::fill(resPointer,resPointer+inputNbOfCompo*_deno_reverse_multiply.size(),0.); - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - { - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - isReached[(*iter2).first]=true; - std::transform(inputPointer+idx*inputNbOfCompo,inputPointer+(idx+1)*inputNbOfCompo,tmp,std::bind2nd(std::multiplies(),(*iter2).second/_deno_reverse_multiply[(*iter2).first][idx])); - std::transform(tmp,tmp+inputNbOfCompo,resPointer+((*iter2).first)*inputNbOfCompo,resPointer+((*iter2).first)*inputNbOfCompo,std::plus()); - } - } - delete [] tmp; - idx=0; - for(std::vector::const_iterator iter3=isReached.begin();iter3!=isReached.end();iter3++,idx++) - if(!*iter3) - std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue); -} - -void MEDCouplingRemapper::ReverseMatrix(const std::vector >& matIn, int nbColsMatIn, std::vector >& matOut) -{ - matOut.resize(nbColsMatIn); - int id=0; - for(std::vector >::const_iterator iter1=matIn.begin();iter1!=matIn.end();iter1++,id++) - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - matOut[(*iter2).first][id]=(*iter2).second; -} - -void MEDCouplingRemapper::ComputeRowSumAndColSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse) -{ - std::map values; - int idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - double sum=0.; - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - sum+=(*iter2).second; - values[(*iter2).first]+=(*iter2).second; - } - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - deno[idx][(*iter2).first]=sum; - } - idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - denoReverse[(*iter2).first][idx]=values[(*iter2).first]; - } -} - -void MEDCouplingRemapper::ComputeColSumAndRowSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse) -{ - std::map values; - int idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - double sum=0.; - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - sum+=(*iter2).second; - values[(*iter2).first]+=(*iter2).second; - } - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - denoReverse[(*iter2).first][idx]=sum; - } - idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - deno[idx][(*iter2).first]=values[(*iter2).first]; - } -} - -void MEDCouplingRemapper::buildFinalInterpolationMatrixByConvolution(const std::vector< std::map >& m1D, - const std::vector< std::map >& m2D, - const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc, - const int *corrCellIdTrg) -{ - int nbOf2DCellsTrg=m2D.size(); - int nbOf1DCellsTrg=m1D.size(); - int nbOf3DCellsTrg=nbOf2DCellsTrg*nbOf1DCellsTrg; - _matrix.resize(nbOf3DCellsTrg); - int id2R=0; - for(std::vector< std::map >::const_iterator iter2R=m2D.begin();iter2R!=m2D.end();iter2R++,id2R++) - { - for(std::map::const_iterator iter2C=(*iter2R).begin();iter2C!=(*iter2R).end();iter2C++) - { - int id1R=0; - for(std::vector< std::map >::const_iterator iter1R=m1D.begin();iter1R!=m1D.end();iter1R++,id1R++) - { - for(std::map::const_iterator iter1C=(*iter1R).begin();iter1C!=(*iter1R).end();iter1C++) - { - _matrix[corrCellIdTrg[id1R*nbOf2DCellsTrg+id2R]][corrCellIdSrc[(*iter1C).first*nbOf2DCellsSrc+(*iter2C).first]]=(*iter1C).second*((*iter2C).second); - } - } - } - } -} - -void MEDCouplingRemapper::PrintMatrix(const std::vector >& m) -{ - int id=0; - for(std::vector >::const_iterator iter1=m.begin();iter1!=m.end();iter1++,id++) - { - std::cout << "Target Cell # " << id << " : "; - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - std::cout << "(" << (*iter2).first << "," << (*iter2).second << "), "; - std::cout << std::endl; - } -} - -const std::vector >& MEDCouplingRemapper::getCrudeMatrix() const -{ - return _matrix; -} - -/*! - * Returns the number of columns of matrix returned by MEDCouplingRemapper::getCrudeMatrix method. - */ -int MEDCouplingRemapper::getNumberOfColsOfMatrix() const -{ - return (int)_deno_reverse_multiply.size(); -} - -/*! - * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. - * If not the behaviour is unpredictable. - * This method works on precomputed \a this->_matrix. All coefficients in the matrix is lower than \a maxValAbs this coefficient is - * set to 0. That is to say that its entry disappear from the map storing the corresponding row in the data storage of sparse crude matrix. - * This method is useful to correct at a high level some problems linked to precision. Indeed, with some \ref NatureOfField "natures of field" some threshold effect - * can occur. - * - * \param [in] maxValAbs is a limit behind which a coefficient is set to 0. \a maxValAbs is expected to be positive, if not this method do nothing. - * \return a positive value that tells the number of coefficients put to 0. The 0 returned value means that the matrix has remained unchanged. - * \sa MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrix - */ -int MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) -{ - int ret=0; - std::vector > matrixNew(_matrix.size()); - int i=0; - for(std::vector >::const_iterator it1=_matrix.begin();it1!=_matrix.end();it1++,i++) - { - std::map& rowNew=matrixNew[i]; - for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - { - if(fabs((*it2).second)>maxValAbs) - rowNew[(*it2).first]=(*it2).second; - else - ret++; - } - } - if(ret>0) - _matrix=matrixNew; - return ret; -} - -/*! - * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. - * If not the behaviour is unpredictable. - * This method works on precomputed \a this->_matrix. All coefficients in the matrix is lower than delta multiplied by \a scaleFactor this coefficient is - * set to 0. That is to say that its entry disappear from the map storing the corresponding row in the data storage of sparse crude matrix. - * delta is the value returned by MEDCouplingRemapper::getMaxValueInCrudeMatrix method. - * This method is useful to correct at a high level some problems linked to precision. Indeed, with some \ref NatureOfField "natures of field" some threshold effect - * can occur. - * - * \param [in] scaleFactor is the scale factor from which coefficients lower than \a scaleFactor times range width of coefficients are set to zero. - * \return a positive value that tells the number of coefficients put to 0. The 0 returned value means that the matrix has remained unchanged. If -1 is returned it means - * that all coefficients are null. - * \sa MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrixAbs - */ -int MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) -{ - double maxVal=getMaxValueInCrudeMatrix(); - if(maxVal==0.) - return -1; - return nullifiedTinyCoeffInCrudeMatrixAbs(scaleFactor*maxVal); -} - -/*! - * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. - * If not the behaviour is unpredictable. - * This method returns the maximum of the absolute values of coefficients into the sparse crude matrix. - * The returned value is positive. - */ -double MEDCouplingRemapper::getMaxValueInCrudeMatrix() const -{ - double ret=0.; - for(std::vector >::const_iterator it1=_matrix.begin();it1!=_matrix.end();it1++) - for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - if(fabs((*it2).second)>ret) - ret=fabs((*it2).second); - return ret; -} diff --git a/medtool/src/MEDCoupling/MEDCouplingRemapper.hxx b/medtool/src/MEDCoupling/MEDCouplingRemapper.hxx deleted file mode 100644 index 61bee847d..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingRemapper.hxx +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGREMAPPER_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGREMAPPER_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "InterpolationOptions.hxx" -#include "MEDCouplingNatureOfField.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - class MEDCouplingFieldDouble; - class MEDCouplingFieldTemplate; -} - -namespace ParaMEDMEM -{ - typedef enum - { - IK_ONLY_PREFERED = 0, - NOT_IK_ONLY_PREFERED = 1, - IK_ONLY_FORCED = 2, - NOT_IK_ONLY_FORCED =3 - } InterpolationMatrixPolicy; - - class MEDCouplingRemapper : public TimeLabel, public INTERP_KERNEL::InterpolationOptions - { - public: - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingRemapper(); - MEDCOUPLINGREMAPPER_EXPORT ~MEDCouplingRemapper(); - MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method); - MEDCOUPLINGREMAPPER_EXPORT int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target); - MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT void partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField); - MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT bool setOptionInt(const std::string& key, int value); - MEDCOUPLINGREMAPPER_EXPORT bool setOptionDouble(const std::string& key, double value); - MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, const std::string& value); - MEDCOUPLINGREMAPPER_EXPORT int getInterpolationMatrixPolicy() const; - MEDCOUPLINGREMAPPER_EXPORT void setInterpolationMatrixPolicy(int newInterpMatPol); - // - MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs); - MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor); - MEDCOUPLINGREMAPPER_EXPORT double getMaxValueInCrudeMatrix() const; - public: - MEDCOUPLINGREMAPPER_EXPORT const std::vector >& getCrudeMatrix() const; - MEDCOUPLINGREMAPPER_EXPORT int getNumberOfColsOfMatrix() const; - MEDCOUPLINGREMAPPER_EXPORT static void PrintMatrix(const std::vector >& m); - MEDCOUPLINGREMAPPER_EXPORT static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2); - private: - int prepareInterpKernelOnly(); - int prepareInterpKernelOnlyUU(); - int prepareInterpKernelOnlyEE(); - int prepareInterpKernelOnlyUC(); - int prepareInterpKernelOnlyCU(); - int prepareInterpKernelOnlyCC(); - // - int prepareNotInterpKernelOnly(); - int prepareNotInterpKernelOnlyGaussGauss(); - // - static int CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method); - // - bool isInterpKernelOnlyOrNotOnly() const; - void updateTime() const; - void checkPrepare() const; - std::string checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const; - void releaseData(bool matrixSuppression); - void transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue); - void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); - void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); - void computeProduct(const double *inputPointer, int inputNbOfCompo, bool isDftVal, double dftValue, double *resPointer); - void computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer); - void buildFinalInterpolationMatrixByConvolution(const std::vector< std::map >& m1D, - const std::vector< std::map >& m2D, - const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc, - const int *corrCellIdTrg); - static void ReverseMatrix(const std::vector >& matIn, int nbColsMatIn, - std::vector >& matOut); - static void ComputeRowSumAndColSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse); - static void ComputeColSumAndRowSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse); - private: - MEDCouplingAutoRefCountObjectPtr _src_ft; - MEDCouplingAutoRefCountObjectPtr _target_ft; - InterpolationMatrixPolicy _interp_matrix_pol; - NatureOfField _nature_of_deno; - unsigned int _time_deno_update; - std::vector > _matrix; - std::vector > _deno_multiply; - std::vector > _deno_reverse_multiply; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.cxx b/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.cxx deleted file mode 100644 index 87f1bae2d..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.cxx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDCouplingSkyLineArray.hxx" - -using namespace ParaMEDMEM; - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(): - _index( DataArrayInt::New() ), _value( DataArrayInt::New() ) -{ -} - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(const MEDCouplingSkyLineArray &myArray) -{ - _index=myArray._index; - _value=myArray._value; -} - -MEDCouplingSkyLineArray::~MEDCouplingSkyLineArray() -{ -} - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(DataArrayInt* index, DataArrayInt* value) -{ - set( index, value ); -} - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray( const std::vector& index, - const std::vector& value ): - _index( DataArrayInt::New() ), _value( DataArrayInt::New() ) -{ - _index->reserve( index.size() ); - _index->insertAtTheEnd( index.begin(), index.end() ); - _value->reserve( value.size() ); - _value->insertAtTheEnd( value.begin(), value.end() ); -} - -void MEDCouplingSkyLineArray::set( DataArrayInt* index, DataArrayInt* value ) -{ - _index=index; - _value=value; - if ( (DataArrayInt*)_index ) _index->incrRef(); - else _index = DataArrayInt::New(); - if ( (DataArrayInt*)_value ) _value->incrRef(); - else _value = DataArrayInt::New(); -} - -DataArrayInt* MEDCouplingSkyLineArray::getIndexArray() const -{ - return ((MEDCouplingSkyLineArray*)this)->_index; -} - -DataArrayInt* MEDCouplingSkyLineArray::getValueArray() const -{ - return ((MEDCouplingSkyLineArray*)this)->_value; -} - -std::string MEDCouplingSkyLineArray::simpleRepr() const -{ - std::ostringstream oss; - oss << "MEDCouplingSkyLineArray" << std::endl; - oss << " Nb of items: " << getNumberOf() << std::endl; - oss << " Nb of values: " << getLength() << std::endl; - oss << " Index:" << std::endl; - oss << " "; - const int * i = _index->begin(); - for ( ; i != _index->end(); ++i ) - oss << *i << " "; - oss << std::endl; - oss << " Value:" << std::endl; - oss << " "; - const int * v = _value->begin(); - int cnt = 0; - for ( i = _index->begin(); v != _value->end(); ++v, ++cnt ) - { - if ( cnt == *i ) - { - oss << "| "; - ++i; - } - oss << *v << " "; - } - oss << std::endl; - - return oss.str(); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.hxx b/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.hxx deleted file mode 100644 index c12dc6b68..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCOUPLING_EXPORT MEDCouplingSkyLineArray - { - private: - MEDCouplingAutoRefCountObjectPtr _index; - MEDCouplingAutoRefCountObjectPtr _value; - public: - MEDCouplingSkyLineArray(); - MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray ); - MEDCouplingSkyLineArray( const std::vector& index, const std::vector& value ); - MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value ); - ~MEDCouplingSkyLineArray(); - - void set( DataArrayInt* index, DataArrayInt* value ); - - int getNumberOf() const { return _index->getNbOfElems()-1; } - int getLength() const { return _value->getNbOfElems(); } - const int* getIndex() const { return _index->begin(); } - const int* getValue() const { return _value->begin(); } - - DataArrayInt* getIndexArray() const; - DataArrayInt* getValueArray() const; - - std::string simpleRepr() const; - }; -} -# endif diff --git a/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.cxx deleted file mode 100644 index ceec53712..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ /dev/null @@ -1,2109 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingStructuredMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingIMesh.hxx"//tony to throw when optimization will be performed in AssignPartOfFieldOfDoubleUsing - -#include - -using namespace ParaMEDMEM; - -MEDCouplingStructuredMesh::MEDCouplingStructuredMesh() -{ -} - -MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other) -{ -} - -MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh() -{ -} - -std::size_t MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); -} - -void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - MEDCouplingMesh::copyTinyStringsFrom(other); -} - -bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const -{ - return GetGeoTypeGivenMeshDimension(getMeshDimension()); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(int meshDim) -{ - switch(meshDim) - { - case 3: - return INTERP_KERNEL::NORM_HEXA8; - case 2: - return INTERP_KERNEL::NORM_QUAD4; - case 1: - return INTERP_KERNEL::NORM_SEG2; - case 0: - return INTERP_KERNEL::NORM_POINT1; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension !"); - } -} - -std::set MEDCouplingStructuredMesh::getAllGeoTypes() const -{ - std::set ret2; - ret2.insert(getTypeOfCell(0)); - return ret2; -} - -int MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - int ret=getNumberOfCells(); - if(type==getTypeOfCell(0)) - return ret; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getNumberOfCellsWithType : no specified type ! Type available is " << cm.getRepr() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - if(getTypeOfCell(0)==type) - { - ret->alloc(getNumberOfCells(),1); - ret->iota(0); - } - else - ret->alloc(0,1); - return ret.retn(); -} - -DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const -{ - int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbCells,1); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); - ret->fillWithValue((int)cm.getNumberOfNodes()); - return ret.retn(); -} - -DataArrayInt *MEDCouplingStructuredMesh::computeNbOfFacesPerCell() const -{ - int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbCells,1); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); - ret->fillWithValue((int)cm.getNumberOfSons()); - return ret.retn(); -} - -/*! - * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, - * will be counted only once here whereas it will be counted several times in MEDCouplingMesh::computeNbOfNodesPerCell method. - * Here for structured mesh it returns exactly as MEDCouplingStructuredMesh::computeNbOfNodesPerCell does. - * - * \return DataArrayInt * - new object to be deallocated by the caller. - */ -DataArrayInt *MEDCouplingStructuredMesh::computeEffectiveNbOfNodesPerCell() const -{ - return computeNbOfNodesPerCell(); -} - -void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int meshDim=getMeshDimension(); - int tmpCell[3],tmpNode[3]; - getSplitCellValues(tmpCell); - getSplitNodeValues(tmpNode); - int tmp2[3]; - GetPosFromId(cellId,meshDim,tmpCell,tmp2); - switch(meshDim) - { - case 1: - conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); - break; - case 2: - conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]); - break; - case 3: - conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); - conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !"); - }; -} - -/*! - * This method returns the mesh dimension of \a this. It can be different from space dimension in case of a not null dimension contains only one node. - */ -int MEDCouplingStructuredMesh::getMeshDimension() const -{ - std::vector ngs(getNodeGridStructure()); - int ret(0),pos(0); - for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++,pos++) - { - if(*it<=0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getMeshDimension : At pos #" << pos << " number of nodes is " << *it << " ! Must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(*it>1) - ret++; - } - return ret; -} - -/*! - * This method returns the space dimension by only considering the node grid structure. - * For cartesian mesh the returned value is equal to those returned by getSpaceDimension. - * But for curvelinear is could be different ! - */ -int MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct() const -{ - std::vector nodeStr(getNodeGridStructure()); - int spd1(0),pos(0); - for(std::vector::const_iterator it=nodeStr.begin();it!=nodeStr.end();it++,pos++) - { - int elt(*it); - if(elt<=0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct : At pos #" << pos << " value of node grid structure is " << *it << " ! must be >=1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - spd1++; - } - return spd1; -} - -void MEDCouplingStructuredMesh::getSplitCellValues(int *res) const -{ - std::vector strct(getCellGridStructure()); - std::vector ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct)); - std::copy(ret.begin(),ret.end(),res); -} - -void MEDCouplingStructuredMesh::getSplitNodeValues(int *res) const -{ - std::vector strct(getNodeGridStructure()); - std::vector ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct)); - std::copy(ret.begin(),ret.end(),res); -} - -/*! - * This method returns the number of cells of unstructured sub level mesh, without building it. - */ -int MEDCouplingStructuredMesh::getNumberOfCellsOfSubLevelMesh() const -{ - std::vector cgs(getCellGridStructure()); - return GetNumberOfCellsOfSubLevelMesh(cgs,getMeshDimension()); -} - -/*! - * See MEDCouplingUMesh::getDistributionOfTypes for more information - */ -std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const -{ - //only one type of cell - std::vector ret(3); - ret[0]=getTypeOfCell(0); - ret[1]=getNumberOfCells(); - ret[2]=-1; //ret[3*k+2]==-1 because it has no sense here - return ret; -} - -/*! - * This method tries to minimize at most the number of deep copy. - * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. - * - * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information - */ -DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - int nbOfCells=getNumberOfCells(); - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); - if(code[0]!=(int)getTypeOfCell(0)) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getTypeOfCell(0) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(code[2]==-1) - { - if(code[1]==nbOfCells) - return 0; - else - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(code[2]!=0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); - if(idsPerType.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); - const DataArrayInt *pfl=idsPerType[0]; - if(!pfl) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); - if(pfl->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); - pfl->checkAllIdsInRange(0,nbOfCells); - pfl->incrRef(); - return const_cast(pfl); -} - -/*! - * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. - * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. - * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. - * - * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. - * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, - * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] - * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. - * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. - * - * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. - * - * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined - * - * \b Example1:
- * - Before \a this has 3 cells \a profile contains [0,1,2] - * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty
- * - * \b Example2:
- * - Before \a this has 3 cells \a profile contains [1,2] - * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
- - */ -void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - if(!profile || !profile->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile is NULL or not allocated !"); - if(profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile should have exactly one component !"); - int nbTuples(profile->getNumberOfTuples()); - int nbOfCells=getNumberOfCells(); - code.resize(3); idsInPflPerType.resize(1); - code[0]=(int)getTypeOfCell(0); code[1]=nbOfCells; - idsInPflPerType.resize(1); - if(profile->isIdentity2(nbOfCells)) - { - code[2]=-1; - idsInPflPerType[0]=profile->deepCpy(); - idsPerType.clear(); - return ; - } - code[1]=profile->getNumberOfTuples(); - code[2]=0; - profile->checkAllIdsInRange(0,nbOfCells); - idsPerType.resize(1); - idsPerType[0]=profile->deepCpy(); - idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); -} - -/*! - * Creates a new unstructured mesh (MEDCoupling1SGTUMesh) from \a this structured one. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If \a this->getMeshDimension() is not among [1,2,3]. - */ -MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTUnstructured() const -{ - int meshDim(getMeshDimension()),spaceDim(getSpaceDimensionOnNodeStruct()); - if((meshDim<0 || meshDim>3) || (spaceDim<0 || spaceDim>3)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTUnstructured : meshdim and spacedim must be in [1,2,3] !"); - MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); - int ns[3]; - getNodeGridStructure(ns); - MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivity(ns,ns+spaceDim)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim))); - ret->setNodalConnectivity(conn); ret->setCoords(coords); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -/*! - * This method returns the unstructured mesh (having single geometric type) of the sub level mesh of \a this. - * This method is equivalent to computing MEDCouplingUMesh::buildDescendingConnectivity on the unstructurized \a this mesh. - * - * The caller is to delete the returned mesh using decrRef() as it is no more needed. - */ -MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTSubLevelMesh() const -{ - int meshDim(getMeshDimension()); - if(meshDim<1 || meshDim>3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTSubLevelMesh : meshdim must be in [2,3] !"); - MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); - int ns[3]; - getNodeGridStructure(ns); - MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivityOfSubLevelMesh(ns,ns+meshDim)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim-1))); - ret->setNodalConnectivity(conn); ret->setCoords(coords); - return ret.retn(); -} - -/*! - * Creates a new unstructured mesh (MEDCouplingUMesh) from \a this structured one. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If \a this->getMeshDimension() is not among [1,2,3]. - */ -MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr ret0(build1SGTUnstructured()); - return ret0->buildUnstructured(); -} - -/*! - * Creates a new MEDCouplingUMesh containing a part of cells of \a this mesh. - * The cells to include to the - * result mesh are specified by an array of cell ids. - * \param [in] start - an array of cell ids to include to the result mesh. - * \param [in] end - specifies the end of the array \a start, so that - * the last value of \a start is \a end[ -1 ]. - * \return MEDCouplingMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDCouplingStructuredMesh::buildPart(const int *start, const int *end) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPart(start,end); - um->decrRef(); - return ret; -} - -MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - std::vector cgs(getCellGridStructure()); - std::vector< std::pair > cellPartFormat,nodePartFormat; - if(IsPartStructured(start,end,cgs,cellPartFormat)) - { - MEDCouplingAutoRefCountObjectPtr ret(buildStructuredSubPart(cellPartFormat)); - nodePartFormat=cellPartFormat; - for(std::vector< std::pair >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) - (*it).second++; - MEDCouplingAutoRefCountObjectPtr tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); - MEDCouplingAutoRefCountObjectPtr tmp2(DataArrayInt::New()); tmp2->alloc(getNumberOfNodes(),1); - tmp2->fillWithValue(-1); - MEDCouplingAutoRefCountObjectPtr tmp3(DataArrayInt::New()); tmp3->alloc(tmp1->getNumberOfTuples(),1); tmp3->iota(0); - tmp2->setPartOfValues3(tmp3,tmp1->begin(),tmp1->end(),0,1,1); - arr=tmp2.retn(); - return ret.retn(); - } - else - { - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); - um->decrRef(); - return ret; - } -} - -DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) -{ - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::simplexize : not available for Cartesian mesh !"); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding normal vectors to cells of \a this - * 2D mesh. The computed vectors have 3 components and are normalized. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time. The caller is to delete this field using decrRef() as - * it is no more needed. - * \throw If \a this->getMeshDimension() != 2. - */ -MEDCouplingFieldDouble *MEDCouplingStructuredMesh::buildOrthogonalField() const -{ - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("Expected a MEDCouplingStructuredMesh with meshDim == 2 !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - array->alloc(nbOfCells,3); - double *vals=array->getPointer(); - for(int i=0;isetArray(array); - array->decrRef(); - ret->setMesh(this); - return ret; -} - -void MEDCouplingStructuredMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - std::vector ngs(getNodeGridStructure()); - int dim(getSpaceDimension()); - switch(dim) - { - case 1: - return GetReverseNodalConnectivity1(ngs,revNodal,revNodalIndx); - case 2: - return GetReverseNodalConnectivity2(ngs,revNodal,revNodalIndx); - case 3: - return GetReverseNodalConnectivity3(ngs,revNodal,revNodalIndx); - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getReverseNodalConnectivity : only dimensions 1, 2 and 3 are supported !"); - } -} - -void MEDCouplingStructuredMesh::GetReverseNodalConnectivity1(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) -{ - int nbNodes(ngs[0]); - revNodalIndx->alloc(nbNodes+1,1); - if(nbNodes==0) - { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } - if(nbNodes==1) - { revNodal->alloc(1,1); revNodal->setIJ(0,0,0); revNodalIndx->setIJ(0,0,0); revNodalIndx->setIJ(1,0,1); return ; } - revNodal->alloc(2*(nbNodes-1),1); - int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); - *rni++=0; *rni=1; *rn++=0; - for(int i=1;i& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) -{ - int nbNodesX(ngs[0]),nbNodesY(ngs[1]); - int nbNodes(nbNodesX*nbNodesY); - if(nbNodesX==0 || nbNodesY==0) - { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } - if(nbNodesX==1 || nbNodesY==1) - { std::vector ngs2(1); ngs2[0]=std::max(nbNodesX,nbNodesY); return GetReverseNodalConnectivity1(ngs2,revNodal,revNodalIndx); } - revNodalIndx->alloc(nbNodes+1,1); - int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1); - revNodal->alloc(4*(nbNodesX-2)*(nbNodesY-2)+2*2*(nbNodesX-2)+2*2*(nbNodesY-2)+4,1); - int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); - *rni++=0; *rni=1; *rn++=0; - for(int i=1;i& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) -{ - int nbNodesX(ngs[0]),nbNodesY(ngs[1]),nbNodesZ(ngs[2]); - int nbNodes(nbNodesX*nbNodesY*nbNodesZ); - if(nbNodesX==0 || nbNodesY==0 || nbNodesZ==0) - { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } - if(nbNodesX==1 || nbNodesY==1 || nbNodesZ==1) - { - std::vector ngs2(2); - int pos(0); - bool pass(false); - for(int i=0;i<3;i++) - { - if(pass) - { ngs2[pos++]=ngs[i]; } - else - { - pass=ngs[i]==1; - if(!pass) - { ngs2[pos++]=ngs[i]; } - } - } - return GetReverseNodalConnectivity2(ngs2,revNodal,revNodalIndx); - } - revNodalIndx->alloc(nbNodes+1,1); - int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1),nbCellsZ(nbNodesZ-1); - revNodal->alloc(8*(nbNodesX-2)*(nbNodesY-2)*(nbNodesZ-2)+4*(2*(nbNodesX-2)*(nbNodesY-2)+2*(nbNodesX-2)*(nbNodesZ-2)+2*(nbNodesY-2)*(nbNodesZ-2))+2*4*(nbNodesX-2)+2*4*(nbNodesY-2)+2*4*(nbNodesZ-2)+8,1); - int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); - *rni=0; - for(int k=0;k=1 && j>=1 && i>=1) - *rn++=off00+i-1; - if(k>=1 && j>=1 && i=1 && j=1) - *rn++=off01+i-1; - if(k>=1 && j=1 && i>=1) - *rn++=off10+i-1; - if(k=1 && i=1) - *rn++=off11+i-1; - if(k conn(DataArrayInt::New()); - conn->alloc(1,1); conn->setIJ(0,0,0); - return conn.retn(); - } - case 1: - return Build1GTNodalConnectivity1D(zippedNodeSt); - case 2: - return Build1GTNodalConnectivity2D(zippedNodeSt); - case 3: - return Build1GTNodalConnectivity3D(zippedNodeSt); - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivity : only dimension in [0,1,2,3] supported !"); - } -} - -DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd) -{ - std::size_t dim(std::distance(nodeStBg,nodeStEnd)); - switch(dim) - { - case 3: - return Build1GTNodalConnectivityOfSubLevelMesh3D(nodeStBg); - case 2: - return Build1GTNodalConnectivityOfSubLevelMesh2D(nodeStBg); - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh: only dimension in [2,3] supported !"); - } -} - -/*! - * This method returns the list of ids sorted ascendingly of entities that are in the corner in ghost zone. - * The ids are returned in a newly created DataArrayInt having a single component. - * - * \param [in] st - The structure \b without ghost cells. - * \param [in] ghostLev - The size of the ghost zone (>=0) - * \return DataArrayInt * - The DataArray containing all the ids the caller is to deallocate. - */ -DataArrayInt *MEDCouplingStructuredMesh::ComputeCornersGhost(const std::vector& st, int ghostLev) -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : ghost lev must be >= 0 !"); - std::size_t dim(st.size()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - switch(dim) - { - case 1: - { - ret->alloc(2*ghostLev,1); - int *ptr(ret->getPointer()); - for(int i=0;i= 0 !"); - for(int i=0;i= 0 !"); - ret->alloc(4*ghostLev,1); - int *ptr(ret->getPointer()); - for(int i=0;i= 0 !"); - ret->alloc(8*ghostLev,1); - int *ptr(ret->getPointer()); - int zeOffsetZ((offsetX+2*ghostLev)*(offsetY+2*ghostLev)); - for(int i=0;i=0;i--,j++) - { - *ptr++=i*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; - *ptr++=offsetX+2*ghostLev-1+i*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; - *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+ghostLev-1+(ghostLev-i-1)*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; - *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+offsetX+ghostLev+(ghostLev-i-1)*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : Only dimensions 1, 2 and 3 are supported actually !"); - } - return ret.retn(); -} - -/*! - * This method retrieves the number of entities (it can be cells or nodes) given a range in compact standard format - * used in methods like BuildExplicitIdsFrom,IsPartStructured. - * - * \sa BuildExplicitIdsFrom,IsPartStructured - */ -int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat) -{ - int ret(1); - std::size_t ii(0); - for(std::vector< std::pair >::const_iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,ii++) - { - int a((*it).first),b((*it).second); - if(a<0 || b<0 || b-a<0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt : invalid input at dimension " << ii << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret*=(b-a); - } - return ret; -} - -int MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(const std::vector& st) -{ - int ret(1); - bool isFetched(false); - for(std::size_t i=0;i >& partCompactFormat, int& axisId, int& sizeOfRange) -{ - int dim((int)partCompactFormat.size()); - int ret(-1); - for(int i=0;iret) - { - axisId=i; sizeOfRange=curDelta; - ret=curDelta; - } - } -} - -/*! - * This method is \b NOT wrapped in python because it has no sense in python (for performance reasons). - * This method starts from a structured mesh with structure \a st on which a boolean field \a crit is set. - * This method find for such minimalist information of mesh and field which is the part of the mesh, given by the range per axis in output parameter - * \a partCompactFormat that contains all the True in \a crit. The returned vector of boolean is the field reduced to that part. - * So the number of True is equal in \a st and in returned vector of boolean. - * - * \param [in] minPatchLgth - minimum length that the patch may have for all directions. - * \param [in] st - The structure per axis of the structured mesh considered. - * \param [in] crit - The field of boolean (for performance reasons) lying on the mesh defined by \a st. - * \param [out] partCompactFormat - The minimal part of \a st containing all the true of \a crit. - * \param [out] reducedCrit - The reduction of \a criterion on \a partCompactFormat. - * \return - The number of True in \a st (that is equal to those in \a reducedCrit) - */ -int MEDCouplingStructuredMesh::FindMinimalPartOf(int minPatchLgth, const std::vector& st, const std::vector& crit, std::vector& reducedCrit, std::vector< std::pair >& partCompactFormat) -{ - if(minPatchLgth<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : the input minPatchLgth has to be >=0 !"); - if((int)crit.size()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : size of vector of boolean is invalid regarding the declared structure !"); - int ret(-1); - switch((int)st.size()) - { - case 1: - { - ret=FindMinimalPartOf1D(st,crit,partCompactFormat); - break; - } - case 2: - { - ret=FindMinimalPartOf2D(st,crit,partCompactFormat); - break; - } - case 3: - { - ret=FindMinimalPartOf3D(st,crit,partCompactFormat); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : only dimension 1, 2 and 3 are supported actually !"); - } - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(partCompactFormat)); - int i(0); - for(std::vector< std::pair >::iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,i++) - { - if(st[i]st[i]) - { - (*it).first-=(*it).second-st[i]; - (*it).second=st[i]; - } - } - } - ExtractFieldOfBoolFrom(st,crit,partCompactFormat,reducedCrit); - return ret; -} - -/*! - * This method is \b NOT wrapped in python. - * This method considers \a crit input parameter as a matrix having dimensions specified by \a st. This method returns for each axis - * the signature, that is to say the number of elems equal to true in \a crit along this axis. - */ -std::vector< std::vector > MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(const std::vector& st, const std::vector& crit) -{ - int dim((int)st.size()); - std::vector< std::vector > ret(dim); - switch(dim) - { - case 1: - { - int nx(st[0]); - ret[0].resize(nx); - std::vector& retX(ret[0]); - for(int i=0;i& retX(ret[0]); - for(int i=0;i& retY(ret[1]); - for(int j=0;j& retX(ret[0]); - for(int i=0;i& retY(ret[1]); - for(int j=0;j& retZ(ret[2]); - for(int k=0;k conn(DataArrayInt::New()); - conn->alloc(2*nbOfCells,1); - int *cp=conn->getPointer(); - for(int i=0;i conn(DataArrayInt::New()); - conn->alloc(4*n1*n2,1); - int *cp=conn->getPointer(); - int pos=0; - for(int j=0;j conn(DataArrayInt::New()); - conn->alloc(8*n1*n2*n3,1); - int *cp=conn->getPointer(); - int pos=0; - for(int k=0;k ngs(3); - int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1),n2(nodeStBg[2]-1); ngs[0]=n0; ngs[1]=n1; ngs[2]=n2; - int off0(nodeStBg[0]),off1(nodeStBg[0]*nodeStBg[1]); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - conn->alloc(4*GetNumberOfCellsOfSubLevelMesh(ngs,3)); - int *cp(conn->getPointer()); - //X - for(int i=0;i& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf1D : the input size of st must be equal to 1 !"); - int nxMin(std::numeric_limits::max()),nxMax(-std::numeric_limits::max()); - int nx(st[0]),ret(0); - for(int i=0;i& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf2D : the input size of st must be equal to 2 !"); - int nxMin(std::numeric_limits::max()),nxMax(-std::numeric_limits::max()),nyMin(std::numeric_limits::max()),nyMax(-std::numeric_limits::max()); - int it(0),nx(st[0]),ny(st[1]); - int ret(0); - for(int i=0;i& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf3D : the input size of st must be equal to 3 !"); - int nxMin(std::numeric_limits::max()),nxMax(-std::numeric_limits::max()),nyMin(std::numeric_limits::max()),nyMax(-std::numeric_limits::max()),nzMin(std::numeric_limits::max()),nzMax(-std::numeric_limits::max()); - int it(0),nx(st[0]),ny(st[1]),nz(st[2]); - int ret(0); - for(int i=0;i3 || spaceDim<1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ZipNodeStructure : spaceDim must in [1,2,3] !"); - zipNodeSt[0]=0; zipNodeSt[1]=0; zipNodeSt[2]=0; - int zippedI(0); - for(int i=0;i=2) - zipNodeSt[zippedI++]=elt; - } - return zippedI; -} - -DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg) -{ - std::vector ngs(2); - int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1); ngs[0]=n0; ngs[1]=n1; - int off0(nodeStBg[0]); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - conn->alloc(2*GetNumberOfCellsOfSubLevelMesh(ngs,2)); - int *cp(conn->getPointer()); - //X - for(int i=0;i()); - return std::accumulate(tmp,tmp+meshDim,0); -} - -/*! - * Returns a node id by its (i,j,k) index. - * \param [in] i - a index of node coordinates array along X axis. - * \param [in] j - a index of node coordinates array along Y axis. - * \param [in] k - a index of node coordinates array along Z axis. - * \return int - a node id in \a this mesh. - */ -int MEDCouplingStructuredMesh::getNodeIdFromPos(int i, int j, int k) const -{ - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim(getSpaceDimension()); - getSplitNodeValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - - -int MEDCouplingStructuredMesh::getNumberOfCells() const -{ - std::vector ngs(getNodeGridStructure()); - int ret(1); - bool isCatched(false); - std::size_t ii(0); - for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++,ii++) - { - int elt(*it); - if(elt<=0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getNumberOfCells : at pos #" << ii << " the number of nodes in nodeStructure is " << *it << " ! Must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(elt>1) - { - ret*=elt-1; - isCatched=true; - } - } - return isCatched?ret:0; -} - -int MEDCouplingStructuredMesh::getNumberOfNodes() const -{ - std::vector ngs(getNodeGridStructure()); - int ret(1); - for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++) - ret*=*it; - return ret; -} - -/*! - * This method returns for a cell which id is \a cellId the location (locX,locY,locZ) of this cell in \a this. - * - * \param [in] cellId - * \return - A vector of size this->getMeshDimension() - * \throw if \a cellId not in [ 0, this->getNumberOfCells() ) - */ -std::vector MEDCouplingStructuredMesh::getLocationFromCellId(int cellId) const -{ - int meshDim(getMeshDimension()); - std::vector ret(meshDim); - std::vector struc(getCellGridStructure()); - int nbCells(std::accumulate(struc.begin(),struc.end(),1,std::multiplies())); - if(cellId<0 || cellId>=nbCells) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromCellId : Input cell id (" << cellId << ") is invalid ! Should be in [0," << nbCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector spt(GetSplitVectFromStruct(struc)); - GetPosFromId(cellId,meshDim,&spt[0],&ret[0]); - return ret; -} - -/*! - * This method returns for a node which id is \a nodeId the location (locX,locY,locZ) of this node in \a this. - * - * \param [in] nodeId - * \return - A vector of size this->getSpaceDimension() - * \throw if \a cellId not in [ 0, this->getNumberOfNodes() ) - */ -std::vector MEDCouplingStructuredMesh::getLocationFromNodeId(int nodeId) const -{ - int spaceDim(getSpaceDimension()); - std::vector ret(spaceDim); - std::vector struc(getNodeGridStructure()); - int nbNodes(std::accumulate(struc.begin(),struc.end(),1,std::multiplies())); - if(nodeId<0 || nodeId>=nbNodes) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromNodeId : Input node id (" << nodeId << ") is invalid ! Should be in [0," << nbNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector spt(GetSplitVectFromStruct(struc)); - GetPosFromId(nodeId,spaceDim,&spt[0],&ret[0]); - return ret; -} - -void MEDCouplingStructuredMesh::GetPosFromId(int eltId, int meshDim, const int *split, int *res) -{ - int work(eltId); - for(int i=meshDim-1;i>=0;i--) - { - int pos=work/split[i]; - work=work%split[i]; - res[i]=pos; - } -} - -std::vector MEDCouplingStructuredMesh::getCellGridStructure() const -{ - std::vector ret(getNodeGridStructure()); - std::transform(ret.begin(),ret.end(),ret.begin(),std::bind2nd(std::plus(),-1)); - return ret; -} - -/*! - * This method returns the squareness of \a this (quadrature). \a this is expected to be with a mesh dimension equal to 2 or 3. - */ -double MEDCouplingStructuredMesh::computeSquareness() const -{ - std::vector cgs(getCellGridStructure()); - if(cgs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : empty mesh !"); - std::size_t dim(cgs.size()); - if(dim==1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : A segment cannot be square !"); - if(dim<4) - { - int minAx(cgs[0]),maxAx(cgs[0]); - for(std::size_t i=1;i MEDCouplingStructuredMesh::GetSplitVectFromStruct(const std::vector& strct) -{ - int spaceDim((int)strct.size()); - std::vector res(spaceDim); - for(int l=0;l& st, std::vector< std::pair >& partCompactFormat) -{ - int dim((int)st.size()); - partCompactFormat.resize(dim); - if(dim<1 || dim>3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::isPartStructured : input structure must be of dimension in [1,2,3] !"); - std::vector tmp2(dim),tmp(dim),tmp3(dim),tmp4(dim); tmp2[0]=1; - for(int i=1;i=st[dim-1]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : first id in input is not in valid range !"); - if(sz==1) - { - for(int i=0;i=st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : last id in input is not in valid range !"); - partCompactFormat[i].second=tmp3[i]+1; - tmp4[i]=partCompactFormat[i].second-partCompactFormat[i].first; - if(tmp4[i]<=0) - return false; - szExp*=tmp4[i]; - } - if(szExp!=(int)sz) - return false; - const int *w(startIds); - switch(dim) - { - case 3: - { - for(int i=0;i MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(const std::vector< std::pair >& partCompactFormat) -{ - std::vector ret(partCompactFormat.size()); - for(std::size_t i=0;ipartCompactFormat[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt : For axis #" << i << " end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret[i]=partCompactFormat[i].second-partCompactFormat[i].first; - } - return ret; -} - -/*! - * This method takes in input a vector giving the number of entity per axis and returns for each axis a range starting from [0,0...] - * - * \throw if there is an axis in \a dims that is < 0. - * \sa GetDimensionsFromCompactFrmt, ChangeReferenceFromGlobalOfCompactFrmt, ChangeReferenceToGlobalOfCompactFrmt - */ -std::vector< std::pair > MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(const std::vector& dims) -{ - std::size_t sz(dims.size()); - std::vector< std::pair > ret(sz); - for(std::size_t i=0;i > MEDCouplingStructuredMesh::IntersectRanges(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2) -{ - std::size_t sz(r1.size()); - if(sz!=r2.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IntersectRanges : the two ranges must have the same dimension !"); - std::vector< std::pair > ret(sz); - for(std::size_t i=0;ir1[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r1, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(r2[i].first>r2[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r2, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret[i].first=std::max(r1[i].first,r2[i].first); - ret[i].second=std::min(r1[i].second,r2[i].second); - if(ret[i].first>ret[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " the intersection of r1 and r2 is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -/*! - * This method states if \a r1 and \a r2 do overlap of not. If yes you can call IntersectRanges to know the intersection area. - * - * \sa IntersectRanges - */ -bool MEDCouplingStructuredMesh::AreRangesIntersect(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2) -{ - std::size_t sz(r1.size()); - if(sz!=r2.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::AreRangesIntersect : the two ranges must have the same dimension !"); - for(std::size_t i=0;ir1[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r1, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(r2[i].first>r2[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r2, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(r1[i].second<=r2[i].first) - return false; - if(r1[i].first>=r2[i].second) - return false; - } - return true; -} - -/*! - * This method is close to BuildExplicitIdsFrom except that instead of returning a DataArrayInt instance containing explicit ids it - * enable elems in the vector of booleans (for performance reasons). As it is method for performance, this method is \b not - * available in python. - * - * \param [in] st The entity structure. - * \param [in] partCompactFormat The compact subpart to be enabled. - * \param [in,out] vectToSwitchOn Vector which fetched items are enabled. - * - * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, ExtractFieldOfBoolFrom - */ -void MEDCouplingStructuredMesh::SwitchOnIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat, std::vector& vectToSwitchOn) -{ - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : input arrays must have the same size !"); - if((int)vectToSwitchOn.size()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : invalid size of input vector of boolean regarding the structure !"); - std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, const std::vector& fieldOfBool, const std::vector< std::pair >& partCompactFormat, std::vector& fieldOut) -{ - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : input arrays must have the same size !"); - if((int)fieldOfBool.size()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : invalid size of input field of boolean regarding the structure !"); - std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); - int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)); - fieldOut.resize(nbOfTuplesOfOutField); - int it(0); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat) -{ - if(!fieldOfDbl || !fieldOfDbl->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input array of double is NULL or not allocated!"); - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input arrays must have the same size !"); - if(fieldOfDbl->getNumberOfTuples()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : invalid size of input array of double regarding the structure !"); - std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); - int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)),nbComp(fieldOfDbl->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp); - ret->copyStringInfoFrom(*fieldOfDbl); - double *ptRet(ret->getPointer()); - const double *fieldOfDblPtr(fieldOfDbl->begin()); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat, const DataArrayDouble *other) -{//to be optimized - std::vector facts(st.size(),1.); - MEDCouplingIMesh::CondenseFineToCoarse(st,other,partCompactFormat,facts,fieldOfDbl); -} - -/*! - * This method changes the reference of a part of structured mesh \a partOfBigInAbs define in absolute reference to a new reference \a bigInAbs. - * So this method only performs a translation by doing \a partOfBigRelativeToBig = \a partOfBigInAbs - \a bigInAbs - * This method also checks (if \a check=true) that \a partOfBigInAbs is included in \a bigInAbs. - * This method is useful to extract a part from a field lying on a big mesh. - * - * \sa ChangeReferenceToGlobalOfCompactFrmt, BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom - */ -void MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigInAbs, std::vector< std::pair >& partOfBigRelativeToBig, bool check) -{ - std::size_t dim(bigInAbs.size()); - if(dim!=partOfBigInAbs.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : The size of parts (dimension) must be the same !"); - partOfBigRelativeToBig.resize(dim); - for(std::size_t i=0;ibigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(partOfBigInAbs[i].first=bigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (start) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigRelativeToBig[i].first=partOfBigInAbs[i].first-bigInAbs[i].first; - if(check) - { - if(partOfBigInAbs[i].secondbigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (end) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigRelativeToBig[i].second=partOfBigInAbs[i].second-bigInAbs[i].first; - } -} - -/* - * This method is performs the opposite reference modification than explained in ChangeReferenceFromGlobalOfCompactFrmt. - * - * \sa ChangeReferenceFromGlobalOfCompactFrmt - */ -void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigRelativeToBig, std::vector< std::pair >& partOfBigInAbs, bool check) -{ - std::size_t dim(bigInAbs.size()); - if(dim!=partOfBigRelativeToBig.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : The size of parts (dimension) must be the same !"); - partOfBigInAbs.resize(dim); - for(std::size_t i=0;ibigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(partOfBigRelativeToBig[i].first<0 || partOfBigRelativeToBig[i].first>=bigInAbs[i].second-bigInAbs[i].first) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the start of part is not in the big one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigInAbs[i].first=partOfBigRelativeToBig[i].first+bigInAbs[i].first; - if(check) - { - if(partOfBigRelativeToBig[i].secondbigInAbs[i].second-bigInAbs[i].first) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the end of part is not in the big one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigInAbs[i].second=partOfBigRelativeToBig[i].second+bigInAbs[i].first; - } -} - -/*! - * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part. - * - * \sa FindTranslationFrom - */ -std::vector< std::pair > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair >& part, const std::vector& translation) -{ - std::size_t sz(part.size()); - if(translation.size()!=sz) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::TranslateCompactFrmt : the sizes are not equal !"); - std::vector< std::pair > ret(sz); - for(std::size_t i=0;i MEDCouplingStructuredMesh::FindTranslationFrom(const std::vector< std::pair >& startingFrom, const std::vector< std::pair >& goingTo) -{ - std::size_t sz(startingFrom.size()); - if(goingTo.size()!=sz) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindTranslationFrom : the sizes are not equal !"); - std::vector< int > ret(sz); - for(std::size_t i=0;i& st, const std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : input arrays must have the same size !"); - int nbOfItems(1); - std::vector dims(st.size()); - for(std::size_t i=0;ist[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 1 !"); - if(partCompactFormat[i].second<0 || partCompactFormat[i].second>st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 2 !"); - if(partCompactFormat[i].second ret(DataArrayInt::New()); - ret->alloc(nbOfItems,1); - int *pt(ret->getPointer()); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, const std::vector< std::pair >& part, double factor, DataArrayDouble *da) -{ - if(!da || !da->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : DataArrayDouble instance must be not NULL and allocated !"); - if(st.size()!=part.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : input arrays must have the same size !"); - std::vector dims(st.size()); - for(std::size_t i=0;ist[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 1 !"); - if(part[i].second<0 || part[i].second>st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 2 !"); - if(part[i].secondgetNumberOfComponents()); - if(da->getNumberOfTuples()!=nbOfTuplesExp) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::MultiplyPartOf : invalid nb of tuples ! Expected " << nbOfTuplesExp << " having " << da->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - double *pt(da->getPointer()); - switch(st.size()) - { - case 3: - { - for(int i=0;i(),factor)); - } - } - } - break; - } - case 2: - { - for(int j=0;j(),factor)); - } - } - break; - } - case 1: - { - for(int k=0;k(),factor)); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : Dimension supported are 1,2 or 3 !"); - } -} - -/*! - * This method multiplies by \a factor values in tuples located by \a part in \a da. - * - * \param [in] st - the structure of grid ( \b without considering ghost cells). - * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. - * \param [in] ghostSize - \a ghostSize must be >= 0. - * \param [in] factor - the factor, the tuples in \a da will be multiply by. - * \param [in,out] da - The DataArray in wich only tuples specified by \a part will be modified. - * - * \sa MultiplyPartOf, PutInGhostFormat - */ -void MEDCouplingStructuredMesh::MultiplyPartOfByGhost(const std::vector& st, const std::vector< std::pair >& part, int ghostSize, double factor, DataArrayDouble *da) -{ - std::vector stWG; - std::vector< std::pair > partWG; - PutInGhostFormat(ghostSize,st,part,stWG,partWG); - MultiplyPartOf(stWG,partWG,factor,da); -} - -/*! - * This method multiplies by \a factor values in tuples located by \a part in \a da. - * - * \param [in] st - the structure of grid ( \b without considering ghost cells). - * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. - * \param [in] ghostSize - \a ghostSize must be >= 0. - * \param [out] stWithGhost - the structure considering ghost cells. - * \param [out] partWithGhost - the part considering the ghost cells. - * - * \sa MultiplyPartOf, PutInGhostFormat - */ -void MEDCouplingStructuredMesh::PutInGhostFormat(int ghostSize, const std::vector& st, const std::vector< std::pair >& part, std::vector& stWithGhost, std::vector< std::pair >&partWithGhost) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : ghost size must be >= 0 !"); - std::size_t dim(part.size()); - if(st.size()!=dim) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the dimension of input vectors must be the same !"); - for(std::size_t i=0;ipart[i].second || part[i].second>st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the specified part is invalid ! The begin must be >= 0 and <= end ! The end must be <= to the size at considered dimension !"); - stWithGhost.resize(st.size()); - std::transform(st.begin(),st.end(),stWithGhost.begin(),std::bind2nd(std::plus(),2*ghostSize)); - partWithGhost=part; - ApplyGhostOnCompactFrmt(partWithGhost,ghostSize); -} - -/*! - * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference. - * \param [in] ghostSize - the ghost size of zone for all axis. - */ -void MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !"); - std::size_t sz(partBeforeFact.size()); - for(std::size_t i=0;i& cgs, int mdim) -{ - int ret(0); - for(int i=0;i getAllGeoTypes() const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT std::vector getLocationFromCellId(int cellId) const; - MEDCOUPLING_EXPORT std::vector getLocationFromNodeId(int nodeId) const; - MEDCOUPLING_EXPORT static void GetPosFromId(int eltId, int meshDim, const int *split, int *res); - MEDCOUPLING_EXPORT static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim); - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - //tools - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *build1SGTUnstructured() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - //some useful methods - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const; - MEDCOUPLING_EXPORT int getCellIdFromPos(int i, int j, int k) const; - MEDCOUPLING_EXPORT int getNodeIdFromPos(int i, int j, int k) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT int getNumberOfCellsOfSubLevelMesh() const; - MEDCOUPLING_EXPORT int getSpaceDimensionOnNodeStruct() const; - MEDCOUPLING_EXPORT virtual void getNodeGridStructure(int *res) const = 0; - MEDCOUPLING_EXPORT virtual void getSplitCellValues(int *res) const; - MEDCOUPLING_EXPORT virtual void getSplitNodeValues(int *res) const; - MEDCOUPLING_EXPORT virtual std::vector getNodeGridStructure() const = 0; - MEDCOUPLING_EXPORT std::vector getCellGridStructure() const; - MEDCOUPLING_EXPORT double computeSquareness() const; - MEDCOUPLING_EXPORT virtual MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const = 0; - MEDCOUPLING_EXPORT static std::vector GetSplitVectFromStruct(const std::vector& strct); - MEDCOUPLING_EXPORT static bool IsPartStructured(const int *startIds, const int *stopIds, const std::vector& st, std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static std::vector GetDimensionsFromCompactFrmt(const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static std::vector< std::pair > GetCompactFrmtFromDimensions(const std::vector& dims); - MEDCOUPLING_EXPORT static std::vector< std::pair > IntersectRanges(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2); - MEDCOUPLING_EXPORT static bool AreRangesIntersect(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2); - MEDCOUPLING_EXPORT static void SwitchOnIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat, std::vector& vectToSwitchOn); - MEDCOUPLING_EXPORT static void ExtractFieldOfBoolFrom(const std::vector& st, const std::vector& fieldOfBool, const std::vector< std::pair >& partCompactFormat, std::vector& fieldOut); - MEDCOUPLING_EXPORT static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static void AssignPartOfFieldOfDoubleUsing(const std::vector& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat, const DataArrayDouble *other); - MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigInAbs, std::vector< std::pair >& partOfBigRelativeToBig, bool check=true); - MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigRelativeToBig, std::vector< std::pair >& partOfBigInAbs, bool check=true); - MEDCOUPLING_EXPORT static std::vector< std::pair > TranslateCompactFrmt(const std::vector< std::pair >& part, const std::vector& translation); - MEDCOUPLING_EXPORT static std::vector FindTranslationFrom(const std::vector< std::pair >& startingFrom, const std::vector< std::pair >& goingTo); - MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static void MultiplyPartOf(const std::vector& st, const std::vector< std::pair >& part, double factor, DataArrayDouble *da); - MEDCOUPLING_EXPORT static void MultiplyPartOfByGhost(const std::vector& st, const std::vector< std::pair >& part, int ghostSize, double factor, DataArrayDouble *da); - MEDCOUPLING_EXPORT static void PutInGhostFormat(int ghostSize, const std::vector& st, const std::vector< std::pair >& part, std::vector& stWithGhost, std::vector< std::pair >&partWithGhost); - MEDCOUPLING_EXPORT static void ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); - MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd); - MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeCornersGhost(const std::vector& st, int ghostLev); - MEDCOUPLING_EXPORT static int DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static int DeduceNumberOfGivenStructure(const std::vector& st); - MEDCOUPLING_EXPORT static void FindTheWidestAxisOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat, int& axisId, int& sizeOfRange); - MEDCOUPLING_EXPORT static int FindMinimalPartOf(int minPatchLgth, const std::vector& st, const std::vector& crit, std::vector& reducedCrit, std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static std::vector< std::vector > ComputeSignaturePerAxisOf(const std::vector& st, const std::vector& crit); - private: - static int GetNumberOfCellsOfSubLevelMesh(const std::vector& cgs, int mdim); - static void GetReverseNodalConnectivity1(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); - static void GetReverseNodalConnectivity2(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); - static void GetReverseNodalConnectivity3(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); - static DataArrayInt *Build1GTNodalConnectivity1D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivity2D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivity3D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh3D(const int *nodeStBg); - static int FindMinimalPartOf1D(const std::vector& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat); - static int FindMinimalPartOf2D(const std::vector& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat); - static int FindMinimalPartOf3D(const std::vector& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat); - protected: - static int ZipNodeStructure(const int *nodeStBg, const int *nodeStEnd, int zipNodeSt[3]); - protected: - MEDCOUPLING_EXPORT MEDCouplingStructuredMesh(); - MEDCOUPLING_EXPORT MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy); - MEDCOUPLING_EXPORT ~MEDCouplingStructuredMesh(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx deleted file mode 100644 index cb456a024..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ /dev/null @@ -1,2951 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMesh.hxx" - -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12; - -const char MEDCouplingNoTimeLabel::EXCEPTION_MSG[]="MEDCouplingNoTimeLabel::setTime : no time info attached."; - -const char MEDCouplingNoTimeLabel::REPR[]="No time label defined."; - -const char MEDCouplingWithTimeStep::EXCEPTION_MSG[]="No data on this time."; - -const char MEDCouplingWithTimeStep::REPR[]="One time label."; - -const char MEDCouplingConstOnTimeInterval::EXCEPTION_MSG[]="No data on this time."; - -const char MEDCouplingConstOnTimeInterval::REPR[]="Constant on a time interval."; - -const char MEDCouplingTwoTimeSteps::EXCEPTION_MSG[]="No data on this time."; - -const char MEDCouplingLinearTime::REPR[]="Linear time between 2 time steps."; - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDiscretization type) -{ - switch(type) - { - case MEDCouplingNoTimeLabel::DISCRETIZATION: - return new MEDCouplingNoTimeLabel; - case MEDCouplingWithTimeStep::DISCRETIZATION: - return new MEDCouplingWithTimeStep; - case MEDCouplingConstOnTimeInterval::DISCRETIZATION: - return new MEDCouplingConstOnTimeInterval; - case MEDCouplingLinearTime::DISCRETIZATION: - return new MEDCouplingLinearTime; - default: - throw INTERP_KERNEL::Exception("Time discretization not implemented yet"); - } -} - -void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - _time_tolerance=other._time_tolerance; - _time_unit=other._time_unit; -} - -void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) -{ - _time_unit=other._time_unit; - if(_array && other._array) - _array->copyStringInfoFrom(*other._array); -} - -void MEDCouplingTimeDiscretization::checkCoherency() const -{ - if(!_array) - throw INTERP_KERNEL::Exception("Field invalid because no values set !"); - if(_time_tolerance<0.) - throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !"); -} - -void MEDCouplingTimeDiscretization::updateTime() const -{ - if(_array) - updateTimeWith(*_array); -} - -std::size_t MEDCouplingTimeDiscretization::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_time_unit.capacity()); - return ret; -} - -std::vector MEDCouplingTimeDiscretization::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_array); - return ret; -} - -bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - std::ostringstream oss; oss.precision(15); - if(_time_unit!=other->_time_unit) - { - oss << "Field discretizations differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; - reason=oss.str(); - return false; - } - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - { - oss << "Field discretizations differ : this time tolerance = \"" << _time_tolerance << "\" and other time tolerance = \"" << other->_time_tolerance << "\" !"; - reason=oss.str(); - return false; - } - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - { - reason="Field discretizations differ : Only one timediscretization between the two this and other has a DataArrayDouble for values defined"; - return false; - } - if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) - return false; - if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - int nbC1=_array->getNumberOfComponents(); - int nbC2=other->_array->getNumberOfComponents(); - int nbMin=std::min(nbC1,nbC2); - if(nbC1!=nbC2 && nbMin!=1) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - int nbC1=_array->getNumberOfComponents(); - int nbC2=other->_array->getNumberOfComponents(); - if(nbC1!=nbC2 && nbC2!=1) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - if(!areStrictlyCompatible(other,reason)) - return false; - if(_array==other->_array) - return true; - return _array->isEqualIfNotWhy(*other->_array,prec,reason); -} - -bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const -{ - std::string reason; - return isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - std::string tmp; - if(!areStrictlyCompatible(other,tmp)) - return false; - if(_array==other->_array) - return true; - return _array->isEqualWithoutConsideringStr(*other->_array,prec); -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const -{ - MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(type); - ret->setTimeUnit(getTimeUnit()); - const DataArrayDouble *arrSrc=getArray(); - MEDCouplingAutoRefCountObjectPtr arr; - if(arrSrc) - arr=arrSrc->performCpy(deepCpy); - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingTimeDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - if(_array) - { - tinyInfo.push_back(_array->getNumberOfTuples()); - tinyInfo.push_back(_array->getNumberOfComponents()); - } - else - { - tinyInfo.push_back(-1); - tinyInfo.push_back(-1); - } -} - -void MEDCouplingTimeDiscretization::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) -{ - arrays.resize(1); - if(_array!=0) - _array->decrRef(); - DataArrayDouble *arr=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[0],tinyInfoI[1]); - } - _array=arr; - arrays[0]=arr; -} - -void MEDCouplingTimeDiscretization::checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays) -{ - static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size one !"; - if(arrays.size()!=1) - throw INTERP_KERNEL::Exception(MSG); - if(_array!=0) - _array->decrRef(); - _array=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - if(!arrays[0]) - throw INTERP_KERNEL::Exception(MSG); - arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); - _array=arrays[0]; - _array->incrRef(); - } -} - -void MEDCouplingTimeDiscretization::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - _time_tolerance=tinyInfoD[0]; - int nbOfCompo=_array->getNumberOfComponents(); - for(int i=0;isetInfoOnComponent(i,tinyInfoS[i]); -} - -void MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - tinyInfo.push_back(_time_tolerance); -} - -void MEDCouplingTimeDiscretization::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - int nbOfCompo=_array->getNumberOfComponents(); - for(int i=0;igetInfoOnComponent(i)); -} - -MEDCouplingTimeDiscretization::MEDCouplingTimeDiscretization():_time_tolerance(TIME_TOLERANCE_DFT),_array(0) -{ -} - -MEDCouplingTimeDiscretization::MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy):_time_unit(other._time_unit),_time_tolerance(other._time_tolerance) -{ - if(other._array) - _array=other._array->performCpy(deepCpy); - else - _array=0; -} - -MEDCouplingTimeDiscretization::~MEDCouplingTimeDiscretization() -{ - if(_array) - _array->decrRef(); -} - -void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *owner) -{ - if(array!=_array) - { - if(_array) - _array->decrRef(); - _array=array; - if(_array) - _array->incrRef(); - if(owner) - owner->declareAsNew(); - } -} - -const DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const -{ - throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); -} - -DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() -{ - throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); -} - -void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner) -{ - throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !"); -} - -void MEDCouplingTimeDiscretization::setArrays(const std::vector& arrays, TimeLabel *owner) -{ - if(arrays.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingTimeDiscretization::setArrays : number of arrays must be one."); - setArray(arrays.back(),owner); -} - -void MEDCouplingTimeDiscretization::getArrays(std::vector& arrays) const -{ - arrays.resize(1); - arrays[0]=_array; -} - -bool MEDCouplingTimeDiscretization::isBefore(const MEDCouplingTimeDiscretization *other) const -{ - int iteration,order; - double time1=getEndTime(iteration,order)-_time_tolerance; - double time2=other->getStartTime(iteration,order)+other->getTimeTolerance(); - return time1<=time2; -} - -bool MEDCouplingTimeDiscretization::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const -{ - int iteration,order; - double time1=getEndTime(iteration,order)+_time_tolerance; - double time2=other->getStartTime(iteration,order)-other->getTimeTolerance(); - return time1setTimeUnit(getTimeUnit()); - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jdoublyContractedProduct(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jdeterminant(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jeigenValues(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jeigenVectors(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jinverse(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jtrace(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jdeviator(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jmagnitude(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::negate() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jnegate(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jmaxPerTuple(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::keepSelectedComponents(const std::vector& compoIds) const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;j(arrays[j]->keepSelectedComponents(compoIds)); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -void MEDCouplingTimeDiscretization::setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds) -{ - std::vector arrays1,arrays2; - getArrays(arrays1); - other->getArrays(arrays2); - if(arrays1.size()!=arrays2.size()) - throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : number of arrays mismatch !"); - for(std::size_t i=0;isetSelectedComponents(arrays2[i],compoIds); - else if(arrays1[i]!=0 || arrays2[i]!=0) - throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : some time array in correspondance are not defined symetrically !"); - } -} - -void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double dftValue) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jchangeNbOfComponents(newNbOfComp,dftValue); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - for(std::size_t j=0;jsortPerTuple(asc); - } -} - -void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jchangeNbOfComponents(nbOfCompo,value); - arrays2[j]->fillWithValue(value); - } - else - { - arrays2[j]=DataArrayDouble::New(); - arrays2[j]->alloc(nbOfTuple,nbOfCompo); - arrays2[j]->fillWithValue(value); - } - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - bool newArr=false; - for(std::size_t j=0;jincrRef(); - arrays2[j]->fillWithValue(value); - } - else - { - newArr=true; - arrays2[j]=DataArrayDouble::New(); - arrays2[j]->alloc(nbOfTuple,1); - arrays2[j]->fillWithValue(value); - } - } - if(newArr) - { - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - for(std::size_t j=0;japplyLin(a,b,compoId); - } -} - -void MEDCouplingTimeDiscretization::applyLin(double a, double b) -{ - std::vector arrays; - getArrays(arrays); - for(std::size_t j=0;japplyLin(a,b); - } -} - -void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc2(nbOfComp,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j& varsOrder, const std::string& func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc3(nbOfComp,varsOrder,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - for(std::size_t j=0;japplyFuncFast32(func); - } -} - -void MEDCouplingTimeDiscretization::applyFuncFast64(const std::string& func) -{ - std::vector arrays; - getArrays(arrays); - for(std::size_t j=0;japplyFuncFast64(func); - } -} - -void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc2(nbOfComp,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j& varsOrder, const std::string& func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc3(nbOfComp,varsOrder,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is NO_TIME, other has a different time discretization."); - return ret; -} - -bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - { - reason="This has time discretization NO_TIME, other not."; - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingNoTimeLabel *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("NoTimeLabel::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setTimeTolerance(getTimeTolerance()); - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::dot on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Dot(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Add(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::addEqual : Data Array is NULL !"); - getArray()->addEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::substract on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::substract : Data Array is NULL !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Substract(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::substractEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::substractEqual : Data Array is NULL !"); - getArray()->substractEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Multiply(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::multiplyEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::multiplyEqual : Data Array is NULL !"); - getArray()->multiplyEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Divide(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::divideEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::divideEqual : Data Array is NULL !"); - getArray()->divideEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::pow(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("pow on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Pow(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::powEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::powEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::powEqual : Data Array is NULL !"); - getArray()->powEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::performCpy(bool deepCpy) const -{ - return new MEDCouplingNoTimeLabel(*this,deepCpy); -} - -void MEDCouplingNoTimeLabel::checkTimePresence(double time) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -std::vector< const DataArrayDouble *> MEDCouplingNoTimeLabel::getArraysForTime(double time) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::getValueForTime(double time, const std::vector& vals, double *res) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -bool MEDCouplingNoTimeLabel::isBefore(const MEDCouplingTimeDiscretization *other) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -bool MEDCouplingNoTimeLabel::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -double MEDCouplingNoTimeLabel::getStartTime(int& iteration, int& order) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -double MEDCouplingNoTimeLabel::getEndTime(int& iteration, int& order) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartIteration(int it) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndIteration(int it) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartOrder(int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndOrder(int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartTimeValue(double time) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndTimeValue(double time) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartTime(double time, int iteration, int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndTime(double time, int iteration, int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::getValueOnTime(int eltId, double time, double *value) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingNoTimeLabel::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.clear(); -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingNoTimeLabel::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(1); - tinyInfo[0]=_time_tolerance; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingNoTimeLabel::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _time_tolerance=tinyInfoD[0]; -} - -MEDCouplingWithTimeStep::MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), - _time(other._time),_iteration(other._iteration),_order(other._order) -{ -} - -MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_iteration(-1),_order(-1) -{ -} - -std::string MEDCouplingWithTimeStep::getStringRepr() const -{ - std::ostringstream stream; - stream << REPR << " Time is defined by iteration=" << _iteration << " order=" << _order << " and time=" << _time << "."; - stream << "\nTime unit is : \"" << _time_unit << "\""; - return stream.str(); -} - -void MEDCouplingWithTimeStep::synchronizeTimeWith(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); - int it=-1,order=-1; - double val=mesh->getTime(it,order); - _time=val; _iteration=it; _order=order; - std::string tUnit=mesh->getTimeUnit(); - _time_unit=tUnit; -} - -void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_iteration); - tinyInfo.push_back(_order); -} - -void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); - tinyInfo.push_back(_time); -} - -void MEDCouplingWithTimeStep::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); - _time=tinyInfoD[1]; - _iteration=tinyInfoI[2]; - _order=tinyInfoI[3]; -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingWithTimeStep::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(2); - tinyInfo[0]=_iteration; - tinyInfo[1]=_order; -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingWithTimeStep::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(2); - tinyInfo[0]=_time_tolerance; - tinyInfo[1]=_time; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingWithTimeStep::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _iteration=tinyInfoI[0]; - _order=tinyInfoI[1]; - _time_tolerance=tinyInfoD[0]; - _time=tinyInfoD[1]; -} - -bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatible(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is ONE_TIME, other has a different time discretization."); - return ret; -} - -bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - std::ostringstream oss; oss.precision(15); - if(!otherC) - { - reason="This has time discretization ONE_TIME, other not."; - return false; - } - if(_iteration!=otherC->_iteration) - { - oss << "iterations differ. this iteration=" << _iteration << " other iteration=" << otherC->_iteration; - reason=oss.str(); - return false; - } - if(_order!=otherC->_order) - { - oss << "orders differ. this order=" << _order << " other order=" << otherC->_order; - reason=oss.str(); - return false; - } - if(std::fabs(_time-otherC->_time)>_time_tolerance) - { - oss << "times differ. this time=" << _time << " other time=" << otherC->_time; - reason=oss.str(); - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_iteration!=otherC->_iteration) - return false; - if(_order!=otherC->_order) - return false; - if(std::fabs(_time-otherC->_time)>_time_tolerance) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); - const MEDCouplingWithTimeStep *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::copyTinyAttrFrom : mismatch of time discretization !"); - _time=otherC->_time; - _iteration=otherC->_iteration; - _order=otherC->_order; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingWithTimeStep *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("WithTimeStep::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::dot on mismatched time discretization !"); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Dot(getArray(),other->getArray()); - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::min on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Add(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::addEqual : Data Array is NULL !"); - getArray()->addEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Substract(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingWithTimeStep::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::substractEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::substractEqual : Data Array is NULL !"); - getArray()->substractEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Multiply(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingWithTimeStep::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::multiplyEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::multiplyEqual : Data Array is NULL !"); - getArray()->multiplyEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Divide(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingWithTimeStep::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::divideEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::divideEqual : Data Array is NULL !"); - getArray()->divideEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::pow(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::pow on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Pow(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingWithTimeStep::powEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::powEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::powEqual : Data Array is NULL !"); - getArray()->powEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::performCpy(bool deepCpy) const -{ - return new MEDCouplingWithTimeStep(*this,deepCpy); -} - -void MEDCouplingWithTimeStep::checkNoTimePresence() const -{ - throw INTERP_KERNEL::Exception("No time specified on a field defined on one time"); -} - -void MEDCouplingWithTimeStep::checkTimePresence(double time) const -{ - if(std::fabs(time-_time)>_time_tolerance) - { - std::ostringstream stream; - stream << "The field is defined on time " << _time << " with eps=" << _time_tolerance << " and asking time = " << time << " !"; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } -} - -std::vector< const DataArrayDouble *> MEDCouplingWithTimeStep::getArraysForTime(double time) const -{ - if(std::fabs(time-_time)<=_time_tolerance) - { - std::vector< const DataArrayDouble *> ret(1); - ret[0]=_array; - return ret; - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingWithTimeStep::getValueForTime(double time, const std::vector& vals, double *res) const -{ - std::copy(vals.begin(),vals.end(),res); -} - -void MEDCouplingWithTimeStep::getValueOnTime(int eltId, double time, double *value) const -{ - if(std::fabs(time-_time)<=_time_tolerance) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - if(_iteration==iteration && _order==order) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception("No data on this discrete time."); -} - -MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1) -{ -} - -void MEDCouplingConstOnTimeInterval::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::copyTinyAttrFrom : mismatch of time discretization !"); - _start_time=otherC->_start_time; - _end_time=otherC->_end_time; - _start_iteration=otherC->_start_iteration; - _end_iteration=otherC->_end_iteration; - _start_order=otherC->_start_order; - _end_order=otherC->_end_order; -} - -void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_start_iteration); - tinyInfo.push_back(_start_order); - tinyInfo.push_back(_end_iteration); - tinyInfo.push_back(_end_order); -} - -void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); - tinyInfo.push_back(_start_time); - tinyInfo.push_back(_end_time); -} - -void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; - _start_iteration=tinyInfoI[2]; - _start_order=tinyInfoI[3]; - _end_iteration=tinyInfoI[4]; - _end_order=tinyInfoI[5]; -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(4); - tinyInfo[0]=_start_iteration; - tinyInfo[1]=_start_order; - tinyInfo[2]=_end_iteration; - tinyInfo[3]=_end_order; -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(3); - tinyInfo[0]=_time_tolerance; - tinyInfo[1]=_start_time; - tinyInfo[2]=_end_time; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingConstOnTimeInterval::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _start_iteration=tinyInfoI[0]; - _start_order=tinyInfoI[1]; - _end_iteration=tinyInfoI[2]; - _end_order=tinyInfoI[3]; - _time_tolerance=tinyInfoD[0]; - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; -} - -MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy): - MEDCouplingTimeDiscretization(other,deepCpy),_start_time(other._start_time),_end_time(other._end_time),_start_iteration(other._start_iteration), - _end_iteration(other._end_iteration),_start_order(other._start_order),_end_order(other._end_order) -{ -} - -std::string MEDCouplingConstOnTimeInterval::getStringRepr() const -{ - std::ostringstream stream; - stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; - stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; - stream << "\nTime unit is : \"" << _time_unit << "\""; - return stream.str(); -} - -void MEDCouplingConstOnTimeInterval::synchronizeTimeWith(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); - int it=-1,order=-1; - double val=mesh->getTime(it,order); - _start_time=val; _start_iteration=it; _start_order=order; - _end_time=val; _end_iteration=it; _end_order=order; - std::string tUnit=mesh->getTimeUnit(); - _time_unit=tUnit; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const -{ - return new MEDCouplingConstOnTimeInterval(*this,deepCpy); -} - -std::vector< const DataArrayDouble *> MEDCouplingConstOnTimeInterval::getArraysForTime(double time) const -{ - if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) - { - std::vector< const DataArrayDouble *> ret(1); - ret[0]=_array; - return ret; - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingConstOnTimeInterval::getValueForTime(double time, const std::vector& vals, double *res) const -{ - std::copy(vals.begin(),vals.end(),res); -} - -bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatible(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is CONST_ON_TIME_INTERVAL, other has a different time discretization."); - return ret; -} - -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - std::ostringstream oss; oss.precision(15); - if(!otherC) - { - reason="This has time discretization CONST_ON_TIME_INTERVAL, other not."; - return false; - } - if(_start_iteration!=otherC->_start_iteration) - { - oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; - reason=oss.str(); - return false; - } - if(_start_order!=otherC->_start_order) - { - oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; - reason=oss.str(); - return false; - } - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - { - oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; - reason=oss.str(); - return false; - } - if(_end_iteration!=otherC->_end_iteration) - { - oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; - reason=oss.str(); - return false; - } - if(_end_order!=otherC->_end_order) - { - oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; - reason=oss.str(); - return false; - } - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - { - oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; - reason=oss.str(); - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_start_iteration!=otherC->_start_iteration) - return false; - if(_start_order!=otherC->_start_order) - return false; - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - return false; - if(_end_iteration!=otherC->_end_iteration) - return false; - if(_end_order!=otherC->_end_order) - return false; - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, double *value) const -{ - if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - if(iteration>=_start_iteration && iteration<=_end_iteration) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingConstOnTimeInterval::checkNoTimePresence() const -{ - throw INTERP_KERNEL::Exception("No time specified on a field defined as constant on one time interval"); -} - -void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const -{ - if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) - { - std::ostringstream stream; - stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; - stream << _time_tolerance << " and trying to access on time = " << time; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingConstOnTimeInterval *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setTimeTolerance(getTimeTolerance()); - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::dot on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Dot(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::min on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Add(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - tmp3=getEndTime(tmp1,tmp2); - ret->setEndTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingConstOnTimeInterval::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::substractaddEqual : Data Array is NULL !"); - getArray()->addEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substract on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Substract(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - tmp3=getEndTime(tmp1,tmp2); - ret->setEndTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingConstOnTimeInterval::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substractEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::substractEqual : Data Array is NULL !"); - getArray()->substractEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Multiply(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - tmp3=getEndTime(tmp1,tmp2); - ret->setEndTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingConstOnTimeInterval::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::multiplyEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::multiplyEqual : Data Array is NULL !"); - getArray()->multiplyEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Divide(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - tmp3=getEndTime(tmp1,tmp2); - ret->setEndTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::divideEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::divideEqual : Data Array is NULL !"); - getArray()->divideEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::pow(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("pow on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Pow(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - tmp3=getEndTime(tmp1,tmp2); - ret->setEndTime(tmp3,tmp1,tmp2); - return ret; -} - -void MEDCouplingConstOnTimeInterval::powEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::powEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::powEqual : Data Array is NULL !"); - getArray()->powEqual(other->getArray()); -} - -MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), - _start_time(other._start_time),_end_time(other._end_time), - _start_iteration(other._start_iteration),_end_iteration(other._end_iteration), - _start_order(other._start_order),_end_order(other._end_order) -{ - if(other._end_array) - _end_array=other._end_array->performCpy(deepCpy); - else - _end_array=0; -} - -void MEDCouplingTwoTimeSteps::updateTime() const -{ - MEDCouplingTimeDiscretization::updateTime(); - if(_end_array) - updateTimeWith(*_end_array); -} - -void MEDCouplingTwoTimeSteps::synchronizeTimeWith(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); - int it=-1,order=-1; - double val=mesh->getTime(it,order); - _start_time=val; _start_iteration=it; _start_order=order; - _end_time=val; _end_iteration=it; _end_order=order; - std::string tUnit=mesh->getTimeUnit(); - _time_unit=tUnit; -} - -std::size_t MEDCouplingTwoTimeSteps::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingTimeDiscretization::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingTwoTimeSteps::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingTimeDiscretization::getDirectChildrenWithNull()); - ret.push_back(_end_array); - return ret; -} - -void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::copyTinyAttrFrom : mismatch of time discretization !"); - _start_time=otherC->_start_time; - _end_time=otherC->_end_time; - _start_iteration=otherC->_start_iteration; - _end_iteration=otherC->_end_iteration; - _start_order=otherC->_start_order; - _end_order=otherC->_end_order; -} - -void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyStringsFrom(other); - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("Trying to operate copyTinyStringsFrom on different field type (two times//one time) !"); - if(_end_array && otherC->_end_array) - _end_array->copyStringInfoFrom(*otherC->_end_array); -} - -const DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const -{ - return _end_array; -} - -DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() -{ - return _end_array; -} - -void MEDCouplingTwoTimeSteps::checkCoherency() const -{ - MEDCouplingTimeDiscretization::checkCoherency(); - if(!_end_array) - throw INTERP_KERNEL::Exception("No end array specified !"); - if(_array->getNumberOfComponents()!=_end_array->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("The number of components mismatch between the start and the end arrays !"); - if(_array->getNumberOfTuples()!=_end_array->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("The number of tuples mismatch between the start and the end arrays !"); -} - -bool MEDCouplingTwoTimeSteps::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - std::ostringstream oss; - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); - if(!otherC) - { - reason="This has time discretization LINEAR_TIME, other not."; - return false; - } - if(_start_iteration!=otherC->_start_iteration) - { - oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; - reason=oss.str(); - return false; - } - if(_start_order!=otherC->_start_order) - { - oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; - reason=oss.str(); - return false; - } - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - { - oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; - reason=oss.str(); - return false; - } - if(_end_iteration!=otherC->_end_iteration) - { - oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; - reason=oss.str(); - return false; - } - if(_end_order!=otherC->_end_order) - { - oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; - reason=oss.str(); - return false; - } - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - { - oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; - reason=oss.str(); - return false; - } - if(_end_array!=otherC->_end_array) - if(!_end_array->isEqualIfNotWhy(*otherC->_end_array,prec,reason)) - { - reason.insert(0,"end arrays differ for linear time."); - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_start_iteration!=otherC->_start_iteration) - return false; - if(_end_iteration!=otherC->_end_iteration) - return false; - if(_start_order!=otherC->_start_order) - return false; - if(_end_order!=otherC->_end_order) - return false; - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - return false; - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - return false; - if(_end_array!=otherC->_end_array) - if(!_end_array->isEqualWithoutConsideringStr(*otherC->_end_array,prec)) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1),_end_array(0) -{ -} - -MEDCouplingTwoTimeSteps::~MEDCouplingTwoTimeSteps() -{ - if(_end_array) - _end_array->decrRef(); -} - -void MEDCouplingTwoTimeSteps::checkNoTimePresence() const -{ - throw INTERP_KERNEL::Exception("The field presents a time to be specified in every access !"); -} - -void MEDCouplingTwoTimeSteps::checkTimePresence(double time) const -{ - if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) - { - std::ostringstream stream; - stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; - stream << _time_tolerance << " and trying to access on time = " << time; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } -} - -void MEDCouplingTwoTimeSteps::getArrays(std::vector& arrays) const -{ - arrays.resize(2); - arrays[0]=_array; - arrays[1]=_end_array; -} - -void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner) -{ - if(array!=_end_array) - { - if(_end_array) - _end_array->decrRef(); - _end_array=array; - if(_end_array) - _end_array->incrRef(); - if(owner) - owner->declareAsNew(); - } -} - -void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_start_iteration); - tinyInfo.push_back(_start_order); - tinyInfo.push_back(_end_iteration); - tinyInfo.push_back(_end_order); - if(_end_array) - { - tinyInfo.push_back(_end_array->getNumberOfTuples()); - tinyInfo.push_back(_end_array->getNumberOfComponents()); - } - else - { - tinyInfo.push_back(-1); - tinyInfo.push_back(-1); - } -} - -void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); - tinyInfo.push_back(_start_time); - tinyInfo.push_back(_end_time); -} - -void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - int nbOfCompo=_array->getNumberOfComponents(); - for(int i=0;igetInfoOnComponent(i)); - for(int i=0;igetInfoOnComponent(i)); -} - -void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) -{ - arrays.resize(2); - if(_array!=0) - _array->decrRef(); - if(_end_array!=0) - _end_array->decrRef(); - DataArrayDouble *arr=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[0],tinyInfoI[1]); - } - _array=arr; - arrays[0]=arr; - arr=0; - if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) - { - arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[6],tinyInfoI[7]); - } - _end_array=arr; - arrays[1]=arr; -} - -void MEDCouplingTwoTimeSteps::checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays) -{ - static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size two !"; - if(arrays.size()!=2) - throw INTERP_KERNEL::Exception(MSG); - if(_array!=0) - _array->decrRef(); - if(_end_array!=0) - _end_array->decrRef(); - _array=0; _end_array=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - if(!arrays[0]) - throw INTERP_KERNEL::Exception(MSG); - arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); - _array=arrays[0]; _array->incrRef(); - } - if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) - { - if(!arrays[1]) - throw INTERP_KERNEL::Exception(MSG); - arrays[1]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); - _end_array=arrays[1]; _end_array->incrRef(); - } -} - -void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; - _start_iteration=tinyInfoI[2]; - _start_order=tinyInfoI[3]; - _end_iteration=tinyInfoI[4]; - _end_order=tinyInfoI[5]; -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(4); - tinyInfo[0]=_start_iteration; - tinyInfo[1]=_start_order; - tinyInfo[2]=_end_iteration; - tinyInfo[3]=_end_order; -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(3); - tinyInfo[0]=_time_tolerance; - tinyInfo[1]=_start_time; - tinyInfo[2]=_end_time; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingTwoTimeSteps::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _start_iteration=tinyInfoI[0]; - _start_order=tinyInfoI[1]; - _end_iteration=tinyInfoI[2]; - _end_order=tinyInfoI[3]; - _time_tolerance=tinyInfoD[0]; - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; -} - -std::vector< const DataArrayDouble *> MEDCouplingTwoTimeSteps::getArraysForTime(double time) const -{ - if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) - { - std::vector< const DataArrayDouble *> ret(2); - ret[0]=_array; - ret[1]=_end_array; - return ret; - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingTwoTimeSteps::setArrays(const std::vector& arrays, TimeLabel *owner) -{ - if(arrays.size()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::setArrays : number of arrays must be two."); - setArray(arrays.front(),owner); - setEndArray(arrays.back(),owner); -} - -MEDCouplingLinearTime::MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy):MEDCouplingTwoTimeSteps(other,deepCpy) -{ -} - -MEDCouplingLinearTime::MEDCouplingLinearTime() -{ -} - -std::string MEDCouplingLinearTime::getStringRepr() const -{ - std::ostringstream stream; - stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; - stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; - stream << "Time unit is : \"" << _time_unit << "\""; - return stream.str(); -} - -void MEDCouplingLinearTime::checkCoherency() const -{ - MEDCouplingTwoTimeSteps::checkCoherency(); - if(std::fabs(_start_time-_end_time)<_time_tolerance) - throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance."); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const -{ - return new MEDCouplingLinearTime(*this,deepCpy); -} - -bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatible(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(otherC==0) - return false; - if(_end_array==0 && otherC->_end_array==0) - return true; - if(_end_array==0 || otherC->_end_array==0) - return false; - if(_end_array->getNumberOfComponents()!=otherC->_end_array->getNumberOfComponents()) - return false; - return true; -} - -bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is LINEAR_TIME, other has a different time discretization."); - return ret; -} - -bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingLinearTime::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(otherC==0) - return false; - if(_end_array==0 && otherC->_end_array==0) - return true; - if(_end_array==0 || otherC->_end_array==0) - return false; - int nbC1=_end_array->getNumberOfComponents(); - int nbC2=otherC->_end_array->getNumberOfComponents(); - if(nbC1!=nbC2 && nbC2!=1) - return false; - return true; -} - -bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - return otherC!=0; -} - -/*! - * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples() - */ -void MEDCouplingLinearTime::getValueForTime(double time, const std::vector& vals, double *res) const -{ - double alpha=(_end_time-time)/(_end_time-_start_time); - std::size_t nbComp=vals.size()/2; - std::transform(vals.begin(),vals.begin()+nbComp,res,std::bind2nd(std::multiplies(),alpha)); - std::vector tmp(nbComp); - std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); - std::transform(tmp.begin(),tmp.end(),res,res,std::plus()); -} - -void MEDCouplingLinearTime::getValueOnTime(int eltId, double time, double *value) const -{ - double alpha=(_end_time-time)/(_end_time-_start_time); - int nbComp; - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No start array existing."); - nbComp=_array->getNumberOfComponents(); - std::transform(value,value+nbComp,value,std::bind2nd(std::multiplies(),alpha)); - std::vector tmp(nbComp); - if(_end_array) - _end_array->getTuple(eltId,&tmp[0]); - else - throw INTERP_KERNEL::Exception("No end array existing."); - std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); - std::transform(tmp.begin(),tmp.end(),value,value,std::plus()); -} - -void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - if(iteration==_start_iteration && order==_start_order) - { - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("iteration order match with start time but no start array existing."); - } - if(iteration==_end_iteration && order==_end_order) - { - if(_end_array) - _end_array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("iteration order match with end time but no end array existing."); - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Aggregate(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - std::vector b(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingLinearTime *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - b[i]=itC->getEndArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Aggregate(b); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Meld(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setTimeTolerance(getTimeTolerance()); - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::dot on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Dot(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Dot(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::CrossProduct(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::max on mismatched time discretization !"); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Max(getEndArray(),other->getEndArray()); - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::min on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Min(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Add(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Add(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::addEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::addEqual : Data Array (end) is NULL !"); - getArray()->addEqual(other->getArray()); - getEndArray()->addEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::substract on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Substract(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Substract(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::substractEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::substractEqual : Data Array (end) is NULL !"); - getArray()->substractEqual(other->getArray()); - getEndArray()->substractEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Multiply(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Multiply(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::multiplyEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::multiplyEqual : Data Array (end) is NULL !"); - getArray()->multiplyEqual(other->getArray()); - getEndArray()->multiplyEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Divide(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Divide(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::divideEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::divideEqual : Data Array (end) is NULL !"); - getArray()->divideEqual(other->getArray()); - getEndArray()->divideEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::pow(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::pow on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Pow(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Pow(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::powEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::powEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::powEqual : Data Array (end) is NULL !"); - getArray()->powEqual(other->getArray()); - getEndArray()->powEqual(other->getEndArray()); -} diff --git a/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx deleted file mode 100644 index 3bf7b82ad..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - class DataArrayDouble; - class TimeLabel; - - class MEDCouplingTimeDiscretization : public TimeLabel, public BigMemoryObject - { - protected: - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization(); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT virtual std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type); - MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit) { _time_unit=unit; } - MEDCOUPLING_EXPORT std::string getTimeUnit() const { return _time_unit; } - MEDCOUPLING_EXPORT virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT virtual void checkCoherency() const; - MEDCOUPLING_EXPORT virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const; - MEDCOUPLING_EXPORT virtual std::string getStringRepr() const = 0; - MEDCOUPLING_EXPORT virtual TypeOfTimeDiscretization getEnum() const = 0; - MEDCOUPLING_EXPORT virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void addEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void substractEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void divideEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void powEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); - MEDCOUPLING_EXPORT virtual void checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays); - MEDCOUPLING_EXPORT virtual void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation2(std::vector& tinyInfo) const = 0; - MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation2(std::vector& tinyInfo) const = 0; - MEDCOUPLING_EXPORT virtual void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const = 0; - MEDCOUPLING_EXPORT void setTimeTolerance(double val) { _time_tolerance=val; } - MEDCOUPLING_EXPORT double getTimeTolerance() const { return _time_tolerance; } - MEDCOUPLING_EXPORT virtual void checkNoTimePresence() const = 0; - MEDCOUPLING_EXPORT virtual void checkTimePresence(double time) const = 0; - MEDCOUPLING_EXPORT virtual void setArray(DataArrayDouble *array, TimeLabel *owner); - MEDCOUPLING_EXPORT virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner); - MEDCOUPLING_EXPORT virtual void setArrays(const std::vector& arrays, TimeLabel *owner); - MEDCOUPLING_EXPORT DataArrayDouble *getArray() { return _array; } - MEDCOUPLING_EXPORT const DataArrayDouble *getArray() const { return _array; } - MEDCOUPLING_EXPORT virtual const DataArrayDouble *getEndArray() const; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getEndArray(); - MEDCOUPLING_EXPORT virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const = 0; - MEDCOUPLING_EXPORT virtual void getValueForTime(double time, const std::vector& vals, double *res) const = 0; - MEDCOUPLING_EXPORT virtual void getArrays(std::vector& arrays) const; - MEDCOUPLING_EXPORT virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { return getStartTime(iteration,order); } - MEDCOUPLING_EXPORT virtual double getStartTime(int& iteration, int& order) const = 0; - MEDCOUPLING_EXPORT virtual double getEndTime(int& iteration, int& order) const = 0; - MEDCOUPLING_EXPORT void setTime(double time, int iteration, int order) { setStartTime(time,iteration,order); } - MEDCOUPLING_EXPORT void setIteration(int it) { setStartIteration(it); } - MEDCOUPLING_EXPORT void setOrder(int order) { setStartOrder(order); } - MEDCOUPLING_EXPORT void setTimeValue(double val) { setStartTimeValue(val); } - MEDCOUPLING_EXPORT virtual void setStartIteration(int it) = 0; - MEDCOUPLING_EXPORT virtual void setEndIteration(int it) = 0; - MEDCOUPLING_EXPORT virtual void setStartOrder(int order) = 0; - MEDCOUPLING_EXPORT virtual void setEndOrder(int order) = 0; - MEDCOUPLING_EXPORT virtual void setStartTimeValue(double time) = 0; - MEDCOUPLING_EXPORT virtual void setEndTimeValue(double time) = 0; - MEDCOUPLING_EXPORT virtual void setStartTime(double time, int iteration, int order) = 0; - MEDCOUPLING_EXPORT virtual void setEndTime(double time, int iteration, int order) = 0; - MEDCOUPLING_EXPORT virtual void getValueOnTime(int eltId, double time, double *value) const = 0; - MEDCOUPLING_EXPORT virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const = 0; - // - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *determinant() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *eigenValues() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *eigenVectors() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *inverse() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *trace() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *deviator() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *magnitude() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *negate() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *maxPerTuple() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds); - MEDCOUPLING_EXPORT virtual void changeNbOfComponents(int newNbOfComp, double dftValue); - MEDCOUPLING_EXPORT virtual void sortPerTuple(bool asc); - MEDCOUPLING_EXPORT virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value); - MEDCOUPLING_EXPORT virtual void setOrCreateUniformValueOnAllComponents(int nbOfTuple, double value); - MEDCOUPLING_EXPORT virtual void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT virtual void applyLin(double a, double b); - MEDCOUPLING_EXPORT virtual void applyFunc(int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT virtual void applyFunc(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFunc2(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFunc(const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFuncFast32(const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFuncFast64(const std::string& func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic2(const DataArrayDouble *loc, int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector& varsOrder, const std::string& func); - // - MEDCOUPLING_EXPORT virtual ~MEDCouplingTimeDiscretization(); - protected: - std::string _time_unit; - double _time_tolerance; - DataArrayDouble *_array; - protected: - static const double TIME_TOLERANCE_DFT; - }; - - class MEDCouplingNoTimeLabel : public MEDCouplingTimeDiscretization - { - public: - MEDCOUPLING_EXPORT MEDCouplingNoTimeLabel(); - MEDCOUPLING_EXPORT MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void checkNoTimePresence() const { } - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT bool isBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const; - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const; - MEDCOUPLING_EXPORT void setStartIteration(int it); - MEDCOUPLING_EXPORT void setEndIteration(int it); - MEDCOUPLING_EXPORT void setStartOrder(int order); - MEDCOUPLING_EXPORT void setEndOrder(int order); - MEDCOUPLING_EXPORT void setStartTimeValue(double time); - MEDCOUPLING_EXPORT void setEndTimeValue(double time); - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order); - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order); - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; - MEDCOUPLING_EXPORT static const char REPR[]; - private: - static const char EXCEPTION_MSG[]; - }; - - class MEDCouplingWithTimeStep : public MEDCouplingTimeDiscretization - { - protected: - MEDCOUPLING_EXPORT MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT MEDCouplingWithTimeStep(); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void checkNoTimePresence() const; - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _time=time; _iteration=iteration; _order=order; } - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _time=time; _iteration=iteration; _order=order; } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } - MEDCOUPLING_EXPORT void setStartIteration(int it) { _iteration=it; } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _iteration=it; } - MEDCOUPLING_EXPORT void setStartOrder(int order) { _order=order; } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _order=order; } - MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _time=time; } - MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _time=time; } - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - public: - static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; - MEDCOUPLING_EXPORT static const char REPR[]; - private: - static const char EXCEPTION_MSG[]; - protected: - double _time; - int _iteration; - int _order; - }; - - class MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization - { - protected: - MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval(); - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _start_time=time; _start_iteration=iteration; _start_order=order; } - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _end_time=time; _end_iteration=iteration; _end_order=order; } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_start_iteration; order=_start_order; return _start_time; } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_end_iteration; order=_end_order; return _end_time; } - MEDCOUPLING_EXPORT void setStartIteration(int it) { _start_iteration=it; } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _end_iteration=it; } - MEDCOUPLING_EXPORT void setStartOrder(int order) { _start_order=order; } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _end_order=order; } - MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _start_time=time; } - MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _end_time=time; } - MEDCOUPLING_EXPORT void checkNoTimePresence() const; - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - public: - static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; - MEDCOUPLING_EXPORT static const char REPR[]; - private: - static const char EXCEPTION_MSG[]; - protected: - double _start_time; - double _end_time; - int _start_iteration; - int _end_iteration; - int _start_order; - int _end_order; - }; - - class MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization - { - protected: - MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy); - MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps(); - MEDCOUPLING_EXPORT ~MEDCouplingTwoTimeSteps(); - public: - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT const DataArrayDouble *getEndArray() const; - MEDCOUPLING_EXPORT DataArrayDouble *getEndArray(); - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT void checkNoTimePresence() const; - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - MEDCOUPLING_EXPORT void getArrays(std::vector& arrays) const; - MEDCOUPLING_EXPORT void setEndArray(DataArrayDouble *array, TimeLabel *owner); - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _start_time=time; _start_iteration=iteration; _start_order=order; } - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _end_time=time; _end_iteration=iteration; _end_order=order; } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_start_iteration; order=_start_order; return _start_time; } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_end_iteration; order=_end_order; return _end_time; } - MEDCOUPLING_EXPORT void setStartIteration(int it) { _start_iteration=it; } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _end_iteration=it; } - MEDCOUPLING_EXPORT void setStartOrder(int order) { _start_order=order; } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _end_order=order; } - MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _start_time=time; } - MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _end_time=time; } - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); - MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void setArrays(const std::vector& arrays, TimeLabel *owner); - protected: - static const char EXCEPTION_MSG[]; - protected: - double _start_time; - double _end_time; - int _start_iteration; - int _end_iteration; - int _start_order; - int _end_order; - DataArrayDouble *_end_array; - }; - - class MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps - { - protected: - MEDCOUPLING_EXPORT MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT MEDCouplingLinearTime(); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; - MEDCOUPLING_EXPORT static const char REPR[]; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingTimeLabel.cxx b/medtool/src/MEDCoupling/MEDCouplingTimeLabel.cxx deleted file mode 100644 index 4bb3671f7..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingTimeLabel.cxx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingTimeLabel.hxx" - -#include "InterpKernelException.hxx" - -#include - -using namespace ParaMEDMEM; - -std::size_t TimeLabel::GLOBAL_TIME=0; - -TimeLabel::TimeLabel():_time(GLOBAL_TIME++) -{ -} - -TimeLabel::~TimeLabel() -{ -} - -TimeLabel& TimeLabel::operator=(const TimeLabel& other) -{ - _time=GLOBAL_TIME++; - return *this; -} - -void TimeLabel::declareAsNew() const -{ - _time=GLOBAL_TIME++; -} - -void TimeLabel::updateTimeWith(const TimeLabel& other) const -{ - if(_time::max()) -{ - if(!_tl) - throw INTERP_KERNEL::Exception("TimeLabelConstOverseer constructor : input instance must be not NULL !"); - _tl->updateTime(); - _ref_time=tl->getTimeOfThis(); -} - -/*! - * This method checks that the tracked instance is not NULL and if not NULL that its internal state has not changed. - */ -void TimeLabelConstOverseer::checkConst() const -{ - if(!_tl) - throw INTERP_KERNEL::Exception("TimeLabelConstOverseer::checkConst : NULL tracked instance !"); - _tl->updateTime(); - if(_ref_time!=_tl->getTimeOfThis()) - throw INTERP_KERNEL::Exception("TimeLabelConstOverseer::checkConst : the state of the controlled instance of TimeLable has changed !"); -} - -bool TimeLabelConstOverseer::resetState() -{ - if(_tl) - { - _tl->updateTime(); - _ref_time=_tl->getTimeOfThis(); - return true; - } - else - return false; -} - -bool TimeLabelConstOverseer::keepTrackOfNewTL(const TimeLabel *tl) -{ - if(_tl==tl) - return false; - _tl=tl; - if(_tl) - { - _tl->updateTime(); - _ref_time=_tl->getTimeOfThis(); - } - else - { - _ref_time=std::numeric_limits::max(); - } - return true; -} diff --git a/medtool/src/MEDCoupling/MEDCouplingTimeLabel.hxx b/medtool/src/MEDCoupling/MEDCouplingTimeLabel.hxx deleted file mode 100644 index 2ab528aad..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingTimeLabel.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_TIMELABEL_HXX__ -#define __PARAMEDMEM_TIMELABEL_HXX__ - -#include "MEDCoupling.hxx" - -#include - -namespace ParaMEDMEM -{ - /*! - * Class representing a label of time of the lastely modified part of this. - * More _time is high more the object has been modified recently. - */ - class TimeLabel - { - public: - MEDCOUPLING_EXPORT TimeLabel& operator=(const TimeLabel& other); - //! This method should be called when write access has been done on this. - MEDCOUPLING_EXPORT void declareAsNew() const; - //! This method should be called on high level classes as Field or Mesh to take into acount modifications done in aggregates objects. - MEDCOUPLING_EXPORT virtual void updateTime() const = 0; - MEDCOUPLING_EXPORT std::size_t getTimeOfThis() const { return _time; } - protected: - MEDCOUPLING_EXPORT TimeLabel(); - MEDCOUPLING_EXPORT virtual ~TimeLabel(); - MEDCOUPLING_EXPORT void updateTimeWith(const TimeLabel& other) const; - MEDCOUPLING_EXPORT void forceTimeOfThis(const TimeLabel& other) const; - private: - static std::size_t GLOBAL_TIME; - mutable std::size_t _time; - }; - - class TimeLabelConstOverseer - { - public: - MEDCOUPLING_EXPORT TimeLabelConstOverseer(const TimeLabel *tl); - MEDCOUPLING_EXPORT void checkConst() const; - MEDCOUPLING_EXPORT bool resetState(); - MEDCOUPLING_EXPORT bool keepTrackOfNewTL(const TimeLabel *tl); - private: - const TimeLabel *_tl; - std::size_t _ref_time; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/MEDCouplingUMesh.cxx b/medtool/src/MEDCoupling/MEDCouplingUMesh.cxx deleted file mode 100644 index 81e8295b4..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingUMesh.cxx +++ /dev/null @@ -1,11921 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingUMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingMemArray.txx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "CellModel.hxx" -#include "VolSurfUser.txx" -#include "InterpolationUtils.hxx" -#include "PointLocatorAlgos.txx" -#include "BBTree.txx" -#include "BBTreeDst.txx" -#include "SplitterTetra.hxx" -#include "DiameterCalculator.hxx" -#include "DirectedBoundingBox.hxx" -#include "InterpKernelMatrixTools.hxx" -#include "InterpKernelMeshQuality.hxx" -#include "InterpKernelCellSimplify.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" - -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14; - -/// @cond INTERNAL -const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED }; -/// @endcond - -MEDCouplingUMesh *MEDCouplingUMesh::New() -{ - return new MEDCouplingUMesh; -} - -MEDCouplingUMesh *MEDCouplingUMesh::New(const std::string& meshName, int meshDim) -{ - MEDCouplingUMesh *ret=new MEDCouplingUMesh; - ret->setName(meshName); - ret->setMeshDimension(meshDim); - return ret; -} - -/*! - * Returns a new MEDCouplingMesh which is a full copy of \a this one. No data is shared - * between \a this and the new mesh. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const -{ - return clone(true); -} - -/*! - * Returns a new MEDCouplingMesh which is a copy of \a this one. - * \param [in] recDeepCpy - if \a true, the copy is deep, else all data arrays of \a - * this mesh are shared by the new mesh. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingUMesh(*this,recDeepCpy); -} - -/*! - * This method behaves mostly like MEDCouplingUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. - * The coordinates are shared between \a this and the returned instance. - * - * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) - * \sa MEDCouplingUMesh::deepCpy - */ -MEDCouplingPointSet *MEDCouplingUMesh::deepCpyConnectivityOnly() const -{ - checkConnectivityFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret=clone(false); - MEDCouplingAutoRefCountObjectPtr c(getNodalConnectivity()->deepCpy()),ci(getNodalConnectivityIndex()->deepCpy()); - ret->setConnectivity(c,ci); - return ret.retn(); -} - -void MEDCouplingUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is null !"); - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCouplingUMesh instance !"); - MEDCouplingUMesh *otherC2=const_cast(otherC);//sorry :( - setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true); -} - -std::size_t MEDCouplingUMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingPointSet::getHeapMemorySizeWithoutChildren()); - return ret; -} - -std::vector MEDCouplingUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingPointSet::getDirectChildrenWithNull()); - ret.push_back(_nodal_connec); - ret.push_back(_nodal_connec_index); - return ret; -} - -void MEDCouplingUMesh::updateTime() const -{ - MEDCouplingPointSet::updateTime(); - if(_nodal_connec) - { - updateTimeWith(*_nodal_connec); - } - if(_nodal_connec_index) - { - updateTimeWith(*_nodal_connec_index); - } -} - -MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0) -{ -} - -/*! - * Checks if \a this mesh is well defined. If no exception is thrown by this method, - * then \a this mesh is most probably is writable, exchangeable and available for most - * of algorithms. When a mesh is constructed from scratch, it is a good habit to call - * this method to check that all is in order with \a this mesh. - * \throw If the mesh dimension is not set. - * \throw If the coordinates array is not set (if mesh dimension != -1 ). - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - */ -void MEDCouplingUMesh::checkCoherency() const -{ - if(_mesh_dim<-1) - throw INTERP_KERNEL::Exception("No mesh dimension specified !"); - if(_mesh_dim!=-1) - MEDCouplingPointSet::checkCoherency(); - for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) - { - if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim) - { - std::ostringstream message; - message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter); - throw INTERP_KERNEL::Exception(message.str().c_str()); - } - } - if(_nodal_connec) - { - if(_nodal_connec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); - if(_nodal_connec->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); - } - else - if(_mesh_dim!=-1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is not defined !"); - if(_nodal_connec_index) - { - if(_nodal_connec_index->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); - if(_nodal_connec_index->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); - } - else - if(_mesh_dim!=-1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is not defined !"); -} - -/*! - * Checks if \a this mesh is well defined. If no exception is thrown by this method, - * then \a this mesh is most probably is writable, exchangeable and available for all - * algorithms.
In addition to the checks performed by checkCoherency(), this - * method thoroughly checks the nodal connectivity. - * \param [in] eps - a not used parameter. - * \throw If the mesh dimension is not set. - * \throw If the coordinates array is not set (if mesh dimension != -1 ). - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - * \throw If number of nodes defining an element does not correspond to the type of element. - * \throw If the nodal connectivity includes an invalid node id. - */ -void MEDCouplingUMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - if(_mesh_dim==-1) - return ; - int meshDim=getMeshDimension(); - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=getNumberOfCells(); - const int *ptr=_nodal_connec->getConstPointer(); - const int *ptrI=_nodal_connec_index->getConstPointer(); - for(int i=0;i=0) - { - if(nodeId>=nbOfNodes) - { - std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " whereas there are only " << nbOfNodes << " nodes in the mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else if(nodeId<-1) - { - std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " in connectivity ! sounds bad !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { - if((INTERP_KERNEL::NormalizedCellType)(ptr[ptrI[i]])!=INTERP_KERNEL::NORM_POLYHED) - { - std::ostringstream oss; oss << "Cell #" << i << " is built with node #-1 in connectivity ! sounds bad !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } -} - - -/*! - * Checks if \a this mesh is well defined. If no exception is thrown by this method, - * then \a this mesh is most probably is writable, exchangeable and available for all - * algorithms.
This method performs the same checks as checkCoherency1() does. - * \param [in] eps - a not used parameter. - * \throw If the mesh dimension is not set. - * \throw If the coordinates array is not set (if mesh dimension != -1 ). - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - * \throw If number of nodes defining an element does not correspond to the type of element. - * \throw If the nodal connectivity includes an invalid node id. - */ -void MEDCouplingUMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -/*! - * Sets dimension of \a this mesh. The mesh dimension in general depends on types of - * elements contained in the mesh. For more info on the mesh dimension see - * \ref MEDCouplingUMeshPage. - * \param [in] meshDim - a new mesh dimension. - * \throw If \a meshDim is invalid. A valid range is -1 <= meshDim <= 3. - */ -void MEDCouplingUMesh::setMeshDimension(int meshDim) -{ - if(meshDim<-1 || meshDim>3) - throw INTERP_KERNEL::Exception("Invalid meshDim specified ! Must be greater or equal to -1 and lower or equal to 3 !"); - _mesh_dim=meshDim; - declareAsNew(); -} - -/*! - * Allocates memory to store an estimation of the given number of cells. The closer is the estimation to the number of cells effectively inserted, - * the less will the library need to reallocate memory. If the number of cells to be inserted is not known simply put 0 to this parameter. - * If a nodal connectivity previouly existed before the call of this method, it will be reset. - * - * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::allocateCells(int nbOfCells) -{ - if(nbOfCells<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::allocateCells : the input number of cells should be >= 0 !"); - if(_nodal_connec_index) - { - _nodal_connec_index->decrRef(); - } - if(_nodal_connec) - { - _nodal_connec->decrRef(); - } - _nodal_connec_index=DataArrayInt::New(); - _nodal_connec_index->reserve(nbOfCells+1); - _nodal_connec_index->pushBackSilent(0); - _nodal_connec=DataArrayInt::New(); - _nodal_connec->reserve(2*nbOfCells); - _types.clear(); - declareAsNew(); -} - -/*! - * Appends a cell to the connectivity array. For deeper understanding what is - * happening see \ref MEDCouplingUMeshNodalConnectivity. - * \param [in] type - type of cell to add. - * \param [in] size - number of nodes constituting this cell. - * \param [in] nodalConnOfCell - the connectivity of the cell to add. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(_nodal_connec_index==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !"); - if((int)cm.getDimension()==_mesh_dim) - { - if(!cm.isDynamic()) - if(size!=(int)cm.getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : Trying to push a " << cm.getRepr() << " cell with a size of " << size; - oss << " ! Expecting " << cm.getNumberOfNodes() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int idx=_nodal_connec_index->back(); - int val=idx+size+1; - _nodal_connec_index->pushBackSilent(val); - _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size); - _types.insert(type); - } - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : cell type " << cm.getRepr() << " has a dimension " << cm.getDimension(); - oss << " whereas Mesh Dimension of current UMesh instance is set to " << _mesh_dim << " ! Please invoke \"setMeshDimension\" method before or invoke "; - oss << "\"MEDCouplingUMesh::New\" static method with 2 parameters name and meshDimension !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Compacts data arrays to release unused memory. This method is to be called after - * finishing cell insertion using \a this->insertNextCell(). - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::finishInsertingCells() -{ - _nodal_connec->pack(); - _nodal_connec_index->pack(); - _nodal_connec->declareAsNew(); - _nodal_connec_index->declareAsNew(); - updateTime(); -} - -/*! - * Entry point for iteration over cells of this. Warning the returned cell iterator should be deallocated. - * Useful for python users. - */ -MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator() -{ - return new MEDCouplingUMeshCellIterator(this); -} - -/*! - * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated. - * If \a this is not so that that cells are grouped by geo types this method will throw an exception. - * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method. - * Useful for python users. - */ -MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType() -{ - if(!checkConsecutiveCellTypes()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::cellsByType : this mesh is not sorted by type !"); - return new MEDCouplingUMeshCellByTypeEntry(this); -} - -/*! - * Returns a set of all cell types available in \a this mesh. - * \return std::set - the set of cell types. - * \warning this method does not throw any exception even if \a this is not defined. - * \sa MEDCouplingUMesh::getAllGeoTypesSorted - */ -std::set MEDCouplingUMesh::getAllGeoTypes() const -{ - return _types; -} - -/*! - * This method returns the sorted list of geometric types in \a this. - * Sorted means in the same order than the cells in \a this. A single entry in return vector means the maximal chunk of consecutive cells in \a this - * having the same geometric type. So a same geometric type can appear more than once if the cells are not sorted per geometric type. - * - * \throw if connectivity in \a this is not correctly defined. - * - * \sa MEDCouplingMesh::getAllGeoTypes - */ -std::vector MEDCouplingUMesh::getAllGeoTypesSorted() const -{ - std::vector ret; - checkConnectivityFullyDefined(); - int nbOfCells(getNumberOfCells()); - if(nbOfCells==0) - return ret; - if(getMeshLength()<1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAllGeoTypesSorted : the connectivity in this seems invalid !"); - const int *c(_nodal_connec->begin()),*ci(_nodal_connec_index->begin()); - ret.push_back((INTERP_KERNEL::NormalizedCellType)c[*ci++]); - for(int i=1;i(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingUMesh !"; - return false; - } - if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) - return false; - if(_mesh_dim!=otherC->_mesh_dim) - { - oss << "umesh dimension mismatch : this mesh dimension=" << _mesh_dim << " other mesh dimension=" << otherC->_mesh_dim; - reason=oss.str(); - return false; - } - if(_types!=otherC->_types) - { - oss << "umesh geometric type mismatch :\nThis geometric types are :"; - for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) - { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } - oss << "\nOther geometric types are :"; - for(std::set::const_iterator iter=otherC->_types.begin();iter!=otherC->_types.end();iter++) - { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } - reason=oss.str(); - return false; - } - if(_nodal_connec!=0 || otherC->_nodal_connec!=0) - if(_nodal_connec==0 || otherC->_nodal_connec==0) - { - reason="Only one UMesh between the two this and other has its nodal connectivity DataArrayInt defined !"; - return false; - } - if(_nodal_connec!=otherC->_nodal_connec) - if(!_nodal_connec->isEqualIfNotWhy(*otherC->_nodal_connec,reason)) - { - reason.insert(0,"Nodal connectivity DataArrayInt differ : "); - return false; - } - if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) - if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) - { - reason="Only one UMesh between the two this and other has its nodal connectivity index DataArrayInt defined !"; - return false; - } - if(_nodal_connec_index!=otherC->_nodal_connec_index) - if(!_nodal_connec_index->isEqualIfNotWhy(*otherC->_nodal_connec_index,reason)) - { - reason.insert(0,"Nodal connectivity index DataArrayInt differ : "); - return false; - } - return true; -} - -/*! - * Checks if data arrays of this mesh (node coordinates, nodal - * connectivity of cells, etc) of two meshes are same. Textual data like name etc. are - * not considered. - * \param [in] other - the mesh to compare with. - * \param [in] prec - precision value used to compare node coordinates. - * \return bool - \a true if the two meshes are same. - */ -bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) - return false; - if(_mesh_dim!=otherC->_mesh_dim) - return false; - if(_types!=otherC->_types) - return false; - if(_nodal_connec!=0 || otherC->_nodal_connec!=0) - if(_nodal_connec==0 || otherC->_nodal_connec==0) - return false; - if(_nodal_connec!=otherC->_nodal_connec) - if(!_nodal_connec->isEqualWithoutConsideringStr(*otherC->_nodal_connec)) - return false; - if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) - if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) - return false; - if(_nodal_connec_index!=otherC->_nodal_connec_index) - if(!_nodal_connec_index->isEqualWithoutConsideringStr(*otherC->_nodal_connec_index)) - return false; - return true; -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent with high - * probability, else an exception is thrown. The meshes are considered equivalent if - * (1) meshes contain the same number of nodes and the same number of elements of the - * same types (2) three cells of the two meshes (first, last and middle) are based - * on coincident nodes (with a specified precision). - * \param [in] other - the mesh to compare with. - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \throw If the two meshes do not match. - */ -void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkFastEquivalWith : Two meshes are not not unstructured !"); -} - -/*! - * Returns the reverse nodal connectivity. The reverse nodal connectivity enumerates - * cells each node belongs to. - * \warning For speed reasons, this method does not check if node ids in the nodal - * connectivity correspond to the size of node coordinates array. - * \param [in,out] revNodal - an array holding ids of cells sharing each node. - * \param [in,out] revNodalIndx - an array, of length \a this->getNumberOfNodes() + 1, - * dividing cell ids in \a revNodal into groups each referring to one - * node. Its every element (except the last one) is an index pointing to the - * first id of a group of cells. For example cells sharing the node #1 are - * described by following range of indices: - * [ \a revNodalIndx[1], \a revNodalIndx[2] ) and the cell ids are - * \a revNodal[ \a revNodalIndx[1] ], \a revNodal[ \a revNodalIndx[1] + 1], ... - * Number of cells sharing the *i*-th node is - * \a revNodalIndx[ *i*+1 ] - \a revNodalIndx[ *i* ]. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".
- * \ref py_mcumesh_getReverseNodalConnectivity "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); - int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int)); - revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1); - std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0); - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; - for(int eltId=0;eltId=0)//for polyhedrons - { - nbOfEltsInRevNodal++; - revNodalIndxPtr[(*iter)+1]++; - } - } - std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus()); - int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int)); - revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1); - std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1); - for(int eltId=0;eltId=0)//for polyhedrons - *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to(),-1))=eltId; - } -} - -/// @cond INTERNAL - -int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2) -{ - return id; -} - -int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2) -{ - if(!compute) - return id+1; - else - { - if(cm.getOrientationStatus(nb,conn1,conn2)) - return id+1; - else - return -(id+1); - } -} - -class MinusOneSonsGenerator -{ -public: - MinusOneSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } - unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); } - unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - static const int DELTA=1; -private: - const INTERP_KERNEL::CellModel& _cm; -}; - -class MinusOneSonsGeneratorBiQuadratic -{ -public: - MinusOneSonsGeneratorBiQuadratic(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } - unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); } - unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity4(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - static const int DELTA=1; -private: - const INTERP_KERNEL::CellModel& _cm; -}; - -class MinusTwoSonsGenerator -{ -public: - MinusTwoSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } - unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfEdgesIn3D(conn,lgth); } - unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonEdgesNodalConnectivity3D(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - static const int DELTA=2; -private: - const INTERP_KERNEL::CellModel& _cm; -}; - -/// @endcond - -/*! - * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a - * this->getMeshDimension(), that bound cells of \a this mesh. In addition arrays - * describing correspondence between cells of \a this and the result meshes are - * returned. The arrays \a desc and \a descIndx (\ref numbering-indirect) describe the descending connectivity, - * i.e. enumerate cells of the result mesh bounding each cell of \a this mesh. The - * arrays \a revDesc and \a revDescIndx (\ref numbering-indirect) describe the reverse descending connectivity, - * i.e. enumerate cells of \a this mesh bounded by each cell of the result mesh. - * \warning For speed reasons, this method does not check if node ids in the nodal - * connectivity correspond to the size of node coordinates array. - * \warning Cells of the result mesh are \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in,out] desc - the array containing cell ids of the result mesh bounding - * each cell of \a this mesh. - * \param [in,out] descIndx - the array, of length \a this->getNumberOfCells() + 1, - * dividing cell ids in \a desc into groups each referring to one - * cell of \a this mesh. Its every element (except the last one) is an index - * pointing to the first id of a group of cells. For example cells of the - * result mesh bounding the cell #1 of \a this mesh are described by following - * range of indices: - * [ \a descIndx[1], \a descIndx[2] ) and the cell ids are - * \a desc[ \a descIndx[1] ], \a desc[ \a descIndx[1] + 1], ... - * Number of cells of the result mesh sharing the *i*-th cell of \a this mesh is - * \a descIndx[ *i*+1 ] - \a descIndx[ *i* ]. - * \param [in,out] revDesc - the array containing cell ids of \a this mesh bounded - * by each cell of the result mesh. - * \param [in,out] revDescIndx - the array, of length one more than number of cells - * in the result mesh, - * dividing cell ids in \a revDesc into groups each referring to one - * cell of the result mesh the same way as \a descIndx divides \a desc. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is node defined. - * \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a - * revDescIndx == NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".
- * \ref py_mcumesh_buildDescendingConnectivity "Here is a Python example". - * \endif - * \sa buildDescendingConnectivity2() - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const -{ - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); -} - -/*! - * \a this has to have a mesh dimension equal to 3. If it is not the case an INTERP_KERNEL::Exception will be thrown. - * This behaves exactly as MEDCouplingUMesh::buildDescendingConnectivity does except that this method compute directly the transition from mesh dimension 3 to sub edges (dimension 1) - * in one shot. That is to say that this method is equivalent to 2 successive calls to MEDCouplingUMesh::buildDescendingConnectivity. - * This method returns 4 arrays and a mesh as MEDCouplingUMesh::buildDescendingConnectivity does. - * \sa MEDCouplingUMesh::buildDescendingConnectivity - */ -MEDCouplingUMesh *MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const -{ - checkFullyDefined(); - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::explode3DMeshTo1D : This has to have a mesh dimension to 3 !"); - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); -} - -/*! - * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a - * this->getMeshDimension(), that bound cells of \a this mesh. In - * addition arrays describing correspondence between cells of \a this and the result - * meshes are returned. The arrays \a desc and \a descIndx (\ref numbering-indirect) describe the descending - * connectivity, i.e. enumerate cells of the result mesh bounding each cell of \a this - * mesh. This method differs from buildDescendingConnectivity() in that apart - * from cell ids, \a desc returns mutual orientation of cells in \a this and the - * result meshes. So a positive id means that order of nodes in corresponding cells - * of two meshes is same, and a negative id means a reverse order of nodes. Since a - * cell with id #0 can't be negative, the array \a desc returns ids in FORTRAN mode, - * i.e. cell ids are one-based. - * Arrays \a revDesc and \a revDescIndx (\ref numbering-indirect) describe the reverse descending connectivity, - * i.e. enumerate cells of \a this mesh bounded by each cell of the result mesh. - * \warning For speed reasons, this method does not check if node ids in the nodal - * connectivity correspond to the size of node coordinates array. - * \warning Cells of the result mesh are \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in,out] desc - the array containing cell ids of the result mesh bounding - * each cell of \a this mesh. - * \param [in,out] descIndx - the array, of length \a this->getNumberOfCells() + 1, - * dividing cell ids in \a desc into groups each referring to one - * cell of \a this mesh. Its every element (except the last one) is an index - * pointing to the first id of a group of cells. For example cells of the - * result mesh bounding the cell #1 of \a this mesh are described by following - * range of indices: - * [ \a descIndx[1], \a descIndx[2] ) and the cell ids are - * \a desc[ \a descIndx[1] ], \a desc[ \a descIndx[1] + 1], ... - * Number of cells of the result mesh sharing the *i*-th cell of \a this mesh is - * \a descIndx[ *i*+1 ] - \a descIndx[ *i* ]. - * \param [in,out] revDesc - the array containing cell ids of \a this mesh bounded - * by each cell of the result mesh. - * \param [in,out] revDescIndx - the array, of length one more than number of cells - * in the result mesh, - * dividing cell ids in \a revDesc into groups each referring to one - * cell of the result mesh the same way as \a descIndx divides \a desc. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This result mesh - * shares the node coordinates array with \a this mesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is node defined. - * \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a - * revDescIndx == NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".
- * \ref py_mcumesh_buildDescendingConnectivity2 "Here is a Python example". - * \endif - * \sa buildDescendingConnectivity() - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const -{ - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer); -} - -/*! - * \b WARNING this method do the assumption that connectivity lies on the coordinates set. - * For speed reasons no check of this will be done. This method calls - * MEDCouplingUMesh::buildDescendingConnectivity to compute the result. - * This method lists cell by cell in \b this which are its neighbors. To compute the result - * only connectivities are considered. - * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. - * The format of return is hence \ref numbering-indirect. - * - * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly - * allocated and should be dealt by the caller. \b neighborsIndx 2nd output - * parameter allows to select the right part in this array (\ref numbering-indirect). The number of tuples - * is equal to the last values in \b neighborsIndx. - * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be - * dealt by the caller. This arrays allow to use the first output parameter \b neighbors (\ref numbering-indirect). - */ -void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const -{ - MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - meshDM1=0; - ComputeNeighborsOfCellsAdv(desc,descIndx,revDesc,revDescIndx,neighbors,neighborsIndx); -} - -/*! - * This method is called by MEDCouplingUMesh::computeNeighborsOfCells. This methods performs the algorithm - * of MEDCouplingUMesh::computeNeighborsOfCells. - * This method is useful for users that want to reduce along a criterion the set of neighbours cell. This is - * typically the case to extract a set a neighbours, - * excluding a set of meshdim-1 cells in input descending connectivity. - * Typically \b desc, \b descIndx, \b revDesc and \b revDescIndx (\ref numbering-indirect) input params are - * the result of MEDCouplingUMesh::buildDescendingConnectivity. - * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities - * are considered. - * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. - * - * \param [in] desc descending connectivity array. - * \param [in] descIndx descending connectivity index array used to walk through \b desc (\ref numbering-indirect). - * \param [in] revDesc reverse descending connectivity array. - * \param [in] revDescIndx reverse descending connectivity index array used to walk through \b revDesc (\ref numbering-indirect). - * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output - * parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx. - * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. - */ -void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descIndx, const DataArrayInt *revDesc, const DataArrayInt *revDescIndx, - DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) -{ - if(!desc || !descIndx || !revDesc || !revDescIndx) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeNeighborsOfCellsAdv some input array is empty !"); - const int *descPtr=desc->getConstPointer(); - const int *descIPtr=descIndx->getConstPointer(); - const int *revDescPtr=revDesc->getConstPointer(); - const int *revDescIPtr=revDescIndx->getConstPointer(); - // - int nbCells=descIndx->getNumberOfTuples()-1; - MEDCouplingAutoRefCountObjectPtr out0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr out1=DataArrayInt::New(); out1->alloc(nbCells+1,1); - int *out1Ptr=out1->getPointer(); - *out1Ptr++=0; - out0->reserve(desc->getNumberOfTuples()); - for(int i=0;i s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]); - s.erase(i); - out0->insertAtTheEnd(s.begin(),s.end()); - } - *out1Ptr=out0->getNumberOfTuples(); - } - neighbors=out0.retn(); - neighborsIndx=out1.retn(); -} - -/*! - * \b WARNING this method do the assumption that connectivity lies on the coordinates set. - * For speed reasons no check of this will be done. This method calls - * MEDCouplingUMesh::buildDescendingConnectivity to compute the result. - * This method lists node by node in \b this which are its neighbors. To compute the result - * only connectivities are considered. - * The neighbor nodes of node having id 'nodeId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. - * - * \param [out] neighbors is an array storing all the neighbors of all nodes in \b this. This array - * is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output - * parameter allows to select the right part in this array (\ref numbering-indirect). - * The number of tuples is equal to the last values in \b neighborsIndx. - * \param [out] neighborsIdx is an array of size this->getNumberOfCells()+1 newly allocated and should - * be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. - */ -void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const -{ - checkFullyDefined(); - int mdim(getMeshDimension()),nbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descIndx(DataArrayInt::New()),revDesc(DataArrayInt::New()),revDescIndx(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr mesh1D; - switch(mdim) - { - case 3: - { - mesh1D=explode3DMeshTo1D(desc,descIndx,revDesc,revDescIndx); - break; - } - case 2: - { - mesh1D=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - break; - } - case 1: - { - mesh1D=const_cast(this); - mesh1D->incrRef(); - break; - } - default: - { - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computeNeighborsOfNodes : Mesh dimension supported are [3,2,1] !"); - } - } - desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=0; revDescIndx=0; - mesh1D->getReverseNodalConnectivity(desc,descIndx); - MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()); - ret0->alloc(desc->getNumberOfTuples(),1); - int *r0Pt(ret0->getPointer()); - const int *c1DPtr(mesh1D->getNodalConnectivity()->begin()),*rn(desc->begin()),*rni(descIndx->begin()); - for(int i=0;i -MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const -{ - if(!desc || !descIndx || !revDesc || !revDescIndx) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildDescendingConnectivityGen : present of a null pointer in input !"); - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - int nbOfNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero(); - int *revNodalIndxPtr=revNodalIndx->getPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - std::string name="Mesh constituent of "; name+=getName(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(name,getMeshDimension()-SonsGenerator::DELTA); - ret->setCoords(getCoords()); - ret->allocateCells(2*nbOfCells); - descIndx->alloc(nbOfCells+1,1); - MEDCouplingAutoRefCountObjectPtr revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells); - int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0; - for(int eltId=0;eltId tmp=new int[posP1-pos]; - for(unsigned i=0;i=0) - revNodalIndxPtr[tmp[k]+1]++; - ret->insertNextCell(cmsId,nbOfNodesSon,tmp); - revDesc2->pushBackSilent(eltId); - } - descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons; - } - int nbOfCellsM1=ret->getNumberOfCells(); - std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus()); - MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1); - std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1); - int *revNodalPtr=revNodal->getPointer(); - const int *connM1=ret->getNodalConnectivity()->getConstPointer(); - const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer(); - for(int eltId=0;eltId=0)//for polyhedrons - *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to(),-1))=eltId; - } - // - DataArrayInt *commonCells=0,*commonCellsI=0; - FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer()); - int newNbOfCellsM1=-1; - MEDCouplingAutoRefCountObjectPtr o2nM1=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCellsM1,commonCells->begin(), - commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1); - std::vector isImpacted(nbOfCellsM1,false); - for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++) - for(int work2=work[0];work2!=work[1];work2++) - isImpacted[commonCellsPtr[work2]]=true; - const int *o2nM1Ptr=o2nM1->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1); - const int *n2oM1Ptr=n2oM1->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret2=static_cast(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true)); - ret2->copyTinyInfoFrom(this); - desc->alloc(descIndx->back(),1); - int *descPtr=desc->getPointer(); - const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1); - for(int i=0;ireserve(newNbOfCellsM1); - revDescIndx->alloc(newNbOfCellsM1+1,1); - int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0; - const int *revDesc2Ptr=revDesc2->getConstPointer(); - for(int i=0;ipushBackSilent(revDesc2Ptr[oldCellIdM1]); - revDescIndxPtr[0]=revDescIndxPtr[-1]+1; - } - else - { - for(int j=commonCellsIPtr[0];jpushBackSilent(revDesc2Ptr[commonCellsPtr[j]]); - revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0]; - commonCellsIPtr++; - } - } - // - return ret2.retn(); -} - -struct MEDCouplingAccVisit -{ - MEDCouplingAccVisit():_new_nb_of_nodes(0) { } - int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } - int _new_nb_of_nodes; -}; - -/// @endcond - -/*! - * Converts specified cells to either polygons (if \a this is a 2D mesh) or - * polyhedrons (if \a this is a 3D mesh). The cells to convert are specified by an - * array of cell ids. Pay attention that after conversion all algorithms work slower - * with \a this mesh than before conversion.
If an exception is thrown during the - * conversion due presence of invalid ids in the array of cells to convert, as a - * result \a this mesh contains some already converted elements. In this case the 2D - * mesh remains valid but 3D mesh becomes \b inconsistent! - * \warning This method can significantly modify the order of geometric types in \a this, - * hence, to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in] cellIdsToConvertBg - the array holding ids of cells to convert. - * \param [in] cellIdsToConvertEnd - a pointer to the last-plus-one-th element of \a - * cellIdsToConvertBg. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is node defined. - * \throw If dimension of \a this mesh is not either 2 or 3. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".
- * \ref py_mcumesh_convertToPolyTypes "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd) -{ - checkFullyDefined(); - int dim=getMeshDimension(); - if(dim<2 || dim>3) - throw INTERP_KERNEL::Exception("Invalid mesh dimension : must be 2 or 3 !"); - int nbOfCells(getNumberOfCells()); - if(dim==2) - { - const int *connIndex=_nodal_connec_index->getConstPointer(); - int *conn=_nodal_connec->getPointer(); - for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) - { - if(*iter>=0 && *itergetPointer()); - const int *connOld(_nodal_connec->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr connNew(DataArrayInt::New()),connNewI(DataArrayInt::New()); connNew->alloc(0,1); connNewI->alloc(1,1); connNewI->setIJ(0,0,0); - std::vector toBeDone(nbOfCells,false); - for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) - { - if(*iter>=0 && *iterpushBackValsSilent(tmp,tmp+newLgth); - connNewI->pushBackSilent(connNewI->back()+(int)newLgth); - delete [] tmp; - } - else - { - connNew->pushBackValsSilent(connOld+pos,connOld+posP1); - connNewI->pushBackSilent(connNewI->back()+posP1-pos); - } - } - setConnectivity(connNew,connNewI,false);//false because computeTypes called just behind. - } - computeTypes(); -} - -/*! - * Converts all cells to either polygons (if \a this is a 2D mesh) or - * polyhedrons (if \a this is a 3D mesh). - * \warning As this method is purely for user-friendliness and no optimization is - * done to avoid construction of a useless vector, this method can be costly - * in memory. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is node defined. - * \throw If dimension of \a this mesh is not either 2 or 3. - */ -void MEDCouplingUMesh::convertAllToPoly() -{ - int nbOfCells=getNumberOfCells(); - std::vector cellIds(nbOfCells); - for(int i=0;i - * This method is useful to build an extruded unstructured mesh with polyhedrons as - * it releases the user from boring description of polyhedra connectivity in the valid - * format. - * \throw If \a this->getMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If \a this mesh contains polyhedrons with the valid connectivity. - * \throw If \a this mesh contains polyhedrons with odd number of nodes. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::convertExtrudedPolyhedra() -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertExtrudedPolyhedra works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr newCi=DataArrayInt::New(); - newCi->alloc(nbOfCells+1,1); - int *newci=newCi->getPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - const int *c=_nodal_connec->getConstPointer(); - newci[0]=0; - for(int i=0;i newC=DataArrayInt::New(); - newC->alloc(newci[nbOfCells],1); - int *newc=newC->getPointer(); - for(int i=0;idecrRef(); _nodal_connec_index=newCi.retn(); - _nodal_connec->decrRef(); _nodal_connec=newC.retn(); -} - - -/*! - * Converts all polygons (if \a this is a 2D mesh) or polyhedrons (if \a this is a 3D - * mesh) to cells of classical types. This method is opposite to convertToPolyTypes(). - * \warning Cells of the result mesh are \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \return \c true if at least one cell has been converted, \c false else. In the - * last case the nodal connectivity remains unchanged. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() < 0. - */ -bool MEDCouplingUMesh::unPolyze() -{ - checkFullyDefined(); - int mdim=getMeshDimension(); - if(mdim<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::unPolyze works on umeshes with meshdim equals to 0, 1 2 or 3 !"); - if(mdim<=1) - return false; - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return false; - int initMeshLgth=getMeshLength(); - int *conn=_nodal_connec->getPointer(); - int *index=_nodal_connec_index->getPointer(); - int posOfCurCell=0; - int newPos=0; - int lgthOfCurCell; - bool ret=false; - for(int i=0;i tmp=new int[lgthOfCurCell-1]; - std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,(int *)tmp); - newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(cm.isQuadratic(),tmp,lgthOfCurCell-1,conn+newPos+1,newLgth); - break; - } - case 3: - { - int nbOfFaces,lgthOfPolyhConn; - INTERP_KERNEL::AutoPtr zipFullReprOfPolyh=INTERP_KERNEL::CellSimplify::getFullPolyh3DCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,nbOfFaces,lgthOfPolyhConn); - newType=INTERP_KERNEL::CellSimplify::tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth); - break; - } - case 1: - { - newType=(lgthOfCurCell==3)?INTERP_KERNEL::NORM_SEG2:INTERP_KERNEL::NORM_POLYL; - break; - } - } - ret=ret || (newType!=type); - conn[newPos]=newType; - newPos+=newLgth+1; - posOfCurCell=index[i+1]; - index[i+1]=newPos; - } - else - { - std::copy(conn+posOfCurCell,conn+posOfCurCell+lgthOfCurCell,conn+newPos); - newPos+=lgthOfCurCell; - posOfCurCell+=lgthOfCurCell; - index[i+1]=newPos; - } - } - if(newPos!=initMeshLgth) - _nodal_connec->reAlloc(newPos); - if(ret) - computeTypes(); - return ret; -} - -/*! - * This method expects that spaceDimension is equal to 3 and meshDimension equal to 3. - * This method performs operation only on polyhedrons in \b this. If no polyhedrons exists in \b this, \b this remains unchanged. - * This method allows to merge if any coplanar 3DSurf cells that may appear in some polyhedrons cells. - * - * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. This epsilon is used to recenter around origin to have maximal - * precision. - */ -void MEDCouplingUMesh::simplifyPolyhedra(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyPolyhedra : works on meshdimension 3 and spaceDimension 3 !"); - MEDCouplingAutoRefCountObjectPtr coords=getCoords()->deepCpy(); - coords->recenterForMaxPrecision(eps); - // - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *index=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr connINew=DataArrayInt::New(); - connINew->alloc(nbOfCells+1,1); - int *connINewPtr=connINew->getPointer(); *connINewPtr++=0; - MEDCouplingAutoRefCountObjectPtr connNew=DataArrayInt::New(); connNew->alloc(0,1); - bool changed=false; - for(int i=0;iinsertAtTheEnd(conn+index[i],conn+index[i+1]); - *connINewPtr=connNew->getNumberOfTuples(); - } - if(changed) - setConnectivity(connNew,connINew,false); -} - -/*! - * This method returns all node ids used in the connectivity of \b this. The data array returned has to be dealt by the caller. - * The returned node ids are sorted ascendingly. This method is close to MEDCouplingUMesh::getNodeIdsInUse except - * the format of the returned DataArrayInt instance. - * - * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. - * \sa MEDCouplingUMesh::getNodeIdsInUse, areAllNodesFetched - */ -DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const int *maxEltPt=std::max_element(_nodal_connec->begin(),_nodal_connec->end()); - int maxElt=maxEltPt==_nodal_connec->end()?0:std::abs(*maxEltPt)+1; - std::vector retS(maxElt,false); - for(int i=0;i=0) - retS[conn[j]]=true; - int sz=0; - for(int i=0;ialloc(sz,1); - int *retPtr=ret->getPointer(); - for(int i=0;i& nodeIdsInUse) const -{ - int nbOfNodes((int)nodeIdsInUse.size()),nbOfCells(getNumberOfCells()); - const int *connIndex(_nodal_connec_index->getConstPointer()),*conn(_nodal_connec->getConstPointer()); - for(int i=0;i=0) - { - if(conn[j]getNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".
- * \ref py_mcumesh_getNodeIdsInUse "Here is a Python example". - * \endif - * \sa computeFetchedNodeIds, computeNodeIdsAlg() - */ -DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const -{ - nbrOfNodesInUse=-1; - int nbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfNodes,1); - int *traducer=ret->getPointer(); - std::fill(traducer,traducer+nbOfNodes,-1); - int nbOfCells=getNumberOfCells(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - for(int i=0;i=0) - { - if(conn[j]getNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of nodes constituting cell is computed. - * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. - * So for pohyhedrons some nodes can be counted several times in the returned result. - * - * \return a newly allocated array - * \sa MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell - */ -DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;i ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;i s(conn+connI[i]+1,conn+connI[i+1]); - if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED) - *retPtr=(int)s.size(); - else - { - s.erase(-1); - *retPtr=(int)s.size(); - } - } - return ret.retn(); -} - -/*! - * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. - * - * \return a newly allocated array - */ -DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;igetNumberOfNodes() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa areAllNodesFetched - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() -{ - return MEDCouplingPointSet::zipCoordsTraducer(); -} - -/*! - * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. - * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. - */ -int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType) -{ - switch(compType) - { - case 0: - return AreCellsEqual0(conn,connI,cell1,cell2); - case 1: - return AreCellsEqual1(conn,connI,cell1,cell2); - case 2: - return AreCellsEqual2(conn,connI,cell1,cell2); - case 3: - return AreCellsEqual3(conn,connI,cell1,cell2); - case 7: - return AreCellsEqual7(conn,connI,cell1,cell2); - } - throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1,2,3 or 7."); -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 0. - */ -int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2) -{ - if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) - return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0; - return 0; -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 1. - */ -int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2) -{ - int sz=connI[cell1+1]-connI[cell1]; - if(sz==connI[cell2+1]-connI[cell2]) - { - if(conn[connI[cell1]]==conn[connI[cell2]]) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]); - unsigned dim=cm.getDimension(); - if(dim!=3) - { - if(dim!=1) - { - int sz1=2*(sz-1); - INTERP_KERNEL::AutoPtr tmp=new int[sz1]; - int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); - std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); - work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); - return work!=tmp+sz1?1:0; - } - else - return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3 - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual1 : not implemented yet for meshdim == 3 !"); - } - } - return 0; -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 2. - */ -int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2) -{ - if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) - { - if(conn[connI[cell1]]==conn[connI[cell2]]) - { - std::set s1(conn+connI[cell1]+1,conn+connI[cell1+1]); - std::set s2(conn+connI[cell2]+1,conn+connI[cell2+1]); - return s1==s2?1:0; - } - } - return 0; -} - -/*! - * This method is less restrictive than AreCellsEqual2. Here the geometric type is absolutely not taken into account ! - */ -int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2) -{ - if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) - { - std::set s1(conn+connI[cell1]+1,conn+connI[cell1+1]); - std::set s2(conn+connI[cell2]+1,conn+connI[cell2+1]); - return s1==s2?1:0; - } - return 0; -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 7. - */ -int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2) -{ - int sz=connI[cell1+1]-connI[cell1]; - if(sz==connI[cell2+1]-connI[cell2]) - { - if(conn[connI[cell1]]==conn[connI[cell2]]) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]); - unsigned dim=cm.getDimension(); - if(dim!=3) - { - if(dim!=1) - { - int sz1=2*(sz-1); - INTERP_KERNEL::AutoPtr tmp=new int[sz1]; - int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); - std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); - work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); - if(work!=tmp+sz1) - return 1; - else - { - std::reverse_iterator it1((int *)tmp+sz1); - std::reverse_iterator it2((int *)tmp); - if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2) - return 2; - else - return 0; - } - - return work!=tmp+sz1?1:0; - } - else - {//case of SEG2 and SEG3 - if(std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)) - return 1; - if(!cm.isQuadratic()) - { - std::reverse_iterator it1(conn+connI[cell1+1]); - std::reverse_iterator it2(conn+connI[cell1]+1); - if(std::equal(it1,it2,conn+connI[cell2]+1)) - return 2; - return 0; - } - else - { - if(conn[connI[cell1]+1]==conn[connI[cell2]+2] && conn[connI[cell1]+2]==conn[connI[cell2]+1] && conn[connI[cell1]+3]==conn[connI[cell2]+3]) - return 2; - return 0; - } - } - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual7 : not implemented yet for meshdim == 3 !"); - } - } - return 0; -} - -/*! - * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'. - * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned - * and result remains unchanged. - * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. - * If in 'candidates' pool -1 value is considered as an empty value. - * WARNING this method returns only ONE set of result ! - */ -bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) -{ - if(candidates.size()<1) - return false; - bool ret=false; - std::vector::const_iterator iter=candidates.begin(); - int start=(*iter++); - for(;iter!=candidates.end();iter++) - { - int status=AreCellsEqual(conn,connI,start,*iter,compType); - if(status!=0) - { - if(!ret) - { - result->pushBackSilent(start); - ret=true; - } - if(status==1) - result->pushBackSilent(*iter); - else - result->pushBackSilent(status==2?(*iter+1):-(*iter+1)); - } - } - return ret; -} - -/*! - * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified - * by \a compType. - * This method keeps the coordiantes of \a this. This method is time consuming. - * - * \param [in] compType input specifying the technique used to compare cells each other. - * - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy. - * - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation) - * and their type equal. For 1D mesh the policy 1 is equivalent to 0. - * - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy - * can be used for users not sensitive to orientation of cell - * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned. - * \param [out] commonCellsArr common cells ids (\ref numbering-indirect) - * \param [out] commonCellsIArr common cells ids (\ref numbering-indirect) - * \return the correspondance array old to new in a newly allocated array. - * - */ -void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const -{ - MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); - getReverseNodalConnectivity(revNodal,revNodalI); - FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr); -} - -void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, - DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) -{ - MEDCouplingAutoRefCountObjectPtr commonCells=DataArrayInt::New(),commonCellsI=DataArrayInt::New(); commonCells->alloc(0,1); - int nbOfCells=nodalI->getNumberOfTuples()-1; - commonCellsI->reserve(1); commonCellsI->pushBackSilent(0); - const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); - const int *connPtr=nodal->getConstPointer(),*connIPtr=nodalI->getConstPointer(); - std::vector isFetched(nbOfCells,false); - if(startCellId==0) - { - for(int i=0;i(),-1)); - std::vector v,v2; - if(connOfNode!=connPtr+connIPtr[i+1]) - { - const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); - v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]); - connOfNode++; - } - for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) - if(*connOfNode>=0) - { - v=v2; - const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); - std::vector::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); - v2.resize(std::distance(v2.begin(),it)); - } - if(v2.size()>1) - { - if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) - { - int pos=commonCellsI->back(); - commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); - for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) - isFetched[*it]=true; - } - } - } - } - } - else - { - for(int i=startCellId;i(),-1)); - std::vector v,v2; - if(connOfNode!=connPtr+connIPtr[i+1]) - { - v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]); - connOfNode++; - } - for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) - if(*connOfNode>=0) - { - v=v2; - std::vector::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); - v2.resize(std::distance(v2.begin(),it)); - } - if(v2.size()>1) - { - if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) - { - int pos=commonCellsI->back(); - commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); - for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) - isFetched[*it]=true; - } - } - } - } - } - commonCellsArr=commonCells.retn(); - commonCellsIArr=commonCellsI.retn(); -} - -/*! - * Checks if \a this mesh includes all cells of an \a other mesh, and returns an array - * giving for each cell of the \a other an id of a cell in \a this mesh. A value larger - * than \a other->getNumberOfCells() in the returned array means that there is no - * corresponding cell in \a this mesh. - * It is expected that \a this and \a other meshes share the same node coordinates - * array, if it is not so an exception is thrown. - * \param [in] other - the mesh to compare with. - * \param [in] compType - specifies a cell comparison technique. For meaning of its - * valid values [0,1,2], see zipConnectivityTraducer(). - * \param [out] arr - a new instance of DataArrayInt returning correspondence - * between cells of the two meshes. It contains \a other->getNumberOfCells() - * values. The caller is to delete this array using - * decrRef() as it is no more needed. - * \return bool - \c true if all cells of \a other mesh are present in the \a this - * mesh. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_areCellsIncludedIn "Here is a C++ example".
- * \ref py_mcumesh_areCellsIncludedIn "Here is a Python example". - * \endif - * \sa checkDeepEquivalOnSameNodesWith() - * \sa checkGeoEquivalWith() - */ -bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const -{ - MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - int nbOfCells=getNumberOfCells(); - static const int possibleCompType[]={0,1,2}; - if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int)) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : "; - std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator(oss," ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType,nbOfCells); - arr=o2n->substr(nbOfCells); - arr->setName(other->getName()); - int tmp; - if(other->getNumberOfCells()==0) - return true; - return arr->getMaxValue(tmp)getNumberOfCells()'. - * \return If \a other is fully included in 'this 'true is returned. If not false is returned. - */ -bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const -{ - MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - DataArrayInt *commonCells=0,*commonCellsI=0; - int thisNbCells=getNumberOfCells(); - mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - const int *commonCellsPtr=commonCells->getConstPointer(),*commonCellsIPtr=commonCellsI->getConstPointer(); - int otherNbCells=other->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayInt::New(); - arr2->alloc(otherNbCells,1); - arr2->fillWithZero(); - int *arr2Ptr=arr2->getPointer(); - int nbOfCommon=commonCellsI->getNumberOfTuples()-1; - for(int i=0;i0?1:-1; - int val=std::abs(commonCellsPtr[j])-1; - if(val>=thisNbCells) - arr2Ptr[val-thisNbCells]=sig*(start+1); - } - } - } - arr2->setName(other->getName()); - if(arr2->presenceOfValue(0)) - return false; - arr=arr2.retn(); - return true; -} - -MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : input other is null !"); - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type unstructured !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - return MergeUMeshesOnSameCoords(ms); -} - -/*! - * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords). - * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input - * cellIds is not given explicitely but by a range python like. - * - * \param start - * \param end - * \param step - * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called. - * \return a newly allocated - * - * \warning This method modifies can generate an unstructured mesh whose cells are not sorted by geometric type order. - * In view of the MED file writing, a renumbering of cells of returned unstructured mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const -{ - if(getMeshDimension()!=-1) - return MEDCouplingPointSet::buildPartOfMySelf2(start,end,step,keepCoords); - else - { - int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh "); - if(newNbOfCells!=1) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); - if(start!=0) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); - incrRef(); - return const_cast(this); - } -} - -/*! - * Creates a new MEDCouplingUMesh containing specified cells of \a this mesh. - * The result mesh shares or not the node coordinates array with \a this mesh depending - * on \a keepCoords parameter. - * \warning Cells of the result mesh can be \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in] begin - an array of cell ids to include to the new mesh. - * \param [in] end - a pointer to last-plus-one-th element of \a begin. - * \param [in] keepCoords - if \c true, the result mesh shares the node coordinates - * array of \a this mesh, else "free" nodes are removed from the result mesh - * by calling zipCoords(). - * \return MEDCouplingPointSet * - a new instance of MEDCouplingUMesh. The caller is - * to delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in the array \a begin is not valid. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildPartOfMySelf "Here is a C++ example".
- * \ref py_mcumesh_buildPartOfMySelf "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const -{ - if(getMeshDimension()!=-1) - return MEDCouplingPointSet::buildPartOfMySelf(begin,end,keepCoords); - else - { - if(end-begin!=1) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); - if(begin[0]!=0) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); - incrRef(); - return const_cast(this); - } -} - -/*! - * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here. - * - * This method allows to partially modify some cells in \b this (whose list is specified by [ \b cellIdsBg, \b cellIdsEnd ) ) with cells coming in \b otherOnSameCoordsThanThis. - * Size of [ \b cellIdsBg, \b cellIdsEnd ) ) must be equal to the number of cells of otherOnSameCoordsThanThis. - * The number of cells of \b this will remain the same with this method. - * - * \param [in] cellIdsBg begin of cell ids (included) of cells in this to assign - * \param [in] cellIdsEnd end of cell ids (excluded) of cells in this to assign - * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd ). - * Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same - */ -void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) -{ - checkConnectivityFullyDefined(); - otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); - if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); - if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); - oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCellsToModify=(int)std::distance(cellIdsBg,cellIdsEnd); - if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCells=getNumberOfCells(); - bool easyAssign=true; - const int *connI=_nodal_connec_index->getConstPointer(); - const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); - for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++) - { - if(*it>=0 && *it arrOutAuto(arrOut),arrIOutAuto(arrIOut); - setConnectivity(arrOut,arrIOut,true); - } -} - -void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) -{ - checkConnectivityFullyDefined(); - otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); - if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); - if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); - oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : "); - if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCells=getNumberOfCells(); - bool easyAssign=true; - const int *connI=_nodal_connec_index->getConstPointer(); - const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); - int it=start; - for(int i=0;i=0 && it arrOutAuto(arrOut),arrIOutAuto(arrIOut); - setConnectivity(arrOut,arrIOut,true); - } -} - -/*! - * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). - * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. - * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. - * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept. - * - * \param [in] begin input start of array of node ids. - * \param [in] end input end of array of node ids. - * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in. - * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. - */ -void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const -{ - MEDCouplingAutoRefCountObjectPtr cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); - checkConnectivityFullyDefined(); - int tmp=-1; - int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1; - std::vector fastFinder(sz,false); - for(const int *work=begin;work!=end;work++) - if(*work>=0 && *workgetConstPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;i=0) - { - ref++; - if(fastFinder[*work2]) - nbOfHit++; - } - if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) - cellIdsKept->pushBackSilent(i); - } - cellIdsKeptArr=cellIdsKept.retn(); -} - -/*! - * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a - * this->getMeshDimension(), that bound some cells of \a this mesh. - * The cells of lower dimension to include to the result mesh are selected basing on - * specified node ids and the value of \a fullyIn parameter. If \a fullyIn ==\c true, a - * cell is copied if its all nodes are in the array \a begin of node ids. If \a fullyIn - * ==\c false, a cell is copied if any its node is in the array of node ids. The - * created mesh shares the node coordinates array with \a this mesh. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are added, else cells whose any node is in the - * array \a begin are added. - * \return MEDCouplingPointSet * - new instance of MEDCouplingUMesh. The caller is - * to delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any node id in \a begin is not valid. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildFacePartOfMySelfNode "Here is a C++ example".
- * \ref py_mcumesh_buildFacePartOfMySelfNode "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const -{ - MEDCouplingAutoRefCountObjectPtr desc,descIndx,revDesc,revDescIndx; - desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - desc=0; descIndx=0; revDesc=0; revDescIndx=0; - return subMesh->buildPartOfMySelfNode(begin,end,fullyIn); -} - -/*! - * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a - * this->getMeshDimension(), which bound only one cell of \a this mesh. - * \param [in] keepCoords - if \c true, the result mesh shares the node coordinates - * array of \a this mesh, else "free" nodes are removed from the result mesh - * by calling zipCoords(). - * \return MEDCouplingPointSet * - a new instance of MEDCouplingUMesh. The caller is - * to delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildBoundaryMesh "Here is a C++ example".
- * \ref py_mcumesh_buildBoundaryMesh "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const -{ - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - revDesc->decrRef(); - desc->decrRef(); - descIndx->decrRef(); - int nbOfCells=meshDM1->getNumberOfCells(); - const int *revDescIndxC=revDescIndx->getConstPointer(); - std::vector boundaryCells; - for(int i=0;idecrRef(); - MEDCouplingPointSet *ret=meshDM1->buildPartOfMySelf(&boundaryCells[0],&boundaryCells[0]+boundaryCells.size(),keepCoords); - return ret; -} - -/*! - * This method returns a newly created DataArrayInt instance containing ids of cells located in boundary. - * A cell is detected to be on boundary if it contains one or more than one face having only one father. - * This method makes the assumption that \a this is fully defined (coords,connectivity). If not an exception will be thrown. - */ -DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const -{ - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); - // - buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx)->decrRef(); - desc=(DataArrayInt*)0; descIndx=(DataArrayInt*)0; - // - MEDCouplingAutoRefCountObjectPtr tmp=revDescIndx->deltaShiftIndex(); - MEDCouplingAutoRefCountObjectPtr faceIds=tmp->getIdsEqual(1); tmp=(DataArrayInt*)0; - const int *revDescPtr=revDesc->getConstPointer(); - const int *revDescIndxPtr=revDescIndx->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector ret1(nbOfCells,false); - int sz=0; - for(const int *pt=faceIds->begin();pt!=faceIds->end();pt++) - if(!ret1[revDescPtr[revDescIndxPtr[*pt]]]) - { ret1[revDescPtr[revDescIndxPtr[*pt]]]=true; sz++; } - // - DataArrayInt *ret2=DataArrayInt::New(); - ret2->alloc(sz,1); - int *ret2Ptr=ret2->getPointer(); - sz=0; - for(std::vector::const_iterator it=ret1.begin();it!=ret1.end();it++,sz++) - if(*it) - *ret2Ptr++=sz; - ret2->setName("BoundaryCells"); - return ret2; -} - -/*! - * This method finds in \b this the cell ids that lie on mesh \b otherDimM1OnSameCoords. - * \b this and \b otherDimM1OnSameCoords have to lie on the same coordinate array pointer. The coherency of that coords array with connectivity - * of \b this and \b otherDimM1OnSameCoords is not important here because this method works only on connectivity. - * this->getMeshDimension() - 1 must be equal to otherDimM1OnSameCoords.getMeshDimension() - * - * s0 is the cell ids set in \b this lying on at least one node in the fetched nodes in \b otherDimM1OnSameCoords. - * This method also returns the cells ids set s1 which contains the cell ids in \b this for which one of the dim-1 constituent - * equals a cell in \b otherDimM1OnSameCoords. - * - * \throw if \b otherDimM1OnSameCoords is not part of constituent of \b this, or if coordinate pointer of \b this and \b otherDimM1OnSameCoords - * are not same, or if this->getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension() - * - * \param [in] otherDimM1OnSameCoords - * \param [out] cellIdsRk0 a newly allocated array containing the cell ids of s0 (which are cell ids of \b this) in the above algorithm. - * \param [out] cellIdsRk1 a newly allocated array containing the cell ids of s1 \b indexed into the \b cellIdsRk0 subset. To get the absolute ids of s1, simply invoke - * cellIdsRk1->transformWithIndArr(cellIdsRk0->begin(),cellIdsRk0->end()); - */ -void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const -{ - if(getCoords()!=otherDimM1OnSameCoords.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : coordinates pointer are not the same ! Use tryToShareSameCoords method !"); - checkConnectivityFullyDefined(); - otherDimM1OnSameCoords.checkConnectivityFullyDefined(); - if(getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : invalid mesh dimension of input mesh regarding meshdimesion of this !"); - MEDCouplingAutoRefCountObjectPtr fetchedNodeIds1=otherDimM1OnSameCoords.computeFetchedNodeIds(); - MEDCouplingAutoRefCountObjectPtr s0arr=getCellIdsLyingOnNodes(fetchedNodeIds1->begin(),fetchedNodeIds1->end(),false); - MEDCouplingAutoRefCountObjectPtr thisPart=static_cast(buildPartOfMySelf(s0arr->begin(),s0arr->end(),true)); - MEDCouplingAutoRefCountObjectPtr descThisPart=DataArrayInt::New(),descIThisPart=DataArrayInt::New(),revDescThisPart=DataArrayInt::New(),revDescIThisPart=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr thisPartConsti=thisPart->buildDescendingConnectivity(descThisPart,descIThisPart,revDescThisPart,revDescIThisPart); - const int *revDescThisPartPtr=revDescThisPart->getConstPointer(),*revDescIThisPartPtr=revDescIThisPart->getConstPointer(); - DataArrayInt *idsOtherInConsti=0; - bool b=thisPartConsti->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsOtherInConsti); - MEDCouplingAutoRefCountObjectPtr idsOtherInConstiAuto(idsOtherInConsti); - if(!b) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : the given mdim-1 mesh in other is not a constituent of this !"); - std::set s1; - for(const int *idOther=idsOtherInConsti->begin();idOther!=idsOtherInConsti->end();idOther++) - s1.insert(revDescThisPartPtr+revDescIThisPartPtr[*idOther],revDescThisPartPtr+revDescIThisPartPtr[*idOther+1]); - MEDCouplingAutoRefCountObjectPtr s1arr_renum1=DataArrayInt::New(); s1arr_renum1->alloc((int)s1.size(),1); std::copy(s1.begin(),s1.end(),s1arr_renum1->getPointer()); - s1arr_renum1->sort(); - cellIdsRk0=s0arr.retn(); - //cellIdsRk1=s_renum1.retn(); - cellIdsRk1=s1arr_renum1.retn(); -} - -/*! - * This method computes the skin of \b this. That is to say the consituting meshdim-1 mesh is built and only the boundary subpart is - * returned. This subpart of meshdim-1 mesh is built using meshdim-1 cells in it shared only one cell in \b this. - * - * \return a newly allocated mesh lying on the same coordinates than \b this. The caller has to deal with returned mesh. - */ -MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const -{ - MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); - // - MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - revDesc=0; desc=0; descIndx=0; - MEDCouplingAutoRefCountObjectPtr revDescIndx2=revDescIndx->deltaShiftIndex(); - MEDCouplingAutoRefCountObjectPtr part=revDescIndx2->getIdsEqual(1); - return static_cast(meshDM1->buildPartOfMySelf(part->begin(),part->end(),true)); -} - -/*! - * Finds nodes lying on the boundary of \a this mesh. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * nodes. The caller is to delete this array using decrRef() as it is no - * more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is node defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_findBoundaryNodes "Here is a C++ example".
- * \ref py_mcumesh_findBoundaryNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const -{ - MEDCouplingAutoRefCountObjectPtr skin=computeSkin(); - return skin->computeFetchedNodeIds(); -} - -MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const -{ - incrRef(); - return const_cast(this); -} - -/*! - * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array. - * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1. - * This method searches for nodes needed to be duplicated. These nodes are nodes fetched by \b otherDimM1OnSameCoords which are not part of the boundary of \b otherDimM1OnSameCoords. - * If a node is in the boundary of \b this \b and in the boundary of \b otherDimM1OnSameCoords this node is considerd as needed to be duplicated. - * When the set of node ids \b nodeIdsToDuplicate is computed, cell ids in \b this is searched so that their connectivity includes at least 1 node in \b nodeIdsToDuplicate. - * - * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input - * parameter is altered during the call. - * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above. - * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed. - * \param [out] cellIdsNotModified cell ids int \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum. - * - * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons). - */ -void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, - DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const -{ - typedef MEDCouplingAutoRefCountObjectPtr DAInt; - - checkFullyDefined(); - otherDimM1OnSameCoords.checkFullyDefined(); - if(getCoords()!=otherDimM1OnSameCoords.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : meshes do not share the same coords array !"); - if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the mesh given in other parameter must have this->getMeshDimension()-1 !"); - DataArrayInt *cellIdsRk0=0,*cellIdsRk1=0; - findCellIdsLyingOn(otherDimM1OnSameCoords,cellIdsRk0,cellIdsRk1); - DAInt cellIdsRk0Auto(cellIdsRk0),cellIdsRk1Auto(cellIdsRk1); - DAInt s0=cellIdsRk1->buildComplement(cellIdsRk0->getNumberOfTuples()); - s0->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end()); - MEDCouplingAutoRefCountObjectPtr m0Part=static_cast(buildPartOfMySelf(s0->begin(),s0->end(),true)); - DAInt s1=m0Part->computeFetchedNodeIds(); - DAInt s2=otherDimM1OnSameCoords.computeFetchedNodeIds(); - DAInt s3=s2->buildSubstraction(s1); - cellIdsRk1->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end()); - // - MEDCouplingAutoRefCountObjectPtr m0Part2=static_cast(buildPartOfMySelf(cellIdsRk1->begin(),cellIdsRk1->end(),true)); - int nCells2 = m0Part2->getNumberOfCells(); - DAInt desc00=DataArrayInt::New(),descI00=DataArrayInt::New(),revDesc00=DataArrayInt::New(),revDescI00=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr m01=m0Part2->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00); - // Neighbor information of the mesh without considering the crack (serves to count how many connex pieces it is made of) - DataArrayInt *tmp00=0,*tmp11=0; - MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00, tmp00, tmp11); - DAInt neighInit00(tmp00); - DAInt neighIInit00(tmp11); - // Neighbor information of the mesh WITH the crack (some neighbors are removed): - DataArrayInt *idsTmp=0; - bool b=m01->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsTmp); - DAInt ids(idsTmp); - if(!b) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the given mdim-1 mesh in other is not a constituent of this !"); - // In the neighbor information remove the connection between high dimension cells and its low level constituents which are part - // of the frontier given in parameter (i.e. the cells of low dimension from the group delimiting the crack): - MEDCouplingUMesh::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00); - DataArrayInt *tmp0=0,*tmp1=0; - // Compute the neighbor of each cell in m0Part2, taking into account the broken link above. Two - // cells on either side of the crack (defined by the mesh of low dimension) are not neighbor anymore. - ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1); - DAInt neigh00(tmp0); - DAInt neighI00(tmp1); - - // For each initial connex part of the sub-mesh (or said differently for each independent crack): - int seed = 0, nIter = 0; - int nIterMax = nCells2+1; // Safety net for the loop - DAInt hitCells = DataArrayInt::New(); hitCells->alloc(nCells2); - hitCells->fillWithValue(-1); - DAInt cellsToModifyConn0_torenum = DataArrayInt::New(); - cellsToModifyConn0_torenum->alloc(0,1); - while (nIter < nIterMax) - { - DAInt t = hitCells->getIdsEqual(-1); - if (!t->getNumberOfTuples()) - break; - // Connex zone without the crack (to compute the next seed really) - int dnu; - DAInt connexCheck = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neighInit00,neighIInit00, -1, dnu); - int cnt = 0; - for (int * ptr = connexCheck->getPointer(); cnt < connexCheck->getNumberOfTuples(); ptr++, cnt++) - hitCells->setIJ(*ptr,0,1); - // Connex zone WITH the crack (to identify cells lying on either part of the crack) - DAInt spreadZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neigh00,neighI00, -1, dnu); - cellsToModifyConn0_torenum = DataArrayInt::Aggregate(cellsToModifyConn0_torenum, spreadZone, 0); - // Compute next seed, i.e. a cell in another connex part, which was not covered by the previous iterations - DAInt comple = cellsToModifyConn0_torenum->buildComplement(nCells2); - DAInt nonHitCells = hitCells->getIdsEqual(-1); - DAInt intersec = nonHitCells->buildIntersection(comple); - if (intersec->getNumberOfTuples()) - { seed = intersec->getIJ(0,0); } - else - { break; } - nIter++; - } - if (nIter >= nIterMax) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate(): internal error - too many iterations."); - - DAInt cellsToModifyConn1_torenum=cellsToModifyConn0_torenum->buildComplement(neighI00->getNumberOfTuples()-1); - cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); - cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); - // - cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn(); - cellIdsNotModified=cellsToModifyConn1_torenum.retn(); - nodeIdsToDuplicate=s3.retn(); -} - -/*! - * This method operates a modification of the connectivity and coords in \b this. - * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this - * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). - * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be - * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1, - * node id nodeIdsToDuplicateBg[2] will have id this->getNumberOfNodes()+2... - * - * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. - * - * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only - * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - */ -void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) -{ - int nbOfNodes=getNumberOfNodes(); - duplicateNodesInCoords(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); - duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes); -} - -/*! - * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of - * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range ! - * - * \param [in] offset - specifies the offset to be applied on each element of connectivity. - * - * \sa renumberNodesInConn - */ -void MEDCouplingUMesh::renumberNodesWithOffsetInConn(int offset) -{ - checkConnectivityFullyDefined(); - int *conn(getNodalConnectivity()->getPointer()); - const int *connIndex(getNodalConnectivityIndex()->getConstPointer()); - int nbOfCells(getNumberOfCells()); - for(int i=0;i=0)//avoid polyhedron separator - { - node+=offset; - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead - * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction - * of a big mesh. - */ -void MEDCouplingUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N) -{ - checkConnectivityFullyDefined(); - int *conn(getNodalConnectivity()->getPointer()); - const int *connIndex(getNodalConnectivityIndex()->getConstPointer()); - int nbOfCells(getNumberOfCells()); - for(int i=0;i=0)//avoid polyhedron separator - { - INTERP_KERNEL::HashMap::const_iterator it(newNodeNumbersO2N.find(node)); - if(it!=newNodeNumbersO2N.end()) - { - node=(*it).second; - } - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::renumberNodesInConn(map) : presence in connectivity for cell #" << i << " of node #" << node << " : Not in map !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * Changes ids of nodes within the nodal connectivity arrays according to a permutation - * array in "Old to New" mode. The node coordinates array is \b not changed by this method. - * This method is a generalization of shiftNodeNumbersInConn(). - * \warning This method performs no check of validity of new ids. **Use it with care !** - * \param [in] newNodeNumbersO2N - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_renumberNodesInConn "Here is a C++ example".
- * \ref py_mcumesh_renumberNodesInConn "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - checkConnectivityFullyDefined(); - int *conn=getNodalConnectivity()->getPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells(getNumberOfCells()); - for(int i=0;i=0)//avoid polyhedron separator - { - node=newNodeNumbersO2N[node]; - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords. - * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care ! - * This method is an specialization of \ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn method". - * - * \param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this. - */ -void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) -{ - checkConnectivityFullyDefined(); - int *conn=getNodalConnectivity()->getPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for(int i=0;i=0)//avoid polyhedron separator - { - node+=delta; - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * This method operates a modification of the connectivity in \b this. - * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method. - * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this - * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). - * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be - * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1, - * node id nodeIdsToDuplicateBg[2] will have id offset+2... - * - * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. - * As an another consequense after the call of this method \b this can be transiently non cohrent. - * - * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only - * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - * \param [in] offset the offset applied to all node ids in connectivity that are in [ \a nodeIdsToDuplicateBg, \a nodeIdsToDuplicateEnd ). - */ -void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) -{ - checkConnectivityFullyDefined(); - std::map m; - int val=offset; - for(const int *work=nodeIdsToDuplicateBg;work!=nodeIdsToDuplicateEnd;work++,val++) - m[*work]=val; - int *conn=getNodalConnectivity()->getPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for(int i=0;i=0)//avoid polyhedron separator - { - std::map::iterator it=m.find(node); - if(it!=m.end()) - node=(*it).second; - } - } - updateTime(); -} - -/*! - * This method renumbers cells of \a this using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) - * - * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell. - * After the call of this method the number of cells remains the same as before. - * - * If 'check' equals true the method will check that any elements in [ \a old2NewBg; \a old2NewEnd ) is unique ; if not - * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [ \a old2NewBg ; \a old2NewEnd ) is not expected to - * be strictly in [0;this->getNumberOfCells()). - * - * If 'check' equals false the method will not check the content of [ \a old2NewBg ; \a old2NewEnd ). - * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [ \a old2NewBg ; \a old2NewEnd ) should be unique and - * should be contained in[0;this->getNumberOfCells()). - * - * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells() - * \param check - */ -void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) -{ - checkConnectivityFullyDefined(); - int nbCells=getNumberOfCells(); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells); - // - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); o2n->useArray(array,false,C_DEALLOC,nbCells,1); - MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(nbCells); - const int *n2oPtr=n2o->begin(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - newConn->alloc(_nodal_connec->getNumberOfTuples(),_nodal_connec->getNumberOfComponents()); - newConn->copyStringInfoFrom(*_nodal_connec); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(_nodal_connec_index->getNumberOfTuples(),_nodal_connec_index->getNumberOfComponents()); - newConnI->copyStringInfoFrom(*_nodal_connec_index); - // - int *newC=newConn->getPointer(); - int *newCI=newConnI->getPointer(); - int loc=0; - newCI[0]=loc; - for(int i=0;i(array)); -} - -/*! - * Finds cells whose bounding boxes intersect a given bounding box. - * \param [in] bbox - an array defining the bounding box via coordinates of its - * extremum points in "no interlace" mode, i.e. xMin, xMax, yMin, yMax, zMin, - * zMax (if in 3D). - * \param [in] eps - a factor used to increase size of the bounding box of cell - * before comparing it with \a bbox. This factor is multiplied by the maximal - * extent of the bounding box of cell to produce an addition to this bounding box. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids for found - * cells. The caller is to delete this array using decrRef() as it is no more - * needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsInBoundingBox "Here is a C++ example".
- * \ref py_mcumesh_getCellsInBoundingBox "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); - if(getMeshDimension()==-1) - { - elems->pushBackSilent(0); - return elems.retn(); - } - int dim=getSpaceDimension(); - INTERP_KERNEL::AutoPtr elem_bb=new double[2*dim]; - const int* conn = getNodalConnectivity()->getConstPointer(); - const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); - const double* coords = getCoords()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for ( int ielem=0; ielem::max(); - elem_bb[i*2+1]=-std::numeric_limits::max(); - } - - for (int inode=conn_index[ielem]+1; inode=0)//avoid polyhedron separator - { - for (int idim=0; idim elem_bb[idim*2+1] ) - { - elem_bb[idim*2+1] = coords[node*dim+idim] ; - } - } - } - } - if (intersectsBoundingBox(elem_bb, bbox, dim, eps)) - elems->pushBackSilent(ielem); - } - return elems.retn(); -} - -/*! - * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox' or touching 'bbox' (within 'eps' distance). - * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be - * added in 'elems' parameter. - */ -DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) -{ - MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); - if(getMeshDimension()==-1) - { - elems->pushBackSilent(0); - return elems.retn(); - } - int dim=getSpaceDimension(); - INTERP_KERNEL::AutoPtr elem_bb=new double[2*dim]; - const int* conn = getNodalConnectivity()->getConstPointer(); - const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); - const double* coords = getCoords()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for ( int ielem=0; ielem::max(); - elem_bb[i*2+1]=-std::numeric_limits::max(); - } - - for (int inode=conn_index[ielem]+1; inode=0)//avoid polyhedron separator - { - for (int idim=0; idim elem_bb[idim*2+1] ) - { - elem_bb[idim*2+1] = coords[node*dim+idim] ; - } - } - } - } - if(intersectsBoundingBox(bbox, elem_bb, dim, eps)) - elems->pushBackSilent(ielem); - } - return elems.retn(); -} - -/*! - * Returns a type of a cell by its id. - * \param [in] cellId - the id of the cell of interest. - * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type. - * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). - */ -INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - if(cellId>=0 && cellId<(int)_nodal_connec_index->getNbOfElems()-1) - return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]]; - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << _nodal_connec_index->getNbOfElems()-1 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. - * This method does not throw exception if geometric type \a type is not in \a this. - * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. - * The coordinates array is not considered here. - * - * \param [in] type the geometric type - * \return cell ids in this having geometric type \a type. - */ -DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(0,1); - checkConnectivityFullyDefined(); - int nbCells=getNumberOfCells(); - int mdim=getMeshDimension(); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(mdim!=(int)cm.getDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::giveCellsWithType : Mismatch between mesh dimension and dimension of the cell !"); - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - for(int i=0;ipushBackSilent(i); - } - return ret.retn(); -} - -/*! - * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. - */ -int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - int nbOfCells=getNumberOfCells(); - int ret=0; - for(int i=0;igetNumberOfCells() ). - */ -void MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - for(const int *w=pt+ptI[cellId]+1;w!=pt+ptI[cellId+1];w++) - if(*w>=0) - conn.push_back(*w); -} - -std::string MEDCouplingUMesh::simpleRepr() const -{ - static const char msg0[]="No coordinates specified !"; - std::ostringstream ret; - ret << "Unstructured mesh with name : \"" << getName() << "\"\n"; - ret << "Description of mesh : \"" << getDescription() << "\"\n"; - int tmpp1,tmpp2; - double tt=getTime(tmpp1,tmpp2); - ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; - ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; - if(_mesh_dim>=-1) - { ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : "; } - else - { ret << " Mesh dimension has not been set or is invalid !"; } - if(_coords!=0) - { - const int spaceDim=getSpaceDimension(); - ret << spaceDim << "\nInfo attached on space dimension : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - ret << msg0 << "\n"; - ret << "Number of nodes : "; - if(_coords!=0) - ret << getNumberOfNodes() << "\n"; - else - ret << msg0 << "\n"; - ret << "Number of cells : "; - if(_nodal_connec!=0 && _nodal_connec_index!=0) - ret << getNumberOfCells() << "\n"; - else - ret << "No connectivity specified !" << "\n"; - ret << "Cell types present : "; - for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); - ret << cm.getRepr() << " "; - } - ret << "\n"; - return ret.str(); -} - -std::string MEDCouplingUMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << simpleRepr(); - ret << "\nCoordinates array : \n___________________\n\n"; - if(_coords) - _coords->reprWithoutNameStream(ret); - else - ret << "No array set !\n"; - ret << "\n\nConnectivity arrays : \n_____________________\n\n"; - reprConnectivityOfThisLL(ret); - return ret.str(); -} - -/*! - * This method returns a C++ code that is a dump of \a this. - * This method will throw if this is not fully defined. - */ -std::string MEDCouplingUMesh::cppRepr() const -{ - static const char coordsName[]="coords"; - static const char connName[]="conn"; - static const char connIName[]="connI"; - checkFullyDefined(); - std::ostringstream ret; ret << "// coordinates" << std::endl; - _coords->reprCppStream(coordsName,ret); ret << std::endl << "// connectivity" << std::endl; - _nodal_connec->reprCppStream(connName,ret); ret << std::endl; - _nodal_connec_index->reprCppStream(connIName,ret); ret << std::endl; - ret << "MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(\"" << getName() << "\"," << getMeshDimension() << ");" << std::endl; - ret << "mesh->setCoords(" << coordsName << ");" << std::endl; - ret << "mesh->setConnectivity(" << connName << "," << connIName << ",true);" << std::endl; - ret << coordsName << "->decrRef(); " << connName << "->decrRef(); " << connIName << "->decrRef();" << std::endl; - return ret.str(); -} - -std::string MEDCouplingUMesh::reprConnectivityOfThis() const -{ - std::ostringstream ret; - reprConnectivityOfThisLL(ret); - return ret.str(); -} - -/*! - * This method builds a newly allocated instance (with the same name than \a this) that the caller has the responsability to deal with. - * This method returns an instance with all arrays allocated (connectivity, connectivity index, coordinates) - * but with length of these arrays set to 0. It allows to define an "empty" mesh (with nor cells nor nodes but compliant with - * some algos). - * - * This method expects that \a this has a mesh dimension set and higher or equal to 0. If not an exception will be thrown. - * This method analyzes the 3 arrays of \a this. For each the following behaviour is done : if the array is null a newly one is created - * with number of tuples set to 0, if not the array is taken as this in the returned instance. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const -{ - int mdim=getMeshDimension(); - if(mdim<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),mdim); - MEDCouplingAutoRefCountObjectPtr tmp1,tmp2; - bool needToCpyCT=true; - if(!_nodal_connec) - { - tmp1=DataArrayInt::New(); tmp1->alloc(0,1); - needToCpyCT=false; - } - else - { - tmp1=_nodal_connec; - tmp1->incrRef(); - } - if(!_nodal_connec_index) - { - tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); - needToCpyCT=false; - } - else - { - tmp2=_nodal_connec_index; - tmp2->incrRef(); - } - ret->setConnectivity(tmp1,tmp2,false); - if(needToCpyCT) - ret->_types=_types; - if(!_coords) - { - MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); - ret->setCoords(coords); - } - else - ret->setCoords(_coords); - return ret.retn(); -} - -void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const -{ - if(_nodal_connec!=0 && _nodal_connec_index!=0) - { - int nbOfCells=getNumberOfCells(); - const int *c=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;i(stream," ")); - stream << "\n"; - } - } - else - stream << "Connectivity not defined !\n"; -} - -int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - if(pt[ptI[cellId]]!=INTERP_KERNEL::NORM_POLYHED) - return ptI[cellId+1]-ptI[cellId]-1; - else - return (int)std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind2nd(std::not_equal_to(),-1)); -} - -/*! - * Returns types of cells of the specified part of \a this mesh. - * This method avoids computing sub-mesh explicitely to get its types. - * \param [in] begin - an array of cell ids of interest. - * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. - * \return std::set - a set of enumeration items - * describing the cell types. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \sa getAllGeoTypes() - */ -std::set MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const -{ - checkFullyDefined(); - std::set ret; - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - for(const int *w=begin;w!=end;w++) - ret.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]); - return ret; -} - -/*! - * Defines the nodal connectivity using given connectivity arrays in \ref numbering-indirect format. - * Optionally updates - * a set of types of cells constituting \a this mesh. - * This method is for advanced users having prepared their connectivity before. For - * more info on using this method see \ref MEDCouplingUMeshAdvBuild. - * \param [in] conn - the nodal connectivity array. - * \param [in] connIndex - the nodal connectivity index array. - * \param [in] isComputingTypes - if \c true, the set of types constituting \a this - * mesh is updated. - */ -void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes) -{ - DataArrayInt::SetArrayIn(conn,_nodal_connec); - DataArrayInt::SetArrayIn(connIndex,_nodal_connec_index); - if(isComputingTypes) - computeTypes(); - declareAsNew(); -} - -/*! - * Copy constructor. If 'deepCpy' is false \a this is a shallow copy of other. - * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied. - */ -MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim), - _nodal_connec(0),_nodal_connec_index(0), - _types(other._types) -{ - if(other._nodal_connec) - _nodal_connec=other._nodal_connec->performCpy(deepCopy); - if(other._nodal_connec_index) - _nodal_connec_index=other._nodal_connec_index->performCpy(deepCopy); -} - -MEDCouplingUMesh::~MEDCouplingUMesh() -{ - if(_nodal_connec) - _nodal_connec->decrRef(); - if(_nodal_connec_index) - _nodal_connec_index->decrRef(); -} - -/*! - * Recomputes a set of cell types of \a this mesh. For more info see - * \ref MEDCouplingUMeshNodalConnectivity. - */ -void MEDCouplingUMesh::computeTypes() -{ - ComputeAllTypesInternal(_types,_nodal_connec,_nodal_connec_index); -} - -/*! - * This method checks that all arrays are set. If yes nothing done if no an exception is thrown. - */ -void MEDCouplingUMesh::checkFullyDefined() const -{ - if(!_nodal_connec_index || !_nodal_connec || !_coords) - throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh."); -} - -/*! - * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown. - */ -void MEDCouplingUMesh::checkConnectivityFullyDefined() const -{ - if(!_nodal_connec_index || !_nodal_connec) - throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh."); -} - -/*! - * Returns a number of cells constituting \a this mesh. - * \return int - the number of cells in \a this mesh. - * \throw If the nodal connectivity of cells is not defined. - */ -int MEDCouplingUMesh::getNumberOfCells() const -{ - if(_nodal_connec_index) - return _nodal_connec_index->getNumberOfTuples()-1; - else - if(_mesh_dim==-1) - return 1; - else - throw INTERP_KERNEL::Exception("Unable to get number of cells because no connectivity specified !"); -} - -/*! - * Returns a dimension of \a this mesh, i.e. a dimension of cells constituting \a this - * mesh. For more info see \ref meshes. - * \return int - the dimension of \a this mesh. - * \throw If the mesh dimension is not defined using setMeshDimension(). - */ -int MEDCouplingUMesh::getMeshDimension() const -{ - if(_mesh_dim<-1) - throw INTERP_KERNEL::Exception("No mesh dimension specified !"); - return _mesh_dim; -} - -/*! - * Returns a length of the nodal connectivity array. - * This method is for test reason. Normally the integer returned is not useable by - * user. For more info see \ref MEDCouplingUMeshNodalConnectivity. - * \return int - the length of the nodal connectivity array. - */ -int MEDCouplingUMesh::getMeshLength() const -{ - return _nodal_connec->getNbOfElems(); -} - -/*! - * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process. - */ -void MEDCouplingUMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings); - tinyInfo.push_back(getMeshDimension()); - tinyInfo.push_back(getNumberOfCells()); - if(_nodal_connec) - tinyInfo.push_back(getMeshLength()); - else - tinyInfo.push_back(-1); -} - -/*! - * First step of unserialization process. - */ -bool MEDCouplingUMesh::isEmptyMesh(const std::vector& tinyInfo) const -{ - return tinyInfo[6]<=0; -} - -/*! - * Second step of serialization process. - * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. - * \param a1 - * \param a2 - * \param littleStrings - */ -void MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - MEDCouplingPointSet::resizeForUnserialization(tinyInfo,a1,a2,littleStrings); - if(tinyInfo[5]!=-1) - a1->alloc(tinyInfo[7]+tinyInfo[6]+1,1); -} - -/*! - * Third and final step of serialization process. - */ -void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - MEDCouplingPointSet::serialize(a1,a2); - if(getMeshDimension()>-1) - { - a1=DataArrayInt::New(); - a1->alloc(getMeshLength()+getNumberOfCells()+1,1); - int *ptA1=a1->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *index=getNodalConnectivityIndex()->getConstPointer(); - ptA1=std::copy(index,index+getNumberOfCells()+1,ptA1); - std::copy(conn,conn+getMeshLength(),ptA1); - } - else - a1=0; -} - -/*! - * Second and final unserialization process. - * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. - */ -void MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) -{ - MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfo,a1,a2,littleStrings); - setMeshDimension(tinyInfo[5]); - if(tinyInfo[7]!=-1) - { - // Connectivity - const int *recvBuffer=a1->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr myConnecIndex=DataArrayInt::New(); - myConnecIndex->alloc(tinyInfo[6]+1,1); - std::copy(recvBuffer,recvBuffer+tinyInfo[6]+1,myConnecIndex->getPointer()); - MEDCouplingAutoRefCountObjectPtr myConnec=DataArrayInt::New(); - myConnec->alloc(tinyInfo[7],1); - std::copy(recvBuffer+tinyInfo[6]+1,recvBuffer+tinyInfo[6]+1+tinyInfo[7],myConnec->getPointer()); - setConnectivity(myConnec, myConnecIndex); - } -} - -/*! - * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2. - * CellIds are given using range specified by a start an end and step. - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const -{ - checkFullyDefined(); - int ncell=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - ret->_mesh_dim=_mesh_dim; - ret->setCoords(_coords); - int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : "); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1); - int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0; - int work=start; - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - for(int i=0;i=0 && work newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1); - int *newConnPtr=newConn->getPointer(); - std::set types; - work=start; - for(int i=0;isetConnectivity(newConn,newConnI,false); - ret->_types=types; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf. - * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). - * The return newly allocated mesh will share the same coordinates as \a this. - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const -{ - checkConnectivityFullyDefined(); - int ncell=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - ret->_mesh_dim=_mesh_dim; - ret->setCoords(_coords); - std::size_t nbOfElemsRet=std::distance(begin,end); - int *connIndexRet=(int *)malloc((nbOfElemsRet+1)*sizeof(int)); - connIndexRet[0]=0; - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - int newNbring=0; - for(const int *work=begin;work!=end;work++,newNbring++) - { - if(*work>=0 && *work types; - for(const int *work=begin;work!=end;work++) - { - types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]); - connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork); - } - MEDCouplingAutoRefCountObjectPtr connRetArr=DataArrayInt::New(); - connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1); - MEDCouplingAutoRefCountObjectPtr connIndexRetArr=DataArrayInt::New(); - connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1); - ret->setConnectivity(connRetArr,connIndexRetArr,false); - ret->_types=types; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this - * mesh.
- * For 1D cells, the returned field contains lengths.
- * For 2D cells, the returned field contains areas.
- * For 3D cells, the returned field contains volumes. - * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell - * orientation, i.e. the volume is always positive. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells - * and one time . The caller is to delete this field using decrRef() as it is no - * more needed. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const -{ - std::string name="MeasureOfMesh_"; - name+=getName(); - int nbelem=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - field->setName(name); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - array->alloc(nbelem,1); - double *area_vol=array->getPointer(); - field->setArray(array) ; array=0; - field->setMesh(const_cast(this)); - field->synchronizeTimeWithMesh(); - if(getMeshDimension()!=-1) - { - int ipt; - INTERP_KERNEL::NormalizedCellType type; - int dim_space=getSpaceDimension(); - const double *coords=getCoords()->getConstPointer(); - const int *connec=getNodalConnectivity()->getConstPointer(); - const int *connec_index=getNodalConnectivityIndex()->getConstPointer(); - for(int iel=0;iel(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space); - } - if(isAbs) - std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun(fabs)); - } - else - { - area_vol[0]=std::numeric_limits::max(); - } - return field.retn(); -} - -/*! - * Returns a new DataArrayDouble containing volumes of specified cells of \a this - * mesh.
- * For 1D cells, the returned array contains lengths.
- * For 2D cells, the returned array contains areas.
- * For 3D cells, the returned array contains volumes. - * This method avoids building explicitly a part of \a this mesh to perform the work. - * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell - * orientation, i.e. the volume is always positive. - * \param [in] begin - an array of cell ids of interest. - * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. - * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to - * delete this array using decrRef() as it is no more needed. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getPartMeasureField "Here is a C++ example".
- * \ref py_mcumesh_getPartMeasureField "Here is a Python example". - * \endif - * \sa getMeasureField() - */ -DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const -{ - std::string name="PartMeasureOfMesh_"; - name+=getName(); - int nbelem=(int)std::distance(begin,end); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - array->setName(name); - array->alloc(nbelem,1); - double *area_vol=array->getPointer(); - if(getMeshDimension()!=-1) - { - int ipt; - INTERP_KERNEL::NormalizedCellType type; - int dim_space=getSpaceDimension(); - const double *coords=getCoords()->getConstPointer(); - const int *connec=getNodalConnectivity()->getConstPointer(); - const int *connec_index=getNodalConnectivityIndex()->getConstPointer(); - for(const int *iel=begin;iel!=end;iel++) - { - ipt=connec_index[*iel]; - type=(INTERP_KERNEL::NormalizedCellType)connec[ipt]; - *area_vol++=INTERP_KERNEL::computeVolSurfOfCell2(type,connec+ipt+1,connec_index[*iel+1]-ipt-1,coords,dim_space); - } - if(isAbs) - std::transform(array->getPointer(),area_vol,array->getPointer(),std::ptr_fun(fabs)); - } - else - { - area_vol[0]=std::numeric_limits::max(); - } - return array.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh of - * \a this one. The returned field contains the dual cell volume for each corresponding - * node in \a this mesh. In other words, the field returns the getMeasureField() of - * the dual mesh in P1 sens of \a this.
- * For 1D cells, the returned field contains lengths.
- * For 2D cells, the returned field contains areas.
- * For 3D cells, the returned field contains volumes. - * This method is useful to check "P1*" conservative interpolators. - * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell - * orientation, i.e. the volume is always positive. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * nodes and one time. The caller is to delete this array using decrRef() as - * it is no more needed. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const -{ - MEDCouplingAutoRefCountObjectPtr tmp=getMeasureField(isAbs); - std::string name="MeasureOnNodeOfMesh_"; - name+=getName(); - int nbNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_NODES); - double cst=1./((double)getMeshDimension()+1.); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - array->alloc(nbNodes,1); - double *valsToFill=array->getPointer(); - std::fill(valsToFill,valsToFill+nbNodes,0.); - const double *values=tmp->getArray()->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr da=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr daInd=DataArrayInt::New(); - getReverseNodalConnectivity(da,daInd); - const int *daPtr=da->getConstPointer(); - const int *daIPtr=daInd->getConstPointer(); - for(int i=0;isetMesh(this); - ret->setArray(array); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding normal vectors to cells of \a this - * mesh. The returned normal vectors to each cell have a norm2 equal to 1. - * The computed vectors have this->getMeshDimension()+1 components - * and are normalized. - *
\a this can be either - * - a 2D mesh in 2D or 3D space or - * - an 1D mesh in 2D space. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time. The caller is to delete this field using decrRef() as - * it is no more needed. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If the mesh dimension is not set. - * \throw If the mesh and space dimension is not as specified above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const -{ - if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) - throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - int nbComp=getMeshDimension()+1; - array->alloc(nbOfCells,nbComp); - double *vals=array->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const double *coords=_coords->getConstPointer(); - if(getMeshDimension()==2) - { - if(getSpaceDimension()==3) - { - MEDCouplingAutoRefCountObjectPtr loc=getBarycenterAndOwner(); - const double *locPtr=loc->getConstPointer(); - for(int i=0;i(locPtr+3*i,coords+3*conn[offset+1],coords+3*conn[offset+2],vals); - double n=INTERP_KERNEL::norm<3>(vals); - std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies(),1./n)); - } - } - else - { - MEDCouplingAutoRefCountObjectPtr isAbs=getMeasureField(false); - const double *isAbsPtr=isAbs->getArray()->begin(); - for(int i=0;i0.?1.:-1.; } - } - } - else//meshdimension==1 - { - double tmp[2]; - for(int i=0;i()); - double n=INTERP_KERNEL::norm<2>(tmp); - std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies(),1./n)); - *vals++=-tmp[1]; - *vals++=tmp[0]; - } - } - ret->setArray(array); - ret->setMesh(this); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding normal vectors to specified cells of - * \a this mesh. The computed vectors have this->getMeshDimension()+1 components - * and are normalized. - *
\a this can be either - * - a 2D mesh in 2D or 3D space or - * - an 1D mesh in 2D space. - * - * This method avoids building explicitly a part of \a this mesh to perform the work. - * \param [in] begin - an array of cell ids of interest. - * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time. The caller is to delete this field using decrRef() as - * it is no more needed. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If the mesh dimension is not set. - * \throw If the mesh and space dimension is not as specified above. - * \sa buildOrthogonalField() - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildPartOrthogonalField "Here is a C++ example".
- * \ref py_mcumesh_buildPartOrthogonalField "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const -{ - if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) - throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - std::size_t nbelems=std::distance(begin,end); - int nbComp=getMeshDimension()+1; - array->alloc((int)nbelems,nbComp); - double *vals=array->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const double *coords=_coords->getConstPointer(); - if(getMeshDimension()==2) - { - if(getSpaceDimension()==3) - { - MEDCouplingAutoRefCountObjectPtr loc=getPartBarycenterAndOwner(begin,end); - const double *locPtr=loc->getConstPointer(); - for(const int *i=begin;i!=end;i++,vals+=3,locPtr+=3) - { - int offset=connI[*i]; - INTERP_KERNEL::crossprod<3>(locPtr,coords+3*conn[offset+1],coords+3*conn[offset+2],vals); - double n=INTERP_KERNEL::norm<3>(vals); - std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies(),1./n)); - } - } - else - { - for(std::size_t i=0;i()); - double n=INTERP_KERNEL::norm<2>(tmp); - std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies(),1./n)); - *vals++=-tmp[1]; - *vals++=tmp[0]; - } - } - ret->setArray(array); - ret->setMesh(this); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding a direction vector for each SEG2 in \a - * this 1D mesh. The computed vectors have this->getSpaceDimension() components - * and are \b not normalized. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time. The caller is to delete this field using decrRef() as - * it is no more needed. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If \a this->getMeshDimension() != 1. - * \throw If \a this mesh includes cells of type other than SEG2. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const -{ - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !"); - if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) - throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - int spaceDim=getSpaceDimension(); - array->alloc(nbOfCells,spaceDim); - double *pt=array->getPointer(); - const double *coo=getCoords()->getConstPointer(); - std::vector conn; - conn.reserve(2); - for(int i=0;i()); - } - ret->setArray(array); - ret->setMesh(this); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a 2D mesh by cutting \a this 3D mesh with a plane. In addition to the mesh, - * returns a new DataArrayInt, of length equal to the number of 2D cells in the result - * mesh, holding, for each cell in the result mesh, an id of a 3D cell it comes - * from. If a result face is shared by two 3D cells, then the face in included twice in - * the result mesh. - * \param [in] origin - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude - * must be greater than 1e-6. - * \param [in] eps - half-thickness of the plane. - * \param [out] cellIds - a new instance of DataArrayInt holding ids of 3D cells - * producing correspondent 2D cells. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This mesh does - * not share the node coordinates array with \a this mesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 3 or \a this->getSpaceDimension() != 3. - * \throw If magnitude of \a vec is less than 1e-6. - * \throw If the plane does not intersect any 3D cell of \a this mesh. - * \throw If \a this includes quadratic cells. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); - MEDCouplingAutoRefCountObjectPtr candidates=getCellIdsCrossingPlane(origin,vec,eps); - if(candidates->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !"); - std::vector nodes; - DataArrayInt *cellIds1D=0; - MEDCouplingAutoRefCountObjectPtr subMesh=static_cast(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); - subMesh->findNodesOnPlane(origin,vec,eps,nodes); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(),desc2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(),descIndx2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(),revDesc2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3 - revDesc2=0; revDescIndx2=0; - MEDCouplingAutoRefCountObjectPtr mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 - revDesc1=0; revDescIndx1=0; - mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); - MEDCouplingAutoRefCountObjectPtr cellIds1DTmp(cellIds1D); - // - std::vector cut3DCurve(mDesc1->getNumberOfCells(),-2); - for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) - cut3DCurve[*it]=-1; - mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); - std::vector< std::pair > cut3DSurf(mDesc2->getNumberOfCells()); - AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(), - mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), - desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); - connI->pushBackSilent(0); conn->alloc(0,1); cellIds2->alloc(0,1); - subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2); - if(cellIds2->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Slice3D",2); - ret->setCoords(mDesc1->getCoords()); - ret->setConnectivity(conn,connI,true); - cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); - return ret.retn(); -} - -/*! - * Creates an 1D mesh by cutting \a this 2D mesh in 3D space with a plane. In -addition to the mesh, returns a new DataArrayInt, of length equal to the number of 1D cells in the result mesh, holding, for each cell in the result mesh, an id of a 2D cell it comes -from. If a result segment is shared by two 2D cells, then the segment in included twice in -the result mesh. - * \param [in] origin - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude - * must be greater than 1e-6. - * \param [in] eps - half-thickness of the plane. - * \param [out] cellIds - a new instance of DataArrayInt holding ids of faces - * producing correspondent segments. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This is an 1D - * mesh in 3D space. This mesh does not share the node coordinates array with - * \a this mesh. The caller is to delete this mesh using decrRef() as it is - * no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 2 or \a this->getSpaceDimension() != 3. - * \throw If magnitude of \a vec is less than 1e-6. - * \throw If the plane does not intersect any 2D cell of \a this mesh. - * \throw If \a this includes quadratic cells. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const -{ - checkFullyDefined(); - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !"); - MEDCouplingAutoRefCountObjectPtr candidates=getCellIdsCrossingPlane(origin,vec,eps); - if(candidates->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !"); - std::vector nodes; - DataArrayInt *cellIds1D=0; - MEDCouplingAutoRefCountObjectPtr subMesh=static_cast(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); - subMesh->findNodesOnPlane(origin,vec,eps,nodes); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 - mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); - MEDCouplingAutoRefCountObjectPtr cellIds1DTmp(cellIds1D); - // - std::vector cut3DCurve(mDesc1->getNumberOfCells(),-2); - for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) - cut3DCurve[*it]=-1; - mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); - int ncellsSub=subMesh->getNumberOfCells(); - std::vector< std::pair > cut3DSurf(ncellsSub); - AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(), - mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), - desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); connI->pushBackSilent(0); - conn->alloc(0,1); - const int *nodal=subMesh->getNodalConnectivity()->getConstPointer(); - const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;ipushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(cut3DSurf[i].first); conn->pushBackSilent(cut3DSurf[i].second); - connI->pushBackSilent(conn->getNumberOfTuples()); - cellIds2->pushBackSilent(i); - } - else - { - int cellId3DSurf=cut3DSurf[i].second; - int offset=nodalI[cellId3DSurf]+1; - int nbOfEdges=nodalI[cellId3DSurf+1]-offset; - for(int j=0;jpushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(nodal[offset+j]); conn->pushBackSilent(nodal[offset+(j+1)%nbOfEdges]); - connI->pushBackSilent(conn->getNumberOfTuples()); - cellIds2->pushBackSilent(cellId3DSurf); - } - } - } - } - if(cellIds2->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Slice3DSurf",1); - ret->setCoords(mDesc1->getCoords()); - ret->setConnectivity(conn,connI,true); - cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); - return ret.retn(); -} - -/*! - * Finds cells whose bounding boxes intersect a given plane. - * \param [in] origin - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude - * must be greater than 1e-6. - * \param [in] eps - half-thickness of the plane. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of the found - * cells. The caller is to delete this array using decrRef() as it is no more - * needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If magnitude of \a vec is less than 1e-6. - * \sa buildSlice3D() - */ -DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const -{ - checkFullyDefined(); - if(getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with spaceDim equal to 3 !"); - double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); - if(normm<1e-6) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellIdsCrossingPlane : parameter 'vec' should have a norm2 greater than 1e-6 !"); - double vec2[3]; - vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1) - double angle=acos(vec[2]/normm); - MEDCouplingAutoRefCountObjectPtr cellIds; - double bbox[6]; - if(angle>eps) - { - MEDCouplingAutoRefCountObjectPtr coo=_coords->deepCpy(); - double normm2(sqrt(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2])); - if(normm2/normm>1e-6) - MEDCouplingPointSet::Rotate3DAlg(origin,vec2,angle,coo->getNumberOfTuples(),coo->getPointer()); - MEDCouplingAutoRefCountObjectPtr mw=clone(false);//false -> shallow copy - mw->setCoords(coo); - mw->getBoundingBox(bbox); - bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; - cellIds=mw->getCellsInBoundingBox(bbox,eps); - } - else - { - getBoundingBox(bbox); - bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; - cellIds=getCellsInBoundingBox(bbox,eps); - } - return cellIds.retn(); -} - -/*! - * This method checks that \a this is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1. - * If not an exception will thrown. If this is an empty mesh with no cell an exception will be thrown too. - * No consideration of coordinate is done by this method. - * A 1D mesh is said contiguous if : a cell i with nodal connectivity (k,p) the cell i+1 the nodal connectivity should be (p,m) - * If not false is returned. In case that false is returned a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes could be usefull. - */ -bool MEDCouplingUMesh::isContiguous1D() const -{ - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense only for 1D mesh !"); - int nbCells=getNumberOfCells(); - if(nbCells<1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense for non empty mesh !"); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - int ref=conn[connI[0]+2]; - for(int i=1;igetNumberOfCells - */ -void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const -{ - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for project1D !"); - if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) - throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for project1D !"); - if(getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !"); - MEDCouplingAutoRefCountObjectPtr f=buildDirectionVectorField(); - const double *fPtr=f->getArray()->getConstPointer(); - double tmp[3]; - for(int i=0;i(tmp); - n1/=INTERP_KERNEL::norm<3>(tmp1); - if(n1>eps) - throw INTERP_KERNEL::Exception("UMesh::Projection 1D failed !"); - } - const double *coo=getCoords()->getConstPointer(); - for(int i=0;i()); - std::transform(tmp,tmp+3,v,tmp,std::multiplies()); - res[i]=std::accumulate(tmp,tmp+3,0.); - } -} - -/*! - * This method computes the distance from a point \a pt to \a this and the first \a cellId in \a this corresponding to the returned distance. - * \a this is expected to be a mesh so that its space dimension is equal to its - * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. - * Distance from \a ptBg to \a ptEnd is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). - * - * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken - * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance). - * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this. - * - * So this method is more accurate (so, more costly) than simply searching for the closest point in \a this. - * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. - * - * \param [in] ptBg the start pointer (included) of the coordinates of the point - * \param [in] ptEnd the end pointer (not included) of the coordinates of the point - * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. - * \return the positive value of the distance. - * \throw if distance from \a ptBg to \a ptEnd is not equal to the space dimension. An exception is also thrown if mesh dimension of \a this is not equal to space - * dimension - 1. - * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoints - */ -double MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const -{ - int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); - if(meshDim!=spaceDim-1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint works only for spaceDim=meshDim+1 !"); - if(meshDim!=2 && meshDim!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !"); - checkFullyDefined(); - if((int)std::distance(ptBg,ptEnd)!=spaceDim) - { std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoint : input point has to have dimension equal to the space dimension of this (" << spaceDim << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - DataArrayInt *ret1=0; - MEDCouplingAutoRefCountObjectPtr pts=DataArrayDouble::New(); pts->useArray(ptBg,false,C_DEALLOC,1,spaceDim); - MEDCouplingAutoRefCountObjectPtr ret0=distanceToPoints(pts,ret1); - MEDCouplingAutoRefCountObjectPtr ret1Safe(ret1); - cellId=*ret1Safe->begin(); - return *ret0->begin(); -} - -/*! - * This method computes the distance from each point of points serie \a pts (stored in a DataArrayDouble in which each tuple represents a point) - * to \a this and the first \a cellId in \a this corresponding to the returned distance. - * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken - * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance). - * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this. - * - * \a this is expected to be a mesh so that its space dimension is equal to its - * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. - * Number of components of \a pts is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). - * - * So this method is more accurate (so, more costly) than simply searching for each point in \a pts the closest point in \a this. - * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. - * - * \param [in] pts the list of points in which each tuple represents a point - * \param [out] cellIds a newly allocated object that tells for each point in \a pts the first cell id in \a this that minimizes the distance. - * \return a newly allocated object to be dealed by the caller that tells for each point in \a pts the distance to \a this. - * \throw if number of components of \a pts is not equal to the space dimension. - * \throw if mesh dimension of \a this is not equal to space dimension - 1. - * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoint - */ -DataArrayDouble *MEDCouplingUMesh::distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const -{ - if(!pts) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : input points pointer is NULL !"); - pts->checkAllocated(); - int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); - if(meshDim!=spaceDim-1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints works only for spaceDim=meshDim+1 !"); - if(meshDim!=2 && meshDim!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only mesh dimension 2 and 1 are implemented !"); - if(pts->getNumberOfComponents()!=spaceDim) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoints : input pts DataArrayDouble has " << pts->getNumberOfComponents() << " components whereas it should be equal to " << spaceDim << " (mesh spaceDimension) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - checkFullyDefined(); - int nbCells=getNumberOfCells(); - if(nbCells==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : no cells in this !"); - int nbOfPts=pts->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret0=DataArrayDouble::New(); ret0->alloc(nbOfPts,1); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc(nbOfPts,1); - const int *nc=_nodal_connec->begin(),*ncI=_nodal_connec_index->begin(); const double *coords=_coords->begin(); - double *ret0Ptr=ret0->getPointer(); int *ret1Ptr=ret1->getPointer(); const double *ptsPtr=pts->begin(); - MEDCouplingAutoRefCountObjectPtr bboxArr(getBoundingBoxForBBTree()); - const double *bbox(bboxArr->begin()); - switch(spaceDim) - { - case 3: - { - BBTreeDst<3> myTree(bbox,0,0,nbCells); - for(int i=0;i::max(); - std::vector elems; - myTree.getMinDistanceOfMax(ptsPtr,x); - myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems); - DistanceToPoint3DSurfAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr); - } - break; - } - case 2: - { - BBTreeDst<2> myTree(bbox,0,0,nbCells); - for(int i=0;i::max(); - std::vector elems; - myTree.getMinDistanceOfMax(ptsPtr,x); - myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems); - DistanceToPoint2DCurveAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only spacedim 2 and 3 supported !"); - } - cellIds=ret1.retn(); - return ret0.retn(); -} - -/// @cond INTERNAL - -/*! - * \param [in] pt the start pointer (included) of the coordinates of the point - * \param [in] cellIdsBg the start pointer (included) of cellIds - * \param [in] cellIdsEnd the end pointer (excluded) of cellIds - * \param [in] nc nodal connectivity - * \param [in] ncI nodal connectivity index - * \param [in,out] ret0 the min distance between \a this and the external input point - * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. - * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints - */ -void MEDCouplingUMesh::DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId) -{ - cellId=-1; - ret0=std::numeric_limits::max(); - for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++) - { - switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]]) - { - case INTERP_KERNEL::NORM_TRI3: - { - double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*nc[ncI[*zeCell]+1],coords+3*nc[ncI[*zeCell]+2],coords+3*nc[ncI[*zeCell]+3]); - if(tmp::max(); - for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++) - { - switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]]) - { - case INTERP_KERNEL::NORM_SEG2: - { - std::size_t uselessEntry=0; - double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*nc[ncI[*zeCell]+1],coords+2*nc[ncI[*zeCell]+2],uselessEntry); - tmp=sqrt(tmp); - if(tmpgetMeshDimension() != \a this->getSpaceDimension(). - */ -int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const -{ - std::vector elts; - getCellsContainingPoint(pos,eps,elts); - if(elts.empty()) - return -1; - return elts.front(); -} - -/*! - * Finds cells in contact with a ball (i.e. a point with precision). - * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. - * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. - * \warning This method is suitable if the caller intends to evaluate only one - * point, for more points getCellsContainingPoints() is recommended as it is - * faster. - * \param [in] pos - array of coordinates of the ball central point. - * \param [in] eps - ball radius. - * \param [out] elts - vector returning ids of the found cells. It is cleared - * before inserting ids. - * \throw If the coordinates array is not set. - * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const -{ - MEDCouplingAutoRefCountObjectPtr eltsUg,eltsIndexUg; - getCellsContainingPoints(pos,1,eps,eltsUg,eltsIndexUg); - elts.clear(); elts.insert(elts.end(),eltsUg->begin(),eltsUg->end()); -} - -/// @cond INTERNAL - -namespace ParaMEDMEM -{ - template - class DummyClsMCUG - { - public: - static const int MY_SPACEDIM=SPACEDIMM; - static const int MY_MESHDIM=8; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; - // begin - // useless, but for windows compilation ... - const double* getCoordinatesPtr() const { return 0; } - const int* getConnectivityPtr() const { return 0; } - const int* getConnectivityIndexPtr() const { return 0; } - INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; } - // end - }; - - INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map< MEDCouplingAutoRefCountObjectPtr,int>& m) - { - INTERP_KERNEL::Edge *ret(0); - MEDCouplingAutoRefCountObjectPtr n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1])); - m[n0]=bg[0]; m[n1]=bg[1]; - switch(typ) - { - case INTERP_KERNEL::NORM_SEG2: - { - ret=new INTERP_KERNEL::EdgeLin(n0,n1); - break; - } - case INTERP_KERNEL::NORM_SEG3: - { - INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2]; - INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1)); - INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); - // is the SEG3 degenerated, and thus can be reduced to a SEG2? - bool colinearity(inters.areColinears()); - delete e1; delete e2; - if(colinearity) - { ret=new INTERP_KERNEL::EdgeLin(n0,n1); } - else - { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !"); - } - return ret; - } - - INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map >& mapp2, const int *bg) - { - INTERP_KERNEL::Edge *ret=0; - switch(typ) - { - case INTERP_KERNEL::NORM_SEG2: - { - ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first); - break; - } - case INTERP_KERNEL::NORM_SEG3: - { - INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first); - INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first); - INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); - // is the SEG3 degenerated, and thus can be reduced to a SEG2? - bool colinearity=inters.areColinears(); - delete e1; delete e2; - if(colinearity) - ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first); - else - ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first); - mapp2[bg[2]].second=false; - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !"); - } - return ret; - } - - /*! - * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed by the sub set of cells in 'candidates' taken from - * the global mesh 'mDesc'. - * The input mesh 'mDesc' must be so that mDim==1 and spaceDim==2. - * 'mapp' returns a mapping between local numbering in submesh (represented by a Node*) and the global node numbering in 'mDesc'. - */ - INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector& candidates, - std::map& mapp) - { - mapp.clear(); - std::map > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3. - const double *coo=mDesc->getCoords()->getConstPointer(); - const int *c=mDesc->getNodalConnectivity()->getConstPointer(); - const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer(); - std::set s; - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - s.insert(c+cI[*it]+1,c+cI[(*it)+1]); - for(std::set::const_iterator it2=s.begin();it2!=s.end();it2++) - { - INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]); - mapp2[*it2]=std::pair(n,true); - } - INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon; - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - { - INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]]; - ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1)); - } - for(std::map >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++) - { - if((*it2).second.second) - mapp[(*it2).second.first]=(*it2).first; - ((*it2).second.first)->decrRef(); - } - return ret; - } - - INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector& addCoo) - { - if(nodeId>=offset2) - { - int locId=nodeId-offset2; - return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]); - } - if(nodeId>=offset1) - { - int locId=nodeId-offset1; - return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]); - } - return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]); - } - - /** - * Construct a mapping between set of Nodes and the standart MEDCoupling connectivity format (c, cI). - */ - void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector& addCoo, - const int *desc1Bg, const int *desc1End, const std::vector >& intesctEdges1, - /*output*/std::map& mapp, std::map& mappRev) - { - for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++) - { - int eltId1=abs(*desc1)-1; - for(std::vector::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++) - { - std::map::const_iterator it=mappRev.find(*it1); - if(it==mappRev.end()) - { - INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo); - mapp[node]=*it1; - mappRev[*it1]=node; - } - } - } - } -} - -/// @endcond - -template -void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, - double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const -{ - elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1); - int *eltsIndexPtr(eltsIndex->getPointer()); - MEDCouplingAutoRefCountObjectPtr bboxArr(getBoundingBoxForBBTree(eps)); - const double *bbox(bboxArr->begin()); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - double bb[2*SPACEDIM]; - BBTree myTree(&bbox[0],0,0,nbOfCells,-eps); - for(int i=0;i candidates; - myTree.getIntersectingElems(bb,candidates); - for(std::vector::const_iterator iter=candidates.begin();iter!=candidates.end();iter++) - { - int sz(connI[(*iter)+1]-connI[*iter]-1); - INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]]); - bool status(false); - if(ct!=INTERP_KERNEL::NORM_POLYGON && ct!=INTERP_KERNEL::NORM_QPOLYG) - status=INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos+i*SPACEDIM,ct,coords,conn+connI[*iter]+1,sz,eps); - else - { - if(SPACEDIM!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPointsAlg : not implemented yet for POLYGON and QPOLYGON in spaceDim 3 !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - std::vector nodes(sz); - INTERP_KERNEL::QuadraticPolygon *pol(0); - for(int j=0;jnormalizeMe(b,c); n->applySimilarity(b,c,a); - status=pol->isInOrOut2(n); - delete pol; n->decrRef(); - } - if(status) - { - eltsIndexPtr[i+1]++; - elts->pushBackSilent(*iter); - } - } - } -} -/*! - * Finds cells in contact with several balls (i.e. points with precision). - * This method is an extension of getCellContainingPoint() and - * getCellsContainingPoint() for the case of multiple points. - * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. - * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. - * \param [in] pos - an array of coordinates of points in full interlace mode : - * X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a - * this->getSpaceDimension() * \a nbOfPoints - * \param [in] nbOfPoints - number of points to locate within \a this mesh. - * \param [in] eps - radius of balls (i.e. the precision). - * \param [out] elts - vector returning ids of found cells. - * \param [out] eltsIndex - an array, of length \a nbOfPoints + 1, - * dividing cell ids in \a elts into groups each referring to one - * point. Its every element (except the last one) is an index pointing to the - * first id of a group of cells. For example cells in contact with the *i*-th - * point are described by following range of indices: - * [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are - * \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ... - * Number of cells in contact with the *i*-th point is - * \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ]. - * \throw If the coordinates array is not set. - * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, - MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const -{ - int spaceDim=getSpaceDimension(); - int mDim=getMeshDimension(); - if(spaceDim==3) - { - if(mDim==3) - { - const double *coords=_coords->getConstPointer(); - getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex); - } - /*else if(mDim==2) - { - - }*/ - else - throw INTERP_KERNEL::Exception("For spaceDim==3 only meshDim==3 implemented for getelementscontainingpoints !"); - } - else if(spaceDim==2) - { - if(mDim==2) - { - const double *coords=_coords->getConstPointer(); - getCellsContainingPointsAlg<2>(coords,pos,nbOfPoints,eps,elts,eltsIndex); - } - else - throw INTERP_KERNEL::Exception("For spaceDim==2 only meshDim==2 implemented for getelementscontainingpoints !"); - } - else if(spaceDim==1) - { - if(mDim==1) - { - const double *coords=_coords->getConstPointer(); - getCellsContainingPointsAlg<1>(coords,pos,nbOfPoints,eps,elts,eltsIndex); - } - else - throw INTERP_KERNEL::Exception("For spaceDim==1 only meshDim==1 implemented for getelementscontainingpoints !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPoints : not managed for mdim not in [1,2,3] !"); -} - -/*! - * Finds butterfly cells in \a this mesh. A 2D cell is considered to be butterfly if at - * least two its edges intersect each other anywhere except their extremities. An - * INTERP_KERNEL::NORM_NORI3 cell can \b not be butterfly. - * \param [in,out] cells - a vector returning ids of the found cells. It is not - * cleared before filling in. - * \param [in] eps - precision. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 2 && \a this->getSpaceDimension() != 3. - */ -void MEDCouplingUMesh::checkButterflyCells(std::vector& cells, double eps) const -{ - const char msg[]="Butterfly detection work only for 2D cells with spaceDim==2 or 3!"; - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception(msg); - int spaceDim=getSpaceDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception(msg); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector cell2DinS2; - for(int i=0;igetConstPointer(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr nodalConnecIndexOut=DataArrayInt::New(); - nodalConnecIndexOut->alloc(nbOfCells+1,1); - MEDCouplingAutoRefCountObjectPtr nodalConnecOut(DataArrayInt::New()); - int *workIndexOut=nodalConnecIndexOut->getPointer(); - *workIndexOut=0; - const int *nodalConnecIn=_nodal_connec->getConstPointer(); - const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer(); - std::set types; - MEDCouplingAutoRefCountObjectPtr isChanged(DataArrayInt::New()); - isChanged->alloc(0,1); - for(int i=0;igetNumberOfTuples(); - if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut)) - isChanged->pushBackSilent(i); - types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut->getIJ(pos,0)); - workIndexOut[1]=nodalConnecOut->getNumberOfTuples(); - } - if(isChanged->empty()) - return 0; - setConnectivity(nodalConnecOut,nodalConnecIndexOut,false); - _types=types; - return isChanged.retn(); -} - -/*! - * This method is \b NOT const because it can modify \a this. - * \a this is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. - * \param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. - * \param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), - * \b 1 for translation and rotation around point of 'mesh1D'. - * \return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than \a this. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) -{ - checkFullyDefined(); - mesh1D->checkFullyDefined(); - if(!mesh1D->isContiguous1D()) - throw INTERP_KERNEL::Exception("buildExtrudedMesh : 1D mesh passed in parameter is not contiguous !"); - if(getSpaceDimension()!=mesh1D->getSpaceDimension()) - throw INTERP_KERNEL::Exception("Invalid call to buildExtrudedMesh this and mesh1D must have same space dimension !"); - if((getMeshDimension()!=2 || getSpaceDimension()!=3) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) - throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMesh method : must be (meshDim==2 and spaceDim==3) or (meshDim==1 and spaceDim==2) !"); - if(mesh1D->getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMesh method : must be meshDim==1 !"); - bool isQuad=false; - if(isPresenceOfQuadratic()) - { - if(mesh1D->isFullyQuadratic()) - isQuad=true; - else - throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !"); - } - int oldNbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr newCoords; - switch(policy) - { - case 0: - { - newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad); - break; - } - case 1: - { - newCoords=fillExtCoordsUsingTranslAndAutoRotation(mesh1D,isQuad); - break; - } - default: - throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !"); - } - setCoords(newCoords); - MEDCouplingAutoRefCountObjectPtr ret(buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad)); - updateTime(); - return ret.retn(); -} - -/*! - * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3). - * If it is not the case an exception will be thrown. - * This method is non const because the coordinate of \a this can be appended with some new points issued from - * intersection of plane defined by ('origin','vec'). - * This method has one in/out parameter : 'cut3DCurve'. - * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()') - * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously. - * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec'). - * This method will throw an exception if \a this contains a non linear segment. - */ -void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve) -{ - checkFullyDefined(); - if(getMeshDimension()!=1 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !"); - int ncells=getNumberOfCells(); - int nnodes=getNumberOfNodes(); - double vec2[3],vec3[3],vec4[3]; - double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); - if(normm<1e-6) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !"); - vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm; - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - std::vector addCoo; - for(int i=0;ieps)//if colin<=eps -> current SEG2 is colinear to the input plane - { - const double *st2=coo+3*st; - vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2]; - double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])); - if(pos>eps && pos<1-eps) - { - int nNode=((int)addCoo.size())/3; - vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2]; - addCoo.insert(addCoo.end(),vec4,vec4+3); - cut3DCurve[i]=nnodes+nNode; - } - } - } - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !"); - } - if(!addCoo.empty()) - { - int newNbOfNodes=nnodes+((int)addCoo.size())/3; - MEDCouplingAutoRefCountObjectPtr coo2=DataArrayDouble::New(); - coo2->alloc(newNbOfNodes,3); - double *tmp=coo2->getPointer(); - tmp=std::copy(_coords->begin(),_coords->end(),tmp); - std::copy(addCoo.begin(),addCoo.end(),tmp); - DataArrayDouble::SetArrayIn(coo2,_coords); - } -} - -/*! - * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - int oldNbOfNodes=getNumberOfNodes(); - int nbOf1DCells=mesh1D->getNumberOfCells(); - int spaceDim=getSpaceDimension(); - DataArrayDouble *ret=DataArrayDouble::New(); - std::vector isQuads; - int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1; - ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim); - double *retPtr=ret->getPointer(); - const double *coords=getCoords()->getConstPointer(); - double *work=std::copy(coords,coords+spaceDim*oldNbOfNodes,retPtr); - std::vector v; - std::vector c; - double vec[3]; - v.reserve(3); - c.reserve(6); - for(int i=0;igetNodeIdsOfCell(i,v); - c.resize(0); - mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c); - mesh1D->getCoordinatesOfNode(v[0],c); - std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus()); - for(int j=0;j()); - if(isQuad) - { - c.resize(0); - mesh1D->getCoordinatesOfNode(v[1],c); - mesh1D->getCoordinatesOfNode(v[0],c); - std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus()); - for(int j=0;j()); - } - } - ret->copyStringInfoFrom(*getCoords()); - return ret; -} - -/*! - * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - if(mesh1D->getSpaceDimension()==2) - return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad); - if(mesh1D->getSpaceDimension()==3) - return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad); - throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !"); -} - -/*! - * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - if(isQuad) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !"); - int oldNbOfNodes=getNumberOfNodes(); - int nbOf1DCells=mesh1D->getNumberOfCells(); - if(nbOf1DCells<2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbOfLevsInVec=nbOf1DCells+1; - ret->alloc(oldNbOfNodes*nbOfLevsInVec,2); - double *retPtr=ret->getPointer(); - retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr); - MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr tmp2=getCoords()->deepCpy(); - tmp->setCoords(tmp2); - const double *coo1D=mesh1D->getCoords()->getConstPointer(); - const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer(); - const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer(); - for(int i=1;itranslate(vec); - double tmp3[2],radius,alpha,alpha0; - const double *p0=i+1rotate(end,0,angle); - retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr); - } - return ret.retn(); -} - -/*! - * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - if(isQuad) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !"); - int oldNbOfNodes=getNumberOfNodes(); - int nbOf1DCells=mesh1D->getNumberOfCells(); - if(nbOf1DCells<2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbOfLevsInVec=nbOf1DCells+1; - ret->alloc(oldNbOfNodes*nbOfLevsInVec,3); - double *retPtr=ret->getPointer(); - retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr); - MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr tmp2=getCoords()->deepCpy(); - tmp->setCoords(tmp2); - const double *coo1D=mesh1D->getCoords()->getConstPointer(); - const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer(); - const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer(); - for(int i=1;itranslate(vec); - double tmp3[2],radius,alpha,alpha0; - const double *p0=i+11.e-7) - { - vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm; - double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]); - double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2}; - double s2=norm2; - double c2=cos(asin(s2)); - double m[3][3]={ - {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2}, - {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2}, - {-vec2[1]*s2, vec2[0]*s2, c2} - }; - double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]}; - double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]}; - double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]}; - INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0); - double cosangle=i+1rotate(end,vecPlane,angle); - } - retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr); - } - return ret.retn(); -} - -/*! - * This method is private because not easy to use for end user. This method is const contrary to - * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain - * the coords sorted slice by slice. - * \param isQuad specifies presence of quadratic cells. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const -{ - int nbOf1DCells(getNumberOfNodes()/nbOfNodesOf1Lev-1); - int nbOf2DCells(getNumberOfCells()); - int nbOf3DCells(nbOf2DCells*nbOf1DCells); - MEDCouplingUMesh *ret(MEDCouplingUMesh::New("Extruded",getMeshDimension()+1)); - const int *conn(_nodal_connec->begin()),*connI(_nodal_connec_index->begin()); - MEDCouplingAutoRefCountObjectPtr newConn(DataArrayInt::New()),newConnI(DataArrayInt::New()); - newConnI->alloc(nbOf3DCells+1,1); - int *newConnIPtr(newConnI->getPointer()); - *newConnIPtr++=0; - std::vector newc; - for(int j=0;jalloc((int)(newc.size())*nbOf1DCells,1); - int *newConnPtr(newConn->getPointer()); - int deltaPerLev(isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev); - newConnIPtr=newConnI->getPointer(); - for(int iz=0;iz(),newConnIPtr[iz*nbOf2DCells])); - const int *posOfTypeOfCell(newConnIPtr); - for(std::vector::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++) - { - int icell((int)(iter-newc.begin()));//std::distance unfortunately cannot been called here in C++98 - if(icell!=*posOfTypeOfCell) - { - if(*iter!=-1) - *newConnPtr=(*iter)+iz*deltaPerLev; - else - *newConnPtr=-1; - } - else - { - *newConnPtr=*iter; - posOfTypeOfCell++; - } - } - } - ret->setConnectivity(newConn,newConnI,true); - ret->setCoords(getCoords()); - return ret; -} - -/*! - * Checks if \a this mesh is constituted by only quadratic cells. - * \return bool - \c true if there are only quadratic cells in \a this mesh. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - */ -bool MEDCouplingUMesh::isFullyQuadratic() const -{ - checkFullyDefined(); - bool ret=true; - int nbOfCells=getNumberOfCells(); - for(int i=0;igetConstPointer(); - for(int i=0;i newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - const int *icptr=_nodal_connec->getConstPointer(); - newConn->alloc(getMeshLength()-delta,1); - newConnI->alloc(nbOfCells+1,1); - int *ocptr=newConn->getPointer(); - int *ociptr=newConnI->getPointer(); - *ociptr=0; - _types.clear(); - for(int i=0;i types; - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret,connSafe,connISafe; - MEDCouplingAutoRefCountObjectPtr coordsSafe; - int meshDim=getMeshDimension(); - switch(conversionType) - { - case 0: - switch(meshDim) - { - case 1: - ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 2: - ret=convertLinearCellsToQuadratic2D0(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 3: - ret=convertLinearCellsToQuadratic3D0(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 0 mesh dimensions available are [1,2,3] !"); - } - break; - case 1: - { - switch(meshDim) - { - case 1: - ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types);//it is not a bug. In 1D policy 0 and 1 are equals - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 2: - ret=convertLinearCellsToQuadratic2D1(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 3: - ret=convertLinearCellsToQuadratic3D1(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 1 mesh dimensions available are [1,2,3] !"); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion type available are 0 (default, the simplest) and 1 (the most complex) !"); - } - setConnectivity(connSafe,connISafe,false); - _types=types; - setCoords(coordsSafe); - return ret.retn(); -} - -#if 0 -/*! - * This method only works if \a this has spaceDimension equal to 2 and meshDimension also equal to 2. - * This method allows to modify connectivity of cells in \a this that shares some edges in \a edgeIdsToBeSplit. - * The nodes to be added in those 2D cells are defined by the pair of \a nodeIdsToAdd and \a nodeIdsIndexToAdd. - * Length of \a nodeIdsIndexToAdd is expected to equal to length of \a edgeIdsToBeSplit + 1. - * The node ids in \a nodeIdsToAdd should be valid. Those nodes have to be sorted exactly following exactly the direction of the edge. - * This method can be seen as the opposite method of colinearize2D. - * This method can be lead to create some new nodes if quadratic polygon cells have to be split. In this case the added nodes will be put at the end - * to avoid to modify the numbering of existing nodes. - * - * \param [in] nodeIdsToAdd - the list of node ids to be added (\a nodeIdsIndexToAdd array allows to walk on this array) - * \param [in] nodeIdsIndexToAdd - the entry point of \a nodeIdsToAdd to point to the corresponding nodes to be added. - * \param [in] mesh1Desc - 1st output of buildDescendingConnectivity2 on \a this. - * \param [in] desc - 2nd output of buildDescendingConnectivity2 on \a this. - * \param [in] descI - 3rd output of buildDescendingConnectivity2 on \a this. - * \param [in] revDesc - 4th output of buildDescendingConnectivity2 on \a this. - * \param [in] revDescI - 5th output of buildDescendingConnectivity2 on \a this. - * - * \sa buildDescendingConnectivity2 - */ -void MEDCouplingUMesh::splitSomeEdgesOf2DMesh(const DataArrayInt *nodeIdsToAdd, const DataArrayInt *nodeIdsIndexToAdd, const DataArrayInt *edgeIdsToBeSplit, - const MEDCouplingUMesh *mesh1Desc, const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI) -{ - if(!nodeIdsToAdd || !nodeIdsIndexToAdd || !edgeIdsToBeSplit || !mesh1Desc || !desc || !descI || !revDesc || !revDescI) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : input pointers must be not NULL !"); - nodeIdsToAdd->checkAllocated(); nodeIdsIndexToAdd->checkAllocated(); edgeIdsToBeSplit->checkAllocated(); desc->checkAllocated(); descI->checkAllocated(); revDesc->checkAllocated(); revDescI->checkAllocated(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : this must have spacedim=meshdim=2 !"); - if(mesh1Desc->getSpaceDimension()!=2 || mesh1Desc->getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : mesh1Desc must be the explosion of this with spaceDim=2 and meshDim = 1 !"); - //DataArrayInt *out0(0),*outi0(0); - //MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0); - //MEDCouplingAutoRefCountObjectPtr out0s(out0),outi0s(outi0); - //out0s=out0s->buildUnique(); out0s->sort(true); -} -#endif - -/*! - * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. - * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. - */ -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - int nbOfCells=getNumberOfCells(); - int nbOfNodes=getNumberOfNodes(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0,offset=nbOfNodes; - for(int i=0;ipushBackSilent((int)INTERP_KERNEL::NORM_SEG3); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3); - newConn->pushBackSilent(offset++); - lastVal+=4; - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(type); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn(); - return ret.retn(); -} - -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - // - const int *descPtr(desc->begin()),*descIPtr(descI->begin()); - DataArrayInt *conn1D=0,*conn1DI=0; - std::set types1D; - DataArrayDouble *coordsTmp=0; - MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; - MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); - MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); - const int *c1DPtr=conn1D->begin(); - const int *c1DIPtr=conn1DI->begin(); - int nbOfCells=getNumberOfCells(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0; - for(int i=0;ipushBackSilent(typ2); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); - for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) - newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]); - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(typ); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn(); - return ret.retn(); -} - -/*! - * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. - * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. - */ -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; - return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); -} - -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; - // - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - // - MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); - const int *descPtr(desc->begin()),*descIPtr(descI->begin()); - DataArrayInt *conn1D=0,*conn1DI=0; - std::set types1D; - DataArrayDouble *coordsTmp=0; - MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; - MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); - MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); - const int *c1DPtr=conn1D->begin(); - const int *c1DIPtr=conn1DI->begin(); - int nbOfCells=getNumberOfCells(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); - for(int i=0;ipushBackSilent(typ2); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); - for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) - newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - newConn->pushBackSilent(offset+ret->getNumberOfTuples()); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1; - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(typ); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn(); - return ret.retn(); -} - -/*! - * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. - * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. - */ -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; - return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); -} - -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m2D=buildDescendingConnectivityGen(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0; - MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0; - // - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1); - // - MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); - const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin()); - DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0; - std::set types1D,types2D; - DataArrayDouble *coordsTmp=0,*coordsTmp2=0; - MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); - MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); - MEDCouplingAutoRefCountObjectPtr ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr coordsTmp2Safe(coordsTmp2); - MEDCouplingAutoRefCountObjectPtr conn2DSafe(conn2D),conn2DISafe(conn2DI); - const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin(); - int nbOfCells=getNumberOfCells(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); - for(int i=0;ipushBackSilent(typ2); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); - for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) - newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++) - { - int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1]; - int tmpPos=newConn->getNumberOfTuples(); - newConn->pushBackSilent(nodeId2); - ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos); - } - newConn->pushBackSilent(offset+ret->getNumberOfTuples()); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1; - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(typ); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - MEDCouplingAutoRefCountObjectPtr diffRet2D=ret2D->getDifferentValues(); - MEDCouplingAutoRefCountObjectPtr o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples()); - coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end()); - MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - std::vector v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp; - int *c=newConn->getPointer(); - const int *cI(newConnI->begin()); - for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++) - c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset; - offset=coordsTmp2Safe->getNumberOfTuples(); - for(const int *elt=ret->begin();elt!=ret->end();elt++) - c[cI[(*elt)+1]-1]+=offset; - coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn(); - return ret.retn(); -} - -/*! - * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces, - * so that the number of cells remains the same. Quadratic faces are converted to - * polygons. This method works only for 2D meshes in - * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8, - * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged. - * \warning This method can lead to a huge amount of nodes if \a eps is very low. - * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of - * a polylinized edge constituting the input polygon. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 2. - */ -void MEDCouplingUMesh::tessellate2D(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!"); - double epsa=fabs(eps); - if(epsa::min()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); - revDesc1=0; revDescIndx1=0; - mDesc->tessellate2DCurve(eps); - subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer()); - setCoords(mDesc->getCoords()); -} - -/*! - * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges. - * \warning This method can lead to a huge amount of nodes if \a eps is very low. - * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of - * a sub-divided edge. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 1. - * \throw If \a this->getSpaceDimension() != 2. - */ -void MEDCouplingUMesh::tessellate2DCurve(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=1 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!"); - double epsa=fabs(eps); - if(epsa::min()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10; - int nbCells=getNumberOfCells(); - int nbNodes=getNumberOfNodes(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coords=_coords->getConstPointer(); - std::vector addCoo; - std::vector newConn;//no direct DataArrayInt because interface with Geometric2D - MEDCouplingAutoRefCountObjectPtr newConnI(DataArrayInt::New()); - newConnI->alloc(nbCells+1,1); - int *newConnIPtr=newConnI->getPointer(); - *newConnIPtr=0; - int tmp1[3]; - INTERP_KERNEL::Node *tmp2[3]; - std::set types; - for(int i=0;itesselate(tmp1,nbNodes,epsa,newConn,addCoo); - types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]); - delete eac; - newConnIPtr[1]=(int)newConn.size(); - } - else - { - types.insert(INTERP_KERNEL::NORM_SEG2); - newConn.push_back(INTERP_KERNEL::NORM_SEG2); - newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3); - newConnIPtr[1]=newConnIPtr[0]+3; - } - } - else - { - types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); - newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]); - newConnIPtr[1]=newConnIPtr[0]+3; - } - } - if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed - return ; - _types=types; - DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index); - MEDCouplingAutoRefCountObjectPtr newConnArr=DataArrayInt::New(); - newConnArr->alloc((int)newConn.size(),1); - std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer()); - DataArrayInt::SetArrayIn(newConnArr,_nodal_connec); - MEDCouplingAutoRefCountObjectPtr newCoords=DataArrayDouble::New(); - newCoords->alloc(nbNodes+((int)addCoo.size())/2,2); - double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer()); - std::copy(addCoo.begin(),addCoo.end(),work); - DataArrayDouble::SetArrayIn(newCoords,_coords); - updateTime(); -} - -/*! - * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D). - * In addition, returns an array mapping new cells to old ones.
- * This method typically increases the number of cells in \a this mesh - * but the number of nodes remains \b unchanged. - * That's why the 3D splitting policies - * INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here. - * \param [in] policy - specifies a pattern used for splitting. - * The semantic of \a policy is: - * - 0 - to split QUAD4 by cutting it along 0-2 diagonal (for 2D mesh only). - * - 1 - to split QUAD4 by cutting it along 1-3 diagonal (for 2D mesh only). - * - INTERP_KERNEL::PLANAR_FACE_5 - to split HEXA8 into 5 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image). - * - INTERP_KERNEL::PLANAR_FACE_6 - to split HEXA8 into 6 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image). - * - * - * \return DataArrayInt * - a new instance of DataArrayInt holding, for each new cell, - * an id of old cell producing it. The caller is to delete this array using - * decrRef() as it is no more needed. - * - * \throw If \a policy is 0 or 1 and \a this->getMeshDimension() != 2. - * \throw If \a policy is INTERP_KERNEL::PLANAR_FACE_5 or INTERP_KERNEL::PLANAR_FACE_6 - * and \a this->getMeshDimension() != 3. - * \throw If \a policy is not one of the four discussed above. - * \throw If the nodal connectivity of cells is not defined. - * \sa MEDCouplingUMesh::tetrahedrize, MEDCoupling1SGTUMesh::sortHexa8EachOther - */ -DataArrayInt *MEDCouplingUMesh::simplexize(int policy) -{ - switch(policy) - { - case 0: - return simplexizePol0(); - case 1: - return simplexizePol1(); - case (int) INTERP_KERNEL::PLANAR_FACE_5: - return simplexizePlanarFace5(); - case (int) INTERP_KERNEL::PLANAR_FACE_6: - return simplexizePlanarFace6(); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); - } -} - -/*! - * Checks if \a this mesh is constituted by simplex cells only. Simplex cells are: - * - 1D: INTERP_KERNEL::NORM_SEG2 - * - 2D: INTERP_KERNEL::NORM_TRI3 - * - 3D: INTERP_KERNEL::NORM_TETRA4. - * - * This method is useful for users that need to use P1 field services as - * MEDCouplingFieldDouble::getValueOn(), MEDCouplingField::buildMeasureField() etc. - * All these methods need mesh support containing only simplex cells. - * \return bool - \c true if there are only simplex cells in \a this mesh. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() < 1. - */ -bool MEDCouplingUMesh::areOnlySimplexCells() const -{ - checkFullyDefined(); - int mdim=getMeshDimension(); - if(mdim<1 || mdim>3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areOnlySimplexCells : only available with meshes having a meshdim 1, 2 or 3 !"); - int nbCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - for(int i=0;i ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); - ret->alloc(nbOfCells+nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+3*nbOfCutCells,1); - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCouplingUMesh::simplexizePol1() -{ - checkConnectivityFullyDefined(); - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); - ret->alloc(nbOfCells+nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+3*nbOfCutCells,1); - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5() -{ - checkConnectivityFullyDefined(); - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); - ret->alloc(nbOfCells+4*nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+16*nbOfCutCells,1);//21 - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() -{ - checkConnectivityFullyDefined(); - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); - ret->alloc(nbOfCells+5*nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+21*nbOfCutCells,1); - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown. - * This method completly ignore coordinates. - * \param nodeSubdived is the nodal connectivity of subdivision of edges - * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges - * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 - * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 - */ -void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) -{ - checkFullyDefined(); - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !"); - int nbOfCells=getNumberOfCells(); - int *connI=_nodal_connec_index->getPointer(); - int newConnLgth=0; - for(int i=0;i0; - int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1; - int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1]; - for(int j=0;j0; - int edgeId=std::abs(desc[offset+j])-1; - if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic()) - { - int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1]; - int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1]; - int ref2=direct?id1:id2; - if(ref==ref2) - { - int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1; - newConnLgth+=nbOfSubNodes-1; - ref=direct?id2:id1; - } - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !"); - } - } - newConnLgth++;//+1 is for cell type - connI[1]=newConnLgth; - } - // - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - newConn->alloc(newConnLgth,1); - int *work=newConn->getPointer(); - for(int i=0;i0; - int edgeId=std::abs(desc[offset+j])-1; - if(direct) - work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work); - else - { - int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1; - std::reverse_iterator it(nodeSubdived+nodeIndxSubdived[edgeId+1]); - work=std::copy(it,it+nbOfSubNodes-1,work); - } - } - } - DataArrayInt::SetArrayIn(newConn,_nodal_connec); - _types.clear(); - if(nbOfCells>0) - _types.insert(INTERP_KERNEL::NORM_POLYGON); -} - -/*! - * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler - * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in - * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method - * does \b not perform geometrical checks and checks only nodal connectivity of cells, - * so it can be useful to call mergeNodes() before calling this method. - * \throw If \a this->getMeshDimension() <= 1. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - */ -void MEDCouplingUMesh::convertDegeneratedCells() -{ - checkFullyDefined(); - if(getMeshDimension()<=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !"); - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return ; - int initMeshLgth=getMeshLength(); - int *conn=_nodal_connec->getPointer(); - int *index=_nodal_connec_index->getPointer(); - int posOfCurCell=0; - int newPos=0; - int lgthOfCurCell; - for(int i=0;ireAlloc(newPos); - computeTypes(); -} - -/*! - * Finds incorrectly oriented cells of this 2D mesh in 3D space. - * A cell is considered to be oriented correctly if an angle between its - * normal vector and a given vector is less than \c PI / \c 2. - * \param [in] vec - 3 components of the vector specifying the correct orientation of - * cells. - * \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are - * checked. - * \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It - * is not cleared before filling in. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - for(int i=0;igetMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". - * \endif - * - * \sa changeOrientationOfCells - */ -void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !"); - int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer()); - const int *connI(_nodal_connec_index->getConstPointer()); - const double *coordsPtr(_coords->getConstPointer()); - bool isModified(false); - for(int i=0;ideclareAsNew(); - updateTime(); -} - -/*! - * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted. - * - * \sa orientCorrectly2DCells - */ -void MEDCouplingUMesh::changeOrientationOfCells() -{ - int mdim(getMeshDimension()); - if(mdim!=2 && mdim!=1) - throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !"); - int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer()); - const int *connI(_nodal_connec_index->getConstPointer()); - if(mdim==2) - {//2D - for(int i=0;igetMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cells) const -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - for(int i=0;igetMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the reparation fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". - * \endif - * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells - */ -void MEDCouplingUMesh::orientCorrectlyPolyhedrons() -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectlyPolyhedrons on it : must be meshDim==3 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - for(int i=0;igetMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a C++ example".
- * \ref py_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a Python example". - * \endif - * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells - */ -DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells() -{ - const char msg[]="check3DCellsWellOriented detection works only for 3D cells !"; - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception(msg); - int spaceDim=getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception(msg); - // - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=getCoords()->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr cells(DataArrayInt::New()); cells->alloc(0,1); - for(int i=0;ipushBackSilent(i); - } - } - } - return cells.retn(); -} - -/*! - * This method is a faster method to correct orientation of all 3D cells in \a this. - * This method works only if \a this is a 3D mesh, that is to say a mesh with mesh dimension 3 and a space dimension 3. - * This method makes the hypothesis that \a this a coherent that is to say MEDCouplingUMesh::checkCoherency2 should throw no exception. - * - * \return a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling) - * \sa MEDCouplingUMesh::orientCorrectlyPolyhedrons, - */ -DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells() -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply findAndCorrectBadOriented3DCells on it : must be meshDim==3 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - } - break; - } - case INTERP_KERNEL::NORM_PYRA5: - { - if(!IsPyra5WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) - { - std::swap(*(conn+connI[i]+2),*(conn+connI[i]+4)); - ret->pushBackSilent(i); - } - break; - } - case INTERP_KERNEL::NORM_PENTA6: - case INTERP_KERNEL::NORM_HEXA8: - case INTERP_KERNEL::NORM_HEXGP12: - { - if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) - { - CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]); - ret->pushBackSilent(i); - } - break; - } - case INTERP_KERNEL::NORM_POLYHED: - { - if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) - { - TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr); - ret->pushBackSilent(i); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orientCorrectly3DCells : Your mesh contains type of cell not supported yet ! send mail to anthony.geay@cea.fr to add it !"); - } - } - updateTime(); - return ret.retn(); -} - -/*! - * This method has a sense for meshes with spaceDim==3 and meshDim==2. - * If it is not the case an exception will be thrown. - * This method is fast because the first cell of \a this is used to compute the plane. - * \param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane. - * \param pos output of size at least 3 used to store a point owned of searched plane. - */ -void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply getFastAveragePlaneOfThis on it : must be meshDim==2 and spaceDim==3 !"); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - INTERP_KERNEL::areaVectorOfPolygon(conn+1,connI[1]-connI[0]-1,coordsPtr,vec); - std::copy(coordsPtr+3*conn[1],coordsPtr+3*conn[1]+3,pos); -} - -/*! - * Creates a new MEDCouplingFieldDouble holding Edge Ratio values of all - * cells. Currently cells of the following types are treated: - * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4. - * For a cell of other type an exception is thrown. - * Space dimension of a 2D mesh can be either 2 or 3. - * The Edge Ratio of a cell \f$t\f$ is: - * \f$\frac{|t|_\infty}{|t|_0}\f$, - * where \f$|t|_\infty\f$ and \f$|t|_0\f$ respectively denote the greatest and - * the smallest edge lengths of \f$t\f$. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - * \throw If \a this->getMeshDimension() is neither 2 nor 3. - * \throw If \a this->getSpaceDimension() is neither 2 nor 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !"); - if(meshDim!=2 && meshDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("EdgeRatio"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble holding Aspect Ratio values of all - * cells. Currently cells of the following types are treated: - * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4. - * For a cell of other type an exception is thrown. - * Space dimension of a 2D mesh can be either 2 or 3. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - * \throw If \a this->getMeshDimension() is neither 2 nor 3. - * \throw If \a this->getSpaceDimension() is neither 2 nor 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !"); - if(meshDim!=2 && meshDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("AspectRatio"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble holding Warping factor values of all - * cells of \a this 2D mesh in 3D space. Currently cells of the following types are - * treated: INTERP_KERNEL::NORM_QUAD4. - * For a cell of other type an exception is thrown. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !"); - if(meshDim!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("Warp"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - - -/*! - * Creates a new MEDCouplingFieldDouble holding Skew factor values of all - * cells of \a this 2D mesh in 3D space. Currently cells of the following types are - * treated: INTERP_KERNEL::NORM_QUAD4. - * For a cell of other type an exception is thrown. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If \a this mesh contains elements of dimension different from the mesh dimension. - * \throw If the connectivity data array has more than one component. - * \throw If the connectivity data array has a named component. - * \throw If the connectivity index data array has more than one component. - * \throw If the connectivity index data array has a named component. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !"); - if(meshDim!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("Skew"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell. - * - * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller. - * - * \sa getSkewField, getWarpField, getAspectRatioField, getEdgeRatioField - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::computeDiameterField() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); - ret->setMesh(this); - std::set types; - ComputeAllTypesInternal(types,_nodal_connec,_nodal_connec_index); - int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr arr(DataArrayDouble::New()); - arr->alloc(nbCells,1); - for(std::set::const_iterator it=types.begin();it!=types.end();it++) - { - INTERP_KERNEL::AutoCppPtr dc(INTERP_KERNEL::CellModel::GetCellModel(*it).buildInstanceOfDiameterCalulator(spaceDim)); - MEDCouplingAutoRefCountObjectPtr cellIds(giveCellsWithType(*it)); - dc->computeForListOfCellIdsUMeshFrmt(cellIds->begin(),cellIds->end(),_nodal_connec_index->begin(),_nodal_connec->begin(),getCoords()->begin(),arr->getPointer()); - } - ret->setArray(arr); - ret->setName("Diameter"); - return ret.retn(); -} - -/*! - * This method aggregate the bbox of each cell and put it into bbox parameter. - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * For all other cases this input parameter is ignored. - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - * \sa MEDCouplingUMesh::getBoundingBoxForBBTreeFast, MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic - */ -DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) const -{ - int mDim(getMeshDimension()),sDim(getSpaceDimension()); - if((mDim==3 && sDim==3) || (mDim==2 && sDim==3) || (mDim==1 && sDim==1) || ( mDim==1 && sDim==3)) // Compute refined boundary box for quadratic elements only in 2D. - return getBoundingBoxForBBTreeFast(); - if((mDim==2 && sDim==2) || (mDim==1 && sDim==2)) - { - bool presenceOfQuadratic(false); - for(std::set::const_iterator it=_types.begin();it!=_types.end();it++) - { - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it)); - if(cm.isQuadratic()) - presenceOfQuadratic=true; - } - if(!presenceOfQuadratic) - return getBoundingBoxForBBTreeFast(); - if(mDim==2 && sDim==2) - return getBoundingBoxForBBTree2DQuadratic(arcDetEps); - else - return getBoundingBoxForBBTree1DQuadratic(arcDetEps); - } - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree : Managed dimensions are (mDim=1,sDim=1), (mDim=1,sDim=2), (mDim=1,sDim=3), (mDim=2,sDim=2), (mDim=2,sDim=3) and (mDim=3,sDim=3) !"); -} - -/*! - * This method aggregate the bbox of each cell only considering the nodes constituting each cell and put it into bbox parameter. - * So meshes having quadratic cells the computed bounding boxes can be invalid ! - * - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - */ -DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const -{ - checkFullyDefined(); - int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - for(int i=0;i::max(); - bbox[2*i+1]=-std::numeric_limits::max(); - } - const double *coordsPtr(_coords->getConstPointer()); - const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); - for(int i=0;i=0 && nodeId ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - const double *coords(_coords->getConstPointer()); - const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); - for(int i=0;i nodes(sz); - INTERP_KERNEL::QuadraticPolygon *pol(0); - for(int j=0;jfillBounds(b); delete pol; - bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); - } - return ret.retn(); -} - -/*! - * This method aggregates the bbox of each 1D cell in \a this considering the whole shape. This method is particularly - * useful for 2D meshes having quadratic cells - * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers - * the two extremities of the arc of circle). - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * \throw If \a this is not fully defined. - * \throw If \a this is not a mesh with meshDimension equal to 1. - * \throw If \a this is not a mesh with spaceDimension equal to 2. - * \sa MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic - */ -DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic(double arcDetEps) const -{ - checkFullyDefined(); - int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()); - if(spaceDim!=2 || mDim!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic : This method should be applied on mesh with mesh dimension equal to 1 and space dimension also equal to 2!"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - const double *coords(_coords->getConstPointer()); - const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); - for(int i=0;i nodes(sz); - INTERP_KERNEL::Edge *edge(0); - for(int j=0;jgetBounds()); - bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); edge->decrRef(); - } - return ret.retn(); -} - -/// @cond INTERNAL - -namespace ParaMEDMEMImpl -{ - class ConnReader - { - public: - ConnReader(const int *c, int val):_conn(c),_val(val) { } - bool operator() (const int& pos) { return _conn[pos]!=_val; } - private: - const int *_conn; - int _val; - }; - - class ConnReader2 - { - public: - ConnReader2(const int *c, int val):_conn(c),_val(val) { } - bool operator() (const int& pos) { return _conn[pos]==_val; } - private: - const int *_conn; - int _val; - }; -} - -/// @endcond - -/*! - * This method expects that \a this is sorted by types. If not an exception will be thrown. - * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how - * \a this is composed in cell types. - * The returned array is of size 3*n where n is the number of different types present in \a this. - * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. - * This parameter is kept only for compatibility with other methode listed above. - */ -std::vector MEDCouplingUMesh::getDistributionOfTypes() const -{ - checkConnectivityFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *work=connI; - int nbOfCells=getNumberOfCells(); - std::size_t n=getAllGeoTypes().size(); - std::vector ret(3*n,-1); //ret[3*k+2]==-1 because it has no sense here - std::set types; - for(std::size_t i=0;work!=connI+nbOfCells;i++) - { - INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn[*work]; - if(types.find(typ)!=types.end()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::getDistributionOfTypes : Type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr(); - oss << " is not contiguous !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - types.insert(typ); - ret[3*i]=typ; - const int *work2=std::find_if(work+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,typ)); - ret[3*i+1]=(int)std::distance(work,work2); - work=work2; - } - return ret; -} - -/*! - * This method is used to check that this has contiguous cell type in same order than described in \a code. - * only for types cell, type node is not managed. - * Format of \a code is the following. \a code should be of size 3*n and non empty. If not an exception is thrown. - * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k. - * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array. - * If 2 or more same geometric type is in \a code and exception is thrown too. - * - * This method firstly checks - * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown. - * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match, - * an exception is thrown too. - * - * If all geometric types in \a code are exactly those in \a this null pointer is returned. - * If it exists a geometric type in \a this \b not in \a code \b no exception is thrown - * and a DataArrayInt instance is returned that the user has the responsability to deallocate. - */ -DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code is empty, should not !"); - std::size_t sz=code.size(); - std::size_t n=sz/3; - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !"); - std::vector types; - int nb=0; - bool isNoPflUsed=true; - for(std::size_t i=0;i ret=DataArrayInt::New(); - ret->alloc(nb,1); - int *retPtr=ret->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - int nbOfCells=getNumberOfCells(); - const int *i=connI; - int kk=0; - for(std::vector::const_iterator it=types.begin();it!=types.end();it++,kk++) - { - i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it))); - int offset=(int)std::distance(connI,i); - const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it))); - int nbOfCellsOfCurType=(int)std::distance(i,j); - if(code[3*kk+2]==-1) - for(int k=0;k=0 && idInIdsPerType<(int)idsPerType.size()) - { - const DataArrayInt *zePfl=idsPerType[idInIdsPerType]; - if(zePfl) - { - zePfl->checkAllocated(); - if(zePfl->getNumberOfComponents()==1) - { - for(const int *k=zePfl->begin();k!=zePfl->end();k++,retPtr++) - { - if(*k>=0 && *k& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - if(!profile) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile is NULL !"); - if(profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile should have exactly one component !"); - checkConnectivityFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector types; - std::vector typeRangeVals(1); - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - if(std::find(types.begin(),types.end(),curType)!=types.end()) - { - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : current mesh is not sorted by type !"); - } - types.push_back(curType); - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - typeRangeVals.push_back((int)std::distance(connI,i)); - } - // - DataArrayInt *castArr=0,*rankInsideCast=0,*castsPresent=0; - profile->splitByValueRange(&typeRangeVals[0],&typeRangeVals[0]+typeRangeVals.size(),castArr,rankInsideCast,castsPresent); - MEDCouplingAutoRefCountObjectPtr tmp0=castArr; - MEDCouplingAutoRefCountObjectPtr tmp1=rankInsideCast; - MEDCouplingAutoRefCountObjectPtr tmp2=castsPresent; - // - int nbOfCastsFinal=castsPresent->getNumberOfTuples(); - code.resize(3*nbOfCastsFinal); - std::vector< MEDCouplingAutoRefCountObjectPtr > idsInPflPerType2; - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerType2; - for(int i=0;igetIJ(i,0); - MEDCouplingAutoRefCountObjectPtr tmp3=castArr->getIdsEqual(castId); - idsInPflPerType2.push_back(tmp3); - code[3*i]=(int)types[castId]; - code[3*i+1]=tmp3->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr tmp4=rankInsideCast->selectByTupleId(tmp3->getConstPointer(),tmp3->getConstPointer()+tmp3->getNumberOfTuples()); - if(tmp4->getNumberOfTuples()!=typeRangeVals[castId+1]-typeRangeVals[castId] || !tmp4->isIdentity()) - { - tmp4->copyStringInfoFrom(*profile); - idsPerType2.push_back(tmp4); - code[3*i+2]=(int)idsPerType2.size()-1; - } - else - { - code[3*i+2]=-1; - } - } - std::size_t sz2=idsInPflPerType2.size(); - idsInPflPerType.resize(sz2); - for(std::size_t i=0;iincrRef(); - idsInPflPerType[i]=locDa; - } - std::size_t sz=idsPerType2.size(); - idsPerType.resize(sz); - for(std::size_t i=0;iincrRef(); - idsPerType[i]=locDa; - } -} - -/*! - * This method is here too emulate the MEDMEM behaviour on BDC (buildDescendingConnectivity). Hoping this method becomes deprecated very soon. - * This method make the assumption that \a this and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does. - * The following equality should be verified 'nM1LevMesh->getMeshDimension()==this->getMeshDimension()-1' - * This method returns 5+2 elements. 'desc', 'descIndx', 'revDesc', 'revDescIndx' and 'meshnM1' behaves exactly as ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity except the content as described after. The returned array specifies the n-1 mesh reordered by type as MEDMEM does. 'nM1LevMeshIds' contains the ids in returned 'meshnM1'. Finally 'meshnM1Old2New' contains numbering old2new that is to say the cell #k in coarse 'nM1LevMesh' will have the number ret[k] in returned mesh 'nM1LevMesh' MEDMEM reordered. - */ -MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const -{ - checkFullyDefined(); - nM1LevMesh->checkFullyDefined(); - if(getMeshDimension()-1!=nM1LevMesh->getMeshDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : The mesh passed as first argument should have a meshDim equal to this->getMeshDimension()-1 !" ); - if(_coords!=nM1LevMesh->getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : 'this' and mesh in first argument should share the same coords : Use tryToShareSameCoords method !"); - MEDCouplingAutoRefCountObjectPtr tmp0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmp1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr ret1=buildDescendingConnectivity(desc,descIndx,tmp0,tmp1); - MEDCouplingAutoRefCountObjectPtr ret0=ret1->sortCellsInMEDFileFrmt(); - desc->transformWithIndArr(ret0->getConstPointer(),ret0->getConstPointer()+ret0->getNbOfElems()); - MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::New(); - tmp->setConnectivity(tmp0,tmp1); - tmp->renumberCells(ret0->getConstPointer(),false); - revDesc=tmp->getNodalConnectivity(); - revDescIndx=tmp->getNodalConnectivityIndex(); - DataArrayInt *ret=0; - if(!ret1->areCellsIncludedIn(nM1LevMesh,2,ret)) - { - int tmp2; - ret->getMaxValue(tmp2); - ret->decrRef(); - std::ostringstream oss; oss << "MEDCouplingUMesh::emulateMEDMEMBDC : input N-1 mesh present a cell not in descending mesh ... Id of cell is " << tmp2 << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - nM1LevMeshIds=ret; - // - revDesc->incrRef(); - revDescIndx->incrRef(); - ret1->incrRef(); - ret0->incrRef(); - meshnM1Old2New=ret0; - return ret1; -} - -/*! - * Permutes the nodal connectivity arrays so that the cells are sorted by type, which is - * necessary for writing the mesh to MED file. Additionally returns a permutation array - * in "Old to New" mode. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete - * this array using decrRef() as it is no more needed. - * \throw If the nodal connectivity of cells is not defined. - */ -DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() -{ - checkConnectivityFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret=getRenumArrForMEDFileFrmt(); - renumberCells(ret->getConstPointer(),false); - return ret.retn(); -} - -/*! - * This methods checks that cells are sorted by their types. - * This method makes asumption (no check) that connectivity is correctly set before calling. - */ -bool MEDCouplingUMesh::checkConsecutiveCellTypes() const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::set types; - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - if(types.find(curType)!=types.end()) - return false; - types.insert(curType); - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - } - return true; -} - -/*! - * This method is a specialization of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method that is called here. - * The geometric type order is specified by MED file. - * - * \sa MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder - */ -bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const -{ - return checkConsecutiveCellTypesAndOrder(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); -} - -/*! - * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check - * that the order is specified in array defined by [ \a orderBg , \a orderEnd ). - * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous. - * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous. - */ -bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - if(nbOfCells==0) - return true; - int lastPos=-1; - std::set sg; - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - const INTERP_KERNEL::NormalizedCellType *isTypeExists=std::find(orderBg,orderEnd,curType); - if(isTypeExists!=orderEnd) - { - int pos=(int)std::distance(orderBg,isTypeExists); - if(pos<=lastPos) - return false; - lastPos=pos; - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - } - else - { - if(sg.find(curType)==sg.end()) - { - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - sg.insert(curType); - } - else - return false; - } - } - return true; -} - -/*! - * This method returns 2 newly allocated DataArrayInt instances. The first is an array of size 'this->getNumberOfCells()' with one component, - * that tells for each cell the pos of its type in the array on type given in input parameter. The 2nd output parameter is an array with the same - * number of tuples than input type array and with one component. This 2nd output array gives type by type the number of occurence of type in 'this'. - */ -DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr tmpa=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmpb=DataArrayInt::New(); - tmpa->alloc(nbOfCells,1); - tmpb->alloc((int)std::distance(orderBg,orderEnd),1); - tmpb->fillWithZero(); - int *tmp=tmpa->getPointer(); - int *tmp2=tmpb->getPointer(); - for(const int *i=connI;i!=connI+nbOfCells;i++) - { - const INTERP_KERNEL::NormalizedCellType *where=std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i]); - if(where!=orderEnd) - { - int pos=(int)std::distance(orderBg,where); - tmp2[pos]++; - tmp[std::distance(connI,i)]=pos; - } - else - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*i]); - std::ostringstream oss; oss << "MEDCouplingUMesh::getLevArrPerCellTypes : Cell #" << std::distance(connI,i); - oss << " has a type " << cm.getRepr() << " not in input array of type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - nbPerType=tmpb.retn(); - return tmpa.retn(); -} - -/*! - * This method behaves exactly as MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec but the order is those defined in MED file spec. - * - * \return a new object containing the old to new correspondance. - * - * \sa MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec, MEDCouplingUMesh::sortCellsInMEDFileFrmt. - */ -DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const -{ - return getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); -} - -/*! - * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this. - * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells. - * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs. - * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same. - */ -DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const -{ - DataArrayInt *nbPerType=0; - MEDCouplingAutoRefCountObjectPtr tmpa=getLevArrPerCellTypes(orderBg,orderEnd,nbPerType); - nbPerType->decrRef(); - return tmpa->buildPermArrPerLevel(); -} - -/*! - * This method reorganize the cells of \a this so that the cells with same geometric types are put together. - * The number of cells remains unchanged after the call of this method. - * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as - * MEDCouplingUMesh::sortCellsInMEDFileFrmt. - * - * \return the array giving the correspondance old to new. - */ -DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() -{ - checkFullyDefined(); - computeTypes(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector types; - for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());) - if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end()) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - types.push_back(curType); - for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - std::fill(retPtr,retPtr+nbOfCells,-1); - int newCellId=0; - for(std::vector::const_iterator iter=types.begin();iter!=types.end();iter++) - { - for(const int *i=connI;i!=connI+nbOfCells;i++) - if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) - retPtr[std::distance(connI,i)]=newCellId++; - } - renumberCells(retPtr,false); - return ret; -} - -/*! - * This method splits \a this into as mush as untructured meshes that consecutive set of same type cells. - * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense. - * This method makes asumption that connectivity is correctly set before calling. - */ -std::vector MEDCouplingUMesh::splitByType() const -{ - checkConnectivityFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector ret; - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - int beginCellId=(int)std::distance(connI,i); - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - int endCellId=(int)std::distance(connI,i); - int sz=endCellId-beginCellId; - int *cells=new int[sz]; - for(int j=0;j ret=MEDCoupling1GTUMesh::New(getName(),typ); - ret->setCoords(getCoords()); - MEDCoupling1SGTUMesh *retC=dynamic_cast((MEDCoupling1GTUMesh*)ret); - if(retC) - { - MEDCouplingAutoRefCountObjectPtr c=convertNodalConnectivityToStaticGeoTypeMesh(); - retC->setNodalConnectivity(c); - } - else - { - MEDCoupling1DGTUMesh *retD=dynamic_cast((MEDCoupling1GTUMesh*)ret); - if(!retD) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : Internal error !"); - DataArrayInt *c=0,*ci=0; - convertNodalConnectivityToDynamicGeoTypeMesh(c,ci); - MEDCouplingAutoRefCountObjectPtr cs(c),cis(ci); - retD->setNodalConnectivity(cs,cis); - } - return ret.retn(); -} - -DataArrayInt *MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh() const -{ - checkConnectivityFullyDefined(); - if(_types.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : current mesh does not contain exactly one geometric type !"); - INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - if(cm.isDynamic()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : this contains a single geo type (" << cm.getRepr() << ") but "; - oss << "this type is dynamic ! Only static geometric type is possible for that type ! call convertNodalConnectivityToDynamicGeoTypeMesh instead !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbCells=getNumberOfCells(); - int typi=(int)typ; - int nbNodesPerCell=(int)cm.getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr connOut=DataArrayInt::New(); connOut->alloc(nbCells*nbNodesPerCell,1); - int *outPtr=connOut->getPointer(); - const int *conn=_nodal_connec->begin(); - const int *connI=_nodal_connec_index->begin(); - nbNodesPerCell++; - for(int i=0;igetNumberOfTuples(); - if(lgth c(DataArrayInt::New()),ci(DataArrayInt::New()); - c->alloc(lgth-nbCells,1); ci->alloc(nbCells+1,1); - int *cp(c->getPointer()),*cip(ci->getPointer()); - const int *incp(_nodal_connec->begin()),*incip(_nodal_connec_index->begin()); - cip[0]=0; - for(int i=0;i=1) - { - if((strt>=0 && strt=0 && stop<=lgth)) - cp=std::copy(incp+strt,incp+stop,cp); - else - throw INTERP_KERNEL::Exception(msg0); - } - else - throw INTERP_KERNEL::Exception(msg0); - cip[1]=cip[0]+delta; - } - nodalConn=c.retn(); nodalConnIndex=ci.retn(); -} - -/*! - * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions. - * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt). - * This method is particulary useful for MED file interaction. It allows to aggregate several meshes and keeping the type sorting - * and the track of the permutation by chunk of same geotype cells to retrieve it. The traditional formats old2new and new2old - * are not used here to avoid the build of big permutation array. - * - * \param [in] ms meshes with same mesh dimension lying on the same coords and sorted by type following de the same geometric type order than - * those specified in MEDCouplingUMesh::sortCellsInMEDFileFrmt method. - * \param [out] szOfCellGrpOfSameType is a newly allocated DataArrayInt instance whose number of tuples is equal to the number of chunks of same geotype - * in all meshes in \b ms. The accumulation of all values of this array is equal to the number of cells of returned mesh. - * \param [out] idInMsOfCellGrpOfSameType is a newly allocated DataArrayInt instance having the same size than \b szOfCellGrpOfSameType. This - * output array gives for each chunck of same type the corresponding mesh id in \b ms. - * \return A newly allocated unstructured mesh that is the result of the aggregation on same coords of all meshes in \b ms. This returned mesh - * is sorted by type following the geo cell types order of MEDCouplingUMesh::sortCellsInMEDFileFrmt method. - */ -MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, - DataArrayInt *&szOfCellGrpOfSameType, - DataArrayInt *&idInMsOfCellGrpOfSameType) -{ - std::vector ms2; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - if(*it) - { - (*it)->checkConnectivityFullyDefined(); - ms2.push_back(*it); - } - if(ms2.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : input vector is empty !"); - const DataArrayDouble *refCoo=ms2[0]->getCoords(); - int meshDim=ms2[0]->getMeshDimension(); - std::vector m1ssm; - std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmAuto; - // - std::vector m1ssmSingle; - std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmSingleAuto; - int fake=0,rk=0; - MEDCouplingAutoRefCountObjectPtr ret1(DataArrayInt::New()),ret2(DataArrayInt::New()); - ret1->alloc(0,1); ret2->alloc(0,1); - for(std::vector::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++) - { - if(meshDim!=(*it)->getMeshDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshdims mismatch !"); - if(refCoo!=(*it)->getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshes are not shared by a single coordinates coords !"); - std::vector sp=(*it)->splitByType(); - std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector >(m1ssm)); - std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector > >(m1ssmAuto)); - for(std::vector::const_iterator it2=sp.begin();it2!=sp.end();it2++) - { - MEDCouplingUMesh *singleCell=static_cast((*it2)->buildPartOfMySelf(&fake,&fake+1,true)); - m1ssmSingleAuto.push_back(singleCell); - m1ssmSingle.push_back(singleCell); - ret1->pushBackSilent((*it2)->getNumberOfCells()); ret2->pushBackSilent(rk); - } - } - MEDCouplingAutoRefCountObjectPtr m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle); - MEDCouplingAutoRefCountObjectPtr renum=m1ssmSingle2->sortCellsInMEDFileFrmt(); - std::vector m1ssmfinal(m1ssm.size()); - for(std::size_t i=0;igetIJ(i,0)]=m1ssm[i]; - MEDCouplingAutoRefCountObjectPtr ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal); - szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer()); - idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer()); - return ret0.retn(); -} - -/*! - * This method returns a newly created DataArrayInt instance. - * This method retrieves cell ids in [ \a begin, \a end ) that have the type \a type. - */ -DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(const int *w=begin;w!=end;w++) - if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type) - ret->pushBackSilent(*w); - return ret.retn(); -} - -/*! - * This method makes the assumption that da->getNumberOfTuples()getNumberOfCells(). This method makes the assumption that ids contained in 'da' - * are in [0:getNumberOfCells()) - */ -DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::set types(getAllGeoTypes()); - int *tmp=new int[nbOfCells]; - for(std::set::const_iterator iter=types.begin();iter!=types.end();iter++) - { - int j=0; - for(const int *i=connI;i!=connI+nbOfCells;i++) - if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) - tmp[std::distance(connI,i)]=j++; - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(da->getNumberOfTuples(),da->getNumberOfComponents()); - ret->copyStringInfoFrom(*da); - int *retPtr=ret->getPointer(); - const int *daPtr=da->getConstPointer(); - int nbOfElems=da->getNbOfElems(); - for(int k=0;k code=getDistributionOfTypes(); - std::size_t nOfTypesInThis=code.size()/3; - int sz=0,szOfType=0; - for(std::size_t i=0;i=szOfType) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::keepSpecifiedCells : Request on type " << type << " at place #" << std::distance(idsPerGeoTypeBg,work) << " value " << *work; - oss << ". It should be in [0," << szOfType << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr idsTokeep=DataArrayInt::New(); idsTokeep->alloc(sz+(int)std::distance(idsPerGeoTypeBg,idsPerGeoTypeEnd),1); - int *idsPtr=idsTokeep->getPointer(); - int offset=0; - for(std::size_t i=0;i(),offset)); - offset+=code[3*i+1]; - } - MEDCouplingAutoRefCountObjectPtr ret=static_cast(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true)); - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * This method returns a vector of size 'this->getNumberOfCells()'. - * This method retrieves for each cell in \a this if it is linear (false) or quadratic(true). - */ -std::vector MEDCouplingUMesh::getQuadraticStatus() const -{ - int ncell=getNumberOfCells(); - std::vector ret(ncell); - const int *cI=getNodalConnectivityIndex()->getConstPointer(); - const int *c=getNodalConnectivity()->getConstPointer(); - for(int i=0;igetType()!=UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh each other !"); - const MEDCouplingUMesh *otherC=static_cast(other); - return MergeUMeshes(this,otherC); -} - -/*! - * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is - * computed by averaging coordinates of cell nodes, so this method is not a right - * choice for degnerated meshes (not well oriented, cells with measure close to zero). - * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a - * this->getNumberOfCells() tuples per \a this->getSpaceDimension() - * components. The caller is to delete this array using decrRef() as it is - * no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \sa MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell - */ -DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells(); - ret->alloc(nbOfCells,spaceDim); - ret->copyStringInfoFrom(*getCoords()); - double *ptToFill=ret->getPointer(); - const int *nodal=_nodal_connec->getConstPointer(); - const int *nodalI=_nodal_connec_index->getConstPointer(); - const double *coor=_coords->getConstPointer(); - for(int i=0;i(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill); - ptToFill+=spaceDim; - } - return ret.retn(); -} - -/*! - * This method computes for each cell in \a this, the location of the iso barycenter of nodes constituting - * the cell. Contrary to badly named MEDCouplingUMesh::getBarycenterAndOwner method that returns the center of inertia of the - * - * \return a newly allocated DataArrayDouble instance that the caller has to deal with. The returned - * DataArrayDouble instance will have \c this->getNumberOfCells() tuples and \c this->getSpaceDimension() components. - * - * \sa MEDCouplingUMesh::getBarycenterAndOwner - * \throw If \a this is not fully defined (coordinates and connectivity) - * \throw If there is presence in nodal connectivity in \a this of node ids not in [0, \c this->getNumberOfNodes() ) - */ -DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const -{ - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells(); - int nbOfNodes=getNumberOfNodes(); - ret->alloc(nbOfCells,spaceDim); - double *ptToFill=ret->getPointer(); - const int *nodal=_nodal_connec->getConstPointer(); - const int *nodalI=_nodal_connec_index->getConstPointer(); - const double *coor=_coords->getConstPointer(); - for(int i=0;i=0 && *conn()); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *conn << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - int nbOfNodesInCell=nodalI[i+1]-nodalI[i]-1; - if(nbOfNodesInCell>0) - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(double)nbOfNodesInCell)); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of cell with no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::set s(nodal+nodalI[i]+1,nodal+nodalI[i+1]); - s.erase(-1); - for(std::set::const_iterator it=s.begin();it!=s.end();it++) - { - if(*it>=0 && *it()); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell polyhedron cell #" << i << " presence of nodeId #" << *it << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(!s.empty()) - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(double)s.size())); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on polyhedron cell #" << i << " there are no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - return ret.retn(); -} - -/*! - * Returns a new DataArrayDouble holding barycenters of specified cells. The - * barycenter is computed by averaging coordinates of cell nodes. The cells to treat - * are specified via an array of cell ids. - * \warning Validity of the specified cell ids is not checked! - * Valid range is [ 0, \a this->getNumberOfCells() ). - * \param [in] begin - an array of cell ids of interest. - * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. - * \return DataArrayDouble * - a new instance of DataArrayDouble, of size ( \a - * end - \a begin ) tuples per \a this->getSpaceDimension() components. The - * caller is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getPartBarycenterAndOwner "Here is a C++ example".
- * \ref py_mcumesh_getPartBarycenterAndOwner "Here is a Python example". - * \endif - */ -DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const -{ - DataArrayDouble *ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfTuple=(int)std::distance(begin,end); - ret->alloc(nbOfTuple,spaceDim); - double *ptToFill=ret->getPointer(); - double *tmp=new double[spaceDim]; - const int *nodal=_nodal_connec->getConstPointer(); - const int *nodalI=_nodal_connec_index->getConstPointer(); - const double *coor=_coords->getConstPointer(); - for(const int *w=begin;w!=end;w++) - { - INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[*w]]; - INTERP_KERNEL::computeBarycenter2(type,nodal+nodalI[*w]+1,nodalI[*w+1]-nodalI[*w]-1,coor,spaceDim,ptToFill); - ptToFill+=spaceDim; - } - delete [] tmp; - return ret; -} - -/*! - * Returns a DataArrayDouble instance giving for each cell in \a this the equation of plane given by "a*X+b*Y+c*Z+d=0". - * So the returned instance will have 4 components and \c this->getNumberOfCells() tuples. - * So this method expects that \a this has a spaceDimension equal to 3 and meshDimension equal to 2. - * The computation of the plane equation is done using each time the 3 first nodes of 2D cells. - * This method is useful to detect 2D cells in 3D space that are not coplanar. - * - * \return DataArrayDouble * - a new instance of DataArrayDouble having 4 components and a number of tuples equal to number of cells in \a this. - * \throw If spaceDim!=3 or meshDim!=2. - * \throw If connectivity of \a this is invalid. - * \throw If connectivity of a cell in \a this points to an invalid node. - */ -DataArrayDouble *MEDCouplingUMesh::computePlaneEquationOf3DFaces() const -{ - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - if(getSpaceDimension()!=3 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computePlaneEquationOf3DFaces : This method must be applied on a mesh having meshDimension equal 2 and a spaceDimension equal to 3 !"); - ret->alloc(nbOfCells,4); - double *retPtr(ret->getPointer()); - const int *nodal(_nodal_connec->begin()),*nodalI(_nodal_connec_index->begin()); - const double *coor(_coords->begin()); - for(int i=0;i=3) - { - for(int j=0;j<3;j++) - { - int nodeId(nodal[nodalI[0]+1+j]); - if(nodeId>=0 && nodeIdcheckAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(da->getName(),0); - ret->setCoords(da); - int nbOfTuples=da->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); - c->alloc(2*nbOfTuples,1); - cI->alloc(nbOfTuples+1,1); - int *cp=c->getPointer(); - int *cip=cI->getPointer(); - *cip++=0; - for(int i=0;isetConnectivity(c,cI,true); - return ret.retn(); -} -/*! - * Creates a new MEDCouplingUMesh by concatenating two given meshes of the same dimension. - * Cells and nodes of - * the first mesh precede cells and nodes of the second mesh within the result mesh. - * \param [in] mesh1 - the first mesh. - * \param [in] mesh2 - the second mesh. - * \return MEDCouplingUMesh * - the result mesh. It is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If \a mesh1 == NULL or \a mesh2 == NULL. - * \throw If the coordinates array is not set in none of the meshes. - * \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0. - * \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension(). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); - return MergeUMeshes(tmp); -} - -/*! - * Creates a new MEDCouplingUMesh by concatenating all given meshes of the same dimension. - * Cells and nodes of - * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh. - * \param [in] a - a vector of meshes (MEDCouplingUMesh) to concatenate. - * \return MEDCouplingUMesh * - the result mesh. It is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If \a a.size() == 0. - * \throw If \a a[ *i* ] == NULL. - * \throw If the coordinates array is not set in none of the meshes. - * \throw If \a a[ *i* ]->getMeshDimension() < 0. - * \throw If the meshes in \a a are of different dimension (getMeshDimension()). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector& a) -{ - std::size_t sz=a.size(); - if(sz==0) - return MergeUMeshesLL(a); - for(std::size_t ii=0;ii > bb(sz); - std::vector< const MEDCouplingUMesh * > aa(sz); - int spaceDim=-3; - for(std::size_t i=0;igetCoords(); - if(coo) - spaceDim=coo->getNumberOfComponents(); - } - if(spaceDim==-3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : no spaceDim specified ! unable to perform merge !"); - for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); - aa[i]=bb[i]; - } - return MergeUMeshesLL(aa); -} - -/// @cond INTERNAL - -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - int meshDim=(*it)->getMeshDimension(); - int nbOfCells=(*it)->getNumberOfCells(); - int meshLgth=(*it++)->getMeshLength(); - for(;it!=a.end();it++) - { - if(meshDim!=(*it)->getMeshDimension()) - throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !"); - nbOfCells+=(*it)->getNumberOfCells(); - meshLgth+=(*it)->getMeshLength(); - } - std::vector aps(a.size()); - std::copy(a.begin(),a.end(),aps.begin()); - MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("merge",meshDim); - ret->setCoords(pts); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - c->alloc(meshLgth,1); - int *cPtr=c->getPointer(); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); - cI->alloc(nbOfCells+1,1); - int *cIPtr=cI->getPointer(); - *cIPtr++=0; - int offset=0; - int offset2=0; - for(it=a.begin();it!=a.end();it++) - { - int curNbOfCell=(*it)->getNumberOfCells(); - const int *curCI=(*it)->_nodal_connec_index->getConstPointer(); - const int *curC=(*it)->_nodal_connec->getConstPointer(); - cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus(),offset)); - for(int j=0;jgetNumberOfNodes(); - } - // - ret->setConnectivity(c,cI,true); - return ret.retn(); -} - -/// @endcond - -/*! - * Creates a new MEDCouplingUMesh by concatenating cells of two given meshes of same - * dimension and sharing the node coordinates array. - * All cells of the first mesh precede all cells of the second mesh - * within the result mesh. - * \param [in] mesh1 - the first mesh. - * \param [in] mesh2 - the second mesh. - * \return MEDCouplingUMesh * - the result mesh. It is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If \a mesh1 == NULL or \a mesh2 == NULL. - * \throw If the meshes do not share the node coordinates array. - * \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0. - * \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension(). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=mesh1; tmp[1]=mesh2; - return MergeUMeshesOnSameCoords(tmp); -} - -/*! - * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same - * dimension and sharing the node coordinates array. - * All cells of the *i*-th mesh precede all cells of the - * (*i*+1)-th mesh within the result mesh. - * \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate. - * \return MEDCouplingUMesh * - the result mesh. It is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If \a a.size() == 0. - * \throw If \a a[ *i* ] == NULL. - * \throw If the meshes do not share the node coordinates array. - * \throw If \a a[ *i* ]->getMeshDimension() < 0. - * \throw If the meshes in \a a are of different dimension (getMeshDimension()). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector& meshes) -{ - if(meshes.empty()) - throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty."); - for(std::size_t ii=0;iigetCoords(); - int meshDim=meshes.front()->getMeshDimension(); - std::vector::const_iterator iter=meshes.begin(); - int meshLgth=0; - int meshIndexLgth=0; - for(;iter!=meshes.end();iter++) - { - if(coords!=(*iter)->getCoords()) - throw INTERP_KERNEL::Exception("meshes does not share the same coords ! Try using tryToShareSameCoords method !"); - if(meshDim!=(*iter)->getMeshDimension()) - throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, FuseUMeshesOnSameCoords impossible !"); - meshLgth+=(*iter)->getMeshLength(); - meshIndexLgth+=(*iter)->getNumberOfCells(); - } - MEDCouplingAutoRefCountObjectPtr nodal=DataArrayInt::New(); - nodal->alloc(meshLgth,1); - int *nodalPtr=nodal->getPointer(); - MEDCouplingAutoRefCountObjectPtr nodalIndex=DataArrayInt::New(); - nodalIndex->alloc(meshIndexLgth+1,1); - int *nodalIndexPtr=nodalIndex->getPointer(); - int offset=0; - for(iter=meshes.begin();iter!=meshes.end();iter++) - { - const int *nod=(*iter)->getNodalConnectivity()->getConstPointer(); - const int *index=(*iter)->getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=(*iter)->getNumberOfCells(); - int meshLgth2=(*iter)->getMeshLength(); - nodalPtr=std::copy(nod,nod+meshLgth2,nodalPtr); - if(iter!=meshes.begin()) - nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus(),offset)); - else - nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr); - offset+=meshLgth2; - } - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName("merge"); - ret->setMeshDimension(meshDim); - ret->setConnectivity(nodal,nodalIndex,true); - ret->setCoords(coords); - return ret; -} - -/*! - * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same - * dimension and sharing the node coordinates array. Cells of the *i*-th mesh precede - * cells of the (*i*+1)-th mesh within the result mesh. Duplicates of cells are - * removed from \a this mesh and arrays mapping between new and old cell ids in "Old to - * New" mode are returned for each input mesh. - * \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate. - * \param [in] compType - specifies a cell comparison technique. For meaning of its - * valid values [0,1,2], see zipConnectivityTraducer(). - * \param [in,out] corr - an array of DataArrayInt, of the same size as \a - * meshes. The *i*-th array describes cell ids mapping for \a meshes[ *i* ] - * mesh. The caller is to delete each of the arrays using decrRef() as it is - * no more needed. - * \return MEDCouplingUMesh * - the result mesh. It is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If \a meshes.size() == 0. - * \throw If \a meshes[ *i* ] == NULL. - * \throw If the meshes do not share the node coordinates array. - * \throw If \a meshes[ *i* ]->getMeshDimension() < 0. - * \throw If the \a meshes are of different dimension (getMeshDimension()). - * \throw If the nodal connectivity of cells of any of \a meshes is not defined. - * \throw If the nodal connectivity any of \a meshes includes an invalid id. - */ -MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr) -{ - //All checks are delegated to MergeUMeshesOnSameCoords - MEDCouplingAutoRefCountObjectPtr ret=MergeUMeshesOnSameCoords(meshes); - MEDCouplingAutoRefCountObjectPtr o2n=ret->zipConnectivityTraducer(compType); - corr.resize(meshes.size()); - std::size_t nbOfMeshes=meshes.size(); - int offset=0; - const int *o2nPtr=o2n->getConstPointer(); - for(std::size_t i=0;igetNumberOfCells(); - tmp->alloc(curNbOfCells,1); - std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer()); - offset+=curNbOfCells; - tmp->setName(meshes[i]->getName()); - corr[i]=tmp; - } - return ret.retn(); -} - -/*! - * Makes all given meshes share the nodal connectivity array. The common connectivity - * array is created by concatenating the connectivity arrays of all given meshes. All - * the given meshes must be of the same space dimension but dimension of cells **can - * differ**. This method is particulary useful in MEDLoader context to build a \ref - * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying - * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. - * \param [in,out] meshes - a vector of meshes to update. - * \throw If any of \a meshes is NULL. - * \throw If the coordinates array is not set in any of \a meshes. - * \throw If the nodal connectivity of cells is not defined in any of \a meshes. - * \throw If \a meshes are of different space dimension. - */ -void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector& meshes) -{ - std::size_t sz=meshes.size(); - if(sz==0 || sz==1) - return; - std::vector< const DataArrayDouble * > coords(meshes.size()); - std::vector< const DataArrayDouble * >::iterator it2=coords.begin(); - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++,it2++) - { - if((*it)) - { - (*it)->checkConnectivityFullyDefined(); - const DataArrayDouble *coo=(*it)->getCoords(); - if(coo) - *it2=coo; - else - { - std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size(); - oss << " has no coordinate array defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size(); - oss << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - MEDCouplingAutoRefCountObjectPtr res=DataArrayDouble::Aggregate(coords); - std::vector::const_iterator it=meshes.begin(); - int offset=(*it)->getNumberOfNodes(); - (*it++)->setCoords(res); - for(;it!=meshes.end();it++) - { - int oldNumberOfNodes=(*it)->getNumberOfNodes(); - (*it)->setCoords(res); - (*it)->shiftNodeNumbersInConn(offset); - offset+=oldNumberOfNodes; - } -} - -/*! - * Merges nodes coincident with a given precision within all given meshes that share - * the nodal connectivity array. The given meshes **can be of different** mesh - * dimension. This method is particulary useful in MEDLoader context to build a \ref - * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying - * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. - * \param [in,out] meshes - a vector of meshes to update. - * \param [in] eps - the precision used to detect coincident nodes (infinite norm). - * \throw If any of \a meshes is NULL. - * \throw If the \a meshes do not share the same node coordinates array. - * \throw If the nodal connectivity of cells is not defined in any of \a meshes. - */ -void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps) -{ - if(meshes.empty()) - return ; - std::set s; - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++) - { - if(*it) - s.insert((*it)->getCoords()); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << " the element #" << std::distance(meshes.begin(),it) << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(s.size()!=1) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << ", it appears that they do not share the same instance of DataArrayDouble for coordiantes ! tryToShareSameCoordsPermute method can help to reach that !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayDouble *coo=*(s.begin()); - if(!coo) - return; - // - DataArrayInt *comm,*commI; - coo->findCommonTuples(eps,-1,comm,commI); - MEDCouplingAutoRefCountObjectPtr tmp1(comm),tmp2(commI); - int oldNbOfNodes=coo->getNumberOfTuples(); - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes); - if(oldNbOfNodes==newNbOfNodes) - return ; - MEDCouplingAutoRefCountObjectPtr newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes); - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++) - { - (*it)->renumberNodesInConn(o2n->getConstPointer()); - (*it)->setCoords(newCoords); - } -} - -/*! - * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [ \a connBg , \a connEnd ) and returns its extruded cell by inserting the result at the end of ret. - * \param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset - * \param isQuad specifies the policy of connectivity. - * @ret in/out parameter in which the result will be append - */ -void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret) -{ - INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType); - ret.push_back(cm.getExtrudedType()); - int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev; - switch(flatType) - { - case INTERP_KERNEL::NORM_POINT1: - { - ret.push_back(connBg[1]); - ret.push_back(connBg[1]+nbOfNodesPerLev); - break; - } - case INTERP_KERNEL::NORM_SEG2: - { - int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz}; - ret.insert(ret.end(),conn,conn+4); - break; - } - case INTERP_KERNEL::NORM_SEG3: - { - int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev}; - ret.insert(ret.end(),conn,conn+8); - break; - } - case INTERP_KERNEL::NORM_QUAD4: - { - int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz}; - ret.insert(ret.end(),conn,conn+8); - break; - } - case INTERP_KERNEL::NORM_TRI3: - { - int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz}; - ret.insert(ret.end(),conn,conn+6); - break; - } - case INTERP_KERNEL::NORM_TRI6: - { - int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz, - connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev}; - ret.insert(ret.end(),conn,conn+15); - break; - } - case INTERP_KERNEL::NORM_QUAD8: - { - int conn[20]={ - connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz, - connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz, - connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev - }; - ret.insert(ret.end(),conn,conn+20); - break; - } - case INTERP_KERNEL::NORM_POLYGON: - { - std::back_insert_iterator< std::vector > ii(ret); - std::copy(connBg+1,connEnd,ii); - *ii++=-1; - std::reverse_iterator rConnBg(connEnd); - std::reverse_iterator rConnEnd(connBg+1); - std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus(),deltaz)); - std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd); - for(std::size_t i=0;i0.); -} - -/*! - * The polyhedron is specfied by its connectivity nodes in [ \a begin , \a end ). - */ -bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords) -{ - std::vector > edges; - std::size_t nbOfFaces=std::count(begin,end,-1)+1; - const int *bgFace=begin; - for(std::size_t i=0;i p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); - if(std::find(edges.begin(),edges.end(),p1)!=edges.end()) - return false; - edges.push_back(p1); - } - bgFace=endFace+1; - } - return INTERP_KERNEL::calculateVolumeForPolyh2(begin,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION; -} - -/*! - * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [ \a begin , \a end ). - */ -bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords) -{ - double vec0[3],vec1[3]; - std::size_t sz=std::distance(begin,end); - if(sz%2!=0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented : the length of nodal connectivity of extruded cell is not even !"); - int nbOfNodes=(int)sz/2; - INTERP_KERNEL::areaVectorOfPolygon(begin,nbOfNodes,coords,vec0); - const double *pt0=coords+3*begin[0]; - const double *pt1=coords+3*begin[nbOfNodes]; - vec1[0]=pt1[0]-pt0[0]; vec1[1]=pt1[1]-pt0[1]; vec1[2]=pt1[2]-pt0[2]; - return (vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2])<0.; -} - -void MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end) -{ - std::size_t sz=std::distance(begin,end); - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - std::size_t nbOfNodes(sz/2); - std::copy(begin,end,(int *)tmp); - for(std::size_t j=1;j(begin,4,coords,vec0); - const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[4]; - return (vec0[0]*(pt1[0]-pt0[0])+vec0[1]*(pt1[1]-pt0[1])+vec0[2]*(pt1[2]-pt0[2]))<0.; -} - -/*! - * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [ \b begin , \b end ) - * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to - * a 2D space. - * - * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. - * \param [in] coords the coordinates with nb of components exactly equal to 3 - * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell - * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded) - * \param [out] res the result is put at the end of the vector without any alteration of the data. - */ -void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) -{ - int nbFaces=std::count(begin+1,end,-1)+1; - MEDCouplingAutoRefCountObjectPtr v=DataArrayDouble::New(); v->alloc(nbFaces,3); - double *vPtr=v->getPointer(); - MEDCouplingAutoRefCountObjectPtr p=DataArrayDouble::New(); p->alloc(nbFaces,1); - double *pPtr=p->getPointer(); - const int *stFaceConn=begin+1; - for(int i=0;igetConstPointer(),stFaceConn,endFaceConn,vPtr,pPtr); - stFaceConn=endFaceConn+1; - } - pPtr=p->getPointer(); vPtr=v->getPointer(); - DataArrayInt *comm1=0,*commI1=0; - v->findCommonTuples(eps,-1,comm1,commI1); - MEDCouplingAutoRefCountObjectPtr comm1Auto(comm1),commI1Auto(commI1); - const int *comm1Ptr=comm1->getConstPointer(); - const int *commI1Ptr=commI1->getConstPointer(); - int nbOfGrps1=commI1Auto->getNumberOfTuples()-1; - res->pushBackSilent((int)INTERP_KERNEL::NORM_POLYHED); - // - MEDCouplingAutoRefCountObjectPtr mm=MEDCouplingUMesh::New("",3); - mm->setCoords(const_cast(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1); - mm->finishInsertingCells(); - // - for(int i=0;i tmpgrp2=p->selectByTupleId(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]); - DataArrayInt *comm2=0,*commI2=0; - tmpgrp2->findCommonTuples(eps,-1,comm2,commI2); - MEDCouplingAutoRefCountObjectPtr comm2Auto(comm2),commI2Auto(commI2); - const int *comm2Ptr=comm2->getConstPointer(); - const int *commI2Ptr=commI2->getConstPointer(); - int nbOfGrps2=commI2Auto->getNumberOfTuples()-1; - for(int j=0;jinsertAtTheEnd(begin,end); - res->pushBackSilent(-1); - } - else - { - int pointId=comm1Ptr[commI1Ptr[i]+comm2Ptr[commI2Ptr[j]]]; - MEDCouplingAutoRefCountObjectPtr ids2=comm2->selectByTupleId2(commI2Ptr[j],commI2Ptr[j+1],1); - ids2->transformWithIndArr(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]); - DataArrayInt *tmp0=DataArrayInt::New(),*tmp1=DataArrayInt::New(),*tmp2=DataArrayInt::New(),*tmp3=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mm2=mm->buildDescendingConnectivity(tmp0,tmp1,tmp2,tmp3); tmp0->decrRef(); tmp1->decrRef(); tmp2->decrRef(); tmp3->decrRef(); - MEDCouplingAutoRefCountObjectPtr mm3=static_cast(mm2->buildPartOfMySelf(ids2->begin(),ids2->end(),true)); - MEDCouplingAutoRefCountObjectPtr idsNodeTmp=mm3->zipCoordsTraducer(); - MEDCouplingAutoRefCountObjectPtr idsNode=idsNodeTmp->invertArrayO2N2N2O(mm3->getNumberOfNodes()); - const int *idsNodePtr=idsNode->getConstPointer(); - double center[3]; center[0]=pPtr[pointId]*vPtr[3*vecId]; center[1]=pPtr[pointId]*vPtr[3*vecId+1]; center[2]=pPtr[pointId]*vPtr[3*vecId+2]; - double vec[3]; vec[0]=vPtr[3*vecId+1]; vec[1]=-vPtr[3*vecId]; vec[2]=0.; - double norm=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]; - if(std::abs(norm)>eps) - { - double angle=INTERP_KERNEL::EdgeArcCircle::SafeAsin(norm); - mm3->rotate(center,vec,angle); - } - mm3->changeSpaceDimension(2); - MEDCouplingAutoRefCountObjectPtr mm4=mm3->buildSpreadZonesWithPoly(); - const int *conn4=mm4->getNodalConnectivity()->getConstPointer(); - const int *connI4=mm4->getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=mm4->getNumberOfCells(); - for(int k=0;kpushBackSilent(idsNodePtr[*work]); - res->pushBackSilent(-1); - } - } - } - } - res->popBackSilent(); -} - -/*! - * This method computes the normalized vector of the plane and the pos of the point belonging to the plane and the line defined by the vector going - * through origin. The plane is defined by its nodal connectivity [ \b begin, \b end ). - * - * \param [in] eps below that value the dot product of 2 vectors is considered as colinears - * \param [in] coords coordinates expected to have 3 components. - * \param [in] begin start of the nodal connectivity of the face. - * \param [in] end end of the nodal connectivity (excluded) of the face. - * \param [out] v the normalized vector of size 3 - * \param [out] p the pos of plane - */ -void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p) -{ - std::size_t nbPoints=std::distance(begin,end); - if(nbPoints<3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeVecAndPtOfFace : < of 3 points in face ! not able to find a plane on that face !"); - double vec[3]={0.,0.,0.}; - std::size_t j=0; - bool refFound=false; - for(;jeps) - { - refFound=true; - vec[0]/=norm; vec[1]/=norm; vec[2]/=norm; - } - } - for(std::size_t i=j;ieps) - { - v[0]/=norm; v[1]/=norm; v[2]/=norm; - *p=v[0]*coords[3*begin[i]]+v[1]*coords[3*begin[i]+1]+v[2]*coords[3*begin[i]+2]; - return ; - } - } - throw INTERP_KERNEL::Exception("Not able to find a normal vector of that 3D face !"); -} - -/*! - * This method tries to obtain a well oriented polyhedron. - * If the algorithm fails, an exception will be thrown. - */ -void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) -{ - std::list< std::pair > edgesOK,edgesFinished; - std::size_t nbOfFaces=std::count(begin,end,-1)+1; - std::vector isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented - isPerm[0]=true; - int *bgFace=begin,*endFace=std::find(begin+1,end,-1); - std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace); - for(std::size_t l=0;l p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); } - // - while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end()) - { - bgFace=begin; - std::size_t smthChanged=0; - for(std::size_t i=0;i p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); - std::pair p2(p1.second,p1.first); - bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end(); - bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end(); - if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; } - } - if(isPerm[i]) - { - if(!b) - std::reverse(bgFace+1,endFace); - for(std::size_t j=0;j p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); - std::pair p2(p1.second,p1.first); - if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end()) - { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end()) - { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - std::list< std::pair >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2); - if(it!=edgesOK.end()) - { - edgesOK.erase(it); - edgesFinished.push_back(p1); - } - else - edgesOK.push_back(p1); - } - } - } - bgFace=endFace+1; - } - if(smthChanged==0) - { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); } - } - if(!edgesOK.empty()) - { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); } - if(INTERP_KERNEL::calculateVolumeForPolyh2(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION) - {//not lucky ! The first face was not correctly oriented : reorient all faces... - bgFace=begin; - for(std::size_t i=0;igetNumberOfNodes()); - const int *n2oPtr(n2o->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); - skin->getReverseNodalConnectivity(revNodal,revNodalI); - const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); - const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); - const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); - int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_POLYGON; - if(nbOfNodesExpected<1) - return ret.retn(); - int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); - *work++=n2oPtr[prevNode]; - for(int i=1;i conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); - conn.erase(prevNode); - if(conn.size()==1) - { - int curNode(*(conn.begin())); - *work++=n2oPtr[curNode]; - std::set shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); - shar.erase(prevCell); - if(shar.size()==1) - { - prevCell=*(shar.begin()); - prevNode=curNode; - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !"); - } - return ret.retn(); -} - -DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const -{ - int nbOfNodesExpected(skin->getNumberOfNodes()); - int nbOfTurn(nbOfNodesExpected/2); - const int *n2oPtr(n2o->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); - skin->getReverseNodalConnectivity(revNodal,revNodalI); - const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); - const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); - const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); - int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_QPOLYG; - if(nbOfNodesExpected<1) - return ret.retn(); - int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); - *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++; - for(int i=1;i conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); - conn.erase(prevNode); - if(conn.size()==1) - { - int curNode(*(conn.begin())); - *work=n2oPtr[curNode]; - std::set shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); - shar.erase(prevCell); - if(shar.size()==1) - { - int curCell(*(shar.begin())); - work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]]; - prevCell=curCell; - prevNode=curNode; - work++; - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !"); - } - return ret.retn(); -} - -/*! - * This method makes the assumption spacedimension == meshdimension == 2. - * This method works only for linear cells. - * - * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) - */ -DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr skin(computeSkin()); - int oldNbOfNodes(skin->getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr o2n(skin->zipCoordsTraducer()); - int nbOfNodesExpected(skin->getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes)); - int nbCells(skin->getNumberOfCells()); - if(nbCells==nbOfNodesExpected) - return buildUnionOf2DMeshLinear(skin,n2o); - else if(2*nbCells==nbOfNodesExpected) - return buildUnionOf2DMeshQuadratic(skin,n2o); - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !"); -} - -/*! - * This method makes the assumption spacedimension == meshdimension == 3. - * This method works only for linear cells. - * - * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYHED in pos#0) - */ -DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf3DMesh : meshdimension, spacedimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr m=computeSkin(); - const int *conn=m->getNodalConnectivity()->getConstPointer(); - const int *connI=m->getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1); - int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYHED; - if(nbOfCells<1) - return ret.retn(); - work=std::copy(conn+connI[0]+1,conn+connI[1],work); - for(int i=1;igetMeshDimension(); - ParaMEDMEM::DataArrayInt* indexr=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); - this->getReverseNodalConnectivity(revConn,indexr); - const int* indexr_ptr=indexr->getConstPointer(); - const int* revConn_ptr=revConn->getConstPointer(); - - const ParaMEDMEM::DataArrayInt* index; - const ParaMEDMEM::DataArrayInt* conn; - conn=this->getNodalConnectivity(); // it includes a type as the 1st element!!! - index=this->getNodalConnectivityIndex(); - int nbCells=this->getNumberOfCells(); - const int* index_ptr=index->getConstPointer(); - const int* conn_ptr=conn->getConstPointer(); - - //creating graph arcs (cell to cell relations) - //arcs are stored in terms of (index,value) notation - // 0 3 5 6 6 - // 1 2 3 2 3 3 - // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) - // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell - - //warning here one node have less than or equal effective number of cell with it - //but cell could have more than effective nodes - //because other equals nodes in other domain (with other global inode) - std::vector cell2cell_index(nbCells+1,0); - std::vector cell2cell; - cell2cell.reserve(3*nbCells); - - for (int icell=0; icell counter; - for (int iconn=index_ptr[icell]+1; iconn::iterator iter=counter.find(icell2); - if (iter!=counter.end()) (iter->second)++; - else counter.insert(std::make_pair(icell2,1)); - } - } - for (std::map::const_iterator iter=counter.begin(); - iter!=counter.end(); iter++) - if (iter->second >= meshDim) - { - cell2cell_index[icell+1]++; - cell2cell.push_back(iter->first); - } - } - indexr->decrRef(); - revConn->decrRef(); - cell2cell_index[0]=0; - for (int icell=0; icell\n"; - ofs << " \n"; - ofs << " \n" << pointData << std::endl; - ofs << " \n"; - ofs << " \n" << cellData << std::endl; - ofs << " \n"; - ofs << " \n"; - if(getSpaceDimension()==3) - _coords->writeVTK(ofs,8,"Points",byteData); - else - { - MEDCouplingAutoRefCountObjectPtr coo=_coords->changeNbOfComponents(3,0.); - coo->writeVTK(ofs,8,"Points",byteData); - } - ofs << " \n"; - ofs << " \n"; - const int *cPtr=_nodal_connec->getConstPointer(); - const int *cIPtr=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr faceoffsets=DataArrayInt::New(); faceoffsets->alloc(nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr types=DataArrayInt::New(); types->alloc(nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr offsets=DataArrayInt::New(); offsets->alloc(nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr connectivity=DataArrayInt::New(); connectivity->alloc(_nodal_connec->getNumberOfTuples()-nbOfCells,1); - int *w1=faceoffsets->getPointer(),*w2=types->getPointer(),*w3=offsets->getPointer(),*w4=connectivity->getPointer(); - int szFaceOffsets=0,szConn=0; - for(int i=0;i c(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1]); c.erase(-1); - *w3=szConn+(int)c.size(); szConn+=(int)c.size(); - w4=std::copy(c.begin(),c.end(),w4); - } - } - types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE+1); - types->writeVTK(ofs,8,"UInt8","types",byteData); - offsets->writeVTK(ofs,8,"Int32","offsets",byteData); - if(szFaceOffsets!=0) - {//presence of Polyhedra - connectivity->reAlloc(szConn); - faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets",byteData); - MEDCouplingAutoRefCountObjectPtr faces=DataArrayInt::New(); faces->alloc(szFaceOffsets,1); - w1=faces->getPointer(); - for(int i=0;iwriteVTK(ofs,8,"Int32","faces",byteData); - } - connectivity->writeVTK(ofs,8,"Int32","connectivity",byteData); - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingUMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; - if(_mesh_dim==-2) - { stream << " Not set !"; return ; } - stream << " Mesh dimension : " << _mesh_dim << "."; - if(_mesh_dim==-1) - return ; - if(!_coords) - { stream << " No coordinates set !"; return ; } - if(!_coords->isAllocated()) - { stream << " Coordinates set but not allocated !"; return ; } - stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; - stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; - if(!_nodal_connec_index) - { stream << std::endl << "Nodal connectivity NOT set !"; return ; } - if(!_nodal_connec_index->isAllocated()) - { stream << std::endl << "Nodal connectivity set but not allocated !"; return ; } - int lgth=_nodal_connec_index->getNumberOfTuples(); - int cpt=_nodal_connec_index->getNumberOfComponents(); - if(cpt!=1 || lgth<1) - return ; - stream << std::endl << "Number of cells : " << lgth-1 << "."; -} - -std::string MEDCouplingUMesh::getVTKDataSetType() const -{ - return std::string("UnstructuredGrid"); -} - -std::string MEDCouplingUMesh::getVTKFileExtension() const -{ - return std::string("vtu"); -} - -/*! - * Partitions the first given 2D mesh using the second given 2D mesh as a tool, and - * returns a result mesh constituted by polygons. - * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains - * all nodes from m2. - * The meshes should be in 2D space. In - * addition, returns two arrays mapping cells of the result mesh to cells of the input - * meshes. - * \param [in] m1 - the first input mesh which is a partitioned object. The mesh must be so that each point in the space covered by \a m1 - * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) - * \param [in] m2 - the second input mesh which is a partition tool. The mesh must be so that each point in the space covered by \a m2 - * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) - * \param [in] eps - precision used to detect coincident mesh entities. - * \param [out] cellNb1 - a new instance of DataArrayInt holding for each result - * cell an id of the cell of \a m1 it comes from. The caller is to delete - * this array using decrRef() as it is no more needed. - * \param [out] cellNb2 - a new instance of DataArrayInt holding for each result - * cell an id of the cell of \a m2 it comes from. -1 value means that a - * result cell comes from a cell (or part of cell) of \a m1 not overlapped by - * any cell of \a m2. The caller is to delete this array using decrRef() as - * it is no more needed. - * \return MEDCouplingUMesh * - the result 2D mesh which is a new instance of - * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it - * is no more needed. - * \throw If the coordinates array is not set in any of the meshes. - * \throw If the nodal connectivity of cells is not defined in any of the meshes. - * \throw If any of the meshes is not a 2D mesh in 2D space. - * - * \sa conformize2D, mergeNodes - */ -MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, - double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) -{ - if(!m1 || !m2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes : input meshes must be not NULL !"); - m1->checkFullyDefined(); - m2->checkFullyDefined(); - if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2 with meshdim equal to 2 and spaceDim equal to 2 too!"); - - // Step 1: compute all edge intersections (new nodes) - std::vector< std::vector > intersectEdge1, colinear2, subDiv2; - MEDCouplingUMesh *m1Desc=0,*m2Desc=0; // descending connec. meshes - DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0; - std::vector addCoo,addCoordsQuadratic; // coordinates of newly created nodes - IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2, - m1Desc,desc1,descIndx1,revDesc1,revDescIndx1, - addCoo, m2Desc,desc2,descIndx2,revDesc2,revDescIndx2); - revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef(); - MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2); - MEDCouplingAutoRefCountObjectPtr dd5(m1Desc),dd6(m2Desc); - - // Step 2: re-order newly created nodes according to the ordering found in m2 - std::vector< std::vector > intersectEdge2; - BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2); - subDiv2.clear(); dd5=0; dd6=0; - - // Step 3: - std::vector cr,crI; //no DataArrayInt because interface with Geometric2D - std::vector cNb1,cNb2; //no DataArrayInt because interface with Geometric2D - BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo, - /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2); - - // Step 4: Prepare final result: - MEDCouplingAutoRefCountObjectPtr addCooDa(DataArrayDouble::New()); - addCooDa->alloc((int)(addCoo.size())/2,2); - std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer()); - MEDCouplingAutoRefCountObjectPtr addCoordsQuadraticDa(DataArrayDouble::New()); - addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2); - std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer()); - std::vector coordss(4); - coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa; - MEDCouplingAutoRefCountObjectPtr coo(DataArrayDouble::Aggregate(coordss)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New("Intersect2D",2)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer()); - MEDCouplingAutoRefCountObjectPtr connI(DataArrayInt::New()); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer()); - MEDCouplingAutoRefCountObjectPtr c1(DataArrayInt::New()); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); - MEDCouplingAutoRefCountObjectPtr c2(DataArrayInt::New()); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); - ret->setConnectivity(conn,connI,true); - ret->setCoords(coo); - cellNb1=c1.retn(); cellNb2=c2.retn(); - return ret.retn(); -} - -/// @cond INTERNAL - -bool IsColinearOfACellOf(const std::vector< std::vector >& intersectEdge1, const std::vector& candidates, int start, int stop, int& retVal) -{ - if(candidates.empty()) - return false; - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - { - const std::vector& pool(intersectEdge1[*it]); - int tmp[2]; tmp[0]=start; tmp[1]=stop; - if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end()) - { - retVal=*it+1; - return true; - } - tmp[0]=stop; tmp[1]=start; - if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end()) - { - retVal=-*it-1; - return true; - } - } - return false; -} - -MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector >& intersectEdge2, const DataArrayDouble *coords1, const std::vector& addCoo, const std::map& mergedNodes, const std::vector< std::vector >& colinear2, const std::vector< std::vector >& intersectEdge1, - MEDCouplingAutoRefCountObjectPtr& idsInRetColinear, MEDCouplingAutoRefCountObjectPtr& idsInMesh1DForIdsInRetColinear) -{ - idsInRetColinear=DataArrayInt::New(); idsInRetColinear->alloc(0,1); - idsInMesh1DForIdsInRetColinear=DataArrayInt::New(); idsInMesh1DForIdsInRetColinear->alloc(0,1); - int nCells(mesh1D->getNumberOfCells()); - if(nCells!=(int)intersectEdge2.size()) - throw INTERP_KERNEL::Exception("BuildMesh1DCutFrom : internal error # 1 !"); - const DataArrayDouble *coo2(mesh1D->getCoords()); - const int *c(mesh1D->getNodalConnectivity()->begin()),*ci(mesh1D->getNodalConnectivityIndex()->begin()); - const double *coo2Ptr(coo2->begin()); - int offset1(coords1->getNumberOfTuples()); - int offset2(offset1+coo2->getNumberOfTuples()); - int offset3(offset2+addCoo.size()/2); - std::vector addCooQuad; - MEDCouplingAutoRefCountObjectPtr cOut(DataArrayInt::New()),ciOut(DataArrayInt::New()); cOut->alloc(0,1); ciOut->alloc(1,1); ciOut->setIJ(0,0,0); - int tmp[4],cicnt(0),kk(0); - for(int i=0;i,int> m; - INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coo2Ptr,m)); - const std::vector& subEdges(intersectEdge2[i]); - int nbSubEdge(subEdges.size()/2); - for(int j=0;j n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)); - MEDCouplingAutoRefCountObjectPtr e2(e->buildEdgeLyingOnMe(n1,n2)); - INTERP_KERNEL::Edge *e2Ptr(e2); - std::map::const_iterator itm; - if(dynamic_cast(e2Ptr)) - { - tmp[0]=INTERP_KERNEL::NORM_SEG3; - itm=mergedNodes.find(subEdges[2*j]); - tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; - itm=mergedNodes.find(subEdges[2*j+1]); - tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; - tmp[3]=offset3+(int)addCooQuad.size()/2; - double tmp2[2]; - e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2); - cicnt+=4; - cOut->insertAtTheEnd(tmp,tmp+4); - ciOut->pushBackSilent(cicnt); - } - else - { - tmp[0]=INTERP_KERNEL::NORM_SEG2; - itm=mergedNodes.find(subEdges[2*j]); - tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; - itm=mergedNodes.find(subEdges[2*j+1]); - tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; - cicnt+=3; - cOut->insertAtTheEnd(tmp,tmp+3); - ciOut->pushBackSilent(cicnt); - } - int tmp00; - if(IsColinearOfACellOf(intersectEdge1,colinear2[i],tmp[1],tmp[2],tmp00)) - { - idsInRetColinear->pushBackSilent(kk); - idsInMesh1DForIdsInRetColinear->pushBackSilent(tmp00); - } - } - e->decrRef(); - } - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New(mesh1D->getName(),1)); - ret->setConnectivity(cOut,ciOut,true); - MEDCouplingAutoRefCountObjectPtr arr3(DataArrayDouble::New()); - arr3->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); - MEDCouplingAutoRefCountObjectPtr arr4(DataArrayDouble::New()); arr4->useArray(&addCooQuad[0],false,C_DEALLOC,(int)addCooQuad.size()/2,2); - std::vector coordss(4); - coordss[0]=coords1; coordss[1]=mesh1D->getCoords(); coordss[2]=arr3; coordss[3]=arr4; - MEDCouplingAutoRefCountObjectPtr arr(DataArrayDouble::Aggregate(coordss)); - ret->setCoords(arr); - return ret.retn(); -} - -MEDCouplingUMesh *BuildRefined2DCellLinear(const DataArrayDouble *coords, const int *descBg, const int *descEnd, const std::vector< std::vector >& intersectEdge1) -{ - std::vector allEdges; - for(const int *it2(descBg);it2!=descEnd;it2++) - { - const std::vector& edge1(intersectEdge1[std::abs(*it2)-1]); - if(*it2>0) - allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); - else - allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); - } - std::size_t nb(allEdges.size()); - if(nb%2!=0) - throw INTERP_KERNEL::Exception("BuildRefined2DCellLinear : internal error 1 !"); - std::size_t nbOfEdgesOf2DCellSplit(nb/2); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New("",2)); - ret->setCoords(coords); - ret->allocateCells(1); - std::vector connOut(nbOfEdgesOf2DCellSplit); - for(std::size_t kk=0;kkinsertNextCell(INTERP_KERNEL::NORM_POLYGON,connOut.size(),&connOut[0]); - return ret.retn(); -} - -MEDCouplingUMesh *BuildRefined2DCellQuadratic(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector >& intersectEdge1) -{ - const int *c(mesh2D->getNodalConnectivity()->begin()),*ci(mesh2D->getNodalConnectivityIndex()->begin()); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[cellIdInMesh2D]])); - std::size_t ii(0); - unsigned sz(cm.getNumberOfSons2(c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1)); - if(sz!=std::distance(descBg,descEnd)) - throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 1 !"); - INTERP_KERNEL::AutoPtr tmpPtr(new int[ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]]); - std::vector allEdges,centers; - const double *coordsPtr(coords->begin()); - MEDCouplingAutoRefCountObjectPtr addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); - int offset(coords->getNumberOfTuples()); - for(const int *it2(descBg);it2!=descEnd;it2++,ii++) - { - INTERP_KERNEL::NormalizedCellType typeOfSon; - cm.fillSonCellNodalConnectivity2(ii,c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1,tmpPtr,typeOfSon); - const std::vector& edge1(intersectEdge1[std::abs(*it2)-1]); - if(*it2>0) - allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); - else - allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); - if(edge1.size()==2) - centers.push_back(tmpPtr[2]);//special case where no subsplit of edge -> reuse the original center. - else - {//the current edge has been subsplit -> create corresponding centers. - std::size_t nbOfCentersToAppend(edge1.size()/2); - std::map< MEDCouplingAutoRefCountObjectPtr,int> m; - MEDCouplingAutoRefCountObjectPtr ee(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpPtr,coordsPtr,m)); - std::vector::const_iterator it3(allEdges.end()-edge1.size()); - for(std::size_t k=0;kgetMiddleOfPoints(aa,bb,tmpp); - addCoo->insertAtTheEnd(tmpp,tmpp+2); - centers.push_back(offset+k); - } - } - } - std::size_t nb(allEdges.size()); - if(nb%2!=0) - throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 2 !"); - std::size_t nbOfEdgesOf2DCellSplit(nb/2); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New("",2)); - if(addCoo->empty()) - ret->setCoords(coords); - else - { - addCoo->rearrange(2); - addCoo=DataArrayDouble::Aggregate(coords,addCoo); - ret->setCoords(addCoo); - } - ret->allocateCells(1); - std::vector connOut(nbOfEdgesOf2DCellSplit); - for(std::size_t kk=0;kkinsertNextCell(INTERP_KERNEL::NORM_QPOLYG,connOut.size(),&connOut[0]); - return ret.retn(); -} - -/*! - * This method creates a refinement of a cell in \a mesh2D. Those cell is defined by descending connectivity and the sorted subdivided nodal connectivity - * of those edges. - * - * \param [in] mesh2D - The origin 2D mesh. \b Warning \b coords are not those of \a mesh2D. But mesh2D->getCoords()==coords[:mesh2D->getNumberOfNodes()] - */ -MEDCouplingUMesh *BuildRefined2DCell(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector >& intersectEdge1) -{ - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(mesh2D->getTypeOfCell(cellIdInMesh2D))); - if(!cm.isQuadratic()) - return BuildRefined2DCellLinear(coords,descBg,descEnd,intersectEdge1); - else - return BuildRefined2DCellQuadratic(coords,mesh2D,cellIdInMesh2D,descBg,descEnd,intersectEdge1); -} - -void AddCellInMesh2D(MEDCouplingUMesh *mesh2D, const std::vector& conn, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edges) -{ - bool isQuad(false); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=edges.begin();it!=edges.end();it++) - { - const INTERP_KERNEL::Edge *ee(*it); - if(dynamic_cast(ee)) - isQuad=true; - } - if(!isQuad) - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,conn.size(),&conn[0]); - else - { - const double *coo(mesh2D->getCoords()->begin()); - std::size_t sz(conn.size()); - std::vector addCoo; - std::vector conn2(conn); - int offset(mesh2D->getNumberOfNodes()); - for(std::size_t i=0;igetMiddleOfPoints(coo+2*conn[i],coo+2*conn[(i+1)%sz],tmp);// tony a chier i+1 -> i - addCoo.insert(addCoo.end(),tmp,tmp+2); - conn2.push_back(offset+(int)i); - } - mesh2D->getCoords()->rearrange(1); - mesh2D->getCoords()->pushBackValsSilent(&addCoo[0],&addCoo[0]+addCoo.size()); - mesh2D->getCoords()->rearrange(2); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,conn2.size(),&conn2[0]); - } -} - -/*! - * \b WARNING edges in out1 coming from \a splitMesh1D are \b NOT oriented because only used for equation of curve. - * - * This method cuts in 2 parts the input 2D cell given using boundaries description (\a edge1Bis and \a edge1BisPtr) using - * a set of edges defined in \a splitMesh1D. - */ -void BuildMesh2DCutInternal2(const MEDCouplingUMesh *splitMesh1D, const std::vector& edge1Bis, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edge1BisPtr, - std::vector< std::vector >& out0, std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >& out1) -{ - std::size_t nb(edge1Bis.size()/2); - std::size_t nbOfEdgesOf2DCellSplit(nb/2); - int iEnd(splitMesh1D->getNumberOfCells()); - if(iEnd==0) - throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal2 : internal error ! input 1D mesh must have at least one cell !"); - std::size_t ii,jj; - const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin()); - for(ii=0;ii single output cell - out0.resize(1); out1.resize(1); - std::vector& connOut(out0[0]); - connOut.resize(nbOfEdgesOf2DCellSplit); - std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr(out1[0]); - edgesPtr.resize(nbOfEdgesOf2DCellSplit); - for(std::size_t kk=0;kk& connOutLeft(out0[0]); - std::vector& connOutRight(out0[1]);//connOutLeft should end with edge1Bis[2*ii] and connOutRight should end with edge1Bis[2*jj+1] - std::vector< MEDCouplingAutoRefCountObjectPtr >& eleft(out1[0]); - std::vector< MEDCouplingAutoRefCountObjectPtr >& eright(out1[1]); - for(std::size_t k=ii;k > ees(iEnd); - for(int ik=0;ik,int> m; - MEDCouplingAutoRefCountObjectPtr ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cSplitPtr[ciSplitPtr[ik]],cSplitPtr+ciSplitPtr[ik]+1,splitMesh1D->getCoords()->begin(),m)); - ees[ik]=ee; - } - for(int ik=iEnd-1;ik>=0;ik--) - connOutLeft.push_back(cSplitPtr[ciSplitPtr[ik]+1]); - for(std::size_t k=jj+1;k& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr); -public: - std::vector _edges; - std::vector< MEDCouplingAutoRefCountObjectPtr > _edges_ptr; -}; - -CellInfo::CellInfo(const std::vector& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr) -{ - std::size_t nbe(edges.size()); - std::vector edges2(2*nbe); std::vector< MEDCouplingAutoRefCountObjectPtr > edgesPtr2(2*nbe); - for(std::size_t i=0;i& mesh):_istart(istart),_iend(iend),_mesh(mesh),_left(-7),_right(-7) { } - EdgeInfo(int istart, int iend, int pos, const MEDCouplingAutoRefCountObjectPtr& edge):_istart(istart),_iend(iend),_edge(edge),_left(pos),_right(pos+1) { } - bool isInMyRange(int pos) const { return pos>=_istart && pos<_iend; } - void somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight); - void feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const; -private: - int _istart; - int _iend; - MEDCouplingAutoRefCountObjectPtr _mesh; - MEDCouplingAutoRefCountObjectPtr _edge; - int _left; - int _right; -}; - -void EdgeInfo::somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight) -{ - const MEDCouplingUMesh *mesh(_mesh); - if(mesh) - return ; - if(_rightpos) - { _left++; _right++; return ; } - if(_right==pos) - { - bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end()); - if((isLeft && isRight) || (!isLeft && !isRight)) - throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 1 !"); - if(isLeft) - return ; - if(isRight) - { - _right++; - return ; - } - } - if(_left==pos) - { - bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end()); - if((isLeft && isRight) || (!isLeft && !isRight)) - throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 2 !"); - if(isLeft) - { - _right++; - return ; - } - if(isRight) - { - _left++; - _right++; - return ; - } - } -} - -void EdgeInfo::feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const -{ - const MEDCouplingUMesh *mesh(_mesh); - if(!mesh) - { - neighbors[0]=offset+_left; neighbors[1]=offset+_right; - } - else - {// not fully splitting cell case - if(mesh2D->getNumberOfCells()==1) - {//little optimization. 1 cell no need to find in which cell mesh is ! - neighbors[0]=offset; neighbors[1]=offset; - return; - } - else - { - MEDCouplingAutoRefCountObjectPtr barys(mesh->getBarycenterAndOwner()); - int cellId(mesh2D->getCellContainingPoint(barys->begin(),eps)); - if(cellId==-1) - throw INTERP_KERNEL::Exception("EdgeInfo::feedEdgeInfoAt : internal error !"); - neighbors[0]=offset+cellId; neighbors[1]=offset+cellId; - } - } -} - -class VectorOfCellInfo -{ -public: - VectorOfCellInfo(const std::vector& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr); - std::size_t size() const { return _pool.size(); } - int getPositionOf(double eps, const MEDCouplingUMesh *mesh) const; - void setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr& mesh1DInCase, const std::vector< std::vector >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >& edgePtrs); - const std::vector& getConnOf(int pos) const { return get(pos)._edges; } - const std::vector< MEDCouplingAutoRefCountObjectPtr >& getEdgePtrOf(int pos) const { return get(pos)._edges_ptr; } - MEDCouplingAutoRefCountObjectPtr getZeMesh() const { return _ze_mesh; } - void feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const; -private: - int getZePosOfEdgeGivenItsGlobalId(int pos) const; - void updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight); - const CellInfo& get(int pos) const; - CellInfo& get(int pos); -private: - std::vector _pool; - MEDCouplingAutoRefCountObjectPtr _ze_mesh; - std::vector _edge_info; -}; - -VectorOfCellInfo::VectorOfCellInfo(const std::vector& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr):_pool(1) -{ - _pool[0]._edges=edges; - _pool[0]._edges_ptr=edgesPtr; -} - -int VectorOfCellInfo::getPositionOf(double eps, const MEDCouplingUMesh *mesh) const -{ - if(_pool.empty()) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : empty !"); - if(_pool.size()==1) - return 0; - const MEDCouplingUMesh *zeMesh(_ze_mesh); - if(!zeMesh) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : null aggregated mesh !"); - MEDCouplingAutoRefCountObjectPtr barys(mesh->getBarycenterAndOwner()); - return zeMesh->getCellContainingPoint(barys->begin(),eps); -} - -void VectorOfCellInfo::setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr& mesh1DInCase, const std::vector< std::vector >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >& edgePtrs) -{ - get(pos);//to check pos - bool isFast(pos==0 && _pool.size()==1); - std::size_t sz(edges.size()); - // dealing with edges - if(sz==1) - _edge_info.push_back(EdgeInfo(istart,iend,mesh1DInCase)); - else - _edge_info.push_back(EdgeInfo(istart,iend,pos,edgePtrs[0].back())); - // - std::vector pool(_pool.size()-1+sz); - for(int i=0;i > ms; - if(pos>0) - { - MEDCouplingAutoRefCountObjectPtr elt(static_cast(_ze_mesh->buildPartOfMySelf2(0,pos,true))); - ms.push_back(elt); - } - ms.push_back(mesh); - if(pos<_ze_mesh->getNumberOfCells()-1) - { - MEDCouplingAutoRefCountObjectPtr elt(static_cast(_ze_mesh->buildPartOfMySelf2(pos+1,_ze_mesh->getNumberOfCells(),true))); - ms.push_back(elt); - } - std::vector< const MEDCouplingUMesh *> ms2(ms.size()); - for(std::size_t j=0;j=0 !"); - int ret(0); - for(std::vector::const_iterator it=_edge_info.begin();it!=_edge_info.end();it++,ret++) - { - if((*it).isInMyRange(pos)) - return ret; - } - throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id !"); -} - -void VectorOfCellInfo::updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight) -{ - get(pos);//to check; - if(_edge_info.empty()) - return ; - std::size_t sz(_edge_info.size()-1); - for(std::size_t i=0;i=(int)_pool.size()) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get const : invalid pos !"); - return _pool[pos]; -} - -CellInfo& VectorOfCellInfo::get(int pos) -{ - if(pos<0 || pos>=(int)_pool.size()) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get : invalid pos !"); - return _pool[pos]; -} - -/*! - * Given : - * - a \b closed set of edges ( \a allEdges and \a allEdgesPtr ) that defines the split descending 2D cell. - * - \a splitMesh1D a split 2D curve mesh contained into 2D cell defined above. - * - * This method returns the 2D mesh and feeds \a idsLeftRight using offset. - * - * Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells. - * - * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge. - */ -MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector& allEdges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& allEdgesPtr, int offset, - MEDCouplingAutoRefCountObjectPtr& idsLeftRight) -{ - int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells()); - if(nbCellsInSplitMesh1D==0) - throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal : internal error ! input 1D mesh must have at least one cell !"); - const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin()); - std::size_t nb(allEdges.size()),jj; - if(nb%2!=0) - throw INTERP_KERNEL::Exception("BuildMesh2DCutFrom : internal error 2 !"); - std::vector edge1Bis(nb*2); - std::vector< MEDCouplingAutoRefCountObjectPtr > edge1BisPtr(nb*2); - std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()); - std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()+nb); - std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()); - std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()+nb); - // - idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2); - int *idsLeftRightPtr(idsLeftRight->getPointer()); - VectorOfCellInfo pool(edge1Bis,edge1BisPtr); - for(int iStart=0;iStart partOfSplitMesh1D(static_cast(splitMesh1D->buildPartOfMySelf2(iStart,iEnd,1,true))); - int pos(pool.getPositionOf(eps,partOfSplitMesh1D)); - // - MEDCouplingAutoRefCountObjectPtrretTmp(MEDCouplingUMesh::New("",2)); - retTmp->setCoords(splitMesh1D->getCoords()); - retTmp->allocateCells(); - - std::vector< std::vector > out0; - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > out1; - - BuildMesh2DCutInternal2(partOfSplitMesh1D,pool.getConnOf(pos),pool.getEdgePtrOf(pos),out0,out1); - for(std::size_t cnt=0;cnt >& intersectEdge1, int offset, - MEDCouplingAutoRefCountObjectPtr& idsLeftRight) -{ - const int *cdescPtr(mesh2DDesc->getNodalConnectivity()->begin()),*cidescPtr(mesh2DDesc->getNodalConnectivityIndex()->begin()); - // - std::vector allEdges; - std::vector< MEDCouplingAutoRefCountObjectPtr > allEdgesPtr; // for each sub edge in splitMesh2D the uncut Edge object of the original mesh2D - for(const int *it(descBg);it!=descEnd;it++) // for all edges in the descending connectivity of the 2D mesh in relative Fortran mode - { - int edgeId(std::abs(*it)-1); - std::map< MEDCouplingAutoRefCountObjectPtr,int> m; - MEDCouplingAutoRefCountObjectPtr ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cdescPtr[cidescPtr[edgeId]],cdescPtr+cidescPtr[edgeId]+1,mesh2DDesc->getCoords()->begin(),m)); - const std::vector& edge1(intersectEdge1[edgeId]); - if(*it>0) - allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); - else - allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); - std::size_t sz(edge1.size()); - for(std::size_t cnt=0;cntgetCoords()->begin()); - if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1) - return *candidatesIn2DBg; - int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1); - MEDCouplingAutoRefCountObjectPtr cur1D(static_cast(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true))); - if(cellIdInMesh1DSplitRelative<0) - cur1D->changeOrientationOfCells(); - const int *c1D(cur1D->getNodalConnectivity()->begin()); - const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0])); - for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++) - { - MEDCouplingAutoRefCountObjectPtr cur2D(static_cast(mesh2DSplit->buildPartOfMySelf(it,it+1,true))); - const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin()); - const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]])); - unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1)); - INTERP_KERNEL::AutoPtr tmpPtr(new int[ci[1]-ci[0]]); - for(unsigned it2=0;it2checkFullyDefined(); - mesh1D->checkFullyDefined(); - const std::vector& compNames(mesh2D->getCoords()->getInfoOnComponents()); - if(mesh2D->getMeshDimension()!=2 || mesh2D->getSpaceDimension()!=2 || mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine works with mesh2D with spacedim=meshdim=2 and mesh1D with meshdim=1 spaceDim=2 !"); - // Step 1: compute all edge intersections (new nodes) - std::vector< std::vector > intersectEdge1, colinear2, subDiv2; - std::vector addCoo,addCoordsQuadratic; // coordinates of newly created nodes - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - // - // Build desc connectivity - DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); - MEDCouplingAutoRefCountObjectPtr m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1)); - std::map mergedNodes; - Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes); - // use mergeNodes to fix intersectEdge1 - for(std::vector< std::vector >::iterator it0=intersectEdge1.begin();it0!=intersectEdge1.end();it0++) - { - std::size_t n((*it0).size()/2); - int eltStart((*it0)[0]),eltEnd((*it0)[2*n-1]); - std::map::const_iterator it1; - it1=mergedNodes.find(eltStart); - if(it1!=mergedNodes.end()) - (*it0)[0]=(*it1).second; - it1=mergedNodes.find(eltEnd); - if(it1!=mergedNodes.end()) - (*it0)[2*n-1]=(*it1).second; - } - // - MEDCouplingAutoRefCountObjectPtr addCooDa(DataArrayDouble::New()); - addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); - // Step 2: re-order newly created nodes according to the ordering found in m2 - std::vector< std::vector > intersectEdge2; - BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2); - subDiv2.clear(); - // Step 3: compute splitMesh1D - MEDCouplingAutoRefCountObjectPtr idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear; - MEDCouplingAutoRefCountObjectPtr ret2(DataArrayInt::New()); ret2->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1, - idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear)); - MEDCouplingAutoRefCountObjectPtr ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits::max()); ret3->rearrange(2); - MEDCouplingAutoRefCountObjectPtr idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells())); - // deal with cells in mesh2D that are not cut but only some of their edges are - MEDCouplingAutoRefCountObjectPtr idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCpy()); - idsInDesc2DToBeRefined->abs(); idsInDesc2DToBeRefined->applyLin(1,-1); - idsInDesc2DToBeRefined=idsInDesc2DToBeRefined->buildUnique(); - MEDCouplingAutoRefCountObjectPtr out0s;//ids in mesh2D that are impacted by the fact that some edges of \a mesh1D are part of the edges of those cells - if(!idsInDesc2DToBeRefined->empty()) - { - DataArrayInt *out0(0),*outi0(0); - MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0); - MEDCouplingAutoRefCountObjectPtr outi0s(outi0); - out0s=out0; - out0s=out0s->buildUnique(); - out0s->sort(true); - } - // - MEDCouplingAutoRefCountObjectPtr ret1NonCol(static_cast(ret1->buildPartOfMySelf(idsInRet1NotColinear->begin(),idsInRet1NotColinear->end()))); - MEDCouplingAutoRefCountObjectPtr baryRet1(ret1NonCol->getBarycenterAndOwner()); - MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; - mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex); - MEDCouplingAutoRefCountObjectPtr eltsIndex2(eltsIndex->deltaShiftIndex()); - MEDCouplingAutoRefCountObjectPtr eltsIndex3(eltsIndex2->getIdsEqual(1)); - if(eltsIndex2->count(0)+eltsIndex3->getNumberOfTuples()!=ret1NonCol->getNumberOfCells()) - throw INTERP_KERNEL::Exception("Intersect2DMeshWith1DLine : internal error 1 !"); - MEDCouplingAutoRefCountObjectPtr cellsToBeModified(elts->buildUnique()); - MEDCouplingAutoRefCountObjectPtr untouchedCells(cellsToBeModified->buildComplement(mesh2D->getNumberOfCells())); - if((DataArrayInt *)out0s) - untouchedCells=untouchedCells->buildSubstraction(out0s);//if some edges in ret1 are colinear to descending mesh of mesh2D remove cells from untouched one - std::vector< MEDCouplingAutoRefCountObjectPtr > outMesh2DSplit; - // OK all is ready to insert in ret2 mesh - if(!untouchedCells->empty()) - {// the most easy part, cells in mesh2D not impacted at all - outMesh2DSplit.push_back(static_cast(mesh2D->buildPartOfMySelf(untouchedCells->begin(),untouchedCells->end()))); - outMesh2DSplit.back()->setCoords(ret1->getCoords()); - ret2->pushBackValsSilent(untouchedCells->begin(),untouchedCells->end()); - } - if((DataArrayInt *)out0s) - {// here dealing with cells in out0s but not in cellsToBeModified - MEDCouplingAutoRefCountObjectPtr fewModifiedCells(out0s->buildSubstraction(cellsToBeModified)); - const int *rdptr(dd3->begin()),*rdiptr(dd4->begin()),*dptr(dd1->begin()),*diptr(dd2->begin()); - for(const int *it=fewModifiedCells->begin();it!=fewModifiedCells->end();it++) - { - outMesh2DSplit.push_back(BuildRefined2DCell(ret1->getCoords(),mesh2D,*it,dptr+diptr[*it],dptr+diptr[*it+1],intersectEdge1)); - ret1->setCoords(outMesh2DSplit.back()->getCoords()); - } - int offset(ret2->getNumberOfTuples()); - ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end()); - MEDCouplingAutoRefCountObjectPtr partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1); - partOfRet3->fillWithValue(std::numeric_limits::max()); partOfRet3->rearrange(2); - int kk(0),*ret3ptr(partOfRet3->getPointer()); - for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++) - { - int faceId(std::abs(*it)-1); - for(const int *it2=rdptr+rdiptr[faceId];it2!=rdptr+rdiptr[faceId+1];it2++) - { - int tmp(fewModifiedCells->locateValue(*it2)); - if(tmp!=-1) - { - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk]=tmp+offset; - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk+1]=tmp+offset; - } - else - {//the current edge is shared by a 2D cell that will be split just after - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk]=-(*it2+1); - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk+1]=-(*it2+1); - } - } - } - m1Desc->setCoords(ret1->getCoords()); - ret1NonCol->setCoords(ret1->getCoords()); - ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true); - if(!outMesh2DSplit.empty()) - { - DataArrayDouble *da(outMesh2DSplit.back()->getCoords()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator itt=outMesh2DSplit.begin();itt!=outMesh2DSplit.end();itt++) - (*itt)->setCoords(da); - } - } - cellsToBeModified=cellsToBeModified->buildUniqueNotSorted(); - for(const int *it=cellsToBeModified->begin();it!=cellsToBeModified->end();it++) - { - MEDCouplingAutoRefCountObjectPtr idsNonColPerCell(elts->getIdsEqual(*it)); - idsNonColPerCell->transformWithIndArr(eltsIndex3->begin(),eltsIndex3->end()); - MEDCouplingAutoRefCountObjectPtr idsNonColPerCell2(idsInRet1NotColinear->selectByTupleId(idsNonColPerCell->begin(),idsNonColPerCell->end())); - MEDCouplingAutoRefCountObjectPtr partOfMesh1CuttingCur2DCell(static_cast(ret1NonCol->buildPartOfMySelf(idsNonColPerCell->begin(),idsNonColPerCell->end()))); - MEDCouplingAutoRefCountObjectPtr partOfRet3; - MEDCouplingAutoRefCountObjectPtr splitOfOneCell(BuildMesh2DCutFrom(eps,*it,m1Desc,partOfMesh1CuttingCur2DCell,dd1->begin()+dd2->getIJ(*it,0),dd1->begin()+dd2->getIJ((*it)+1,0),intersectEdge1,ret2->getNumberOfTuples(),partOfRet3)); - ret3->setPartOfValues3(partOfRet3,idsNonColPerCell2->begin(),idsNonColPerCell2->end(),0,2,1,true); - outMesh2DSplit.push_back(splitOfOneCell); - for(int i=0;igetNumberOfCells();i++) - ret2->pushBackSilent(*it); - } - // - std::size_t nbOfMeshes(outMesh2DSplit.size()); - std::vector tmp(nbOfMeshes); - for(std::size_t i=0;igetCoords()->setInfoOnComponents(compNames); - MEDCouplingAutoRefCountObjectPtr ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp)); - // To finish - filter ret3 - std::numeric_limits::max() -> -1 - negate values must be resolved. - ret3->rearrange(1); - MEDCouplingAutoRefCountObjectPtr edgesToDealWith(ret3->getIdsStrictlyNegative()); - for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++) - { - int old2DCellId(-ret3->getIJ(*it,0)-1); - MEDCouplingAutoRefCountObjectPtr candidates(ret2->getIdsEqual(old2DCellId)); - ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3 - } - ret3->replaceOneValByInThis(std::numeric_limits::max(),-1); - ret3->rearrange(2); - // - splitMesh1D=ret1.retn(); - splitMesh2D=ret2D.retn(); - cellIdInMesh2D=ret2.retn(); - cellIdInMesh1D=ret3.retn(); -} - -/** - * Private. Third step of the partitioning algorithm (Intersect2DMeshes): reconstruct full 2D cells from the - * (newly created) nodes corresponding to the edge intersections. - * Output params: - * @param[out] cr, crI connectivity of the resulting mesh - * @param[out] cNb1, cNb2 correspondance arrays giving for the merged mesh the initial cells IDs in m1 / m2 - * TODO: describe input parameters - */ -void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, - const std::vector >& intesctEdges1, const std::vector< std::vector >& colinear2, - const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector >& intesctEdges2, - const std::vector& addCoords, - std::vector& addCoordsQuadratic, std::vector& cr, std::vector& crI, std::vector& cNb1, std::vector& cNb2) -{ - static const int SPACEDIM=2; - const double *coo1(m1->getCoords()->getConstPointer()); - const int *conn1(m1->getNodalConnectivity()->getConstPointer()),*connI1(m1->getNodalConnectivityIndex()->getConstPointer()); - int offset1(m1->getNumberOfNodes()); - const double *coo2(m2->getCoords()->getConstPointer()); - const int *conn2(m2->getNodalConnectivity()->getConstPointer()),*connI2(m2->getNodalConnectivityIndex()->getConstPointer()); - int offset2(offset1+m2->getNumberOfNodes()); - int offset3(offset2+((int)addCoords.size())/2); - MEDCouplingAutoRefCountObjectPtr bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree()); - const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin()); - // Here a BBTree on 2D-cells, not on segments: - BBTree myTree(bbox2,0,0,m2->getNumberOfCells(),eps); - int ncell1(m1->getNumberOfCells()); - crI.push_back(0); - for(int i=0;i candidates2; - myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2); - std::map mapp; - std::map mappRev; - INTERP_KERNEL::QuadraticPolygon pol1; - INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects: - MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev); - // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes. - pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1, - desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1); - // - std::set edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result - std::set edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1. - INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1); - for(it1.first();!it1.finished();it1.next()) - edges1.insert(it1.current()->getPtr()); - // - std::map > edgesIn2ForShare; // common edges - std::vector pol2s(candidates2.size()); - int ii=0; - for(std::vector::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) - { - INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]]; - const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2); - // Complete mapping with elements coming from the current cell it2 in mesh2: - MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev); - // pol2 is the new QP in the final merged result. - pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2, - pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare); - } - ii=0; - for(std::vector::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) - { - INTERP_KERNEL::ComposedEdge::InitLocationsWithOther(pol1,pol2s[ii]); - pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2); - //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2); - pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2); - } - // Deals with remaining (non-consumed) edges from m1: these are the edges that were never touched - // by m2 but that we still want to keep in the final result. - if(!edges1.empty()) - { - try - { - INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - for(std::map::const_iterator it=mappRev.begin();it!=mappRev.end();it++) - (*it).second->decrRef(); - } -} - -/** - * Provides a renumbering of the cells of this (which has to be a piecewise connected 1D line), so that - * the segments of the line are indexed in consecutive order (i.e. cells \a i and \a i+1 are neighbors). - * This doesn't modify the mesh. This method only works using nodal connectivity consideration. Coordinates of nodes are ignored here. - * The caller is to deal with the resulting DataArrayInt. - * \throw If the coordinate array is not set. - * \throw If the nodal connectivity of the cells is not defined. - * \throw If m1 is not a mesh of dimension 2, or m1 is not a mesh of dimension 1 - * \throw If m2 is not a (piecewise) line (i.e. if a point has more than 2 adjacent segments) - * - * \sa DataArrayInt::sortEachPairToMakeALinkedList - */ -DataArrayInt *MEDCouplingUMesh::orderConsecutiveCells1D() const -{ - checkFullyDefined(); - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D works on unstructured mesh with meshdim = 1 !"); - - // Check that this is a line (and not a more complex 1D mesh) - each point is used at most by 2 segments: - MEDCouplingAutoRefCountObjectPtr _d(DataArrayInt::New()),_dI(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr _rD(DataArrayInt::New()),_rDI(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m_points(buildDescendingConnectivity(_d, _dI, _rD, _rDI)); - const int *d(_d->getConstPointer()), *dI(_dI->getConstPointer()); - const int *rD(_rD->getConstPointer()), *rDI(_rDI->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr _dsi(_rDI->deltaShiftIndex()); - const int * dsi(_dsi->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr dsii = _dsi->getIdsNotInRange(0,3); - m_points=0; - if (dsii->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D only work with a mesh being a (piecewise) connected line!"); - - int nc(getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr result(DataArrayInt::New()); - result->alloc(nc,1); - - // set of edges not used so far - std::set edgeSet; - for (int i=0; i linePiece; - // fills a list of consecutive segment linked to startSeg. This can go forward or backward. - for (int direction=0;direction<2;direction++) // direction=0 --> forward, direction=1 --> backward - { - // Fill the list forward (resp. backward) from the start segment: - int activeSeg = startSeg; - int prevPointId = -20; - int ptId; - while (!edgeSet.empty()) - { - if (!(direction == 1 && prevPointId==-20)) // prevent adding twice startSeg - { - if (direction==0) - linePiece.push_back(activeSeg); - else - linePiece.push_front(activeSeg); - edgeSet.erase(activeSeg); - } - - int ptId1 = d[dI[activeSeg]], ptId2 = d[dI[activeSeg]+1]; - ptId = direction ? (ptId1 == prevPointId ? ptId2 : ptId1) : (ptId2 == prevPointId ? ptId1 : ptId2); - if (dsi[ptId] == 1) // hitting the end of the line - break; - prevPointId = ptId; - int seg1 = rD[rDI[ptId]], seg2 = rD[rDI[ptId]+1]; - activeSeg = (seg1 == activeSeg) ? seg2 : seg1; - } - } - // Done, save final piece into DA: - std::copy(linePiece.begin(), linePiece.end(), result->getPointer()+newIdx); - newIdx += linePiece.size(); - - // identify next valid start segment (one which is not consumed) - if(!edgeSet.empty()) - startSeg = *(edgeSet.begin()); - } - while (!edgeSet.empty()); - return result.retn(); -} - -/// @cond INTERNAL - -void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map,int>& m, int forbVal0, int forbVal1, std::vector& isect) -{ - MEDCouplingAutoRefCountObjectPtr nTmp(n); nTmp->incrRef(); - std::map,int>::const_iterator it(m.find(nTmp)); - if(it==m.end()) - throw INTERP_KERNEL::Exception("Internal error in remapping !"); - int v((*it).second); - if(v==forbVal0 || v==forbVal1) - return ; - if(std::find(isect.begin(),isect.end(),v)==isect.end()) - isect.push_back(v); -} - -bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map,int>& m, int forbVal0, int forbVal1, std::vector& isect) -{ - int sz(c.size()); - if(sz<=1) - return false; - bool presenceOfOn(false); - for(int i=0;igetLoc()!=INTERP_KERNEL::FULL_ON_1) - continue ; - IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect); - IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect); - } - return presenceOfOn; -} - -/// @endcond - -/** - * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg - * and in \a subNodesInSegI using \ref numbering-indirect storage mode. - * To do the work this method can optionally needs information about middle of subedges for quadratic cases if - * a minimal creation of new nodes is wanted. - * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add - * nodes if a SEG3 is split without information of middle. - * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to - * avoid to have a non conform mesh. - * - * \return int - the number of new nodes created (in most of cases 0). - * - * \throw If \a this is not coherent. - * \throw If \a this has not spaceDim equal to 2. - * \throw If \a this has not meshDim equal to 2. - * \throw If some subcells needed to be split are orphan. - * \sa MEDCouplingUMesh::conformize2D - */ -int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI) -{ - if(!desc || !descI || !subNodesInSeg || !subNodesInSegI) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !"); - desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !"); - if(midOpt==0 && midOptI==0) - { - split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI); - return 0; - } - else if(midOpt!=0 && midOptI!=0) - return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI); - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all."); -} - -/*! - * \b WARNING this method is \b potentially \b non \b const (if returned array is empty). - * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) ! - * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method - * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges are both linear (INTERP_KERNEL::NORM_SEG2). - * In the other cases new nodes can be created. If any are created, they will be appended at the end of the coordinates object before the invokation of this method. - * - * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells. - * The modified cells, if any, are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the initial quadraticness of geometric type. - * - * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too. - * This method expects that all nodes in \a this are not closer than \a eps. - * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method. - * - * \param [in] eps the relative error to detect merged edges. - * \return DataArrayInt * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array - * that the user is expected to deal with. - * - * \throw If \a this is not coherent. - * \throw If \a this has not spaceDim equal to 2. - * \throw If \a this has not meshDim equal to 2. - * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells - */ -DataArrayInt *MEDCouplingUMesh::conformize2D(double eps) -{ - static const int SPACEDIM=2; - checkCoherency(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); - MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1)); - const int *c(mDesc->getNodalConnectivity()->getConstPointer()),*ci(mDesc->getNodalConnectivityIndex()->getConstPointer()),*rd(revDesc1->getConstPointer()),*rdi(revDescIndx1->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr bboxArr(mDesc->getBoundingBoxForBBTree()); - const double *bbox(bboxArr->begin()),*coords(getCoords()->begin()); - int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells()); - std::vector< std::vector > intersectEdge(nDescCell),overlapEdge(nDescCell); - std::vector addCoo; - BBTree myTree(bbox,0,0,nDescCell,-eps); - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - for(int i=0;i candidates; - myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates); - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - if(*it>i) - { - std::map,int> m; - INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)), - *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m)); - INTERP_KERNEL::MergePoints merge; - INTERP_KERNEL::QuadraticPolygon c1,c2; - e1->intersectWith(e2,merge,c1,c2); - e1->decrRef(); e2->decrRef(); - if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i])) - overlapEdge[i].push_back(*it); - if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it])) - overlapEdge[*it].push_back(i); - } - } - // splitting done. sort intersect point in intersectEdge. - std::vector< std::vector > middle(nDescCell); - int nbOf2DCellsToBeSplit(0); - bool middleNeedsToBeUsed(false); - std::vector cells2DToTreat(nDescCell,false); - for(int i=0;i& isect(intersectEdge[i]); - int sz((int)isect.size()); - if(sz>1) - { - std::map,int> m; - INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)); - e->sortSubNodesAbs(coords,isect); - e->decrRef(); - } - if(sz!=0) - { - int idx0(rdi[i]),idx1(rdi[i+1]); - if(idx1-idx0!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !"); - if(!cells2DToTreat[rd[idx0]]) - { - cells2DToTreat[rd[idx0]]=true; - nbOf2DCellsToBeSplit++; - } - // try to reuse at most eventual 'middle' of SEG3 - std::vector& mid(middle[i]); - mid.resize(sz+1,-1); - if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3) - { - middleNeedsToBeUsed=true; - const std::vector& candidates(overlapEdge[i]); - std::vector trueCandidates; - for(std::vector::const_iterator itc=candidates.begin();itc!=candidates.end();itc++) - if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3) - trueCandidates.push_back(*itc); - int stNode(c[ci[i]+1]),endNode(isect[0]); - for(int j=0;j::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++) - { - int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]); - if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode)) - { mid[j]=*itc; break; } - } - stNode=endNode; - endNode=j ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1); - if(nbOf2DCellsToBeSplit==0) - return ret.retn(); - // - int *retPtr(ret->getPointer()); - for(int i=0;i mSafe,nSafe,oSafe,pSafe,qSafe,rSafe; - DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0); - MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n; - DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p; - if(middleNeedsToBeUsed) - { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; } - MEDCouplingAutoRefCountObjectPtr modif(static_cast(buildPartOfMySelf(ret->begin(),ret->end(),true))); - int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe)); - setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important. - setPartOfMySelf(ret->begin(),ret->end(),*modif); - { - bool areNodesMerged; int newNbOfNodes; - if(nbOfNodesCreated!=0) - MEDCouplingAutoRefCountObjectPtr tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes)); - } - return ret.retn(); -} - -/*! - * This non const method works on 2D mesh. This method scans every cell in \a this and look if each edge constituting this cell is not mergeable with neighbors edges of that cell. - * If yes, the cell is "repaired" to minimize at most its number of edges. So this method do not change the overall shape of cells in \a this (with eps precision). - * This method do not take care of shared edges between cells, so this method can lead to a non conform mesh (\a this). If a conform mesh is required you're expected - * to invoke MEDCouplingUMesh::mergeNodes and MEDCouplingUMesh::conformize2D right after this call. - * This method works on any 2D geometric types of cell (even static one). If a cell is touched its type becomes dynamic automaticaly. For 2D "repaired" quadratic cells - * new nodes for center of merged edges is are systematically created and appended at the end of the previously existing nodes. - * - * If the returned array is empty it means that nothing has changed in \a this (as if it were a const method). If the array is not empty the connectivity of \a this is modified - * using new instance, idem for coordinates. - * - * If \a this is constituted by only linear 2D cells, this method is close to the computation of the convex hull of each cells in \a this. - * - * \return DataArrayInt * - The list of cellIds in \a this that have at least one edge colinearized. - * - * \throw If \a this is not coherent. - * \throw If \a this has not spaceDim equal to 2. - * \throw If \a this has not meshDim equal to 2. - * - * \sa MEDCouplingUMesh::conformize2D, MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::convexEnvelop2D. - */ -DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps) -{ - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - checkCoherency(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::colinearize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - const int *cptr(_nodal_connec->begin()),*ciptr(_nodal_connec_index->begin()); - MEDCouplingAutoRefCountObjectPtr newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr appendedCoords(DataArrayDouble::New()); appendedCoords->alloc(0,1);//1 not 2 it is not a bug. - const double *coords(_coords->begin()); - int *newciptr(newci->getPointer()); - for(int i=0;ipushBackSilent(i); - newciptr[1]=newc->getNumberOfTuples(); - } - // - if(ret->empty()) - return ret.retn(); - if(!appendedCoords->empty()) - { - appendedCoords->rearrange(2); - MEDCouplingAutoRefCountObjectPtr newCoords(DataArrayDouble::Aggregate(getCoords(),appendedCoords));//treat info on components - //non const part - setCoords(newCoords); - } - //non const part - setConnectivity(newc,newci,true); - return ret.retn(); -} - -/*! - * \param [out] intersectEdge1 - for each cell in \a m1Desc returns the result of the split. The result is given using pair of int given resp start and stop. - * So for all edge \a i in \a m1Desc \a intersectEdge1[i] is of length 2*n where n is the number of sub edges. - * And for each j in [1,n) intersect[i][2*(j-1)+1]==intersect[i][2*j]. - * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo - * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it. - * \param [out] addCoo - nodes to be append at the end - * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc. - */ -void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, - std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo, std::map& mergedNodes) -{ - static const int SPACEDIM=2; - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - const int *c1(m1Desc->getNodalConnectivity()->getConstPointer()),*ci1(m1Desc->getNodalConnectivityIndex()->getConstPointer()); - // Build BB tree of all edges in the tool mesh (second mesh) - MEDCouplingAutoRefCountObjectPtr bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree()); - const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin()); - int nDescCell1(m1Desc->getNumberOfCells()),nDescCell2(m2Desc->getNumberOfCells()); - intersectEdge1.resize(nDescCell1); - colinear2.resize(nDescCell2); - subDiv2.resize(nDescCell2); - BBTree myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps); - - std::vector candidates1(1); - int offset1(m1Desc->getNumberOfNodes()); - int offset2(offset1+m2Desc->getNumberOfNodes()); - for(int i=0;i candidates2; // edges of mesh2 candidate for intersection - myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2); - if(!candidates2.empty()) // candidates2 holds edges from the second mesh potentially intersecting current edge i in mesh1 - { - std::map map1,map2; - // pol2 is not necessarily a closed polygon: just a set of (quadratic) edges (same as candidates2) in the Geometric DS format - INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2); - candidates1[0]=i; - INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1); - // This following part is to avoid that some removed nodes (for example due to a merge between pol1 and pol2) are replaced by a newly created one - // This trick guarantees that Node * are discriminant (i.e. form a unique identifier) - std::set nodes; - pol1->getAllNodes(nodes); pol2->getAllNodes(nodes); - std::size_t szz(nodes.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > nodesSafe(szz); - std::set::const_iterator itt(nodes.begin()); - for(std::size_t iii=0;iiiincrRef(); nodesSafe[iii]=*itt; } - // end of protection - // Performs egde cutting: - pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes); - delete pol2; - delete pol1; - } - else - // Copy the edge (take only the two first points, ie discard quadratic point at this stage) - intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i]+3); - } -} - -/*! - * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2). - * It builds the descending connectivity of the two meshes, and then using a binary tree - * it computes the edge intersections. This results in new points being created : they're stored in addCoo. - * Documentation about parameters colinear2 and subDiv2 can be found in method QuadraticPolygon::splitAbs(). - */ -void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, - std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, - MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1, - std::vector& addCoo, - MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2) -{ - // Build desc connectivity - desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New(); - desc2=DataArrayInt::New(); - descIndx2=DataArrayInt::New(); - revDesc2=DataArrayInt::New(); - revDescIndx2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); - MEDCouplingAutoRefCountObjectPtr dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2); - m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); - m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2); - MEDCouplingAutoRefCountObjectPtr dd9(m1Desc),dd10(m2Desc); - std::map notUsedMap; - Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap); - m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef(); - m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef(); -} - -/*! - * This method performs the 2nd step of Partition of 2D mesh. - * This method has 4 inputs : - * - a mesh 'm1' with meshDim==1 and a SpaceDim==2 - * - a mesh 'm2' with meshDim==1 and a SpaceDim==2 - * - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted. - * The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2' - * Nodes end up lying consecutively on a cutted edge. - * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. - * (Only present for its coords in case of 'subDiv' shares some nodes of 'm1') - * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. - * \param addCoo input parameter with additional nodes linked to intersection of the 2 meshes. - * \param[out] intersectEdge the same content as subDiv, but correclty oriented. - */ -void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, - const std::vector& addCoo, - const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge) -{ - int offset1=m1->getNumberOfNodes(); - int ncell=m2->getNumberOfCells(); - const int *c=m2->getNodalConnectivity()->getConstPointer(); - const int *cI=m2->getNodalConnectivityIndex()->getConstPointer(); - const double *coo=m2->getCoords()->getConstPointer(); - const double *cooBis=m1->getCoords()->getConstPointer(); - int offset2=offset1+m2->getNumberOfNodes(); - intersectEdge.resize(ncell); - for(int i=0;i& divs=subDiv[i]; - int nnode=cI[1]-cI[0]-1; - std::map > mapp2; - std::map mapp22; - for(int j=0;j(nn,true); - mapp22[nn]=nnid+offset1; - } - INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1); - for(std::map >::const_iterator it=mapp2.begin();it!=mapp2.end();it++) - ((*it).second.first)->decrRef(); - std::vector addNodes(divs.size()); - std::map mapp3; - for(std::size_t j=0;jsortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]); - for(std::vector::const_iterator it=addNodes.begin();it!=addNodes.end();it++) - (*it)->decrRef(); - e->decrRef(); - } -} - -/*! - * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). - * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells - * with a plane. The result will be put in 'cut3DSuf' out parameter. - * \param [in] cut3DCurve input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially. - * \param [out] nodesOnPlane, returns all the nodes that are on the plane. - * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh. - * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh. - * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh. - * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh. - * \param [in] desc is the descending connectivity 3DSurf->3DCurve - * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve - * \param [out] cut3DSuf input/output param. - */ -void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector& cut3DCurve, std::vector& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf, - const int *nodal3DCurve, const int *nodalIndx3DCurve, - const int *desc, const int *descIndx, - std::vector< std::pair >& cut3DSurf) -{ - std::set nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end()); - int nbOf3DSurfCell=(int)cut3DSurf.size(); - for(int i=0;i res; - int offset=descIndx[i]; - int nbOfSeg=descIndx[i+1]-offset; - for(int j=0;j-1) - res.push_back(status); - else - { - res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]); - res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]); - } - } - } - switch(res.size()) - { - case 2: - { - cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1]; - break; - } - case 1: - case 0: - { - std::set s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]); - std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector >(res)); - if(res.size()==2) - { - cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1]; - } - else - { - cut3DSurf[i].first=-1; cut3DSurf[i].second=-1; - } - break; - } - default: - {// case when plane is on a multi colinear edge of a polyhedron - if((int)res.size()==2*nbOfSeg) - { - cut3DSurf[i].first=-2; cut3DSurf[i].second=i; - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !"); - } - } - } -} - -/*! - * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown. - * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). - * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells - * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters. - * \param cut3DSurf input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve). - * \param desc is the descending connectivity 3D->3DSurf - * \param descIndx is the descending connectivity index 3D->3DSurf - */ -void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, - const int *desc, const int *descIndx, - DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); - const int *nodal3D=_nodal_connec->getConstPointer(); - const int *nodalIndx3D=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for(int i=0;i > m; - int offset=descIndx[i]; - int nbOfFaces=descIndx[i+1]-offset; - int start=-1; - int end=-1; - for(int j=0;j& p=cut3DSurf[desc[offset+j]]; - if(p.first!=-1 && p.second!=-1) - { - if(p.first!=-2) - { - start=p.first; end=p.second; - m[p.first].insert(p.second); - m[p.second].insert(p.first); - } - else - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]); - int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1; - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - INTERP_KERNEL::NormalizedCellType cmsId; - unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId); - start=tmp[0]; end=tmp[nbOfNodesSon-1]; - for(unsigned k=0;k conn(1,(int)INTERP_KERNEL::NORM_POLYGON); - int prev=end; - while(end!=start) - { - std::map >::const_iterator it=m.find(start); - const std::set& s=(*it).second; - std::set s2; s2.insert(prev); - std::set s3; - std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin())); - if(s3.size()==1) - { - int val=*s3.begin(); - conn.push_back(start); - prev=start; - start=val; - } - else - start=end; - } - conn.push_back(end); - if(conn.size()>3) - { - nodalRes->insertAtTheEnd(conn.begin(),conn.end()); - nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples()); - cellIds->pushBackSilent(i); - } - } -} - -/*! - * This method compute the convex hull of a single 2D cell. This method tries to conserve at maximum the given input connectivity. In particular, if the orientation of cell is not clockwise - * as in MED format norm. If definitely the result of Jarvis algorithm is not matchable with the input connectivity, the result will be copied into \b nodalConnecOut parameter and - * the geometric cell type set to INTERP_KERNEL::NORM_POLYGON. - * This method excepts that \b coords parameter is expected to be in dimension 2. [ \b nodalConnBg , \b nodalConnEnd ) is the nodal connectivity of the input - * cell (geometric cell type included at the position 0). If the meshdimension of the input cell is not equal to 2 an INTERP_KERNEL::Exception will be thrown. - * - * \return false if the input connectivity represents already the convex hull, true if the input cell needs to be reordered. - */ -bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) -{ - std::size_t sz=std::distance(nodalConnBg,nodalConnEnd); - if(sz>=4) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)*nodalConnBg); - if(cm.getDimension()==2) - { - const int *node=nodalConnBg+1; - int startNode=*node++; - double refX=coords[2*startNode]; - for(;node!=nodalConnEnd;node++) - { - if(coords[2*(*node)] tmpOut; tmpOut.reserve(sz); tmpOut.push_back(startNode); - refX=1e300; - double tmp1; - double tmp2[2]; - double angle0=-M_PI/2; - // - int nextNode=-1; - int prevNode=-1; - double resRef; - double angleNext=0.; - while(nextNode!=startNode) - { - nextNode=-1; - resRef=1e300; - for(node=nodalConnBg+1;node!=nodalConnEnd;node++) - { - if(*node!=tmpOut.back() && *node!=prevNode) - { - tmp2[0]=coords[2*(*node)]-coords[2*tmpOut.back()]; tmp2[1]=coords[2*(*node)+1]-coords[2*tmpOut.back()+1]; - double angleM=INTERP_KERNEL::EdgeArcCircle::GetAbsoluteAngle(tmp2,tmp1); - double res; - if(angleM<=angle0) - res=angle0-angleM; - else - res=angle0-angleM+2.*M_PI; - if(res tmp3(2*(sz-1)); - std::vector::iterator it=std::copy(nodalConnBg+1,nodalConnEnd,tmp3.begin()); - std::copy(nodalConnBg+1,nodalConnEnd,it); - if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end()) - { - nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); - return false; - } - if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend()) - { - nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); - return false; - } - else - { - nodalConnecOut->pushBackSilent((int)INTERP_KERNEL::NORM_POLYGON); - nodalConnecOut->insertAtTheEnd(tmpOut.begin(),tmpOut.end()); - return true; - } - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); -} - -/*! - * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx. - * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression. - * - * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included) - * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded) - * \param [in,out] arr array in which the remove operation will be done. - * \param [in,out] arrIndx array in the remove operation will modify - * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1]) - * \return true if \b arr and \b arrIndx have been modified, false if not. - */ -bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval) -{ - if(!arrIndx || !arr) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : some input arrays are empty !"); - if(offsetForRemoval<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !"); - std::set s(idsToRemoveBg,idsToRemoveEnd); - int nbOfGrps=arrIndx->getNumberOfTuples()-1; - int *arrIPtr=arrIndx->getPointer(); - *arrIPtr++=0; - int previousArrI=0; - const int *arrPtr=arr->getConstPointer(); - std::vector arrOut;//no utility to switch to DataArrayInt because copy always needed - for(int i=0;ioffsetForRemoval) - { - for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++) - { - if(s.find(*work)==s.end()) - arrOut.push_back(*work); - } - } - previousArrI=*arrIPtr; - *arrIPtr=(int)arrOut.size(); - } - if(arr->getNumberOfTuples()==(int)arrOut.size()) - return false; - arr->alloc((int)arrOut.size(),1); - std::copy(arrOut.begin(),arrOut.end(),arr->getPointer()); - return true; -} - -/*! - * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn - * (\ref numbering-indirect). - * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ). - * The selection of extraction is done standardly in new2old format. - * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut). - * - * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) - * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * \sa MEDCouplingUMesh::ExtractFromIndexedArrays2 - */ -void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(!arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); - arrIn->checkAllocated(); arrIndxIn->checkAllocated(); - if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input arrays must have exactly one component !"); - std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd); - const int *arrInPtr=arrIn->getConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; - if(nbOfGrps<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); - int maxSizeOfArr=arrIn->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - arrIo->alloc((int)(sz+1),1); - const int *idsIt=idsOfSelectBg; - int *work=arrIo->getPointer(); - *work++=0; - int lgth=0; - for(std::size_t i=0;i=0 && *idsIt=work[-1]) - *work=lgth; - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt; - oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arro->alloc(lgth,1); - work=arro->getPointer(); - idsIt=idsOfSelectBg; - for(std::size_t i=0;i=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr) - work=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],work); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx["; - oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arrOut=arro.retn(); - arrIndexOut=arrIo.retn(); -} - -/*! - * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn - * (\ref numbering-indirect). - * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ). - * The selection of extraction is done standardly in new2old format. - * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut). - * - * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included) - * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded) - * \param [in] idsOfSelectStep - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * \sa MEDCouplingUMesh::ExtractFromIndexedArrays - */ -void MEDCouplingUMesh::ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(!arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input pointer is NULL !"); - arrIn->checkAllocated(); arrIndxIn->checkAllocated(); - if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input arrays must have exactly one component !"); - int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArrays2 : Input slice "); - const int *arrInPtr=arrIn->getConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; - if(nbOfGrps<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); - int maxSizeOfArr=arrIn->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - arrIo->alloc((int)(sz+1),1); - int idsIt=idsOfSelectStart; - int *work=arrIo->getPointer(); - *work++=0; - int lgth=0; - for(int i=0;i=0 && idsIt=work[-1]) - *work=lgth; - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt; - oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arro->alloc(lgth,1); - work=arro->getPointer(); - idsIt=idsOfSelectStart; - for(int i=0;i=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr) - work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx["; - oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arrOut=arro.retn(); - arrIndexOut=arrIo.retn(); -} - -/*! - * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. - * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for - * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). - * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. - * - * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) - * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd ) - * \param [in] srcArrIndex index array of \b srcArr - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * - * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx - */ -void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : presence of null pointer in input parameter !"); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - std::vector v(nbOfTuples,true); - int offset=0; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) - { - if(*it>=0 && *itgetConstPointer(); - arrIo->alloc(nbOfTuples+1,1); - arro->alloc(arrIn->getNumberOfTuples()+offset,1); - const int *arrInPtr=arrIn->getConstPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; - int *arroPtr=arro->getPointer(); - for(int ii=0;iigetNumberOfTuples()-1; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - int *arrInOutPtr=arrInOut->getPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) - { - if(*it>=0 && *itgetNumberOfTuples()-1. - * - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. - * \sa MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed, MEDCouplingUMesh::partitionBySpreadZone - */ -DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) -{ - int seed=0,nbOfDepthPeelingPerformed=0; - return ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1,arrIn,arrIndxIn,-1,nbOfDepthPeelingPerformed); -} - -/*! - * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn. - * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method. - * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. - * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. - * A negative value in \b arrIn means that it is ignored. - * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. - * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone - * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] nbOfDepthPeeling the max number of peels requested in search. By default -1, that is to say, no limit. - * \param [out] nbOfDepthPeelingPerformed the number of peels effectively performed. May be different from \a nbOfDepthPeeling - * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. - * \sa MEDCouplingUMesh::partitionBySpreadZone - */ -DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) -{ - nbOfDepthPeelingPerformed=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed : arrIndxIn input pointer is NULL !"); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - if(nbOfTuples<=0) - { - DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1); - return ret; - } - // - std::vector fetched(nbOfTuples,false); - return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); -} - -DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) -{ - nbOfDepthPeelingPerformed=0; - if(!seedBg || !seedEnd || !arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !"); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - std::vector fetched2(nbOfTuples,false); - int i=0; - for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++) - { - if(*seedElt>=0 && *seedEltgetConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits::max(); - std::vector idsToFetch1(seedBg,seedEnd); - std::vector idsToFetch2; - std::vector *idsToFetch=&idsToFetch1; - std::vector *idsToFetchOther=&idsToFetch2; - while(!idsToFetch->empty() && nbOfDepthPeelingPerformed::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++) - for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++) - if(!fetched[*it2]) - { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); } - std::swap(idsToFetch,idsToFetchOther); - idsToFetchOther->clear(); - nbOfDepthPeelingPerformed++; - } - int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true); - i=0; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(lgth,1); - int *retPtr=ret->getPointer(); - for(std::vector::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++) - if(*it) - *retPtr++=i; - return ret.retn(); -} - -/*! - * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. - * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for - * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). - * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. - * - * \param [in] start begin of set of ids of the input extraction (included) - * \param [in] end end of set of ids of the input extraction (excluded) - * \param [in] step step of the set of ids in range mode. - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) - * \param [in] srcArrIndex index array of \b srcArr - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * - * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays - */ -void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !"); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - int offset=0; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : "); - int it=start; - for(int i=0;i=0 && itgetConstPointer(); - arrIo->alloc(nbOfTuples+1,1); - arro->alloc(arrIn->getNumberOfTuples()+offset,1); - const int *arrInPtr=arrIn->getConstPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; - int *arroPtr=arro->getPointer(); - for(int ii=0;iigetNumberOfTuples()-1; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - int *arrInOutPtr=arrInOut->getPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : "); - int it=start; - for(int i=0;i=0 && it partition=partitionBySpreadZone(); - std::vector< MEDCouplingAutoRefCountObjectPtr > partitionAuto; partitionAuto.reserve(partition.size()); - std::copy(partition.begin(),partition.end(),std::back_insert_iterator > >(partitionAuto)); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),mdim); - ret->setCoords(getCoords()); - ret->allocateCells((int)partition.size()); - // - for(std::vector::const_iterator it=partition.begin();it!=partition.end();it++) - { - MEDCouplingAutoRefCountObjectPtr tmp=static_cast(buildPartOfMySelf((*it)->begin(),(*it)->end(),true)); - MEDCouplingAutoRefCountObjectPtr cell; - switch(mdim) - { - case 2: - cell=tmp->buildUnionOf2DMesh(); - break; - case 3: - cell=tmp->buildUnionOf3DMesh(); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension supported are [2,3] ! Not implemented yet for others !"); - } - - ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)cell->getIJSafe(0,0),cell->getNumberOfTuples()-1,cell->getConstPointer()+1); - } - // - ret->finishInsertingCells(); - return ret.retn(); -} - -/*! - * This method partitions \b this into contiguous zone. - * This method only needs a well defined connectivity. Coordinates are not considered here. - * This method returns a vector of \b newly allocated arrays that the caller has to deal with. - */ -std::vector MEDCouplingUMesh::partitionBySpreadZone() const -{ - int nbOfCellsCur=getNumberOfCells(); - std::vector ret; - if(nbOfCellsCur<=0) - return ret; - DataArrayInt *neigh=0,*neighI=0; - computeNeighborsOfCells(neigh,neighI); - MEDCouplingAutoRefCountObjectPtr neighAuto(neigh),neighIAuto(neighI); - std::vector fetchedCells(nbOfCellsCur,false); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret2; - int seed=0; - while(seed >::iterator it=ret2.begin();it!=ret2.end();it++) - ret.push_back((*it).retn()); - return ret; -} - -/*! - * This method returns given a distribution of cell type (returned for example by MEDCouplingUMesh::getDistributionOfTypes method and customized after) a - * newly allocated DataArrayInt instance with 2 components ready to be interpreted as input of DataArrayInt::findRangeIdForEachTuple method. - * - * \param [in] code a code with the same format than those returned by MEDCouplingUMesh::getDistributionOfTypes except for the code[3*k+2] that should contain start id of chunck. - * \return a newly allocated DataArrayInt to be managed by the caller. - * \throw In case of \a code has not the right format (typically of size 3*n) - */ -DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector& code) -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::size_t nb=code.size()/3; - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeRangesFromTypeDistribution : invalid input code !"); - ret->alloc((int)nb,2); - int *retPtr=ret->getPointer(); - for(std::size_t i=0;i 0, the coordinates array in returned mesh will have \a nbOfAdditionalPoints - * more tuples (nodes) than in \a this. Anyway, all the nodes in \a this (with the same order) will be in the returned mesh. - * - * \param [in] policy - the policy of splitting that must be in (PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48). The policy will be used only for INTERP_KERNEL::NORM_HEXA8 cells. - * For all other cells, the splitting policy will be ignored. See INTERP_KERNEL::SplittingPolicy for the images. - * \param [out] nbOfAdditionalPoints - number of nodes added to \c this->_coords. If > 0 a new coordinates object will be constructed result of the aggregation of the old one and the new points added. - * \param [out] n2oCells - A new instance of DataArrayInt holding, for each new cell, - * an id of old cell producing it. The caller is to delete this array using - * decrRef() as it is no more needed. - * \return MEDCoupling1SGTUMesh * - the mesh containing only INTERP_KERNEL::NORM_TETRA4 cells. - * - * \warning This method operates on each cells in this independantly ! So it can leads to non conform mesh in returned value ! If you expect to have a conform mesh in output - * the policy PLANAR_FACE_6 should be used on a mesh sorted with MEDCoupling1SGTUMesh::sortHexa8EachOther. - * - * \throw If \a this is not a 3D mesh (spaceDim==3 and meshDim==3). - * \throw If \a this is not fully constituted with linear 3D cells. - * \sa MEDCouplingUMesh::simplexize, MEDCoupling1SGTUMesh::sortHexa8EachOther - */ -MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const -{ - INTERP_KERNEL::SplittingPolicy pol((INTERP_KERNEL::SplittingPolicy)policy); - checkConnectivityFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tetrahedrize : only available for mesh with meshdim == 3 and spacedim == 3 !"); - int nbOfCells(getNumberOfCells()),nbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret0(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_TETRA4)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfCells,1); - int *retPt(ret->getPointer()); - MEDCouplingAutoRefCountObjectPtr newConn(DataArrayInt::New()); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr addPts(DataArrayDouble::New()); addPts->alloc(0,1); - const int *oldc(_nodal_connec->begin()); - const int *oldci(_nodal_connec_index->begin()); - const double *coords(_coords->begin()); - for(int i=0;i a; std::vector b; - INTERP_KERNEL::SplitIntoTetras(pol,(INTERP_KERNEL::NormalizedCellType)oldc[oldci[0]],oldc+oldci[0]+1,oldc+oldci[1],coords,a,b); - std::size_t nbOfTet(a.size()/4); *retPt=(int)nbOfTet; - const int *aa(&a[0]); - if(!b.empty()) - { - for(std::vector::iterator it=a.begin();it!=a.end();it++) - if(*it<0) - *it=(-(*(it))-1+nbNodes); - addPts->insertAtTheEnd(b.begin(),b.end()); - nbNodes+=(int)b.size()/3; - } - for(std::size_t j=0;jinsertAtTheEnd(aa,aa+4); - } - if(!addPts->empty()) - { - addPts->rearrange(3); - nbOfAdditionalPoints=addPts->getNumberOfTuples(); - addPts=DataArrayDouble::Aggregate(getCoords(),addPts); - ret0->setCoords(addPts); - } - else - { - nbOfAdditionalPoints=0; - ret0->setCoords(getCoords()); - } - ret0->setNodalConnectivity(newConn); - // - ret->computeOffsets2(); - n2oCells=ret->buildExplicitArrOfSliceOnScaledArr(0,nbOfCells,1); - return ret0.retn(); -} - -/*! - * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch). - * - * \sa MEDCouplingUMesh::split2DCells - */ -void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI) -{ - checkConnectivityFullyDefined(); - int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+subNodesInSeg->getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); - const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); - int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); - int prevPosOfCi(ciPtr[0]); - for(int i=0;iend()!=cPtr) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !"); - _nodal_connec->decrRef(); - _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON); -} - -int InternalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) -{ - if(id!=-1) - return id; - else - { - int ret(nodesCnter++); - double newPt[2]; - e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt); - addCoo.insertAtTheEnd(newPt,newPt+2); - return ret; - } -} - -int InternalAddPointOriented(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) -{ - if(id!=-1) - return id; - else - { - int ret(nodesCnter++); - double newPt[2]; - e->getMiddleOfPointsOriented(coo+2*startId,coo+2*endId,newPt); - addCoo.insertAtTheEnd(newPt,newPt+2); - return ret; - } -} - - -/// @cond INTERNAL - -void EnterTheResultOf2DCellFirst(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector& middles) -{ - int tmp[3]; - int trueStart(start>=0?start:nbOfEdges+start); - tmp[0]=linOrArc?(int)INTERP_KERNEL::NORM_QPOLYG:(int)INTERP_KERNEL::NORM_POLYGON; tmp[1]=connBg[trueStart]; tmp[2]=connBg[stp]; - newConnOfCell->insertAtTheEnd(tmp,tmp+3); - if(linOrArc) - { - if(stp-start>1) - { - int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); - InternalAddPointOriented(e,-1,coords,tmp[1],tmp[2],*appendedCoords,tmp2); - middles.push_back(tmp3+offset); - } - else - middles.push_back(connBg[trueStart+nbOfEdges]); - } -} - -void EnterTheResultOf2DCellMiddle(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector& middles) -{ - int tmpSrt(newConnOfCell->back()),tmpEnd(connBg[stp]); - newConnOfCell->pushBackSilent(tmpEnd); - if(linOrArc) - { - if(stp-start>1) - { - int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); - InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2); - middles.push_back(tmp3+offset); - } - else - middles.push_back(connBg[start+nbOfEdges]); - } -} - -void EnterTheResultOf2DCellEnd(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector& middles) -{ - // only the quadratic point to deal with: - if(linOrArc) - { - if(stp-start>1) - { - int tmpSrt(connBg[start]),tmpEnd(connBg[stp]); - int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); - InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2); - middles.push_back(tmp3+offset); - } - else - middles.push_back(connBg[start+nbOfEdges]); - } -} - -/// @endcond - -/*! - * Returns true if a colinearization has been found in the given cell. If false is returned the content pushed in \a newConnOfCell is equal to [ \a connBg , \a connEnd ) . - * \a appendedCoords is a DataArrayDouble instance with number of components equal to one (even if the items are pushed by pair). - */ -bool MEDCouplingUMesh::Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords) -{ - std::size_t sz(std::distance(connBg,connEnd)); - if(sz<3)//3 because 2+1(for the cell type) and 2 is the minimal number of edges of 2D cell. - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Colinearize2DCell : the input cell has invalid format !"); - sz--; - INTERP_KERNEL::AutoPtr tmpConn(new int[sz]); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connBg[0])); - unsigned nbs(cm.getNumberOfSons2(connBg+1,sz)); - unsigned nbOfHit(0); // number of fusions operated - int posBaseElt(0),posEndElt(0),nbOfTurn(0); - const unsigned int maxNbOfHit = cm.isQuadratic() ? nbs-2 : nbs-3; // a quad cell is authorized to end up with only two edges, a linear one has to keep 3 at least - INTERP_KERNEL::NormalizedCellType typeOfSon; - std::vector middles; - bool ret(false); - for(;(nbOfTurn+nbOfHit),int> m; - INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m)); - posEndElt = posBaseElt+1; - - // Look backward first: are the final edges of the cells colinear with the first ones? - // This initializes posBaseElt. - if(nbOfTurn==0) - { - for(unsigned i=1;iareColinears(); - if(isColinear) - { - nbOfHit++; - posBaseElt--; - ret=true; - } - delete eint; - eCand->decrRef(); - if(!isColinear) - break; - } - } - // Now move forward: - const unsigned fwdStart = (nbOfTurn == 0 ? 0 : posBaseElt); // the first element to be inspected going forward - for(unsigned j=fwdStart+1;jareColinears()); - if(isColinear) - { - nbOfHit++; - posEndElt++; - ret=true; - } - delete eint; - eCand->decrRef(); - if(!isColinear) - break; - } - //push [posBaseElt,posEndElt) in newConnOfCell using e - // The if clauses below are (volontary) not mutually exclusive: on a quad cell with 2 edges, the end of the connectivity is also its begining! - if(nbOfTurn==0) - // at the begining of the connectivity (insert type) - EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); - else if((nbOfHit+nbOfTurn) != (nbs-1)) - // in the middle - EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); - if ((nbOfHit+nbOfTurn) == (nbs-1)) - // at the end (only quad points to deal with) - EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); - posBaseElt=posEndElt; - e->decrRef(); - } - if(!middles.empty()) - newConnOfCell->insertAtTheEnd(middles.begin(),middles.end()); - return ret; -} - -/*! - * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object. - * - * \return int - the number of new nodes created. - * \sa MEDCouplingUMesh::split2DCells - */ -int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI) -{ - checkCoherency(); - int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); - MEDCouplingAutoRefCountObjectPtr addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); - const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); - const int *midPtr(mid->begin()),*midIPtr(midI->begin()); - const double *oldCoordsPtr(getCoords()->begin()); - int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); - int prevPosOfCi(ciPtr[0]); - for(int i=0;i ns(3); - ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]); - ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]); - ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]); - MEDCouplingAutoRefCountObjectPtr e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns)); - for(int k=0;kend()!=cPtr) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !"); - _nodal_connec->decrRef(); - _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG); - addCoo->rearrange(2); - MEDCouplingAutoRefCountObjectPtr coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate - setCoords(coo); - return addCoo->getNumberOfTuples(); -} - -void MEDCouplingUMesh::ComputeAllTypesInternal(std::set& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex) -{ - if(nodalConnec && nodalConnecIndex) - { - types.clear(); - const int *conn(nodalConnec->getConstPointer()),*connIndex(nodalConnecIndex->getConstPointer()); - int nbOfElem(nodalConnecIndex->getNbOfElems()-1); - if(nbOfElem>0) - for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++) - types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]); - } -} - -MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), - _own_cell(true),_cell_id(-1),_nb_cell(0) -{ - if(mesh) - { - mesh->incrRef(); - _nb_cell=mesh->getNumberOfCells(); - } -} - -MEDCouplingUMeshCellIterator::~MEDCouplingUMeshCellIterator() -{ - if(_mesh) - _mesh->decrRef(); - if(_own_cell) - delete _cell; -} - -MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_cell(itc), - _own_cell(false),_cell_id(bg-1), - _nb_cell(end) -{ - if(mesh) - mesh->incrRef(); -} - -MEDCouplingUMeshCell *MEDCouplingUMeshCellIterator::nextt() -{ - _cell_id++; - if(_cell_id<_nb_cell) - { - _cell->next(); - return _cell; - } - else - return 0; -} - -MEDCouplingUMeshCellByTypeEntry::MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh):_mesh(mesh) -{ - if(_mesh) - _mesh->incrRef(); -} - -MEDCouplingUMeshCellByTypeIterator *MEDCouplingUMeshCellByTypeEntry::iterator() -{ - return new MEDCouplingUMeshCellByTypeIterator(_mesh); -} - -MEDCouplingUMeshCellByTypeEntry::~MEDCouplingUMeshCellByTypeEntry() -{ - if(_mesh) - _mesh->decrRef(); -} - -MEDCouplingUMeshCellEntry::MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh, INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_type(type), - _itc(itc), - _bg(bg),_end(end) -{ - if(_mesh) - _mesh->incrRef(); -} - -MEDCouplingUMeshCellEntry::~MEDCouplingUMeshCellEntry() -{ - if(_mesh) - _mesh->decrRef(); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCellEntry::getType() const -{ - return _type; -} - -int MEDCouplingUMeshCellEntry::getNumberOfElems() const -{ - return _end-_bg; -} - -MEDCouplingUMeshCellIterator *MEDCouplingUMeshCellEntry::iterator() -{ - return new MEDCouplingUMeshCellIterator(_mesh,_itc,_bg,_end); -} - -MEDCouplingUMeshCellByTypeIterator::MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),_cell_id(0),_nb_cell(0) -{ - if(mesh) - { - mesh->incrRef(); - _nb_cell=mesh->getNumberOfCells(); - } -} - -MEDCouplingUMeshCellByTypeIterator::~MEDCouplingUMeshCellByTypeIterator() -{ - if(_mesh) - _mesh->decrRef(); - delete _cell; -} - -MEDCouplingUMeshCellEntry *MEDCouplingUMeshCellByTypeIterator::nextt() -{ - const int *c=_mesh->getNodalConnectivity()->getConstPointer(); - const int *ci=_mesh->getNodalConnectivityIndex()->getConstPointer(); - if(_cell_id<_nb_cell) - { - INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[_cell_id]]; - int nbOfElems=(int)std::distance(ci+_cell_id,std::find_if(ci+_cell_id,ci+_nb_cell,ParaMEDMEMImpl::ConnReader(c,type))); - int startId=_cell_id; - _cell_id+=nbOfElems; - return new MEDCouplingUMeshCellEntry(_mesh,type,_cell,startId,_cell_id); - } - else - return 0; -} - -MEDCouplingUMeshCell::MEDCouplingUMeshCell(MEDCouplingUMesh *mesh):_conn(0),_conn_indx(0),_conn_lgth(NOTICABLE_FIRST_VAL) -{ - if(mesh) - { - _conn=mesh->getNodalConnectivity()->getPointer(); - _conn_indx=mesh->getNodalConnectivityIndex()->getPointer(); - } -} - -void MEDCouplingUMeshCell::next() -{ - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - { - _conn+=_conn_lgth; - _conn_indx++; - } - _conn_lgth=_conn_indx[1]-_conn_indx[0]; -} - -std::string MEDCouplingUMeshCell::repr() const -{ - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - { - std::ostringstream oss; oss << "Cell Type " << INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)_conn[0]).getRepr(); - oss << " : "; - std::copy(_conn+1,_conn+_conn_lgth,std::ostream_iterator(oss," ")); - return oss.str(); - } - else - return std::string("MEDCouplingUMeshCell::repr : Invalid pos"); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCell::getType() const -{ - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - return (INTERP_KERNEL::NormalizedCellType)_conn[0]; - else - return INTERP_KERNEL::NORM_ERROR; -} - -const int *MEDCouplingUMeshCell::getAllConn(int& lgth) const -{ - lgth=_conn_lgth; - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - return _conn; - else - return 0; -} diff --git a/medtool/src/MEDCoupling/MEDCouplingUMesh.hxx b/medtool/src/MEDCoupling/MEDCouplingUMesh.hxx deleted file mode 100644 index e3bb9c6d7..000000000 --- a/medtool/src/MEDCoupling/MEDCouplingUMesh.hxx +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDMEM_MEDCOUPLINGUMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGUMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingMemArray.hxx" - -#include "CellModel.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingUMeshCellByTypeEntry; - class MEDCouplingUMeshCellIterator; - class MEDCoupling1SGTUMesh; - class MEDCoupling1GTUMesh; - class MEDCouplingSkyLineArray; - - class MEDCouplingUMesh : public MEDCouplingPointSet - { - public: - MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(const std::string& meshName, int meshDim); - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; - MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; } - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT void setMeshDimension(int meshDim); - MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); - MEDCOUPLING_EXPORT void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell); - MEDCOUPLING_EXPORT void finishInsertingCells(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator *cellIterator(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeEntry *cellsByType(); - MEDCOUPLING_EXPORT std::set getAllGeoTypes() const; - MEDCOUPLING_EXPORT std::vector getAllGeoTypesSorted() const; - MEDCOUPLING_EXPORT std::set getTypesOfPart(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); - MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivity() const { return _nodal_connec; } - MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; } - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() { return _nodal_connec; } - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() { return _nodal_connec_index; } - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT std::string cppRepr() const; - MEDCOUPLING_EXPORT std::string reprConnectivityOfThis() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const; - MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT int getMeshLength() const; - MEDCOUPLING_EXPORT void computeTypes(); - //! size of returned tinyInfo must be always the same. - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); - MEDCOUPLING_EXPORT std::string getVTKDataSetType() const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - //tools - MEDCOUPLING_EXPORT static int AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType); - MEDCOUPLING_EXPORT static int AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT void convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd); - MEDCOUPLING_EXPORT void convertAllToPoly(); - MEDCOUPLING_EXPORT void convertExtrudedPolyhedra(); - MEDCOUPLING_EXPORT bool unPolyze(); - MEDCOUPLING_EXPORT void simplifyPolyhedra(double eps); - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSpreadZonesWithPoly() const; - MEDCOUPLING_EXPORT std::vector partitionBySpreadZone() const; - MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; - MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer(); - MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; - MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT void computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; - MEDCOUPLING_EXPORT static void ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, - DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); - MEDCOUPLING_EXPORT void computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; - MEDCOUPLING_EXPORT void setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis); - MEDCOUPLING_EXPORT void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; - MEDCOUPLING_EXPORT DataArrayInt *findCellIdsOnBoundary() const; - MEDCOUPLING_EXPORT void findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *computeSkin() const; - MEDCOUPLING_EXPORT void findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, - DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const; - MEDCOUPLING_EXPORT void duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); - MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); - MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N); - MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); - MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta); - MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset); - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT DataArrayDouble *getPartMeasureField(bool isAbs, const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildPartOrthogonalField(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildDirectionVectorField() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const; - MEDCOUPLING_EXPORT bool isContiguous1D() const; - MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const; - MEDCOUPLING_EXPORT double distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const; - MEDCOUPLING_EXPORT DataArrayDouble *distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; - MEDCOUPLING_EXPORT void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; - MEDCOUPLING_EXPORT void checkButterflyCells(std::vector& cells, double eps=1e-12) const; - MEDCOUPLING_EXPORT DataArrayInt *convexEnvelop2D(); - MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DExtrudedCells(); - MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DCells(); - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTreeFast() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); - MEDCOUPLING_EXPORT bool isFullyQuadratic() const; - MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; - MEDCOUPLING_EXPORT void convertQuadraticCellsToLinear(); - MEDCOUPLING_EXPORT DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0); - MEDCOUPLING_EXPORT void tessellate2D(double eps); - MEDCOUPLING_EXPORT void tessellate2DCurve(double eps); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT bool areOnlySimplexCells() const; - MEDCOUPLING_EXPORT void convertDegeneratedCells(); - MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const; - MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly); - MEDCOUPLING_EXPORT void changeOrientationOfCells(); - MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector& cells) const; - MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons(); - MEDCOUPLING_EXPORT void getFastAveragePlaneOfThis(double *vec, double *pos) const; - //Mesh quality - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getEdgeRatioField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getAspectRatioField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getWarpField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getSkewField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; - //utilities for MED File RW - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const; - MEDCOUPLING_EXPORT DataArrayInt *sortCellsInMEDFileFrmt(); - MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; - MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesForMEDFileFrmt() const; - MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const; - MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForMEDFileFrmt() const; - MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); - MEDCOUPLING_EXPORT std::vector splitByType() const; - MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const; - MEDCOUPLING_EXPORT void convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndex) const; - MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, - DataArrayInt *&szOfCellGrpOfSameType, - DataArrayInt *&idInMsOfCellGrpOfSameType); - MEDCOUPLING_EXPORT DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const; - MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; - MEDCOUPLING_EXPORT std::vector getQuadraticStatus() const; - // - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayDouble *getPartBarycenterAndOwner(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT DataArrayDouble *computePlaneEquationOf3DFaces() const; - MEDCOUPLING_EXPORT DataArrayInt *conformize2D(double eps); - MEDCOUPLING_EXPORT DataArrayInt *colinearize2D(double eps); - MEDCOUPLING_EXPORT int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(std::vector& a); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector& meshes); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); - MEDCOUPLING_EXPORT static void PutUMeshesOnSameAggregatedCoords(const std::vector& meshes); - MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps); - MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static bool Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static void CorrectExtrudedStaticCell(int *begin, int *end); - MEDCOUPLING_EXPORT static bool IsTetra4WellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static bool IsPyra5WellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res); - MEDCOUPLING_EXPORT static void ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p); - MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2); - MEDCOUPLING_EXPORT static void Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, - double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D); - MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut); - MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0); - MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); - MEDCOUPLING_EXPORT static void FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, - DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr); - MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf2DMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf3DMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *orderConsecutiveCells1D() const; - MEDCOUPLING_EXPORT MEDCouplingSkyLineArray *generateGraph() const; - private: - MEDCouplingUMesh(); - MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); - ~MEDCouplingUMesh(); - void checkFullyDefined() const; - void checkConnectivityFullyDefined() const; - void reprConnectivityOfThisLL(std::ostringstream& stream) const; - //tools - DataArrayInt *simplexizePol0(); - DataArrayInt *simplexizePol1(); - DataArrayInt *simplexizePlanarFace5(); - DataArrayInt *simplexizePlanarFace6(); - void subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex); - void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; - void split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve); - MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - static bool AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; - MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; - DataArrayInt *convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; - DataArrayInt *buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; - template - void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, - double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; -/// @cond INTERNAL - static MEDCouplingUMesh *MergeUMeshesLL(std::vector& a); - typedef int (*DimM1DescNbrer)(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2); - template - MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const; - static void DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId); - static void DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId); - static DataArrayInt *ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); - static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt); - static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); - static void Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo, std::map& mergedNodes); - static void IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, - std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, - MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1, - std::vector& addCoo, - MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2); - static void BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector& addCoo, const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge); - static void BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector >& intesctEdges1, const std::vector< std::vector >& colinear2, - const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector >& intesctEdges2, - const std::vector& addCoords, - std::vector& addCoordsQuadratic, std::vector& cr, std::vector& crI, std::vector& cNb1, std::vector& cNb2); - static void AssemblyForSplitFrom3DCurve(const std::vector& cut3DCurve, std::vector& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf, - const int *nodal3DCurve, const int *nodalIndx3DCurve, - const int *desc, const int *descIndx, std::vector< std::pair >& cut3DSurf); - void assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, - const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const; - void split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI); - int split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI); - static bool Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords); - static void ComputeAllTypesInternal(std::set& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex); - public: - MEDCOUPLING_EXPORT static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector& code); - MEDCOUPLING_EXPORT static const int N_MEDMEM_ORDER=24; - MEDCOUPLING_EXPORT static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N_MEDMEM_ORDER]; - /// @endcond - private: - int _mesh_dim; - DataArrayInt *_nodal_connec; - DataArrayInt *_nodal_connec_index; - std::set _types; - public: - static double EPS_FOR_POLYH_ORIENTATION; - }; - - class MEDCouplingUMeshCell; - - class MEDCouplingUMeshCellIterator - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellIterator(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCell *nextt(); - private: - MEDCouplingUMesh *_mesh; - MEDCouplingUMeshCell *_cell; - bool _own_cell; - int _cell_id; - int _nb_cell; - }; - - class MEDCouplingUMeshCellByTypeIterator; - - class MEDCouplingUMeshCellByTypeEntry - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeIterator *iterator(); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellByTypeEntry(); - private: - MEDCouplingUMesh *_mesh; - }; - - class MEDCouplingUMeshCellEntry - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh, INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellEntry(); - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const; - MEDCOUPLING_EXPORT int getNumberOfElems() const; - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator *iterator(); - private: - MEDCouplingUMesh *_mesh; - INTERP_KERNEL::NormalizedCellType _type; - MEDCouplingUMeshCell *_itc; - int _bg; - int _end; - }; - - class MEDCouplingUMeshCellByTypeIterator - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellByTypeIterator(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellEntry *nextt(); - private: - MEDCouplingUMesh *_mesh; - MEDCouplingUMeshCell *_cell; - int _cell_id; - int _nb_cell; - }; - - class MEDCouplingUMeshCell - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCell(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT void next(); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const; - MEDCOUPLING_EXPORT const int *getAllConn(int& lgth) const; - private: - int *_conn; - int *_conn_indx; - int _conn_lgth; - static const int NOTICABLE_FIRST_VAL=-7; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/CMakeLists.txt b/medtool/src/MEDCoupling/Test/CMakeLists.txt deleted file mode 100644 index 89e65948e..000000000 --- a/medtool/src/MEDCoupling/Test/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -ADD_DEFINITIONS(${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${PTHREADS_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/GaussPoints - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest - ) - -SET(TestMEDCoupling_SOURCES - MEDCouplingBasicsTestInterp.cxx - TestMEDCoupling.cxx - MEDCouplingBasicsTest0.cxx - MEDCouplingBasicsTest1.cxx - MEDCouplingBasicsTest2.cxx - MEDCouplingBasicsTest3.cxx - MEDCouplingBasicsTest4.cxx - MEDCouplingBasicsTest5.cxx - ) - -SET(TestMEDCouplingRemapper_SOURCES - TestMEDCouplingRemapper.cxx - MEDCouplingRemapperTest.cxx - MEDCouplingBasicsTest0.cxx - ) - -SET(TestMEDCouplingExamples_SOURCES - MEDCouplingExamplesTest.cxx - MEDCouplingBasicsTest0.cxx - ) - -ADD_EXECUTABLE(TestMEDCoupling ${TestMEDCoupling_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDCoupling medcoupling ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDCoupling TestMEDCoupling) - -ADD_EXECUTABLE(TestMEDCouplingRemapper ${TestMEDCouplingRemapper_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDCouplingRemapper medcouplingremapper ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDCouplingRemapper TestMEDCouplingRemapper) - -ADD_EXECUTABLE(TestMEDCouplingExamples ${TestMEDCouplingExamples_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDCouplingExamples medcoupling ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDCouplingExamples TestMEDCouplingExamples) - -INSTALL(TARGETS TestMEDCoupling TestMEDCouplingRemapper TestMEDCouplingExamples DESTINATION ${MEDCOUPLING_INSTALL_BINS}) - -SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES UnitTestsResult) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDCoupling) -INSTALL(TARGETS TestMEDCoupling TestMEDCouplingRemapper TestMEDCouplingExamples DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/MEDCoupling/Test/CTestTestfileInstall.cmake b/medtool/src/MEDCoupling/Test/CTestTestfileInstall.cmake deleted file mode 100644 index fa82537e4..000000000 --- a/medtool/src/MEDCoupling/Test/CTestTestfileInstall.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(TestMEDCoupling TestMEDCoupling) -SET_TESTS_PROPERTIES(TestMEDCoupling PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(TestMEDCouplingRemapper TestMEDCouplingRemapper) -SET_TESTS_PROPERTIES(TestMEDCouplingRemapper PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(TestMEDCouplingExamples TestMEDCouplingExamples) -SET_TESTS_PROPERTIES(TestMEDCouplingExamples PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx deleted file mode 100644 index be5313b08..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTEST_HXX__ -#define __MEDCOUPLINGBASICSTEST_HXX__ - -#include - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest : public CppUnit::TestFixture - { - public: - static MEDCouplingUMesh *build3DSourceMesh_2(); - static MEDCouplingUMesh *build3DTargetMesh_2(); - static MEDCouplingUMesh *build1DTargetMesh_1(); - static MEDCouplingUMesh *build2DSourceMesh_1(); - static MEDCouplingUMesh *build2DTargetMesh_1(); - static MEDCouplingUMesh *build2DTargetMeshPerm_1(); - static MEDCouplingUMesh *build2DTargetMesh_2(); - static MEDCouplingUMesh *buildCU1DMesh_U(); - static MEDCouplingUMesh *buildCU2DMesh_U(); - static MEDCouplingUMesh *buildCU3DMesh_U(); - static MEDCouplingUMesh *build3DSurfSourceMesh_1(); - static MEDCouplingUMesh *build3DSurfSourceMesh_2(); - static MEDCouplingUMesh *build3DSurfTargetMesh_1(); - static MEDCouplingUMesh *build3DSurfTargetMeshPerm_1(); - static MEDCouplingUMesh *build3DSurfTargetMesh_2(); - static MEDCouplingUMesh *build3DSourceMesh_1(); - static MEDCouplingUMesh *build3DTargetMesh_1(); - static MEDCouplingUMesh *build2DTargetMeshMergeNode_1(); - static MEDCouplingUMesh *build3DTargetMeshMergeNode_1(); - static MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D); - static void build3DExtrudedUMesh_2(MEDCouplingUMesh *&meshN, MEDCouplingUMesh *&meshTT, MEDCouplingUMesh *&meshTF); - static MEDCouplingUMesh *build2DTargetMeshMerged_1(); - static MEDCouplingUMesh *build2DCurveMesh(double dx, double dy); - static MEDCouplingUMesh *build1DMesh(double dx); - static MEDCouplingUMesh *build1DSourceMesh_2(); - static MEDCouplingUMesh *build1DTargetMesh_2(); - static MEDCouplingUMesh *build2DCurveSourceMesh_2(); - static MEDCouplingUMesh *build2DCurveTargetMesh_2(); - static MEDCouplingUMesh *build1DTargetMesh_3(); - static MEDCouplingUMesh *build2DCurveTargetMesh_3(); - static MEDCouplingUMesh *build2DTargetMesh_3(); - static MEDCouplingUMesh *build3DTargetMesh_3(); - static MEDCouplingUMesh *build2DTargetMesh_4(); - static MEDCouplingUMesh *build1DMultiTypes_1(); - static MEDCouplingUMesh *build2DMultiTypes_1(); - static MEDCouplingUMesh *build3DMultiTypes_1(); - static MEDCouplingUMesh *buildHexa8Mesh_1(); - static MEDCouplingUMesh *buildPointe_1(MEDCouplingUMesh *&m1); - - static MEDCouplingUMesh *build2D1DSourceMesh(); - static MEDCouplingUMesh *build2D1DTargetMesh(); - static MEDCouplingUMesh *build2D1DSegSourceMesh(const double shiftX = 0., - const double inclinationX = 0.); - static MEDCouplingUMesh *build2D1DQuadTargetMesh(const double inclinaisonX = 0.); - static MEDCouplingUMesh *build2D1DTriTargetMesh(const double inclinaisonX = 0.); - static MEDCouplingUMesh *build3D2DSourceMesh(); - static MEDCouplingUMesh *build3D2DTargetMesh(); - static MEDCouplingUMesh* build3D2DQuadSourceMesh(const double shiftX = 0., - const double inclinationX = 0.); - static MEDCouplingUMesh* build3D2DTriSourceMesh(const double shiftX = 0., - const double inclinationX = 0.); - static MEDCouplingUMesh* build3D2DTetraTargetMesh(const double inclinaisonX = 0.); - static MEDCouplingUMesh* build3D2DHexaTargetMesh(const double inclinaisonX = 0.); - - static DataArrayDouble *buildCoordsForMultiTypes_1(); - static MEDCouplingMultiFields *buildMultiFields_1(); - static std::vector buildMultiFields_2(); - static double sumAll(const std::vector< std::map >& matrix); - protected: - static int countNonZero(const std::vector< std::map >& matrix); - - static void test2D1DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctSurf, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr = -1); - static void test3D2DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctSurf, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr = -1); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx deleted file mode 100644 index f42235c44..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx +++ /dev/null @@ -1,1716 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - -#include "MEDCouplingBasicsTestData1.hxx" - -#include "Interpolation2D.txx" -#include "Interpolation3D2D.txx" -#include "Interpolation2D1D.txx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingNormalizedCartesianMesh.txx" - -using namespace ParaMEDMEM; - -typedef std::vector > IntersectionMatrix; - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_2() -{ - double sourceCoords[84]={100.0, 100.0, 0.0, 100.0, 100.0, 100.0, 100.0, 0.0, 100.0, 100.0, 0.0, 0.0, 0.0, 100.0, 0.0, 0.0, 100.0, 100.0, 0.0, - 0.0, 100.0, 0.0, 0.0, 0.0, 100.0, 100.0, 200.0, 100.0, 0.0, 200.0, 0.0, 100.0, 200.0, 0.0, 0.0, 200.0, 100.0, 200.0, - 0.0, 100.0, 200.0, 100.0, 0.0, 200.0, 0.0, 0.0, 200.0, 100.0, 100.0, 200.0, 200.0, 0.0, 200.0, 200.0, 200.0, 100.0, - 0.0, 200.0, 100.00000000833332, 100.00000000833332, 200.0, 0.0, 100.0, 200.0, 0.0, 0.0, 200.0, 100.0, 200.0, 200.0, - 0.0, 200.0, 200.0, 200.0, 0.0, 200.0, 200.0, 100.0, 200.0, 200.0, 200.0, 149.999999970343, 149.9999999874621, 49.999999881628682}; - - - int sourceConn[212]={25, 27, 13, 19, 18, 3, 20, 21, 5, 10, 17, 1, 1, 3, 0, 7, 18, 1, 0, 27, 12, 27, 13, 24, 25, 19, 16, 26, 1, 2, 6, 8, 15, 13, - 12, 5, 24, 13, 25, 27, 10, 11, 9, 6, 19, 8, 23, 1, 22, 8, 23, 19, 16, 13, 17, 1, 6, 9, 10, 8, 13, 17, 5, 15, 5, 4, 1, 12, 18, - 0, 24, 27, 19, 20, 18, 1, 7, 6, 5, 1, 4, 12, 15, 14, 25, 27, 19, 18, 1, 19, 16, 13, 20, 19, 23, 1, 27, 12, 1, 0, 6, 5, 1, 10, - 4, 5, 1, 7, 12, 27, 1, 13, 5, 15, 4, 12, 19, 16, 26, 22, 13, 5, 17, 1, 1, 3, 7, 2, 13, 5, 1, 12, 18, 1, 3, 0, 8, 23, 2, 9, 3, - 1, 18, 20, 1, 27, 19, 13, 24, 25, 18, 27, 25, 16, 19, 13, 7, 1, 2, 6, 3, 1, 20, 2, 8, 16, 17, 1, 7, 4, 0, 1, 18, 19, 1, 27, - 27, 12, 0, 24, 9, 6, 2, 8, 1, 4, 0, 12, 19, 16, 22, 8, 8, 2, 23, 1, 1, 16, 19, 8, 20, 2, 1, 23, 10, 1, 6, 8, 10, 8, 17, 1}; - - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(3); - sourceMesh->allocateCells(53); - for(int i=0;i<53;i++) - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4*i); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(28,3); - std::copy(sourceCoords,sourceCoords+84,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_2() -{ - double targetCoords[24]={200.0, 200.0, 0.0, 200.0, 200.0, 200.0, 200.0, 0.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 0.0, 200.0, 200.0, 0.0, 0.0, 0.0, 0.0, 0.0, 200.0}; - int targetConn[20]={5, 6, 3, 0, 1, 3, 0, 5, 3, 6, 5, 7, 6, 4, 0, 5, 6, 3, 0, 2}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(5); - for(int i=0;i<5;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn+4*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(8,3); - std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_1() -{ - double targetCoords[36]={ - 25.,25.,0., 25.,25.,50., 25.,25.,200., 75.,25.,0., 75.,25.,50., 75.,25.,200., - 25.,125.,0., 25.,125.,50., 25.,125.,200., 125.,125.,0., 125.,125.,50., 125.,125.,200. - }; - int targetConn[16]={0,1, 1,2, 3,4, 4,5, 6,7, 7,8, 9,10, 10,11}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("my name of mesh 1D",1); - targetMesh->allocateCells(8); - for(int i=0;i<8;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,3); - std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DSourceMesh_1() -{ - double sourceCoords[8]={-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7}; - int sourceConn[6]={0,3,1,0,2,3}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New("my name of mesh 2D",2); - sourceMesh->allocateCells(2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_1() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshPerm_1() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_2() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[24]={0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 }; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(8); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+9); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+15); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU1DMesh_U() -{ - double coords[4]={ 0.0, 0.3, 0.75, 1.0 }; - int conn[2*3]={ 0,1, 1,2, 2,3 }; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(1); - mesh->allocateCells(3); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,1); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} -MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU2DMesh_U() -{ - double coords[18]={0.0,0.0, 0.5,0.0, 1.0,0.0, 0.0,0.5, 0.5,0.5, 1.0,0.5, 0.0,1.0, 0.5,1.0, 1.0,1.0 }; - int conn[18]={0,1,4,3, 3,4,7,6, 4,5,8,7, 1,5,4, 1,2,5 }; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+8); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+12); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+15); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(coords,coords+18,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} -MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU3DMesh_U() -{ - double coords[27*3]= - { -// 0.0,1.0,0.0 ,0.0,0.3,0.0 ,0.0,0.3,0.3 ,0.3,0.0,0.0 ,0.3,0.3,1.0 ,1.0,0.0,1.0 ,1.0,0.0,0.3 ,0.3,0.0,0.3 ,0.3,1.0,0.3 ,0.0,0.3,1.0 ,0.3,0.0,1.0 ,0.3,0.3,0.3 ,1.0,0.3,1.0 ,1.0,0.0,0.0 ,0.0,0.0,0.0 ,1.0,0.3,0.3 ,0.3,1.0,0.0 ,1.0,1.0,0.3 ,1.0,1.0,1.0 ,0.0,1.0,1.0 ,0.3,0.3,0.0 ,0.0,1.0,0.3 ,0.0,0.0,1.0 ,0.3,1.0,1.0 ,1.0,0.3,0.0 ,0.0,0.0,0.3 ,1.0,1.0,0.0 - 0.0,0.0,0.0, 0.3,0.0,0.0, 1.0,0.0,0.0, 0.0,0.3,0.0, 0.3,0.3,0.0, 1.0,0.3,0.0, 0.0,1.0,0.0, 0.3,1.0,0.0, 1.0,1.0,0.0, 0.0,0.0,0.3, 0.3,0.0,0.3, 1.0,0.0,0.3, 0.0,0.3,0.3, 0.3,0.3,0.3, 1.0,0.3,0.3, 0.0,1.0,0.3, 0.3,1.0,0.3, 1.0,1.0,0.3, 0.0,0.0,1.0, 0.3,0.0,1.0, 1.0,0.0,1.0, 0.0,0.3,1.0, 0.3,0.3,1.0, 1.0,0.3,1.0, 0.0,1.0,1.0, 0.3,1.0,1.0, 1.0,1.0,1.0, - }; - int conn[8*8]= - { -// 11,15,12,4,8,17,18,23,3,13,6,7,20,24,15,11,14,3,7,25,1,20,11,2,1,20,11,2,0,16,8,21,20,24,15,11,16,26,17,8,25,7,10,22,2,11,4,9,2,11,4,9,21,8,23,19,7,6,5,10,11,15,12,4 - 0,3,4,1,9,12,13,10, 1,4,5,2,10,13,14,11, 3,6,7,4,12,15,16,13, 4,7,8,5,13,16,17,14, 9,12,13,10,18,21,22,19, 10,13,14,11,19,22,23,20, 12,15,16,13,21,24,25,22, 13,16,17,14,22,25,26,23 - }; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(3); - mesh->allocateCells(8); - for(int i=0;i<8;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8*i); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(27,3); - std::copy(coords,coords+27*3,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_1() -{ - double sourceCoords[12]={-0.3,-0.3,0.5, 0.7,-0.3,1.5, -0.3,0.7,0.5, 0.7,0.7,1.5}; - int sourceConn[6]={0,3,1,0,2,3}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_2() -{ - double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.}; - int sourceConn[6]={0,3,1,0,2,3}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_1() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -/*! - * Idem build3DSurfTargetMesh_1 except that cell id 2 is not correctly numbered. - */ -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMeshPerm_1() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - int targetConn[18]={0,3,4,1, 1,4,2, 4,2,5, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_2() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - int targetConn[24]={0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 }; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(8); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+9); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+15); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_1() -{ - double sourceCoords[27]={ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, - 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0 }; - int sourceConn[48]={8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(3); - sourceMesh->allocateCells(12); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+8); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+12); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+16); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+20); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+24); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+28); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+32); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+36); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+40); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+44); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(sourceCoords,sourceCoords+27,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_1() -{ - double targetCoords[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. }; - int targetConn[64]={0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(12); - for(int i=0;i<8;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(27,3); - std::copy(targetCoords,targetCoords+81,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMergeNode_1() -{ - double targetCoords[36]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 }; - int targetConn[18]={0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(18,2); - std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMeshMergeNode_1() -{ - double targetCoords[93]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.}; - int targetConn[64]={0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(12); - for(int i=0;i<8;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(31,3); - std::copy(targetCoords,targetCoords+93,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D) -{ - double coords[180]={ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; - - int conn[354]={ - // 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - // 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - // 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58 - }; - int conn2[28]={7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3}; - // - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setMeshDimension(3); - ret->allocateCells(18); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); - // - ret->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(60,3); - std::copy(coords,coords+180,myCoords->getPointer()); - ret->setCoords(myCoords); - // - mesh2D=MEDCouplingUMesh::New(); - mesh2D->setMeshDimension(2); - mesh2D->allocateCells(6); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+4); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+10); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+14); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+18); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+24); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -void MEDCouplingBasicsTest::build3DExtrudedUMesh_2(MEDCouplingUMesh *&meshN, MEDCouplingUMesh *&meshTT, MEDCouplingUMesh *&meshTF) -{ - const double coordsN[270]={ - 0, 0, 0, 0.10803000450134277, 0, 0, 0.21606000900268554, 0, 0, 0.28808000564575198, 0, 0, 0.36010002136230468, 0, 0, 0.43212001800537109, 0, 0, 0, - 0.072020001411437995, 0, 0.10803000450134277, 0.072020001411437995, 0, 0.21606000900268554, 0.072020001411437995, 0, 0.28808000564575198, 0.072020001411437995, - 0, 0.36010002136230468, 0.072020001411437995, 0, 0.43212001800537109, 0.072020001411437995, 0, 0, 0.10803000450134277, 0, 0.10803000450134277, - 0.10803000450134277, 0, 0.21606000900268554, 0.10803000450134277, 0, 0.28808000564575198, 0.10803000450134277, 0, 0.36010002136230468, 0.10803000450134277, 0, - 0.43212001800537109, 0.10803000450134277, 0, 0, 0.14404000282287599, 0, 0.10803000450134277, 0.14404000282287599, 0, 0.21606000900268554, 0.14404000282287599, 0, - 0.28808000564575198, 0.14404000282287599, 0, 0.36010002136230468, 0.14404000282287599, 0, 0.43212001800537109, 0.14404000282287599, 0, 0, 0.21606000900268554, 0, - 0.10803000450134277, 0.21606000900268554, 0, 0.21606000900268554, 0.21606000900268554, 0, 0.28808000564575198, 0.21606000900268554, 0, 0.36010002136230468, - 0.21606000900268554, 0, 0.43212001800537109, 0.21606000900268554, 0, 0, 0, 2.1364999389648438, 0.10803000450134277, 0, 2.1364999389648438, 0.21606000900268554, - 0, 2.1364999389648438, 0.28808000564575198, 0, 2.1364999389648438, 0.36010002136230468, 0, 2.1364999389648438, 0.43212001800537109, 0, 2.1364999389648438, 0, - 0.072020001411437995, 2.1364999389648438, 0.10803000450134277, 0.072020001411437995, 2.1364999389648438, 0.21606000900268554, 0.072020001411437995, - 2.1364999389648438, 0.28808000564575198, 0.072020001411437995, 2.1364999389648438, 0.36010002136230468, 0.072020001411437995, 2.1364999389648438, - 0.43212001800537109, 0.072020001411437995, 2.1364999389648438, 0, 0.10803000450134277, 2.1364999389648438, 0.10803000450134277, 0.10803000450134277, - 2.1364999389648438, 0.21606000900268554, 0.10803000450134277, 2.1364999389648438, 0.28808000564575198, 0.10803000450134277, 2.1364999389648438, - 0.36010002136230468, 0.10803000450134277, 2.1364999389648438, 0.43212001800537109, 0.10803000450134277, 2.1364999389648438, 0, 0.14404000282287599, - 2.1364999389648438, 0.10803000450134277, 0.14404000282287599, 2.1364999389648438, 0.21606000900268554, 0.14404000282287599, 2.1364999389648438, - 0.28808000564575198, 0.14404000282287599, 2.1364999389648438, 0.36010002136230468, 0.14404000282287599, 2.1364999389648438, 0.43212001800537109, - 0.14404000282287599, 2.1364999389648438, 0, 0.21606000900268554, 2.1364999389648438, 0.10803000450134277, 0.21606000900268554, 2.1364999389648438, - 0.21606000900268554, 0.21606000900268554, 2.1364999389648438, 0.28808000564575198, 0.21606000900268554, 2.1364999389648438, 0.36010002136230468, - 0.21606000900268554, 2.1364999389648438, 0.43212001800537109, 0.21606000900268554, 2.1364999389648438, 0, 0, 4.2729998779296876, 0.10803000450134277, 0, - 4.2729998779296876, 0.21606000900268554, 0, 4.2729998779296876, 0.28808000564575198, 0, 4.2729998779296876, 0.36010002136230468, 0, 4.2729998779296876, - 0.43212001800537109, 0, 4.2729998779296876, 0, 0.072020001411437995, 4.2729998779296876, 0.10803000450134277, 0.072020001411437995, 4.2729998779296876, - 0.21606000900268554, 0.072020001411437995, 4.2729998779296876, 0.28808000564575198, 0.072020001411437995, 4.2729998779296876, 0.36010002136230468, - 0.072020001411437995, 4.2729998779296876, 0.43212001800537109, 0.072020001411437995, 4.2729998779296876, 0, 0.10803000450134277, 4.2729998779296876, - 0.10803000450134277, 0.10803000450134277, 4.2729998779296876, 0.21606000900268554, 0.10803000450134277, 4.2729998779296876, 0.28808000564575198, - 0.10803000450134277, 4.2729998779296876, 0.36010002136230468, 0.10803000450134277, 4.2729998779296876, 0.43212001800537109, 0.10803000450134277, - 4.2729998779296876, 0, 0.14404000282287599, 4.2729998779296876, 0.10803000450134277, 0.14404000282287599, 4.2729998779296876, 0.21606000900268554, - 0.14404000282287599, 4.2729998779296876, 0.28808000564575198, 0.14404000282287599, 4.2729998779296876, 0.36010002136230468, 0.14404000282287599, - 4.2729998779296876, 0.43212001800537109, 0.14404000282287599, 4.2729998779296876, 0, 0.21606000900268554, 4.2729998779296876, 0.10803000450134277, - 0.21606000900268554, 4.2729998779296876, 0.21606000900268554, 0.21606000900268554, 4.2729998779296876, 0.28808000564575198, 0.21606000900268554, - 4.2729998779296876, 0.36010002136230468, 0.21606000900268554, 4.2729998779296876, 0.43212001800537109, 0.21606000900268554, 4.2729998779296876}; - const int connN[320]={ - 0, 1, 7, 6, 30, 31, 37, 36, 1, 2, 8, 7, 31, 32, 38, 37, 2, 3, 9, 8, 32, 33, 39, 38, 3, 4, 10, 9, 33, 34, 40, 39, 4, 5, 11, 10, 34, 35, 41, 40, 6, - 7, 13, 12, 36, 37, 43, 42, 7, 8, 14, 13, 37, 38, 44, 43, 8, 9, 15, 14, 38, 39, 45, 44, 9, 10, 16, 15, 39, 40, 46, 45, 10, 11, 17, 16, 40, 41, 47, - 46, 12, 13, 19, 18, 42, 43, 49, 48, 13, 14, 20, 19, 43, 44, 50, 49, 14, 15, 21, 20, 44, 45, 51, 50, 15, 16, 22, 21, 45, 46, 52, 51, 16, 17, 23, - 22, 46, 47, 53, 52, 18, 19, 25, 24, 48, 49, 55, 54, 19, 20, 26, 25, 49, 50, 56, 55, 20, 21, 27, 26, 50, 51, 57, 56, 21, 22, 28, 27, 51, 52, 58, - 57, 22, 23, 29, 28, 52, 53, 59, 58, 30, 31, 37, 36, 60, 61, 67, 66, 31, 32, 38, 37, 61, 62, 68, 67, 32, 33, 39, 38, 62, 63, 69, 68, 33, 34, 40, - 39, 63, 64, 70, 69, 34, 35, 41, 40, 64, 65, 71, 70, 36, 37, 43, 42, 66, 67, 73, 72, 37, 38, 44, 43, 67, 68, 74, 73, 38, 39, 45, 44, 68, 69, 75, - 74, 39, 40, 46, 45, 69, 70, 76, 75, 40, 41, 47, 46, 70, 71, 77, 76, 42, 43, 49, 48, 72, 73, 79, 78, 43, 44, 50, 49, 73, 74, 80, 79, 44, 45, 51, - 50, 74, 75, 81, 80, 45, 46, 52, 51, 75, 76, 82, 81, 46, 47, 53, 52, 76, 77, 83, 82, 48, 49, 55, 54, 78, 79, 85, 84, 49, 50, 56, 55, 79, 80, 86, - 85, 50, 51, 57, 56, 80, 81, 87, 86, 51, 52, 58, 57, 81, 82, 88, 87, 52, 53, 59, 58, 82, 83, 89, 88}; - meshN=MEDCouplingUMesh::New(); - meshN->setName("meshExtrudedN"); - meshN->setMeshDimension(3); - meshN->allocateCells(40); - for(int i=0;i<40;i++) - meshN->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,connN+8*i); - meshN->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(90,3); - std::copy(coordsN,coordsN+270,myCoords->getPointer()); - meshN->setCoords(myCoords); - myCoords->decrRef(); - // - meshTT=MEDCouplingUMesh::New(); - meshTT->setName("meshExtrudedTT"); - meshTT->setMeshDimension(3); - meshTT->allocateCells(200); - for(int i=0;i<200;i++) - meshTT->insertNextCell(INTERP_KERNEL::NORM_POLYHED,connITT[i+1]-connITT[i],connTT+connITT[i]); - meshTT->finishInsertingCells(); - myCoords=DataArrayDouble::New(); - myCoords->alloc(1720,3); - std::copy(coordsTT,coordsTT+5160,myCoords->getPointer()); - meshTT->setCoords(myCoords); - myCoords->decrRef(); - // - meshTF=MEDCouplingUMesh::New(); - meshTF->setName("meshExtrudedTF"); - meshTF->setMeshDimension(3); - meshTF->allocateCells(340); - for(int i=0;i<320;i++) - meshTF->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,connTFH8+8*i); - for(int i=0;i<20;i++) - meshTF->insertNextCell(INTERP_KERNEL::NORM_POLYHED,connTFPOLH_I[i+1]-connTFPOLH_I[i],connTFPOLH+connTFPOLH_I[i]); - meshTF->finishInsertingCells(); - myCoords=DataArrayDouble::New(); - myCoords->alloc(567,3); - std::copy(coordsTF,coordsTF+1701,myCoords->getPointer()); - meshTF->setCoords(myCoords); - myCoords->decrRef(); -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMerged_1() -{ - double targetCoords[26]={ - -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 - }; - int targetConn[24]={ - 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, - 9,12,10,9,11,12 - }; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setName("merge"); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(13,2); - std::copy(targetCoords,targetCoords+26,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveMesh(double dx, double dy) -{ - // 1d mesh: - // - // * - // / - // *---* - double targetCoords[3*2]= - { - 0.+dx,0.+dy, 1.+dx,0.+dy, 2.+dx,1.+dy - }; - int targetConn[2*2]={1,2, 0,1}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("2Dcurve 1D mesh",1); - targetMesh->allocateCells(2); - for(int i=0;i<2;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(targetCoords,targetCoords+3*2,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMesh(double dx) -{ - double targetCoords[4]= - { - 0.+dx, 1.+dx, 3.+dx, 4.+dx - }; - int targetConn[2*3]={1,2, 0,1, 2,3}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("1D mesh",1); - targetMesh->allocateCells(3); - for(int i=0;i<3;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,1); - std::copy(targetCoords,targetCoords+4,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DSourceMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); - ret->allocateCells(4); - int conn[8]={0,1,2,3,1,2,3,4}; - for(int i=0;i<4;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[5]={0.3,0.7,0.9,1.0,1.12}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,1); - std::copy(coords,coords+5,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); - ret->allocateCells(2); - int conn[4]={1,2,0,1}; - for(int i=0;i<2;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[3]={0.5,0.75,1.2}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,1); - std::copy(coords,coords+3,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveSourceMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); - ret->allocateCells(4); - int conn[8]={0,1,2,3,1,2,3,4}; - for(int i=0;i<4;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[10]={0.3,0.3,0.7,0.7,0.9,0.9,1.0,1.0,1.12,1.12}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coords,coords+10,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); - ret->allocateCells(2); - int conn[4]={1,2,0,1}; - for(int i=0;i<2;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[6]={0.5,0.5,0.75,0.75,1.2,1.2}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_3() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DMesh_3",1); - ret->allocateCells(4); - int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); - ret->finishInsertingCells(); - double coords[10]={0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,1); - std::copy(coords,coords+10,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_3() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DCurveMesh_3",1); - ret->allocateCells(4); - int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); - ret->finishInsertingCells(); - double coords[20]={0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(coords,coords+20,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_3() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DMesh_3",2); - ret->allocateCells(10); - int conn[52]={ - 0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, - 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6 - }; - ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+3); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+7); - ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+12); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+18); - ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+26); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+29); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+33); - ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+38); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+44); - ret->finishInsertingCells(); - double coords[22]={0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(11,2); - std::copy(coords,coords+22,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - ret->checkCoherency(); - return ret; -} - -/*! - * Same as build2DTargetMesh_1 but with more nodes than needed. To check tryToShareSameCoordsPermute method. - */ -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_4() -{ - double targetCoords[20]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_3() -{ - return 0; -} - -MEDCouplingMultiFields *MEDCouplingBasicsTest::buildMultiFields_1() -{ - ParaMEDMEM::MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->setName("m1"); - ParaMEDMEM::MEDCouplingUMesh *m2=build2DTargetMesh_1(); - m2->setName("m2"); - const double vals0[]={-0.7,-1.,-2.,-3.,-4.}; - const double vals1[]={0.,1.,2.,3.,4.,0.1,0.2,0.3,0.4}; - const double vals1_1[]={170.,171.,172.,173.,174.,170.1,170.2,170.3,170.4}; - const double vals2[]={5.,6.,7.,8.,9.}; - const double vals4[]={15.,16.,17.,18.,19.}; - // - ParaMEDMEM::DataArrayDouble *d0=ParaMEDMEM::DataArrayDouble::New(); d0->alloc(5,1); std::copy(vals0,vals0+5,d0->getPointer()); - ParaMEDMEM::DataArrayDouble *d1=ParaMEDMEM::DataArrayDouble::New(); d1->alloc(9,1); std::copy(vals1,vals1+9,d1->getPointer()); - ParaMEDMEM::DataArrayDouble *d1_1=ParaMEDMEM::DataArrayDouble::New(); d1_1->alloc(9,1); std::copy(vals1_1,vals1_1+9,d1_1->getPointer()); - ParaMEDMEM::DataArrayDouble *d2=ParaMEDMEM::DataArrayDouble::New(); d2->alloc(5,1); std::copy(vals2,vals2+5,d2->getPointer()); - ParaMEDMEM::DataArrayDouble *d4=ParaMEDMEM::DataArrayDouble::New(); d4->alloc(5,1); std::copy(vals4,vals4+5,d4->getPointer()); - // - d0->setName("d0"); d1->setName("d1"); d1_1->setName("d1_1"); d2->setName("d2"); d4->setName("d4"); - d0->setInfoOnComponent(0,"c1"); - d1->setInfoOnComponent(0,"c6"); - d1_1->setInfoOnComponent(0,"c9"); - d2->setInfoOnComponent(0,"c5"); - d4->setInfoOnComponent(0,"c7"); - // - ParaMEDMEM::MEDCouplingFieldDouble *f0=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f0->setMesh(m1); - f0->setArray(d0); - f0->setTime(0.2,5,6); - f0->setName("f0"); - ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::LINEAR_TIME); - f1->setMesh(m1); - std::vector d1s(2); d1s[0]=d1; d1s[1]=d1_1; - f1->setArrays(d1s); - f1->setStartTime(0.7,7,8); - f1->setEndTime(1.2,9,10); - f1->setName("f1"); - ParaMEDMEM::MEDCouplingFieldDouble *f2=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::CONST_ON_TIME_INTERVAL); - f2->setMesh(m2); - f2->setArray(d2); - f2->setTime(1.2,11,12); - f2->setEndTime(1.5,13,14); - f2->setName("f2"); - ParaMEDMEM::MEDCouplingFieldDouble *f3=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f3->setMesh(m1); - f3->setArray(d2); - f3->setTime(1.7,15,16); - f3->setName("f3"); - ParaMEDMEM::MEDCouplingFieldDouble *f4=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); - f4->setMesh(m2); - f4->setArray(d4); - f4->setName("f4"); - // - std::vector fs(5); - fs[0]=f0; fs[1]=f1; fs[2]=f2; fs[3]=f3; fs[4]=f4; - ParaMEDMEM::MEDCouplingMultiFields *ret=ParaMEDMEM::MEDCouplingMultiFields::New(fs); - // - m1->decrRef(); - m2->decrRef(); - d0->decrRef(); - d1->decrRef(); - d1_1->decrRef(); - d2->decrRef(); - d4->decrRef(); - f0->decrRef(); - f1->decrRef(); - f2->decrRef(); - f3->decrRef(); - f4->decrRef(); - // - return ret; -} - -std::vector MEDCouplingBasicsTest::buildMultiFields_2() -{ - ParaMEDMEM::MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->setName("m1"); - ParaMEDMEM::MEDCouplingUMesh *m2=build2DTargetMesh_1(); - m2->setName("m2"); - const double vals0[]={-0.7,-1.,-2.,-3.,-4.}; - const double vals1[]={0.,1.,2.,3.,4.}; - const double vals1_1[]={170.,171.,172.,173.,174.}; - const double vals2[]={5.,6.,7.,8.,9.}; - const double vals4[]={15.,16.,17.,18.,19.}; - // - ParaMEDMEM::DataArrayDouble *d0=ParaMEDMEM::DataArrayDouble::New(); d0->alloc(5,1); std::copy(vals0,vals0+5,d0->getPointer()); - ParaMEDMEM::DataArrayDouble *d1=ParaMEDMEM::DataArrayDouble::New(); d1->alloc(5,1); std::copy(vals1,vals1+5,d1->getPointer()); - ParaMEDMEM::DataArrayDouble *d1_1=ParaMEDMEM::DataArrayDouble::New(); d1_1->alloc(5,1); std::copy(vals1_1,vals1_1+5,d1_1->getPointer()); - ParaMEDMEM::DataArrayDouble *d2=ParaMEDMEM::DataArrayDouble::New(); d2->alloc(5,1); std::copy(vals2,vals2+5,d2->getPointer()); - ParaMEDMEM::DataArrayDouble *d4=ParaMEDMEM::DataArrayDouble::New(); d4->alloc(5,1); std::copy(vals4,vals4+5,d4->getPointer()); - // - d0->setName("d0"); d1->setName("d1"); d1_1->setName("d1_1"); d2->setName("d2"); d4->setName("d4"); - d0->setInfoOnComponent(0,"c1"); - d1->setInfoOnComponent(0,"c6"); - d1_1->setInfoOnComponent(0,"c9"); - d2->setInfoOnComponent(0,"c5"); - d4->setInfoOnComponent(0,"c7"); - // - ParaMEDMEM::MEDCouplingFieldDouble *f0=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f0->setMesh(m1); - f0->setArray(d0); - f0->setTime(0.2,5,6); - f0->setName("f0"); - ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::LINEAR_TIME); - f1->setMesh(m1); - std::vector d1s(2); d1s[0]=d1; d1s[1]=d1_1; - f1->setArrays(d1s); - f1->setStartTime(0.7,7,8); - f1->setEndTime(1.2,9,10); - f1->setName("f1"); - ParaMEDMEM::MEDCouplingFieldDouble *f2=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::CONST_ON_TIME_INTERVAL); - f2->setMesh(m2); - f2->setArray(d2); - f2->setTime(1.2,11,12); - f2->setEndTime(1.5,13,14); - f2->setName("f2"); - ParaMEDMEM::MEDCouplingFieldDouble *f3=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f3->setMesh(m1); - f3->setArray(d2); - f3->setTime(1.7,15,16); - f3->setName("f3"); - ParaMEDMEM::MEDCouplingFieldDouble *f4=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); - f4->setMesh(m2); - f4->setArray(d4); - f4->setName("f4"); - // - std::vector fs(5); - fs[0]=f0; fs[1]=f1; fs[2]=f2; fs[3]=f3; fs[4]=f4; - m1->decrRef(); - m2->decrRef(); - d0->decrRef(); - d1->decrRef(); - d1_1->decrRef(); - d2->decrRef(); - d4->decrRef(); - // - return fs; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMultiTypes_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi1DMesh",1); - DataArrayDouble *coo=buildCoordsForMultiTypes_1(); - const int conn[5]={0,2, 0,2,1}; - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+2); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DMultiTypes_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi2DMesh",2); - DataArrayDouble *coo=buildCoordsForMultiTypes_1(); - const int conn[21]={3,4,5, 3,4,5,6,7,8, 0,9,10,11, 0,9,10,11,12,13,14,15}; - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+3); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+9); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+13); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DMultiTypes_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi3DMesh",3); - DataArrayDouble *coo=buildCoordsForMultiTypes_1(); - const int conn[81]={0,16,17,18, - 0,16,17,18,19,20,21,22,23,24, - 0,11,10,9,25, - 0,11,10,9,25,15,14,13,12,26,27,28,29, - 0,30,31,32,33,34, - 0,30,31,32,33,34,35,36,37,38,39,40,41,42,43, - 0,9,10,11,44,45,46,47, - 0,9,10,11,44,45,46,47,12,13,14,15,48,49,50,51,52,53,54,55 }; - mesh->allocateCells(8); - mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+14); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA13,13,conn+19); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+32); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA15,15,conn+38); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+53); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA20,20,conn+61); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -DataArrayDouble *MEDCouplingBasicsTest::buildCoordsForMultiTypes_1() -{ - DataArrayDouble *coords=DataArrayDouble::New(); - coords->alloc(56,3); - coords->setInfoOnComponent(0,"X (cm)"); - coords->setInfoOnComponent(1,"Y (cm)"); - coords->setInfoOnComponent(2,"Z (cm)"); - const double data[168]={ - 0.0, 0.0, 0.0, //#0 - 0.5, 0.5, 0.5, //#1 - 1.0, 1.0, 1.0, //#2 - 1.0, 1.0, 0.0, //#3 - 2.0, 2.5, 0.0, //#4 - 6.0, 1.5, 0.0, //#5 - 1.0, 2.0, 0.0, //#6 - 4.5, 2.5, 0.0, //#7 - 4.0, 0.5, 0.0, //#8 - 0.0, 4.0, 0.0, //#9 - 4.0, 4.0, 0.0, //#10 - 4.0, 0.0, 0.0, //#11 - 0.0, 2.0, 0.0, //#12 - 2.0, 4.0, 0.0, //#13 - 4.0, 2.0, 0.0, //#14 - 2.0, 0.0, 0.0, //#15 - 0.0, 6.0, 0.0, //#16 - 3.0, 3.0, 0.0, //#17 - 1.3, 3.0, 3.0, //#18 - 0.0, 3.0, 0.0, //#19 - 1.5, 4.5, 0.0, //#20 - 1.5, 1.5, 0.0, //#21 - 0.65, 1.5, 1.5, //#22 - 0.65, 4.5, 1.5, //#23 - 2.15, 3.0, 1.5, //#24 - 2.0, 2.0, 2.0, //#25 - 3.0, 1.0, 1.0, //#26 - 3.0, 3.0, 1.0, //#27 - 1.0, 3.0, 1.0, //#28 - 1.0, 1.0, 1.0, //#29 - 0.0, 3.0, 0.0, //#30 - 2.0, 0.0, 0.0, //#31 - 0.0, 0.0, 6.0, //#32 - 0.0, 3.0, 6.0, //#33 - 3.0, 0.0, 6.0, //#34 - 0.0, 1.5, 0.0, //#35 - 1.5, 1.5, 0.0, //#36 - 1.5, 0.0, 0.0, //#37 - 0.0, 1.5, 6.0, //#38 - 1.5, 1.5, 6.0, //#39 - 1.5, 0.0, 6.0, //#40 - 0.0, 0.0, 3.0, //#41 - 0.0, 3.0, 3.0, //#42 - 3.0, 0.0, 3.0, //#43 - 0.0, 0.0, 4.0, //#44 - 0.0, 4.0, 4.0, //#45 - 4.0, 4.0, 4.0, //#46 - 4.0, 0.0, 4.0, //#47 - 0.0, 2.0, 4.0, //#48 - 2.0, 4.0, 4.0, //#49 - 4.0, 2.0, 4.0, //#50 - 2.0, 0.0, 4.0, //#51 - 0.0, 0.0, 2.0, //#52 - 0.0, 4.0, 2.0, //#53 - 4.0, 4.0, 2.0, //#54 - 4.0, 0.0, 2.0 //#55 - }; - std::copy(data,data+168,coords->getPointer()); - return coords; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::buildHexa8Mesh_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Hexa8Only",3); - DataArrayDouble *coo=DataArrayDouble::New(); - const double coords[81]={0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0}; - coo->alloc(27,3); - std::copy(coords,coords+81,coo->getPointer()); - const int conn[64]={3,12,13,4,0,9,10,1, - 4,13,14,5,1,10,11,2, - 6,15,16,7,3,12,13,4, - 7,16,17,8,4,13,14,5, - 12,21,22,13,9,18,19,10, - 13,22,23,14,10,19,20,11, - 15,24,25,16,12,21,22,13, - 16,25,26,17,13,22,23,14}; - mesh->allocateCells(8); - for(int i=0;i<8;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8*i); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::buildPointe_1(MEDCouplingUMesh *& m1) -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Pointe.med",3); - MEDCouplingUMesh *mesh2=MEDCouplingUMesh::New("Pointe.med",2); - const double coords[57]={0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 2.0, 1.0, -2.0, 0.0, 1.0, 0.0, -2.0, 1.0, 1.0, 1.0, 2.0, -1.0, 1.0, 2.0, -1.0, -1.0, 2.0, 1.0, -1.0, 2.0, 1.0, 1.0, 3.0, -1.0, 1.0, 3.0, -1.0, -1.0, 3.0, 1.0, -1.0, 3.0, 1.0, 1.0, 4.0, -1.0, 1.0, 4.0, -1.0, -1.0, 4.0, 1.0, -1.0, 4.0, 0.0, 0.0, 5.0}; - const int conn[74]={0,1,2,5,0,1,3,2,0,1,4,3,0,1,5,4,1,6,3,2,1,7,4,3,1,8,5,4,1,9,2,5,1,6,2,9,1,7,3,6,1,8,4,7,1,9,5,8, 6,7,8,9,1,14,17,16,15,18, 10,11,12,13,6,7,8,9,14,15,16,17,10,11,12,13}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(19,3); - std::copy(coords,coords+57,coo->getPointer()); - mesh->setCoords(coo); - mesh2->setCoords(coo); - coo->decrRef(); - mesh->allocateCells(16); - for(int i=0;i<12;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+4*i); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+48); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+53); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+58); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+66); - mesh->finishInsertingCells(); - //[1,34,29,23,41,32] - const int conn2[20]={0,5,1,14,18,17,8,7,4,9,5,2, 12,8,9,13,6,7,8,9}; - mesh2->allocateCells(6); - for(int i=0;i<4;i++) - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn2+3*i); - mesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+12); - mesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+16); - mesh2->finishInsertingCells(); - m1=mesh2; - // - return mesh; -} - -double MEDCouplingBasicsTest::sumAll(const std::vector< std::map >& matrix) -{ - double ret=0.; - for(std::vector< std::map >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) - for(std::map::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) - ret+=(*iter2).second; - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2D1DSourceMesh() -{ - double sourceCoords[18]={-17., 3., -17., 8., -5., 8., - -5., 3., -9., 0., -13., 3., - -9., 8., -7., 0., -7., 8. - }; - int sourceConn[16]={0,1, 1,2, 2,3, 3,0, 3,4, 4,5, 4,6, 7,8}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(1); - sourceMesh->allocateCells(8); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+6); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+8); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+10); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+12); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+14); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(sourceCoords,sourceCoords+18,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2D1DTargetMesh() -{ - double targetCoords[10]={-17., 0., -17.,6., -9.,6., -9.,0., -5., 3.}; - int targetConn[7]={0,1,2,3, 2,3,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,targetConn + 4); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(targetCoords,targetCoords+10,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DSegSourceMesh(const double shiftX, - const double inclinationX) -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(1); - - const int nbY = 4; - const int nbYP1 = nbY + 1; - sourceMesh->allocateCells(nbY); - - int sourceConn[2]; - for (int iY = 0; iY < nbY; ++iY) - { - sourceConn[0] = iY ; - sourceConn[1] = iY + 1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn); - } - sourceMesh->finishInsertingCells(); - - std::vector sourceCoords; - for (int iY = 0; iY < nbYP1; ++iY) - { - sourceCoords.push_back(iY * inclinationX + shiftX); - sourceCoords.push_back(iY * 4.); - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbYP1,2); - std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - - return sourceMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DQuadTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - - const int nbX = 5; - const int nbY = 4; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - targetMesh->allocateCells(nbX * nbY); - - int targetConn[4]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - targetConn[0] = iY + iX * nbYP1; - targetConn[1] = iY + 1 + iX * nbYP1; - targetConn[2] = iY + 1 + (iX + 1) * nbYP1; - targetConn[3] = iY + (iX + 1) * nbYP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1, 2); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DTriTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - - const int nbX = 5; - const int nbY = 4; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - targetMesh->allocateCells(nbX * nbY * 2); - - int targetConn[3]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - targetConn[0] = iY + iX * nbYP1; - targetConn[1] = iY + 1 + iX * nbYP1; - targetConn[2] = iY + 1 + (iX + 1) * nbYP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetConn[0] = iY + iX * nbYP1; - targetConn[1] = iY + 1 + (iX + 1) * nbYP1; - targetConn[2] = iY + (iX + 1) * nbYP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1, 2); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3D2DSourceMesh() -{ - double sourceCoords[63]={-12., 6., 10., -12.,10., 6., -16.,10. , 10., - -20., 0., 0., -12., 0., 0., -12., 0. , -4., -20.,0.,-4., - -20., 0., 10., -12., 0., 10., -20.,10. , 10., - -25., 5., -5., 5., 5., -5., 5., 5. , 25., -25.,5.,25., - -20., 0., 16., -18., 0., 16., -20., 2.5, 16., - -25., 0., -5., 5., 0., -5., 5., 0. , 25., -25.,0.,25. - }; - int sourceConn[25]={0,1,2, 3,4,5,6, 7,8,9, 10,11,12,13, 14,15,16, 3,4,8,7, 17,18,19,20}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(7); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+3); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn+7); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+10); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn+14); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+17); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+21); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(21,3); - std::copy(sourceCoords,sourceCoords+63,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3D2DTargetMesh() -{ - double targetCoords[45]={-20., 0., 0., -20.,10., 0., -12.,10., 0., - -12., 0., 0., -20., 0.,10., -20.,10.,10., - -12.,10.,10., -12., 0.,10., -20., 0.,18., - -20.,-5.,10., -20.,-5.,-4., -12.,-5.,-4., - -12.,-5.,10., -20., 0.,-4., -12., 0.,-4. - }; - int targetConn[20]={4,5,7,8, 0,3,2,1,4,7,6,5, 4,13,14,7,9,10,11,12}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn + 4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn + 12); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(15,3); - std::copy(targetCoords,targetCoords+45,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DQuadSourceMesh(const double shiftX, - const double inclinationX) -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - - const int nbY = 4; - const int nbZ = 5; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - sourceMesh->allocateCells(nbY * nbZ); - - int sourceConn[4]; - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - sourceConn[0] = iZ + iY * nbZP1; - sourceConn[1] = iZ + 1 + iY * nbZP1; - sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; - sourceConn[3] = iZ + (iY + 1) * nbZP1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn); - } - } - sourceMesh->finishInsertingCells(); - - std::vector sourceCoords; - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - sourceCoords.push_back(iY * inclinationX + shiftX); - sourceCoords.push_back(iY * 4.); - sourceCoords.push_back(iZ * 3.); - } - - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbYP1 * nbZP1,3); - std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - - return sourceMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DTriSourceMesh(const double shiftX, - const double inclinationX) -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - - const int nbY = 4; - const int nbZ = 5; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - sourceMesh->allocateCells(nbY * nbZ * 2); - - int sourceConn[3]; - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - sourceConn[0] = iZ + iY * nbZP1; - sourceConn[1] = iZ + 1 + iY * nbZP1; - sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceConn[0] = iZ + iY * nbZP1; - sourceConn[1] = iZ + (iY + 1) * nbZP1; - sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - } - } - sourceMesh->finishInsertingCells(); - - std::vector sourceCoords; - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - sourceCoords.push_back(iY * inclinationX + shiftX); - sourceCoords.push_back(iY * 4.); - sourceCoords.push_back(iZ * 3.); - } - - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbYP1 * nbZP1,3); - std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - - return sourceMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DHexaTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - - const int nbX = 5; - const int nbY = 4; - const int nbZ = 5; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - targetMesh->allocateCells(nbX * nbY * nbZ); - - int targetConn[8]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ( iY + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[3] = iZ + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[4] = iZ + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[5] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[6] = iZ + 1 + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[7] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn); - } - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - targetCoords.push_back(iZ * 3.); - } - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1 * nbZP1, 3); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DTetraTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - - const int nbX = 5; - const int nbY = 4; - const int nbZ = 5; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - targetMesh->allocateCells(nbX * nbY * nbZ * 5); - - int targetConn[4]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ( iY + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[2] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - } - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - targetCoords.push_back(iZ * 3.); - } - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1 * nbZP1, 3); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -int MEDCouplingBasicsTest::countNonZero(const std::vector< std::map >& matrix) -{ - int ret=0.; - for(std::vector< std::map >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) - for(std::map::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) - if (!INTERP_KERNEL::epsilonEqual((*iter2).second, 0.)) ret +=1; - return ret; -} - -void MEDCouplingBasicsTest::test2D1DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctLength, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr) -{ - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D1D myInterpolator; - myInterpolator.setPrecision(1e-12); - const double prec = 1.0e-5; - IntersectionMatrix matrix; - myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - std::cout.precision(16); - - const double length = sumAll(matrix); - LOG(1, "length = " << surf <<" correctLength = " << correctLength ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctLength, length, prec * std::max(correctLength, length)); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - int duplicateFacesNbr = duplicateFaces.size(); - LOG(1, "duplicateFacesNbr = " << duplicateFacesNbr <<" correctDuplicateFacesNbr = " << correctDuplicateFacesNbr); - CPPUNIT_ASSERT_EQUAL(correctDuplicateFacesNbr, duplicateFacesNbr); - - if (correctTotalIntersectFacesNbr >= 0) - { - int totalIntersectFacesNbr = countNonZero(matrix); - LOG(1, "totalIntersectFacesNbr = " << totalIntersectFacesNbr <<" correctTotalIntersectFacesNbr = " << correctTotalIntersectFacesNbr ); - CPPUNIT_ASSERT_EQUAL(correctTotalIntersectFacesNbr, totalIntersectFacesNbr); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest::test3D2DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctSurf, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr) -{ - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D2D myInterpolator; - myInterpolator.setPrecision(1e-12); - const double prec = 1.0e-5; - IntersectionMatrix matrix; - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( size_t i = 0; i < sizeof(sp)/sizeof(sp[0]); ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - matrix.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - std::cout.precision(16); - - const double surf = sumAll(matrix); - LOG(1, "surf = " << surf <<" correctSurf = " << correctSurf ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctSurf, surf, prec * std::max(correctSurf, surf)); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - int duplicateFacesNbr = duplicateFaces.size(); - LOG(1, "duplicateFacesNbr = " << duplicateFacesNbr <<" correctDuplicateFacesNbr = " << correctDuplicateFacesNbr); - CPPUNIT_ASSERT_EQUAL(correctDuplicateFacesNbr, duplicateFacesNbr); - - if (correctTotalIntersectFacesNbr >= 0) - { - int totalIntersectFacesNbr = countNonZero(matrix); - LOG(1, "totalIntersectFacesNbr = " << totalIntersectFacesNbr <<" correctTotalIntersectFacesNbr = " << correctTotalIntersectFacesNbr ); - CPPUNIT_ASSERT_EQUAL(correctTotalIntersectFacesNbr, totalIntersectFacesNbr); - } - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx deleted file mode 100644 index 49d3ed779..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ /dev/null @@ -1,2694 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest1.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest1::testArray() -{ - int tmp1[6]={7,6,5,4,3,2}; - const int tmp2[3]={8,9,10}; - { - MemArray mem; - mem.useArray(tmp1,false,CPP_DEALLOC,6); - CPPUNIT_ASSERT(tmp1==mem.getConstPointer()); - CPPUNIT_ASSERT_THROW(mem.getPointer(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mem[2]=7,INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mem.writeOnPlace(0,12,tmp2,3),INTERP_KERNEL::Exception); - mem.writeOnPlace(4,12,tmp2,3); - } - { - int *tmp3=new int[6]; - std::copy(tmp1,tmp1+6,tmp3); - MemArray mem2; - mem2.useArray(tmp3,true,CPP_DEALLOC,6); - CPPUNIT_ASSERT(tmp3==mem2.getConstPointer()); - CPPUNIT_ASSERT(tmp3==mem2.getPointer()); - CPPUNIT_ASSERT_EQUAL(5,mem2[2]); - mem2[2]=7; - CPPUNIT_ASSERT_EQUAL(7,mem2[2]); - mem2.writeOnPlace(0,12,tmp2,3); - CPPUNIT_ASSERT_EQUAL(9,mem2[2]); - CPPUNIT_ASSERT_EQUAL(12,mem2[0]); - mem2.writeOnPlace(4,12,tmp2,3); - } -} - -void MEDCouplingBasicsTest1::testArray2() -{ - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(3,4); - double *tmp=arr->getPointer(); - const double arrRef[12]={12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.}; - std::copy(arrRef,arrRef+12,tmp); - arr->setInfoOnComponent(0,"ggg"); - arr->setInfoOnComponent(1,"hhhh"); - arr->setInfoOnComponent(2,"jj"); - arr->setInfoOnComponent(3,"kkkkkk"); - DataArrayInt *arr2=arr->convertToIntArr(); - DataArrayDouble *arr3=arr2->convertToDblArr(); - arr2->decrRef(); - CPPUNIT_ASSERT(arr->isEqual(*arr3,1e-14)); - arr3->decrRef(); - arr->decrRef(); -} - -void MEDCouplingBasicsTest1::testArray3() -{ - DataArrayInt *arr1=DataArrayInt::New(); - arr1->alloc(7,2); - int *tmp=arr1->getPointer(); - const int arr1Ref[14]={0,10,1,11,2,12,3,13,4,14,5,15,6,16}; - std::copy(arr1Ref,arr1Ref+14,tmp); - CPPUNIT_ASSERT_EQUAL(7,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr1Ref,arr1Ref+14,arr1->getConstPointer())); - DataArrayInt *arr2=arr1->substr(3); - CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr2->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr1Ref+6,arr1Ref+14,arr2->getConstPointer())); - arr2->decrRef(); - DataArrayInt *arr3=arr1->substr(2,5); - CPPUNIT_ASSERT_EQUAL(3,arr3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr3->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr1Ref+4,arr1Ref+10,arr3->getConstPointer())); - arr1->decrRef(); - arr3->decrRef(); - // - DataArrayDouble *arr4=DataArrayDouble::New(); - arr4->alloc(7,2); - double *tmp2=arr4->getPointer(); - const double arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5}; - std::copy(arr4Ref,arr4Ref+14,tmp2); - CPPUNIT_ASSERT_EQUAL(7,arr4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr4->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr4Ref,arr4Ref+14,arr4->getConstPointer())); - DataArrayDouble *arr5=arr4->substr(3); - CPPUNIT_ASSERT_EQUAL(4,arr5->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr5->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr4Ref+6,arr4Ref+14,arr5->getConstPointer())); - arr5->decrRef(); - DataArrayDouble *arr6=arr4->substr(2,5); - CPPUNIT_ASSERT_EQUAL(3,arr6->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr6->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr4Ref+4,arr4Ref+10,arr6->getConstPointer())); - arr4->decrRef(); - arr6->decrRef(); -} - -void MEDCouplingBasicsTest1::testMesh() -{ - const int nbOfCells=6; - const int nbOfNodes=12; - - double coords[3*nbOfNodes]={ - 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, -0.305, 0.09662000000000001, -1.832979297858306e-18, - -0.305, 0.120775, 0.04183768725682623, -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, - 0.08367537451365246, -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, - 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, 0.08367537451365245, - -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863, }; - - int tab4[4*nbOfCells]={ - 1, 2, 8, 7, 2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, 0, 6, 11, - 0, 1, 7, 6, }; - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_TRI3),3); - CPPUNIT_ASSERT(MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_TRI3)); - CPPUNIT_ASSERT(MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_TRI3)); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_TRI3),2); - CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_TRI3)),std::string("NORM_TRI3")); - CPPUNIT_ASSERT_THROW(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_POLYGON),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_POLYGON)); - CPPUNIT_ASSERT(MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_POLYGON)); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_POLYGON),2); - CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_POLYGON)),std::string("NORM_POLYGON")); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_TRI6),6); - CPPUNIT_ASSERT(MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_TRI6)); - CPPUNIT_ASSERT(!MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_TRI6)); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_TRI6),2); - CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_TRI6)),std::string("NORM_TRI6")); - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(8); - const int *curConn=tab4; - for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_QUAD4,4,curConn); - mesh->finishInsertingCells(); - CPPUNIT_ASSERT_EQUAL((std::size_t)30,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); - //test 0 - no copy no ownership - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->useArray(coords,false,CPP_DEALLOC,nbOfNodes,3); - mesh->setCoords(myCoords); - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); - mesh->checkCoherency(); - //test 1 - no copy ownership C++ - myCoords=DataArrayDouble::New(); - double *tmp=new double[3*nbOfNodes]; - std::copy(coords,coords+3*nbOfNodes,tmp); - myCoords->useArray(tmp,true,CPP_DEALLOC,nbOfNodes,3); - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); - mesh->checkCoherency(); - //test 2 - no copy ownership C - myCoords=DataArrayDouble::New(); - tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); - std::copy(coords,coords+3*nbOfNodes,tmp); - myCoords->useArray(tmp,true,C_DEALLOC,nbOfNodes,3); - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); - mesh->checkCoherency(); - //test 3 - copy. - myCoords=DataArrayDouble::New(); - myCoords->alloc(nbOfNodes,3); - tmp=myCoords->getPointer(); - std::copy(coords,coords+3*nbOfNodes,tmp); - // test 3 bis deepcopy - DataArrayDouble *myCoords2=DataArrayDouble::New(); - *myCoords2=*myCoords; - myCoords2->decrRef(); - // - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - // test clone not recursively - MEDCouplingUMesh *mesh2=mesh->clone(false); - CPPUNIT_ASSERT(mesh2!=mesh); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh2->getSpaceDimension()); - CPPUNIT_ASSERT(mesh!=mesh2); - CPPUNIT_ASSERT(mesh->getCoords()==mesh2->getCoords()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2863,mesh2->getCoords()->getIJ(11,2),1e-14); - CPPUNIT_ASSERT(mesh->getNodalConnectivity()==mesh2->getNodalConnectivity()); - CPPUNIT_ASSERT_EQUAL(3,mesh2->getNodalConnectivity()->getIJ(7,0)); - CPPUNIT_ASSERT(mesh->getNodalConnectivityIndex()==mesh2->getNodalConnectivityIndex()); - CPPUNIT_ASSERT_EQUAL(15,mesh2->getNodalConnectivityIndex()->getIJ(3,0)); - mesh2->decrRef(); - // test clone not recursively - MEDCouplingUMesh *mesh3=mesh->clone(true); - CPPUNIT_ASSERT(mesh3!=mesh); - mesh3->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh3->getSpaceDimension()); - CPPUNIT_ASSERT(mesh!=mesh3); - CPPUNIT_ASSERT(mesh->getCoords()!=mesh3->getCoords()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2863,mesh3->getCoords()->getIJ(11,2),1e-14); - CPPUNIT_ASSERT(mesh->getNodalConnectivity()!=mesh3->getNodalConnectivity()); - CPPUNIT_ASSERT_EQUAL(3,mesh3->getNodalConnectivity()->getIJ(7,0)); - CPPUNIT_ASSERT(mesh->getNodalConnectivityIndex()!=mesh3->getNodalConnectivityIndex()); - CPPUNIT_ASSERT_EQUAL(15,mesh3->getNodalConnectivityIndex()->getIJ(3,0)); - mesh3->decrRef(); - //test 4 - Field on cells - MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); - fieldOnCells->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,9); - fieldOnCells->setArray(array); - tmp=array->getPointer(); - array->decrRef(); - std::fill(tmp,tmp+9*nbOfCells,7.); - //content of field changed -> declare it. - fieldOnCells->declareAsNew(); - fieldOnCells->checkCoherency(); - // testing clone of fields - no recursive - MEDCouplingFieldDouble *fieldOnCells2=fieldOnCells->clone(false); - CPPUNIT_ASSERT(fieldOnCells2!=fieldOnCells); - fieldOnCells2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,fieldOnCells2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,fieldOnCells2->getNumberOfComponents()); - CPPUNIT_ASSERT(fieldOnCells2->getArray()==fieldOnCells->getArray()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,fieldOnCells2->getArray()->getIJ(3,7),1e-14); - CPPUNIT_ASSERT(fieldOnCells2->getMesh()==fieldOnCells->getMesh()); - // testing clone of fields - recursive - MEDCouplingFieldDouble *fieldOnCells3=fieldOnCells->clone(true); - CPPUNIT_ASSERT(fieldOnCells3!=fieldOnCells); - fieldOnCells3->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,fieldOnCells3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,fieldOnCells3->getNumberOfComponents()); - CPPUNIT_ASSERT(fieldOnCells3->getArray()!=fieldOnCells->getArray()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,fieldOnCells3->getArray()->getIJ(3,7),1e-14); - CPPUNIT_ASSERT(fieldOnCells3->getMesh()==fieldOnCells->getMesh()); - fieldOnCells2->decrRef(); - fieldOnCells3->decrRef(); - // - fieldOnCells->decrRef(); - //clean-up - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testMeshPointsCloud() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - const int targetConn[]={0,1,2,3,4,5,7,6}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(0); - targetMesh->allocateCells(8); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+1); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+7); - targetMesh->finishInsertingCells(); - CPPUNIT_ASSERT_THROW(targetMesh->checkCoherency(),INTERP_KERNEL::Exception); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - // - targetMesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,targetMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(8,targetMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(0,targetMesh->getMeshDimension()); - // - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testMeshM1D() -{ - MEDCouplingUMesh *meshM1D=MEDCouplingUMesh::New(); - CPPUNIT_ASSERT_THROW(meshM1D->getMeshDimension(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfNodes(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfCells(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->setMeshDimension(-2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->setMeshDimension(-10),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->checkCoherency(),INTERP_KERNEL::Exception); - meshM1D->setMeshDimension(-1); - meshM1D->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(-1,meshM1D->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(1,meshM1D->getNumberOfCells()); - CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfNodes(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->getSpaceDimension(),INTERP_KERNEL::Exception); - MEDCouplingUMesh *cpy=meshM1D->clone(true); - CPPUNIT_ASSERT(cpy->isEqual(meshM1D,1e-12)); - cpy->decrRef(); - MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); - fieldOnCells->setMesh(meshM1D); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(1,6); - fieldOnCells->setArray(array); - double *tmp=array->getPointer(); - array->decrRef(); - std::fill(tmp,tmp+6,7.); - fieldOnCells->checkCoherency(); - // - fieldOnCells->decrRef(); - meshM1D->decrRef(); -} - -void MEDCouplingBasicsTest1::testDeepCopy() -{ - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(5,3); - std::fill(array->getPointer(),array->getPointer()+5*3,7.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,array->getIJ(3,2),1e-14); - double *tmp1=array->getPointer(); - DataArrayDouble *array2=array->deepCpy(); - double *tmp2=array2->getPointer(); - CPPUNIT_ASSERT(tmp1!=tmp2); - array->decrRef(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,array2->getIJ(3,2),1e-14); - array2->decrRef(); - // - DataArrayInt *array3=DataArrayInt::New(); - array3->alloc(5,3); - std::fill(array3->getPointer(),array3->getPointer()+5*3,17); - CPPUNIT_ASSERT_EQUAL(17,array3->getIJ(3,2)); - int *tmp3=array3->getPointer(); - DataArrayInt *array4=array3->deepCpy(); - int *tmp4=array4->getPointer(); - CPPUNIT_ASSERT(tmp3!=tmp4); - array3->decrRef(); - CPPUNIT_ASSERT_EQUAL(17,array4->getIJ(3,2)); - array4->decrRef(); -} - -void MEDCouplingBasicsTest1::testRevNodal() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayInt *revNodal=DataArrayInt::New(); - DataArrayInt *revNodalIndx=DataArrayInt::New(); - // - mesh->getReverseNodalConnectivity(revNodal,revNodalIndx); - const int revNodalExpected[18]={0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4}; - const int revNodalIndexExpected[10]={0,1,3,5,7,12,14,15,17,18}; - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revNodal->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,revNodalIndx->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(revNodalExpected,revNodalExpected+18,revNodal->getPointer())); - CPPUNIT_ASSERT(std::equal(revNodalIndexExpected,revNodalIndexExpected+10,revNodalIndx->getPointer())); - // - revNodal->decrRef(); - revNodalIndx->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testConvertToPolyTypes() -{ - ////// 2D - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - // - const int elts[2]={1,3}; - std::vector eltsV(elts,elts+2); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(23,mesh->getNodalConnectivity()->getNumberOfTuples()); - const int *pt=mesh->getNodalConnectivity()->getConstPointer(); - const int expected1[23]={4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+23,pt)); - // - mesh->decrRef(); - ////// 3D - mesh=build3DTargetMesh_1(); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(8,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(114,mesh->getNodalConnectivity()->getNumberOfTuples()); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(8,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(114,mesh->getNodalConnectivity()->getNumberOfTuples()); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testDescConn2D() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); - const int expected1[18]={0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); - const int expected2[6]={0,4,7,10,14,18}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); - const int expected3[14]={0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); - const int expected4[18]={0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); - DataArrayInt *conn=mesh2->getNodalConnectivity(); - DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); - const int expected5[14]={0,3,6,9,12,15,18,21,24,27,30,33,36,39}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); - const int expected6[39]={1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - // - const int elts[2]={1,3}; - std::vector eltsV(elts,elts+2); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - // - desc=DataArrayInt::New(); - descIndx=DataArrayInt::New(); - revDesc=DataArrayInt::New(); - revDescIndx=DataArrayInt::New(); - // - mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); - conn=mesh2->getNodalConnectivity(); - connIndex=mesh2->getNodalConnectivityIndex(); - CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testDescConn3D() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(36,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)37,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(37,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)9,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(9,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); - const int expected1[9]={0, 6, 12, 18, 24, 30, 36, 42, 48}; - const int expected2[48]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30}; - const int expected3[37]={0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48}; - const int expected4[48]={0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7}; - const int expected5[37]={0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180}; - const int expected6[180]={4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, - 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16}; - const int expected7[180]={4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, - 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16}; - - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,descIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+48,desc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+37,revDescIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected5,expected5+37,mesh2->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+180,mesh2->getNodalConnectivity()->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - // - const int elts[2]={1,3}; - std::vector eltsV(elts,elts+2); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - desc=DataArrayInt::New(); - descIndx=DataArrayInt::New(); - revDesc=DataArrayInt::New(); - revDescIndx=DataArrayInt::New(); - mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(36,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)37,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(37,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)9,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(9,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,descIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+48,desc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+37,revDescIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected5,expected5+37,mesh2->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected7,expected7+180,mesh2->getNodalConnectivity()->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testFindBoundaryNodes() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - DataArrayInt *boundaryNodes=mesh->findBoundaryNodes(); - CPPUNIT_ASSERT_EQUAL(26,boundaryNodes->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,boundaryNodes->getNumberOfComponents()); - const int expected1[26]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+26,boundaryNodes->begin())); - boundaryNodes->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testBoundaryMesh() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - MEDCouplingPointSet *mesh2=mesh->buildBoundaryMesh(false); - CPPUNIT_ASSERT_EQUAL(24,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(26,mesh2->getNumberOfNodes()); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildPartOfMySelf() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - mesh->setName("Toto"); - const int tab1[2]={0,4}; - const int tab2[3]={0,2,3}; - // - MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelf(tab1,tab1+2,true); - MEDCouplingUMesh *subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - std::string name(subMesh->getName()); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*mesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(mesh->getAllGeoTypes().begin()))); - CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT(name=="Toto"); - CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); - CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); - const int subConn[10]={4,0,3,4,1,4,7,8,5,4}; - const int subConnIndex[3]={0,5,10}; - CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); - subMesh->decrRef(); - // - subMeshSimple=mesh->buildPartOfMySelf(tab2,tab2+3,true); - subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - name=subMesh->getName(); - CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(subMesh->getAllGeoTypes().begin()))); - CPPUNIT_ASSERT(name=="Toto"); - CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); - CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); - const int subConn2[14]={4,0,3,4,1,3,4,5,2,4,6,7,4,3}; - const int subConnIndex2[4]={0,5,9,14}; - CPPUNIT_ASSERT_EQUAL((std::size_t)14,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); - const int tab3[3]={0,1,2}; - MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true); - subMesh->decrRef(); - name=subMeshSimple2->getName(); - CPPUNIT_ASSERT(name=="Toto"); - subMeshSimple2->decrRef(); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildPartOfMySelfNode() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const int tab1[4]={5,7,8,4}; - MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+4,true); - MEDCouplingUMesh *subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(1,subMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - const int subConn[5]={4,7,8,5,4}; - const int subConnIndex[3]={0,5}; - CPPUNIT_ASSERT(std::equal(subConn,subConn+5,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+2,subMesh->getNodalConnectivityIndex()->getPointer())); - CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords()); - subMeshSimple->decrRef(); - // - subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+2,false); - subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllGeoTypes().begin())); - CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - const int subConn2[14]={3,4,5,2,4,6,7,4,3,4,7,8,5,4}; - const int subConnIndex2[4]={0,4,9,14}; - CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); - CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords()); - subMeshSimple->decrRef(); - //testing the case where length of tab2 is greater than max number of node per cell. - const int tab2[7]={0,3,2,1,4,5,6}; - subMeshSimple=mesh->buildPartOfMySelfNode(tab2,tab2+7,true); - subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllGeoTypes().begin())); - CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); - subMeshSimple->decrRef(); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testZipCoords() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); - std::vector oldConn(mesh->getNodalConnectivity()->getNbOfElems()); - std::vector oldConnIndex(mesh->getNumberOfCells()+1); - std::copy(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+oldConn.size(),oldConn.begin()); - std::copy(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+mesh->getNumberOfCells()+1,oldConnIndex.begin()); - DataArrayDouble *oldCoords=mesh->getCoords(); - oldCoords->incrRef(); - mesh->zipCoords(); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); - CPPUNIT_ASSERT(mesh->getCoords()!=oldCoords); - CPPUNIT_ASSERT(std::equal(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+2*9,oldCoords->getPointer())); - CPPUNIT_ASSERT(std::equal(oldConn.begin(),oldConn.end(),mesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(oldConnIndex.begin(),oldConnIndex.end(),mesh->getNodalConnectivityIndex()->getPointer())); - oldCoords->decrRef(); - // - const int tab1[2]={0,4}; - MEDCouplingPointSet *subMeshPtSet=mesh->buildPartOfMySelf(tab1,tab1+2,true); - MEDCouplingUMesh *subMesh=dynamic_cast(subMeshPtSet); - CPPUNIT_ASSERT(subMesh); - DataArrayInt *traducer=subMesh->zipCoordsTraducer(); - const int expectedTraducer[9]={0,1,-1,2,3,4,-1,5,6}; - CPPUNIT_ASSERT(std::equal(expectedTraducer,expectedTraducer+9,traducer->getPointer())); - traducer->decrRef(); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); - const int subConn[10]={4,0,2,3,1,4,5,6,4,3}; - const int subConnIndex[3]={0,5,10}; - CPPUNIT_ASSERT_EQUAL(7,subMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); - subMesh->decrRef(); - // - subMeshPtSet=mesh->buildPartOfMySelf(tab1,tab1+2,false); - subMesh=dynamic_cast(subMeshPtSet); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(7,subMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); - subMesh->decrRef(); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testZipConnectivity() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - int cells1[3]={2,3,4}; - MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m3=dynamic_cast(m3_1); - CPPUNIT_ASSERT(m3); - m2->decrRef(); - MEDCouplingUMesh *m4=build2DSourceMesh_1(); - MEDCouplingUMesh *m5=MEDCouplingUMesh::MergeUMeshes(m1,m3); - m1->decrRef(); - m3->decrRef(); - MEDCouplingUMesh *m6=MEDCouplingUMesh::MergeUMeshes(m5,m4); - m4->decrRef(); - m5->decrRef(); - // - bool areNodesMerged; - int newNbOfNodes; - CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); - DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); - arr->decrRef(); - CPPUNIT_ASSERT(areNodesMerged); - CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(9,newNbOfNodes); - // - arr=m6->zipConnectivityTraducer(0); - CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); - arr->decrRef(); - MEDCouplingUMesh *m7=m6->clone(true); - arr=m6->zipConnectivityTraducer(0); - CPPUNIT_ASSERT(m7->isEqual(m6,1e-12)); - CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); - arr->decrRef(); - // - m7->decrRef(); - m6->decrRef(); -} - -void MEDCouplingBasicsTest1::testEqualMesh() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - // - CPPUNIT_ASSERT(mesh1->isEqual(mesh1,1e-12)); - // - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - double *pt=mesh2->getCoords()->getPointer(); - double tmp=pt[1]; - pt[1]=5.999; - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - pt[1]=tmp; - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - int *pt2=mesh1->getNodalConnectivity()->getPointer(); - pt2[5]++; - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - pt2[5]--; - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - pt2=mesh1->getNodalConnectivityIndex()->getPointer(); - pt2[1]++; - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - pt2[1]--; - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - std::string tmp3=mesh1->getName(); - mesh1->setName("lllll"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - mesh1->setName(tmp3.c_str()); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - tmp3=mesh2->getCoords()->getInfoOnComponent(1); - mesh2->getCoords()->setInfoOnComponent(1,"kkkkkk"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - mesh2->getCoords()->setInfoOnComponent(1,tmp3.c_str()); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest1::testEqualFieldDouble() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - // - MEDCouplingFieldDouble *fieldOnCells1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - fieldOnCells1->setMesh(mesh1); - MEDCouplingFieldDouble *fieldOnCells2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - fieldOnCells2->setMesh(mesh2); - // - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->decrRef(); - // - MEDCouplingFieldDouble *fieldOnNodes1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnNodes1,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnNodes1->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnNodes1->decrRef(); - // - fieldOnCells2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1->decrRef(); - fieldOnCells1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1->setTime(4.,6,7); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setTime(4.,6,7); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1->setName("Power"); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setName("Power"); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - fieldOnCells1->setMesh(mesh1); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setMesh(mesh1); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - DataArrayDouble *arr=DataArrayDouble::New(); - arr->setName("popo"); - arr->alloc(mesh1->getNumberOfCells(),3); - double *pt=arr->getPointer(); - std::fill(pt,pt+mesh1->getNumberOfCells()*3,6.); - fieldOnCells1->setArray(arr); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setArray(arr); - arr->decrRef(); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - DataArrayDouble *arr2=arr->deepCpy(); - fieldOnCells2->setArray(arr2); - arr2->decrRef(); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - pt[4]=6.1; - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - pt[4]=6.; - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - arr2->setName("popo2"); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - arr2->setName("popo"); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - arr2->setInfoOnComponent(2,"jjj"); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - arr->setInfoOnComponent(2,"jjj"); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - fieldOnCells1->decrRef(); - fieldOnCells2->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest1::testNatureChecking() -{ - MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - field->setNature(Integral); - field->setNature(ConservativeVolumic); - field->setNature(IntegralGlobConstraint); - field->decrRef(); - field=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - field->setNature(ConservativeVolumic); - CPPUNIT_ASSERT_THROW(field->setNature(Integral),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(field->setNature(IntegralGlobConstraint),INTERP_KERNEL::Exception); - field->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildSubMeshData() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - //check buildSubMesh on field on cells - MEDCouplingFieldDouble *fieldCells=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - fieldCells->setMesh(targetMesh); - const int elts[3]={1,2,4}; - DataArrayInt *di; - MEDCouplingMesh *ret1=fieldCells->buildSubMeshData(elts,elts+3,di); - CPPUNIT_ASSERT_EQUAL(3,ret1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,ret1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,di->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,di->getNumberOfComponents()); - const int *toCheck=di->getConstPointer(); - CPPUNIT_ASSERT(std::equal(elts,elts+3,toCheck)); - MEDCouplingUMesh *ret1DC=dynamic_cast(ret1); - CPPUNIT_ASSERT(ret1DC); - ret1->decrRef(); - di->decrRef(); - fieldCells->decrRef(); - //check buildSubMesh on field on nodes - MEDCouplingFieldDouble *fieldNodes=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - fieldNodes->setMesh(targetMesh); - MEDCouplingMesh *ret2=fieldNodes->buildSubMeshData(elts,elts+3,di); - MEDCouplingUMesh *ret2DC=dynamic_cast(ret2); - CPPUNIT_ASSERT(ret2DC); - CPPUNIT_ASSERT_EQUAL(3,ret2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,ret2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(6,di->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,di->getNumberOfComponents()); - toCheck=di->getConstPointer(); - const int expected[6]={1,2,4,5,7,8}; - CPPUNIT_ASSERT(std::equal(expected,expected+6,toCheck)); - ret2->decrRef(); - di->decrRef(); - fieldNodes->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testExtrudedMesh1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - MEDCouplingExtrudedMesh *ext=MEDCouplingExtrudedMesh::New(mesh3D,mesh2D,1); - CPPUNIT_ASSERT_EQUAL(18,ext->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(60,ext->getNumberOfNodes()); - DataArrayInt *ids3D=ext->getMesh3DIds(); - const int ids3DExpected[18]={5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12}; - CPPUNIT_ASSERT_EQUAL(18,ids3D->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ids3D->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(ids3DExpected,ids3DExpected+18,ids3D->getConstPointer())); - MEDCouplingUMesh *mesh1D=ext->getMesh1D(); - CPPUNIT_ASSERT_EQUAL(4,mesh1D->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh1D->getNumberOfCells()); - const double mesh1DExpected[12]={0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, 2, 0.66666666666666663, 1.4583333333333333, 3}; - DataArrayDouble *mesh1DCoords=mesh1D->getCoords(); - CPPUNIT_ASSERT_EQUAL(4,mesh1DCoords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,mesh1DCoords->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(mesh1DExpected,mesh1DExpected+12,mesh1DCoords->getConstPointer())); - DataArrayInt *conn1D=mesh1D->getNodalConnectivity(); - CPPUNIT_ASSERT_EQUAL(9,conn1D->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,conn1D->getNumberOfComponents()); - const int conn1DExpected[9]={1,0,1,1,1,2,1,2,3}; - CPPUNIT_ASSERT(std::equal(conn1DExpected,conn1DExpected+9,conn1D->getConstPointer())); - ext->decrRef(); - mesh3D->decrRef(); - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest1::testExtrudedMesh2() -{ - MEDCouplingUMesh *mN,*mTT,*mTF; - build3DExtrudedUMesh_2(mN,mTT,mTF); - // - bool b=false; - int newNbOfNodes; - DataArrayInt *da=mTT->mergeNodes(1e-12,b,newNbOfNodes); - CPPUNIT_ASSERT(b); - da->decrRef(); - std::vector n; - double pt[3]={300.,300.,0.}; - double v[3]={0.,0.,2.}; - mTT->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(43,(int)n.size()); - MEDCouplingUMesh *mTT3dSurf=(MEDCouplingUMesh *)mTT->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *meTT=MEDCouplingExtrudedMesh::New(mTT,mTT3dSurf,0); - CPPUNIT_ASSERT_EQUAL(200,meTT->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(10,meTT->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,meTT->getMesh1D()->getNumberOfCells()); - mTT3dSurf->decrRef(); - // - b=false; - da=mN->mergeNodes(1e-12,b,newNbOfNodes); - da->decrRef(); - CPPUNIT_ASSERT(!b); - n.clear(); - mN->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(30,(int)n.size()); - MEDCouplingUMesh *mN3dSurf=(MEDCouplingUMesh *)mN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *meN=MEDCouplingExtrudedMesh::New(mN,mN3dSurf,0); - CPPUNIT_ASSERT_EQUAL(40,meN->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,meN->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(2,meN->getMesh1D()->getNumberOfCells()); - mN3dSurf->decrRef(); - // - b=false; - da=mTF->mergeNodes(1e-12,b,newNbOfNodes); - da->decrRef(); - CPPUNIT_ASSERT(!b); - n.clear(); - mTF->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(27,(int)n.size()); - MEDCouplingUMesh *mTF3dSurf=(MEDCouplingUMesh *)mTF->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *meTF=MEDCouplingExtrudedMesh::New(mTF,mTF3dSurf,0); - CPPUNIT_ASSERT_EQUAL(340,meTF->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(17,meTF->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,meTF->getMesh1D()->getNumberOfCells()); - mTF3dSurf->decrRef(); - // - meTT->decrRef(); - meN->decrRef(); - meTF->decrRef(); - // - mN->decrRef(); - mTT->decrRef(); - mTF->decrRef(); -} - -/*! - * This test check MEDCouplingUMesh::buildExtrudedMesh method. - */ -void MEDCouplingBasicsTest1::testExtrudedMesh3() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->changeSpaceDimension(3); - MEDCouplingUMesh *m2=buildCU1DMesh_U(); - m2->changeSpaceDimension(3); - double center[3]={0.,0.,0.}; - double vector[3]={0,1,0}; - m2->rotate(center,vector,-M_PI/2.); - MEDCouplingUMesh *m3=m1->buildExtrudedMesh(m2,0); - // - MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); - const int *m3DIds=m4->getMesh3DIds()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_EQUAL(i,m3DIds[i]); - m4->decrRef(); - //some random in cells to check that extrusion alg find it correctly - const int expected1[15]={1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; - m3->renumberCells(expected1,false); - m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); - m3DIds=m4->getMesh3DIds()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); - m4->decrRef(); - m3->decrRef(); - //play with polygons and polyedrons - std::vector cells(2); cells[0]=2; cells[1]=3; - m1->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); - m3=m1->buildExtrudedMesh(m2,0); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_PENTA6,(int)m3->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(4)); - m3->renumberCells(expected1,false); - m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); - m3DIds=m4->getMesh3DIds()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); - m4->decrRef(); - m3->decrRef(); - // - m2->decrRef(); - m1->decrRef(); -} - -/*! - * This test check MEDCouplingUMesh::buildExtrudedMesh method, but also, MEDCouplingExtrudedMesh following methods : - * getCellContainingPoint getMeasureField getNodeIdsOfCell getCoordinateOfNode getTypeOfCell build3DUnstructuredMesh. - */ -void MEDCouplingBasicsTest1::testExtrudedMesh4() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - std::vector cells(2); cells[0]=2; cells[1]=4; - m1->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); - m1->changeSpaceDimension(3); - MEDCouplingUMesh *m2=buildCU1DMesh_U(); - m2->changeSpaceDimension(3); - double center[3]={0.,0.,0.}; - double vector[3]={0.,1.,0.}; - m2->rotate(center,vector,-M_PI/2.); - m1->zipCoords(); - MEDCouplingUMesh *m3=m1->buildExtrudedMesh(m2,0); - const int expected1[15]= {1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; - const int rexpected1[15]={3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12}; - m3->renumberCells(expected1,false); - MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYHED,m4->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,m4->getTypeOfCell(7)); - MEDCouplingFieldDouble *f=m4->getMeasureField(true); - DataArrayDouble *arr=f->getArray(); - CPPUNIT_ASSERT_EQUAL(15,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - const double *arrPtr=arr->getConstPointer(); - const double expected2[15]={0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); - f->decrRef(); - MEDCouplingUMesh *m5=m4->build3DUnstructuredMesh(); - m5->zipCoords(); - CPPUNIT_ASSERT(m5->isEqual(m3,1e-12)); - f=m5->getMeasureField(true); - arr=f->getArray(); - arrPtr=arr->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); - f->decrRef(); - m5->decrRef(); - // - m4->decrRef(); - m3->decrRef(); - m2->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest1::testFindCommonNodes() -{ - DataArrayInt *comm,*commI; - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - targetMesh->findCommonNodes(1e-10,-1,comm,commI); - CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples()); - int newNbOfNodes; - DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(27,o2n->getNumberOfTuples()); - const int o2nExp1[27]= - { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26 - }; - CPPUNIT_ASSERT(std::equal(o2nExp1,o2nExp1+27,o2n->getConstPointer())); - o2n->decrRef(); - comm->decrRef(); - commI->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes()); - targetMesh->findCommonNodes(1e-10,-1,comm,commI); - CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples()); - const int commExpected[6]={1,27,28,29,23,30}; - const int commIExpected[3]={0,4,6}; - CPPUNIT_ASSERT(std::equal(commExpected,commExpected+6,comm->getConstPointer())); - CPPUNIT_ASSERT(std::equal(commIExpected,commIExpected+3,commI->getConstPointer())); - o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(31,o2n->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); - const int o2nExp2[31]= - { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26,1,1,1,23 - }; - CPPUNIT_ASSERT(std::equal(o2nExp2,o2nExp2+31,o2n->getConstPointer())); - o2n->decrRef(); - comm->decrRef(); - commI->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMesh_1(); - bool areNodesMerged; - unsigned int time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); - targetMesh->updateTime(); - CPPUNIT_ASSERT(time==targetMesh->getTimeOfThis()); - CPPUNIT_ASSERT(!areNodesMerged); - targetMesh->decrRef(); - o2n->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); - targetMesh->updateTime(); - CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); - CPPUNIT_ASSERT(areNodesMerged); - int connExp[72]={18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, - 18,4,5,8,7,13,14,17,16, - 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, - 18,13,14,17,16,22,23,26,25}; - CPPUNIT_ASSERT_EQUAL(72,targetMesh->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExp,connExp+72,targetMesh->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL(27,targetMesh->getCoords()->getNumberOfTuples()); - double coordsExp[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , - 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., - 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , - 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. - , 0., 50., 200., 50., 50., 200. , 200., 50., 200., - 0., 200., 200., 50., 200., 200. , 200., 200., 200. }; - CPPUNIT_ASSERT(std::equal(coordsExp,coordsExp+81,targetMesh->getCoords()->getConstPointer())); - targetMesh->decrRef(); - o2n->decrRef(); - //2D - targetMesh=build2DTargetMeshMergeNode_1(); - CPPUNIT_ASSERT_EQUAL(18,targetMesh->getNumberOfNodes()); - time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); - CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); - CPPUNIT_ASSERT(areNodesMerged); - CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); - int connExp2[23]={4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3}; - CPPUNIT_ASSERT_EQUAL(23,targetMesh->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExp2,connExp2+23,targetMesh->getNodalConnectivity()->getConstPointer())); - double coordsExp2[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7}; - CPPUNIT_ASSERT_EQUAL(9,targetMesh->getCoords()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(coordsExp2,coordsExp2+18,targetMesh->getCoords()->getConstPointer())); - targetMesh->decrRef(); - o2n->decrRef(); -} - -void MEDCouplingBasicsTest1::testCheckButterflyCells() -{ - std::vector cells; - MEDCouplingUMesh *sourceMesh=build2DTargetMesh_1(); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - int *pt=sourceMesh->getNodalConnectivity()->getPointer(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT_EQUAL(1,(int)cells.size()); - CPPUNIT_ASSERT_EQUAL(3,cells[0]); - cells.clear(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - sourceMesh->decrRef(); - // 3D surf - sourceMesh=build3DSurfTargetMesh_1(); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - pt=sourceMesh->getNodalConnectivity()->getPointer(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT_EQUAL(1,(int)cells.size()); - CPPUNIT_ASSERT_EQUAL(3,cells[0]); - cells.clear(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - sourceMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testMergeMesh1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DSourceMesh_1(); - const double vec[2]={1.,0.}; - m2->translate(vec); - MEDCouplingMesh *m3=m1->mergeMyselfWith(m2); - MEDCouplingUMesh *m3C=dynamic_cast(m3); - CPPUNIT_ASSERT(m3C); - m3->checkCoherency(); - MEDCouplingUMesh *m4=build2DTargetMeshMerged_1(); - CPPUNIT_ASSERT(m3->isEqual(m4,1.e-12)); - m4->decrRef(); - bool isMerged; - int newNbOfNodes; - DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(11,m3C->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(11,newNbOfNodes); - CPPUNIT_ASSERT(isMerged); - da->decrRef(); - m3->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testMergeMeshOnSameCoords1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - std::vector cells(5); - for(int i=0;i<5;i++) - cells[i]=i; - m2->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); - m1->tryToShareSameCoords(*m2,1e-12); - MEDCouplingUMesh *m3=build2DTargetMesh_1(); - m3->tryToShareSameCoords(*m2,1e-12); - std::vector meshes; - meshes.push_back(m1); meshes.push_back(m2); meshes.push_back(m3); - MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshes); - m4->checkCoherency(); - CPPUNIT_ASSERT(m4->getCoords()==m1->getCoords()); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - const int cells1[5]={0,1,2,3,4}; - MEDCouplingPointSet *m1_1=m4->buildPartOfMySelf(cells1,cells1+5,true); - m1_1->setName(m1->getName().c_str()); - CPPUNIT_ASSERT(m1->isEqual(m1_1,1e-12)); - const int cells2[5]={5,6,7,8,9}; - MEDCouplingPointSet *m2_1=m4->buildPartOfMySelf(cells2,cells2+5,true); - m2_1->setName(m2->getName().c_str()); - CPPUNIT_ASSERT(m2->isEqual(m2_1,1e-12)); - const int cells3[5]={10,11,12,13,14}; - MEDCouplingPointSet *m3_1=m4->buildPartOfMySelf(cells3,cells3+5,true); - m3_1->setName(m3->getName().c_str()); - CPPUNIT_ASSERT(m3->isEqual(m3_1,1e-12)); - m1_1->decrRef(); m2_1->decrRef(); m3_1->decrRef(); - // - m4->decrRef(); - m1->decrRef(); - m2->decrRef(); - m3->decrRef(); -} - -void MEDCouplingBasicsTest1::testMergeField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DSourceMesh_1(); - const double vec[2]={1.,0.}; - m2->translate(vec); - MEDCouplingFieldDouble *f1=m1->getMeasureField(true); - MEDCouplingFieldDouble *f2=m2->getMeasureField(true); - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::MergeFields(f1,f2); - f3->checkCoherency(); - MEDCouplingUMesh *m4=build2DTargetMeshMerged_1(); - CPPUNIT_ASSERT(f3->getMesh()->isEqual(m4,1.e-12)); - std::string name=f3->getName(); - CPPUNIT_ASSERT(name=="MeasureOfMesh_"); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,f3->getNumberOfTuples()); - double values[7]={0.25,0.125,0.125,0.25,0.25,0.5,0.5}; - const double *tmp=f3->getArray()->getConstPointer(); - std::transform(tmp,tmp+7,values,values,std::minus()); - std::transform(values,values+7,values,std::ptr_fun(fabs)); - double max=*std::max_element(values,values+7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - m4->decrRef(); - f3->decrRef(); - f1->decrRef(); - f2->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -bool func1(const double *pt, double *res); -bool func2(const double *pt, double *res); -bool func3(const double *pt, double *res); -bool func4(const double *pt, double *res); - -bool func1(const double *pt, double *res) -{ - res[0]=pt[0]+pt[1]; - return true; -} - -bool func2(const double *pt, double *res) -{ - res[0]=pt[0]+pt[1]; - res[1]=2.*(pt[0]+pt[1]); - return true; -} - -bool func3(const double *pt, double *res) -{ - if(fabs(pt[0]-0.2)<1e-12) - return false; - res[0]=1./(pt[0]-0.2); - return true; -} - -void MEDCouplingBasicsTest1::testFillFromAnalytic() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->setTime(3.4,5,6); m->setTimeUnit("us"); - int a,b; - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,func1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+5,values1,values1,std::minus()); - std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,1,func1); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[9]={-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,2,func2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values3,values3,std::minus()); - std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - double values4[2]; - f1->accumulate(values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->integral(true,values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); - f1->decrRef(); - // - CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,func3),INTERP_KERNEL::Exception); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testFillFromAnalytic2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,"y+x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+5,values1,values1,std::minus()); - std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,1,"y+2*x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - f1=m->fillFromAnalytic(ON_NODES,1,"2.*x+y"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - tmp=f1->getArray()->getConstPointer(); - double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - std::transform(tmp,tmp+9,values2Bis,values2Bis,std::minus()); - std::transform(values2,values2+9,values2Bis,std::ptr_fun(fabs)); - max=*std::max_element(values2Bis,values2Bis+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values3,values3,std::minus()); - std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - double values4[2]; - f1->accumulate(values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->integral(true,values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); - f1->decrRef(); - // - CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,"1./(x-0.2)"),INTERP_KERNEL::Exception); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testApplyFunc() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - f1->applyFunc(1,func1); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values1,values1,std::minus()); - std::transform(values1,values1+9,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testApplyFunc2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - // - MEDCouplingFieldDouble *f2=f1->clone(true); - CPPUNIT_ASSERT_THROW(f2->applyFunc(1,"a+b+c+d"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(f2->applyFunc(1,"a/0"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(f2->applyFunc("a/0"),INTERP_KERNEL::Exception); - f2->applyFunc("abs(u)^2.4+2*u"); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[18]={-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 5.0423700574830965, 17.435300118916864}; - const double *tmp=f2->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values2,values2,std::minus()); - std::transform(values2,values2+18,values2,std::ptr_fun(fabs)); - double max=*std::max_element(values2,values2+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f2->decrRef(); - // - f1->applyFunc(1,"x+y"); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values1,values1,std::minus()); - std::transform(values1,values1+9,values1,std::ptr_fun(fabs)); - max=*std::max_element(values1,values1+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testOperationsOnFields() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,func1); - MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,func1); - f1->checkCoherency(); - f2->checkCoherency(); - MEDCouplingFieldDouble *f3=(*f1)+(*f2); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - double values1[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; - const double *tmp=f3->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values1,values1,std::minus()); - std::transform(values1,values1+9,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f3->decrRef(); - // - f3=(*f1)*(*f2); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - double values2[9]={0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96}; - tmp=f3->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f3->decrRef(); - // - f3=(*f1)+(*f2); - MEDCouplingFieldDouble *f4=(*f1)-(*f3); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); - double values3[9]={0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4}; - tmp=f4->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values3,values3,std::minus()); - std::transform(values3,values3+9,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f3->decrRef(); - f4->decrRef(); - // - f3=(*f1)+(*f2); - f4=(*f3)/(*f2); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); - tmp=f4->getArray()->getConstPointer(); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,tmp[i],1.e-12); - f3->decrRef(); - f4->decrRef(); - // - f4=f2->buildNewTimeReprFromThis(NO_TIME,false); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getArray()==f2->getArray()); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); - CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(ONE_TIME,false); - CPPUNIT_ASSERT(f4->getArray()==f5->getArray()); - CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); - f3=(*f1)+(*f5); - tmp=f3->getArray()->getConstPointer(); - double values4[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; - std::transform(tmp,tmp+9,values4,values4,std::minus()); - std::transform(values4,values4+9,values4,std::ptr_fun(fabs)); - max=*std::max_element(values4,values4+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f5->decrRef(); - f4->decrRef(); - f3->decrRef(); - // - f4=f2->buildNewTimeReprFromThis(NO_TIME,true); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getArray()!=f2->getArray()); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); - CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); - f5=f4->buildNewTimeReprFromThis(ONE_TIME,true); - CPPUNIT_ASSERT(f4->getArray()!=f5->getArray()); - CPPUNIT_ASSERT(f2->getArray()!=f5->getArray()); - CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); - f3=(*f1)+(*f5); - tmp=f3->getArray()->getConstPointer(); - double values5[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; - std::transform(tmp,tmp+9,values5,values5,std::minus()); - std::transform(values5,values5+9,values5,std::ptr_fun(fabs)); - max=*std::max_element(values5,values5+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f5->decrRef(); - f4->decrRef(); - f3->decrRef(); - // - f1->decrRef(); - f2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testOperationsOnFields2() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - m->setTime(3.4,5,6); m->setTimeUnit("us"); - int a,b; - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); - MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - MEDCouplingFieldDouble *f3=(*f1)/(*f2); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f3->getNumberOfTuples()); - const double *val=f3->getArray()->getConstPointer(); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1.e-12); - f3->decrRef(); - f1->decrRef(); - f2->decrRef(); - // - f1=m->buildOrthogonalField(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - f2=m->fillFromAnalytic(ON_CELLS,1,"x"); - f3=(*f1)*(*f2); - const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; - val=f3->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); - f3->decrRef(); - // - f3=(*f2)*(*f1); - val=f3->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); - f3->decrRef(); - // - f1->decrRef(); - f2->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testOperationsOnFields3() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); - MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - (*f1)/=(*f2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - const double *val=f1->getArray()->getConstPointer(); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1.e-12); - f1->decrRef(); - f2->decrRef(); - // - f1=m->buildOrthogonalField(); - f2=m->fillFromAnalytic(ON_CELLS,1,"x"); - (*f1)*=(*f2); - const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; - val=f1->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); - f1->decrRef(); - // - f1=m->buildOrthogonalField(); - CPPUNIT_ASSERT_THROW((*f2)*=(*f1),INTERP_KERNEL::Exception); - f1->decrRef(); - f2->decrRef(); - // - m->decrRef(); -} - -/*! - * Check of LINEAR_TIME and CONST_ON_TIME_INTERVAL policies - */ -void MEDCouplingBasicsTest1::testOperationsOnFields4() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,3); - f1->setArray(array); - CPPUNIT_ASSERT_THROW(f1->setEndArray(array),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(f1->getEndArray(),INTERP_KERNEL::Exception); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[15]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.}; - const double arr2[15]={5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.}; - std::copy(arr1,arr1+15,tmp); - f1->setStartTime(2.,0,0); - f1->setEndTime(3.,0,0); - f1->checkCoherency(); - double res[3]; - const double pos[2]={0.3,-0.2}; - f1->getValueOn(pos,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); - std::fill(res,res+3,0.); - f1->getValueOn(pos,2.2,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); - std::fill(res,res+3,0.); - CPPUNIT_ASSERT_THROW(f1->getValueOn(pos,3.2,res),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f2->setMesh(m); - f2->setArray(f1->getArray()); - f2->setStartTime(2.,3,0); - f2->setEndTime(4.,13,0); - CPPUNIT_ASSERT_THROW(f2->checkCoherency(),INTERP_KERNEL::Exception); - DataArrayDouble *array2=DataArrayDouble::New(); - array2->alloc(nbOfCells,3); - tmp=array2->getPointer(); - std::copy(arr2,arr2+15,tmp); - f2->setEndArray(array2); - array2->decrRef(); - f2->checkCoherency(); - // - std::fill(res,res+3,0.); - f2->getValueOn(pos,3.21,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.025,res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.025,res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.025,res[2],1.e-12); - MEDCouplingFieldDouble *f3=f2->clone(true); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-12)); - f3->getEndArray()->getPointer()[0]=5.001; - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-12)); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.1,3,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,3,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,4,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,3,1); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,3,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.1,13,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,13,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,14,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,13,1); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,13,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->decrRef(); - MEDCouplingFieldDouble *f4=(*f2)+(*f2); - std::fill(res,res+3,0.); - f4->getValueOn(pos,3.21,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.05,res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.05,res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(48.05,res[2],1.e-12); - (*f4)+=*f2; - std::fill(res,res+3,0.); - f4->getValueOn(pos,3.21,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.075,res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(42.075,res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(72.075,res[2],1.e-12); - f4->decrRef(); - // - f2->decrRef(); - f1->decrRef(); - m->decrRef(); -} - -bool func4(const double *pt, double *res) -{ - res[0]=pt[0]+pt[1]+pt[2]; - return true; -} - -void MEDCouplingBasicsTest1::testMergeNodesOnField() -{ - double *tmp; - MEDCouplingUMesh *targetMesh=build3DTargetMeshMergeNode_1(); - MEDCouplingFieldDouble *f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); - f1->mergeNodes(1e-10); - f1->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); - tmp=f1->getArray()->getPointer(); - tmp[0]=1000.; - f1->mergeNodes(1e-10); - f1->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); - tmp=f1->getArray()->getPointer(); - tmp[1]=1000.; - CPPUNIT_ASSERT_THROW(f1->mergeNodes(1e-10),INTERP_KERNEL::Exception); - f1->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testCheckConsecutiveCellTypes() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - CPPUNIT_ASSERT(sourceMesh->checkConsecutiveCellTypes()); - const INTERP_KERNEL::NormalizedCellType order1[]={INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; - const INTERP_KERNEL::NormalizedCellType order2[]={INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI3}; - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypes()); - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); - DataArrayInt *da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order1,order1+2); - CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - const int expected1[5]={2,0,1,3,4}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); - da->decrRef(); - da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order2,order2+2); - CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - const int expected2[5]={0,3,4,1,2}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+5,da->getConstPointer())); - da->decrRef(); - const int renumber1[5]={4,0,1,2,3}; - targetMesh->renumberCells(renumber1,false); - CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypes()); - CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); - targetMesh->decrRef(); - sourceMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testRearrange2ConsecutiveCellTypes() -{ - MEDCouplingUMesh *m1_1=build2DSourceMesh_1(); - MEDCouplingUMesh *m2_1=build2DTargetMesh_1(); - DataArrayInt *arr1=m1_1->rearrange2ConsecutiveCellTypes(); - MEDCouplingUMesh *m1_2=build2DSourceMesh_1(); - CPPUNIT_ASSERT(m1_2->isEqual(m1_1,1e-12)); - const int expected1[2]={0,1}; - CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+2,arr1->getConstPointer())); - arr1->decrRef(); - const int expected2[5]={0,3,4,1,2}; - arr1=m2_1->rearrange2ConsecutiveCellTypes(); - CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); - MEDCouplingUMesh *m2_2=build2DTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); - CPPUNIT_ASSERT(!m2_2->isEqual(m2_1,1e-12)); - m2_2->renumberCells(expected2,false); - CPPUNIT_ASSERT(m2_2->isEqual(m2_1,1e-12)); - arr1->decrRef(); - m1_1->decrRef(); - m1_2->decrRef(); - m2_1->decrRef(); - m2_2->decrRef(); -} - -void MEDCouplingBasicsTest1::testSplitByType() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - std::vector v=m1->splitByType(); - CPPUNIT_ASSERT_EQUAL(3,(int)v.size()); - std::vector v2(v.begin(),v.end()); - MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(v2); - m2->setName(m1->getName().c_str()); - CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12)); - for(std::vector::const_iterator iter=v.begin();iter!=v.end();iter++) - (*iter)->decrRef(); - m2->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest1::testFuseUMeshesOnSameCoords() -{ - std::vector meshes; - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - int cells1[3]={2,3,4}; - MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m3=dynamic_cast(m3_1); - CPPUNIT_ASSERT(m3); - meshes.push_back(m3); - int cells2[3]={1,2,4}; - MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true); - MEDCouplingUMesh *m4=dynamic_cast(m4_1); - CPPUNIT_ASSERT(m4); - meshes.push_back(m4); - int cells3[2]={1,2}; - MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true); - MEDCouplingUMesh *m5=dynamic_cast(m5_1); - CPPUNIT_ASSERT(m5); - meshes.push_back(m5); - m2->decrRef(); - // - std::vector corr; - MEDCouplingUMesh *m7=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,(int)corr.size()); - const int expectedVals1[3]={3,3,2}; - const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}}; - for(int i=0;i<3;i++) - { - DataArrayInt *arr=corr[i]; - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - int nbOfVals=expectedVals1[i]; - CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples()); - const int *vals=arr->getConstPointer(); - for(int j=0;j > fidsOfGroups; - std::vector corr2(corr.begin(),corr.end()); - DataArrayInt *arr2=DataArrayInt::MakePartition(corr2,m7->getNumberOfCells(),fidsOfGroups); - const int fidExp[4]={5,1,3,4}; - const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}}; - CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size()); - CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer())); - for(int i=0;i<3;i++) - { - int nbOfVals=expectedVals1[i]; - CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size()); - CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i])); - } - for(std::vector::iterator iter=corr.begin();iter!=corr.end();iter++) - (*iter)->decrRef(); - arr2->decrRef(); - m7->decrRef(); - // - m3->decrRef(); - m4->decrRef(); - m5->decrRef(); -} - -void MEDCouplingBasicsTest1::testFuseUMeshesOnSameCoords2() -{ - MEDCouplingUMesh *m2; - MEDCouplingUMesh *m1=build3DExtrudedUMesh_1(m2); - m2->decrRef(); - const int part1[5]={2,3,6,4,10}; - MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part1,part1+5,true); - const int part2[4]={5,6,4,7}; - MEDCouplingUMesh *m4=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part2,part2+4,true); - std::vector meshes; - meshes.push_back(m1); - meshes.push_back(m3); - meshes.push_back(m3); - meshes.push_back(m4); - std::vector corr; - MEDCouplingUMesh *m5=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(18,m5->getNumberOfCells()); - std::vector::iterator it=corr.begin(); - const int exp1[4]={18,5,5,4}; - const int exp2[4][18]={ - {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, - {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - {5,6,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} - }; - int i=0; - for(;it!=corr.end();it++,i++) - { - int sz=(*it)->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(exp1[i],sz); - CPPUNIT_ASSERT(std::equal(exp2[i],exp2[i]+sz,(*it)->getConstPointer())); - } - for(it=corr.begin();it!=corr.end();it++) - (*it)->decrRef(); - m5->decrRef(); - m4->decrRef(); - m3->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildOrthogonalField() -{ - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *field=targetMesh->buildOrthogonalField(); - double expected[3]={0.70710678118654746,0.,-0.70710678118654746}; - CPPUNIT_ASSERT_EQUAL(5,field->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents()); - const double *vals=field->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i%3],vals[i],1e-12); - field->decrRef(); - targetMesh->decrRef(); - // testing - double targetCoords[12]={0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.}; - int targetConn[4]={0,1,2,3}; - targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(1); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(targetCoords,targetCoords+12,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - field=targetMesh->buildOrthogonalField(); - CPPUNIT_ASSERT_EQUAL(1,field->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents()); - vals=field->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.70710678118654746,vals[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,vals[1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.70710678118654746,vals[2],1e-12); - field->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testGetCellsContainingPoint() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - double pos[12]={0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.}; - MEDCouplingAutoRefCountObjectPtr t1,t2; - //2D basic - targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2); - CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(7,(int)t2->getNbOfElems()); - const int expectedValues1[6]={0,4,3,0,1,2}; - const int expectedValues2[7]={0,1,2,3,4,5,6}; - CPPUNIT_ASSERT(std::equal(t1->begin(),t1->end(),expectedValues1)); - CPPUNIT_ASSERT(std::equal(t2->begin(),t2->end(),expectedValues2)); - //2D with no help of bounding box. - double center[2]={0.2,0.2}; - MEDCouplingPointSet::Rotate2DAlg(center,0.78539816339744830962,6,pos); - targetMesh->rotate(center,0,0.78539816339744830962); - targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2); - CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(7,(int)t2->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(t1->begin(),t1->end(),expectedValues1)); - CPPUNIT_ASSERT(std::equal(t2->begin(),t2->end(),expectedValues2)); - //2D outside - const double pos1bis[2]={-0.3303300858899107,-0.11819805153394641}; - CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos1bis,1e-12)); - targetMesh->decrRef(); - //test limits 2D - targetMesh=build2DTargetMesh_1(); - const double pos2[2]={0.2,-0.05}; - std::vector t11; - t11.clear(); - targetMesh->getCellsContainingPoint(pos2,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(2,(int)t11.size()); - const int expectedValues3[2]={0,1}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues3)); - const double pos3[2]={0.2,0.2}; - t11.clear(); - targetMesh->getCellsContainingPoint(pos3,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(5,(int)t11.size()); - const int expectedValues4[5]={0,1,2,3,4}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues4)); - CPPUNIT_ASSERT_EQUAL(0,targetMesh->getCellContainingPoint(pos3,1e-12)); - targetMesh->decrRef(); - //3D - targetMesh=build3DTargetMesh_1(); - const double pos4[3]={25.,25.,25.}; - CPPUNIT_ASSERT_EQUAL(0,targetMesh->getCellContainingPoint(pos4,1e-12)); - const double pos5[3]={50.,50.,50.}; - t11.clear(); - targetMesh->getCellsContainingPoint(pos5,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(8,(int)t11.size()); - const int expectedValues5[8]={0,1,2,3,4,5,6,7}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues5)); - const double pos6[3]={0., 50., 0.}; - t11.clear(); - targetMesh->getCellsContainingPoint(pos6,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(2,(int)t11.size()); - const int expectedValues6[2]={0,2}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues6)); - //3D outside - const double pos7[3]={-1.0,-1.0,0.}; - CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos7,1e-12)); - //3D outside 2 - const double center2[3]={0.,0.,0.}; - const double vec2[3]={0.,-1.,0.}; - targetMesh->rotate(center2,vec2,0.78539816339744830962); - const double pos8[3]={-25,25.,12.}; - CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos8,1e-12)); - // - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testGetValueOn1() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); - int nbOfCells=targetMesh->getNumberOfCells(); - fieldOnCells->setMesh(targetMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,2); - fieldOnCells->setArray(array); - double *tmp=array->getPointer(); - for(int i=0;idecrRef(); - // - const double pos1[2]={0.25,0.}; - double res[2]; - fieldOnCells->getValueOn(pos1,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,res[1],1e-12); - // - fieldOnCells->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build2DSourceMesh_1(); - MEDCouplingFieldDouble *fieldOnNodes=MEDCouplingFieldDouble::New(ON_NODES); - int nbOfNodes=targetMesh->getNumberOfNodes(); - fieldOnNodes->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(nbOfNodes,2); - fieldOnNodes->setArray(array); - tmp=array->getPointer(); - for(int i=0;idecrRef(); - // - const double pos2[2]={-0.13333333333333333,-0.13333333333333333}; - fieldOnNodes->getValueOn(pos2,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(17.5,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(27.5,res[1],1e-12); - const double pos3[2]={0.033333333333333326,0.36666666666666664}; - fieldOnNodes->getValueOn(pos3,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(18.666666666666667,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.666666666666667,res[1],1e-12); - // - fieldOnNodes->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testCMesh0() -{ - MEDCouplingCMesh* mesh=MEDCouplingCMesh::New(); - MEDCouplingCMesh* meshEmpty=mesh->clone(true); - CPPUNIT_ASSERT(meshEmpty->isEqual(mesh,1e-12)); - - DataArrayDouble* coordsX=DataArrayDouble::New(); - double arrX[4] = { -1., 1., 2., 4. }; - coordsX->useArray(arrX,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY=DataArrayDouble::New(); - double arrY[4] = { -2., 2., 4., 8. }; - coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ=DataArrayDouble::New(); - double arrZ[4] = { -3., 3., 6., 12. }; - coordsZ->useArray(arrZ,false, CPP_DEALLOC,4,1); - mesh->setCoords(coordsX,coordsY,coordsZ); - coordsX->decrRef(); - coordsY->decrRef(); - coordsZ->decrRef(); - // - MEDCouplingFieldDouble *fieldOnNodes=mesh->fillFromAnalytic(ON_NODES,1,"x+y/2.+z/3."); - CPPUNIT_ASSERT_EQUAL(1,fieldOnNodes->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(64,fieldOnNodes->getNumberOfTuples()); - const double expected1[64]={-3., -1., 0., 2., -1., 1., 2., 4., 0., 2., 3., 5., 2., 4., 5., 7., -1., 1., 2., - 4., 1., 3., 4., 6., 2., 4., 5., 7., 4., 6., 7., 9., 0., 2., 3., 5., 2., 4., 5., - 7., 3., 5., 6., 8., 5., 7., 8., 10., 2., 4., 5., - 7., 4., 6., 7., 9., 5., 7., 8., 10., 7., 9., 10., 12.}; - const double *val=fieldOnNodes->getArray()->getConstPointer(); - for(int i=0;i<64;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1e-12); - double res[1]; //size fieldOnNodes->getNumberOfComponents() - fieldOnNodes->getValueOnPos(1,3,2,&res[0]); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,res[0],1e-12); - fieldOnNodes->decrRef(); - // - MEDCouplingFieldDouble *fieldOnCells=mesh->fillFromAnalytic(ON_CELLS,1,"x+y/2.+z/3."); - CPPUNIT_ASSERT_EQUAL(1,fieldOnCells->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(27,fieldOnCells->getNumberOfTuples()); - val=fieldOnCells->getArray()->getConstPointer(); - const double expected2[27]={0, 1.5, 3, 1.5, 3, 4.5, 3, 4.5, 6, 1.5, 3, 4.5, 3, 4.5, - 6, 4.5, 6, 7.5, 3, 4.5, 6, 4.5, 6, 7.5, 6, 7.5, 9}; - for(int i=0;i<27;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1e-12); - fieldOnCells->getValueOnPos(1,2,1,&res[0]); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.,res[0],1e-12); - fieldOnCells->decrRef(); - // - MEDCouplingMesh* meshDeepCopy=mesh->deepCpy(); - MEDCouplingCMesh* meshClone=mesh->clone(false); - - CPPUNIT_ASSERT_THROW(meshEmpty->copyTinyStringsFrom(0),INTERP_KERNEL::Exception); - meshEmpty->copyTinyStringsFrom(mesh); - //no data in meshEmpty, expected false - CPPUNIT_ASSERT(!meshEmpty->isEqual(mesh,1e-12)); - - CPPUNIT_ASSERT(meshDeepCopy->isEqual(mesh,1e-12)); - meshDeepCopy->copyTinyStringsFrom(mesh); - CPPUNIT_ASSERT(meshDeepCopy->isEqual(mesh,1e-12)); - CPPUNIT_ASSERT(meshClone->isEqual(mesh,1e-12)); - - CPPUNIT_ASSERT_EQUAL(CARTESIAN,mesh->getType()); - CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshEmpty->getType()); - CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshDeepCopy->getType()); - CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshClone->getType()); - - mesh->decrRef(); - meshEmpty->decrRef(); - meshDeepCopy->decrRef(); - meshClone->decrRef(); -} - -void MEDCouplingBasicsTest1::testCMesh1() -{ - MEDCouplingCMesh *mesh1,*mesh2,*mesh3; - mesh1=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX1=DataArrayDouble::New(); - double arrX1[4] = { -1., 1., 2., 4. }; - coordsX1->useArray(arrX1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY1=DataArrayDouble::New(); - double arrY1[4] = { -2., 2., 4., 8. }; - coordsY1->useArray(arrY1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ1=DataArrayDouble::New(); - double arrZ1[4] = { -3., 3., 6., 12. }; - coordsZ1->useArray(arrZ1,false, CPP_DEALLOC,4,1); - mesh1->setCoords(coordsX1,coordsY1,coordsZ1); - - mesh2=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX2=DataArrayDouble::New(); - double arrX2[4] = { -1., 1., 2., 4. }; - coordsX2->useArray(arrX2,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY2=DataArrayDouble::New(); - double arrY2[4] = { -2., 2., 4., 8. }; - coordsY2->useArray(arrY2,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ2=DataArrayDouble::New(); - double arrZ2[4] = { -3., 3., 6., 12.+1e-6 }; //here is not equal - coordsZ2->useArray(arrZ2,false, CPP_DEALLOC,4,1); - mesh2->setCoords(coordsX2,coordsY2,coordsZ2); - - mesh3=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX3=DataArrayDouble::New(); - double arrX3[1] = { -1.}; - coordsX3->useArray(arrX3,false, CPP_DEALLOC,1,1); - DataArrayDouble* coordsY3=DataArrayDouble::New(); - double arrY3[1] = { -2.}; - coordsY3->useArray(arrY3,false, CPP_DEALLOC,1,1); - DataArrayDouble* coordsZ3=DataArrayDouble::New(); - double arrZ3[1] = { -3.}; - coordsZ3->useArray(arrZ3,false, CPP_DEALLOC,1,1); - mesh3->setCoords(coordsX3,coordsY3,coordsZ3); - - CPPUNIT_ASSERT_EQUAL(3,mesh1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh1->getMeshDimension()); - - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqualWithoutConsideringStr(mesh1,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-5)); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-7)); - - CPPUNIT_ASSERT_THROW(mesh3->checkCoherency1(1e-12),INTERP_KERNEL::Exception); - mesh1->checkCoherency2(1e-12); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh1->getTypeOfCell(1)); - - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,*((mesh1->getAllGeoTypes()).begin())); - CPPUNIT_ASSERT_EQUAL(27,mesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_THROW(mesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4),INTERP_KERNEL::Exception); - - std::vector coo; - mesh1->getCoordinatesOfNode(0, coo); - CPPUNIT_ASSERT_EQUAL(3,(int) coo.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,coo[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.,coo[1],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.,coo[2],1e-14); - coo.clear(); - mesh1->getCoordinatesOfNode(63, coo); - CPPUNIT_ASSERT_EQUAL(3,(int) coo.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,coo[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,coo[1],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,coo[2],1e-14); - - std::string repr; - repr=mesh1->simpleRepr(); - repr=mesh1->advancedRepr(); - CPPUNIT_ASSERT(!(repr.find("Cartesian")==std::string::npos)); - CPPUNIT_ASSERT(!(repr.find("Number of components : 1")==std::string::npos)); - CPPUNIT_ASSERT(!(repr.find("Number of tuples : 4")==std::string::npos)); - CPPUNIT_ASSERT(!(repr.find("Z Array :")==std::string::npos)); - coordsX1->decrRef(); - coordsY1->decrRef(); - coordsZ1->decrRef(); - coordsX2->decrRef(); - coordsY2->decrRef(); - coordsZ2->decrRef(); - coordsX3->decrRef(); - coordsY3->decrRef(); - coordsZ3->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); - mesh3->decrRef(); -} - -void MEDCouplingBasicsTest1::testCMesh2() -{ - MEDCouplingCMesh *mesh1; - mesh1=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX1=DataArrayDouble::New(); - double arrX1[4] = { -1., 1., 2., 4. }; - coordsX1->useArray(arrX1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY1=DataArrayDouble::New(); - double arrY1[4] = { -2., 2., 4., 8. }; - coordsY1->useArray(arrY1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ1=DataArrayDouble::New(); - double arrZ1[4] = { -3., 3., 6., 12. }; - coordsZ1->useArray(arrZ1,false, CPP_DEALLOC,4,1); - mesh1->setCoords(coordsX1,coordsY1,coordsZ1); - - std::vector dis=mesh1->getDistributionOfTypes(); - CPPUNIT_ASSERT_EQUAL(3,(int) dis.size()); - CPPUNIT_ASSERT_EQUAL((int) INTERP_KERNEL::NORM_HEXA8,dis[0]); - CPPUNIT_ASSERT_EQUAL(27,dis[1]); - CPPUNIT_ASSERT_EQUAL(-1,dis[2]); - - std::vector idsPerType; - CPPUNIT_ASSERT(!(mesh1->checkTypeConsistencyAndContig(dis, idsPerType))); - dis[0]=(int) INTERP_KERNEL::NORM_QUAD4; - CPPUNIT_ASSERT_THROW(mesh1->checkTypeConsistencyAndContig(dis, idsPerType),INTERP_KERNEL::Exception); - - dis[0]=(int) INTERP_KERNEL::NORM_HEXA8; - dis[2]=0; - DataArrayInt *ids=DataArrayInt::New(); - ids->alloc(10,1); - ids->fillWithValue(23); - idsPerType.push_back(ids); - DataArrayInt* check=mesh1->checkTypeConsistencyAndContig(dis, idsPerType); - CPPUNIT_ASSERT(check); - CPPUNIT_ASSERT(check->isEqual(*ids)); - - std::vector code; - std::vector idsInPflPerType; - std::vector pfls; - mesh1->splitProfilePerType(ids,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(3,(int)code.size()); - CPPUNIT_ASSERT_EQUAL((int) INTERP_KERNEL::NORM_HEXA8,code[0]); - CPPUNIT_ASSERT_EQUAL(10,code[1]); - CPPUNIT_ASSERT_EQUAL(0,code[2]); - CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - DataArrayInt *exp=DataArrayInt::New(); exp->alloc(10,1); exp->iota(0); - CPPUNIT_ASSERT(idsInPflPerType[0]->isEqual(*exp)); - exp->decrRef(); - CPPUNIT_ASSERT(pfls[0]->isEqual(*ids)); - idsInPflPerType[0]->decrRef(); - pfls[0]->decrRef(); - - ids->decrRef(); - check->decrRef(); - int cells1[4]={0,1,25,26}; - MEDCouplingUMesh *partMesh1= - dynamic_cast(mesh1->buildPart(cells1,cells1+4)); - CPPUNIT_ASSERT(partMesh1); - CPPUNIT_ASSERT_EQUAL(4,partMesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_EQUAL(64,mesh1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(64,partMesh1->getNumberOfNodes()); - - int cells2[2]={25,26}; - DataArrayInt* arr1; - MEDCouplingCMesh *partMesh2= - dynamic_cast(mesh1->buildPartAndReduceNodes(cells2,cells2+2,arr1)); - CPPUNIT_ASSERT(partMesh2); - CPPUNIT_ASSERT_EQUAL(2,partMesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_EQUAL(12,partMesh2->getNumberOfNodes()); - - int cells3[2]={2,3}; - DataArrayInt* arr2; - MEDCouplingUMesh *partMesh3= - dynamic_cast(partMesh1->buildPartAndReduceNodes(cells3,cells3+2,arr2)); - CPPUNIT_ASSERT(partMesh3); - CPPUNIT_ASSERT_EQUAL(2,partMesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_EQUAL(12,partMesh3->getNumberOfNodes()); - - CPPUNIT_ASSERT_THROW(mesh1->simplexize(0),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mesh1->getMeasureFieldOnNode(true),INTERP_KERNEL::Exception); - - double bbox1[6]; - double bbox2[6]; - mesh1->getBoundingBox(bbox1); - partMesh1->getBoundingBox(bbox2); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(bbox1[i],bbox2[i],1e-12); - partMesh3->getBoundingBox(bbox1); - partMesh2->getBoundingBox(bbox2); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(bbox1[i],bbox2[i],1e-12); - - CPPUNIT_ASSERT_THROW(mesh1->buildOrthogonalField(),INTERP_KERNEL::Exception); - MEDCouplingCMesh *mesh2d=MEDCouplingCMesh::New(); - mesh2d->setCoords(coordsX1,coordsY1); - MEDCouplingFieldDouble *f1=mesh2d->buildOrthogonalField(); - - std::vector tinyInfoD; - std::vector tinyInfo; - std::vector littleStrings; - mesh2d->getTinySerializationInformation(tinyInfoD, tinyInfo, littleStrings); - CPPUNIT_ASSERT_EQUAL(5,(int)tinyInfo.size()); - CPPUNIT_ASSERT_EQUAL(4,(int)tinyInfo[0]); //x - CPPUNIT_ASSERT_EQUAL(4,(int)tinyInfo[1]); //y - CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[2]); //z - CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[3]); //it - CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[4]); //order - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tinyInfoD[0],1e-14); //time - DataArrayInt* d1=DataArrayInt::New(); - DataArrayDouble* d2=DataArrayDouble::New(); - mesh2d->resizeForUnserialization(tinyInfo, d1, d2, littleStrings); - CPPUNIT_ASSERT_EQUAL(0,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples()); - - partMesh1->decrRef(); - partMesh2->decrRef(); - partMesh3->decrRef(); - mesh2d->decrRef(); - arr1->decrRef(); - arr2->decrRef(); - f1->decrRef(); - d1->decrRef(); - d2->decrRef(); - coordsX1->decrRef(); - coordsY1->decrRef(); - coordsZ1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest1::testScale() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const double pos[2]={0.2,0.2}; - mesh->scale(pos,0.5); - const double expected1[18]={-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, - -0.05,0.45, 0.2,0.45, 0.45,0.45}; - const double *val=mesh->getCoords()->getConstPointer(); - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1e-12); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testTryToShareSameCoords() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m2->tryToShareSameCoords(*m1,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->decrRef(); - m2->decrRef(); - // - m1=build2DTargetMesh_1(); - m2=build2DTargetMesh_2(); - CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m2->tryToShareSameCoords(*m1,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->decrRef(); - m2->decrRef(); - // - m1=build2DTargetMesh_1(); - m2=build2DSourceMesh_1(); - CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); - CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoords(*m2,1e-12),INTERP_KERNEL::Exception); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testFindNodeOnPlane() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - std::vector n; - double pt[3]={300.,300.,0.}; - double v[3]={0.,0.,2.}; - mesh->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(9,(int)n.size()); - MEDCouplingUMesh *m3dSurf=(MEDCouplingUMesh *)mesh->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *me=MEDCouplingExtrudedMesh::New(mesh,m3dSurf,0); - const DataArrayInt *da=me->getMesh3DIds(); - CPPUNIT_ASSERT_EQUAL(8,me->getNumberOfCells()); - const int expected[8]={0,1,2,3,4,5,6,7}; - const int *val=da->getConstPointer(); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expected[i],val[i]); - me->decrRef(); - m3dSurf->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testRenumberCells() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - CPPUNIT_ASSERT(m->isEqual(m2,0)); - const int arr[5]={12,3,25,2,26}; - m->renumberCells(arr,true); - CPPUNIT_ASSERT(!m->isEqual(m2,0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(4)); - const int arr2[5]={5,-1,-5,4,8}; - m->renumberCells(arr2,true); - CPPUNIT_ASSERT(m->isEqual(m2,0)); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testChangeSpaceDimension() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - // - CPPUNIT_ASSERT_EQUAL(3,m1->getSpaceDimension()); - m1->changeSpaceDimension(2); - CPPUNIT_ASSERT_EQUAL(2,m1->getSpaceDimension()); - m1->setName(m2->getName().c_str()); - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m1->changeSpaceDimension(3); - CPPUNIT_ASSERT_EQUAL(3,m1->getSpaceDimension()); - const double expected[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.}; - const double *val=m1->getCoords()->getConstPointer(); - for(int i=0;i<27;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i],val[i],1e-14); - // - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testSetConnectivity() -{ - MEDCouplingUMesh *m1 = build1DTargetMesh_1(); - - DataArrayInt * conn = DataArrayInt::New(); - DataArrayInt * connI = DataArrayInt::New(); - m1->setConnectivity(conn, connI, true); // was SEG-Faulting with empty arrays - conn->decrRef(); - connI->decrRef(); - m1->decrRef(); -} diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx deleted file mode 100644 index 8372492b7..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTEST1_HXX__ -#define __MEDCOUPLINGBASICSTEST1_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest1 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest1); - CPPUNIT_TEST( testArray ); - CPPUNIT_TEST( testArray2 ); - CPPUNIT_TEST( testArray3 ); - CPPUNIT_TEST( testMesh ); - CPPUNIT_TEST( testMeshPointsCloud ); - CPPUNIT_TEST( testMeshM1D ); - CPPUNIT_TEST( testDeepCopy ); - CPPUNIT_TEST( testRevNodal ); - CPPUNIT_TEST( testConvertToPolyTypes ); - CPPUNIT_TEST( testDescConn2D ); - CPPUNIT_TEST( testDescConn3D ); - CPPUNIT_TEST( testFindBoundaryNodes ); - CPPUNIT_TEST( testBoundaryMesh ); - CPPUNIT_TEST( testBuildPartOfMySelf ); - CPPUNIT_TEST( testBuildPartOfMySelfNode ); - CPPUNIT_TEST( testZipCoords ); - CPPUNIT_TEST( testZipConnectivity ); - CPPUNIT_TEST( testEqualMesh ); - CPPUNIT_TEST( testEqualFieldDouble ); - CPPUNIT_TEST( testNatureChecking ); - CPPUNIT_TEST( testBuildSubMeshData ); - CPPUNIT_TEST( testExtrudedMesh1 ); - CPPUNIT_TEST( testExtrudedMesh2 ); - CPPUNIT_TEST( testExtrudedMesh3 ); - CPPUNIT_TEST( testExtrudedMesh4 ); - CPPUNIT_TEST( testFindCommonNodes ); - CPPUNIT_TEST( testCheckButterflyCells ); - CPPUNIT_TEST( testMergeMesh1 ); - CPPUNIT_TEST( testMergeMeshOnSameCoords1 ); - CPPUNIT_TEST( testMergeField1 ); - CPPUNIT_TEST( testFillFromAnalytic ); - CPPUNIT_TEST( testFillFromAnalytic2 ); - CPPUNIT_TEST( testApplyFunc ); - CPPUNIT_TEST( testApplyFunc2 ); - CPPUNIT_TEST( testOperationsOnFields ); - CPPUNIT_TEST( testOperationsOnFields2 ); - CPPUNIT_TEST( testOperationsOnFields3 ); - CPPUNIT_TEST( testOperationsOnFields4 ); - CPPUNIT_TEST( testMergeNodesOnField ); - CPPUNIT_TEST( testCheckConsecutiveCellTypes ); - CPPUNIT_TEST( testRearrange2ConsecutiveCellTypes ); - CPPUNIT_TEST( testSplitByType ); - CPPUNIT_TEST( testFuseUMeshesOnSameCoords ); - CPPUNIT_TEST( testFuseUMeshesOnSameCoords2 ); - CPPUNIT_TEST( testBuildOrthogonalField ); - CPPUNIT_TEST( testGetCellsContainingPoint ); - CPPUNIT_TEST( testGetValueOn1 ); - CPPUNIT_TEST( testCMesh0 ); - CPPUNIT_TEST( testCMesh1 ); - CPPUNIT_TEST( testCMesh2 ); - CPPUNIT_TEST( testScale ); - CPPUNIT_TEST( testTryToShareSameCoords ); - CPPUNIT_TEST( testFindNodeOnPlane ); - CPPUNIT_TEST( testRenumberCells ); - CPPUNIT_TEST( testChangeSpaceDimension ); - CPPUNIT_TEST( testSetConnectivity ); - CPPUNIT_TEST_SUITE_END(); - public: - void testArray(); - void testArray2(); - void testArray3(); - void testMesh(); - void testMeshPointsCloud(); - void testMeshM1D(); - void testDeepCopy(); - void testRevNodal(); - void testConvertToPolyTypes(); - void testDescConn2D(); - void testDescConn3D(); - void testFindBoundaryNodes(); - void testBoundaryMesh(); - void testBuildPartOfMySelf(); - void testBuildPartOfMySelfNode(); - void testZipCoords(); - void testZipConnectivity(); - void testEqualMesh(); - void testEqualFieldDouble(); - void testNatureChecking(); - void testBuildSubMeshData(); - void testExtrudedMesh1(); - void testExtrudedMesh2(); - void testExtrudedMesh3(); - void testExtrudedMesh4(); - void testFindCommonNodes(); - void testCheckButterflyCells(); - void testMergeMesh1(); - void testMergeMeshOnSameCoords1(); - void testMergeField1(); - void testFillFromAnalytic(); - void testFillFromAnalytic2(); - void testApplyFunc(); - void testApplyFunc2(); - void testOperationsOnFields(); - void testOperationsOnFields2(); - void testOperationsOnFields3(); - void testOperationsOnFields4(); - void testMergeNodesOnField(); - void testCheckConsecutiveCellTypes(); - void testRearrange2ConsecutiveCellTypes(); - void testSplitByType(); - void testFuseUMeshesOnSameCoords(); - void testFuseUMeshesOnSameCoords2(); - void testBuildOrthogonalField(); - void testGetCellsContainingPoint(); - void testGetValueOn1(); - void testCMesh0(); - void testCMesh1(); - void testCMesh2(); - void testScale(); - void testTryToShareSameCoords(); - void testFindNodeOnPlane(); - void testRenumberCells(); - void testChangeSpaceDimension(); - void testSetConnectivity(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx deleted file mode 100644 index 4e52b0046..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ /dev/null @@ -1,2277 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest2.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest2::testGaussPointField1() -{ - const double _a=0.446948490915965; - const double _b=0.091576213509771; - const double _p1=0.11169079483905; - const double _p2=0.0549758718227661; - const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; - const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - std::vector _refCoo1(refCoo1,refCoo1+6); - std::vector _gsCoo1(gsCoo1,gsCoo1+12); - std::vector _wg1(wg1,wg1+6); - // - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); - CPPUNIT_ASSERT_THROW(f->getNumberOfTuples(), INTERP_KERNEL::Exception); // Sanity check! - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); - CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); // not a bug only to check that it works well - CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo1,_gsCoo1,_wg1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); - const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; - std::vector _refCoo2(refCoo2,refCoo2+8); - _gsCoo1.resize(4); _wg1.resize(2); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(18,2); - double *ptr=array->getPointer(); - for(int i=0;i<18*2;i++) - ptr[i]=(double)(i+1); - f->setArray(array); - f->setName("MyFirstFieldOnGaussPoint"); - array->decrRef(); - f->checkCoherency(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(27.,f->getIJK(2,5,0),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(16.,f->getIJK(1,5,1),1e-14); - // - f->clearGaussLocalizations(); - CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); - CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception); - int ids1[4]={0,1,3,4}; - CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnCells(ids1,ids1+4,_refCoo2,_gsCoo1,_wg1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); - int ids2[2]={0,4}; - f->setGaussLocalizationOnCells(ids2,ids2+2,_refCoo2,_gsCoo1,_wg1); - CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); - CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); - CPPUNIT_ASSERT_THROW(f->getGaussLocalizationIdOfOneCell(1),INTERP_KERNEL::Exception); - int ids3[2]={1,2}; - f->setGaussLocalizationOnCells(ids3,ids3+2,_refCoo1,_gsCoo1,_wg1); - CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); - CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); - CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(1)); - CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(2)); - CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- cell 3 has no localization - int ids4[1]={3}; - std::vector _gsCoo2(_gsCoo1); - std::vector _wg2(_wg1); - _gsCoo2[0]=0.8888777776666; _wg2[0]=0.1234567892377; - f->setGaussLocalizationOnCells(ids4,ids4+1,_refCoo2,_gsCoo2,_wg2); - CPPUNIT_ASSERT_EQUAL(3,f->getNbOfGaussLocalization()); - std::vector tmpIds; - f->getCellIdsHavingGaussLocalization(0,tmpIds); - CPPUNIT_ASSERT_EQUAL(2,(int)tmpIds.size()); - CPPUNIT_ASSERT(std::equal(ids2,ids2+2,tmpIds.begin())); - CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- it's always not ok because undelying array not with the good size. - DataArrayDouble *array2=f->getArray()->substr(0,10); - f->setArray(array2); - array2->decrRef(); - f->checkCoherency();//<- here it is OK - MEDCouplingFieldDouble *f2=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); - MEDCouplingGaussLocalization& gl1=f2->getGaussLocalization(0); - double tmp=gl1.getGaussCoord(1,1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.07*_b-1,tmp,1e-14); - gl1.setGaussCoord(1,1,0.07); - CPPUNIT_ASSERT(!f->isEqual(f2,1e-14,1e-14)); - gl1.setGaussCoord(1,1,tmp); - CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); - f->decrRef(); - f2->checkCoherency(); - // - f2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testGaussPointNEField1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); - f->setName("MyFirstFieldOnNE"); - f->setDescription("MyDescriptionNE"); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(18,2); - double *ptr=array->getPointer(); - for(int i=0;i<18*2;i++) - ptr[i]=(double)(i+7); - f->setArray(array); - array->decrRef(); - // - f->checkCoherency(); - MEDCouplingFieldDouble *f2=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,f->getIJK(2,0,0),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,f->getIJK(1,1,1),1e-14); - f2->decrRef(); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testCellOrientation1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - double vec[3]={0.,0.,-1.}; - std::vector res1; - CPPUNIT_ASSERT_THROW(m->are2DCellsNotCorrectlyOriented(vec,false,res1),INTERP_KERNEL::Exception); - m->changeSpaceDimension(3); - res1.clear(); - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT(res1.empty()); - vec[2]=1; - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT_EQUAL(5,(int)res1.size()); - res1.clear(); - // - vec[2]=-1.; - // connectivity inversion - int *conn=m->getNodalConnectivity()->getPointer(); - int tmp=conn[11]; - conn[11]=conn[12]; - conn[12]=tmp; - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); - CPPUNIT_ASSERT_EQUAL(2,res1[0]); - res1.clear(); - m->orientCorrectly2DCells(vec,false); - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT(res1.empty()); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - m2->changeSpaceDimension(3); - CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); - m2->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testCellOrientation2() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); - m1->decrRef(); - std::vector res1; - m2->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT_EQUAL(6,(int)res1.size()); - m2->orientCorrectlyPolyhedrons(); - res1.clear(); - m2->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - m2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); - int cellIds[3]={0,6,12}; - std::vector cellIds2(cellIds,cellIds+3); - m2->convertToPolyTypes(&cellIds2[0],&cellIds2[0]+cellIds2.size()); - m2->orientCorrectlyPolyhedrons(); - res1.clear(); - m2->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - MEDCouplingFieldDouble *f2=m2->getMeasureField(false); - //Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation - MEDCouplingUMesh *m3=build2DTargetMesh_1(); - double vec[3]={0.,0.,1.}; - m3->changeSpaceDimension(3); - const int ids1[5]={0,1,2,3,4}; - std::vector ids2(ids1,ids1+5); - m3->convertToPolyTypes(&ids2[0],&ids2[0]+ids2.size()); - m3->orientCorrectly2DCells(vec,false); - MEDCouplingUMesh *m4=buildCU1DMesh_U(); - m4->changeSpaceDimension(3); - double center[3]={0.,0.,0.}; - double vector[3]={0.,1.,0.}; - m4->rotate(center,vector,-M_PI/2.); - MEDCouplingUMesh *m5=m3->buildExtrudedMesh(m4,0); - res1.clear(); - m5->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT_EQUAL(15,(int)res1.size()); - m5->orientCorrectlyPolyhedrons(); - res1.clear(); - m5->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - MEDCouplingFieldDouble *f3=m5->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(15,f3->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - const double *f3Ptr=f3->getArray()->getConstPointer(); - const double expected1[15]={ - 0.075,0.0375,0.0375,0.075,0.075, - 0.1125,0.05625,0.05625,0.1125,0.1125, - 0.0625,0.03125,0.03125,0.0625,0.0625 - }; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),f3Ptr[i],1e-12); - f3->decrRef(); - DataArrayDouble *f4=m5->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(15,f4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f4->getNumberOfComponents()); - const double *f4Ptr=f4->getConstPointer(); - const double expected2[45]={ - -0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15, - -0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525, - -0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875 - }; - for(int i=0;i<45;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4Ptr[i],1e-12); - f4->decrRef(); - m5->decrRef(); - m3->decrRef(); - m4->decrRef(); - // - f2->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest2::testCellOrientation3() -{ - MEDCouplingUMesh *m = MEDCouplingUMesh::New("circle", 2); - - double coords[8]={ 0.,0., 0.,0., 0.,0., 0.,0.}; - coords[0] = cos(-M_PI/4.0); coords[1] = sin(-M_PI/4.0); - coords[2] = cos(3*M_PI/4.0); coords[3] = sin(3*M_PI/4.0); - coords[4] = cos(5*M_PI/4.0); coords[5] = sin(5*M_PI/4.0); - coords[6] = cos(M_PI/4.0); coords[7] = sin(M_PI/4.0); - - int conn[4]= { 0,1,2,3 }; - double vec[3]={0.,0.,-1.}; - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,4,conn); - m->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(coords,coords+8,myCoords->getPointer()); - m->setCoords(myCoords); - myCoords->decrRef(); - m->changeSpaceDimension(3); - - std::vector res1; - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT(res1.empty()); - vec[2] = 1.0; - res1.clear(); - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); - m->decrRef(); -} - -/*! - * This test check polyhedron true barycenter computation. - */ -void MEDCouplingBasicsTest2::testPolyhedronBarycenter() -{ - int connN[]={0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0}; - double coords[]={0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5}; - MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); - meshN->setName("ForBary"); - meshN->setMeshDimension(3); - meshN->allocateCells(4); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,29,connN); - meshN->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(coords,coords+27,myCoords->getPointer()); - meshN->setCoords(myCoords); - myCoords->decrRef(); - meshN->checkCoherency(); - // - std::vector res1; - meshN->arePolyhedronsNotCorrectlyOriented(res1); - meshN->orientCorrectlyPolyhedrons(); - CPPUNIT_ASSERT(res1.empty()); - const double *ref,*daPtr; - DataArrayDouble *da=meshN->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); - da->decrRef(); - // - const double center[]={0.,0.,0.}; - const double vec[]={0.,2.78,0.}; - da=meshN->getBarycenterAndOwner(); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); - da->decrRef(); - // - meshN->rotate(center,vec,M_PI/7.); - meshN->translate(vec); - da=meshN->getBarycenterAndOwner(); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); - da->decrRef(); - // - const double center2[]={1.12,3.45,6.78}; - const double vec2[]={4.5,9.3,2.8}; - meshN->rotate(center2,vec2,M_E); - meshN->translate(vec2); - da=meshN->getBarycenterAndOwner(); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-10); - da->decrRef(); - // - meshN->decrRef(); -} - -void MEDCouplingBasicsTest2::testNormL12Integ1D() -{ - MEDCouplingUMesh *m1=build1DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(m1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(m1->getNumberOfCells(),3); - const double arr[12]={-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72}; - std::copy(arr,arr+12,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const double *ptr; - DataArrayDouble *f3=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - double expected9[4]={0.75,5.105,0.8,5.155}; - ptr=f3->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],ptr[i],1e-12); - f3->decrRef(); - // - MEDCouplingFieldDouble *f2=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - double expected1[4]={0.5,0.21,-0.6,-0.31}; - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); - f2->decrRef(); - double expected2[4]={0.5,0.21,0.6,0.31}; - f2=m1->getMeasureField(true); - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); - f2->decrRef(); - //integral - double res[3]; - f1->integral(false,res); - double expected3[3]={0.9866,-0.3615,0.4217}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f1->integral(0,false),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f1->integral(1,false),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f1->integral(2,false),1e-12); - f1->integral(true,res); - double expected4[3]={-3.4152,8.7639,-14.6879}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],res[i],1e-12); - //normL1 - f1->normL1(res); - double expected5[3]={6.979506172839505, 16.89018518518518, 27.02969135802469}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[0],f1->normL1(0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[1],f1->normL1(1),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[2],f1->normL1(2),1e-12); - //normL2 - f1->normL2(res); - double expected7[3]={7.090910979452395, 16.9275542960123, 27.053271464160858}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[0],f1->normL2(0),1e-9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[1],f1->normL2(1),1e-9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[2],f1->normL2(2),1e-9); - //buildMeasureField - MEDCouplingFieldDouble *f4=f1->buildMeasureField(false); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2,f4->accumulate(0),1e-12); - f4->decrRef(); - f4=f1->buildMeasureField(true); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.62,f4->accumulate(0),1e-12); - f4->decrRef(); - // - f1->decrRef(); - m1->decrRef(); - // Testing with 2D Curve - m1=build2DCurveTargetMesh_3(); - f2=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected2[i],ptr[i],1e-12); - f2->decrRef(); - f2=m1->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i]*sqrt(2.),ptr[i],1e-12); - f2->decrRef(); - //bary - f3=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f3->getNumberOfComponents()); - double expected10[8]={0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155}; - ptr=f3->getConstPointer(); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected10[i],ptr[i],1e-12); - f3->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(m1); - array=DataArrayDouble::New(); - array->alloc(m1->getNumberOfCells(),3); - std::copy(arr,arr+12,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->integral(false,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); - f1->integral(true,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); - f1->normL1(res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); - f1->normL2(res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-12); - // - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest2::testAreaBary2D() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - double expected1[10]={-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1}; - const double *ptr=f1->getArray()->getConstPointer(); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); - f1->decrRef(); - f1=m1->getMeasureField(true); - ptr=f1->getArray()->getConstPointer(); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); - f1->decrRef(); - DataArrayDouble *f2=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - double expected2[20]={ - 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, - 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, - }; - ptr=f2->getConstPointer(); - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); - f2->decrRef(); - m1->changeSpaceDimension(3); - f1=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - ptr=f1->getArray()->getConstPointer(); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); - f1->decrRef(); - f2=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); - ptr=f2->getConstPointer(); - double expected3[30]={ - 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., - 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0. - }; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); - f2->decrRef(); - m1->decrRef(); -} - -/*! - * This test check polyhedron true barycenter computation 2. - */ -void MEDCouplingBasicsTest2::testAreaBary3D() -{ - double coords [] = { 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , - 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , - 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , - 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , - -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , - -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , - 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , - 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , - -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , - 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , - -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , - -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , - -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , - -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , - -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , - -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , - 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , - 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , - 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , - -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , - -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , - -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , - -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , - 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , - 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , - 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , - -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , - -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , - 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , - 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , - -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , - 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , - 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , - 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , - -0.0372812069535 , -0.286740286332 , 0.00963701291166 }; - - int connN [] = { /*polyhedron 0*/ - 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 - , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 - , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 - , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, - /* polyhedron 1*/ - 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 - , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 - , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 - , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, - /* polyhedron 2*/ - 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 - , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, - /*polyhedron 3*/ - 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 - , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 - , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 - , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65}; - - double barys[]={ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , - 0.0287618656076 , 0.135874379934 , -0.14601588119 , - -0.147128055553 , 0.0465995097041 , -0.049391174453 , - -0.00142506732317 , -0.0996953090351 , -0.115159183132 }; - MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); - meshN->setName("ForBary"); - meshN->setMeshDimension(3); - meshN->allocateCells(4); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,113,connN); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,99,connN+113); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,connN+212); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,92,connN+255); - meshN->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(69,3); - std::copy(coords,coords+207,myCoords->getPointer()); - meshN->setCoords(myCoords); - myCoords->decrRef(); - meshN->checkCoherency(); - std::vector res1; - meshN->arePolyhedronsNotCorrectlyOriented(res1); - meshN->orientCorrectlyPolyhedrons(); - res1.clear(); - meshN->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - // - DataArrayDouble *da=meshN->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); - const double *daPtr=da->getConstPointer(); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(barys[i],daPtr[i],1e-12); - da->decrRef(); - // - meshN->decrRef(); -} - -void MEDCouplingBasicsTest2::testRenumberCellsForFields() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - int nbOfCells=m->getNumberOfCells(); - arr->alloc(nbOfCells,3); - f->setArray(arr); - arr->decrRef(); - const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; - std::copy(values1,values1+15,arr->getPointer()); - const int renumber1[5]={3,1,0,4,2}; - double res[3]; - const double loc[]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; - for(int j=0;j<5;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); - } - f->renumberCells(renumber1,false); - const double *ptr=f->getArray()->getConstPointer(); - const double expected1[15]={9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); - //check that fields remains the same geometrically - for(int j=0;j<5;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); - } - f->decrRef(); - //On gauss - f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); - f->setMesh(m); - const double _a=0.446948490915965; - const double _b=0.091576213509771; - const double _p1=0.11169079483905; - const double _p2=0.0549758718227661; - const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; - const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - std::vector _refCoo1(refCoo1,refCoo1+6); - std::vector _gsCoo1(gsCoo1,gsCoo1+12); - std::vector _wg1(wg1,wg1+6); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; - std::vector _refCoo2(refCoo2,refCoo2+8); - _gsCoo1.resize(4); _wg1.resize(2); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - arr=DataArrayDouble::New(); - arr->alloc(18,2); - const double values2[36]={1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.}; - std::copy(values2,values2+36,arr->getPointer()); - f->setArray(arr); - arr->decrRef(); - f->checkCoherency(); - MEDCouplingFieldDouble *fCpy=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - f->renumberCells(renumber1,false); - CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); - double expected2[36]={21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.}; - ptr=f->getArray()->getConstPointer(); - for(int i=0;i<36;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); - const int renumber2[5]={2,1,4,0,3};//reverse renumber1 - f->renumberCells(renumber2,false); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - fCpy->decrRef(); - f->decrRef(); - //GaussNE - f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); - f->setMesh(m); - arr=DataArrayDouble::New(); - arr->alloc(18,2); - const double values3[36]={1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.}; - std::copy(values3,values3+36,arr->getPointer()); - f->setArray(arr); - arr->decrRef(); - f->checkCoherency(); - fCpy=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - f->renumberCells(renumber1,false); - CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); - double expected3[36]={21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.}; - ptr=f->getArray()->getConstPointer(); - for(int i=0;i<36;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); - f->renumberCells(renumber2,false);//perform reverse operation of renumbering to check that the resulting field is equal. - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - fCpy->decrRef(); - f->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testRenumberNodesForFields() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(9,f->getNumberOfMeshPlacesExpected()); - DataArrayDouble *arr=DataArrayDouble::New(); - int nbOfNodes=m->getNumberOfNodes(); - arr->alloc(nbOfNodes,3); - f->setArray(arr); - arr->decrRef(); - const double values1[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; - std::copy(values1,values1+27,arr->getPointer()); - f->checkCoherency(); - const int renumber1[9]={0,4,1,3,5,2,6,7,8}; - double res[3]; - const double loc[]={0.5432,-0.2432, 0.5478,0.1528}; - const double expected1[6]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124}; - for(int j=0;j<2;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); - } - MEDCouplingFieldDouble *fCpy=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - f->renumberNodes(renumber1); - CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); - for(int j=0;j<2;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); - } - const double expected2[27]={7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; - for(int i=0;i<27;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getArray()->getConstPointer()[i],1e-12); - const int renumber2[9]={0,2,5,3,1,4,6,7,8};//reverse of renumber2 - f->renumberNodes(renumber2); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - fCpy->decrRef(); - // - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest2::testConvertQuadraticCellsToLinear() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_3(); - mesh->checkCoherency(); - std::set types=mesh->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(5,(int)types.size()); - INTERP_KERNEL::NormalizedCellType expected1[5]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8}; - std::set expected1Bis(expected1,expected1+5); - CPPUNIT_ASSERT(expected1Bis==types); - CPPUNIT_ASSERT(mesh->isPresenceOfQuadratic()); - CPPUNIT_ASSERT_EQUAL(62,mesh->getMeshLength()); - MEDCouplingFieldDouble *f1=mesh->getMeasureField(false); - // - mesh->convertQuadraticCellsToLinear(); - CPPUNIT_ASSERT(!mesh->isPresenceOfQuadratic()); - // - mesh->checkCoherency(); - MEDCouplingFieldDouble *f2=mesh->getMeasureField(false); - CPPUNIT_ASSERT(f1->getArray()->isEqual(*f2->getArray(),1e-12)); - CPPUNIT_ASSERT_EQUAL(48,mesh->getMeshLength()); - std::set types2=mesh->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(3,(int)types2.size()); - INTERP_KERNEL::NormalizedCellType expected2[3]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; - std::set expected2Bis(expected2,expected2+3); - CPPUNIT_ASSERT(expected2Bis==types2); - // - f1->decrRef(); - f2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest2::testCheckGeoEquivalWith() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); - DataArrayInt *cellCor,*nodeCor; - //First test mesh1 - mesh1->checkGeoEquivalWith(mesh1,0,1e-12,cellCor,nodeCor);//deepEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh1,1,1e-12,cellCor,nodeCor);//fastEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - //Second test mesh1 and mesh2 are 2 different meshes instance - mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - //Third test : cell permutation by keeping the first the middle and the last as it is. - const int renum[]={0,2,1,3,4,5,6,8,7,9}; - mesh2->renumberCells(renum,false); - CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor); - CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); - CPPUNIT_ASSERT(nodeCor==0); - cellCor->decrRef(); - cellCor=0; - CPPUNIT_ASSERT(nodeCor==0); - //4th test : cell and node permutation by keeping the first the middle and the last as it is. - mesh2->decrRef(); - mesh2=build2DTargetMesh_3(); - const int renum2[]={0,2,1,3,4,5,6,8,7,9,10}; - mesh2->renumberCells(renum,false); - mesh2->renumberNodes(renum2,11); - CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor); - CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); - CPPUNIT_ASSERT(nodeCor); - CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); - cellCor->decrRef(); - cellCor=0; - nodeCor->decrRef(); - nodeCor=0; - //5th test : modification of the last cell to check fastCheck detection. - mesh2->decrRef(); - mesh2=build2DTargetMesh_3(); - const int renum3[]={0,2,1,3,4,5,6,8,9,7}; - mesh2->renumberCells(renum3,false); - mesh2->renumberNodes(renum2,11); - bool isExcep=false; - try { mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual fails - } - catch(INTERP_KERNEL::Exception& e) { isExcep=true; } - CPPUNIT_ASSERT(isExcep); isExcep=false; - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - try { mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual has detected something - } - catch(INTERP_KERNEL::Exception& e) { isExcep=true; } - CPPUNIT_ASSERT(isExcep); isExcep=false; - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh2->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor); - CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum3,renum3+10,cellCor->getConstPointer())); - CPPUNIT_ASSERT(nodeCor); - CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); - cellCor->decrRef(); - cellCor=0; - nodeCor->decrRef(); - nodeCor=0; - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testCheckGeoEquivalWith2() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_4(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - DataArrayInt *cellCor,*nodeCor; - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor); - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor!=0); - const int expected1[9]={0, 1, 3, 4, 5, 6, 7, 8, 9}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],nodeCor->getIJ(i,0)); - nodeCor->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testCopyTinyStringsFromOnFields() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); - f->setName("a"); - f->setDescription("b"); - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(nbOfCells,2); - a1->fillWithZero(); - a1->setInfoOnComponent(0,"c"); - a1->setInfoOnComponent(1,"d"); - DataArrayDouble *a2=a1->deepCpy(); - a2->setInfoOnComponent(0,"e"); - a2->setInfoOnComponent(1,"f"); - f->setArray(a1); - f->setEndArray(a2); - f->setEndTime(3.,3,4); - a2->decrRef(); - a1->decrRef(); - m->setName("g"); - m->getCoords()->setInfoOnComponent(0,"h"); - m->getCoords()->setInfoOnComponent(1,"i"); - m->getCoords()->setInfoOnComponent(2,"j"); - // - f->checkCoherency(); - MEDCouplingFieldDouble *f2=f->clone(true); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->setName("smth"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->setDescription("GGG"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->getArray()->setInfoOnComponent(0,"mmmm"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->getEndArray()->setInfoOnComponent(1,"mmmm"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->decrRef(); - MEDCouplingUMesh *m2=m->clone(true); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->setName("123"); - CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); - m2->copyTinyStringsFrom(m); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->getCoords()->setInfoOnComponent(1,"eee"); - CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); - m2->copyTinyStringsFrom(m); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->decrRef(); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testTryToShareSameCoordsPermute() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); - m->tryToShareSameCoordsPermute(*m2,1e-12); - CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - const int renum1[9]={1,2,0,5,8,7,4,3,6}; - m->renumberNodes(renum1,9); - CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); - CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); - m->tryToShareSameCoordsPermute(*m2,1e-12); - CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testTryToShareSameCoordsPermute2() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_4(); - double targetCoords[8]={-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 }; - int targetConn[4]={0,2,3,1}; - MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); - m2->setMeshDimension(2); - m2->allocateCells(1); - m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - m2->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - m2->setCoords(myCoords); - myCoords->decrRef(); - m2->checkCoherency(); - m1->checkCoherency(); - // - const double expected1[5]={0.25,0.125,0.125,0.25,0.25}; - MEDCouplingFieldDouble *f1=m1->getMeasureField(false); - MEDCouplingFieldDouble *f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); - f2->decrRef(); - f1->decrRef(); - CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoordsPermute(*m2,1e-12),INTERP_KERNEL::Exception);// <- here in this order the sharing is impossible. - // Let's go for deeper test of tryToShareSameCoordsPermute - m2->tryToShareSameCoordsPermute(*m1,1e-12); - f1=m1->getMeasureField(false); - f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); - // - f2->decrRef(); - f1->decrRef(); - // - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest2::testChangeUnderlyingMesh1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; - std::copy(arr,arr+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const int renum[]={0,2,1,3,4,5,6,8,7,9}; - mesh2->renumberCells(renum,false); - CPPUNIT_ASSERT(f1->getMesh()==mesh1); - f1->changeUnderlyingMesh(mesh1,10,1e-12);// nothing done only to check that nothing done. - CPPUNIT_ASSERT(f1->getMesh()==mesh1); - f1->changeUnderlyingMesh(mesh2,10,1e-12); - CPPUNIT_ASSERT(f1->getMesh()==mesh2); - const double expected1[20]={7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),2); - const double arr2[22]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.}; - std::copy(arr2,arr2+22,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const int renum2[]={0,2,10,3,4,5,6,8,7,9,1}; - mesh2->renumberNodes(renum2,11); - CPPUNIT_ASSERT(f1->getMesh()==mesh1); - f1->changeUnderlyingMesh(mesh2,10,1e-12); - CPPUNIT_ASSERT(f1->getMesh()==mesh2); - const double expected2[22]={7.,107.,17.,117.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,9.,109.}; - for(int i=0;i<22;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetMaxValue1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f->setMesh(m); - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(nbOfCells,1); - const double val1[5]={3.,4.,5.,6.,7.}; - std::copy(val1,val1+5,a1->getPointer()); - DataArrayDouble *a2=DataArrayDouble::New(); - a2->alloc(nbOfCells,1); - const double val2[5]={0.,1.,2.,8.,7.}; - std::copy(val2,val2+5,a2->getPointer()); - f->setArray(a1); - f->setEndArray(a2); - f->setEndTime(3.,3,4); - f->checkCoherency(); - // - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,f->getMaxValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,f->getAverageValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(0),1e-14); - a1->setIJ(0,2,9.5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); - a2->setIJ(0,0,9.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,f->getMinValue(),1e-14); - // - a2->decrRef(); - a1->decrRef(); - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest2::testSubstractInPlaceDM1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; - std::copy(arr,arr+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(10,f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(20,f1->getNumberOfValues()); - // - const int renum[]={0,2,3,1,4,5,6,8,7,9}; - mesh2->renumberCells(renum,false); - // - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f2->setMesh(mesh2); - array=DataArrayDouble::New(); - array->alloc(mesh2->getNumberOfCells(),2); - const double arr2[20]={7.1,107.1,10.1,110.1,8.1,108.1,9.1,109.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1}; - std::copy(arr2,arr2+20,array->getPointer()); - f2->setArray(array); - array->decrRef(); - // - f1->substractInPlaceDM(f2,10,1e-12); - f1->applyFunc(1,"abs(x+y+0.2)"); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f1->getMaxValue(),1e-14); - // - f1->decrRef(); - f2->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testDotCrossProduct1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setTime(7.8,4,5); - f2->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr2[30]={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.}; - std::copy(arr2,arr2+30,array->getPointer()); - f2->setArray(array); - array->decrRef(); - // - MEDCouplingFieldDouble *f3=f1->dot(*f2); - const double expected1[10]={842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(i,0),1e-9); - f3->decrRef(); - // - MEDCouplingFieldDouble *f4=f1->crossProduct(*f2); - const double expected2[30]={-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); - f4->decrRef(); - // - f2->decrRef(); - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testMinMaxFields1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setTime(7.8,4,5); - f2->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr2[30]={6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.}; - std::copy(arr2,arr2+30,array->getPointer()); - f2->setArray(array); - array->decrRef(); - // - MEDCouplingFieldDouble *f3=f1->max(*f2); - const double expected1[30]={7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-9); - f3->decrRef(); - // - MEDCouplingFieldDouble *f4=f1->min(*f2); - const double expected2[30]={6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); - f4->decrRef(); - // - f2->decrRef(); - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testApplyLin1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; - std::copy(arr,arr+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - f1->applyLin(2.,3.,0); - const double expected1[20]={17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-9); - // - const double arr2[20]={2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - std::copy(arr2,arr2+20,array->getPointer()); - f1->setEndArray(array); - array->decrRef(); - // - f1->applyLin(4.,5.,1); - // - const double expected2[20]={17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-9); - const double expected3[20]={2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f1->getEndArray()->getIJ(0,i),1e-9); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetIdsInRange1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),1); - const double arr1[10]={2.,8.,6.,5.,11.,7.,9.,3.,10.,4.}; - std::copy(arr1,arr1+10,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - f1->checkCoherency(); - DataArrayInt *da=f1->getIdsInRange(2.9,7.1); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,da->getNbOfElems()); - const int expected1[5]={2,3,5,7,9}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); - da->decrRef(); - da=f1->getIdsInRange(8.,12.); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,da->getNbOfElems()); - const int expected2[4]={1,4,6,8}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+4,da->getConstPointer())); - da->decrRef(); - // - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testBuildSubPart1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; - std::copy(arr1,arr1+10,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const int part1[3]={2,1,4}; - MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); - f2->zipCoords(); - CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - const double expected1[6]={5.,105.,4.,104.,7.,107.}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected1[i],1e-12); - CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - MEDCouplingUMesh *m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); - const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); - const double expected4[4]={0,4,8,13}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - f1->decrRef(); - // Test with field on nodes. - f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),2); - const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; - std::copy(arr2,arr2+18,array->getPointer()); - f1->setArray(array); - array->decrRef(); - const int part2[2]={1,2}; - f2=f1->buildSubPart(part2,part2+2); - CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - const double expected5[8]={4.,104.,5.,105.,7.,107.,8.,108.}; - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); - for(int i=0;i<8;i++)//8 is not an error - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); - CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - //idem previous because nodes of cell#4 are not fully present in part3 - const int part3[2]={1,2}; - DataArrayInt *arrr=DataArrayInt::New(); - arrr->alloc(2,1); - std::copy(part3,part3+2,arrr->getPointer()); - f2=f1->buildSubPart(arrr); - arrr->decrRef(); - CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); - for(int i=0;i<8;i++)//8 is not an error - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); - CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - // - const int part4[3]={1,2,4}; - f2=f1->buildSubPart(part4,part4+3); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - const double expected6[12]={4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected6[i],1e-12); - CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); - CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3+8,expected3+13,m2C->getNodalConnectivity()->getConstPointer()+8)); - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - // - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testDoublyContractedProduct1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->doublyContractedProduct(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(3906.56,f2->getIJ(i,0),1e-9); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testDeterminant1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1->setTime(2.3,5,6); - f1->setEndTime(3.8,7,3); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),4); - const double arr1[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; - std::copy(arr1,arr1+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - //4 components - f1->checkCoherency(); - MEDCouplingFieldDouble *f2=f1->determinant(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(CONST_ON_TIME_INTERVAL,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfValues()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.42,f2->getIJ(i,0),1e-13); - f2->decrRef(); - f1->decrRef(); - //6 components multi arrays with end array not defined - f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); - f1->setTime(2.3,5,6); - f1->setEndTime(3.8,7,3); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),6); - const double arr2[54]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, - 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr2,arr2+54,array->getPointer()); - f1->setArray(array); - array->decrRef(); - CPPUNIT_ASSERT_THROW(f1->checkCoherency(),INTERP_KERNEL::Exception);//no end array specified ! - // - f2=f1->determinant(); - CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); - f2->decrRef(); - //6 components multi arrays with end array defined - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),6); - const double arr3[54]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, - 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr3,arr3+54,array->getPointer()); - f1->setEndArray(array); - array->decrRef(); - f1->checkCoherency(); - f2=f1->determinant(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - int it,order; - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(it,order),1e-12); - CPPUNIT_ASSERT_EQUAL(5,it); CPPUNIT_ASSERT_EQUAL(6,order); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.8,f2->getEndTime(it,order),1e-12); - CPPUNIT_ASSERT_EQUAL(7,it); CPPUNIT_ASSERT_EQUAL(3,order); - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1289.685,f2->getEndArray()->getIJ(i,0),1e-9); - } - f2->decrRef(); - f1->decrRef(); - //9 components - f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(7.8,10,2); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),9); - const double arr4[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; - std::copy(arr4,arr4+45,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - f1->checkCoherency(); - f2=f1->determinant(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(ONE_TIME,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f2->getTime(it,order),1e-12); - CPPUNIT_ASSERT_EQUAL(10,it); CPPUNIT_ASSERT_EQUAL(2,order); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.267,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testEigenValues1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->eigenValues(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[3]={13.638813677891717,-4.502313844635971,-2.2364998332557486}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testEigenVectors1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->eigenVectors(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[9]={ - 0.5424262364180696, 0.5351201064614425, 0.6476266283176001,//eigenvect 0 - 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,//eigenvect 1 - -0.4012053603397987, 0.8423032781211455, -0.3599436712889738//eigenvect 2 - }; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testInverse1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),9); - const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; - std::copy(arr1,arr1+45,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->inverse(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[9]={-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); - } - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr3,arr3+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->inverse(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected3[6]={-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[5],f2->getIJ(i,5),1e-13); - } - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),4); - const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; - std::copy(arr2,arr2+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->inverse(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected2[4]={-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[3],f2->getIJ(i,3),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testTrace1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),9); - const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; - std::copy(arr1,arr1+45,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->trace(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.9,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr3,arr3+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->trace(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.8,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),4); - const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; - std::copy(arr2,arr2+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->trace(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testDeviator1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->deviator(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[6]={-1.1,0.,1.1,4.5,5.6,6.7}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testMagnitude1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->magnitude(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.3606219864313918,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testMaxPerTuple1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->maxPerTuple(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - DataArrayInt *d2I=0; - DataArrayDouble *d2=array->maxPerTupleWithCompoId(d2I); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,d2->getNumberOfTuples()); - const int expected2[5]={4,3,2,0,1}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,d2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_EQUAL(expected2[i],d2I->getIJ(i,0)); - } - d2->decrRef(); d2I->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testChangeNbOfComponents() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f1->changeNbOfComponents(3,7.77); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - const double expected1[15]={1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-13); - f1->changeNbOfComponents(4,7.77); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - const double expected2[20]={1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-13); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testSortPerTuple1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f1->sortPerTuple(true); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,4),1e-13); - } - // - f1->sortPerTuple(false); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,4),1e-13); - } - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testIsEqualWithoutConsideringStr1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - DataArrayInt *da1,*da2; - // - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->setName("rr"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh1->checkDeepEquivalWith(mesh2,2,1e-12,da1,da2); - CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,da1,da2),INTERP_KERNEL::Exception); - mesh2->setName(""); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(0,"tty"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(0,""); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(1,"tty"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(1,""); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - double tmp=mesh2->getCoords()->getIJ(0,3); - mesh2->getCoords()->setIJ(0,3,9999.); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setIJ(0,3,tmp); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - int tmp2=mesh2->getNodalConnectivity()->getIJ(0,4); - mesh2->getNodalConnectivity()->setIJ(0,4,0); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getNodalConnectivity()->setIJ(0,4,tmp2); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - // - MEDCouplingFieldDouble *f1=mesh1->getMeasureField(true); - MEDCouplingFieldDouble *f2=mesh2->getMeasureField(true); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2->setName("ftest"); - CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f1->setName("ftest"); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - // - f2->getArray()->setInfoOnComponent(0,"eee"); - CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2->getArray()->setInfoOnComponent(0,""); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - // - f2->getArray()->setIJ(1,0,0.123); - CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(!f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2->getArray()->setIJ(1,0,0.125); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - // - f1->decrRef(); - f2->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetNodeIdsOfCell1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - std::vector nodeIds; - mesh1->getNodeIdsOfCell(1,nodeIds); - CPPUNIT_ASSERT_EQUAL(3,(int)nodeIds.size()); - CPPUNIT_ASSERT_EQUAL(1,nodeIds[0]); - CPPUNIT_ASSERT_EQUAL(4,nodeIds[1]); - CPPUNIT_ASSERT_EQUAL(2,nodeIds[2]); - std::vector coords; - mesh1->getCoordinatesOfNode(4,coords); - CPPUNIT_ASSERT_EQUAL(2,(int)coords.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[1],1e-13); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetEdgeRatioField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->setTime(3.4,5,6); m1->setTimeUnit("us"); - int a,b; - MEDCouplingFieldDouble *f1=m1->getEdgeRatioField(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - const double expected1[5]={1.,1.4142135623730951, 1.4142135623730951,1.,1.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-14); - f1->decrRef(); - m1->decrRef(); - // - m1=build3DSurfTargetMesh_1(); - f1=m1->getEdgeRatioField(); - CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - const double expected2[5]={1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(i,0),1e-14); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest2::testFillFromAnalytic3() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"y+x"),INTERP_KERNEL::Exception); - f1->setMesh(m); - f1->setName("myField"); - f1->fillFromAnalytic(1,"y+x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(std::string(f1->getName())=="myField"); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+5,values1,values1,std::minus()); - std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,CONST_ON_TIME_INTERVAL); - f1->setMesh(m); - f1->setEndTime(1.2,3,4); - f1->fillFromAnalytic(1,"y+2*x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==CONST_ON_TIME_INTERVAL); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); - f1->setMesh(m); - f1->setEndTime(1.2,3,4); - f1->fillFromAnalytic(1,"2.*x+y"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==LINEAR_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - tmp=f1->getArray()->getConstPointer(); - double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - double values2BisBis[9]; - std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus()); - std::transform(values2,values2+9,values2BisBis,std::ptr_fun(fabs)); - max=*std::max_element(values2BisBis,values2BisBis+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - tmp=f1->getEndArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus()); - std::transform(values2,values2+9,values2BisBis,std::ptr_fun(fabs)); - max=*std::max_element(values2BisBis,values2BisBis+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f1->setMesh(m); - f1->fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values3,values3,std::minus()); - std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - double values4[2]; - f1->accumulate(values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->integral(true,values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f1->setMesh(m); - CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"1./(x-0.2)"),INTERP_KERNEL::Exception); - // - m->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testFieldDoubleOpEqual1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT_THROW((*f1)=0.07,INTERP_KERNEL::Exception); - f1->setMesh(m); - (*f1)=0.07; - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.07,f1->getIJ(i,0),1e-16); - (*f1)=0.09; - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09,f1->getIJ(i,0),1e-16); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); - f1->setEndTime(4.5,2,3); - f1->setMesh(m); - (*f1)=0.08; - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getIJ(i,0),1e-16); - CPPUNIT_ASSERT_EQUAL(1,f1->getEndArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getEndArray()->getNumberOfTuples()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getEndArray()->getIJ(i,0),1e-16); - f1->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testAreaBary3D2() -{ - const double coordsForHexa8[24]={ - -75.45749305371, 180.95495078401, 39.515472018008, - -9.755591679144, 23.394927935279, 5.108794294848, - 14.337630157832, 61.705351002702, 160.42422501908, - -27.273893776752, 167.567731083961, 192.830034145464, - // - 99.857193154796,264.499264735586,-8.287335493412, - 144.939882761126,156.38626563134,-31.896173894226, - 161.34096835726,182.4654895809,73.832387065572, - 132.680430393685,255.37973247196,96.15235602819 - }; - const double volHexa8=3258520.29637466; - const double baryHexa8[3]={43.925705821778, 155.31893955289, 65.874418109644}; - - const double coordsForPenta6[18]={ - -68.199829618726,178.938498373416,62.608505919588, - 8.461744647847,76.653979804423,165.00018874933, - -27.273893776752,167.567731083961,192.830034145464, - // - 106.586501038965,262.629609408327,13.124533008813, - 155.465082847275,197.414118382622,78.408350795821, - 132.680430393685,255.37973247196,96.15235602819 - }; - const double volPenta6=944849.868507338; - const double baryPenta6[3]={39.631002313543,182.692711783428,106.98540473964}; - - const double coordsForPyra5[15]={ - 132.680430393685,255.37973247196,96.15235602819, - -27.273893776752,167.567731083961,192.830034145464, - 8.461744647847,76.653979804423,165.00018874933, - 155.465082847275,197.414118382622,78.408350795821, - // - -68.199829618726,178.938498373416,62.608505919588 - }; - const double volPyra5=756943.92980254; - const double baryPyra5[3]={29.204294116618,172.540129749156,118.01035951483}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Bary3D2",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(19,3); - double *tmp=std::copy(coordsForHexa8,coordsForHexa8+24,coo->getPointer()); - tmp=std::copy(coordsForPenta6,coordsForPenta6+18,tmp); - std::copy(coordsForPyra5,coordsForPyra5+15,tmp); - mesh->setCoords(coo); - coo->decrRef(); - // - int tmpConn[8]={0,1,2,3,4,5,6,7}; - mesh->allocateCells(3); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,tmpConn); - std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus(),8)); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,tmpConn); - std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus(),6)); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,tmpConn); - mesh->finishInsertingCells(); - mesh->checkCoherency(); - bool isMerged; - int newNebOfNodes; - DataArrayInt *da=mesh->mergeNodes(1e-7,isMerged,newNebOfNodes); - da->decrRef(); - CPPUNIT_ASSERT_EQUAL(12,newNebOfNodes); - MEDCouplingFieldDouble *vols=mesh->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(3,vols->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(volHexa8,vols->getIJ(0,0),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(volPenta6,vols->getIJ(1,0),1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(volPyra5,vols->getIJ(2,0),1e-7); - vols->decrRef(); - DataArrayDouble *bary=mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[0],bary->getIJ(0,0),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[1],bary->getIJ(0,1),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[2],bary->getIJ(0,2),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[0],bary->getIJ(1,0),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[1],bary->getIJ(1,1),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[2],bary->getIJ(1,2),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[0],bary->getIJ(2,0),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[1],bary->getIJ(2,1),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[2],bary->getIJ(2,2),1e-11); - bary->decrRef(); - // - mesh->decrRef(); -} diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx deleted file mode 100644 index f514d7b31..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTEST2_HXX__ -#define __MEDCOUPLINGBASICSTEST2_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest2 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest2); - CPPUNIT_TEST( testGaussPointField1 ); - CPPUNIT_TEST( testGaussPointNEField1 ); - CPPUNIT_TEST( testCellOrientation1 ); - CPPUNIT_TEST( testCellOrientation2 ); - CPPUNIT_TEST( testCellOrientation3 ); - CPPUNIT_TEST( testPolyhedronBarycenter ); - CPPUNIT_TEST( testNormL12Integ1D ); - CPPUNIT_TEST( testAreaBary2D ); - CPPUNIT_TEST( testAreaBary3D ); - CPPUNIT_TEST( testRenumberCellsForFields ); - CPPUNIT_TEST( testRenumberNodesForFields ); - CPPUNIT_TEST( testConvertQuadraticCellsToLinear ); - CPPUNIT_TEST( testCheckGeoEquivalWith ); - CPPUNIT_TEST( testCheckGeoEquivalWith2 ); - CPPUNIT_TEST( testCopyTinyStringsFromOnFields ); - CPPUNIT_TEST( testTryToShareSameCoordsPermute ); - CPPUNIT_TEST( testTryToShareSameCoordsPermute2 ); - CPPUNIT_TEST( testChangeUnderlyingMesh1 ); - CPPUNIT_TEST( testGetMaxValue1 ); - CPPUNIT_TEST( testSubstractInPlaceDM1 ); - CPPUNIT_TEST( testDotCrossProduct1 ); - CPPUNIT_TEST( testMinMaxFields1 ); - CPPUNIT_TEST( testApplyLin1 ); - CPPUNIT_TEST( testGetIdsInRange1 ); - CPPUNIT_TEST( testBuildSubPart1 ); - CPPUNIT_TEST( testDoublyContractedProduct1 ); - CPPUNIT_TEST( testDeterminant1 ); - CPPUNIT_TEST( testEigenValues1 ); - CPPUNIT_TEST( testEigenVectors1 ); - CPPUNIT_TEST( testInverse1 ); - CPPUNIT_TEST( testTrace1 ); - CPPUNIT_TEST( testDeviator1 ); - CPPUNIT_TEST( testMagnitude1 ); - CPPUNIT_TEST( testMaxPerTuple1 ); - CPPUNIT_TEST( testChangeNbOfComponents ); - CPPUNIT_TEST( testSortPerTuple1 ); - CPPUNIT_TEST( testIsEqualWithoutConsideringStr1 ); - CPPUNIT_TEST( testGetNodeIdsOfCell1 ); - CPPUNIT_TEST( testGetEdgeRatioField1 ); - CPPUNIT_TEST( testFillFromAnalytic3 ); - CPPUNIT_TEST( testFieldDoubleOpEqual1 ); - CPPUNIT_TEST( testAreaBary3D2 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testGaussPointField1(); - void testGaussPointNEField1(); - void testCellOrientation1(); - void testCellOrientation2(); - void testCellOrientation3(); - void testPolyhedronBarycenter(); - void testNormL12Integ1D(); - void testAreaBary2D(); - void testAreaBary3D(); - void testRenumberCellsForFields(); - void testRenumberNodesForFields(); - void testConvertQuadraticCellsToLinear(); - void testCheckGeoEquivalWith(); - void testCheckGeoEquivalWith2(); - void testCopyTinyStringsFromOnFields(); - void testTryToShareSameCoordsPermute(); - void testTryToShareSameCoordsPermute2(); - void testChangeUnderlyingMesh1(); - void testGetMaxValue1(); - void testSubstractInPlaceDM1(); - void testDotCrossProduct1(); - void testMinMaxFields1(); - void testApplyLin1(); - void testGetIdsInRange1(); - void testBuildSubPart1(); - void testDoublyContractedProduct1(); - void testDeterminant1(); - void testEigenValues1(); - void testEigenVectors1(); - void testInverse1(); - void testTrace1(); - void testDeviator1(); - void testMagnitude1(); - void testMaxPerTuple1(); - void testChangeNbOfComponents(); - void testSortPerTuple1(); - void testIsEqualWithoutConsideringStr1(); - void testGetNodeIdsOfCell1(); - void testGetEdgeRatioField1(); - void testFillFromAnalytic3(); - void testFieldDoubleOpEqual1(); - void testAreaBary3D2(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx deleted file mode 100644 index 358d1c4a1..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx +++ /dev/null @@ -1,2467 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest3.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest3::testGetMeasureFieldCMesh1() -{ - MEDCouplingCMesh *m=MEDCouplingCMesh::New(); - DataArrayDouble *da=DataArrayDouble::New(); - const double discX[4]={2.3,3.4,5.8,10.2}; - const double discY[3]={12.3,23.4,45.8}; - const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; - da->alloc(4,1); - std::copy(discX,discX+4,da->getPointer()); - m->setCoordsAt(0,da); - da->decrRef(); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(1,m->getSpaceDimension()); - MEDCouplingFieldDouble *f=m->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(3,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const double expected1[3]={1.1,2.4,4.4}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(i,0),1e-12); - f->decrRef(); - DataArrayDouble *coords=m->getCoordinatesAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(discX[i],coords->getIJ(i,0),1e-12); - coords->decrRef(); - coords=m->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); - const double expected1_3[3]={2.85,4.6,8.}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1_3[i],coords->getIJ(i,0),1e-12); - coords->decrRef(); - // - da=DataArrayDouble::New(); - da->alloc(3,1); - std::copy(discY,discY+3,da->getPointer()); - m->setCoordsAt(1,da); - da->decrRef(); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(12,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(6,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(2,m->getSpaceDimension()); - f=m->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(6,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const double expected2[6]={12.21,26.64,48.84,24.64,53.76,98.56}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(i,0),1e-12); - f->decrRef(); - coords=m->getCoordinatesAndOwner(); - CPPUNIT_ASSERT_EQUAL(12,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); - const double expected2_2[24]={2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8}; - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_2[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - coords=m->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(6,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); - const double expected2_3[12]={2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_3[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - // - da=DataArrayDouble::New(); - da->alloc(5,1); - std::copy(discZ,discZ+5,da->getPointer()); - m->setCoordsAt(2,da); - da->decrRef(); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(60,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(24,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); - f=m->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(24,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const double expected3[24]={23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224}; - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f->getIJ(i,0),1e-12); - f->decrRef(); - coords=m->getCoordinatesAndOwner(); - CPPUNIT_ASSERT_EQUAL(60,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); - const double expected3_2[180]={ - 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, - 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, - 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, - 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, - 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67 - }; - for(int i=0;i<180;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_2[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - coords=m->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(24,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); - const double expected3_3[72]={ - 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, - 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, - 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, - 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4 - }; - for(int i=0;i<72;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_3[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldDoubleZipCoords1() -{ - MEDCouplingUMesh *m=build2DTargetMeshMergeNode_1(); - MEDCouplingFieldDouble *f=m->fillFromAnalytic(ON_NODES,2,"x*2."); - f->getArray()->setInfoOnComponent(0,"titi"); - f->getArray()->setInfoOnComponent(1,"tutu"); - f->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(18,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); - const double expected1[36]={-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; - for(int i=0;i<36;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(f->zipCoords()); - f->checkCoherency(); - const double expected2[30]={-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(!f->zipCoords()); - f->checkCoherency(); - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldDoubleZipConnectivity1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - const int cells1[3]={2,3,4}; - MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m3=dynamic_cast(m3_1); - CPPUNIT_ASSERT(m3); - m2->decrRef(); - MEDCouplingUMesh *m4=build2DSourceMesh_1(); - MEDCouplingUMesh *m5=MEDCouplingUMesh::MergeUMeshes(m1,m3); - m1->decrRef(); - m3->decrRef(); - MEDCouplingUMesh *m6=MEDCouplingUMesh::MergeUMeshes(m5,m4); - m4->decrRef(); - m5->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); - bool areNodesMerged; - int newNbOfNodes; - DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); - arr->decrRef(); - MEDCouplingFieldDouble *f=m6->fillFromAnalytic(ON_CELLS,2,"x"); - MEDCouplingFieldDouble *f2=m6->fillFromAnalytic(ON_NODES,2,"x"); - CPPUNIT_ASSERT_EQUAL(10,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); - const double expected1[20]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, - 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); - f->getArray()->setInfoOnComponent(0,"titi"); - f->getArray()->setInfoOnComponent(1,"tutu"); - f->checkCoherency(); - CPPUNIT_ASSERT(f->zipConnectivity(0)); - const double expected2[14]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; - CPPUNIT_ASSERT_EQUAL(7,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); - CPPUNIT_ASSERT(!f->zipConnectivity(0)); - f->decrRef(); - // - const double expected3[18]={-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, - -0.3, -0.3, 0.2, 0.2, 0.7, 0.7}; - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(f2->zipConnectivity(0)); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); - f2->decrRef(); - // - m6->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumber1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - DataArrayDouble *b=a->renumber(arr2); - CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->renumber(arr2); - CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberAndReduce1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={2,-1,1,-1,0,4,3}; - DataArrayDouble *b=a->renumberAndReduce(arr2,5); - CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->renumberAndReduce(arr2,5); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberInPlace1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - a->renumberInPlace(arr2); - CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); - const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - c->renumberInPlace(arr2); - CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); - const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); - c->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberR1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - DataArrayDouble *b=a->renumberR(arr2); - CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->renumberR(arr2); - CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberInPlaceR1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - a->renumberInPlaceR(arr2); - CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); - const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - c->renumberInPlaceR(arr2); - CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); - const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); - c->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleSelectByTupleId1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={4,2,0,6,5}; - DataArrayDouble *b=a->selectByTupleId(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->selectByTupleId(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleGetMinMaxValues1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(9,1); - const double arr1[9]={2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56}; - std::copy(arr1,arr1+9,a->getPointer()); - int where; - double m=a->getMaxValue(where); - CPPUNIT_ASSERT_EQUAL(1,where); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); - DataArrayInt *ws; - m=a->getMaxValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); - CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - const int expected1[3]={1,4,8}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - a->decrRef(); - a=DataArrayDouble::New(); - const double arr2[9]={-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56}; - a->alloc(9,1); - std::copy(arr2,arr2+9,a->getPointer()); - where=-2; - m=a->getMinValue(where); - CPPUNIT_ASSERT_EQUAL(1,where); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); - m=a->getMinValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); - CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldDoubleGetMinMaxValues2() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); - m1->decrRef(); - CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); - const double arr1[18]={8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71}; - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(18,1); - std::copy(arr1,arr1+18,a->getPointer()); - f->setArray(a); - a->decrRef(); - f->setMesh(m2); - // - f->checkCoherency(); - double m=f->getMaxValue(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); - DataArrayInt *ws; - m=f->getMaxValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); - CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - const int expected1[4]={0,3,7,17}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - // - const double arr2[18]={-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71}; - std::copy(arr2,arr2+18,a->getPointer()); - f->checkCoherency(); - m=f->getMinValue(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); - m=f->getMinValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); - CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - // - f->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest3::testBuildUnstructuredCMesh1() -{ - MEDCouplingCMesh *m=MEDCouplingCMesh::New(); - DataArrayDouble *da=DataArrayDouble::New(); - const double discX[4]={2.3,3.4,5.8,10.2}; - const double discY[3]={12.3,23.4,45.8}; - const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; - da->alloc(4,1); - std::copy(discX,discX+4,da->getPointer()); - m->setCoordsAt(0,da); - da->decrRef(); - m->checkCoherency(); - double pos=2.4; - CPPUNIT_ASSERT_EQUAL(0,m->getCellContainingPoint(&pos,1e-12)); - pos=3.7; - CPPUNIT_ASSERT_EQUAL(1,m->getCellContainingPoint(&pos,1e-12)); - pos=5.9; - CPPUNIT_ASSERT_EQUAL(2,m->getCellContainingPoint(&pos,1e-12)); - pos=10.3; - CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); - pos=1.3; - CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); - // - MEDCouplingUMesh *m2=m->buildUnstructured(); - m2->checkCoherency(); - MEDCouplingFieldDouble *f1=m->getMeasureField(false); - MEDCouplingFieldDouble *f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),3); - CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),3); - CPPUNIT_ASSERT_EQUAL(1,m2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(1,m2->getSpaceDimension()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); - da=DataArrayDouble::New(); - da->alloc(3,1); - std::copy(discY,discY+3,da->getPointer()); - m->setCoordsAt(1,da); - da->decrRef(); - m2->decrRef(); - f1->decrRef(); - f2->decrRef(); - // - m2=m->buildUnstructured(); - m2->checkCoherency(); - f1=m->getMeasureField(false); - f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),6); - CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),6); - CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(2,m2->getSpaceDimension()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); - f1->decrRef(); - f2->decrRef(); - m2->decrRef(); - // - da=DataArrayDouble::New(); - da->alloc(5,1); - std::copy(discZ,discZ+5,da->getPointer()); - m->setCoordsAt(2,da); - da->decrRef(); - m2=m->buildUnstructured(); - m2->checkCoherency(); - f1=m->getMeasureField(false); - f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),24); - CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),24); - CPPUNIT_ASSERT_EQUAL(3,m2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); - f1->decrRef(); - f2->decrRef(); - // - double pos1[3]={5.,30.,2.}; - CPPUNIT_ASSERT_EQUAL(16,m->getCellContainingPoint(pos1,1e-12)); - // - const double pt[3]={2.4,12.7,-3.4}; - m->scale(pt,3.7); - MEDCouplingUMesh *m3=m->buildUnstructured(); - m2->scale(pt,3.7); - CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); - m2->decrRef(); - m3->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDataArrayIntInvertO2NNO21() -{ - const int arr1[6]={2,0,4,1,5,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(6,1); - std::copy(arr1,arr1+6,da->getPointer()); - DataArrayInt *da2=da->invertArrayO2N2N2O(6); - CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[6]={1,3,0,5,2,4}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - DataArrayInt *da3=da2->invertArrayN2O2O2N(6); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(arr1[i],da3->getIJ(i,0)); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); - // - const int arr2[10]={3,-1,5,4,-1,0,-1,1,2,-1}; - da=DataArrayInt::New(); - da->alloc(10,1); - std::copy(arr2,arr2+10,da->getPointer()); - da2=da->invertArrayO2N2N2O(6); - CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected2[10]={5,7,8,0,3,2}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da2->getIJ(i,0)); - da3=da2->invertArrayN2O2O2N(10); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(arr2[i],da3->getIJ(i,0)); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testKeepSetSelectedComponent1() -{ - const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(5,4); - std::copy(arr1,arr1+20,a1->getPointer()); - a1->setInfoOnComponent(0,"aaaa"); - a1->setInfoOnComponent(1,"bbbb"); - a1->setInfoOnComponent(2,"cccc"); - a1->setInfoOnComponent(3,"dddd"); - const int arr2[6]={1,2,1,2,0,0}; - std::vector arr2V(arr2,arr2+6); - DataArrayDouble *a2=static_cast(a1->keepSelectedComponents(arr2V)); - CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="cccc"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="bbbb"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); - const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a2->getIJ(0,i),1e-14); - DataArrayInt *a3=a1->convertToIntArr(); - DataArrayInt *a4=static_cast(a3->keepSelectedComponents(arr2V)); - CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="cccc"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="bbbb"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_EQUAL(int(expected1[i]),a4->getIJ(0,i)); - // setSelectedComponents - const int arr3[2]={3,2}; - std::vector arr3V(arr3,arr3+2); - DataArrayDouble *a5=static_cast(a1->keepSelectedComponents(arr3V)); - a5->setInfoOnComponent(0,"eeee"); - a5->setInfoOnComponent(1,"ffff"); - const int arr4[2]={1,2}; - std::vector arr4V(arr4,arr4+2); - a2->setSelectedComponents(a5,arr4V); - CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="eeee"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="ffff"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); - const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],a2->getIJ(0,i),1e-14); - DataArrayInt *a6=a5->convertToIntArr(); - a6->setInfoOnComponent(0,"eeee"); - a6->setInfoOnComponent(1,"ffff"); - a4->setSelectedComponents(a6,arr4V); - CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="eeee"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="ffff"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_EQUAL(int(expected2[i]),a4->getIJ(0,i)); - // test of throw - const int arr5[3]={2,3,6}; - const int arr6[3]={2,7,5}; - const int arr7[4]={2,1,4,6}; - std::vector arr5V(arr5,arr5+3); - std::vector arr6V(arr6,arr6+3); - std::vector arr7V(arr7,arr7+4); - CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr5V),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr6V),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); - arr7V.resize(3); - CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); - // - a6->decrRef(); - a5->decrRef(); - a4->decrRef(); - a3->decrRef(); - a2->decrRef(); - a1->decrRef(); -} - -void MEDCouplingBasicsTest3::testKeepSetSelectedComponent2() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(5,4); - std::copy(arr1,arr1+20,a1->getPointer()); - a1->setInfoOnComponent(0,"aaaa"); - a1->setInfoOnComponent(1,"bbbb"); - a1->setInfoOnComponent(2,"cccc"); - a1->setInfoOnComponent(3,"dddd"); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,4,5); - f1->setMesh(m1); - f1->setName("f1"); - f1->setArray(a1); - f1->checkCoherency(); - // - const int arr2[6]={1,2,1,2,0,0}; - std::vector arr2V(arr2,arr2+6); - MEDCouplingFieldDouble *f2=f1->keepSelectedComponents(arr2V); - CPPUNIT_ASSERT(f2->getMesh()==f1->getMesh()); - CPPUNIT_ASSERT(f2->getTimeDiscretization()==ONE_TIME); - int dt,it; - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); - CPPUNIT_ASSERT_EQUAL(4,dt); - CPPUNIT_ASSERT_EQUAL(5,it); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="cccc"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="bbbb"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); - const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f2->getIJ(0,i),1e-14); - //setSelectedComponents - const int arr3[2]={3,2}; - std::vector arr3V(arr3,arr3+2); - MEDCouplingFieldDouble *f5=f1->keepSelectedComponents(arr3V); - f5->setTime(6.7,8,9); - f5->getArray()->setInfoOnComponent(0,"eeee"); - f5->getArray()->setInfoOnComponent(1,"ffff"); - f5->checkCoherency(); - const int arr4[2]={1,2}; - std::vector arr4V(arr4,arr4+2); - f2->setSelectedComponents(f5,arr4V); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - f2->checkCoherency(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); - CPPUNIT_ASSERT_EQUAL(4,dt); - CPPUNIT_ASSERT_EQUAL(5,it); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="eeee"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="ffff"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); - const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-14); - f5->decrRef(); - f1->decrRef(); - f2->decrRef(); - a1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testElementaryDAThrowAndSpecialCases() -{ - DataArrayInt *da=DataArrayInt::New(); - CPPUNIT_ASSERT_THROW(da->checkAllocated(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->fillWithValue(1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->iota(1),INTERP_KERNEL::Exception); - da->alloc(7,1); - da->fillWithValue(11); //11,11,11,11... - da->iota(10); //10,11,12,13... - - DataArrayInt *db=DataArrayInt::New(); - db->alloc(7,2); - - DataArrayDouble *dbl2=DataArrayDouble::New(); - dbl2->alloc(7,2); - CPPUNIT_ASSERT_THROW(dbl2->isUniform(10.,1e-15),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl2->sort(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl2->iota(10.),INTERP_KERNEL::Exception); - - DataArrayDouble *dbl=DataArrayDouble::New(); - //DataArrayDouble not allocated yet - CPPUNIT_ASSERT_THROW(dbl->iota(10.),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->isUniform(10.,1e-15),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->sort(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->reverse(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->fromNoInterlace(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->toNoInterlace(),INTERP_KERNEL::Exception); - - dbl->alloc(7,1); - dbl->iota(10.); - CPPUNIT_ASSERT(!dbl->isUniform(10.,1e-15)); - dbl->sort(); - CPPUNIT_ASSERT(dbl->isMonotonic(true, .99)); - CPPUNIT_ASSERT(dbl->isMonotonic(true, -.99)); - CPPUNIT_ASSERT(!dbl->isMonotonic(true, 1.1)); - CPPUNIT_ASSERT(!dbl->isMonotonic(true, -1.1)); - dbl->reverse(); - CPPUNIT_ASSERT(dbl->isMonotonic(false, .99)); - CPPUNIT_ASSERT(!dbl->isMonotonic(false, 1.1)); - CPPUNIT_ASSERT(!dbl->isMonotonic(false, -1.1)); - - DataArrayInt *dc=DataArrayInt::New(); - dc->alloc(14,1); - - DataArrayDouble *dd=DataArrayDouble::New(); - CPPUNIT_ASSERT_THROW(dd->checkAllocated(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->fillWithValue(1.),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->iota(1.),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!((dd->repr().find("No data"))==std::string::npos)); - - dd->alloc(0,1); //Allocated but nbOfElements==0! - CPPUNIT_ASSERT(!((dd->repr().find("Number of tuples : 0"))==std::string::npos)); - CPPUNIT_ASSERT(!((dd->repr().find("Empty Data"))==std::string::npos)); - dd->fillWithValue(11); //?!... - dd->iota(10); //?!... - CPPUNIT_ASSERT(dd->isMonotonic(true, 1.)); - CPPUNIT_ASSERT(dd->isMonotonic(false, 1.)); - - CPPUNIT_ASSERT_THROW(db->copyStringInfoFrom(*da),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->copyStringInfoFrom(*da),INTERP_KERNEL::Exception); - std::vector cIds(2,2); - CPPUNIT_ASSERT_THROW(da->copyPartOfStringInfoFrom(*db,cIds),INTERP_KERNEL::Exception); - cIds[0]=1; - cIds[0]=-1; - CPPUNIT_ASSERT_THROW(da->copyPartOfStringInfoFrom(*db,cIds),INTERP_KERNEL::Exception); - - std::vector info(2,"infoOfOneComponent"); - CPPUNIT_ASSERT_THROW(da->setInfoOnComponents(info),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->setInfoOnComponent(1,info[0].c_str()),INTERP_KERNEL::Exception); - db->setInfoOnComponents(info); - - CPPUNIT_ASSERT_THROW(da->getInfoOnComponent(-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->getInfoOnComponent(2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(db->getInfoOnComponent(1)==db->getInfoOnComponent(0)); - CPPUNIT_ASSERT_THROW(db->getVarOnComponent(-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->getVarOnComponent(2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->getUnitOnComponent(-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->getUnitOnComponent(2),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname unit "))==std::string("varname unit ")); - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname]unit["))==std::string("varname]unit[")); - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("[unit]"))==std::string()); - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname [unit]"))==std::string("varname")); - - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname unit "))==std::string()); - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname]unit["))==std::string()); - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("[unit]"))==std::string("unit")); - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname [unit]"))==std::string("unit")); - - CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(*db,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(*dc,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->checkNbOfTuplesAndComp(*dc,"theMessageInThrow"),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(7,2,"theMessageInThrow"),INTERP_KERNEL::Exception); - da->checkNbOfTuplesAndComp(7,1,"theMessageInThrow"); - - CPPUNIT_ASSERT_THROW(db->checkNbOfElems(7*2+1,"theMessageInThrow"),INTERP_KERNEL::Exception); - db->checkNbOfElems(7*2,"theMessageInThrow"); - - CPPUNIT_ASSERT_THROW(db->GetNumberOfItemGivenBES(10,9,1,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->GetNumberOfItemGivenBES(0,1,-1,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_EQUAL(10,db->GetNumberOfItemGivenBES(0,10,1,"theMessageInThrow")); - CPPUNIT_ASSERT_EQUAL(5,db->GetNumberOfItemGivenBES(0,10,2,"theMessageInThrow")); - CPPUNIT_ASSERT_EQUAL(6,db->GetNumberOfItemGivenBES(0,11,2,"theMessageInThrow")); - - //std::cout<<"\n!!!!!!!!!\n"<repr()<<"\n!!!!!!!!!\n"; - CPPUNIT_ASSERT(!((da->repr().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dd->repr().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dbl->repr().find("Number of components : 1"))==std::string::npos)); - - CPPUNIT_ASSERT(!((da->reprZip().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dd->reprZip().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dbl->reprZip().find("Number of components : 1"))==std::string::npos)); - - std::ostringstream ret; - dbl->writeVTK(ret,2,"file.tmp",0); - CPPUNIT_ASSERT(!((ret.str().find("selectByTupleId2(0,1,-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->substr(-1,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->substr(8,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->substr(0,8),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->meldWith(dd),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(dbl->setPartOfValuesAdv(dbl2,da),INTERP_KERNEL::Exception); //dbl dbl2 not have the same number of components - CPPUNIT_ASSERT_THROW(dbl->setPartOfValuesAdv(dd,da),INTERP_KERNEL::Exception); //da tuple selector DataArrayInt instance not have exactly 2 components - - DataArrayDouble *dbl3=DataArrayDouble::New(); - dbl3->alloc(6,2); - dbl3->fillWithValue(11.); - int tupleId; - //bad number of components - CPPUNIT_ASSERT_THROW(dbl3->getMaxValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->getMaxValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->getMinValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->getMinValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->getAverageValue(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->getAverageValue(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->accumulate(100),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->fromPolarToCart(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->fromCylToCart(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->fromSpherToCart(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->doublyContractedProduct(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->determinant(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->eigenValues(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->eigenVectors(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->inverse(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->trace(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->deviator(),INTERP_KERNEL::Exception); - - dbl3->setIJ(5,1,12.); - CPPUNIT_ASSERT(dbl3->getMaxValueInArray()==12.); - CPPUNIT_ASSERT(dbl3->getMinValueInArray()==11.); - - db->fillWithValue(100); //bad Ids - CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); - db->fillWithValue(-1); //bad Ids - CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); - db->fillWithValue(6); //bad Ids for dbl3 - CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); - - DataArrayDouble::SetArrayIn(dbl,dbl3); //dbl->dbl3 memLeaks? - dbl3->checkNoNullValues(); - dbl3->setIJ(6,0,0.); - CPPUNIT_ASSERT_THROW(dbl3->checkNoNullValues(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->applyInv(1.),INTERP_KERNEL::Exception); //div by zero - CPPUNIT_ASSERT_THROW(dbl2->getIdsInRange(1.,2.),INTERP_KERNEL::Exception); - std::vector a(0); //input list must be NON EMPTY - CPPUNIT_ASSERT_THROW(DataArrayDouble::Aggregate(a),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayDouble::Meld(a),INTERP_KERNEL::Exception); - - a.push_back(dbl2); - a.push_back(dbl); //Nb of components mismatch - CPPUNIT_ASSERT_THROW(DataArrayDouble::Aggregate(a),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(DataArrayDouble::Dot(dbl2,dbl),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl2,dbl),INTERP_KERNEL::Exception); //Nb of components mismatch - CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl2,dbl2),INTERP_KERNEL::Exception); //Nb of components must be equal to 3 - DataArrayDouble *dbl4=DataArrayDouble::New(); - dbl4->alloc(6,3); - DataArrayDouble *dbl5=DataArrayDouble::New(); - dbl5->alloc(7,3); - CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl4,dbl5),INTERP_KERNEL::Exception); //Nb of tuples mismatch - - a[0]=dbl4; //Nb of tuple mismatch - a[1]=dbl5; //Nb of tuple mismatch - CPPUNIT_ASSERT_THROW(DataArrayDouble::Meld(a),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayDouble::Dot(dbl4,dbl5),INTERP_KERNEL::Exception); - - da->decrRef(); - db->decrRef(); - dbl->decrRef(); - dbl2->decrRef(); - dbl3->decrRef(); - dbl4->decrRef(); - dbl5->decrRef(); - dc->decrRef(); - dd->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIGetIdsEqual1() -{ - const int tab1[7]={5,-2,-4,-2,3,2,-2}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(7,1); - std::copy(tab1,tab1+7,da->getPointer()); - DataArrayInt *da2=da->getIdsEqual(-2); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[3]={1,3,6}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,da2->getConstPointer())); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIGetIdsEqualList1() -{ - const int tab1[7]={5,-2,-4,-2,3,2,-2}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(7,1); - std::copy(tab1,tab1+7,da->getPointer()); - const int tab2[3]={3,-2,0}; - std::vector tab2V(tab2,tab2+3); - DataArrayInt *da2=da->getIdsEqualList(&tab2V[0],&tab2V[0]+tab2V.size()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[4]={1,3,4,6}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+4,da2->getConstPointer())); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAFromNoInterlace1() -{ - const int tab1[15]={1,11,21,31,41,2,12,22,32,42,3,13,23,33,43}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(5,3); - std::copy(tab1,tab1+15,da->getPointer()); - DataArrayInt *da2=da->fromNoInterlace(); - const int expected1[15]={1,2,3,11,12,13,21,22,23,31,32,33,41,42,43}; - CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - CPPUNIT_ASSERT(std::equal(expected1,expected1+15,da2->getConstPointer())); - DataArrayDouble *da3=da->convertToDblArr(); - DataArrayDouble *da4=da3->fromNoInterlace(); - CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da4->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)expected1[i],da4->getIJ(0,i),1e-14); - da4->decrRef(); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAToNoInterlace1() -{ - const int tab1[15]={1,2,3,11,12,13,21,22,23,31,32,33,41,42,43}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(5,3); - std::copy(tab1,tab1+15,da->getPointer()); - DataArrayInt *da2=da->toNoInterlace(); - const int expected1[15]={1,11,21,31,41,2,12,22,32,42,3,13,23,33,43}; - CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - CPPUNIT_ASSERT(std::equal(expected1,expected1+15,da2->getConstPointer())); - DataArrayDouble *da3=da->convertToDblArr(); - DataArrayDouble *da4=da3->toNoInterlace(); - CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da4->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)expected1[i],da4->getIJ(0,i),1e-14); - da4->decrRef(); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIsUniform1() -{ - const int tab1[5]={1,1,1,1,1}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(5,1); - std::copy(tab1,tab1+5,da->getPointer()); - CPPUNIT_ASSERT(da->isUniform(1)); - da->setIJ(2,0,2); - CPPUNIT_ASSERT(!da->isUniform(1)); - da->setIJ(2,0,1); - CPPUNIT_ASSERT(da->isUniform(1)); - DataArrayDouble *da2=da->convertToDblArr(); - CPPUNIT_ASSERT(da2->isUniform(1.,1e-12)); - da2->setIJ(1,0,1.+1.e-13); - CPPUNIT_ASSERT(da2->isUniform(1.,1e-12)); - da2->setIJ(1,0,1.+1.e-11); - CPPUNIT_ASSERT(!da2->isUniform(1.,1e-12)); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDADFromPolarToCart1() -{ - const double tab1[4]={2.,0.2,2.5,0.7}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(2,2); - std::copy(tab1,tab1+4,da->getPointer()); - DataArrayDouble *da2=da->fromPolarToCart(); - const double expected1[4]={1.9601331556824833,0.39733866159012243, 1.9121054682112213,1.6105442180942275}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDADFromCylToCart1() -{ - const double tab1[6]={2.,0.2,4.,2.5,0.7,9.}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(2,3); - std::copy(tab1,tab1+6,da->getPointer()); - DataArrayDouble *da2=da->fromCylToCart(); - const double expected1[6]={1.9601331556824833,0.39733866159012243,4., 1.9121054682112213,1.6105442180942275,9.}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDADFromSpherToCart1() -{ - const double tab1[6]={2.,0.2,0.3,2.5,0.7,0.8}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(2,3); - std::copy(tab1,tab1+6,da->getPointer()); - DataArrayDouble *da2=da->fromSpherToCart(); - const double expected1[6]={0.37959212195737485,0.11742160338765303,1.9601331556824833, 1.1220769624465328,1.1553337045129035,1.9121054682112213}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testUnPolyze1() -{ - const int elts[8]={0,1,2,3,4,5,6,7}; - std::vector eltsV(elts,elts+8); - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->unPolyze(); - MEDCouplingUMesh *mesh2=build3DTargetMesh_1(); - mesh->checkCoherency(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); - mesh->getNodalConnectivity()->setIJ(0,6,10); - mesh->getNodalConnectivity()->setIJ(0,7,9); - mesh->getNodalConnectivity()->setIJ(0,8,12); - mesh->getNodalConnectivity()->setIJ(0,9,13); - mesh->unPolyze(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->getNodalConnectivity()->setIJ(0,6,12); - mesh->getNodalConnectivity()->setIJ(0,7,13); - mesh->getNodalConnectivity()->setIJ(0,8,10); - mesh->getNodalConnectivity()->setIJ(0,9,9); - mesh->unPolyze(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->getNodalConnectivity()->setIJ(0,6,12); - mesh->getNodalConnectivity()->setIJ(0,7,10); - mesh->getNodalConnectivity()->setIJ(0,8,13); - mesh->getNodalConnectivity()->setIJ(0,9,9); - mesh->unPolyze(); - CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); - mesh->decrRef(); - mesh2->decrRef(); - // Test for 2D mesh - mesh=build2DTargetMesh_1(); - mesh2=build2DTargetMesh_1(); - eltsV.resize(5); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); - mesh->unPolyze(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest3::testConvertDegeneratedCells1() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - int conn[32]={0,1,3,3,9,10,12,12, 0,1,3,4,9,9,9,9, 1,1,1,1,10,12,9,10, 10,11,12,9,1,1,1,1}; - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+16); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+24); - mesh->finishInsertingCells(); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(3)); - MEDCouplingFieldDouble *f1=mesh->getMeasureField(true); - mesh->convertDegeneratedCells(); - mesh->checkCoherency(); - MEDCouplingFieldDouble *f2=mesh->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(4,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PYRA5,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TETRA4,mesh->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PYRA5,mesh->getTypeOfCell(3)); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getArray()->getIJ(0,i),f2->getArray()->getIJ(0,i),1e-5); - f1->decrRef(); - f2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest3::testGetNodeIdsNearPoints1() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayDouble *coords=mesh->getCoords(); - DataArrayDouble *tmp=DataArrayDouble::New(); - tmp->alloc(3,2); - const double vals[6]={0.2,0.2,0.1,0.2,0.2,0.2}; - std::copy(vals,vals+6,tmp->getPointer()); - DataArrayDouble *tmp2=DataArrayDouble::Aggregate(coords,tmp); - tmp->decrRef(); - mesh->setCoords(tmp2); - tmp2->decrRef(); - const double pts[6]={0.2,0.2,0.1,0.3,-0.3,0.7}; - DataArrayInt *c=mesh->getNodeIdsNearPoint(pts,1e-7); - CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); - c->decrRef(); - DataArrayInt *cI=0; - mesh->getNodeIdsNearPoints(pts,3,1e-7,c,cI); - CPPUNIT_ASSERT_EQUAL(4,cI->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); - CPPUNIT_ASSERT_EQUAL(6,c->getIJ(3,0)); - CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(2,0)); - CPPUNIT_ASSERT_EQUAL(4,cI->getIJ(3,0)); - c->decrRef(); - cI->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldCopyTinyAttrFrom1() -{ - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f1->setTime(1.23,4,5); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTime(6.78,9,10); - f2->setTimeTolerance(4.556e-12); - // - int dt,it; - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(9,dt); - CPPUNIT_ASSERT_EQUAL(10,it); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - f1->decrRef(); - f2->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTimeTolerance(4.556e-12); - // - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - f1->decrRef(); - f2->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f1->setTime(1.23,4,5); - f1->setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTimeTolerance(4.556e-12); - f2->setTime(6.78,9,10); - f2->setEndTime(10.98,7,6); - // - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(9,dt); - CPPUNIT_ASSERT_EQUAL(10,it); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.98,f1->getEndTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(7,dt); - CPPUNIT_ASSERT_EQUAL(6,it); - f1->decrRef(); - f2->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f1->setTime(1.23,4,5); - f1->setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTimeTolerance(4.556e-12); - f2->setTime(6.78,9,10); - f2->setEndTime(10.98,7,6); - // - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(9,dt); - CPPUNIT_ASSERT_EQUAL(10,it); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.98,f1->getEndTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(7,dt); - CPPUNIT_ASSERT_EQUAL(6,it); - f1->decrRef(); - f2->decrRef(); -} - -/*! - * 1D -> 2D extrusion with rotation - */ -void MEDCouplingBasicsTest3::testExtrudedMesh5() -{ - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - MEDCouplingUMesh *c=b->buildUnstructured(); - CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); - c->changeSpaceDimension(2); - // - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(13,1); - d->iota(); - MEDCouplingCMesh *ee=MEDCouplingCMesh::New(); - ee->setCoordsAt(0,d); - MEDCouplingUMesh *f=ee->buildUnstructured(); - DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - CPPUNIT_ASSERT_THROW(f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*KVec"),INTERP_KERNEL::Exception); // KVec refers to component #2 and there is only 2 components ! - DataArrayDouble *h=g->fromPolarToCart(); - f->setCoords(h); - MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); - CPPUNIT_ASSERT_EQUAL(52,i->getNumberOfNodes()); - bool tmp2; - int tmp3; - DataArrayInt *tmp=i->mergeNodes(1e-9,tmp2,tmp3); - CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_EQUAL(37,tmp3); - tmp->decrRef(); - i->convertDegeneratedCells(); - i->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(36,i->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(37,i->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(12,i->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3)); - CPPUNIT_ASSERT_EQUAL(24,i->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4)); - const double expected1[3]={0.25,0.75,2.0625}; - MEDCouplingFieldDouble *j=i->getMeasureField(true); - for(int ii=0;ii<12;ii++) - for(int k=0;k<3;k++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[k],j->getIJ(0,ii*3+k),1e-10); - const double expected2[72]={0.62200846792814113, 0.16666666666681595, 1.4513530918323276, 0.38888888888923495, 2.6293994326053212, 0.7045454545460802, 0.45534180126145435, 0.45534180126150181, 1.0624642029433926, 1.0624642029435025, 1.9248539780597826, 1.9248539780599816, 0.16666666666661334, 0.62200846792815856, 0.38888888888876294, 1.4513530918323678, 0.70454545454522521, 2.629399432605394, -0.16666666666674007, 0.62200846792812436, -0.38888888888906142, 1.4513530918322881, -0.70454545454576778, 2.6293994326052488, -0.45534180126154766, 0.45534180126140844, -1.0624642029436118, 1.0624642029432834, -1.9248539780601803, 1.9248539780595841, -0.62200846792817499, 0.1666666666665495, -1.451353091832408, 0.388888888888613, -2.6293994326054668, 0.70454545454495332, -0.62200846792810593, -0.16666666666680507, -1.451353091832247, -0.38888888888921297, -2.6293994326051746, -0.70454545454604123, -0.45534180126135926, -0.45534180126159562, -1.0624642029431723, -1.0624642029437235, -1.9248539780593836, -1.9248539780603811, -0.1666666666664828, -0.62200846792819242, -0.38888888888846079, -1.4513530918324489, -0.70454545454467987, -2.6293994326055397, 0.16666666666687083, -0.62200846792808862, 0.38888888888936374, -1.4513530918322073, 0.70454545454631357, -2.6293994326051022, 0.45534180126164348, -0.45534180126131207, 1.0624642029438327, -1.0624642029430627, 1.9248539780605791, -1.9248539780591853, 0.62200846792821063, -0.16666666666641802, 1.4513530918324888, -0.38888888888831086, 2.6293994326056125, -0.70454545454440853}; - DataArrayDouble *m=i->getBarycenterAndOwner(); - for(int ii=0;ii<72;ii++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[ii],m->getIJ(0,ii),1e-10); - // - m->decrRef(); - j->decrRef(); - i->decrRef(); - h->decrRef(); - g->decrRef(); - f->decrRef(); - ee->decrRef(); - d->decrRef(); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -/*! - * 1D -> 2D extrusion without rotation - */ -void MEDCouplingBasicsTest3::testExtrudedMesh6() -{ - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - MEDCouplingUMesh *c=b->buildUnstructured(); - CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); - c->changeSpaceDimension(2); - // - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(5,1); - d->iota(); - MEDCouplingCMesh *e=MEDCouplingCMesh::New(); - e->setCoordsAt(0,d); - MEDCouplingUMesh *f=e->buildUnstructured(); - DataArrayDouble *d2=f->getCoords()->applyFunc("x*x/2"); - f->setCoords(d2); - f->changeSpaceDimension(2); - // - const double center[2]={0.,0.}; - f->rotate(center,0,M_PI/3); - MEDCouplingUMesh *g=c->buildExtrudedMesh(f,0); - g->checkCoherency(); - const double expected1[]={ 0.4330127018922193, 0.4330127018922193, 0.649519052838329, 1.2990381056766578, 1.299038105676658, 1.948557158514987, 2.1650635094610955, 2.1650635094610964, 3.2475952641916446, 3.031088913245533, 3.0310889132455352, 4.546633369868303 }; - MEDCouplingFieldDouble *f1=g->getMeasureField(true); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-12); - - const double expected2[]={0.625, 0.21650635094610962, 1.625, 0.21650635094610959, 2.8750000000000004, 0.21650635094610965, 1.1250000000000002, 1.0825317547305482, 2.125, 1.0825317547305482, 3.3750000000000004, 1.0825317547305484, 2.125, 2.8145825622994254, 3.125, 2.8145825622994254, 4.375, 2.8145825622994254, 3.6250000000000009, 5.4126587736527414, 4.625, 5.4126587736527414, 5.875, 5.4126587736527414}; - DataArrayDouble *f2=g->getBarycenterAndOwner(); - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-12); - // - f1->decrRef(); - f2->decrRef(); - g->decrRef(); - f->decrRef(); - e->decrRef(); - d->decrRef(); - d2->decrRef(); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -/*! - * 2D -> 3D extrusion with rotation - */ -void MEDCouplingBasicsTest3::testExtrudedMesh7() -{ - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - MEDCouplingUMesh *c=b->buildUnstructured(); - CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); - c->changeSpaceDimension(2); - // - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(13,1); - d->iota(); - MEDCouplingCMesh *e=MEDCouplingCMesh::New(); - e->setCoordsAt(0,d); - MEDCouplingUMesh *f=e->buildUnstructured(); - DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - DataArrayDouble *h=g->fromPolarToCart(); - f->setCoords(h); - MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); - CPPUNIT_ASSERT_EQUAL(52,i->getNumberOfNodes()); - bool tmp2; - int tmp3; - DataArrayInt *tmp=i->mergeNodes(1e-9,tmp2,tmp3); - CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_EQUAL(37,tmp3); - tmp->decrRef(); - i->convertDegeneratedCells(); - const double vec1[3]={10.,0.,0.}; - i->translate(vec1); - DataArrayDouble *g2=h->applyFunc(3,"13.5/3.5*x*IVec+0*JVec+13.5/3.5*y*KVec"); - f->setCoords(g2); - i->changeSpaceDimension(3); - MEDCouplingUMesh *i3=i->buildExtrudedMesh(f,1); - MEDCouplingFieldDouble *f2=i3->getMeasureField(true); - tmp=i->mergeNodes(1e-9,tmp2,tmp3); - CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_EQUAL(444,tmp3); - tmp->decrRef(); - const double expected1[36]={1.327751058489274, 4.2942574094314701, 13.024068164857139, 1.3069177251569044, 4.1484240761012954, 12.297505664866796, 1.270833333332571, 3.8958333333309674, 11.039062499993179, 1.2291666666659207, 3.6041666666644425, 9.585937499993932, 1.1930822748415895, 3.3515759238941376, 8.3274943351204556, 1.1722489415082769, 3.2057425905609289, 7.6009318351210622, 1.1722489415082862, 3.2057425905609884, 7.6009318351213713, 1.1930822748416161, 3.3515759238943001, 8.3274943351212727, 1.2291666666659564, 3.6041666666646734, 9.5859374999950777, 1.2708333333326081, 3.8958333333311868, 11.039062499994293, 1.3069177251569224, 4.1484240761014384, 12.297505664867627, 1.3277510584902354, 4.2942574094346071, 13.024068164866796}; - int kk=0; - for(int ii=0;ii<12;ii++) - for(int jj=0;jj<36;jj++,kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[jj],f2->getIJ(0,kk),1e-9); - // - f2->decrRef(); - i3->decrRef(); - g2->decrRef(); - i->decrRef(); - h->decrRef(); - g->decrRef(); - f->decrRef(); - e->decrRef(); - d->decrRef(); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testSimplexize1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - std::vector v(1); - v[0]=3; - m->convertToPolyTypes(&v[0],&v[0]+v.size()); - DataArrayInt *da=m->simplexize(0); - CPPUNIT_ASSERT_EQUAL(7,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - const int expected2[7]={0,0,1,2,3,4,4}; - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da->getIJ(i,0)); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(7,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,m->getTypeOfCell(4)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(5)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(6)); - const double expected1[7]={0.125,0.125,0.125,0.125,0.25,0.125,0.125}; - MEDCouplingFieldDouble *f=m->getMeasureField(false); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i]*sqrt(2.),f->getIJ(i,0),1e-10); - std::set types=m->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(2,(int)types.size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*(types.begin())); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,*(++(types.begin()))); - f->decrRef(); - da->decrRef(); - m->decrRef(); - // - m=build3DSurfTargetMesh_1(); - v[0]=3; - m->convertToPolyTypes(&v[0],&v[0]+v.size()); - da=m->simplexize(1); - CPPUNIT_ASSERT_EQUAL(7,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da->getIJ(i,0)); - m->checkCoherency(); - types=m->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(2,(int)types.size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*(types.begin())); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,*(++(types.begin()))); - CPPUNIT_ASSERT_EQUAL(7,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,m->getTypeOfCell(4)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(5)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(6)); - f=m->getMeasureField(false); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i]*sqrt(2.),f->getIJ(i,0),1e-10); - f->decrRef(); - da->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testSimplexize2() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - std::vector v(1); - v[0]=3; - m->convertToPolyTypes(&v[0],&v[0]+v.size()); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - const double arr1[10]={10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; - arr->alloc(5,2); - std::copy(arr1,arr1+10,arr->getPointer()); - f1->setArray(arr); - arr->decrRef(); - // - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->simplexize(0)); - f1->checkCoherency(); - const double expected1[14]={10.,110.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.,50.,150.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-10); - CPPUNIT_ASSERT(!f1->simplexize(0)); - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-10); - // - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAMeld1() -{ - DataArrayDouble *da1=DataArrayDouble::New(); - da1->alloc(7,2); - DataArrayDouble *da2=DataArrayDouble::New(); - da2->alloc(7,1); - // - da1->fillWithValue(7.); - da2->iota(0.); - DataArrayDouble *da3=da2->applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); - // - da1->setInfoOnComponent(0,"c0da1"); - da1->setInfoOnComponent(1,"c1da1"); - da3->setInfoOnComponent(0,"c0da3"); - da3->setInfoOnComponent(1,"c1da3"); - da3->setInfoOnComponent(2,"c2da3"); - // - DataArrayDouble *da1C=da1->deepCpy(); - da1->meldWith(da3); - CPPUNIT_ASSERT_EQUAL(5,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,da1->getNumberOfTuples()); - CPPUNIT_ASSERT(da1->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(4)=="c2da3"); - // - const double expected1[35]={7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.}; - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-10); - // - DataArrayInt *dai1=da1C->convertToIntArr(); - DataArrayInt *dai3=da3->convertToIntArr(); - dai1->meldWith(dai3); - CPPUNIT_ASSERT_EQUAL(5,dai1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,dai1->getNumberOfTuples()); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(4)=="c2da3"); - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai1->getIJ(0,i)); - // test of static method DataArrayDouble::meld - DataArrayDouble *da4=DataArrayDouble::Meld(da1C,da3); - CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,da4->getNumberOfTuples()); - CPPUNIT_ASSERT(da4->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(4)=="c2da3"); - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da4->getIJ(0,i),1e-10); - // test of static method DataArrayInt::meld - dai1->decrRef(); - dai1=da1C->convertToIntArr(); - DataArrayInt *dai4=DataArrayInt::Meld(dai1,dai3); - CPPUNIT_ASSERT_EQUAL(5,dai4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,dai4->getNumberOfTuples()); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(4)=="c2da3"); - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai4->getIJ(0,i)); - // - dai4->decrRef(); - da4->decrRef(); - dai3->decrRef(); - dai1->decrRef(); - da1C->decrRef(); - da1->decrRef(); - da2->decrRef(); - da3->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldMeld1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m); - DataArrayDouble *da1=DataArrayDouble::New(); - const double arr1[5]={12.,23.,34.,45.,56.}; - da1->alloc(5,1); - std::copy(arr1,arr1+5,da1->getPointer()); - da1->setInfoOnComponent(0,"aaa"); - f1->setArray(da1); - f1->setTime(3.4,2,1); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->deepCpy(); - f2->setMesh(f1->getMesh()); - f2->checkCoherency(); - f2->changeNbOfComponents(2,5.); - (*f2)=5.; - f2->getArray()->setInfoOnComponent(0,"bbb"); - f2->getArray()->setInfoOnComponent(1,"ccc"); - f2->checkCoherency(); - // - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::MeldFields(f2,f1); - f3->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f3->getNumberOfComponents()); - CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(0)=="bbb"); - CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(1)=="ccc"); - CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(2)=="aaa"); - const double expected1[15]={5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-12); - int dt,it; - double time=f3->getTime(dt,it); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,time,1e-14); - CPPUNIT_ASSERT_EQUAL(2,dt); - CPPUNIT_ASSERT_EQUAL(1,it); - // - MEDCouplingFieldDouble *f4=f2->buildNewTimeReprFromThis(NO_TIME,false); - MEDCouplingFieldDouble *f5=f1->buildNewTimeReprFromThis(NO_TIME,false); - MEDCouplingFieldDouble *f6=MEDCouplingFieldDouble::MeldFields(f4,f5); - f6->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f6->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f6->getNumberOfComponents()); - CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(0)=="bbb"); - CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(1)=="ccc"); - CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(2)=="aaa"); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f6->getIJ(0,i),1e-12); - // - f6->decrRef(); - f4->decrRef(); - f5->decrRef(); - f3->decrRef(); - da1->decrRef(); - f2->decrRef(); - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testMergeNodes2() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - const double vec[2]={0.002,0.}; - m2->translate(vec); - // - std::vector tmp(2); - tmp[0]=m1; - tmp[1]=m2; - MEDCouplingUMesh *m3=MEDCouplingUMesh::MergeUMeshes(tmp); - bool b; - int newNbOfNodes; - DataArrayInt *da=m3->mergeNodes2(0.01,b,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfNodes()); - const double expected1[18]={-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7}; - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],m3->getCoords()->getIJ(0,i),1e-13); - // - da->decrRef(); - m3->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest3::testMergeField2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->fillWithValue(2.); - f1->setArray(arr); - arr->decrRef(); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setMesh(m); - arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->fillWithValue(5.); - f2->setArray(arr); - arr->decrRef(); - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f3->setMesh(m); - arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->fillWithValue(7.); - f3->setArray(arr); - arr->decrRef(); - // - std::vector tmp(3); - tmp[0]=f1; tmp[1]=f2; tmp[2]=f3; - MEDCouplingFieldDouble *f4=MEDCouplingFieldDouble::MergeFields(tmp); - CPPUNIT_ASSERT_EQUAL(15,f4->getMesh()->getNumberOfCells()); - const double expected1[30]={2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f4->getIJ(0,i),1.e-13); - // - f4->decrRef(); - f1->decrRef(); - f2->decrRef(); - f3->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildComplement1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab[4]={3,1,7,8}; - a->alloc(4,1); - std::copy(tab,tab+4,a->getPointer()); - DataArrayInt *b=a->buildComplement(12); - CPPUNIT_ASSERT_EQUAL(8,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[8]={0,2,4,5,6,9,10,11}; - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildUnion1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab1[4]={3,1,7,8}; - a->alloc(4,1); - std::copy(tab1,tab1+4,a->getPointer()); - DataArrayInt *c=DataArrayInt::New(); - const int tab2[5]={5,3,0,18,8}; - c->alloc(5,1); - std::copy(tab2,tab2+5,c->getPointer()); - DataArrayInt *b=a->buildUnion(c); - CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[7]={0,1,3,5,7,8,18}; - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildIntersection1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab1[4]={3,1,7,8}; - a->alloc(4,1); - std::copy(tab1,tab1+4,a->getPointer()); - DataArrayInt *c=DataArrayInt::New(); - const int tab2[5]={5,3,0,18,8}; - c->alloc(5,1); - std::copy(tab2,tab2+5,c->getPointer()); - DataArrayInt *b=a->buildIntersection(c); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[2]={3,8}; - for(int i=0;i<2;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIDeltaShiftIndex1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab[7]={1,3,6,7,7,9,15}; - a->alloc(7,1); - std::copy(tab,tab+7,a->getPointer()); - DataArrayInt *b=a->deltaShiftIndex(); - CPPUNIT_ASSERT_EQUAL(6,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[6]={2,3,1,0,2,6}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleSelectByTupleIdSafe1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={4,2,0,6,5}; - DataArrayDouble *b=a->selectByTupleIdSafe(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - const int arr4[5]={4,-1,0,6,5}; - CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); - const int arr5[5]={4,2,0,6,7}; - CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->selectByTupleIdSafe(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testAreCellsIncludedIn1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - const int pt[2]={1,3}; - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->buildPartOfMySelf(pt,pt+2,true); - DataArrayInt *tmp; - CPPUNIT_ASSERT(m->areCellsIncludedIn(m2,0,tmp)); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,tmp->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(pt[0],tmp->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(pt[1],tmp->getIJ(0,1)); - tmp->decrRef(); - CPPUNIT_ASSERT(!m2->areCellsIncludedIn(m,0,tmp)); - tmp->decrRef(); - m2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildSubstraction1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int aa[]={2,3,6,8,9}; - a->alloc(5,1); - std::copy(aa,aa+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - const int bb[]={1,3,5,9,11}; - b->alloc(5,1); - std::copy(bb,bb+5,b->getPointer()); - // - DataArrayInt *c=a->buildSubstraction(b); - CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); - const int expected1[3]={2,6,8}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - // - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testBuildOrthogonalField2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - DataArrayInt *d4=DataArrayInt::New(); - MEDCouplingUMesh *m1=m->buildDescendingConnectivity(d1,d2,d3,d4); - // - MEDCouplingFieldDouble *f1=m1->buildOrthogonalField(); - DataArrayDouble *da1=f1->getArray(); - CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(13,da1->getNumberOfTuples()); - // - const double expected1[26]={-1.,0.,0.,1.,1.,0.,0.,-1.,0.707106781186548,0.707106781186548,0.,-1.,0.,1.,1.,0.,0.,1.,1.,0.,-1.,0.,0.,1.,1.,0.}; - for(int i=0;i<26;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-14); - // - f1->decrRef(); - m1->decrRef(); - d1->decrRef(); - d2->decrRef(); - d3->decrRef(); - d4->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMInsertNextCell1() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->allocateCells(5); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn),INTERP_KERNEL::Exception); - targetMesh->setMeshDimension(2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn),INTERP_KERNEL::Exception); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - targetMesh->checkCoherency(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldOperatorDivDiffComp1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - DataArrayInt *d4=DataArrayInt::New(); - MEDCouplingUMesh *m1=m->buildDescendingConnectivity(d1,d2,d3,d4); - // - MEDCouplingFieldDouble *f1=m1->buildOrthogonalField(); - const double arr1[13]={2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.}; - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(13,1); - std::copy(arr1,arr1+13,arr->getPointer()); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS); - f2->setArray(arr); - f2->setMesh(m1); - f2->checkCoherency(); - // - MEDCouplingFieldDouble *f3=(*f1)/(*f2); - CPPUNIT_ASSERT_THROW((*f2)/(*f1),INTERP_KERNEL::Exception); - f3->checkCoherency(); - (*f1)/=(*f2); - CPPUNIT_ASSERT(f1->isEqual(f3,1e-10,1e-10)); - CPPUNIT_ASSERT_THROW((*f2)/=(*f1),INTERP_KERNEL::Exception); - const double expected1[26]={-0.5, 0.0, 0.0, 0.33333333333333331, 0.25, 0.0, 0.0, -0.20000000000000001, 0.117851130197758, 0.117851130197758, 0.0, -0.14285714285714285, 0.0, 0.125, 0.1111111111111111, 0.0, 0.0, 0.10000000000000001, 0.090909090909090912, 0.0, -0.083333333333333329, 0.0, 0.0, 0.076923076923076927, 0.071428571428571425, 0.0}; - for(int i=0;i<26;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-10); - // - f3->decrRef(); - f2->decrRef(); - arr->decrRef(); - f1->decrRef(); - m1->decrRef(); - d1->decrRef(); - d2->decrRef(); - d3->decrRef(); - d4->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDARearrange1() -{ - DataArrayInt *da1=DataArrayInt::New(); - da1->alloc(12,1); - da1->iota(0); - const int *ptr=da1->getConstPointer(); - // - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,da1->getNumberOfTuples()); - da1->rearrange(4); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - // - da1->rearrange(6); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(6,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - // - CPPUNIT_ASSERT_THROW(da1->rearrange(7),INTERP_KERNEL::Exception); - // - da1->rearrange(12); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(12,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - // - da1->rearrange(3); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - //double - DataArrayDouble *da2=da1->convertToDblArr(); - da1->decrRef(); - const double *ptr2=da2->getConstPointer(); - // - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - da2->rearrange(4); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - // - da2->rearrange(6); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - // - CPPUNIT_ASSERT_THROW(da2->rearrange(7),INTERP_KERNEL::Exception); - // - da2->rearrange(1); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - // - da2->rearrange(3); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - da2->decrRef(); -} - -void MEDCouplingBasicsTest3::testGetDifferentValues1() -{ - DataArrayInt *da1=DataArrayInt::New(); - const int arr[12]={1,2,3,2,2,3,5,1,5,5,2,2}; - da1->alloc(4,3); - std::copy(arr,arr+12,da1->getPointer()); - DataArrayInt *s=da1->getDifferentValues(); - const int expected1[4]={1,2,3,5}; - CPPUNIT_ASSERT_EQUAL(4,s->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+4,s->begin())); - da1->decrRef(); - s->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildPermutationArr1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int vala[5]={4,5,6,7,8}; - a->alloc(5,1); - std::copy(vala,vala+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - const int valb[5]={5,4,8,6,7}; - b->alloc(5,1); - std::copy(valb,valb+5,b->getPointer()); - DataArrayInt *c=a->buildPermutationArr(*b); - const int expect1[5]={1,0,4,2,3}; - CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); - CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); - b->setIJ(0,0,9); - CPPUNIT_ASSERT(!a->isEqualWithoutConsideringStrAndOrder(*b)); - CPPUNIT_ASSERT_THROW(a->buildPermutationArr(*b),INTERP_KERNEL::Exception); - a->setIJ(3,0,4); - b->setIJ(0,0,5); - b->setIJ(4,0,4);//;a==[4,5,6,4,8] and b==[5,4,8,6,4] - CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); - c->decrRef(); - c=a->buildPermutationArr(*b); - const int expect2[5]={1,3,4,2,3}; - CPPUNIT_ASSERT(std::equal(expect2,expect2+5,c->getConstPointer())); - DataArrayDouble *d=b->convertToDblArr(); - b->sort(); - const int expect3[5]={4,4,5,6,8}; - CPPUNIT_ASSERT(std::equal(expect3,expect3+5,b->getConstPointer())); - d->sort(); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(double(expect3[i]),d->getIJ(i,0),1e-14); - // - d->decrRef(); - c->decrRef(); - a->decrRef(); - b->decrRef(); -} - -void MEDCouplingBasicsTest3::testAreCellsIncludedIn2() -{ - const char myName[]="Vitoo"; - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->buildPartOfMySelf(0,0,true); - CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); - m2->setName(myName); - DataArrayInt *tmp; - CPPUNIT_ASSERT(m->areCellsIncludedIn(m2,0,tmp)); - CPPUNIT_ASSERT(std::string(myName)==tmp->getName()); - CPPUNIT_ASSERT_EQUAL(0,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,tmp->getNumberOfComponents()); - m->decrRef(); - m2->decrRef(); - tmp->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshGetPartBarycenterAndOwner1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part[3]={1,0,4}; - DataArrayDouble *b=m1->getPartBarycenterAndOwner(part,part+3); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,b->getNumberOfTuples()); - const double expected1[6]={0.36666666666666665,-0.13333333333333333,-0.05,-0.05,0.45,0.45}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshGetPartMeasureField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part[3]={1,0,4}; - DataArrayDouble *b=m1->getPartMeasureField(true,part,part+3); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,b->getNumberOfTuples()); - const double expected1[3]={0.125,0.25,0.25}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshBuildPartOrthogonalField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->changeSpaceDimension(3); - const int part[3]={1,0,4}; - MEDCouplingFieldDouble *b=m1->buildPartOrthogonalField(part,part+3); - CPPUNIT_ASSERT_EQUAL(3,b->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,b->getArray()->getNumberOfTuples()); - const double expected1[9]={0.,0.,-1.,0.,0.,-1.,0.,0.,-1.}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getArray()->getIJ(0,i),1e-14); - b->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshGetTypesOfPart1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part1[]={0,3,4}; - std::set s; - s=m1->getTypesOfPart(part1,part1+3); - CPPUNIT_ASSERT(s.size()==1); - CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_QUAD4); - const int part2[]={2,2,2,1}; - s=m1->getTypesOfPart(part2,part2+4); - CPPUNIT_ASSERT(s.size()==1); - CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_TRI3); - const int part3[]={3,2,1}; - s=m1->getTypesOfPart(part3,part3+3); - CPPUNIT_ASSERT(s.size()==2); - CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_TRI3); - CPPUNIT_ASSERT(*(++s.begin())==INTERP_KERNEL::NORM_QUAD4); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshKeepCellIdsByType1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part1[3]={0,3,4}; - DataArrayInt *a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_TRI3,part1,part1+3); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); - a->decrRef(); - // - const int part2[5]={3,2,0,2,4}; - a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_TRI3,part2,part2+5); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,a->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,a->getIJ(1,0)); - a->decrRef(); - // - a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_QUAD4,part2,part2+5); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,a->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(0,a->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(4,a->getIJ(2,0)); - // - a->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIAggregateMulti1() -{ - DataArrayInt *a=DataArrayInt::New(); - a->setName("aa"); - a->alloc(4,1); - a->iota(0); - a->rearrange(2); - DataArrayInt *b=DataArrayInt::New(); - b->setName("bb"); - b->alloc(6,1); - b->iota(0); - b->rearrange(2); - // - std::vector v(2); - v[0]=a; v[1]=b; - DataArrayInt *c=DataArrayInt::Aggregate(v); - CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); - CPPUNIT_ASSERT(c->getName()=="aa"); - const int expect1[10]={0,1,2,3,0,1,2,3,4,5}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expect1[i],c->getIJ(0,i)); - // - c->decrRef(); - a->decrRef(); - b->decrRef(); -} - -void MEDCouplingBasicsTest3::testMergeUMeshes2() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m3=build3DSurfTargetMesh_1(); - // - const int vec1[3]={0,2,3}; - MEDCouplingUMesh *m2_2=(MEDCouplingUMesh *)m2->buildPartOfMySelf(vec1,vec1+3,false); - const int vec2[2]={1,1}; - MEDCouplingUMesh *m3_2=(MEDCouplingUMesh *)m3->buildPartOfMySelf(vec2,vec2+2,false); - // - std::vector ms(3); - std::vector ms2(3); - ms[0]=m1; ms[1]=m2_2; ms[2]=m3_2; - ms2[0]=m1; ms2[1]=m2_2; ms2[2]=m3_2; - // - MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshes(ms); - m4->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(10,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,m4->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(45,m4->getMeshLength()); - // - MEDCouplingMesh *m4bis=MEDCouplingMesh::MergeMeshes(ms2); - CPPUNIT_ASSERT(m4->isEqual(m4bis,1e-12)); - m4bis->decrRef(); - // - const int vec3[5]={0,1,2,3,4}; - MEDCouplingUMesh *m4_1=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec3,vec3+5,false); - m4_1->setName(m1->getName().c_str()); - CPPUNIT_ASSERT(m4_1->isEqual(m1,1e-12)); - m4_1->decrRef(); - // - const int vec4[3]={5,6,7}; - MEDCouplingUMesh *m4_2=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec4,vec4+3,false); - DataArrayInt *cellCor=0; - DataArrayInt *nodeCor=0; - m4_2->checkGeoEquivalWith(m2_2,10,1e-12,cellCor,nodeCor); - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - m4_2->decrRef(); - // - const int vec5[2]={8,9}; - MEDCouplingUMesh *m4_3=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec5,vec5+2,false); - CPPUNIT_ASSERT_EQUAL(2,m4_3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4_3->getNumberOfNodes()); - m3_2->zipCoords(); - m4_3->setName(m3_2->getName().c_str()); - CPPUNIT_ASSERT(m4_3->isEqual(m3_2,1e-12)); - m4_3->decrRef(); - // - m4->decrRef(); - m1->decrRef(); - m2->decrRef(); - m2_2->decrRef(); - m3->decrRef(); - m3_2->decrRef(); -} - -void MEDCouplingBasicsTest3::testBuild0DMeshFromCoords1() -{ - const double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(4,3); - coo->setName("My0D"); - std::copy(sourceCoords,sourceCoords+12,coo->getPointer()); - MEDCouplingUMesh *m=MEDCouplingUMesh::Build0DMeshFromCoords(coo); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(0,m->getMeshDimension()); - std::set types=m->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POINT1,*types.begin()); - for(int i=0;i<4;i++) - { - std::vector conn; - m->getNodeIdsOfCell(i,conn); - CPPUNIT_ASSERT_EQUAL(1,(int)conn.size()); - CPPUNIT_ASSERT_EQUAL(i,conn[0]); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_POINT1==m->getTypeOfCell(i)); - } - CPPUNIT_ASSERT(std::string(m->getName())=="My0D"); - m->decrRef(); - coo->decrRef(); -} - diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx deleted file mode 100644 index df3197d90..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTEST3_HXX__ -#define __MEDCOUPLINGBASICSTEST3_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest3 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest3); - CPPUNIT_TEST( testGetMeasureFieldCMesh1 ); - CPPUNIT_TEST( testFieldDoubleZipCoords1 ); - CPPUNIT_TEST( testFieldDoubleZipConnectivity1 ); - CPPUNIT_TEST( testDaDoubleRenumber1 ); - CPPUNIT_TEST( testDaDoubleRenumberAndReduce1 ); - CPPUNIT_TEST( testDaDoubleRenumberInPlace1 ); - CPPUNIT_TEST( testDaDoubleSelectByTupleId1 ); - CPPUNIT_TEST( testDaDoubleRenumberR1 ); - CPPUNIT_TEST( testDaDoubleRenumberInPlaceR1 ); - CPPUNIT_TEST( testDaDoubleGetMinMaxValues1 ); - CPPUNIT_TEST( testFieldDoubleGetMinMaxValues2 ); - CPPUNIT_TEST( testBuildUnstructuredCMesh1 ); - CPPUNIT_TEST( testDataArrayIntInvertO2NNO21 ); - CPPUNIT_TEST( testKeepSetSelectedComponent1 ); - CPPUNIT_TEST( testKeepSetSelectedComponent2 ); - CPPUNIT_TEST( testElementaryDAThrowAndSpecialCases ); - CPPUNIT_TEST( testDAIGetIdsEqual1 ); - CPPUNIT_TEST( testDAIGetIdsEqualList1 ); - CPPUNIT_TEST( testDAFromNoInterlace1 ); - CPPUNIT_TEST( testDAToNoInterlace1 ); - CPPUNIT_TEST( testDAIsUniform1 ); - CPPUNIT_TEST( testDADFromPolarToCart1 ); - CPPUNIT_TEST( testDADFromCylToCart1 ); - CPPUNIT_TEST( testDADFromSpherToCart1 ); - CPPUNIT_TEST( testUnPolyze1 ); - CPPUNIT_TEST( testConvertDegeneratedCells1 ); - CPPUNIT_TEST( testGetNodeIdsNearPoints1 ); - CPPUNIT_TEST( testFieldCopyTinyAttrFrom1 ); - CPPUNIT_TEST( testExtrudedMesh5 ); - CPPUNIT_TEST( testExtrudedMesh6 ); - CPPUNIT_TEST( testExtrudedMesh7 ); - CPPUNIT_TEST( testSimplexize1 ); - CPPUNIT_TEST( testSimplexize2 ); - CPPUNIT_TEST( testDAMeld1 ); - CPPUNIT_TEST( testFieldMeld1 ); - CPPUNIT_TEST( testMergeNodes2 ); - CPPUNIT_TEST( testMergeField2 ); - CPPUNIT_TEST( testDAIBuildComplement1 ); - CPPUNIT_TEST( testDAIBuildUnion1 ); - CPPUNIT_TEST( testDAIBuildIntersection1 ); - CPPUNIT_TEST( testDAIDeltaShiftIndex1 ); - CPPUNIT_TEST( testDaDoubleSelectByTupleIdSafe1 ); - CPPUNIT_TEST( testAreCellsIncludedIn1 ); - CPPUNIT_TEST( testDAIBuildSubstraction1 ); - CPPUNIT_TEST( testBuildOrthogonalField2 ); - CPPUNIT_TEST( testUMInsertNextCell1 ); - CPPUNIT_TEST( testFieldOperatorDivDiffComp1 ); - CPPUNIT_TEST( testDARearrange1 ); - CPPUNIT_TEST( testGetDifferentValues1 ); - CPPUNIT_TEST( testDAIBuildPermutationArr1 ); - CPPUNIT_TEST( testAreCellsIncludedIn2 ); - CPPUNIT_TEST( testUMeshGetPartBarycenterAndOwner1 ); - CPPUNIT_TEST( testUMeshGetPartMeasureField1 ); - CPPUNIT_TEST( testUMeshBuildPartOrthogonalField1 ); - CPPUNIT_TEST( testUMeshGetTypesOfPart1 ); - CPPUNIT_TEST( testUMeshKeepCellIdsByType1 ); - CPPUNIT_TEST( testDAIAggregateMulti1 ); - CPPUNIT_TEST( testMergeUMeshes2 ); - CPPUNIT_TEST( testBuild0DMeshFromCoords1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testGetMeasureFieldCMesh1(); - void testFieldDoubleZipCoords1(); - void testFieldDoubleZipConnectivity1(); - void testDaDoubleRenumber1(); - void testDaDoubleRenumberAndReduce1(); - void testDaDoubleRenumberInPlace1(); - void testDaDoubleSelectByTupleId1(); - void testDaDoubleRenumberR1(); - void testDaDoubleRenumberInPlaceR1(); - void testDaDoubleGetMinMaxValues1(); - void testFieldDoubleGetMinMaxValues2(); - void testBuildUnstructuredCMesh1(); - void testDataArrayIntInvertO2NNO21(); - void testKeepSetSelectedComponent1(); - void testKeepSetSelectedComponent2(); - void testElementaryDAThrowAndSpecialCases(); - void testDAIGetIdsEqual1(); - void testDAIGetIdsEqualList1(); - void testDAFromNoInterlace1(); - void testDAToNoInterlace1(); - void testDAIsUniform1(); - void testDADFromPolarToCart1(); - void testDADFromCylToCart1(); - void testDADFromSpherToCart1(); - void testUnPolyze1(); - void testConvertDegeneratedCells1(); - void testGetNodeIdsNearPoints1(); - void testFieldCopyTinyAttrFrom1(); - void testExtrudedMesh5(); - void testExtrudedMesh6(); - void testExtrudedMesh7(); - void testSimplexize1(); - void testSimplexize2(); - void testDAMeld1(); - void testFieldMeld1(); - void testMergeNodes2(); - void testMergeField2(); - void testDAIBuildComplement1(); - void testDAIBuildUnion1(); - void testDAIBuildIntersection1(); - void testDAIDeltaShiftIndex1(); - void testDaDoubleSelectByTupleIdSafe1(); - void testAreCellsIncludedIn1(); - void testDAIBuildSubstraction1(); - void testBuildOrthogonalField2(); - void testUMInsertNextCell1(); - void testFieldOperatorDivDiffComp1(); - void testDARearrange1(); - void testGetDifferentValues1(); - void testDAIBuildPermutationArr1(); - void testAreCellsIncludedIn2(); - void testUMeshGetPartBarycenterAndOwner1(); - void testUMeshGetPartMeasureField1(); - void testUMeshBuildPartOrthogonalField1(); - void testUMeshGetTypesOfPart1(); - void testUMeshKeepCellIdsByType1(); - void testDAIAggregateMulti1(); - void testMergeUMeshes2(); - void testBuild0DMeshFromCoords1(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx deleted file mode 100644 index 8b547fe08..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ /dev/null @@ -1,2223 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest4.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldOverTime.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest4::testDescriptionInMeshTimeUnit1() -{ - static const char text1[]="totoTTEDD"; - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->setDescription(text1); - CPPUNIT_ASSERT(std::string(m->getDescription())==text1); - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->deepCpy(); - CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); - CPPUNIT_ASSERT(std::string(m2->getDescription())==text1); - m2->setDescription("ggg"); - CPPUNIT_ASSERT(!m->isEqual(m2,1e-12)); - m2->decrRef(); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setTimeUnit(text1); - CPPUNIT_ASSERT(std::string(f->getTimeUnit())==text1); - MEDCouplingFieldDouble *f2=f->deepCpy(); - CPPUNIT_ASSERT(std::string(f2->getTimeUnit())==text1); - f2->decrRef(); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testMultiFields1() -{ - MEDCouplingMultiFields *mfs=buildMultiFields_1(); - std::vector ms=mfs->getMeshes(); - std::vector refs; - std::vector dms=mfs->getDifferentMeshes(refs); - std::vector das=mfs->getArrays(); - std::vector< std::vector > refs2; - std::vector das2=mfs->getDifferentArrays(refs2); - // - CPPUNIT_ASSERT_EQUAL(5,(int)ms.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)dms.size()); - CPPUNIT_ASSERT_EQUAL(6,(int)das.size()); - CPPUNIT_ASSERT_EQUAL(5,(int)das2.size()); - // - MEDCouplingMultiFields *mfs2=mfs->deepCpy(); - CPPUNIT_ASSERT(mfs->isEqual(mfs2,1e-12,1e-12)); - mfs2->decrRef(); - // - mfs->decrRef(); -} - -void MEDCouplingBasicsTest4::testFieldOverTime1() -{ - std::vector fs=buildMultiFields_2(); - CPPUNIT_ASSERT_THROW(MEDCouplingFieldOverTime::New(fs),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f4bis=fs[4]->buildNewTimeReprFromThis(ONE_TIME,false); - fs[4]->decrRef(); - fs[4]=f4bis; - CPPUNIT_ASSERT_THROW(MEDCouplingFieldOverTime::New(fs),INTERP_KERNEL::Exception); - f4bis->setTime(2.7,20,21); - MEDCouplingFieldOverTime *fot=MEDCouplingFieldOverTime::New(fs); - MEDCouplingDefinitionTime dt=fot->getDefinitionTimeZone(); - std::vector hs=dt.getHotSpotsTime(); - CPPUNIT_ASSERT_EQUAL(6,(int)hs.size()); - const double expected1[]={0.2,0.7,1.2,1.35,1.7,2.7}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],hs[i],1e-12); - int meshId,arrId,arrIdInField,fieldId; - dt.getIdsOnTimeRight(0.2,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(0,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(0,fieldId); - // - dt.getIdsOnTimeRight(0.7,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(1,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(1,fieldId); - // - dt.getIdsOnTimeLeft(1.2,meshId,arrId,arrIdInField,fieldId);//**** WARNING left here - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(2,arrId); - CPPUNIT_ASSERT_EQUAL(1,arrIdInField); - CPPUNIT_ASSERT_EQUAL(1,fieldId); - // - dt.getIdsOnTimeRight(1.2,meshId,arrId,arrIdInField,fieldId);//**** WARNING right again here - CPPUNIT_ASSERT_EQUAL(1,meshId); - CPPUNIT_ASSERT_EQUAL(3,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(2,fieldId); - // - dt.getIdsOnTimeRight(1.35,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(1,meshId); - CPPUNIT_ASSERT_EQUAL(3,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(2,fieldId); - // - dt.getIdsOnTimeRight(1.7,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(3,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(3,fieldId); - // - dt.getIdsOnTimeRight(2.7,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(1,meshId); - CPPUNIT_ASSERT_EQUAL(4,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(4,fieldId); - // - MEDCouplingDefinitionTime dt2; - CPPUNIT_ASSERT(!dt2.isEqual(dt)); - dt2.assign(dt); - dt2.assign(dt);//to check memory management - CPPUNIT_ASSERT(dt2.isEqual(dt)); - // - MEDCouplingDefinitionTime dt3; - std::vector tmp1; - std::vector tmp2; - CPPUNIT_ASSERT(!dt2.isEqual(dt3)); - dt2.getTinySerializationInformation(tmp1,tmp2); - dt3.unserialize(tmp1,tmp2); - CPPUNIT_ASSERT(dt2.isEqual(dt3)); - // - for(std::vector::iterator it=fs.begin();it!=fs.end();it++) - (*it)->decrRef(); - fot->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAICheckAndPreparePermutation1() -{ - const int vals1[]={9,10,0,6,4,11,3,7}; - const int expect1[]={5,6,0,3,2,7,1,4}; - const int vals2[]={9,10,0,6,10,11,3,7}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(8,1); - std::copy(vals1,vals1+8,da->getPointer()); - DataArrayInt *da2=da->checkAndPreparePermutation(); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expect1[i],da2->getIJ(i,0)); - da2->decrRef(); - da->decrRef(); - // - da=DataArrayInt::New(); - da->alloc(8,1); - da->iota(0); - da2=da->checkAndPreparePermutation(); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - CPPUNIT_ASSERT(da2->isIdentity()); - da2->decrRef(); - da->decrRef(); - // - da=DataArrayInt::New(); - da->alloc(8,1); - std::copy(vals2,vals2+8,da->getPointer()); - CPPUNIT_ASSERT_THROW(da->checkAndPreparePermutation(),INTERP_KERNEL::Exception); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIChangeSurjectiveFormat1() -{ - const int vals1[8]={0,3,2,3,2,2,1,2}; - const int expected1[5]={0,1,2,6,8}; - const int expected2[8]={0, 6, 2,4,5,7, 1,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(8,1); - std::copy(vals1,vals1+8,da->getPointer()); - // - DataArrayInt *da2,*da2I; - da->changeSurjectiveFormat(4,da2,da2I); - CPPUNIT_ASSERT_EQUAL(5,da2I->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da2I->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+8,da2->getConstPointer())); - da2->decrRef(); - da2I->decrRef(); - // - CPPUNIT_ASSERT_THROW(da->changeSurjectiveFormat(3,da2,da2I),INTERP_KERNEL::Exception); - // - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshGetCellIdsLyingOnNodes1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - const int nodeIds1[5]={1,2,3,4,6}; - const int nodeIds2[2]={6,7}; - DataArrayInt *da=m->getCellIdsLyingOnNodes(nodeIds1,nodeIds1+5,true); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,da->getIJ(0,0)); - da->decrRef(); - da=m->getCellIdsLyingOnNodes(nodeIds2,nodeIds2+2,false); - CPPUNIT_ASSERT_EQUAL(2,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,da->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(4,da->getIJ(1,0)); - da->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshFindCellIdsOnBoundary1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - DataArrayInt *da5=m->findCellIdsOnBoundary(); - CPPUNIT_ASSERT_EQUAL(5,da5->getNumberOfTuples()); - CPPUNIT_ASSERT(da5->isIdentity()); - // - da5->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testMeshSetTime1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - // - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m1->setTime(3.14,6,7); - int tmp1,tmp2; - double tmp3=m1->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(6,tmp1); - CPPUNIT_ASSERT_EQUAL(7,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.14,tmp3,1e-12); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTime(3.14,6,7); - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m1->setTimeUnit("ms"); - CPPUNIT_ASSERT(std::string(m1->getTimeUnit())=="ms"); - m1->setTimeUnit("us"); - CPPUNIT_ASSERT(std::string(m1->getTimeUnit())=="us"); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTimeUnit("us"); - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m2->setTime(3.14,6,8); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTime(3.14,7,7); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTime(3.15,6,7); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - // - m1->setTime(10.34,55,12); - MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->deepCpy(); - CPPUNIT_ASSERT(m1->isEqual(m3,1e-12)); - tmp3=m3->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(55,tmp1); - CPPUNIT_ASSERT_EQUAL(12,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.34,tmp3,1e-12); - // - m3->decrRef(); - m1->decrRef(); - m2->decrRef(); - // testing CMesh - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - a->decrRef(); - // - b->setTime(5.67,8,100); - tmp3=b->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(8,tmp1); - CPPUNIT_ASSERT_EQUAL(100,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.67,tmp3,1e-12); - MEDCouplingCMesh *c=(MEDCouplingCMesh *)b->deepCpy(); - CPPUNIT_ASSERT(c->isEqual(b,1e-12)); - tmp3=c->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(8,tmp1); - CPPUNIT_ASSERT_EQUAL(100,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.67,tmp3,1e-12); - c->decrRef(); - b->decrRef(); -} - -void MEDCouplingBasicsTest4::testApplyFuncTwo1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m1); - // - const double vals[15]={1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(5,3); - std::copy(vals,vals+15,da->getPointer()); - f1->setArray(da); - // - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"y+z"),INTERP_KERNEL::Exception); - da->setInfoOnComponent(0,"x [m]"); - da->setInfoOnComponent(1,"y [mm]"); - da->setInfoOnComponent(2,"z [km]"); - - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"x+y+zz+zzz"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"toto(x+y)"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"x/0"),INTERP_KERNEL::Exception); - - DataArrayDouble *da2=da->applyFunc2(1,"y+z"); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); - const double expected1[5]={32.,34.,36.,38.,40.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); - da2->decrRef(); - da2=da->applyFunc(1,"y+z"); - const double expected2[5]={12.,14.,16.,18.,20.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],da2->getIJ(0,i),1e-12); - da2->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - f1->applyFunc2(1,"y+z"); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - // - da->decrRef(); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testApplyFuncThree1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m1); - // - const double vals[15]={1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(5,3); - std::copy(vals,vals+15,da->getPointer()); - f1->setArray(da); - // - std::vector vs(3); - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"y+z"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"x+Y+z+zz+zzz"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"x/0."),INTERP_KERNEL::Exception); - vs[1]="y"; - DataArrayDouble *da2=da->applyFunc3(1,vs,"y+z"); - const double expected1[5]={32.,34.,36.,38.,40.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); - da2->decrRef(); - std::vector vs2(4); vs2[0]="x"; vs2[1]="y"; vs2[2]="z"; vs2[3]="a"; - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs2,"x+a"),INTERP_KERNEL::Exception); - f1->setArray(da); - CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - f1->applyFunc3(1,vs,"y+z"); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - // - da->decrRef(); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - m1->setTime(3.4,5,6); m1->setTimeUnit("us"); - int a,b; - CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic2(ON_NODES,1,"y+z"),INTERP_KERNEL::Exception); - m1->getCoords()->setInfoOnComponent(0,"x [m]"); - m1->getCoords()->setInfoOnComponent(1,"y"); - m1->getCoords()->setInfoOnComponent(2,"z"); - MEDCouplingFieldDouble *f1=m1->fillFromAnalytic2(ON_NODES,1,"y+z"); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testFillFromAnalyticThree1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - m1->setTime(3.4,5,6); m1->setTimeUnit("us"); - int a,b; - std::vector vs(3); - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"),INTERP_KERNEL::Exception); - vs[1]="y"; - MEDCouplingFieldDouble *f1=m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAUnitVar1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(1,3); - da->setInfoOnComponent(0,"XPS [m]"); - std::string st1,st2; - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPS"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2=="m"); - // - da->setInfoOnComponent(0,"XPS [m]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPS"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2=="m"); - // - da->setInfoOnComponent(0,"XPP [m]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPP"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2=="m"); - // - da->setInfoOnComponent(0,"XPP kdep kefer [ m ]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPP kdep kefer"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==" m "); - // - da->setInfoOnComponent(0," XPP k[ dep k]efer [ m^ 2/s^3*kJ ]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1==" XPP k[ dep k]efer"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==" m^ 2/s^3*kJ "); - // - da->setInfoOnComponent(0," XPP kefer "); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1==" XPP kefer "); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==""); - // - da->setInfoOnComponent(0,"temperature( bof)"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="temperature( bof)"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==""); - // - da->setInfoOnComponent(0,"kkk [m]"); - da->setInfoOnComponent(1,"ppp [m^2/kJ]"); - da->setInfoOnComponent(2,"abcde [MW/s]"); - // - std::vector vs; - vs=da->getVarsOnComponent(); - CPPUNIT_ASSERT_EQUAL(3,(int)vs.size()); - CPPUNIT_ASSERT(vs[0]=="kkk"); - CPPUNIT_ASSERT(vs[1]=="ppp"); - CPPUNIT_ASSERT(vs[2]=="abcde"); - vs=da->getUnitsOnComponent(); - CPPUNIT_ASSERT_EQUAL(3,(int)vs.size()); - CPPUNIT_ASSERT(vs[0]=="m"); - CPPUNIT_ASSERT(vs[1]=="m^2/kJ"); - CPPUNIT_ASSERT(vs[2]=="MW/s"); - // - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testGaussCoordinates1() -{ - //Testing 1D cell types - MEDCouplingUMesh *m1=build1DMultiTypes_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setMesh(m1); - std::vector wg1(1); wg1[0]=0.3; - std::vector gsCoo1(1); gsCoo1[0]=0.2; - std::vector refCoo1(2); refCoo1[0]=-1.0; refCoo1[1]=1.0; - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_SEG2,refCoo1,gsCoo1,wg1); - std::vector wg2(wg1); - std::vector gsCoo2(1); gsCoo2[0]=0.2; - std::vector refCoo2(3); refCoo2[0]=-1.0; refCoo2[1]=1.0; refCoo2[2]=0.0; - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_SEG3,refCoo2,gsCoo2,wg2); - // - DataArrayDouble *resToTest=f->getLocalizationOfDiscr(); - CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,resToTest->getNumberOfTuples()); - const double expected1[6]={0.6,0.6,0.6, 0.6,0.6,0.6}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],resToTest->getIJ(0,i),1e-14); - resToTest->decrRef(); - // - m1->decrRef(); - f->decrRef(); - //Testing 2D cell types - MEDCouplingUMesh *m2=build2DMultiTypes_1(); - f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setMesh(m2); - std::vector wg3(2); wg3[0]=0.3; wg3[1]=0.3; - const double tria3CooGauss[4]={ 0.1, 0.8, 0.2, 0.7 }; - std::vector gsCoo3(tria3CooGauss,tria3CooGauss+4); - const double tria3CooRef[6]={ 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0 }; - std::vector refCoo3(tria3CooRef,tria3CooRef+6); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,refCoo3,gsCoo3,wg3); - std::vector wg4(3); wg4[0]=0.3; wg4[1]=0.3; wg4[2]=0.3; - const double tria6CooGauss[6]={ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4 }; - std::vector gsCoo4(tria6CooGauss,tria6CooGauss+6); - const double tria6CooRef[12]={0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5}; - std::vector refCoo4(tria6CooRef,tria6CooRef+12); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,refCoo4,gsCoo4,wg4); - std::vector wg5(4); wg5[0]=0.3; wg5[1]=0.3; wg5[2]=0.3; wg5[3]=0.3; - const double quad4CooGauss[8]={ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27 }; - std::vector gsCoo5(quad4CooGauss,quad4CooGauss+8); - const double quad4CooRef[8]={-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; - std::vector refCoo5(quad4CooRef,quad4CooRef+8); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,refCoo5,gsCoo5,wg5); - std::vector wg6(4); wg6[0]=0.3; wg6[1]=0.3; wg6[2]=0.3; wg6[3]=0.3; - const double quad8CooGauss[8]={ 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37 }; - std::vector gsCoo6(quad8CooGauss,quad8CooGauss+8); - const double quad8CooRef[16]={ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0}; - std::vector refCoo6(quad8CooRef,quad8CooRef+16); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD8,refCoo6,gsCoo6,wg6); - // - resToTest=f->getLocalizationOfDiscr(); - CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(13,resToTest->getNumberOfTuples());//2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - const double expected2[39]={5.1,1.55,0.0, 4.7,1.65,0.0, //TRI3 - 2.32,1.52,0.0, 1.6,1.32,0.0, 3.52,1.26,0.0,//TRI6 - 2.6,1.6,0.0, 2.4,1.8,0.0, 2.4,1.2,0.0, 2.3,1.46,0.0,//QUAD4 - 2.32,2.68,0.0, 2.6,2.42,0.0, 2.8,2.46,0.0, 2.74,2.28,0.0 };//QUAD8 - for(int i=0;i<39;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],resToTest->getIJ(0,i),1e-14); - resToTest->decrRef(); - // - m2->decrRef(); - f->decrRef(); - //Testing 3D cell types - MEDCouplingUMesh *m3=build3DMultiTypes_1(); - f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setMesh(m3); - // - std::vector wg7(1); wg7[0]=0.3; - const double tetra4CooGauss[3]={0.34, 0.16, 0.21}; - std::vector gsCoo7(tetra4CooGauss,tetra4CooGauss+3); - const double tetra4CooRef[12]={0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,0.0,0.0, 1.0,0.0,0.0}; - std::vector refCoo7(tetra4CooRef,tetra4CooRef+12); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TETRA4,refCoo7,gsCoo7,wg7); - std::vector wg8(1); wg8[0]=0.3; - const double tetra10CooGauss[3]={0.2, 0.3, 0.1}; - std::vector gsCoo8(tetra10CooGauss,tetra10CooGauss+3); - const double tetra10CooRef[30]={0.0,1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 0.0,0.5,0.0, 0.0,0.0,0.5, 0.0,0.5,0.5, 0.5,0.5,0.0, 0.5,0.0,0.0, 0.5,0.0,0.5}; - std::vector refCoo8(tetra10CooRef,tetra10CooRef+30); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TETRA10,refCoo8,gsCoo8,wg8); - std::vector wg9(1); wg9[0]=0.3; - const double pyra5CooGauss[3]={0.2, 0.3, 0.1}; - std::vector gsCoo9(pyra5CooGauss,pyra5CooGauss+3); - const double pyra5CooRef[15]={1.0,0.0,0.0, 0.0,1.0,0.0, -1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,1.0}; - std::vector refCoo9(pyra5CooRef,pyra5CooRef+15); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PYRA5,refCoo9,gsCoo9,wg9); - std::vector wg10(1); wg10[0]=0.3; - const double pyra13CooGauss[3]={0.1, 0.2, 0.7}; - std::vector gsCoo10(pyra13CooGauss,pyra13CooGauss+3); - const double pyra13CooRef[39]={1.0,0.0,0.0, 0.0,1.0,0.0,-1.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.0,1.0,0.5,0.5,0.0,-0.5,0.5,0.0,-0.5,-0.5,0.0,0.5,-0.5,0.0,0.5,0.0,0.5,0.0,0.5,0.5,-0.5,0.0,0.5,0.0,-0.5,0.5}; - std::vector refCoo10(pyra13CooRef,pyra13CooRef+39); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PYRA13,refCoo10,gsCoo10,wg10); - std::vector wg11(1); wg11[0]=0.3; - const double penta6CooGauss[3]={0.2, 0.3, 0.1}; - std::vector gsCoo11(penta6CooGauss,penta6CooGauss+3); - const double penta6CooRef[18]={-1.0,1.0,0.0,-1.0,-0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0}; - std::vector refCoo11(penta6CooRef,penta6CooRef+18); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PENTA6,refCoo11,gsCoo11,wg11); - std::vector wg12(1); wg12[0]=0.3; - const double penta15CooGauss[3]={0.2, 0.3,0.15}; - std::vector gsCoo12(penta15CooGauss,penta15CooGauss+3); - const double penta15CooRef[45]={-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0,-1.0,0.5,0.5,-1.0,0.0,0.5,-1.0,0.5,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.5,0.5,1.0,0.0, 0.5,1.0,0.5,0.0}; - std::vector refCoo12(penta15CooRef,penta15CooRef+45); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PENTA15,refCoo12,gsCoo12,wg12); - std::vector wg13(1); wg13[0]=0.3; - const double hexa8CooGauss[3]={0.2,0.3,0.15}; - std::vector gsCoo13(hexa8CooGauss,hexa8CooGauss+3); - const double hexa8CooRef[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0}; - std::vector refCoo13(hexa8CooRef,hexa8CooRef+24); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_HEXA8,refCoo13,gsCoo13,wg13); - std::vector wg14(1); wg14[0]=0.3; - const double hexa20CooGauss[3]={0.11,0.3,0.55}; - std::vector gsCoo14(hexa20CooGauss,hexa20CooGauss+3); - const double hexa20CooRef[60]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,0.0,-1.0,-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,-1.0,0.0,-1.0,-1.0,-1.0,0.0,1.0,-1.0,0.0,1.0,1.0,0.0,-1.0,1.0,0.0,0.0,-1.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,-1.0,0.0,1.0}; - std::vector refCoo14(hexa20CooRef,hexa20CooRef+60); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_HEXA20,refCoo14,gsCoo14,wg14); - // - resToTest=f->getLocalizationOfDiscr(); - CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(8,resToTest->getNumberOfTuples());//2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - const double expected3[24]={1.312,3.15,1.02, 0.56,3.3,0.6, 2.18,1.1,0.2, 1.18,1.54,0.98, 1.56,0.3,3.6, 1.613,0.801,4.374, 2.6,2.4,2.3, 2.31232,2.3933985,1.553255}; - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],resToTest->getIJ(0,i),1e-14); - resToTest->decrRef(); - // - m3->decrRef(); - f->decrRef(); -} - -/*! - * Not activated test ! To be implemented ! - */ -void MEDCouplingBasicsTest4::testQ1Localization1() -{ - MEDCouplingUMesh *m=buildHexa8Mesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - DataArrayDouble *da=DataArrayDouble::New(); - const double vals1[27]={1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0,1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0,1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0}; - da->alloc(27,1); - std::copy(vals1,vals1+27,da->getPointer()); - f->setMesh(m); - f->setArray(da); - da->decrRef(); - // - const double point1[3]={0.25,0.75,0.25}; - //const double points1[6]={0.25,0.75,0.25,1.0,1.0,1.0}; - double res1[3]; - f->getValueOn(point1,res1); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testP2Localization1() -{ - MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2",2); - const double coords[12]={0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4}; - const int conn[6]={0,1,2,3,4,5}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(6,2); - std::copy(coords,coords+12,coo->getPointer()); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn); - m->finishInsertingCells(); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f->setMesh(m); - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,3); - const double vals1[18]={1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4}; - std::copy(vals1,vals1+18,da->getPointer()); - f->setArray(da); - da->decrRef(); - // - const double loc[2]={2.27,1.3}; - DataArrayDouble *locs=f->getValueOnMulti(loc,1); - const double expected1[3]={6.0921164547752236, 7.1921164547752232, 8.2921164547752255}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); - locs->decrRef(); - // - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testP2Localization2() -{ - MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2_2",3); - const double coords[30]={0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891}; - const int conn[10]={0,1,2,3,4,5,6,7,8,9}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(10,3); - std::copy(coords,coords+30,coo->getPointer()); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn); - m->finishInsertingCells(); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f->setMesh(m); - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(10,1); - const double vals1[10]={1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2}; - std::copy(vals1,vals1+10,da->getPointer()); - f->setArray(da); - da->decrRef(); - // - const double loc[3]={0.64637931739890486, -0.16185896817550552, 0.22678966365273748}; - DataArrayDouble *locs=f->getValueOnMulti(loc,1); - const double expected1[1]={10.0844021968047}; - for(int i=0;i<1;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); - locs->decrRef(); - // - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetValueOn2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - int nbOfCells=m->getNumberOfCells(); - arr->alloc(nbOfCells,3); - f->setArray(arr); - arr->decrRef(); - const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; - std::copy(values1,values1+15,arr->getPointer()); - const double loc[10]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; - f->checkCoherency(); - DataArrayDouble *locs=f->getValueOnMulti(loc,5); - CPPUNIT_ASSERT_EQUAL(5,locs->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,locs->getNumberOfComponents()); - for(int j=0;j<15;j++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[j],locs->getIJ(0,j),1e-12); - locs->decrRef(); - f->decrRef(); - // Testing ON_NODES - f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f->setMesh(m); - arr=DataArrayDouble::New(); - int nbOfNodes=m->getNumberOfNodes(); - arr->alloc(nbOfNodes,3); - f->setArray(arr); - arr->decrRef(); - const double values2[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; - std::copy(values2,values2+27,arr->getPointer()); - const double loc2[8]={0.5432,-0.2432, 0.5478,0.1528, 0.5432,-0.2432, 0.5432,-0.2432}; - const double expected2[12]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124, 9.0272, 109.0272, 10009.0272, 9.0272, 109.0272, 10009.0272}; - f->checkCoherency(); - locs=f->getValueOnMulti(loc2,4); - CPPUNIT_ASSERT_EQUAL(4,locs->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,locs->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],locs->getIJ(0,i),1e-12); - f->decrRef(); - locs->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIGetIdsNotEqual1() -{ - DataArrayInt *d=DataArrayInt::New(); - const int vals1[10]={2,3,5,6,8,5,5,6,1,-5}; - d->alloc(10,1); - std::copy(vals1,vals1+10,d->getPointer()); - DataArrayInt *d2=d->getIdsNotEqual(5); - CPPUNIT_ASSERT_EQUAL(7,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); - const int expected1[7]={0,1,3,4,7,8,9}; - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],d2->getIJ(0,i)); - d->rearrange(2); - CPPUNIT_ASSERT_THROW(d->getIdsNotEqual(5),INTERP_KERNEL::Exception); - const int vals2[3]={-4,5,6}; - std::vector vals3(vals2,vals2+3); - d->rearrange(1); - DataArrayInt *d3=d->getIdsNotEqualList(&vals3[0],&vals3[0]+vals3.size()); - CPPUNIT_ASSERT_EQUAL(5,d3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d3->getNumberOfComponents()); - const int expected2[5]={0,1,4,8,9}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d3->getIJ(0,i)); - d3->decrRef(); - d->decrRef(); - d2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIComputeOffsets1() -{ - DataArrayInt *d=DataArrayInt::New(); - const int vals1[6]={3,5,1,2,0,8}; - const int expected1[6]={0,3,8,9,11,11}; - d->alloc(6,1); - std::copy(vals1,vals1+6,d->getPointer()); - d->computeOffsets(); - CPPUNIT_ASSERT_EQUAL(6,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],d->getIJ(0,i)); - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshHexagonPrism1() -{ - const double coords[36]={ - 0.8660254037844386, 0.5, 0.0, 0.0, 1.0, 0.0, -0.8660254037844386, 0.5, 0.0, -0.8660254037844386, -0.5, 0.0, 0.0, -1.0, 0.0, 0.8660254037844386, -0.5, 0.0, - 0.8660254037844386, 0.5, 2.0, 0.0, 1.0, 2.0, -0.8660254037844386, 0.5, 2.0, -0.8660254037844386, -0.5, 2.0, 0.0, -1.0, 2.0, 0.8660254037844386, -0.5, 2.0 - }; - const int conn[12]={1,2,3,4,5,0,7,8,9,10,11,6}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("MyFirstHexagonalPrism",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(12,3); - std::copy(coords,coords+36,coo->getPointer()); - mesh->setCoords(coo); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXGP12,12,conn); - mesh->finishInsertingCells(); - coo->decrRef(); - // - mesh->checkCoherency(); - MEDCouplingFieldDouble *vols=mesh->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-5.196152422706632,vols->getIJ(0,0),1e-12); - DataArrayDouble *bary=mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(1,bary->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); - const double expected1[3]={0.,0.,1.}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],bary->getIJ(0,i),1e-12); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - DataArrayInt *d4=DataArrayInt::New(); - MEDCouplingUMesh *m2=mesh->buildDescendingConnectivity(d1,d2,d3,d4); - CPPUNIT_ASSERT_EQUAL(8,m2->getNumberOfCells()); - const int expected4[8][6]={{1,2,3,4,5,0},{7,6,11,10,9,8},{1,7,8,2},{2,8,9,3},{3,9,10,4},{4,10,11,5},{5,11,6,0},{0,6,7,1}}; - const INTERP_KERNEL::NormalizedCellType expected2[8]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4}; - const int expected3[8]={6,6,4,4,4,4,4,4}; - for(int i=0;i<8;i++) - { - CPPUNIT_ASSERT(m2->getTypeOfCell(i)==expected2[i]); - std::vector v; - m2->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==expected3[i]); - CPPUNIT_ASSERT(std::equal(expected4[i],expected4[i]+expected3[i],v.begin())); - } - d1->decrRef(); - d2->decrRef(); - d3->decrRef(); - d4->decrRef(); - m2->decrRef(); - // - mesh->convertAllToPoly(); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_POLYHED==mesh->getTypeOfCell(0)); - mesh->unPolyze(); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_HEXGP12==mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(13,mesh->getMeshLength()); - // - vols->decrRef(); - bary->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADCheckIsMonotonic() -{ - DataArrayDouble *da=DataArrayDouble::New(); - const double vals[4]={-1.,1.01,2.03,6.}; - da->alloc(2,2); - std::copy(vals,vals+4,da->getPointer()); - CPPUNIT_ASSERT_THROW(da->isMonotonic(true, 1e-12),INTERP_KERNEL::Exception); - da->rearrange(1); - CPPUNIT_ASSERT(da->isMonotonic(true, 1e-12)); - da->checkMonotonic(true, 1e-12); - da->setIJ(2,0,6.1); - CPPUNIT_ASSERT(!da->isMonotonic(true, 1e-12)); - CPPUNIT_ASSERT_THROW(da->checkMonotonic(true, 1e-12),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->checkMonotonic(false, 1e-12),INTERP_KERNEL::Exception); - da->setIJ(2,0,5.99); - CPPUNIT_ASSERT(da->isMonotonic(true, 1e-12)); - CPPUNIT_ASSERT(!da->isMonotonic(true, 1e-1)); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testCheckCoherencyDeeper1() -{ - MEDCouplingUMesh *m=build3DSourceMesh_1(); - m->checkCoherency(); - m->checkCoherency1(); - m->getNodalConnectivity()->setIJ(8,0,-1); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(8,0,-6); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(8,0,9);//9>=NbOfNodes - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(8,0,8);//OK - m->checkCoherency(); - m->checkCoherency1(); - const int elts[2]={1,5}; - std::vector eltsV(elts,elts+2); - m->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - m->checkCoherency(); - m->checkCoherency1(); - m->getNodalConnectivity()->setIJ(2,0,9);//9>=NbOfNodes - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(2,0,-3); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(2,0,-1); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw because cell#0 is not a polyhedron - m->getNodalConnectivity()->setIJ(2,0,4); - m->checkCoherency(); - m->checkCoherency1(); - m->getNodalConnectivity()->setIJ(7,0,-1); - m->checkCoherency(); - m->checkCoherency1();//OK because we are in polyhedron connec - m->getNodalConnectivity()->setIJ(36,0,14); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testUnPolyze2() -{ - MEDCouplingUMesh *m=MEDCouplingUMesh::New("jjj",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(4,3); - coo->rearrange(1); - coo->iota(0); - coo->rearrange(3); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(2); - const int conn[4]={0,1,2,3}; - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - m->finishInsertingCells(); - std::vector ms(4,m); - MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms); - std::vector temp(1,2); - m2->convertToPolyTypes(&temp[0],&temp[0]+temp.size()); - m2->unPolyze(); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_TETRA4==m2->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(40,m2->getMeshLength()); - std::vector temp2; - m2->getNodeIdsOfCell(2,temp2); - CPPUNIT_ASSERT(4==(int)temp2.size()); - CPPUNIT_ASSERT(std::equal(conn,conn+4,temp2.begin())); - m2->checkCoherency1(); - MEDCouplingMesh *m3=m2->deepCpy(); - m2->unPolyze(); - CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); - m3->decrRef(); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDACpyFrom1() -{ - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(12,1); - d->iota(14.); - d->rearrange(3); - d->setName("Toto"); - d->setInfoOnComponent(0,"X [m]"); - d->setInfoOnComponent(1,"Y [m]"); - d->setInfoOnComponent(2,"Z [m]"); - // - DataArrayDouble *d1=DataArrayDouble::New(); - CPPUNIT_ASSERT(!d->isEqual(*d1,1e-12)); - d1->cpyFrom(*d); - CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); - d1->cpyFrom(*d); - CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); - d1->rearrange(2); - CPPUNIT_ASSERT(!d->isEqual(*d1,1e-12)); - d1->cpyFrom(*d); - CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); - // - DataArrayInt *d2=d->convertToIntArr(); - DataArrayInt *d4=DataArrayInt::New(); - CPPUNIT_ASSERT(!d2->isEqual(*d4)); - d4->cpyFrom(*d2); - CPPUNIT_ASSERT(d2->isEqual(*d4)); - d4->cpyFrom(*d2); - CPPUNIT_ASSERT(d2->isEqual(*d4)); - d4->rearrange(2); - CPPUNIT_ASSERT(!d2->isEqual(*d4)); - d4->cpyFrom(*d2); - CPPUNIT_ASSERT(d2->isEqual(*d4)); - // - d->decrRef(); - d1->decrRef(); - d2->decrRef(); - d4->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAITransformWithIndArr1() -{ - const int tab1[4]={17,18,22,19}; - const int tab2[12]={0,1,1,3,3,0,1,3,2,2,3,0}; - const int expected[12]={17,18,18,19,19,17,18,19,22,22,19,17}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(4,1); - std::copy(tab1,tab1+4,d->getPointer()); - DataArrayInt *d1=DataArrayInt::New(); - d1->alloc(12,1); - std::copy(tab2,tab2+12,d1->getPointer()); - // - d1->transformWithIndArr(d->getConstPointer(),d->getConstPointer()+d->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected[i],d1->getIJ(i,0)); - // - d->decrRef(); - d1->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIBuildPermArrPerLevel1() -{ - const int arr[12]={2,0,1,1,0,1,2,0,1,1,0,0}; - const int expected1[12]={10,0,5,6,1,7,11,2,8,9,3,4}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(12,1); - std::copy(arr,arr+12,da->getPointer()); - DataArrayInt *da2=da->buildPermArrPerLevel(); - CPPUNIT_ASSERT_EQUAL(12,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - da->decrRef(); - da2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIOperations1() -{ - const int arr1[12]={-1,-2,4,7,3,2,6,6,4,3,0,1}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(4,3); - std::copy(arr1,arr1+12,da->getPointer()); - DataArrayInt *da1=DataArrayInt::New(); - da1->alloc(12,1); - da1->iota(2); - CPPUNIT_ASSERT_THROW(DataArrayInt::Add(da,da1),INTERP_KERNEL::Exception);//not same number of tuples/Components - da1->rearrange(3); - DataArrayInt *da2=DataArrayInt::Add(da,da1); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - const int expected1[12]={1,1,8,12,9,9,14,15,14,14,12,14}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(0,i)); - da2->decrRef(); - da1->substractEqual(da); - const int expected2[12]={3,5,0,-2,3,5,2,3,6,8,12,12}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da1->getIJ(0,i)); - da1->rearrange(1); da1->iota(2); da1->rearrange(3); - da1->addEqual(da); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da1->getIJ(0,i)); - da1->rearrange(1); da1->iota(2); da1->rearrange(3); - da2=DataArrayInt::Multiply(da,da1); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - const int expected3[12]={-2,-6,16,35,18,14,48,54,40,33,0,13}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],da2->getIJ(0,i)); - da2->decrRef(); - da->divideEqual(da1); - CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); - const int expected4[12]={0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],da->getIJ(0,i)); - std::copy(arr1,arr1+12,da->getPointer()); - da1->multiplyEqual(da); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],da1->getIJ(0,i)); - da1->rearrange(1); da1->iota(2); da1->rearrange(3); - da2=DataArrayInt::Divide(da,da1); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],da2->getIJ(0,i)); - da2->decrRef(); - da1->applyInv(321); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - const int expected5[12]={160,107,80,64,53,45,40,35,32,29,26,24}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected5[i],da1->getIJ(0,i)); - da1->applyDivideBy(2); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - const int expected6[12]={80,53,40,32,26,22,20,17,16,14,13,12}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected6[i],da1->getIJ(0,i)); - const int expected7[12]={3,4,5,4,5,1,6,3,2,0,6,5}; - da1->applyModulus(7); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected7[i],da1->getIJ(0,i)); - da1->applyLin(1,1); - const int expected8[12]={3,3,3,3,3,1,3,3,0,0,3,3}; - da1->applyRModulus(3); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected8[i],da1->getIJ(0,i)); - // - da1->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testEmulateMEDMEMBDC1() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m=buildPointe_1(m1); - DataArrayInt *da1=DataArrayInt::New(); - DataArrayInt *da2=DataArrayInt::New(); - DataArrayInt *da3=0; - DataArrayInt *da4=0; - DataArrayInt *da5=0; - DataArrayInt *da0=0; - MEDCouplingUMesh *m2=m->emulateMEDMEMBDC(m1,da1,da2,da3,da4,da5,da0); - const int expected0[47]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46}; - const int expected1[6]={1,32,29,23,41,36}; - CPPUNIT_ASSERT_EQUAL(47,da0->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da0->getNumberOfComponents()); - for(int i=0;i<47;i++) - CPPUNIT_ASSERT_EQUAL(expected0[i],da0->getIJ(0,i)); - CPPUNIT_ASSERT_EQUAL(6,da5->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da5->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da5->getIJ(0,i)); - const int expected2[70]={0,1,2,3,4,0,5,6,7,4,8,9,1,7,10,11,12,13,14,5,15,16,17,8,18,19,20,10,21,22,23,2,13,24,25,21,16,26,27,12,19,28,29,15,22,30,31,18,36,26,28,30,24,37,32,33,34,35,38,36,39,40,41,42,37,38,43,44,45,46}; - CPPUNIT_ASSERT_EQUAL(70,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); - for(int i=0;i<70;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da1->getIJ(0,i)); - const int expected3[17]={0,4,8,12,16,20,24,28,32,36,40,44,48,53,58,64,70}; - CPPUNIT_ASSERT_EQUAL(17,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<17;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],da2->getIJ(0,i)); - const int expected4[48]={0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,53,54,55,56,58,60,62,63,64,65,66,67,68,69,70}; - //const int expected4[48]={0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,54,56,57,58,59,60,62,63,64,65,66,67,68,69,70}; - CPPUNIT_ASSERT_EQUAL(48,da4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da4->getNumberOfComponents()); - for(int i=0;i<48;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],da4->getIJ(0,i)); - const int expected5[70]={0,1,0,3,0,7,0,1,2,1,4,1,2,3,2,5,2,3,6,3,4,9,4,8,4,5,10,5,9,5,6,11,6,10,6,7,8,7,11,7,8,12,8,9,12,9,10,12,10,11,12,11,13,13,13,13,12,14,13,15,14,15,14,14,14,14,15,15,15,15}; - CPPUNIT_ASSERT_EQUAL(70,da3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da3->getNumberOfComponents()); - for(int i=0;i<70;i++) - CPPUNIT_ASSERT_EQUAL(expected5[i],da3->getIJ(0,i)); - // - da0->decrRef(); - da1->decrRef(); - da2->decrRef(); - da3->decrRef(); - da4->decrRef(); - da5->decrRef(); - // - m2->decrRef(); - m1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetLevArrPerCellTypes1() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m=buildPointe_1(m1); - m1->decrRef(); - DataArrayInt *d0=DataArrayInt::New(); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - m1=m->buildDescendingConnectivity(d0,d1,d2,d3); - d0->decrRef(); d1->decrRef(); d2->decrRef(); d3->decrRef(); - INTERP_KERNEL::NormalizedCellType order[2]={INTERP_KERNEL::NORM_TRI3,INTERP_KERNEL::NORM_QUAD4}; - DataArrayInt *da1=0; - DataArrayInt *da0=m1->getLevArrPerCellTypes(order,order+2,da1); - const int expected0[47]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1}; - const int expected1[47]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46}; - CPPUNIT_ASSERT_EQUAL(47,da0->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da0->getNumberOfComponents()); - for(int i=0;i<47;i++) - CPPUNIT_ASSERT_EQUAL(expected0[i],da0->getIJ(0,i)); - CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(36,da1->getIJ(0,0));//36 TRI3 - CPPUNIT_ASSERT_EQUAL(11,da1->getIJ(1,0));//11 QUAD4 - // - DataArrayInt *da2=da0->buildPermArrPerLevel(); - // - CPPUNIT_ASSERT_EQUAL(47,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<47;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(0,i)); - da2->decrRef(); - da0->decrRef(); - da1->decrRef(); - // - m->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testSortCellsInMEDFileFrmt1() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m=buildPointe_1(m1); - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->deepCpy(); - m->setCoords(0); - const int vals[16]={0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(16,1); - std::copy(vals,vals+16,da->getPointer()); - DataArrayInt *daa=da->invertArrayN2O2O2N(16); - m->renumberCells(daa->getConstPointer(),false); - daa->decrRef(); - DataArrayInt *da2=m->sortCellsInMEDFileFrmt(); - CPPUNIT_ASSERT(m2->isEqual(m2,1e-12)); - CPPUNIT_ASSERT(da->isEqual(*da2)); - m2->decrRef(); - da2->decrRef(); - da->decrRef(); - m1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testBuildPartAndReduceNodes1() -{ - MEDCouplingMesh *m=build2DTargetMesh_1(); - const int arr[2]={1,0}; - DataArrayInt *da; - MEDCouplingMesh *m2=m->buildPartAndReduceNodes(arr,arr+2,da); - CPPUNIT_ASSERT_EQUAL(5,m2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m2->getNumberOfCells()); - MEDCouplingFieldDouble *f=m2->getMeasureField(true); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,f->getArray()->getIJ(0,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,f->getArray()->getIJ(1,0),1e-12); - f->decrRef(); - da->decrRef(); - m2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAITransformWithIndArrR1() -{ - const int tab1[6]={2,4,5,3,6,7}; - const int tab2[12]={-1,-1,0,1,2,3,4,5,-1,-1,-1,-1}; - const int expected[6]={0,3,1,2,4,5}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(6,1); - std::copy(tab1,tab1+6,d->getPointer()); - DataArrayInt *d1=DataArrayInt::New(); - d1->alloc(12,1); - std::copy(tab2,tab2+12,d1->getPointer()); - // - DataArrayInt *d3=d->transformWithIndArrR(d1->getConstPointer(),d1->getConstPointer()+d1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(6,d3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d3->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected[i],d3->getIJ(i,0)); - d3->decrRef(); - // - d->decrRef(); - d1->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAISplitByValueRange1() -{ - const int val1[9]={6,5,0,3,2,7,8,1,4}; - const int val2[3]={0,4,9}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(9,1); - std::copy(val1,val1+9,d->getPointer()); - DataArrayInt *ee=0,*f=0,*g=0; - d->splitByValueRange(val2,val2+3,ee,f,g); - CPPUNIT_ASSERT_EQUAL(9,ee->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ee->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,g->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,g->getNumberOfComponents()); - // - const int expected1[9]={1,1,0,0,0,1,1,0,1}; - const int expected2[9]={2,1,0,3,2,3,4,1,0}; - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_EQUAL(expected1[i],ee->getIJ(i,0)); - CPPUNIT_ASSERT_EQUAL(expected2[i],f->getIJ(i,0)); - } - CPPUNIT_ASSERT_EQUAL(0,g->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,g->getIJ(1,0)); - // - ee->decrRef(); - f->decrRef(); - g->decrRef(); - // - d->setIJ(6,0,9); - CPPUNIT_ASSERT_THROW(d->splitByValueRange(val2,val2+3,ee,f,g),INTERP_KERNEL::Exception); - // - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshSplitProfilePerType1() -{ - const int val0[5]={2,0,1,3,4}; - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->renumberCells(val0,false); - std::vector code; - std::vector idsInPflPerType; - std::vector pfls; - // - const int val1[3]={0,2,3}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(3,1); - d->setName("sup"); - std::copy(val1,val1+3,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); - const int expected1[6]={3,1,0, 4,2,1}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],code[i]); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(1,0)); - idsInPflPerType[0]->decrRef(); - idsInPflPerType[1]->decrRef(); - CPPUNIT_ASSERT_EQUAL(2,(int)pfls.size()); - CPPUNIT_ASSERT(std::string("sup")==pfls[0]->getName()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(0,0)); - CPPUNIT_ASSERT(std::string("sup")==pfls[1]->getName()); - CPPUNIT_ASSERT_EQUAL(2,pfls[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,pfls[1]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,pfls[1]->getIJ(1,0)); - pfls[0]->decrRef(); - pfls[1]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - const int val2[4]={0,2,3,4};// all quad4 are selected here ! So no profile for Quads - d=DataArrayInt::New(); - d->alloc(4,1); - std::copy(val2,val2+4,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); - const int expected2[6]={3,1,0, 4,3,-1}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],code[i]); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(3,idsInPflPerType[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(3,idsInPflPerType[1]->getIJ(2,0)); - idsInPflPerType[0]->decrRef(); - idsInPflPerType[1]->decrRef(); - CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(0,0)); - pfls[0]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - const int val3[3]={1,0,2};// all tri3 are selected here but not in the same order ! Profile requested for Tri3 - d=DataArrayInt::New(); - d->alloc(3,1); - std::copy(val3,val3+3,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); - const int expected3[6]={3,2,0, 4,1,1}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],code[i]); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(0,0)); - idsInPflPerType[0]->decrRef(); - idsInPflPerType[1]->decrRef(); - CPPUNIT_ASSERT_EQUAL(2,(int)pfls.size()); - CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(0,pfls[1]->getIJ(0,0)); - pfls[0]->decrRef(); - pfls[1]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - const int val4[2]={3,4};// all tri3 are selected here but not in the same order ! Profile requested for Tri3 - d=DataArrayInt::New(); - d->alloc(2,1); - std::copy(val4,val4+2,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(3,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); - const int expected4[3]={4,2,0}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],code[i]); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getIJ(1,0)); - idsInPflPerType[0]->decrRef(); - CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getIJ(1,0)); - pfls[0]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIBuildExplicitArrByRanges1() -{ - DataArrayInt *d=DataArrayInt::New(); - d->alloc(3,1); - const int vals1[3]={0,2,3}; - std::copy(vals1,vals1+3,d->getPointer()); - DataArrayInt *e=DataArrayInt::New(); - e->alloc(6,1); - const int vals2[6]={0,3,6,10,14,20}; - std::copy(vals2,vals2+6,e->getPointer()); - // - DataArrayInt *f=d->buildExplicitArrByRanges(e); - CPPUNIT_ASSERT_EQUAL(11,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const int expected1[11]={0,1,2,6,7,8,9,10,11,12,13}; - for(int i=0;i<11;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],f->getIJ(i,0)); - // - f->decrRef(); - e->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIComputeOffsets2() -{ - DataArrayInt *d=DataArrayInt::New(); - const int vals1[6]={3,5,1,2,0,8}; - const int expected1[7]={0,3,8,9,11,11,19}; - d->alloc(6,1); - std::copy(vals1,vals1+6,d->getPointer()); - d->computeOffsets2(); - CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],d->getIJ(0,i)); - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testMergeField3() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->getCoords()->setInfoOnComponent(0,"x [m]"); - m->getCoords()->setInfoOnComponent(1,"z [km]"); - m->setName("m"); - m->setDescription("desc"); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("f1"); - f1->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->setInfoOnComponent(0,"X [m]"); - arr->setInfoOnComponent(1,"YY [mm]"); - arr->fillWithValue(2.); - f1->setArray(arr); - arr->decrRef(); - m->decrRef(); - // - std::vector tmp(1); - tmp[0]=f1; - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::MergeFields(tmp); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - // - f1->decrRef(); - f2->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetDistributionOfTypes1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - const int tab1[5]={2,0,1,3,4}; - CPPUNIT_ASSERT_THROW(m->getDistributionOfTypes(),INTERP_KERNEL::Exception); - m->renumberCells(tab1,false); - std::vector code=m->getDistributionOfTypes(); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(3,code[0]); - CPPUNIT_ASSERT_EQUAL(2,code[1]); - CPPUNIT_ASSERT_EQUAL(-1,code[2]); - CPPUNIT_ASSERT_EQUAL(4,code[3]); - CPPUNIT_ASSERT_EQUAL(3,code[4]); - CPPUNIT_ASSERT_EQUAL(-1,code[5]); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testNorm2_1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setMesh(m); - m->decrRef(); - // - DataArrayDouble *d=DataArrayDouble::New(); - const double tab[10]={1.2,1.3,2.2,2.3,3.2,3.3,4.2,4.3,5.2,5.3}; - d->alloc(5,2); - std::copy(tab,tab+10,d->getPointer()); - f->setArray(d); - d->decrRef(); - f->checkCoherency(); - // - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.209371079592289,f->norm2(),1e-14); - // - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testNormMax1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setMesh(m); - m->decrRef(); - // - DataArrayDouble *d=DataArrayDouble::New(); - const double tab[10]={2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6}; - d->alloc(5,2); - std::copy(tab,tab+10,d->getPointer()); - f->setArray(d); - d->decrRef(); - f->checkCoherency(); - // - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f->normMax(),1e-14); - // - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testFindAndCorrectBadOriented3DExtrudedCells1() -{ - const double coords[38*3]={0.0011180339887498999, -0.0011755705045849499, 0.0, -0.0012331070204200001, -0.0011755705045849499, 0.0, -0.00067557050458494599, -0.00145964954842536, 0.0, -0.00050000000000000001, -0.00086602540378443902, 0.0, 0.00140211303259031, -0.00061803398874989504, 0.0, 0.00086602540378443902, -0.00050000000000000001, 0.0, 0.001, 0.0, 0.0, 0.00034561537182258202, 0.000269164072574575, 0.0, 0.0, 0.001, 0.0, -0.00050000000000000001, 0.00086602540378443902, 0.0, -0.000269164072574575, 0.00034561537182258202, 0.0, -0.001, 0.0, 0.0, -0.00086602540378443902, -0.00050000000000000001, 0.0, -0.00034561537182258202, -0.000269164072574575, 0.0, 0.0, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, 0.0, 0.000269164072574575, -0.00034561537182258202, 0.0, 0.0015, -6.01853107621011e-36, 0.0, 0.00056049747291484397, -0.00145964954842536, 0.0, 0.0011180339887498999, -0.0011755705045849499, 0.00050000000000000001, -0.0012331070204200001, -0.0011755705045849499, 0.00050000000000000001, -0.00067557050458494599, -0.00145964954842536, 0.00050000000000000001, -0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.00140211303259031, -0.00061803398874989504, 0.00050000000000000001, 0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, 0.001, 0.0, 0.00050000000000000001, 0.00034561537182258202, 0.000269164072574575, 0.00050000000000000001, 0.0, 0.001, 0.00050000000000000001, -0.00050000000000000001, 0.00086602540378443902, 0.00050000000000000001, -0.000269164072574575, 0.00034561537182258202, 0.00050000000000000001, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, -0.00034561537182258202, -0.000269164072574575, 0.00050000000000000001, 0.0, -0.001, 0.00050000000000000001, 0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.000269164072574575, -0.00034561537182258202, 0.00050000000000000001, 0.0015, -6.01853107621011e-36, 0.00050000000000000001, 0.00056049747291484397, -0.00145964954842536, 0.00050000000000000001}; - const int conn[56]={2, 1, 3, 21, 20, 22, 4, 0, 5, 23, 19, 24, 8, 9, 10, 27, 28, 29, 11, 12, 13, 30, 31, 32, 0, 18, 15, 5, 19, 37, 34, 24, 6, 17, 4, 5, 25, 36, 23, 24, 3, 14, 16, 13, 22, 33, 35, 32, 13, 16, 7, 10, 32, 35, 26, 29}; - const int connExp[64]={16, 2, 1, 3, 21, 20, 22, 16, 4, 0, 5, 23, 19, 24, 16, 8, 10, 9, 27, 29, 28, 16, 11, 13, 12, 30, 32, 31, 18, 0, 18, 15, 5, 19, 37, 34, 24,18, 6, 17, 4, 5, 25, 36, 23, 24, 18, 3, 13, 16, 14, 22, 32, 35, 33, 18, 13, 10, 7, 16, 32, 29, 26, 35}; - const int invalidCells[4]={2,3,6,7}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("Example",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(38,3); - std::copy(coords,coords+114,coo->getPointer()); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(8); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+6); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+12); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+18); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+24); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+32); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+40); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+48); - m->finishInsertingCells(); - // - DataArrayInt *v=m->findAndCorrectBadOriented3DExtrudedCells(); - CPPUNIT_ASSERT_EQUAL(4,v->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(v->begin(),v->end(),invalidCells)); - CPPUNIT_ASSERT(std::equal(connExp,connExp+64,m->getNodalConnectivity()->getConstPointer())); - v->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testConvertExtrudedPolyhedra1() -{ - const int conn[72]={1,2,3,4, 5,6,7,8,9,10,11,12, 13,14,15,16, 17,18,19,20,21,22, 23,24,25,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,65,66,67,68,69,70,71,72}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("Example",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(73,3); - coo->rearrange(1); coo->iota(0); coo->rearrange(3); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(9); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+12); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,6,conn+16); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+22); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,10,conn+28); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+38); - m->insertNextCell(INTERP_KERNEL::NORM_HEXGP12,12,conn+46); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,14,conn+58); - m->finishInsertingCells(); - // - m->convertExtrudedPolyhedra(); - DataArrayInt *da=m->getNodalConnectivity(); - DataArrayInt *dai=m->getNodalConnectivityIndex(); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,dai->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)159,da->getNbOfElems()); - // - const int expected1[159]={14,1,2,3,4, - 18,5,6,7,8,9,10,11,12, - 14,13,14,15,16, - 31,17,18,19,-1,20,22,21,-1,17,20,21,18,-1,18,21,22,19,-1,19,22,20,17, - 16,23,24,25,26,27,28, - 31,29,30,31,32,33,-1,34,38,37,36,35,-1,29,34,35,30,-1,30,35,36,31,-1,31,36,37,32,-1,32,37,38,33,-1,33,38,34,29, - 18,39,40,41,42,43,44,45,46, - 22,47,48,49,50,51,52,53,54,55,56,57,58, - 31,59,60,61,62,63,64,65,-1,66,72,71,70,69,68,67,-1,59,66,67,60,-1,60,67,68,61,-1,61,68,69,62,-1,62,69,70,63,-1,63,70,71,64,-1,64,71,72,65,-1,65,72,66,59}; - const int expected2[10]={0,5,14,19,42,49,86,95,108,159}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+159,da->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+10,dai->getConstPointer())); - m->checkCoherency2(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testNonRegressionCopyTinyStrings() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->getMeasureField(true); - f1->getArray()->setInfoOnComponent(0,"P [N/m^2]"); - DataArrayDouble *bary=m->getBarycenterAndOwner(); - MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(NO_TIME,false); - f2->setArray(bary); - CPPUNIT_ASSERT_THROW(f1->copyTinyAttrFrom(f2),INTERP_KERNEL::Exception); - m->decrRef(); - f1->decrRef(); - bary->decrRef(); - f2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDaDSetPartOfValuesAdv1() -{ - const double tab1[18]={3.,4.,5., 13.,14.,15., 23.,24.,25., 33.,34.,35., 43.,44.,45., 53.,54.,55.}; - const double tab2[9]={6.,7.,8., 16.,17.,18., 26.,27.,28.}; - const int tab3[6]={4,1, 2,2, 3,0}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(6,3); - std::copy(tab1,tab1+18,a->getPointer()); - DataArrayDouble *b=DataArrayDouble::New(); - b->alloc(3,3); - std::copy(tab2,tab2+9,b->getPointer()); - DataArrayInt *c=DataArrayInt::New(); - c->alloc(3,2); - std::copy(tab3,tab3+6,c->getPointer()); - // - a->setPartOfValuesAdv(b,c); - const double expected1[18]={3.,4.,5., 13.,14.,15., 26.,27.,28., 6.,7.,8., 16.,17.,18., 53.,54.,55.}; - std::equal(expected1,expected1+18,a->getConstPointer()); - // - a->decrRef(); - b->decrRef(); - c->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshBuildSetInstanceFromThis1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=m->buildSetInstanceFromThis(3); - CPPUNIT_ASSERT_EQUAL(m->getNodalConnectivity(),m2->getNodalConnectivity()); - CPPUNIT_ASSERT_EQUAL(m->getNodalConnectivityIndex(),m2->getNodalConnectivityIndex()); - CPPUNIT_ASSERT_EQUAL(m->getCoords(),m2->getCoords()); - m2->decrRef(); - m->decrRef(); - // - m=MEDCouplingUMesh::New("toto",2); - m2=m->buildSetInstanceFromThis(3); - CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfCells()); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshMergeMeshesCVW1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("toto",2); - MEDCouplingUMesh *m3=MEDCouplingUMesh::MergeUMeshes(m,m2); - m3->setName(m->getName().c_str()); - CPPUNIT_ASSERT(m->isEqual(m3,1e-12)); - m3->decrRef(); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testChangeUnderlyingMeshWithCMesh1() -{ - MEDCouplingCMesh* mesh=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX=DataArrayDouble::New(); - double arrX[4] = { -1., 1., 2., 4. }; - coordsX->useArray(arrX,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY=DataArrayDouble::New(); - double arrY[4] = { -2., 2., 4., 8. }; - coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ=DataArrayDouble::New(); - double arrZ[4] = { -3., 3., 6., 12. }; - coordsZ->useArray(arrZ,false, CPP_DEALLOC,4,1); - mesh->setCoords(coordsX,coordsY,coordsZ); - coordsX->decrRef(); - coordsY->decrRef(); - coordsZ->decrRef(); - MEDCouplingMesh *mesh2=mesh->deepCpy(); - // - static const int ids1[9]={0,1,2,10,11,12,20,21,22}; - for(const int *myId=ids1;myId!=ids1+9;myId++) - { - MEDCouplingFieldDouble *f=mesh->getMeasureField(true); - f->changeUnderlyingMesh(mesh2,*myId,1e-12); - f->decrRef(); - } - mesh2->setName("uuuu"); - for(const int *myId=ids1+1;myId!=ids1+9;myId++) - { - MEDCouplingFieldDouble *f=mesh->getMeasureField(true); - f->changeUnderlyingMesh(mesh2,*myId,1e-12); - f->decrRef(); - } - // - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADFindCommonTuples1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,1); - const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; - std::copy(array1,array1+6,da->getPointer()); - DataArrayInt *c=0,*cI=0; - // nbOftuples=1 - da->findCommonTuples(1e-2,-1,c,cI); - const int expected1[3]={0,3,4}; - const int expected2[2]={0,3}; - CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - da->findCommonTuples(2e-1,-1,c,cI); - const int expected3[5]={0,3,4,1,2}; - const int expected4[3]={0,3,5}; - CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // nbOftuples=2 - da->alloc(6,2); - const double array2[12]={2.3,2.3,1.2,1.2,1.3,1.3,2.3,2.3,2.301,2.301,0.8,0.8}; - std::copy(array2,array2+12,da->getPointer()); - da->findCommonTuples(1e-2,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - da->findCommonTuples(2e-1,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // nbOftuples=3 - da->alloc(6,3); - const double array3[18]={2.3,2.3,2.3,1.2,1.2,1.2,1.3,1.3,1.3,2.3,2.3,2.3,2.301,2.301,2.301,0.8,0.8,0.8}; - std::copy(array3,array3+18,da->getPointer()); - da->findCommonTuples(1e-2,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - da->findCommonTuples(2e-1,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - const double array11[6]={2.3,1.2,1.3,2.4,2.5,0.8}; - da->alloc(6,1); - std::copy(array11,array11+6,da->getPointer()); - // nbOftuples=1, no common groups - da->findCommonTuples(1e-2,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)0,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)1,cI->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); - - da->alloc(6,5); //bad NumberOfComponents - CPPUNIT_ASSERT_THROW(da->findCommonTuples(1e-2,-1,c,cI),INTERP_KERNEL::Exception); - - c->decrRef(); - cI->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testDABack1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,1); - const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; - std::copy(array1,array1+6,da->getPointer()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.8,da->back(),1e-14); - da->rearrange(2); - CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); - da->alloc(0,1); - CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); - da->decrRef(); - // - DataArrayInt *da2=DataArrayInt::New(); - da2->alloc(4,1); - const int array2[4]={4,7,8,2}; - std::copy(array2,array2+4,da2->getPointer()); - CPPUNIT_ASSERT_EQUAL(2,da2->back()); - da2->rearrange(2); - CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); - da2->alloc(0,1); - CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); - da2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADGetDifferentValues1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,1); - const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; - std::copy(array1,array1+6,da->getPointer()); - // - const double expected1[4]={2.301,1.2,1.3,0.8}; - DataArrayDouble *dv=da->getDifferentValues(1e-2); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,dv->getNbOfElems()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],dv->getIJ(i,0),1e-14); - dv->decrRef(); - // - dv=da->getDifferentValues(2e-1); - const double expected2[3]={2.301,1.3,0.8}; - CPPUNIT_ASSERT_EQUAL((std::size_t)3,dv->getNbOfElems()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],dv->getIJ(i,0),1e-14); - dv->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2() -{ - const int arr[5]={0,3, 5,7,9}; - const int arrI[3]={0,2,5}; - DataArrayInt *a=DataArrayInt::New(); - a->alloc(5,1); - std::copy(arr,arr+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - b->alloc(3,1); - std::copy(arrI,arrI+3,b->getPointer()); - int newNbTuple=-1; - DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a->begin(),b->begin(),b->end(),newNbTuple); - const int expected[10]={0,1,2,0,3,4,5,4,6,4}; - CPPUNIT_ASSERT_EQUAL((std::size_t)10,ret->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(7,newNbTuple); - CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer())); - CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a->begin(),b->begin(),b->end(),newNbTuple),INTERP_KERNEL::Exception); - ret->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADIReverse1() -{ - const int arr[6]={0,3,5,7,9,2}; - DataArrayInt *a=DataArrayInt::New(); - a->alloc(6,1); - std::copy(arr,arr+6,a->getPointer()); - CPPUNIT_ASSERT_EQUAL(2,a->back()); - a->reverse(); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(arr[5-i],a->getIJ(i,0)); - a->alloc(5,1); - std::copy(arr,arr+5,a->getPointer()); - a->reverse(); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_EQUAL(arr[4-i],a->getIJ(i,0)); - a->decrRef(); - // - const double arr2[6]={0.,3.,5.,7.,9.,2.}; - DataArrayDouble *b=DataArrayDouble::New(); - b->alloc(6,1); - std::copy(arr2,arr2+6,b->getPointer()); - b->reverse(); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[5-i],b->getIJ(i,0),1e-14); - b->alloc(5,1); - std::copy(arr,arr+5,b->getPointer()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,b->back(),1e-14); - b->reverse(); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[4-i],b->getIJ(i,0),1e-14); - b->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetNodeIdsInUse1() -{ - MEDCouplingUMesh *m0=build2DTargetMesh_1(); - const int CellIds[2]={1,2}; - MEDCouplingUMesh *m1=static_cast(m0->buildPartOfMySelf(CellIds,CellIds+2,true)); - int newNbOfNodes=-1; - DataArrayInt *arr=m1->getNodeIdsInUse(newNbOfNodes); - const int expected[9]={-1,0,1,-1,2,3,-1,-1,-1}; - CPPUNIT_ASSERT_EQUAL(4,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL((std::size_t)9,arr->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected,expected+9,arr->getConstPointer())); - DataArrayInt *arr2=arr->invertArrayO2N2N2O(newNbOfNodes); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,arr2->getNbOfElems()); - const int expected2[4]={1,2,4,5}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+4,arr2->getConstPointer())); - arr2->decrRef(); - arr->decrRef(); - m1->decrRef(); - m0->decrRef(); -} - -void MEDCouplingBasicsTest4::testBuildDescendingConnec2() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); - const int expected1[18]={1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); - const int expected2[6]={0,4,7,10,14,18}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); - const int expected3[14]={0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); - const int expected4[18]={0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); - DataArrayInt *conn=mesh2->getNodalConnectivity(); - DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); - const int expected5[14]={0,3,6,9,12,15,18,21,24,27,30,33,36,39}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); - const int expected6[39]={1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp1() -{ - MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); - DataArrayDouble *coordX=DataArrayDouble::New(); - const double arrX[4]={-1., 1., 2., 4.}; - coordX->alloc(4,1); - std::copy(arrX,arrX+4,coordX->getPointer()); - m1c->setCoordsAt(0,coordX); - DataArrayDouble *coordY=DataArrayDouble::New(); - const double arrY[4]={-2., 2., 4., 8.}; - coordY->alloc(4,1); - std::copy(arrY,arrY+4,coordY->getPointer()); - m1c->setCoordsAt(1,coordY); - MEDCouplingUMesh *m1=m1c->buildUnstructured(); - const int subPart1[3]={3,4,5}; - MEDCouplingUMesh *m1bis=static_cast(m1->buildPartOfMySelf(subPart1,subPart1+3,false)); - MEDCouplingUMesh *m2tmp=static_cast(m1->deepCpy()); - const int subPart2[3]={0,1,2}; - MEDCouplingUMesh *m2=static_cast(m2tmp->buildPartOfMySelf(subPart2,subPart2+3,false)); - const double vec[2]={0.5,0.5}; - m2->translate(vec); - // End of construction of input meshes m1bis and m2 -> start of specific part of the test - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1bis,m2,1e-10,d1,d2); - const int expected1[8]={0,0,1,1,1,2,2,2}; - const int expected2[8]={0,-1,0,1,-1,1,2,-1}; - CPPUNIT_ASSERT_EQUAL(8,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+8,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+8,d2->getConstPointer())); - const int expected3[44]={5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14}; - const int expected4[9]={0,5,12,17,22,28,33,38,44}; - const double expected5[44]={-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5}; - CPPUNIT_ASSERT_EQUAL(44,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+44,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<44;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m2->decrRef(); - m2tmp->decrRef(); - m1bis->decrRef(); - m1->decrRef(); - coordX->decrRef(); - coordY->decrRef(); - m1c->decrRef(); -} - -void MEDCouplingBasicsTest4::testFindNodesOnLine1() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const double pt[2]={-0.3,-0.3}; - const double pt2[3]={0.,0.,0.}; - const double pt3[3]={-0.3,0.,0.}; - const double vec[2]={0.,1.}; - const double vec2[3]={1.,0.,0.}; - const double vec3[3]={0.,1.,1.}; - const int expected1[3]={0,3,6}; - std::vector res; - mesh->findNodesOnLine(pt,vec,1e-12,res); - CPPUNIT_ASSERT_EQUAL(3,(int)res.size()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,res.begin())); - res.clear(); - // - mesh->changeSpaceDimension(3); - mesh->rotate(pt2,vec2,M_PI/4.); - mesh->findNodesOnLine(pt3,vec3,1e-12,res); - CPPUNIT_ASSERT_EQUAL(3,(int)res.size()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,res.begin())); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp2() -{ - MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); - DataArrayDouble *coordsX1=DataArrayDouble::New(); - const double arrX1[4]={ 0., 1., 1.5, 2. }; - coordsX1->alloc(4,1); - std::copy(arrX1,arrX1+4,coordsX1->getPointer()); - m1c->setCoordsAt(0,coordsX1); - DataArrayDouble *coordsY1=DataArrayDouble::New(); - const double arrY1[3]={ 0., 1.5, 3.}; - coordsY1->alloc(3,1); - std::copy(arrY1,arrY1+3,coordsY1->getPointer()); - m1c->setCoordsAt(1,coordsY1); - MEDCouplingUMesh *m1=m1c->buildUnstructured(); - // - MEDCouplingCMesh *m2c=MEDCouplingCMesh::New(); - DataArrayDouble *coordsX2=DataArrayDouble::New(); - const double arrX2[3]={ 0., 1., 2. }; - coordsX2->alloc(3,1); - std::copy(arrX2,arrX2+3,coordsX2->getPointer()); - m2c->setCoordsAt(0,coordsX2); - DataArrayDouble *coordsY2=DataArrayDouble::New(); - coordsY2->alloc(3,1); - const double arrY2[3]={ 0., 1., 3.}; - std::copy(arrY2,arrY2+3,coordsY2->getPointer()); - m2c->setCoordsAt(1,coordsY2); - MEDCouplingUMesh *m2=m2c->buildUnstructured(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - const int expected1[9]={0,0,1,1,2,2,3,4,5}; - const int expected2[9]={0,2,1,3,1,3,2,3,3}; - CPPUNIT_ASSERT_EQUAL(9,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+9,d2->getConstPointer())); - const int expected3[45]={5,16,13,12,15,5,15,4,5,16,5,21,2,13,16,5,16,5,6,21,5,17,14,2,21,5,21,6,7,17,5,4,18,19,5,5,5,19,10,6,5,6,10,20,7}; - const int expected4[10]={0,5,10,15,20,25,30,35,40,45}; - const double expected5[44]={0.0,0.0,1.0,0.0,1.5,0.0,2.0,0.0,0.0,1.5,1.0,1.5,1.5,1.5,2.0,1.5,0.0,3.0,1.0,3.0,1.5,3.0,2.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,2.0,1.0,0.0,3.0,1.0,3.0,2.0,3.0,1.5,1.0}; - CPPUNIT_ASSERT_EQUAL(45,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+45,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+10,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<44;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m1c->decrRef(); - coordsX1->decrRef(); - coordsY1->decrRef(); - m1->decrRef(); - m2c->decrRef(); - coordsX2->decrRef(); - coordsY2->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testBuildPartOfMySelfSafe1() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const int input1[4]={0,-1,4,2}; - const int input2[4]={0,4,5,4}; - CPPUNIT_ASSERT_THROW(mesh->buildPartOfMySelf(input1,input1+4,true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mesh->buildPartOfMySelf(input2,input2+4,true),INTERP_KERNEL::Exception); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3() -{ - double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; - int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(8); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(25,2); - std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - double m2Coords[30]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.}; - int m2Conn[32]={0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13}; - MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); - m2->setMeshDimension(2); - m2->allocateCells(8); - for(int i=0;i<8;i++) - m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m2Conn+4*i); - m2->finishInsertingCells(); - DataArrayDouble *myCoords2=DataArrayDouble::New(); - myCoords2->alloc(15,2); - std::copy(m2Coords,m2Coords+30,myCoords2->getPointer()); - m2->setCoords(myCoords2); - myCoords2->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - m3->unPolyze(); - const int expected1[16]={0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7}; - const int expected2[16]={0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1}; - CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer())); - const int expected3[136]={6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103}; - const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136}; - const double expected5[208]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0}; - CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<208;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m1->decrRef(); - m2->decrRef(); -} diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx deleted file mode 100644 index 3e8738255..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTEST4_HXX__ -#define __MEDCOUPLINGBASICSTEST4_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest4 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest4); - CPPUNIT_TEST( testDescriptionInMeshTimeUnit1 ); - CPPUNIT_TEST( testMultiFields1 ); - CPPUNIT_TEST( testFieldOverTime1 ); - CPPUNIT_TEST( testDAICheckAndPreparePermutation1 ); - CPPUNIT_TEST( testDAIChangeSurjectiveFormat1 ); - CPPUNIT_TEST( testUMeshGetCellIdsLyingOnNodes1 ); - CPPUNIT_TEST( testUMeshFindCellIdsOnBoundary1 ); - CPPUNIT_TEST( testMeshSetTime1 ); - CPPUNIT_TEST( testApplyFuncTwo1 ); - CPPUNIT_TEST( testApplyFuncThree1 ); - CPPUNIT_TEST( testFillFromAnalyticTwo1 ); - CPPUNIT_TEST( testFillFromAnalyticThree1 ); - CPPUNIT_TEST( testDAUnitVar1 ); - CPPUNIT_TEST( testGaussCoordinates1 ); - CPPUNIT_TEST( testP2Localization1 ); - CPPUNIT_TEST( testP2Localization2 ); - CPPUNIT_TEST( testGetValueOn2 ); - CPPUNIT_TEST( testDAIGetIdsNotEqual1 ); - CPPUNIT_TEST( testDAIComputeOffsets1 ); - CPPUNIT_TEST( testUMeshHexagonPrism1 ); - CPPUNIT_TEST( testDADCheckIsMonotonic ); - CPPUNIT_TEST( testCheckCoherencyDeeper1 ); - CPPUNIT_TEST( testUnPolyze2 ); - CPPUNIT_TEST( testDACpyFrom1 ); - CPPUNIT_TEST( testDAITransformWithIndArr1 ); - CPPUNIT_TEST( testDAIBuildPermArrPerLevel1 ); - CPPUNIT_TEST( testDAIOperations1 ); - CPPUNIT_TEST( testEmulateMEDMEMBDC1 ); - CPPUNIT_TEST( testGetLevArrPerCellTypes1 ); - CPPUNIT_TEST( testSortCellsInMEDFileFrmt1 ); - CPPUNIT_TEST( testBuildPartAndReduceNodes1 ); - CPPUNIT_TEST( testDAITransformWithIndArrR1 ); - CPPUNIT_TEST( testDAISplitByValueRange1 ); - CPPUNIT_TEST( testUMeshSplitProfilePerType1 ); - CPPUNIT_TEST( testDAIBuildExplicitArrByRanges1 ); - CPPUNIT_TEST( testDAIComputeOffsets2 ); - CPPUNIT_TEST( testMergeField3 ); - CPPUNIT_TEST( testGetDistributionOfTypes1 ); - CPPUNIT_TEST( testNorm2_1 ); - CPPUNIT_TEST( testNormMax1 ); - CPPUNIT_TEST( testFindAndCorrectBadOriented3DExtrudedCells1 ); - CPPUNIT_TEST( testConvertExtrudedPolyhedra1 ); - CPPUNIT_TEST( testNonRegressionCopyTinyStrings ); - CPPUNIT_TEST( testDaDSetPartOfValuesAdv1 ); - CPPUNIT_TEST( testUMeshBuildSetInstanceFromThis1 ); - CPPUNIT_TEST( testUMeshMergeMeshesCVW1 ); - CPPUNIT_TEST( testDADFindCommonTuples1 ); - CPPUNIT_TEST( testDABack1 ); - CPPUNIT_TEST( testDADGetDifferentValues1 ); - CPPUNIT_TEST( testDAIBuildOld2NewArrayFromSurjectiveFormat2 ); - CPPUNIT_TEST( testDADIReverse1 ); - CPPUNIT_TEST( testGetNodeIdsInUse1 ); - CPPUNIT_TEST( testBuildDescendingConnec2 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp1 ); - CPPUNIT_TEST( testFindNodesOnLine1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp2 ); - CPPUNIT_TEST( testBuildPartOfMySelfSafe1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp3 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testDescriptionInMeshTimeUnit1(); - void testMultiFields1(); - void testFieldOverTime1(); - void testDAICheckAndPreparePermutation1(); - void testDAIChangeSurjectiveFormat1(); - void testUMeshGetCellIdsLyingOnNodes1(); - void testUMeshFindCellIdsOnBoundary1(); - void testMeshSetTime1(); - void testApplyFuncTwo1(); - void testApplyFuncThree1(); - void testFillFromAnalyticTwo1(); - void testFillFromAnalyticThree1(); - void testDAUnitVar1(); - void testGaussCoordinates1(); - void testQ1Localization1(); - void testP2Localization1(); - void testP2Localization2(); - void testGetValueOn2(); - void testDAIGetIdsNotEqual1(); - void testDAIComputeOffsets1(); - void testUMeshHexagonPrism1(); - void testDADCheckIsMonotonic(); - void testCheckCoherencyDeeper1(); - void testUnPolyze2(); - void testDACpyFrom1(); - void testDAITransformWithIndArr1(); - void testDAIBuildPermArrPerLevel1(); - void testDAIOperations1(); - void testEmulateMEDMEMBDC1(); - void testGetLevArrPerCellTypes1(); - void testSortCellsInMEDFileFrmt1(); - void testBuildPartAndReduceNodes1(); - void testDAITransformWithIndArrR1(); - void testDAISplitByValueRange1(); - void testUMeshSplitProfilePerType1(); - void testDAIBuildExplicitArrByRanges1(); - void testDAIComputeOffsets2(); - void testMergeField3(); - void testGetDistributionOfTypes1(); - void testNorm2_1(); - void testNormMax1(); - void testFindAndCorrectBadOriented3DExtrudedCells1(); - void testConvertExtrudedPolyhedra1(); - void testNonRegressionCopyTinyStrings(); - void testDaDSetPartOfValuesAdv1(); - void testUMeshBuildSetInstanceFromThis1(); - void testUMeshMergeMeshesCVW1(); - void testChangeUnderlyingMeshWithCMesh1(); - void testDADFindCommonTuples1(); - void testDABack1(); - void testDADGetDifferentValues1(); - void testDAIBuildOld2NewArrayFromSurjectiveFormat2(); - void testDADIReverse1(); - void testGetNodeIdsInUse1(); - void testBuildDescendingConnec2(); - void testIntersect2DMeshesTmp1(); - void testFindNodesOnLine1(); - void testIntersect2DMeshesTmp2(); - void testBuildPartOfMySelfSafe1(); - void testIntersect2DMeshesTmp3(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx deleted file mode 100644 index 0dc0e8c01..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ /dev/null @@ -1,2059 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest5.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldOverTime.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest5::testUMeshTessellate2D1() -{ - double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; - int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(8); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(25,2); - std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - MEDCouplingUMesh *m11=static_cast(m1->deepCpy()); - m11->tessellate2D(1.); - CPPUNIT_ASSERT(m11->getCoords()->isEqual(*m11->getCoords(),1e-12)); - const int expected1[48]={5,0,3,11,1,5,3,4,12,2,1,11,5,5,15,3,0,5,6,16,4,3,15,5,5,5,0,7,19,5,6,5,19,7,8,20,5,0,1,23,7,5,1,2,24,8,7,23}; - const int expected2[9]={0,5,12,17,24,29,36,41,48}; - CPPUNIT_ASSERT_EQUAL(48,m11->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m11->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+48,m11->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+9,m11->getNodalConnectivityIndex()->getConstPointer())); - m11->decrRef(); - // - MEDCouplingUMesh *m12=static_cast(m1->deepCpy()); - m12->tessellate2D(0.5); - CPPUNIT_ASSERT_EQUAL(41,m12->getNumberOfNodes()); - const int expected3[60]={5,0,3,25,26,1,5,3,4,27,28,2,1,26,25,5,5,29,30,3,0,5,6,31,32,4,3,30,29,5,5,5,0,7,33,34,5,6,5,34,33,7,8,35,36,5,0,1,37,38,7,5,1,2,39,40,8,7,38,37}; - const int expected4[9]={0,6,15,21,30,36,45,51,60}; - const double expected5[82]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.479425538604203,0.8775825618903728,0.8414709848078964,0.54030230586814,0.7191383079063044,1.3163738428355591,1.2622064772118446,0.8104534588022099,-0.877582561890373,0.4794255386042027,-0.5403023058681399,0.8414709848078964,-1.3163738428355596,0.7191383079063038,-0.8104534588022098,1.2622064772118446,-0.4794255386042031,-0.8775825618903728,-0.8414709848078965,-0.5403023058681399,-0.7191383079063045,-1.3163738428355591,-1.2622064772118449,-0.8104534588022098,0.8775825618903729,-0.47942553860420295,0.54030230586814,-0.8414709848078964,1.3163738428355594,-0.7191383079063043,0.8104534588022099,-1.2622064772118446}; - for(int i=0;i<82;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m12->getCoords()->getIJ(0,i),1e-12); - CPPUNIT_ASSERT_EQUAL(60,m12->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m12->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+60,m12->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m12->getNodalConnectivityIndex()->getConstPointer())); - m12->decrRef(); - // - m1->decrRef(); -} - -void MEDCouplingBasicsTest5::testUMeshTessellate2DCurve1() -{ - // A quarter of circle: - double mcoords[6] = {0.4,0.0, 0.0,-0.4, 0.283,-0.283}; - int mconnec[3] = {0,1,2}; - - MEDCouplingUMesh *m1 = MEDCouplingUMesh::New(); - m1->setMeshDimension(1); - m1->allocateCells(1); - m1->insertNextCell(INTERP_KERNEL::NORM_SEG3, 3, mconnec); - - DataArrayDouble *myCoords = DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(mcoords,mcoords+6,myCoords->getPointer()); - m1->setCoords(myCoords); - myCoords->decrRef(); - - MEDCouplingUMesh *m2 = static_cast(m1->deepCpy()); - m2->tessellate2DCurve(0.1); - CPPUNIT_ASSERT_NO_THROW(m2->checkCoherency1(0.0)); // eps param not used - m1->decrRef(); - m2->decrRef(); -} - -/*! - * idem MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3 except that m1 and m2 are permuted on call to MEDCouplingUMesh::Intersect2DMeshes - */ -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp4() -{ - double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; - int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(8); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(25,2); - std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - double m2Coords[30]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.}; - int m2Conn[32]={0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13}; - MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); - m2->setMeshDimension(2); - m2->allocateCells(8); - for(int i=0;i<8;i++) - m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m2Conn+4*i); - m2->finishInsertingCells(); - DataArrayDouble *myCoords2=DataArrayDouble::New(); - myCoords2->alloc(15,2); - std::copy(m2Coords,m2Coords+30,myCoords2->getPointer()); - m2->setCoords(myCoords2); - myCoords2->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m2,m1,1e-10,d1,d2); - m3->unPolyze(); - const int expected1[16]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7}; - const int expected2[16]={0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1}; - CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer())); - const int expected3[136]={6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103}; - const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136}; - const double expected5[208]={0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635}; - CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<208;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest5::testGetCellIdsCrossingPlane1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - const double vec[3]={-0.07,1.,0.07}; - const double origin[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids1=mesh3D->getCellIdsCrossingPlane(origin,vec,1e-10); - CPPUNIT_ASSERT_EQUAL(9,ids1->getNumberOfTuples()); - const int expected1[9]={1,3,4,7,9,10,13,15,16}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids1->getConstPointer())); - const double vec2[3]={0.,0.,1.}; - DataArrayInt *ids2=mesh3D->getCellIdsCrossingPlane(origin,vec2,1e-10); - const int expected2[6]={6,7,8,9,10,11}; - CPPUNIT_ASSERT_EQUAL(6,ids2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,ids2->getConstPointer())); - ids1->decrRef(); - ids2->decrRef(); - mesh3D->decrRef(); - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildSlice3D1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - mesh2D->decrRef(); - // First slice in the middle of 3D cells - const double vec1[3]={-0.07,1.,0.07}; - const double origin1[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids=0; - MEDCouplingUMesh *slice1=mesh3D->buildSlice3D(origin1,vec1,1e-10,ids); - const int expected1[9]={1,3,4,7,9,10,13,15,16}; - const int expected2[47]={5,42,41,40,43,44,5,42,46,45,41,5,44,43,40,47,48,5,49,42,44,50,5,49,51,46,42,5,50,44,48,52,5,53,49,50,54,5,53,55,51,49,5,54,50,52,56}; - const int expected3[10]={0,6,11,17,22,27,32,37,42,47}; - const double expected4[171]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.}; - CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(57,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(9,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(47,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+47,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+10,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<171;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // 2nd slice based on already existing nodes of mesh3D. - const double vec2[3]={0.,3.,1.}; - const double origin2[3]={2.5,1.,3.}; - slice1=mesh3D->buildSlice3D(origin2,vec2,1e-10,ids); - const int expected5[49]={5,50,10,4,51,5,50,52,7,10,5,51,4,5,53,5,54,50,51,55,56,5,54,57,52,50,5,56,55,51,53,58,5,38,59,56,54,43,5,54,57,46,43,5,38,59,56,58,48}; - const int expected6[10]={0,5,10,15,21,26,32,38,43,49}; - const double expected7[180]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,1.,3.,0.,2.,2.,0.,2.,3.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,2.,1.6666666666666667,1.,1.,1.6666666666666667,1.,3.,1.6666666666666667,1.,0.,1.6666666666666667,1.,2.,1.3333333333333335,2.,1.,1.5,1.5,1.,1.3333333333333333,2.,3.,1.3333333333333335,2.,0.,1.3333333333333335,2.,1.,1.25,2.25}; - CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(60,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(9,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(49,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected5,expected5+49,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+10,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<180;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // 3rd slice based on shared face of mesh3D. - const double vec3[3]={0.,0.,1.}; - const double origin3[3]={2.5,1.,2.}; - slice1=mesh3D->buildSlice3D(origin3,vec3,1e-10,ids); - const int expected8[12]={6,7,8,9,10,11,12,13,14,15,16,17}; - const int expected9[68]={5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28,5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28}; - const int expected10[13]={0,5,12,17,22,29,34,39,46,51,56,63,68}; - const double expected11[135]={0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.}; - CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(45,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(12,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(12,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(68,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(13,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected8,expected8+12,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected9,expected9+68,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected10,expected10+13,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<135;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected11[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // - mesh3D->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildSlice3DSurf1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - mesh2D->decrRef(); - DataArrayInt *a=DataArrayInt::New(),*b=DataArrayInt::New(),*c=DataArrayInt::New(),*d=DataArrayInt::New(); - mesh2D=mesh3D->buildDescendingConnectivity(a,b,c,d); - a->decrRef(); b->decrRef(); c->decrRef(); d->decrRef(); - mesh3D->decrRef(); - // - const double vec1[3]={-0.07,1.,0.07}; - const double origin1[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids=0; - MEDCouplingUMesh *slice1=mesh2D->buildSlice3DSurf(origin1,vec1,1e-10,ids); - const int expected1[25]={6,8,10,11,13,18,19,21,23,25,26,38,41,43,47,49,52,53,64,67,69,73,75,78,79}; - const int expected2[75]={1,40,41,1,42,41,1,40,43,1,44,43,1,42,44,1,45,41,1,42,46,1,46,45,1,47,40,1,47,48,1,44,48,1,49,42,1,44,50,1,49,50,1,49,51,1,51,46,1,48,52,1,50,52,1,53,49,1,50,54,1,53,54,1,53,55,1,55,51,1,52,56,1,54,56}; - const int expected3[26]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75}; - const double expected4[171]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.}; - CPPUNIT_ASSERT_EQUAL(1,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(57,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(25,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(25,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(75,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(26,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+25,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+47,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+26,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<171;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // - const double vec2[3]={0.,0.,1.}; - const double origin2[3]={2.5,1.,2.}; - slice1=mesh2D->buildSlice3DSurf(origin2,vec2,1e-10,ids); - const int expected5[68]={32,32,32,32,33,34,35,36,37,38,39,40,41,42,43,43,43,43,43,43,44,44,44,44,45,46,47,47,47,47,48,49,50,51,52,53,53,53,53,53,53,54,54,54,54,55,56,57,59,60,61,62,63,64,65,66,67,68,71,72,74,75,76,77,78,81,82,83}; - const int expected6[204]={1,15,18,1,18,16,1,16,26,1,26,15,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,16,21,1,21,28,1,28,22,1,22,19,1,19,17,1,17,16,1,16,18,1,18,20,1,20,21,1,21,16,1,20,21,1,18,20,1,28,21,1,21,24,1,24,25,1,25,28,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,26,16,1,16,17,1,17,19,1,19,22,1,22,23,1,23,26,1,22,28,1,28,29,1,29,27,1,27,22,1,27,22,1,29,27,1,28,29,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,20,21,1,18,20,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,27,22,1,29,27,1,28,29}; - const int expected7[69]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204}; - const double expected8[135]={0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.}; - CPPUNIT_ASSERT_EQUAL(1,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(45,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(68,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(68,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(204,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(69,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected5,expected5+68,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+171,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected7,expected7+69,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<135;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected8[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayDoubleAdvSetting1() -{ - const double data1[14]={1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.}; - const double data2[10]={8.,38.,9.,39.,0.,30.,11.,41.,12.,42.}; - const char *comps[2]={"comp1","comp2"}; - std::vector compsCpp(comps,comps+2); - DataArrayDouble *da=DataArrayDouble::New(); - DataArrayDouble *tmp=0; - da->setInfoAndChangeNbOfCompo(compsCpp); - da->setName("da"); - da->alloc(7,2); - compsCpp.pop_back(); - CPPUNIT_ASSERT_THROW(da->setInfoAndChangeNbOfCompo(compsCpp),INTERP_KERNEL::Exception); - std::copy(data1,data1+14,da->getPointer()); - // - std::vector > p(3); - p[0].first=0; p[0].second=3; p[1].first=3; p[1].second=5; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - CPPUNIT_ASSERT(tmp->isEqual(*da,1e-14)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=3; p[1].second=4; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const double expected1[10]={1.,11.,2.,12.,4.,14.,6.,16.,7.,17.}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp->getIJ(0,i),1e-14); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=6; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const double expected2[10]={1.,11.,2.,12.,1.,11.,2.,12.,6.,16.}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp->getIJ(0,i),1e-14); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=-1; p[1].second=2; p[2].first=5; p[2].second=6; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=8; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - // - DataArrayDouble *da2=DataArrayDouble::New(); - da2->alloc(5,2); - std::copy(data2,data2+10,da2->getPointer()); - // - DataArrayDouble *dac=da->deepCpy(); - dac->setContigPartOfSelectedValues2(1,da2,2,4,1); - const double expected3[14]={1.,11.,0.,30.,11.,41.,4.,14.,5.,15.,6.,16.,7.,17.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - // - dac=da->deepCpy(); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,0,5,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(0,da2,4,6,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,5,0,1),INTERP_KERNEL::Exception); - dac->setContigPartOfSelectedValues2(3,da2,1,5,1); - const double expected4[14]={1.,11.,2.,12.,3.,13.,9.,39.,0.,30.,11.,41.,12.,42.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - // - DataArrayInt *ids=DataArrayInt::New(); - ids->alloc(3,1); - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,0); ids->setIJ(2,0,4); - dac->setContigPartOfSelectedValues(2,da2,ids); - const double expected5[14]={1.,11.,2.,12.,0.,30.,8.,38.,12.,42.,6.,16.,7.,17.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - // - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,5); ids->setIJ(2,0,4); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,-1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(5,da2,ids),INTERP_KERNEL::Exception); - dac->decrRef(); - // - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - dac=da->deepCpy(); - dac->setContigPartOfSelectedValues(4,da2,ids); - const double expected6[14]={1.,11.,2.,12.,3.,13.,4.,14.,0.,30.,0.,30.,9.,39.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected6[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - ids->decrRef(); - // - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayIntAdvSetting1() -{ - const int data1[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - const int data2[10]={8,38,9,39,0,30,11,41,12,42}; - const char *comps[2]={"comp1","comp2"}; - std::vector compsCpp(comps,comps+2); - DataArrayInt *da=DataArrayInt::New(); - DataArrayInt *tmp=0; - da->setInfoAndChangeNbOfCompo(compsCpp); - da->setName("da"); - da->alloc(7,2); - compsCpp.pop_back(); - CPPUNIT_ASSERT_THROW(da->setInfoAndChangeNbOfCompo(compsCpp),INTERP_KERNEL::Exception); - std::copy(data1,data1+14,da->getPointer()); - // - std::vector > p(3); - p[0].first=0; p[0].second=3; p[1].first=3; p[1].second=5; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - CPPUNIT_ASSERT(tmp->isEqual(*da)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=3; p[1].second=4; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const int expected1[10]={1,11,2,12,4,14,6,16,7,17}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],tmp->getIJ(0,i)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=6; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const int expected2[10]={1,11,2,12,1,11,2,12,6,16}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],tmp->getIJ(0,i)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=-1; p[1].second=2; p[2].first=5; p[2].second=6; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=8; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - // - DataArrayInt *da2=DataArrayInt::New(); - da2->alloc(5,2); - std::copy(data2,data2+10,da2->getPointer()); - // - DataArrayInt *dac=da->deepCpy(); - dac->setContigPartOfSelectedValues2(1,da2,2,4,1); - const int expected3[14]={1,11,0,30,11,41,4,14,5,15,6,16,7,17}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],dac->getIJ(0,i)); - dac->decrRef(); - // - dac=da->deepCpy(); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,0,5,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(0,da2,4,6,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,5,0,1),INTERP_KERNEL::Exception); - dac->setContigPartOfSelectedValues2(3,da2,1,5,1); - const int expected4[14]={1,11,2,12,3,13,9,39,0,30,11,41,12,42}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],dac->getIJ(0,i)); - dac->decrRef(); - // - DataArrayInt *ids=DataArrayInt::New(); - ids->alloc(3,1); - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,0); ids->setIJ(2,0,4); - dac->setContigPartOfSelectedValues(2,da2,ids); - const int expected5[14]={1,11,2,12,0,30,8,38,12,42,6,16,7,17}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected5[i],dac->getIJ(0,i)); - dac->decrRef(); - // - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,5); ids->setIJ(2,0,4); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,-1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(5,da2,ids),INTERP_KERNEL::Exception); - dac->decrRef(); - // - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - dac=da->deepCpy(); - dac->setContigPartOfSelectedValues(4,da2,ids); - const int expected6[14]={1,11,2,12,3,13,4,14,0,30,0,30,9,39}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected6[i],dac->getIJ(0,i)); - dac->decrRef(); - ids->decrRef(); - // - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildDescendingConnec2Of3DMesh1() -{ - MEDCouplingUMesh *mesh=build3DSourceMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(30,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)31,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(31,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)13,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(13,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); - const int expected1[48]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,-10,15,-5,-13,16,17,-14,18,-4,19,-2,20,21,22,23,24,25,-11,26,-1,-12,-25,-22,27,28,-7,-20,-24,29,-16,-18,30,-8,-28}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+48,desc->getConstPointer())); - const int expected2[13]={0,4,8,12,16,20,24,28,32,36,40,44,48}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+13,descIndx->getConstPointer())); - const int expected3[31]={0,2,4,5,7,9,10,12,14,15,17,19,21,23,25,26,28,29,31,32,34,35,37,38,40,42,43,44,46,47,48}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+31,revDescIndx->getConstPointer())); - const int expected4[48]={0,8,0,6,0,0,5,1,4,1,1,9,1,11,2,2,3,2,7,2,8,3,4,3,5,3,4,10,4,5,11,5,6,10,6,6,9,7,7,10,7,8,8,9,9,11,10,11}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); - DataArrayInt *conn=mesh2->getNodalConnectivity(); - DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); - const int expected5[31]={0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+31,connIndex->getConstPointer())); - const int expected6[120]={3,8,1,7,3,8,3,1,3,1,3,7,3,7,3,8,3,6,0,8,3,6,2,0,3,0,2,8,3,8,2,6,3,7,4,5,3,7,8,4,3,4,8,5,3,5,8,7,3,6,8,4,3,6,7,8,3,4,7,6,3,8,4,0,3,0,4,6,3,6,3,8,3,7,3,6,3,8,0,1,3,1,0,3,3,3,0,8,3,4,1,5,3,4,8,1,3,1,8,5,3,1,7,5,3,0,2,3,3,3,2,8,3,1,4,0,3,3,2,6}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+120,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest5::testAre2DCellsNotCorrectlyOriented1() -{ - double m1Coords[8]={1.,1.,-1.,-1.,-1.,-1.,1.,-1.}; - int m1Conn[4]={0,3,1,2}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(1); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m1Conn); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(4,2); - std::copy(m1Coords,m1Coords+8,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - double vec1[3]={0.,0.,1.}; - double *vec2=new double[2]; - for(int i=0;i<18;i++) - { - vec2[0]=3.*cos(M_PI/9.*i); - vec2[1]=3.*sin(M_PI/9.*i); - MEDCouplingUMesh *m1Cpy=static_cast(m1->deepCpy()); - m1Cpy->translate(vec2); - std::vector res; - CPPUNIT_ASSERT_THROW(m1Cpy->are2DCellsNotCorrectlyOriented(vec1,false,res),INTERP_KERNEL::Exception); - res.clear(); - m1Cpy->changeSpaceDimension(3); - m1Cpy->are2DCellsNotCorrectlyOriented(vec1,false,res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(0,res[0]); - m1Cpy->decrRef(); - } - delete [] vec2; - // - m1->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayAbs1() -{ - DataArrayDouble *d1=DataArrayDouble::New(); - const double val1[12]={2.,-3.,-5.,6.,-7.,-8.,9.,10.,-11.,-12.,-13.,-15.}; - const double expected1[12]={2.,3.,5.,6.,7.,8.,9.,10.,11.,12.,13.,15.}; - d1->alloc(6,2); - std::copy(val1,val1+12,d1->getPointer()); - DataArrayInt *d2=d1->convertToIntArr(); - // - d1->abs(); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],d1->getIJ(0,i),1e-14); - // - const int expected2[12]={2,3,5,6,7,8,9,10,11,12,13,15}; - d2->abs(); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(0,i)); - // - d2->decrRef(); - d1->decrRef(); -} - -void MEDCouplingBasicsTest5::testGetValueOn3() -{ - const double v[4]={0.,1.,1.5,2.}; - const double v2[5]={0.7,1.25,0.,2.,1.5}; - const double disp[12]={5.,50.,500.,6.,60.,600.,7.,70.,700.,8.,80.,800.}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("myMesh",1); - const int nbNodes=4; - const int nbCells=nbNodes-1; - m->allocateCells(nbCells); - DataArrayDouble *coords=DataArrayDouble::New(); - coords->alloc(nbNodes,1); - std::copy(v,v+nbNodes,coords->getPointer()); - m->setCoords(coords); - coords->decrRef(); - const int conn[6]={0,1,2,1,2,3}; - m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - m->finishInsertingCells(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES); - f->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(m->getNumberOfNodes(),3); - std::copy(disp,disp+12,array->getPointer()); - f->setArray(array); - array->decrRef(); - DataArrayDouble *arr1=f->getValueOnMulti(v2,5); - CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,arr1->getNumberOfComponents()); - const double expected1[15]={5.7,57.,570.,6.5,65.,650.,5.,50.,500.,8.,80.,800.,7.,70.,700.}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],arr1->getIJ(0,i),1e-14); - arr1->decrRef(); - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testGetNodeIdsOfCell2() -{ - MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); - DataArrayDouble *coordsX=DataArrayDouble::New(); - double arrX[5] = { -1., 1., 2., 4., 4.5 }; - coordsX->useArray(arrX,false, CPP_DEALLOC,5,1); - DataArrayDouble *coordsY=DataArrayDouble::New(); - double arrY[4] = { -2., 2., 4., 8. }; - coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); - DataArrayDouble *coordsZ=DataArrayDouble::New(); - double arrZ[3] = { -2., 2., 4. }; - coordsZ->useArray(arrZ,false, CPP_DEALLOC,3,1); - // test in 1D - m1c->setCoordsAt(0,coordsX); - CPPUNIT_ASSERT_EQUAL(4,m1c->getNumberOfCells()); - const int expected1[4][2]={{0,1},{1,2},{2,3},{3,4}}; - for(int i=0;i<4;i++) - { - std::vector v; - m1c->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==2); - std::equal(v.begin(),v.end(),expected1[i]); - } - // test in 2D - m1c->setCoordsAt(1,coordsY); - CPPUNIT_ASSERT_EQUAL(12,m1c->getNumberOfCells()); - const int expected2[12][4]={{0,1,6,5},{1,2,7,6},{2,3,8,7},{3,4,9,8},{4,5,11,10},{5,6,12,11},{6,7,13,12},{7,8,14,13},{8,9,16,15},{9,10,17,16},{10,11,18,17},{11,12,19,18}}; - for(int i=0;i<12;i++) - { - std::vector v; - m1c->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==4); - std::equal(v.begin(),v.end(),expected2[i]); - } - // test in 3D - m1c->setCoordsAt(2,coordsZ); - CPPUNIT_ASSERT_EQUAL(24,m1c->getNumberOfCells()); - const int expected3[24][8]={{0,1,6,5,20,21,26,25},{1,2,7,6,21,22,27,26},{2,3,8,7,22,23,28,27},{3,4,9,8,23,24,29,28},{4,5,11,10,24,25,31,30},{5,6,12,11,25,26,32,31},{6,7,13,12,26,27,33,32},{7,8,14,13,27,28,34,33},{8,9,16,15,28,29,36,35},{9,10,17,16,29,30,37,36},{10,11,18,17,30,31,38,37},{11,12,19,18,31,32,39,38},{20,21,26,25,40,41,46,45},{21,22,27,26,41,42,47,46},{22,23,28,27,42,43,48,47},{23,24,29,28,43,44,49,48},{24,25,31,30,44,45,51,50},{25,26,32,31,45,46,52,51},{26,27,33,32,46,47,53,52},{27,28,34,33,47,48,54,53},{28,29,36,35,48,49,56,55},{29,30,37,36,49,50,57,56},{30,31,38,37,50,51,58,57},{31,32,39,38,51,52,59,58}}; - for(int i=0;i<12;i++) - { - std::vector v; - m1c->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==8); - std::equal(v.begin(),v.end(),expected3[i]); - } - // - coordsX->decrRef(); - coordsY->decrRef(); - coordsZ->decrRef(); - m1c->decrRef(); -} - -void MEDCouplingBasicsTest5::testRenumberNodesInConn1() -{ - double mesh2DCoords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; - int mesh2DConn[18]={1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *mesh2D=MEDCouplingUMesh::New("mesh",2); - mesh2D->allocateCells(5); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,mesh2DConn); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,mesh2DConn+3); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+6); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+10); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+14); - mesh2D->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(mesh2DCoords,mesh2DCoords+27,myCoords->getPointer()); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - mesh2D->checkCoherency(); - // - double mesh3DCoords[24]={-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1. }; - int mesh3DConn[8]={0,1,2,3,4,5,6,7}; - MEDCouplingUMesh *mesh3D=MEDCouplingUMesh::New("mesh",3); - mesh3D->allocateCells(1); - mesh3D->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,mesh3DConn); - mesh3D->finishInsertingCells(); - DataArrayDouble *myCoords3D=DataArrayDouble::New(); - myCoords3D->alloc(8,3); - std::copy(mesh3DCoords,mesh3DCoords+24,myCoords3D->getPointer()); - mesh3D->setCoords(myCoords3D); - myCoords3D->decrRef(); - mesh3D->checkCoherency(); - // - MEDCouplingUMesh *mesh3D_2=dynamic_cast(mesh3D->deepCpy()); - MEDCouplingUMesh *mesh2D_2=dynamic_cast(mesh2D->deepCpy()); - MEDCouplingUMesh *mesh3D_4=dynamic_cast(mesh3D->deepCpy()); - MEDCouplingUMesh *mesh2D_4=dynamic_cast(mesh2D->deepCpy()); - DataArrayInt *renumNodes=DataArrayInt::New(); - int oldNbOf3DNodes=mesh3D->getNumberOfNodes(); - renumNodes->alloc(mesh2D->getNumberOfNodes(),1); - renumNodes->iota(oldNbOf3DNodes); - DataArrayDouble *coo=DataArrayDouble::Aggregate(mesh3D->getCoords(),mesh2D->getCoords()); - mesh3D->setCoords(coo); - mesh2D->setCoords(coo); - coo->decrRef(); - MEDCouplingUMesh *mesh2D_3=dynamic_cast(mesh2D->deepCpy()); - mesh2D_3->shiftNodeNumbersInConn(oldNbOf3DNodes); - mesh2D->renumberNodesInConn(renumNodes->getConstPointer()); - renumNodes->decrRef(); - CPPUNIT_ASSERT(mesh2D_3->isEqual(mesh2D,1e-12)); - mesh2D_3->decrRef(); - // - DataArrayInt *da1,*da2; - mesh3D->checkGeoEquivalWith(mesh3D_2,10,1e-12,da1,da2); - CPPUNIT_ASSERT(da1==0); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[8]={8,11,12,9,4,5,6,7}; - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - da2->decrRef(); - // - mesh2D->checkGeoEquivalWith(mesh2D_2,10,1e-12,da1,da2); - CPPUNIT_ASSERT(da1==0); - CPPUNIT_ASSERT_EQUAL(9,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_EQUAL(8+i,da2->getIJ(i,0)); - da2->decrRef(); - // - const double vect[3]={1.,0.,0.}; - MEDCouplingUMesh *mesh2D_5=dynamic_cast(mesh2D_4->deepCpy()); - mesh2D_5->translate(vect); - std::vector meshes(3); - meshes[0]=mesh3D_4; meshes[1]=mesh2D_4; meshes[2]=mesh2D_5; - MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); - CPPUNIT_ASSERT(mesh3D_4->getCoords()==mesh2D_4->getCoords()); - CPPUNIT_ASSERT(mesh2D_4->getCoords()==mesh2D_5->getCoords()); - mesh3D_4->checkCoherency(); mesh2D_4->checkCoherency(); mesh2D_5->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(26,mesh3D_4->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh3D_4->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh3D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_5->getNodalConnectivity()->getNumberOfTuples()); - const int expected2[9]={18,0,1,2,3,4,5,6,7}; - const int expected3[23]={3,9,12,10, 3,12,13,10, 4,8,11,12,9, 4,14,15,12,11, 4,15,16,13,12}; - const int expected4[23]={3,18,21,19, 3,21,22,19, 4,17,20,21,18, 4,23,24,21,20, 4,24,25,22,21}; - const double expected5[78]={-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1., -0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0., 0.7, -0.3, 0.0, 1.2, -0.3, 0.0, 1.7, -0.3, 0.0, 0.7, 0.2, 0.0, 1.2, 0.2, 0.0, 1.7, 0.2, 0.0, 0.7, 0.7, 0.0, 1.2, 0.7, 0.0, 1.7, 0.7, 0.0}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+9,mesh3D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+23,mesh2D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+23,mesh2D_5->getNodalConnectivity()->getConstPointer())); - for(int i=0;i<78;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],mesh3D_4->getCoords()->getIJ(0,i),1e-12); - // - MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,1e-12); - mesh3D_4->checkCoherency(); mesh2D_4->checkCoherency(); mesh2D_5->checkCoherency(); - CPPUNIT_ASSERT(mesh3D_4->getCoords()==mesh2D_4->getCoords()); - CPPUNIT_ASSERT(mesh2D_4->getCoords()==mesh2D_5->getCoords()); - CPPUNIT_ASSERT_EQUAL(19,mesh3D_4->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh3D_4->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh3D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_5->getNodalConnectivity()->getNumberOfTuples()); - const int expected6[9]={18,0,1,2,3,4,5,6,7}; - const int expected7[23]={3,3,2,8, 3,2,9,8, 4,0,1,2,3, 4,10,11,2,1, 4,11,12,9,2}; - const int expected8[23]={3,13,15,14, 3,15,16,14, 4,8,9,15,13, 4,12,17,15,9, 4,17,18,16,15}; - const double expected9[57]={-0.3, -0.3, 0., -0.3, 0.2, 0., 0.2, 0.2, 0., 0.2, -0.3, 0., -0.3, -0.3, 1., -0.3, 0.2, 1., - 0.2, 0.2, 1., 0.2, -0.3, 1., 0.7, -0.3, 0., 0.7, 0.2, 0., -0.3, 0.7, 0., 0.2, 0.7, 0., - 0.7, 0.7, 0., 1.2, -0.3, 0., 1.7, -0.3, 0., 1.2, 0.2, 0., 1.7, 0.2, 0., 1.2, 0.7, 0., 1.7, 0.7, 0.}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+9,mesh3D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected7,expected7+23,mesh2D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected8,expected8+23,mesh2D_5->getNodalConnectivity()->getConstPointer())); - for(int i=0;i<57;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],mesh3D_4->getCoords()->getIJ(0,i),1e-12); - mesh2D_5->decrRef(); - // - mesh3D_4->decrRef(); - mesh2D_4->decrRef(); - mesh3D_2->decrRef(); - mesh2D_2->decrRef(); - // - mesh3D->decrRef(); - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testComputeNeighborsOfCells1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *d1=0,*d2=0; - m->computeNeighborsOfCells(d1,d2); - CPPUNIT_ASSERT_EQUAL(6,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,d1->getNumberOfTuples()); - const int expected1[6]={0,2,4,6,8,10}; - const int expected2[10]={3,1,0,2,4,1,4,0,2,3}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+6,d2->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+10,d1->getConstPointer())); - d1->decrRef(); - d2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testCheckButterflyCellsBug1() -{ - double mesh2DCoords[10]={323.85,120.983748908684,317.5,131.982271536747,336.55,120.983748908686,330.2,131.982271536751,323.85,142.98079416481}; - int mesh2DConn[5]={4,1,0,2,3}; - MEDCouplingUMesh *mesh2D=MEDCouplingUMesh::New("mesh",2); - mesh2D->allocateCells(1); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,mesh2DConn); - mesh2D->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(mesh2DCoords,mesh2DCoords+10,myCoords->getPointer()); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - mesh2D->checkCoherency(); - // - std::vector v; - mesh2D->checkButterflyCells(v); - CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); - // - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayIntRange1() -{ - DataArrayInt *d=DataArrayInt::Range(2,17,7); - const int expected1[3]={2,9,16}; - CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(2,23,7); - CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(2,24,7); - const int expected2[4]={2,9,16,23}; - CPPUNIT_ASSERT_EQUAL(4,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+4,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(24,2,-7); - const int expected3[4]={24,17,10,3}; - CPPUNIT_ASSERT_EQUAL(4,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(23,2,-7); - const int expected4[3]={23,16,9}; - CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(23,22,-7); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(23,d->getIJ(0,0)); - d->decrRef(); - // - d=DataArrayInt::Range(22,23,7); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(22,d->getIJ(0,0)); - d->decrRef(); - // - d=DataArrayInt::Range(22,22,7); - CPPUNIT_ASSERT_EQUAL(0,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - d->decrRef(); - // - d=DataArrayInt::Range(22,22,-7); - CPPUNIT_ASSERT_EQUAL(0,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - d->decrRef(); - // - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(22,23,-7),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(23,22,7),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(23,22,0),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(22,23,0),INTERP_KERNEL::Exception); -} - -void MEDCouplingBasicsTest5::testDataArrayDoubleGetMinMaxPerComponent1() -{ - const double values1[12]={1.,2.,3.,-0.9,2.1,3.,1.3,1.7,3.,1.,1.8,3.}; - DataArrayDouble *d1=DataArrayDouble::New(); - double *res=new double[2*3]; - CPPUNIT_ASSERT_THROW(d1->getMinMaxPerComponent(res),INTERP_KERNEL::Exception); - d1->alloc(4,3); - std::copy(values1,values1+12,d1->getPointer()); - d1->getMinMaxPerComponent(res); - const double expected1[6]={-0.9,1.3,1.7,2.1,3.,3.}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],res[i],1e-14); - delete [] res; - // - d1->rearrange(2); - res=new double[2*2]; - d1->getMinMaxPerComponent(res); - const double expected2[4]={1.,3.,-0.9,3.}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],res[i],1e-14); - delete [] res; - // - d1->rearrange(1); - res=new double[2*1]; - d1->getMinMaxPerComponent(res); - const double expected3[2]={-0.9,3.}; - for(int i=0;i<2;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-14); - delete [] res; - d1->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayIntGetHashCode1() -{ - DataArrayInt *d1=DataArrayInt::New(); d1->alloc(3545,1); d1->iota(0); - DataArrayInt *d2=DataArrayInt::New(); d2->alloc(3545,1); d2->iota(0); - // - CPPUNIT_ASSERT_EQUAL(d1->getHashCode(),d2->getHashCode()); - CPPUNIT_ASSERT_EQUAL(232341068,d1->getHashCode()); - d1->setIJ(886,0,6); - CPPUNIT_ASSERT_EQUAL(232340188,d1->getHashCode()); - // - d1->decrRef(); - d2->decrRef(); -} - -void MEDCouplingBasicsTest5::testZipConnectivityPol1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int cells1[3]={2,3,4}; - MEDCouplingPointSet *m2_1=m1->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m2=dynamic_cast(m2_1); - DataArrayInt *arr=0; - CPPUNIT_ASSERT(m2); - // no permutation policy 0 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 1 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 2 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - // some modification into m2 - const int modif1[3]={2,4,5}; - std::copy(modif1,modif1+3,m2->getNodalConnectivity()->getPointer()+1); - //policy 0 fails because cell0 in m2 has same orientation be not same connectivity - const int expected1[3]={5,3,4}; - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 1 succeeds because cell0 in m2 has not exactly the same conn - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 2 succeeds because cell0 in m2 has same nodes in connectivity - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - //some new modification into m2 - const int modif2[3]={2,5,4}; - std::copy(modif2,modif2+3,m2->getNodalConnectivity()->getPointer()+1); - //policy 0 fails because cell0 in m2 has not exactly the same conn - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 1 fails too because cell0 in m2 has not same orientation - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 2 succeeds because cell0 in m2 has same nodes in connectivity - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - m1->decrRef(); - m2->decrRef(); - // Now 1D - const int cells2[2]={3,2}; - m1=build1DSourceMesh_2(); - m2_1=m1->buildPartOfMySelf(cells2,cells2+2,true); - m2=dynamic_cast(m2_1); - CPPUNIT_ASSERT(m2); - arr=0; - // no permutation policy 0 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 1 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 2 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - // some modification into m2 - const int modif3[2]={4,3}; - std::copy(modif3,modif3+2,m2->getNodalConnectivity()->getPointer()+1); - //policy 0 fails because cell0 in m2 has not exactly the same conn - const int expected2[2]={4,2}; - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,arr->getConstPointer())); - arr->decrRef(); - //policy 1 fails too because cell0 in m2 has not same orientation - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,arr->getConstPointer())); - arr->decrRef(); - //policy 2 succeeds because cell0 in m2 has same nodes in connectivity - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest5::testConvexEnvelop2D1() -{ - const double coords[662]={7.54758495819e-14,-1.12270326253e-12,8.43143594193,-1.02835845055e-12,4.21571797096,7.30183771609,-4.21571797097,7.30183771609,-8.43143594193,-1.09439981894e-12,-4.21571797097,-7.30183771609,4.21571797097,-7.30183771609,16.8628718839,-1.02835845055e-12,12.6471539129,7.30183771609,8.43143594193,14.6036754322,2.26427548746e-13,14.6036754322,-8.43143594193,14.6036754322,-12.6471539129,7.30183771609,-16.8628718839,-1.39630321727e-12,-12.6471539129,-7.30183771609,-8.43143594193,-14.6036754322,3.7737924791e-14,-14.6036754322,8.43143594193,-14.6036754322,12.6471539129,-7.30183771609,25.2943078258,-1.07553085654e-12,21.0785898548,7.30183771609,16.8628718839,14.6036754322,12.6471539129,21.9055131483,4.21571797096,21.9055131483,-4.21571797097,21.9055131483,-12.6471539129,21.9055131483,-16.8628718839,14.6036754322,-21.0785898548,7.30183771609,-25.2943078258,-1.02835845055e-12,-21.0785898548,-7.30183771609,-16.8628718839,-14.6036754322,-12.6471539129,-21.9055131483,-4.21571797097,-21.9055131483,4.21571797097,-21.9055131483,12.6471539129,-21.9055131483,16.8628718839,-14.6036754322,21.0785898548,-7.30183771609,33.7257437677,-7.45324014622e-13,29.5100257968,7.30183771609,25.2943078258,14.6036754322,21.0785898548,21.9055131483,16.8628718839,29.2073508644,8.43143594193,29.2073508644,-1.20761359331e-12,29.2073508644,-8.43143594193,29.2073508644,-16.8628718839,29.2073508644,-21.0785898548,21.9055131483,-25.2943078258,14.6036754322,-29.5100257968,7.30183771609,-33.7257437677,-7.26455052226e-13,-29.5100257968,-7.30183771609,-25.2943078258,-14.6036754322,-21.0785898548,-21.9055131483,-16.8628718839,-29.2073508644,-8.43143594193,-29.2073508644,4.15117172701e-13,-29.2073508644,8.43143594193,-29.2073508644,16.8628718839,-29.2073508644,21.0785898548,-21.9055131483,25.2943078258,-14.6036754322,29.5100257968,-7.30183771609,42.1571797097,-1.86802727715e-12,37.9414617387,7.30183771609,33.7257437677,14.6036754322,29.5100257968,21.9055131483,25.2943078258,29.2073508644,21.0785898548,36.5091885805,12.6471539129,36.5091885805,4.21571797096,36.5091885805,-4.21571797096,36.5091885805,-12.6471539129,36.5091885805,-21.0785898548,36.5091885805,-25.2943078258,29.2073508644,-29.5100257968,21.9055131483,-33.7257437677,14.6036754322,-37.9414617387,7.30183771609,-42.1571797097,-9.81186044565e-13,-37.9414617387,-7.30183771609,-33.7257437677,-14.6036754322,-29.5100257968,-21.9055131483,-25.2943078258,-29.2073508644,-21.0785898548,-36.5091885805,-12.6471539129,-36.5091885805,-4.21571797097,-36.5091885805,4.21571797097,-36.5091885805,12.6471539129,-36.5091885805,21.0785898548,-36.5091885805,25.2943078258,-29.2073508644,29.5100257968,-21.9055131483,33.7257437677,-14.6036754322,37.9414617387,-7.30183771609,50.5886156516,-6.98151608633e-13,46.3728976806,7.30183771609,42.1571797097,14.6036754322,37.9414617387,21.9055131483,33.7257437677,29.2073508644,29.5100257968,36.5091885805,25.2943078258,43.8110262966,16.8628718839,43.8110262966,8.43143594193,43.8110262966,-1.84915831476e-12,43.8110262966,-8.43143594193,43.8110262966,-16.8628718839,43.8110262966,-25.2943078258,43.8110262966,-29.5100257968,36.5091885805,-33.7257437677,29.2073508644,-37.9414617387,21.9055131483,-42.1571797097,14.6036754322,-46.3728976806,7.30183771609,-50.5886156516,-1.47177906685e-12,-46.3728976806,-7.30183771609,-42.1571797097,-14.6036754322,-37.9414617387,-21.9055131483,-33.7257437677,-29.2073508644,-29.5100257968,-36.5091885805,-25.2943078258,-43.8110262966,-16.8628718839,-43.8110262966,-8.43143594193,-43.8110262966,7.54758495819e-14,-43.8110262966,8.43143594193,-43.8110262966,16.8628718839,-43.8110262966,25.2943078258,-43.8110262966,29.5100257968,-36.5091885805,33.7257437677,-29.2073508644,37.9414617387,-21.9055131483,42.1571797097,-14.6036754322,46.3728976806,-7.30183771609,59.0200515935,-7.9249642061e-13,54.8043336225,7.30183771609,50.5886156516,14.6036754322,46.3728976806,21.9055131483,42.1571797097,29.2073508644,37.9414617387,36.5091885805,33.7257437677,43.8110262966,29.5100257968,51.1128640127,21.0785898548,51.1128640127,12.6471539129,51.1128640127,4.21571797096,51.1128640127,-4.21571797096,51.1128640127,-12.6471539129,51.1128640127,-21.0785898548,51.1128640127,-29.5100257968,51.1128640127,-33.7257437677,43.8110262966,-37.9414617387,36.5091885805,-42.1571797097,29.2073508644,-46.3728976806,21.9055131483,-50.5886156516,14.6036754322,-54.8043336226,7.30183771609,-59.0200515935,-1.31139288649e-12,-54.8043336226,-7.30183771609,-50.5886156516,-14.6036754322,-46.3728976806,-21.9055131483,-42.1571797097,-29.2073508644,-37.9414617387,-36.5091885805,-33.7257437677,-43.8110262966,-29.5100257968,-51.1128640127,-21.0785898548,-51.1128640127,-12.6471539129,-51.1128640127,-4.21571797097,-51.1128640127,4.21571797097,-51.1128640127,12.6471539129,-51.1128640127,21.0785898548,-51.1128640127,29.5100257968,-51.1128640127,33.7257437677,-43.8110262966,37.9414617387,-36.5091885805,42.1571797097,-29.2073508644,46.3728976806,-21.9055131483,50.5886156516,-14.6036754322,54.8043336225,-7.30183771609,67.4514875354,-2.14162723189e-12,63.2357695645,7.30183771609,59.0200515935,14.6036754322,54.8043336226,21.9055131483,50.5886156516,29.2073508644,46.3728976806,36.5091885805,42.1571797097,43.8110262966,37.9414617387,51.1128640127,33.7257437677,58.4147017287,25.2943078258,58.4147017287,16.8628718839,58.4147017287,8.43143594193,58.4147017287,6.79282646237e-13,58.4147017287,-8.43143594193,58.4147017287,-16.8628718839,58.4147017287,-25.2943078258,58.4147017287,-33.7257437677,58.4147017287,-37.9414617387,51.1128640127,-42.1571797097,43.8110262966,-46.3728976806,36.5091885805,-50.5886156516,29.2073508644,-54.8043336226,21.9055131483,-59.0200515935,14.6036754322,-63.2357695645,7.30183771609,-67.4514875354,-1.16044118732e-12,-63.2357695645,-7.30183771609,-59.0200515935,-14.6036754322,-54.8043336226,-21.9055131483,-50.5886156516,-29.2073508644,-46.3728976806,-36.5091885805,-42.1571797097,-43.8110262966,-37.9414617387,-51.1128640127,-33.7257437677,-58.4147017287,-25.2943078258,-58.4147017287,-16.8628718839,-58.4147017287,-8.43143594193,-58.4147017287,-5.66068871864e-14,-58.4147017287,8.43143594193,-58.4147017287,16.8628718839,-58.4147017287,25.2943078258,-58.4147017287,33.7257437677,-58.4147017287,37.9414617387,-51.1128640127,42.1571797097,-43.8110262966,46.3728976806,-36.5091885805,50.5886156516,-29.2073508644,54.8043336226,-21.9055131483,59.0200515935,-14.6036754322,63.2357695645,-7.30183771609,75.8829234774,-2.29257893105e-12,71.6672055064,7.30183771609,67.4514875354,14.6036754322,63.2357695645,21.9055131483,59.0200515935,29.2073508644,54.8043336226,36.5091885805,50.5886156516,43.8110262966,46.3728976806,51.1128640127,42.1571797097,58.4147017287,37.9414617387,65.7165394448,29.5100257968,65.7165394448,21.0785898548,65.7165394448,12.6471539129,65.7165394448,4.21571797097,65.7165394448,-4.21571797096,65.7165394448,-12.6471539129,65.7165394448,-21.0785898548,65.7165394448,-29.5100257968,65.7165394448,-37.9414617387,65.7165394448,-42.1571797097,58.4147017287,-46.3728976806,51.1128640127,-50.5886156516,43.8110262966,-54.8043336226,36.5091885805,-59.0200515935,29.2073508644,-63.2357695645,21.9055131483,-67.4514875354,14.6036754322,-71.6672055064,7.30183771609,-75.8829234774,-1.31139288649e-12,-71.6672055064,-7.30183771609,-67.4514875354,-14.6036754322,-63.2357695645,-21.9055131483,-59.0200515935,-29.2073508644,-54.8043336226,-36.5091885805,-50.5886156516,-43.8110262966,-46.3728976806,-51.1128640127,-42.1571797097,-58.4147017287,-37.9414617387,-65.7165394448,-29.5100257968,-65.7165394448,-21.0785898548,-65.7165394448,-12.6471539129,-65.7165394448,-4.21571797097,-65.7165394448,4.21571797097,-65.7165394448,12.6471539129,-65.7165394448,21.0785898548,-65.7165394448,29.5100257968,-65.7165394448,37.9414617387,-65.7165394448,42.1571797097,-58.4147017287,46.3728976806,-51.1128640127,50.5886156516,-43.8110262966,54.8043336226,-36.5091885805,59.0200515935,-29.2073508644,63.2357695645,-21.9055131483,67.4514875354,-14.6036754322,71.6672055064,-7.30183771609,84.3143594193,-1.49064802924e-12,80.0986414483,7.30183771609,75.8829234774,14.6036754322,71.6672055064,21.9055131483,67.4514875354,29.2073508644,63.2357695645,36.5091885805,59.0200515935,43.8110262966,54.8043336226,51.1128640127,50.5886156516,58.4147017287,46.3728976806,65.7165394448,42.1571797097,73.0183771609,33.7257437677,73.0183771609,25.2943078258,73.0183771609,16.8628718839,73.0183771609,8.43143594193,73.0183771609,2.0755858635e-12,73.0183771609,-8.43143594193,73.0183771609,-16.8628718839,73.0183771609,-25.2943078258,73.0183771609,-33.7257437677,73.0183771609,-42.1571797097,73.0183771609,-46.3728976806,65.7165394448,-50.5886156516,58.4147017287,-54.8043336226,51.1128640127,-59.0200515935,43.8110262966,-63.2357695645,36.5091885805,-67.4514875354,29.2073508644,-71.6672055064,21.9055131483,-75.8829234774,14.6036754322,-80.0986414483,7.30183771609,-84.3143594193,-1.11326878133e-12,-80.0986414483,-7.30183771609,-75.8829234774,-14.6036754322,-71.6672055064,-21.9055131483,-67.4514875354,-29.2073508644,-63.2357695645,-36.5091885805,-59.0200515935,-43.8110262966,-54.8043336226,-51.1128640127,-50.5886156516,-58.4147017287,-46.3728976806,-65.7165394448,-42.1571797097,-73.0183771609,-33.7257437677,-73.0183771609,-25.2943078258,-73.0183771609,-16.8628718839,-73.0183771609,-8.43143594193,-73.0183771609,-5.66068871864e-14,-73.0183771609,8.43143594193,-73.0183771609,16.8628718839,-73.0183771609,25.2943078258,-73.0183771609,33.7257437677,-73.0183771609,42.1571797097,-73.0183771609,46.3728976806,-65.7165394448,50.5886156516,-58.4147017287,54.8043336226,-51.1128640127,59.0200515935,-43.8110262966,63.2357695645,-36.5091885805,67.4514875354,-29.2073508644,71.6672055064,-21.9055131483,75.8829234774,-14.6036754322,80.0986414483,-7.3018377161}; - const int conn[2137]={0,2,3,4,5,6,1,1,8,2,0,6,18,7,2,9,10,3,0,1,8,3,10,11,12,4,0,2,4,3,12,13,14,5,0,5,0,4,14,15,16,6,6,1,0,5,16,17,18,7,20,8,1,18,36,19,8,21,9,2,1,7,20,9,22,23,10,2,8,21,10,23,24,11,3,2,9,11,24,25,26,12,3,10,12,11,26,27,13,4,3,13,12,27,28,29,14,4,14,4,13,29,30,15,5,15,5,14,30,31,32,16,16,6,5,15,32,33,17,17,18,6,16,33,34,35,18,7,1,6,17,35,36,19,38,20,7,36,60,37,20,39,21,8,7,19,38,21,40,22,9,8,20,39,22,41,42,23,9,21,40,23,42,43,24,10,9,22,24,43,44,25,11,10,23,25,44,45,46,26,11,24,26,25,46,47,27,12,11,27,26,47,48,28,13,12,28,27,48,49,50,29,13,29,13,28,50,51,30,14,30,14,29,51,52,31,15,31,15,30,52,53,54,32,32,16,15,31,54,55,33,33,17,16,32,55,56,34,34,35,17,33,56,57,58,35,36,18,17,34,58,59,36,19,7,18,35,59,60,37,62,38,19,60,90,61,38,63,39,20,19,37,62,39,64,40,21,20,38,63,40,65,41,22,21,39,64,41,66,67,42,22,40,65,42,67,68,43,23,22,41,43,68,69,44,24,23,42,44,69,70,45,25,24,43,45,70,71,72,46,25,44,46,45,72,73,47,26,25,47,46,73,74,48,27,26,48,47,74,75,49,28,27,49,48,75,76,77,50,28,50,28,49,77,78,51,29,51,29,50,78,79,52,30,52,30,51,79,80,53,31,53,31,52,80,81,82,54,54,32,31,53,82,83,55,55,33,32,54,83,84,56,56,34,33,55,84,85,57,57,58,34,56,85,86,87,58,59,35,34,57,87,88,59,60,36,35,58,88,89,60,37,19,36,59,89,90,61,92,62,37,90,126,91,62,93,63,38,37,61,92,63,94,64,39,38,62,93,64,95,65,40,39,63,94,65,96,66,41,40,64,95,66,97,98,67,41,65,96,67,98,99,68,42,41,66,68,99,100,69,43,42,67,69,100,101,70,44,43,68,70,101,102,71,45,44,69,71,102,103,104,72,45,70,72,71,104,105,73,46,45,73,72,105,106,74,47,46,74,73,106,107,75,48,47,75,74,107,108,76,49,48,76,75,108,109,110,77,49,77,49,76,110,111,78,50,78,50,77,111,112,79,51,79,51,78,112,113,80,52,80,52,79,113,114,81,53,81,53,80,114,115,116,82,82,54,53,81,116,117,83,83,55,54,82,117,118,84,84,56,55,83,118,119,85,85,57,56,84,119,120,86,86,87,57,85,120,121,122,87,88,58,57,86,122,123,88,89,59,58,87,123,124,89,90,60,59,88,124,125,90,61,37,60,89,125,126,91,128,92,61,126,168,127,92,129,93,62,61,91,128,93,130,94,63,62,92,129,94,131,95,64,63,93,130,95,132,96,65,64,94,131,96,133,97,66,65,95,132,97,134,135,98,66,96,133,98,135,136,99,67,66,97,99,136,137,100,68,67,98,100,137,138,101,69,68,99,101,138,139,102,70,69,100,102,139,140,103,71,70,101,103,140,141,142,104,71,102,104,103,142,143,105,72,71,105,104,143,144,106,73,72,106,105,144,145,107,74,73,107,106,145,146,108,75,74,108,107,146,147,109,76,75,109,108,147,148,149,110,76,110,76,109,149,150,111,77,111,77,110,150,151,112,78,112,78,111,151,152,113,79,113,79,112,152,153,114,80,114,80,113,153,154,115,81,115,81,114,154,155,156,116,116,82,81,115,156,157,117,117,83,82,116,157,158,118,118,84,83,117,158,159,119,119,85,84,118,159,160,120,120,86,85,119,160,161,121,121,122,86,120,161,162,163,122,123,87,86,121,163,164,123,124,88,87,122,164,165,124,125,89,88,123,165,166,125,126,90,89,124,166,167,126,91,61,90,125,167,168,127,170,128,91,168,216,169,128,171,129,92,91,127,170,129,172,130,93,92,128,171,130,173,131,94,93,129,172,131,174,132,95,94,130,173,132,175,133,96,95,131,174,133,176,134,97,96,132,175,134,177,178,135,97,133,176,135,178,179,136,98,97,134,136,179,180,137,99,98,135,137,180,181,138,100,99,136,138,181,182,139,101,100,137,139,182,183,140,102,101,138,140,183,184,141,103,102,139,141,184,185,186,142,103,140,142,141,186,187,143,104,103,143,142,187,188,144,105,104,144,143,188,189,145,106,105,145,144,189,190,146,107,106,146,145,190,191,147,108,107,147,146,191,192,148,109,108,148,147,192,193,194,149,109,149,109,148,194,195,150,110,150,110,149,195,196,151,111,151,111,150,196,197,152,112,152,112,151,197,198,153,113,153,113,152,198,199,154,114,154,114,153,199,200,155,115,155,115,154,200,201,202,156,156,116,115,155,202,203,157,157,117,116,156,203,204,158,158,118,117,157,204,205,159,159,119,118,158,205,206,160,160,120,119,159,206,207,161,161,121,120,160,207,208,162,162,163,121,161,208,209,210,163,164,122,121,162,210,211,164,165,123,122,163,211,212,165,166,124,123,164,212,213,166,167,125,124,165,213,214,167,168,126,125,166,214,215,168,127,91,126,167,215,216,169,218,170,127,216,270,217,170,219,171,128,127,169,218,171,220,172,129,128,170,219,172,221,173,130,129,171,220,173,222,174,131,130,172,221,174,223,175,132,131,173,222,175,224,176,133,132,174,223,176,225,177,134,133,175,224,177,226,227,178,134,176,225,178,227,228,179,135,134,177,179,228,229,180,136,135,178,180,229,230,181,137,136,179,181,230,231,182,138,137,180,182,231,232,183,139,138,181,183,232,233,184,140,139,182,184,233,234,185,141,140,183,185,234,235,236,186,141,184,186,185,236,237,187,142,141,187,186,237,238,188,143,142,188,187,238,239,189,144,143,189,188,239,240,190,145,144,190,189,240,241,191,146,145,191,190,241,242,192,147,146,192,191,242,243,193,148,147,193,192,243,244,245,194,148,194,148,193,245,246,195,149,195,149,194,246,247,196,150,196,150,195,247,248,197,151,197,151,196,248,249,198,152,198,152,197,249,250,199,153,199,153,198,250,251,200,154,200,154,199,251,252,201,155,201,155,200,252,253,254,202,202,156,155,201,254,255,203,203,157,156,202,255,256,204,204,158,157,203,256,257,205,205,159,158,204,257,258,206,206,160,159,205,258,259,207,207,161,160,206,259,260,208,208,162,161,207,260,261,209,209,210,162,208,261,262,263,210,211,163,162,209,263,264,211,212,164,163,210,264,265,212,213,165,164,211,265,266,213,214,166,165,212,266,267,214,215,167,166,213,267,268,215,216,168,167,214,268,269,216,169,127,168,215,269,270,217,272,218,169,270,330,271,218,273,219,170,169,217,272,219,274,220,171,170,218,273,220,275,221,172,171,219,274,221,276,222,173,172,220,275,222,277,223,174,173,221,276,223,278,224,175,174,222,277,224,279,225,176,175,223,278,225,280,226,177,176,224,279,226,281,282,227,177,225,280,227,282,283,228,178,177,226,228,283,284,229,179,178,227,229,284,285,230,180,179,228,230,285,286,231,181,180,229,231,286,287,232,182,181,230,232,287,288,233,183,182,231,233,288,289,234,184,183,232,234,289,290,235,185,184,233,235,290,291,292,236,185,234,236,235,292,293,237,186,185,237,236,293,294,238,187,186,238,237,294,295,239,188,187,239,238,295,296,240,189,188,240,239,296,297,241,190,189,241,240,297,298,242,191,190,242,241,298,299,243,192,191,243,242,299,300,244,193,192,244,243,300,301,302,245,193,245,193,244,302,303,246,194,246,194,245,303,304,247,195,247,195,246,304,305,248,196,248,196,247,305,306,249,197,249,197,248,306,307,250,198,250,198,249,307,308,251,199,251,199,250,308,309,252,200,252,200,251,309,310,253,201,253,201,252,310,311,312,254,254,202,201,253,312,313,255,255,203,202,254,313,314,256,256,204,203,255,314,315,257,257,205,204,256,315,316,258,258,206,205,257,316,317,259,259,207,206,258,317,318,260,260,208,207,259,318,319,261,261,209,208,260,319,320,262,262,263,209,261,320,321,322,263,264,210,209,262,322,323,264,265,211,210,263,323,324,265,266,212,211,264,324,325,266,267,213,212,265,325,326,267,268,214,213,266,326,327,268,269,215,214,267,327,328,269,270,216,215,268,328,329,270,217,169,216,269,329,330,271,272,217,330,273,218,217,271,274,219,218,272,275,220,219,273,276,221,220,274,277,222,221,275,278,223,222,276,279,224,223,277,280,225,224,278,281,226,225,279,281,282,226,280,283,227,226,281,284,228,227,282,285,229,228,283,286,230,229,284,287,231,230,285,288,232,231,286,289,233,232,287,290,234,233,288,291,235,234,289,291,292,235,290,291,293,236,235,292,294,237,236,293,295,238,237,294,296,239,238,295,297,240,239,296,298,241,240,297,299,242,241,298,300,243,242,299,301,244,243,301,300,302,244,244,301,303,245,245,302,304,246,246,303,305,247,247,304,306,248,248,305,307,249,249,306,308,250,250,307,309,251,251,308,310,252,252,309,311,253,311,253,310,312,254,253,311,313,255,254,312,314,256,255,313,315,257,256,314,316,258,257,315,317,259,258,316,318,260,259,317,319,261,260,318,320,262,261,319,321,321,322,262,320,323,263,262,321,324,264,263,322,325,265,264,323,326,266,265,324,327,267,266,325,328,268,267,326,329,269,268,327,330,270,269,328,271,217,270,329}; - const int connI[332]={0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,343,350,357,364,371,378,385,392,399,406,413,420,427,434,441,448,455,462,469,476,483,490,497,504,511,518,525,532,539,546,553,560,567,574,581,588,595,602,609,616,623,630,637,644,651,658,665,672,679,686,693,700,707,714,721,728,735,742,749,756,763,770,777,784,791,798,805,812,819,826,833,840,847,854,861,868,875,882,889,896,903,910,917,924,931,938,945,952,959,966,973,980,987,994,1001,1008,1015,1022,1029,1036,1043,1050,1057,1064,1071,1078,1085,1092,1099,1106,1113,1120,1127,1134,1141,1148,1155,1162,1169,1176,1183,1190,1197,1204,1211,1218,1225,1232,1239,1246,1253,1260,1267,1274,1281,1288,1295,1302,1309,1316,1323,1330,1337,1344,1351,1358,1365,1372,1379,1386,1393,1400,1407,1414,1421,1428,1435,1442,1449,1456,1463,1470,1477,1484,1491,1498,1505,1512,1519,1526,1533,1540,1547,1554,1561,1568,1575,1582,1589,1596,1603,1610,1617,1624,1631,1638,1645,1652,1659,1666,1673,1680,1687,1694,1701,1708,1715,1722,1729,1736,1743,1750,1757,1764,1771,1778,1785,1792,1799,1806,1813,1820,1827,1834,1841,1848,1855,1862,1869,1876,1883,1890,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,2037,2041,2045,2049,2053,2057,2061,2065,2069,2073,2077,2081,2085,2089,2093,2097,2101,2105,2109,2113,2117,2121,2125,2129,2133,2137}; - // - MEDCouplingUMesh *m=MEDCouplingUMesh::New("convexhull",2); - m->allocateCells(331); - for(int i=0;i<331;i++) - m->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connI[i+1]-connI[i],conn+connI[i]); - m->finishInsertingCells(); - DataArrayDouble *coordsDa=DataArrayDouble::New(); - coordsDa->alloc(331,2); - std::copy(coords,coords+662,coordsDa->getPointer()); - m->setCoords(coordsDa); - coordsDa->decrRef(); - m->checkCoherency(); - // - DataArrayInt *da=m->convexEnvelop2D(); - m->checkCoherency(); - CPPUNIT_ASSERT(coordsDa==m->getCoords()); - DataArrayInt *daC=da->buildComplement(331); - da->decrRef(); - const int expected[58]={271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,302,303,304,305,306,307,308,309,310,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330}; - DataArrayInt *expected2=DataArrayInt::New(); - expected2->alloc(58,1); - std::copy(expected,expected+58,expected2->getPointer()); - CPPUNIT_ASSERT(expected2->isEqual(*daC)); - // - expected2->decrRef(); - daC->decrRef(); - // - MEDCouplingFieldDouble *valsF=m->getMeasureField(ON_CELLS); - DataArrayDouble *vals=valsF->getArray(); - const double ref[331]={184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491}; - DataArrayDouble *ref2=DataArrayDouble::New(); ref2->alloc(331,1); std::copy(ref,ref+331,ref2->getPointer()); - vals->substractEqual(ref2); - ref2->decrRef(); - vals->abs(); - DataArrayInt *theTest=vals->getIdsInRange(-1.,1e-7); - CPPUNIT_ASSERT(theTest->isIdentity()); - CPPUNIT_ASSERT_EQUAL(331,theTest->getNumberOfTuples()); - theTest->decrRef(); - valsF->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArraySort1() -{ - DataArrayInt *arr=DataArrayInt::New(); - CPPUNIT_ASSERT_THROW(arr->sort(true),INTERP_KERNEL::Exception);//no allocation - CPPUNIT_ASSERT_THROW(arr->sort(false),INTERP_KERNEL::Exception);//no allocation - const int values[6]={2,1,6,5,4,7}; - arr->alloc(3,2); - CPPUNIT_ASSERT_THROW(arr->sort(true),INTERP_KERNEL::Exception);//no one component - CPPUNIT_ASSERT_THROW(arr->sort(false),INTERP_KERNEL::Exception);//no one component - arr->rearrange(1); - std::copy(values,values+6,arr->getPointer()); - DataArrayInt *arr1=arr->deepCpy(); - DataArrayInt *arr2=arr->deepCpy(); - arr1->sort(true); - const int expected1[6]={1,2,4,5,6,7}; - CPPUNIT_ASSERT_EQUAL(6,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+6,arr1->begin())); - arr2->sort(false); - const int expected2[6]={7,6,5,4,2,1}; - CPPUNIT_ASSERT_EQUAL(6,arr2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,arr2->begin())); - arr1->decrRef(); - arr2->decrRef(); - arr->decrRef(); - // - DataArrayDouble *ard=DataArrayDouble::New(); - CPPUNIT_ASSERT_THROW(ard->sort(true),INTERP_KERNEL::Exception);//no allocation - CPPUNIT_ASSERT_THROW(ard->sort(false),INTERP_KERNEL::Exception);//no allocation - const double valuesD[6]={2.,1.,6.,5.,4.,7.}; - ard->alloc(3,2); - CPPUNIT_ASSERT_THROW(ard->sort(true),INTERP_KERNEL::Exception);//no one component - CPPUNIT_ASSERT_THROW(ard->sort(false),INTERP_KERNEL::Exception);//no one component - ard->rearrange(1); - std::copy(valuesD,valuesD+6,ard->getPointer()); - DataArrayDouble *ard1=ard->deepCpy(); - DataArrayDouble *ard2=ard->deepCpy(); - ard1->sort(true); - const double expected3[6]={1.,2.,4.,5.,6.,7.}; - CPPUNIT_ASSERT_EQUAL(6,ard1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ard1->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ard1->getIJ(i,0),1e-12); - ard2->sort(false); - const double expected4[6]={7.,6.,5.,4.,2.,1.}; - CPPUNIT_ASSERT_EQUAL(6,ard2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ard2->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],ard2->getIJ(i,0),1e-12); - ard1->decrRef(); - ard2->decrRef(); - ard->decrRef(); -} - -void MEDCouplingBasicsTest5::testPartitionBySpreadZone1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - const int part0[3]={2,3,4}; - const int part1[2]={0,1}; - MEDCouplingUMesh *m1=static_cast(m->buildPartOfMySelf(part0,part0+3)); - MEDCouplingUMesh *m2=static_cast(m->buildPartOfMySelf(part1,part1+2)); - std::vector v(3); v[0]=m; v[1]=m1; v[2]=m2; - MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshes(v); - const int renum[10]={5,2,9,6,4,7,0,1,3,8}; - m4->renumberCells(renum); - // - std::vector v2=m4->partitionBySpreadZone(); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - const int expected0[3]={0,1,7}; - const int expected1[5]={2,4,5,6,9}; - const int expected2[2]={3,8}; - CPPUNIT_ASSERT_EQUAL(3,v2[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,v2[0]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,v2[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,v2[1]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,v2[2]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,v2[2]->getNumberOfComponents()); - // - CPPUNIT_ASSERT(std::equal(expected0,expected0+3,v2[0]->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,v2[1]->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,v2[2]->getConstPointer())); - v2[0]->decrRef(); - v2[1]->decrRef(); - v2[2]->decrRef(); - // - MEDCouplingUMesh *m5=m4->buildSpreadZonesWithPoly(); - CPPUNIT_ASSERT_EQUAL(3,m5->getNumberOfCells()); - CPPUNIT_ASSERT(m5->getCoords()==m4->getCoords()); - const int expected3[23]={5,15,16,17,14,11,13,12,5,2,1,0,3,6,7,8,5,5,18,21,22,20,19}; - const int expected4[4]={0,8,17,23}; - CPPUNIT_ASSERT_EQUAL(23,m5->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+23,m5->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL(4,m5->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m5->getNodalConnectivityIndex()->getConstPointer())); - // - m->decrRef(); - m1->decrRef(); - m2->decrRef(); - m4->decrRef(); - m5->decrRef(); -} - -void MEDCouplingBasicsTest5::testGiveCellsWithType1() -{ - const int expected0[2]={1,2}; - const int expected1[3]={0,3,4}; - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *da=m->giveCellsWithType(INTERP_KERNEL::NORM_TRI3); - CPPUNIT_ASSERT_EQUAL(2,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected0,expected0+2,da->getConstPointer())); - da->decrRef(); - // - da=m->giveCellsWithType(INTERP_KERNEL::NORM_QUAD4); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,da->getConstPointer())); - da->decrRef(); - // - da=m->giveCellsWithType(INTERP_KERNEL::NORM_TRI6); - CPPUNIT_ASSERT_EQUAL(0,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - da->decrRef(); - // - CPPUNIT_ASSERT_THROW(m->giveCellsWithType(INTERP_KERNEL::NORM_SEG2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(m->giveCellsWithType(INTERP_KERNEL::NORM_HEXA8),INTERP_KERNEL::Exception); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildSlice3D2() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - mesh2D->decrRef(); - // First slice in the middle of 3D cells - const double vec1[3]={-0.07,1.,0.07}; - const double origin1[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids=0; - MEDCouplingUMesh *slice1=mesh3D->buildSlice3D(origin1,vec1,1e-10,ids); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setTime(4.5,6,7) ; f->setMesh(mesh3D); - DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(mesh3D->getNumberOfCells(),2); - arr->rearrange(1); arr->iota(2.); arr->rearrange(2); - f->setArray(arr); - f->checkCoherency(); - const int exp1[9]={1,3,4,7,9,10,13,15,16}; - DataArrayInt *expected1=DataArrayInt::New(); expected1->alloc(9,1); std::copy(exp1,exp1+9,expected1->getPointer()); - CPPUNIT_ASSERT(expected1->isEqual(*ids)); - DataArrayDouble *arr2=arr->selectByTupleIdSafe(expected1->begin(),expected1->end()); - // - MEDCouplingFieldDouble *f2=f->extractSlice3D(origin1,vec1,1e-10); - CPPUNIT_ASSERT(f2->getArray()->isEqual(*arr2,1e-12)); - CPPUNIT_ASSERT(slice1->isEqual(f2->getMesh(),1e-12)); - int a,b; - double c=f2->getTime(a,b); - CPPUNIT_ASSERT_EQUAL(6,a); - CPPUNIT_ASSERT_EQUAL(7,b); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,c,1e-12); - // - ids->decrRef(); - slice1->decrRef(); - arr2->decrRef(); - arr->decrRef(); - f2->decrRef(); - f->decrRef(); - mesh3D->decrRef(); - expected1->decrRef(); -} - -void MEDCouplingBasicsTest5::testComputeTupleIdsToSelectFromCellIds1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); - f->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(52,2) ; arr->rearrange(1) ; arr->iota(7.); arr->rearrange(2); - f->setArray(arr); - // - const int subPart1[3]={1,5,9}; - MEDCouplingFieldDouble *f2=f->buildSubPart(subPart1,subPart1+3); - f2->checkCoherency(); - DataArrayInt *cI=m->computeNbOfNodesPerCell(); - cI->computeOffsets2(); - const int sel1[3]={1,5,9}; - DataArrayInt *sel=DataArrayInt::New(); sel->useArray(sel1,false,CPP_DEALLOC,3,1); - DataArrayInt *res=sel->buildExplicitArrByRanges(cI); - DataArrayDouble *arr2=arr->selectByTupleIdSafe(res->begin(),res->end()); - const double expected1[30]={13.,14.,15.,16.,17.,18.,19.,20.,59.,60.,61.,62.,63.,64.,95.,96.,97.,98.,99.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.}; - DataArrayDouble *arr3=DataArrayDouble::New(); arr3->useArray(expected1,false,CPP_DEALLOC,15,2); - CPPUNIT_ASSERT(arr2->isEqual(*arr3,1e-12)); - CPPUNIT_ASSERT(arr2->isEqual(*f2->getArray(),1e-12)); - // - cI->decrRef(); - arr3->decrRef(); - arr2->decrRef(); - arr->decrRef(); - m->decrRef(); - f->decrRef(); - f2->decrRef(); - sel->decrRef(); - res->decrRef(); -} - -void MEDCouplingBasicsTest5::testComputeSkin1() -{ - const double input1[5]={2.,3.4,5.6,7.7,8.0}; - const double input2[6]={2.,3.4,5.6,7.7,9.0,14.2}; - DataArrayDouble *arrX=DataArrayDouble::New(); arrX->alloc(5,1); std::copy(input1,input1+5,arrX->getPointer()); - DataArrayDouble *arrY=DataArrayDouble::New(); arrY->alloc(6,1); std::copy(input2,input2+6,arrY->getPointer()); - MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New() ; cmesh->setCoordsAt(0,arrX) ; cmesh->setCoordsAt(1,arrY); - MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); - cmesh->decrRef(); arrX->decrRef(); arrY->decrRef(); - // - MEDCouplingUMesh *skin=umesh->computeSkin(); - CPPUNIT_ASSERT_EQUAL(18,skin->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(1,skin->getMeshDimension()); - CPPUNIT_ASSERT(skin->getCoords()==umesh->getCoords()); - const int expected1[19]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54}; - const int expected2[54]={1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24}; - CPPUNIT_ASSERT_EQUAL((std::size_t)19,skin->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+19,skin->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)54,skin->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+54,skin->getNodalConnectivity()->getConstPointer())); - DataArrayInt *ids=skin->computeFetchedNodeIds(); - const int expected3[18]={0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29}; - CPPUNIT_ASSERT_EQUAL((std::size_t)18,ids->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+18,ids->getConstPointer())); - MEDCouplingUMesh *part=dynamic_cast(umesh->buildFacePartOfMySelfNode(ids->begin(),ids->end(),true)); - part->setName(skin->getName().c_str()); - CPPUNIT_ASSERT(part->isEqual(skin,1e-12)); - MEDCouplingUMesh *part2=dynamic_cast(part->buildPartOfMySelf2(1,18,2,true)); - DataArrayInt *ids2=DataArrayInt::Range(0,18,2); - part->setPartOfMySelf(ids2->begin(),ids2->end(),*part2); - ids2->decrRef(); - CPPUNIT_ASSERT(!part->isEqual(skin,1e-12)); - DataArrayInt *trad=part->zipConnectivityTraducer(0); - CPPUNIT_ASSERT_EQUAL(9,part->getNumberOfCells()); - const int expected4[18]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,trad->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,trad->getNbOfElems()); - trad->decrRef(); - part->decrRef(); - part2->decrRef(); - // - ids->decrRef(); - umesh->decrRef(); - skin->decrRef(); -} - -void MEDCouplingBasicsTest5::testUMeshSetPartOfMySelf2() -{ - // resize with explicit ids list - MEDCouplingUMesh *m=build2DTargetMesh_1(); - std::set s; s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - const int ids1[3]={0,3,4}; - MEDCouplingUMesh *part=static_cast(m->buildPartOfMySelf(ids1,ids1+3,true)); - part->simplexize(0)->decrRef(); - const int ids2[3]={1,2,5}; - MEDCouplingUMesh *part2=static_cast(part->buildPartOfMySelf(ids2,ids2+3,true)); - m->setPartOfMySelf(ids1,ids1+3,*part2); - const int expected1[20]={3,0,4,1,3,1,4,2,3,4,5,2,3,6,7,4,3,7,5,4}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+20,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)20,m->getNodalConnectivity()->getNbOfElems()); - const int expected2[6]={0,4,8,12,16,20}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); part2->decrRef(); - // no resize with explicit ids list - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf(ids1,ids1+2,true)); - part->convertAllToPoly(); - m->setPartOfMySelf(ids1+1,ids1+3,*part); - const int expected3[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+23,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); - const int expected4[6]={0,5,9,13,18,23}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); - // resize with range ids - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf2(3,5,1,true)); - m->setPartOfMySelf2(1,3,1,*part); - const int expected5[25]={4,0,3,4,1,4,6,7,4,3,4,7,8,5,4,4,6,7,4,3,4,7,8,5,4}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+25,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)25,m->getNodalConnectivity()->getNbOfElems()); - const int expected6[6]={0,5,10,15,20,25}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_QUAD4); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); - // no resize with range ids - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf2(0,5,3,true)); - part->convertAllToPoly(); - m->setPartOfMySelf2(3,5,1,*part); - const int expected7[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; - CPPUNIT_ASSERT(std::equal(expected7,expected7+23,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); - const int expected8[6]={0,5,9,13,18,23}; - CPPUNIT_ASSERT(std::equal(expected8,expected8+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); -s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); - // no resize with range ids negative direction - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf2(3,-1,-3,true)); - part->convertAllToPoly(); - m->setPartOfMySelf2(4,2,-1,*part); - const int expected9[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; - CPPUNIT_ASSERT(std::equal(expected9,expected9+23,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); - const int expected10[6]={0,5,9,13,18,23}; - CPPUNIT_ASSERT(std::equal(expected10,expected10+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - part->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testUnPolyze3() -{ - const double coord[18]={0.0,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.0,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5}; - const int conn[22]={1,2,5,4,-1,4,3,0,1,-1,2,0,3,5,-1,0,2,1,-1,4,5,3}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("a mesh",3); - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,22,conn); - m->finishInsertingCells(); - DataArrayDouble *coords=DataArrayDouble::New(); - coords->alloc(6,3); - std::copy(coord,coord+18,coords->getPointer()); - m->setCoords(coords); - coords->decrRef(); - m->checkCoherency(); - // - MEDCouplingFieldDouble *vol=m->getMeasureField(ON_CELLS); - CPPUNIT_ASSERT_EQUAL(1,vol->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,vol->getArray()->getIJ(0,0),1e-12); - vol->decrRef(); - // - m->unPolyze(); - CPPUNIT_ASSERT_EQUAL(1,m->getNumberOfCells()); - std::set s; s.insert(INTERP_KERNEL::NORM_PENTA6); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - // - const int expected1[2]={0,7}; - const int expected2[7]={16,0,2,1,3,5,4}; - CPPUNIT_ASSERT_EQUAL(2,m->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+2,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL(7,m->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+7,m->getNodalConnectivity()->getConstPointer())); - // - vol=m->getMeasureField(ON_CELLS); - CPPUNIT_ASSERT_EQUAL(1,vol->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,vol->getArray()->getIJ(0,0),1e-12); - vol->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testKrSpatialDiscretization1() -{ - const double srcPointCoordsX[10]={0.8401877171547095, 0.7830992237586059, 0.9116473579367843, 0.335222755714889, 0.2777747108031878, 0.4773970518621602, 0.3647844727918433, 0.9522297251747128, 0.6357117279599009, 0.1416025553558034}; - const double srcFieldValsOnPoints[10]={2.129892434968836, 2.295320474540621, 1.931948594981134, 2.728013590937196, 2.715603240418478, 2.661778472822935, 2.695696990104364, 1.893710234970982, 2.529628016549284, 2.728432341300668}; - const double targetPointCoordsX[40]={-0.5,-0.45,-0.4,-0.35,-0.3,-0.25,-0.2,-0.15,-0.1,-0.05,-6.93889390391e-17,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45}; - const double targetFieldValsExpected[40]={2.975379475824351, 2.95613491917003, 2.936890362515361, 2.917645805861018, 2.898401249206574, 2.879156692552137, 2.859912135897732, 2.840667579243201, 2.821423022588731, 2.802178465934342, 2.78293390927989, 2.763689352625457, 2.744444795971001, 2.725209522098197, 2.709077577124666, 2.706677252549218, 2.727467797847971, 2.713338094723676, 2.671342424824244, 2.664877370146978, 2.653840141412181, 2.619607861392791, 2.569777214476479, 2.513263929794591, 2.450732752808528, 2.368313560985155, 2.250909795670307, 2.098194272085416, 1.954257891732065, 1.895040660973802, 1.865256788315972, 1.835475248687992, 1.80569370905998, 1.775912169431971, 1.746130629803976, 1.716349090175918, 1.686567550547855, 1.656786010919941, 1.627004471291988, 1.597222931663817}; - // - int nbOfInputPoints=10; - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES_KR,ONE_TIME); - DataArrayDouble *srcArrX=DataArrayDouble::New(); - srcArrX->alloc(nbOfInputPoints,1); - std::copy(srcPointCoordsX,srcPointCoordsX+nbOfInputPoints,srcArrX->getPointer()); - MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New("aMesh"); - cmesh->setCoordsAt(0,srcArrX); - MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); - f->setMesh(umesh); - DataArrayDouble *srcVals=DataArrayDouble::New(); - srcVals->alloc(nbOfInputPoints,1); - std::copy(srcFieldValsOnPoints,srcFieldValsOnPoints+nbOfInputPoints,srcVals->getPointer()); - f->setArray(srcVals); - f->checkCoherency(); - // - double *res0=new double[1]; - f->getValueOn(targetPointCoordsX,res0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(targetFieldValsExpected[0],res0[0],1e-10); - delete [] res0; - // - DataArrayDouble *valuesToTest=f->getValueOnMulti(targetPointCoordsX,40); - CPPUNIT_ASSERT_EQUAL(40,valuesToTest->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,valuesToTest->getNumberOfComponents()); - for(int i=0;i<40;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(targetFieldValsExpected[i],valuesToTest->getIJ(i,0),1e-10); - valuesToTest->decrRef(); - // - cmesh->decrRef(); - umesh->decrRef(); - srcArrX->decrRef(); - srcVals->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest5::testDuplicateEachTupleNTimes1() -{ - const double vals0[4]={9.,8.,7.,6.}; - DataArrayDouble *d=DataArrayDouble::New(); d->useArray(vals0,false,CPP_DEALLOC,4,1); d->setInfoOnComponent(0,"mass [kg]"); d->setName("aname"); - DataArrayDouble *d2=d->duplicateEachTupleNTimes(3); - const double vals1[12]={9.,9.,9.,8.,8.,8.,7.,7.,7.,6.,6.,6.}; - DataArrayDouble *d3=DataArrayDouble::New(); d3->useArray(vals1,false,CPP_DEALLOC,4*3,1); d3->setName("aname"); d3->setInfoOnComponent(0,"mass [kg]"); - CPPUNIT_ASSERT(d2->isEqual(*d2,1e-14)); d3->decrRef(); - d->decrRef(); - d2->decrRef(); - // - const int vals2[4]={9,8,7,6}; - DataArrayInt *d4=DataArrayInt::New(); d4->useArray(vals2,false,CPP_DEALLOC,4,1); d4->setInfoOnComponent(0,"mass [kg]") ; d4->setName("aname"); - DataArrayInt *d5=d4->duplicateEachTupleNTimes(3); - const int vals3[12]={9,9,9,8,8,8,7,7,7,6,6,6}; - DataArrayInt *d6=DataArrayInt::New(); d6->useArray(vals3,false,CPP_DEALLOC,4*3,1); d6->setName("aname"); d6->setInfoOnComponent(0,"mass [kg]"); - CPPUNIT_ASSERT(d5->isEqual(*d6)); d6->decrRef(); - d4->decrRef(); - d5->decrRef(); -} - -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp5() -{ - // coordinates - DataArrayDouble *coords=DataArrayDouble::New(); - const double coordsData[376]={41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818}; - coords->useArray(coordsData,false,CPP_DEALLOC,188,2); - coords->setName(""); - DataArrayInt *conn=DataArrayInt::New(); - const int connData[540]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175}; - conn->useArray(connData,false,CPP_DEALLOC,540,1); - conn->setName(""); - DataArrayInt *connI=DataArrayInt::New(); - const int connIData[61]={0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540}; - connI->useArray(connIData,false,CPP_DEALLOC,61,1); - connI->setName(""); - // - MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fix",2); - m1->setCoords(coords); - m1->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - coords=DataArrayDouble::New(); - const double coordsData2[84]={46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59}; - coords->useArray(coordsData2,false,CPP_DEALLOC,42,2); - coords->setName(""); - // connectivity - conn=DataArrayInt::New(); - const int connData2[72]={8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36}; - conn->useArray(connData2,false,CPP_DEALLOC,72,1); - conn->setName(""); - connI=DataArrayInt::New(); - const int connIData2[9]={0,9,18,27,36,45,54,63,72}; - connI->useArray(connIData2,false,CPP_DEALLOC,9,1); - connI->setName(""); - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); - m2->setCoords(coords); - m2->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - CPPUNIT_ASSERT_EQUAL(105,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(105,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(105,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(704,m3->getNumberOfNodes()); - // - const double areaExpected[105]={-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241}; - const int expected1[105]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59}; - const int expected2[105]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; - MEDCouplingFieldDouble *f3f=m3->getMeasureField(ON_CELLS); - const double *f3=f3f->getArray()->getConstPointer(); - for(int i=0;i<105;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(areaExpected[i],f3[i],1e-10); - CPPUNIT_ASSERT_EQUAL(expected1[i],d1->getIJ(i,0)); - CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(i,0)); - } - // - f3f->decrRef(); - m3->decrRef(); - d1->decrRef(); - d2->decrRef(); - m2->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIBuildUnique1() -{ - DataArrayInt *d=DataArrayInt::New(); - const int dData[14]={1,2,2,3,3,3,3,4,5,5,7,7,7,19}; - d->useArray(dData,false,CPP_DEALLOC,14,1); - const int expectedData[7]={1,2,3,4,5,7,19}; - // - DataArrayInt *e=d->buildUnique(); - CPPUNIT_ASSERT_EQUAL(7,e->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,e->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expectedData[i],e->getIJ(i,0)); - // - e->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIPartitionByDifferentValues1() -{ - const int data[9]={1,0,1,2,0,2,2,-3,2}; - const int expected1[4]={-3,0,1,2}; - const int expected2_0[1]={7}; - const int expected2_1[2]={1,4}; - const int expected2_2[2]={0,2}; - const int expected2_3[4]={3,5,6,8}; - DataArrayInt *d=DataArrayInt::New(); - d->useArray(data,false,CPP_DEALLOC,9,1); - std::vector f; - static const int nbOfOutputsExpected=4; - std::vector e=d->partitionByDifferentValues(f); - d->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)e.size()); - CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)f.size()); - for(int i=0;igetNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,e[1]->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,e[2]->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,e[3]->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(1,e[0]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,e[1]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,e[2]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,e[3]->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+1,e[0]->begin())); - CPPUNIT_ASSERT(std::equal(expected2_1,expected2_1+2,e[1]->begin())); - CPPUNIT_ASSERT(std::equal(expected2_2,expected2_2+2,e[2]->begin())); - CPPUNIT_ASSERT(std::equal(expected2_3,expected2_3+4,e[3]->begin())); - e[0]->decrRef(); e[1]->decrRef(); e[2]->decrRef(); e[3]->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAICheckMonotonic1() -{ - const int data1[6]={-1,0,2,2,4,5}; - const int data2[6]={6,2,0,-8,-9,-56}; - const int data3[6]={-1,0,3,2,4,6}; - const int data4[6]={7,5,2,3,0,-6}; - DataArrayInt *d=DataArrayInt::New(); - d->useArray(data1,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(d->isMonotonic(true)); - CPPUNIT_ASSERT(!d->isMonotonic(false)); - d->checkMonotonic(true); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->useArray(data2,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(d->isMonotonic(false)); - CPPUNIT_ASSERT(!d->isMonotonic(true)); - d->checkMonotonic(false); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - d->useArray(data3,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(!d->isMonotonic(false)); - CPPUNIT_ASSERT(!d->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->useArray(data4,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(!d->isMonotonic(false)); - CPPUNIT_ASSERT(!d->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->useArray(data4,false,CPP_DEALLOC,0,1); - CPPUNIT_ASSERT(d->isMonotonic(true)); - CPPUNIT_ASSERT(d->isMonotonic(false)); - d->checkMonotonic(true); - d->checkMonotonic(false); - d->useArray(data4,false,CPP_DEALLOC,3,2);//throw because nbComp!=1 - CPPUNIT_ASSERT_THROW(d->isMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->isMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->decrRef(); -} - -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp6() -{ - // coordinates - DataArrayDouble *coords=DataArrayDouble::New(); - const double coordsData[16]={2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15}; - coords->useArray(coordsData,false,CPP_DEALLOC,8,2); - // connectivity - DataArrayInt *conn=DataArrayInt::New(); - const int connData[9]={8,0,3,5,1,4,6,7,2}; - conn->useArray(connData,false,CPP_DEALLOC,9,1); - DataArrayInt *connI=DataArrayInt::New(); - const int connIData[2]={0,9}; - connI->useArray(connIData,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fixe",2); - m1->setCoords(coords); - m1->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - coords=DataArrayDouble::New(); - const double coordsData2[26]={-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839}; - coords->useArray(coordsData2,false,CPP_DEALLOC,13,2); - // connectivity - conn=DataArrayInt::New(); - const int connData2[18]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12}; - conn->useArray(connData2,false,CPP_DEALLOC,18,1); - connI=DataArrayInt::New(); - const int connIData2[3]={0,9,18}; - connI->useArray(connIData2,false,CPP_DEALLOC,3,1); - // - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); - m2->setCoords(coords); - m2->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - CPPUNIT_ASSERT_EQUAL(4,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(4,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(43,m3->getNumberOfNodes()); - bool areMerged=false; - int newNbOfNodes=-1; - m3->mergeNodes(1e-12,areMerged,newNbOfNodes)->decrRef(); - CPPUNIT_ASSERT_EQUAL(35,m3->getNumberOfNodes()); - m3->zipCoords(); - CPPUNIT_ASSERT_EQUAL(23,m3->getNumberOfNodes()); - // - MEDCouplingFieldDouble *f=m3->getMeasureField(true); - const double *vals=f->getArray()->getConstPointer(); - const double valuesExpected[4]={1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i],vals[i],1e-12); - f->decrRef(); - // - m1->decrRef(); - m2->decrRef(); - m3->decrRef(); - d1->decrRef(); - d2->decrRef(); -} - -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp7() -{ - double eps = 1.0e-8; - // coordinates circle - SEE getCircle() on the Python side - DataArrayDouble *coords1=DataArrayDouble::New(); - const double coordsData1[16]={0.5328427124746189, -0.08284271247461905, -0.03284271247461901, 0.4828427124746191, -0.03284271247461906, -0.082842712474619, 0.5328427124746191, 0.482842712474619}; - coords1->useArray(coordsData1,false,CPP_DEALLOC,8,2); - // connectivity - DataArrayInt *conn1=DataArrayInt::New(); - const int connData1[5]={INTERP_KERNEL::NORM_QPOLYG,0,1,2,3}; - conn1->useArray(connData1,false,CPP_DEALLOC,5,1); - DataArrayInt *connI1=DataArrayInt::New(); - const int connIData1[2]={0,5}; - connI1->useArray(connIData1,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *m1=MEDCouplingUMesh::New("circle",2); - m1->setCoords(coords1); - m1->setConnectivity(conn1,connI1,true); - coords1->decrRef(); conn1->decrRef(); connI1->decrRef(); - - // square - DataArrayDouble *coords2=DataArrayDouble::New(); - const double coordsData2[8]={-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5}; - coords2->useArray(coordsData2,false,CPP_DEALLOC,4,2); - // connectivity - DataArrayInt *conn2=DataArrayInt::New(); - const int connData2[5]={INTERP_KERNEL::NORM_POLYGON, 0,1,2,3}; - conn2->useArray(connData2,false,CPP_DEALLOC,5,1); - DataArrayInt *connI2=DataArrayInt::New(); - const int connIData2[2]={0,5}; - connI2->useArray(connIData2,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("square",2); - m2->setCoords(coords2); - m2->setConnectivity(conn2,connI2,true); - coords2->decrRef(); conn2->decrRef(); connI2->decrRef(); - - DataArrayInt * resToM1 = 0, * resToM2 = 0; - MEDCouplingUMesh *m_intersec=MEDCouplingUMesh::Intersect2DMeshes(m2, m1, eps, resToM1, resToM2); - m_intersec->zipCoords(); - - const double coo_tgt[34]={-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, \ - -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, \ - -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5,\ - -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613}; - const int conn_tgt[22]={32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16}; - const int connI_tgt[3]={0, 9, 22}; - const int res1_tgt[2] = {0, 0}; - const int res2_tgt[2] = {0, -1}; - - CPPUNIT_ASSERT(std::equal(conn_tgt,conn_tgt+22,m_intersec->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(connI_tgt,connI_tgt+3,m_intersec->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(res1_tgt,res1_tgt+2,resToM1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(res2_tgt,res2_tgt+2,resToM2->getConstPointer())); - for(int i=0;i<34;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(coo_tgt[i],m_intersec->getCoords()->getIJ(0,i),1e-12); - m1->decrRef(); m2->decrRef(); m_intersec->decrRef(); - resToM1->decrRef(); resToM2->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIBuildSubstractionOptimized1() -{ - const int tab1[7]={1,3,5,6,7,9,13}; - const int tab2[3]={3,5,9}; - const int tab3[3]={1,3,5}; - DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); - DataArrayInt *da2=DataArrayInt::New(); da2->useArray(tab2,false,CPP_DEALLOC,3,1); - DataArrayInt *da3=DataArrayInt::New(); da3->useArray(tab3,false,CPP_DEALLOC,3,1); - DataArrayInt *da4=DataArrayInt::New(); da4->useArray(tab1,false,CPP_DEALLOC,7,1); - // - DataArrayInt *a=0; - a=da1->buildSubstractionOptimized(da2); - CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - const int expected1_0[4]={1,6,7,13}; - CPPUNIT_ASSERT(std::equal(expected1_0,expected1_0+4,a->begin())); - a->decrRef(); - // - a=da1->buildSubstractionOptimized(da3); - CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - const int expected2_0[4]={6,7,9,13}; - CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+4,a->begin())); - a->decrRef(); - // - a=da1->buildSubstractionOptimized(da4); - CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - a->decrRef(); - // - da1->decrRef(); - da2->decrRef(); - da3->decrRef(); - da4->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIIsStrictlyMonotonic1() -{ - const int tab1[7]={1,3,5,6,7,9,13}; - DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); - da1->checkStrictlyMonotonic(true); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - int tab2[7]={1,3,5,6,6,9,13}; - da1=DataArrayInt::New(); da1->useArray(tab2,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - const int tab3[7]={1,3,5,6,5,9,13}; - da1=DataArrayInt::New(); da1->useArray(tab3,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - const int tab4[7]={13,9,7,6,5,3,1}; - da1=DataArrayInt::New(); da1->useArray(tab4,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); - da1->checkStrictlyMonotonic(false); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); - // - const int tab5[7]={13,9,6,6,5,3,1}; - da1=DataArrayInt::New(); da1->useArray(tab5,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); - // - const int tab6[7]={13,9,5,6,5,3,1}; - da1=DataArrayInt::New(); da1->useArray(tab6,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,0,1); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); - da1->checkStrictlyMonotonic(true); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); - da1->checkStrictlyMonotonic(false); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); - // - da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,1,1); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); - da1->checkStrictlyMonotonic(true); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); - da1->checkStrictlyMonotonic(false); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); -} - -void MEDCouplingBasicsTest5::testSimplexize3() -{ - const int conn[24]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("toto",3); - m->allocateCells(0); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+0); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+12); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+20); - const double coords[72]={0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.,2.,0.,0.,2.,1.,0.,3.,1.,0.,3.,0.,0.,2.,0.,1.,2.,1.,1.,3.,1.,1.,3.,0.,1.,4.,0.,0.,4.,1.,0.,5.,1.,0.,5.,0.,0.,4.,0.,1.,4.,1.,1.,5.,1.,1.,5.,0.,1.,6.,0.,0.,6.,1.,0.,7.,0.,0.,6.,0.,1.}; - DataArrayDouble *c=DataArrayDouble::New(); - c->useArray(coords,false,CPP_DEALLOC,24,3); - m->setCoords(c); - c->decrRef(); - m->checkCoherency2(); - // - MEDCouplingUMesh *m1=static_cast(m->deepCpy()); - DataArrayInt *d1=m1->simplexize(INTERP_KERNEL::PLANAR_FACE_5); - m1->checkCoherency2(); - MEDCouplingFieldDouble *f1=m1->getMeasureField(ON_CELLS); - const double vol1Expected[12]={1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6}; - CPPUNIT_ASSERT_EQUAL(1,f1->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,f1->getArray()->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1Expected[i],f1->getIJ(i,0),1e-12); - const int connExpected1[60]={14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23}; - const int connIExpected1[13]={0,5,10,15,20,25,30,35,40,45,50,55,60}; - const int n2o1[12]={0,1,1,1,1,1,2,2,2,2,2,3}; - CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivity()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(60,m1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivityIndex()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(13,m1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExpected1,connExpected1+60,m1->getNodalConnectivity()->begin())); - CPPUNIT_ASSERT(std::equal(connIExpected1,connIExpected1+13,m1->getNodalConnectivityIndex()->begin())); - CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(n2o1,n2o1+12,d1->begin())); - f1->decrRef(); - m1->decrRef(); - d1->decrRef(); - // - MEDCouplingUMesh *m2=static_cast(m->deepCpy()); - DataArrayInt *d2=m2->simplexize(INTERP_KERNEL::PLANAR_FACE_6); - m2->checkCoherency2(); - MEDCouplingFieldDouble *f2=m2->getMeasureField(ON_CELLS); - const double vol2Expected[14]={1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6}; - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(14,f2->getArray()->getNumberOfTuples()); - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol2Expected[i],f2->getIJ(i,0),1e-12); - const int connExpected2[70]={14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23}; - const int connIExpected2[15]={0,5,10,15,20,25,30,35,40,45,50,55,60,65,70}; - const int n2o2[14]={0,1,1,1,1,1,1,2,2,2,2,2,2,3}; - CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivity()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(70,m2->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivityIndex()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(15,m2->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExpected2,connExpected2+70,m2->getNodalConnectivity()->begin())); - CPPUNIT_ASSERT(std::equal(connIExpected2,connIExpected2+15,m2->getNodalConnectivityIndex()->begin())); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(14,d2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(n2o2,n2o2+14,d2->begin())); - f2->decrRef(); - m2->decrRef(); - d2->decrRef(); - // - m->decrRef(); -} diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx deleted file mode 100644 index a4cedd497..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTEST5_HXX__ -#define __MEDCOUPLINGBASICSTEST5_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest5 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest5); - CPPUNIT_TEST( testUMeshTessellate2D1 ); - CPPUNIT_TEST( testUMeshTessellate2DCurve1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp4 ); - CPPUNIT_TEST( testGetCellIdsCrossingPlane1 ); - CPPUNIT_TEST( testBuildSlice3D1 ); - CPPUNIT_TEST( testBuildSlice3DSurf1 ); - CPPUNIT_TEST( testDataArrayDoubleAdvSetting1 ); - CPPUNIT_TEST( testDataArrayIntAdvSetting1 ); - CPPUNIT_TEST( testBuildDescendingConnec2Of3DMesh1 ); - CPPUNIT_TEST( testAre2DCellsNotCorrectlyOriented1 ); - CPPUNIT_TEST( testDataArrayAbs1 ); - CPPUNIT_TEST( testGetValueOn3 ); - CPPUNIT_TEST( testGetNodeIdsOfCell2 ); - CPPUNIT_TEST( testRenumberNodesInConn1 ); - CPPUNIT_TEST( testComputeNeighborsOfCells1 ); - CPPUNIT_TEST( testCheckButterflyCellsBug1 ); - CPPUNIT_TEST( testDataArrayIntRange1 ); - CPPUNIT_TEST( testDataArrayDoubleGetMinMaxPerComponent1 ); - CPPUNIT_TEST( testDataArrayIntGetHashCode1 ); - CPPUNIT_TEST( testZipConnectivityPol1 ); - CPPUNIT_TEST( testConvexEnvelop2D1 ); - CPPUNIT_TEST( testDataArraySort1 ); - CPPUNIT_TEST( testPartitionBySpreadZone1 ); - CPPUNIT_TEST( testGiveCellsWithType1 ); - CPPUNIT_TEST( testBuildSlice3D2 ); - CPPUNIT_TEST( testComputeTupleIdsToSelectFromCellIds1 ); - CPPUNIT_TEST( testComputeSkin1 ); - CPPUNIT_TEST( testUMeshSetPartOfMySelf2 ); - CPPUNIT_TEST( testUnPolyze3 ); - CPPUNIT_TEST( testKrSpatialDiscretization1 ); - CPPUNIT_TEST( testDuplicateEachTupleNTimes1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp5 ); - CPPUNIT_TEST( testDAIBuildUnique1 ); - CPPUNIT_TEST( testDAIPartitionByDifferentValues1 ); - CPPUNIT_TEST( testDAICheckMonotonic1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp6 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp7 ); - CPPUNIT_TEST( testDAIBuildSubstractionOptimized1 ); - CPPUNIT_TEST( testDAIIsStrictlyMonotonic1 ); - CPPUNIT_TEST( testSimplexize3 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testUMeshTessellate2D1(); - void testUMeshTessellate2DCurve1(); - void testIntersect2DMeshesTmp4(); - void testGetCellIdsCrossingPlane1(); - void testBuildSlice3D1(); - void testBuildSlice3DSurf1(); - void testDataArrayDoubleAdvSetting1(); - void testDataArrayIntAdvSetting1(); - void testBuildDescendingConnec2Of3DMesh1(); - void testAre2DCellsNotCorrectlyOriented1(); - void testDataArrayAbs1(); - void testGetValueOn3(); - void testGetNodeIdsOfCell2(); - void testRenumberNodesInConn1(); - void testComputeNeighborsOfCells1(); - void testCheckButterflyCellsBug1(); - void testDataArrayIntRange1(); - void testDataArrayDoubleGetMinMaxPerComponent1(); - void testDataArrayIntGetHashCode1(); - void testZipConnectivityPol1(); - void testConvexEnvelop2D1(); - void testDataArraySort1(); - void testPartitionBySpreadZone1(); - void testGiveCellsWithType1(); - void testBuildSlice3D2(); - void testComputeTupleIdsToSelectFromCellIds1(); - void testComputeSkin1(); - void testUMeshSetPartOfMySelf2(); - void testUnPolyze3(); - void testKrSpatialDiscretization1(); - void testDuplicateEachTupleNTimes1(); - void testIntersect2DMeshesTmp5(); - void testDAIBuildUnique1(); - void testDAIPartitionByDifferentValues1(); - void testDAICheckMonotonic1(); - void testIntersect2DMeshesTmp6(); - void testIntersect2DMeshesTmp7(); - void testDAIBuildSubstractionOptimized1(); - void testDAIIsStrictlyMonotonic1(); - void testSimplexize3(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx deleted file mode 100644 index fde75b35c..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx +++ /dev/null @@ -1,1167 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -int connITT[201]={0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1029, 1058, 1087, 1116, 1145, 1174, 1203, - 1232, 1261, 1290, 1319, 1348, 1377, 1406, 1435, 1464, 1493, 1522, 1551, 1580, 1609, 1638, 1667, 1696, 1725, 1754, 1783, 1812, 1841, 1870, 1899, - 1928, 1957, 1986, 2015, 2044, 2073, 2102, 2131, 2160, 2189, 2218, 2247, 2276, 2305, 2334, 2363, 2392, 2421, 2450, 2479, 2508, 2537, 2566, 2595, - 2624, 2653, 2682, 2711, 2740, 2769, 2798, 2827, 2856, 2885, 2914, 2943, 2972, 3001, 3030, 3059, 3088, 3117, 3146, 3175, 3204, 3233, 3262, 3291, - 3320, 3349, 3378, 3407, 3436, 3465, 3494, 3523, 3552, 3581, 3610, 3639, 3668, 3697, 3726, 3755, 3784, 3813, 3842, 3871, 3900, 3929, 3958, 3987, - 4016, 4045, 4074, 4103, 4132, 4161, 4190, 4219, 4248, 4277, 4306, 4335, 4364, 4393, 4422, 4451, 4480, 4509, 4538, 4567, 4596, 4625, 4654, 4683, - 4712, 4741, 4770, 4799, 4828, 4857, 4886, 4915, 4944, 4973, 5002, 5031, 5060, 5089, 5118, 5147, 5176, 5205, 5234, 5263, 5292, 5321, 5350, 5379, - 5408, 5437, 5466, 5495, 5524, 5553, 5582, 5611, 5640, 5669, 5698, 5727, 5756, 5785, 5814, 5843, 5872, 5901, 5930, 5959, 5988, 6017, 6046, 6075, - 6104, 6133, 6162, 6191, 6220}; - int connTT[6220]={0, 1, 2, 3, 4, 5, 6, -1, 0, 7, 8, 1, -1, 1, 8, 9, 2, -1, 2, 9, 10, 3, -1, 3, 10, 11, 4, -1, 4, 11, 12, 5, -1, 5, 12, 13, 6, -1, 6, 13, 7, 0, -1, 7, 13, 12, 11, 10, 9, 8, 14, 15, 16, 17, 18, 19, - 20, -1, 14, 21, 22, 15, -1, 15, 22, 23, 16, -1, 16, 23, 24, 17, -1, 17, 24, 25, 18, -1, 18, 25, 26, 19, -1, 19, 26, 27, 20, -1, 20, 27, 21, 14, -1, 21, 27, 26, 25, 24, 23, 22, 28, 29, 30, 31, 32, - 33, 34, -1, 28, 35, 36, 29, -1, 29, 36, 37, 30, -1, 30, 37, 38, 31, -1, 31, 38, 39, 32, -1, 32, 39, 40, 33, -1, 33, 40, 41, 34, -1, 34, 41, 35, 28, -1, 35, 41, 40, 39, 38, 37, 36, 42, 43, 44, 45, - 46, 47, 48, -1, 42, 49, 50, 43, -1, 43, 50, 51, 44, -1, 44, 51, 52, 45, -1, 45, 52, 53, 46, -1, 46, 53, 54, 47, -1, 47, 54, 55, 48, -1, 48, 55, 49, 42, -1, 49, 55, 54, 53, 52, 51, 50, 56, 57, 58, - 59, 60, 61, 62, -1, 56, 63, 64, 57, -1, 57, 64, 65, 58, -1, 58, 65, 66, 59, -1, 59, 66, 67, 60, -1, 60, 67, 68, 61, -1, 61, 68, 69, 62, -1, 62, 69, 63, 56, -1, 63, 69, 68, 67, 66, 65, 64, 70, 71, - 72, 73, 74, 75, 76, -1, 70, 77, 78, 71, -1, 71, 78, 79, 72, -1, 72, 79, 80, 73, -1, 73, 80, 81, 74, -1, 74, 81, 82, 75, -1, 75, 82, 83, 76, -1, 76, 83, 77, 70, -1, 77, 83, 82, 81, 80, 79, 78, 84, - 85, 86, 87, 88, 89, 90, -1, 84, 91, 92, 85, -1, 85, 92, 93, 86, -1, 86, 93, 94, 87, -1, 87, 94, 95, 88, -1, 88, 95, 96, 89, -1, 89, 96, 97, 90, -1, 90, 97, 91, 84, -1, 91, 97, 96, 95, 94, 93, 92, - 98, 99, 100, 101, 102, 103, 104, -1, 98, 105, 106, 99, -1, 99, 106, 107, 100, -1, 100, 107, 108, 101, -1, 101, 108, 109, 102, -1, 102, 109, 110, 103, -1, 103, 110, 111, 104, -1, 104, 111, 105, 98, - -1, 105, 111, 110, 109, 108, 107, 106, 112, 113, 114, 115, 116, 117, 118, -1, 112, 119, 120, 113, -1, 113, 120, 121, 114, -1, 114, 121, 122, 115, -1, 115, 122, 123, 116, -1, 116, 123, 124, 117, -1, - 117, 124, 125, 118, -1, 118, 125, 119, 112, -1, 119, 125, 124, 123, 122, 121, 120, 126, 127, 128, 129, 130, 131, 132, -1, 126, 133, 134, 127, -1, 127, 134, 135, 128, -1, 128, 135, 136, 129, -1, 129, - 136, 137, 130, -1, 130, 137, 138, 131, -1, 131, 138, 139, 132, -1, 132, 139, 133, 126, -1, 133, 139, 138, 137, 136, 135, 134, 140, 141, 142, 143, 144, 145, 146, -1, 140, 147, 148, 141, -1, 141, 148, - 149, 142, -1, 142, 149, 150, 143, -1, 143, 150, 151, 144, -1, 144, 151, 152, 145, -1, 145, 152, 153, 146, -1, 146, 153, 147, 140, -1, 147, 153, 152, 151, 150, 149, 148, 154, 155, 156, 157, 158, 159, - 160, -1, 154, 161, 162, 155, -1, 155, 162, 163, 156, -1, 156, 163, 164, 157, -1, 157, 164, 165, 158, -1, 158, 165, 166, 159, -1, 159, 166, 167, 160, -1, 160, 167, 161, 154, -1, 161, 167, 166, 165, - 164, 163, 162, 168, 169, 170, 171, 172, 173, 174, -1, 168, 175, 176, 169, -1, 169, 176, 177, 170, -1, 170, 177, 178, 171, -1, 171, 178, 179, 172, -1, 172, 179, 180, 173, -1, 173, 180, 181, 174, -1, - 174, 181, 175, 168, -1, 175, 181, 180, 179, 178, 177, 176, 182, 183, 184, 185, 186, 187, 188, -1, 182, 189, 190, 183, -1, 183, 190, 191, 184, -1, 184, 191, 192, 185, -1, 185, 192, 193, 186, -1, 186, - 193, 194, 187, -1, 187, 194, 195, 188, -1, 188, 195, 189, 182, -1, 189, 195, 194, 193, 192, 191, 190, 196, 197, 198, 199, 200, 201, 202, -1, 196, 203, 204, 197, -1, 197, 204, 205, 198, -1, 198, 205, - 206, 199, -1, 199, 206, 207, 200, -1, 200, 207, 208, 201, -1, 201, 208, 209, 202, -1, 202, 209, 203, 196, -1, 203, 209, 208, 207, 206, 205, 204, 210, 211, 212, 213, 214, 215, 216, -1, 210, 217, 218, - 211, -1, 211, 218, 219, 212, -1, 212, 219, 220, 213, -1, 213, 220, 221, 214, -1, 214, 221, 222, 215, -1, 215, 222, 223, 216, -1, 216, 223, 217, 210, -1, 217, 223, 222, 221, 220, 219, 218, 224, 225, - 226, 227, 228, 229, 230, -1, 224, 231, 232, 225, -1, 225, 232, 233, 226, -1, 226, 233, 234, 227, -1, 227, 234, 235, 228, -1, 228, 235, 236, 229, -1, 229, 236, 237, 230, -1, 230, 237, 231, 224, -1, - 231, 237, 236, 235, 234, 233, 232, 238, 239, 240, 241, 242, 243, 244, -1, 238, 245, 246, 239, -1, 239, 246, 247, 240, -1, 240, 247, 248, 241, -1, 241, 248, 249, 242, -1, 242, 249, 250, 243, -1, 243, - 250, 251, 244, -1, 244, 251, 245, 238, -1, 245, 251, 250, 249, 248, 247, 246, 252, 253, 254, 255, 256, 257, 258, -1, 252, 259, 260, 253, -1, 253, 260, 261, 254, -1, 254, 261, 262, 255, -1, 255, 262, - 263, 256, -1, 256, 263, 264, 257, -1, 257, 264, 265, 258, -1, 258, 265, 259, 252, -1, 259, 265, 264, 263, 262, 261, 260, 266, 267, 268, 269, 270, 271, 272, -1, 266, 273, 274, 267, -1, 267, 274, 275, - 268, -1, 268, 275, 276, 269, -1, 269, 276, 277, 270, -1, 270, 277, 278, 271, -1, 271, 278, 279, 272, -1, 272, 279, 273, 266, -1, 273, 279, 278, 277, 276, 275, 274, 280, 281, 282, 283, -1, 280, 284, - 285, 281, -1, 281, 285, 286, 282, -1, 282, 286, 287, 283, -1, 283, 287, 284, 280, -1, 284, 287, 286, 285, 288, 289, 290, 291, -1, 288, 292, 293, 289, -1, 289, 293, 294, 290, -1, 290, 294, 295, 291, - -1, 291, 295, 292, 288, -1, 292, 295, 294, 293, 296, 297, 298, 299, -1, 296, 300, 301, 297, -1, 297, 301, 302, 298, -1, 298, 302, 303, 299, -1, 299, 303, 300, 296, -1, 300, 303, 302, 301, 304, 305, - 306, 307, -1, 304, 308, 309, 305, -1, 305, 309, 310, 306, -1, 306, 310, 311, 307, -1, 307, 311, 308, 304, -1, 308, 311, 310, 309, 312, 313, 314, 315, -1, 312, 316, 317, 313, -1, 313, 317, 318, 314, - -1, 314, 318, 319, 315, -1, 315, 319, 316, 312, -1, 316, 319, 318, 317, 320, 321, 322, 323, -1, 320, 324, 325, 321, -1, 321, 325, 326, 322, -1, 322, 326, 327, 323, -1, 323, 327, 324, 320, -1, 324, - 327, 326, 325, 328, 329, 330, 331, -1, 328, 332, 333, 329, -1, 329, 333, 334, 330, -1, 330, 334, 335, 331, -1, 331, 335, 332, 328, -1, 332, 335, 334, 333, 336, 337, 338, 339, -1, 336, 340, 341, 337, - -1, 337, 341, 342, 338, -1, 338, 342, 343, 339, -1, 339, 343, 340, 336, -1, 340, 343, 342, 341, 344, 345, 346, 347, -1, 344, 348, 349, 345, -1, 345, 349, 350, 346, -1, 346, 350, 351, 347, -1, 347, - 351, 348, 344, -1, 348, 351, 350, 349, 352, 353, 354, 355, -1, 352, 356, 357, 353, -1, 353, 357, 358, 354, -1, 354, 358, 359, 355, -1, 355, 359, 356, 352, -1, 356, 359, 358, 357, 360, 361, 362, 363, - -1, 360, 364, 365, 361, -1, 361, 365, 366, 362, -1, 362, 366, 367, 363, -1, 363, 367, 364, 360, -1, 364, 367, 366, 365, 368, 369, 370, 371, -1, 368, 372, 373, 369, -1, 369, 373, 374, 370, -1, 370, - 374, 375, 371, -1, 371, 375, 372, 368, -1, 372, 375, 374, 373, 376, 377, 378, 379, -1, 376, 380, 381, 377, -1, 377, 381, 382, 378, -1, 378, 382, 383, 379, -1, 379, 383, 380, 376, -1, 380, 383, 382, - 381, 384, 385, 386, 387, -1, 384, 388, 389, 385, -1, 385, 389, 390, 386, -1, 386, 390, 391, 387, -1, 387, 391, 388, 384, -1, 388, 391, 390, 389, 392, 393, 394, 395, -1, 392, 396, 397, 393, -1, 393, - 397, 398, 394, -1, 394, 398, 399, 395, -1, 395, 399, 396, 392, -1, 396, 399, 398, 397, 400, 401, 402, 403, -1, 400, 404, 405, 401, -1, 401, 405, 406, 402, -1, 402, 406, 407, 403, -1, 403, 407, 404, - 400, -1, 404, 407, 406, 405, 408, 409, 410, 411, -1, 408, 412, 413, 409, -1, 409, 413, 414, 410, -1, 410, 414, 415, 411, -1, 411, 415, 412, 408, -1, 412, 415, 414, 413, 416, 417, 418, 419, -1, 416, - 420, 421, 417, -1, 417, 421, 422, 418, -1, 418, 422, 423, 419, -1, 419, 423, 420, 416, -1, 420, 423, 422, 421, 424, 425, 426, 427, -1, 424, 428, 429, 425, -1, 425, 429, 430, 426, -1, 426, 430, 431, - 427, -1, 427, 431, 428, 424, -1, 428, 431, 430, 429, 432, 433, 434, 435, -1, 432, 436, 437, 433, -1, 433, 437, 438, 434, -1, 434, 438, 439, 435, -1, 435, 439, 436, 432, -1, 436, 439, 438, 437, 440, - 441, 442, 443, -1, 440, 444, 445, 441, -1, 441, 445, 446, 442, -1, 442, 446, 447, 443, -1, 443, 447, 444, 440, -1, 444, 447, 446, 445, 448, 449, 450, 451, -1, 448, 452, 453, 449, -1, 449, 453, 454, - 450, -1, 450, 454, 455, 451, -1, 451, 455, 452, 448, -1, 452, 455, 454, 453, 456, 457, 458, 459, -1, 456, 460, 461, 457, -1, 457, 461, 462, 458, -1, 458, 462, 463, 459, -1, 459, 463, 460, 456, -1, - 460, 463, 462, 461, 464, 465, 466, 467, -1, 464, 468, 469, 465, -1, 465, 469, 470, 466, -1, 466, 470, 471, 467, -1, 467, 471, 468, 464, -1, 468, 471, 470, 469, 472, 473, 474, 475, -1, 472, 476, 477, - 473, -1, 473, 477, 478, 474, -1, 474, 478, 479, 475, -1, 475, 479, 476, 472, -1, 476, 479, 478, 477, 480, 481, 482, 483, -1, 480, 484, 485, 481, -1, 481, 485, 486, 482, -1, 482, 486, 487, 483, -1, - 483, 487, 484, 480, -1, 484, 487, 486, 485, 488, 489, 490, 491, -1, 488, 492, 493, 489, -1, 489, 493, 494, 490, -1, 490, 494, 495, 491, -1, 491, 495, 492, 488, -1, 492, 495, 494, 493, 496, 497, 498, - 499, -1, 496, 500, 501, 497, -1, 497, 501, 502, 498, -1, 498, 502, 503, 499, -1, 499, 503, 500, 496, -1, 500, 503, 502, 501, 504, 505, 506, 507, -1, 504, 508, 509, 505, -1, 505, 509, 510, 506, -1, 506, - 510, 511, 507, -1, 507, 511, 508, 504, -1, 508, 511, 510, 509, 512, 513, 514, 515, -1, 512, 516, 517, 513, -1, 513, 517, 518, 514, -1, 514, 518, 519, 515, -1, 515, 519, 516, 512, -1, 516, 519, 518, 517, - 520, 521, 522, 523, -1, 520, 524, 525, 521, -1, 521, 525, 526, 522, -1, 522, 526, 527, 523, -1, 523, 527, 524, 520, -1, 524, 527, 526, 525, 528, 529, 530, 531, -1, 528, 532, 533, 529, -1, 529, 533, - 534, 530, -1, 530, 534, 535, 531, -1, 531, 535, 532, 528, -1, 532, 535, 534, 533, 536, 537, 538, 539, -1, 536, 540, 541, 537, -1, 537, 541, 542, 538, -1, 538, 542, 543, 539, -1, 539, 543, 540, 536, - -1, 540, 543, 542, 541, 544, 545, 546, 547, -1, 544, 548, 549, 545, -1, 545, 549, 550, 546, -1, 546, 550, 551, 547, -1, 547, 551, 548, 544, -1, 548, 551, 550, 549, 552, 553, 554, 555, -1, 552, 556, - 557, 553, -1, 553, 557, 558, 554, -1, 554, 558, 559, 555, -1, 555, 559, 556, 552, -1, 556, 559, 558, 557, 560, 561, 562, 563, -1, 560, 564, 565, 561, -1, 561, 565, 566, 562, -1, 562, 566, 567, 563, - -1, 563, 567, 564, 560, -1, 564, 567, 566, 565, 568, 569, 570, 571, -1, 568, 572, 573, 569, -1, 569, 573, 574, 570, -1, 570, 574, 575, 571, -1, 571, 575, 572, 568, -1, 572, 575, 574, 573, 576, 577, - 578, 579, -1, 576, 580, 581, 577, -1, 577, 581, 582, 578, -1, 578, 582, 583, 579, -1, 579, 583, 580, 576, -1, 580, 583, 582, 581, 584, 585, 586, 587, -1, 584, 588, 589, 585, -1, 585, 589, 590, 586, - -1, 586, 590, 591, 587, -1, 587, 591, 588, 584, -1, 588, 591, 590, 589, 592, 593, 594, 595, -1, 592, 596, 597, 593, -1, 593, 597, 598, 594, -1, 594, 598, 599, 595, -1, 595, 599, 596, 592, -1, 596, - 599, 598, 597, 600, 601, 602, 603, -1, 600, 604, 605, 601, -1, 601, 605, 606, 602, -1, 602, 606, 607, 603, -1, 603, 607, 604, 600, -1, 604, 607, 606, 605, 608, 609, 610, 611, -1, 608, 612, 613, 609, - -1, 609, 613, 614, 610, -1, 610, 614, 615, 611, -1, 611, 615, 612, 608, -1, 612, 615, 614, 613, 616, 617, 618, 619, -1, 616, 620, 621, 617, -1, 617, 621, 622, 618, -1, 618, 622, 623, 619, -1, 619, - 623, 620, 616, -1, 620, 623, 622, 621, 624, 625, 626, 627, -1, 624, 628, 629, 625, -1, 625, 629, 630, 626, -1, 626, 630, 631, 627, -1, 627, 631, 628, 624, -1, 628, 631, 630, 629, 632, 633, 634, 635, - -1, 632, 636, 637, 633, -1, 633, 637, 638, 634, -1, 634, 638, 639, 635, -1, 635, 639, 636, 632, -1, 636, 639, 638, 637, 640, 641, 642, 643, -1, 640, 644, 645, 641, -1, 641, 645, 646, 642, -1, 642, - 646, 647, 643, -1, 643, 647, 644, 640, -1, 644, 647, 646, 645, 648, 649, 650, 651, -1, 648, 652, 653, 649, -1, 649, 653, 654, 650, -1, 650, 654, 655, 651, -1, 651, 655, 652, 648, -1, 652, 655, 654, - 653, 656, 657, 658, 659, -1, 656, 660, 661, 657, -1, 657, 661, 662, 658, -1, 658, 662, 663, 659, -1, 659, 663, 660, 656, -1, 660, 663, 662, 661, 664, 665, 666, 667, -1, 664, 668, 669, 665, -1, 665, - 669, 670, 666, -1, 666, 670, 671, 667, -1, 667, 671, 668, 664, -1, 668, 671, 670, 669, 672, 673, 674, 675, -1, 672, 676, 677, 673, -1, 673, 677, 678, 674, -1, 674, 678, 679, 675, -1, 675, 679, 676, - 672, -1, 676, 679, 678, 677, 680, 681, 682, 683, -1, 680, 684, 685, 681, -1, 681, 685, 686, 682, -1, 682, 686, 687, 683, -1, 683, 687, 684, 680, -1, 684, 687, 686, 685, 688, 689, 690, 691, -1, 688, - 692, 693, 689, -1, 689, 693, 694, 690, -1, 690, 694, 695, 691, -1, 691, 695, 692, 688, -1, 692, 695, 694, 693, 696, 697, 698, 699, -1, 696, 700, 701, 697, -1, 697, 701, 702, 698, -1, 698, 702, 703, - 699, -1, 699, 703, 700, 696, -1, 700, 703, 702, 701, 704, 705, 706, 707, -1, 704, 708, 709, 705, -1, 705, 709, 710, 706, -1, 706, 710, 711, 707, -1, 707, 711, 708, 704, -1, 708, 711, 710, 709, 712, - 713, 714, 715, -1, 712, 716, 717, 713, -1, 713, 717, 718, 714, -1, 714, 718, 719, 715, -1, 715, 719, 716, 712, -1, 716, 719, 718, 717, 720, 721, 722, 723, -1, 720, 724, 725, 721, -1, 721, 725, 726, - 722, -1, 722, 726, 727, 723, -1, 723, 727, 724, 720, -1, 724, 727, 726, 725, 728, 729, 730, 731, -1, 728, 732, 733, 729, -1, 729, 733, 734, 730, -1, 730, 734, 735, 731, -1, 731, 735, 732, 728, -1, - 732, 735, 734, 733, 736, 737, 738, 739, -1, 736, 740, 741, 737, -1, 737, 741, 742, 738, -1, 738, 742, 743, 739, -1, 739, 743, 740, 736, -1, 740, 743, 742, 741, 744, 745, 746, 747, -1, 744, 748, 749, - 745, -1, 745, 749, 750, 746, -1, 746, 750, 751, 747, -1, 747, 751, 748, 744, -1, 748, 751, 750, 749, 752, 753, 754, 755, -1, 752, 756, 757, 753, -1, 753, 757, 758, 754, -1, 754, 758, 759, 755, -1, - 755, 759, 756, 752, -1, 756, 759, 758, 757, 760, 761, 762, 763, -1, 760, 764, 765, 761, -1, 761, 765, 766, 762, -1, 762, 766, 767, 763, -1, 763, 767, 764, 760, -1, 764, 767, 766, 765, 768, 769, 770, - 771, -1, 768, 772, 773, 769, -1, 769, 773, 774, 770, -1, 770, 774, 775, 771, -1, 771, 775, 772, 768, -1, 772, 775, 774, 773, 776, 777, 778, 779, -1, 776, 780, 781, 777, -1, 777, 781, 782, 778, -1, - 778, 782, 783, 779, -1, 779, 783, 780, 776, -1, 780, 783, 782, 781, 784, 785, 786, 787, -1, 784, 788, 789, 785, -1, 785, 789, 790, 786, -1, 786, 790, 791, 787, -1, 787, 791, 788, 784, -1, 788, 791, - 790, 789, 792, 793, 794, 795, -1, 792, 796, 797, 793, -1, 793, 797, 798, 794, -1, 794, 798, 799, 795, -1, 795, 799, 796, 792, -1, 796, 799, 798, 797, 800, 801, 802, 803, -1, 800, 804, 805, 801, -1, - 801, 805, 806, 802, -1, 802, 806, 807, 803, -1, 803, 807, 804, 800, -1, 804, 807, 806, 805, 808, 809, 810, 811, -1, 808, 812, 813, 809, -1, 809, 813, 814, 810, -1, 810, 814, 815, 811, -1, 811, 815, - 812, 808, -1, 812, 815, 814, 813, 816, 817, 818, 819, -1, 816, 820, 821, 817, -1, 817, 821, 822, 818, -1, 818, 822, 823, 819, -1, 819, 823, 820, 816, -1, 820, 823, 822, 821, 824, 825, 826, 827, -1, - 824, 828, 829, 825, -1, 825, 829, 830, 826, -1, 826, 830, 831, 827, -1, 827, 831, 828, 824, -1, 828, 831, 830, 829, 832, 833, 834, 835, -1, 832, 836, 837, 833, -1, 833, 837, 838, 834, -1, 834, 838, - 839, 835, -1, 835, 839, 836, 832, -1, 836, 839, 838, 837, 840, 841, 842, 843, -1, 840, 844, 845, 841, -1, 841, 845, 846, 842, -1, 842, 846, 847, 843, -1, 843, 847, 844, 840, -1, 844, 847, 846, 845, - 848, 849, 850, 851, -1, 848, 852, 853, 849, -1, 849, 853, 854, 850, -1, 850, 854, 855, 851, -1, 851, 855, 852, 848, -1, 852, 855, 854, 853, 856, 857, 858, 859, -1, 856, 860, 861, 857, -1, 857, 861, - 862, 858, -1, 858, 862, 863, 859, -1, 859, 863, 860, 856, -1, 860, 863, 862, 861, 864, 865, 866, 867, -1, 864, 868, 869, 865, -1, 865, 869, 870, 866, -1, 866, 870, 871, 867, -1, 867, 871, 868, 864, - -1, 868, 871, 870, 869, 872, 873, 874, 875, -1, 872, 876, 877, 873, -1, 873, 877, 878, 874, -1, 874, 878, 879, 875, -1, 875, 879, 876, 872, -1, 876, 879, 878, 877, 880, 881, 882, 883, -1, 880, 884, - 885, 881, -1, 881, 885, 886, 882, -1, 882, 886, 887, 883, -1, 883, 887, 884, 880, -1, 884, 887, 886, 885, 888, 889, 890, 891, -1, 888, 892, 893, 889, -1, 889, 893, 894, 890, -1, 890, 894, 895, 891, - -1, 891, 895, 892, 888, -1, 892, 895, 894, 893, 896, 897, 898, 899, -1, 896, 900, 901, 897, -1, 897, 901, 902, 898, -1, 898, 902, 903, 899, -1, 899, 903, 900, 896, -1, 900, 903, 902, 901, 904, 905, - 906, 907, -1, 904, 908, 909, 905, -1, 905, 909, 910, 906, -1, 906, 910, 911, 907, -1, 907, 911, 908, 904, -1, 908, 911, 910, 909, 912, 913, 914, 915, -1, 912, 916, 917, 913, -1, 913, 917, 918, 914, - -1, 914, 918, 919, 915, -1, 915, 919, 916, 912, -1, 916, 919, 918, 917, 920, 921, 922, 923, -1, 920, 924, 925, 921, -1, 921, 925, 926, 922, -1, 922, 926, 927, 923, -1, 923, 927, 924, 920, -1, 924, - 927, 926, 925, 928, 929, 930, 931, -1, 928, 932, 933, 929, -1, 929, 933, 934, 930, -1, 930, 934, 935, 931, -1, 931, 935, 932, 928, -1, 932, 935, 934, 933, 936, 937, 938, 939, -1, 936, 940, 941, 937, - -1, 937, 941, 942, 938, -1, 938, 942, 943, 939, -1, 939, 943, 940, 936, -1, 940, 943, 942, 941, 944, 945, 946, 947, -1, 944, 948, 949, 945, -1, 945, 949, 950, 946, -1, 946, 950, 951, 947, -1, 947, - 951, 948, 944, -1, 948, 951, 950, 949, 952, 953, 954, 955, -1, 952, 956, 957, 953, -1, 953, 957, 958, 954, -1, 954, 958, 959, 955, -1, 955, 959, 956, 952, -1, 956, 959, 958, 957, 960, 961, 962, 963, - -1, 960, 964, 965, 961, -1, 961, 965, 966, 962, -1, 962, 966, 967, 963, -1, 963, 967, 964, 960, -1, 964, 967, 966, 965, 968, 969, 970, 971, -1, 968, 972, 973, 969, -1, 969, 973, 974, 970, -1, 970, - 974, 975, 971, -1, 971, 975, 972, 968, -1, 972, 975, 974, 973, 976, 977, 978, 979, -1, 976, 980, 981, 977, -1, 977, 981, 982, 978, -1, 978, 982, 983, 979, -1, 979, 983, 980, 976, -1, 980, 983, 982, - 981, 984, 985, 986, 987, -1, 984, 988, 989, 985, -1, 985, 989, 990, 986, -1, 986, 990, 991, 987, -1, 987, 991, 988, 984, -1, 988, 991, 990, 989, 992, 993, 994, 995, -1, 992, 996, 997, 993, -1, 993, - 997, 998, 994, -1, 994, 998, 999, 995, -1, 995, 999, 996, 992, -1, 996, 999, 998, 997, 1000, 1001, 1002, 1003, -1, 1000, 1004, 1005, 1001, -1, 1001, 1005, 1006, 1002, -1, 1002, 1006, 1007, 1003, - -1, 1003, 1007, 1004, 1000, -1, 1004, 1007, 1006, 1005, 1008, 1009, 1010, 1011, -1, 1008, 1012, 1013, 1009, -1, 1009, 1013, 1014, 1010, -1, 1010, 1014, 1015, 1011, -1, 1011, 1015, 1012, 1008, -1, - 1012, 1015, 1014, 1013, 1016, 1017, 1018, 1019, -1, 1016, 1020, 1021, 1017, -1, 1017, 1021, 1022, 1018, -1, 1018, 1022, 1023, 1019, -1, 1019, 1023, 1020, 1016, -1, 1020, 1023, 1022, 1021, 1024, - 1025, 1026, 1027, -1, 1024, 1028, 1029, 1025, -1, 1025, 1029, 1030, 1026, -1, 1026, 1030, 1031, 1027, -1, 1027, 1031, 1028, 1024, -1, 1028, 1031, 1030, 1029, 1032, 1033, 1034, 1035, -1, 1032, - 1036, 1037, 1033, -1, 1033, 1037, 1038, 1034, -1, 1034, 1038, 1039, 1035, -1, 1035, 1039, 1036, 1032, -1, 1036, 1039, 1038, 1037, 1040, 1041, 1042, 1043, -1, 1040, 1044, 1045, 1041, -1, 1041, - 1045, 1046, 1042, -1, 1042, 1046, 1047, 1043, -1, 1043, 1047, 1044, 1040, -1, 1044, 1047, 1046, 1045, 1048, 1049, 1050, 1051, -1, 1048, 1052, 1053, 1049, -1, 1049, 1053, 1054, 1050, -1, 1050, - 1054, 1055, 1051, -1, 1051, 1055, 1052, 1048, -1, 1052, 1055, 1054, 1053, 1056, 1057, 1058, 1059, -1, 1056, 1060, 1061, 1057, -1, 1057, 1061, 1062, 1058, -1, 1058, 1062, 1063, 1059, -1, 1059, - 1063, 1060, 1056, -1, 1060, 1063, 1062, 1061, 1064, 1065, 1066, 1067, -1, 1064, 1068, 1069, 1065, -1, 1065, 1069, 1070, 1066, -1, 1066, 1070, 1071, 1067, -1, 1067, 1071, 1068, 1064, -1, 1068, - 1071, 1070, 1069, 1072, 1073, 1074, 1075, -1, 1072, 1076, 1077, 1073, -1, 1073, 1077, 1078, 1074, -1, 1074, 1078, 1079, 1075, -1, 1075, 1079, 1076, 1072, -1, 1076, 1079, 1078, 1077, 1080, 1081, - 1082, 1083, -1, 1080, 1084, 1085, 1081, -1, 1081, 1085, 1086, 1082, -1, 1082, 1086, 1087, 1083, -1, 1083, 1087, 1084, 1080, -1, 1084, 1087, 1086, 1085, 1088, 1089, 1090, 1091, -1, 1088, 1092, - 1093, 1089, -1, 1089, 1093, 1094, 1090, -1, 1090, 1094, 1095, 1091, -1, 1091, 1095, 1092, 1088, -1, 1092, 1095, 1094, 1093, 1096, 1097, 1098, 1099, -1, 1096, 1100, 1101, 1097, -1, 1097, 1101, - 1102, 1098, -1, 1098, 1102, 1103, 1099, -1, 1099, 1103, 1100, 1096, -1, 1100, 1103, 1102, 1101, 1104, 1105, 1106, 1107, -1, 1104, 1108, 1109, 1105, -1, 1105, 1109, 1110, 1106, -1, 1106, 1110, - 1111, 1107, -1, 1107, 1111, 1108, 1104, -1, 1108, 1111, 1110, 1109, 1112, 1113, 1114, 1115, -1, 1112, 1116, 1117, 1113, -1, 1113, 1117, 1118, 1114, -1, 1114, 1118, 1119, 1115, -1, 1115, 1119, - 1116, 1112, -1, 1116, 1119, 1118, 1117, 1120, 1121, 1122, 1123, -1, 1120, 1124, 1125, 1121, -1, 1121, 1125, 1126, 1122, -1, 1122, 1126, 1127, 1123, -1, 1123, 1127, 1124, 1120, -1, 1124, 1127, - 1126, 1125, 1128, 1129, 1130, 1131, -1, 1128, 1132, 1133, 1129, -1, 1129, 1133, 1134, 1130, -1, 1130, 1134, 1135, 1131, -1, 1131, 1135, 1132, 1128, -1, 1132, 1135, 1134, 1133, 1136, 1137, 1138, - 1139, -1, 1136, 1140, 1141, 1137, -1, 1137, 1141, 1142, 1138, -1, 1138, 1142, 1143, 1139, -1, 1139, 1143, 1140, 1136, -1, 1140, 1143, 1142, 1141, 1144, 1145, 1146, 1147, -1, 1144, 1148, 1149, - 1145, -1, 1145, 1149, 1150, 1146, -1, 1146, 1150, 1151, 1147, -1, 1147, 1151, 1148, 1144, -1, 1148, 1151, 1150, 1149, 1152, 1153, 1154, 1155, -1, 1152, 1156, 1157, 1153, -1, 1153, 1157, 1158, - 1154, -1, 1154, 1158, 1159, 1155, -1, 1155, 1159, 1156, 1152, -1, 1156, 1159, 1158, 1157, 1160, 1161, 1162, 1163, -1, 1160, 1164, 1165, 1161, -1, 1161, 1165, 1166, 1162, -1, 1162, 1166, 1167, - 1163, -1, 1163, 1167, 1164, 1160, -1, 1164, 1167, 1166, 1165, 1168, 1169, 1170, 1171, -1, 1168, 1172, 1173, 1169, -1, 1169, 1173, 1174, 1170, -1, 1170, 1174, 1175, 1171, -1, 1171, 1175, 1172, - 1168, -1, 1172, 1175, 1174, 1173, 1176, 1177, 1178, 1179, -1, 1176, 1180, 1181, 1177, -1, 1177, 1181, 1182, 1178, -1, 1178, 1182, 1183, 1179, -1, 1179, 1183, 1180, 1176, -1, 1180, 1183, 1182, - 1181, 1184, 1185, 1186, 1187, -1, 1184, 1188, 1189, 1185, -1, 1185, 1189, 1190, 1186, -1, 1186, 1190, 1191, 1187, -1, 1187, 1191, 1188, 1184, -1, 1188, 1191, 1190, 1189, 1192, 1193, 1194, 1195, - -1, 1192, 1196, 1197, 1193, -1, 1193, 1197, 1198, 1194, -1, 1194, 1198, 1199, 1195, -1, 1195, 1199, 1196, 1192, -1, 1196, 1199, 1198, 1197, 1200, 1201, 1202, 1203, -1, 1200, 1204, 1205, 1201, - -1, 1201, 1205, 1206, 1202, -1, 1202, 1206, 1207, 1203, -1, 1203, 1207, 1204, 1200, -1, 1204, 1207, 1206, 1205, 1208, 1209, 1210, 1211, -1, 1208, 1212, 1213, 1209, -1, 1209, 1213, 1214, 1210, - -1, 1210, 1214, 1215, 1211, -1, 1211, 1215, 1212, 1208, -1, 1212, 1215, 1214, 1213, 1216, 1217, 1218, 1219, -1, 1216, 1220, 1221, 1217, -1, 1217, 1221, 1222, 1218, -1, 1218, 1222, 1223, 1219, - -1, 1219, 1223, 1220, 1216, -1, 1220, 1223, 1222, 1221, 1224, 1225, 1226, 1227, -1, 1224, 1228, 1229, 1225, -1, 1225, 1229, 1230, 1226, -1, 1226, 1230, 1231, 1227, -1, 1227, 1231, 1228, 1224, - -1, 1228, 1231, 1230, 1229, 1232, 1233, 1234, 1235, -1, 1232, 1236, 1237, 1233, -1, 1233, 1237, 1238, 1234, -1, 1234, 1238, 1239, 1235, -1, 1235, 1239, 1236, 1232, -1, 1236, 1239, 1238, 1237, - 1240, 1241, 1242, 1243, -1, 1240, 1244, 1245, 1241, -1, 1241, 1245, 1246, 1242, -1, 1242, 1246, 1247, 1243, -1, 1243, 1247, 1244, 1240, -1, 1244, 1247, 1246, 1245, 1248, 1249, 1250, 1251, -1, - 1248, 1252, 1253, 1249, -1, 1249, 1253, 1254, 1250, -1, 1250, 1254, 1255, 1251, -1, 1251, 1255, 1252, 1248, -1, 1252, 1255, 1254, 1253, 1256, 1257, 1258, 1259, -1, 1256, 1260, 1261, 1257, -1, - 1257, 1261, 1262, 1258, -1, 1258, 1262, 1263, 1259, -1, 1259, 1263, 1260, 1256, -1, 1260, 1263, 1262, 1261, 1264, 1265, 1266, 1267, -1, 1264, 1268, 1269, 1265, -1, 1265, 1269, 1270, 1266, -1, - 1266, 1270, 1271, 1267, -1, 1267, 1271, 1268, 1264, -1, 1268, 1271, 1270, 1269, 1272, 1273, 1274, 1275, -1, 1272, 1276, 1277, 1273, -1, 1273, 1277, 1278, 1274, -1, 1274, 1278, 1279, 1275, -1, - 1275, 1279, 1276, 1272, -1, 1276, 1279, 1278, 1277, 1280, 1281, 1282, 1283, -1, 1280, 1284, 1285, 1281, -1, 1281, 1285, 1286, 1282, -1, 1282, 1286, 1287, 1283, -1, 1283, 1287, 1284, 1280, -1, - 1284, 1287, 1286, 1285, 1288, 1289, 1290, 1291, -1, 1288, 1292, 1293, 1289, -1, 1289, 1293, 1294, 1290, -1, 1290, 1294, 1295, 1291, -1, 1291, 1295, 1292, 1288, -1, 1292, 1295, 1294, 1293, 1296, - 1297, 1298, 1299, -1, 1296, 1300, 1301, 1297, -1, 1297, 1301, 1302, 1298, -1, 1298, 1302, 1303, 1299, -1, 1299, 1303, 1300, 1296, -1, 1300, 1303, 1302, 1301, 1304, 1305, 1306, 1307, -1, 1304, - 1308, 1309, 1305, -1, 1305, 1309, 1310, 1306, -1, 1306, 1310, 1311, 1307, -1, 1307, 1311, 1308, 1304, -1, 1308, 1311, 1310, 1309, 1312, 1313, 1314, 1315, -1, 1312, 1316, 1317, 1313, -1, 1313, - 1317, 1318, 1314, -1, 1314, 1318, 1319, 1315, -1, 1315, 1319, 1316, 1312, -1, 1316, 1319, 1318, 1317, 1320, 1321, 1322, 1323, -1, 1320, 1324, 1325, 1321, -1, 1321, 1325, 1326, 1322, -1, 1322, - 1326, 1327, 1323, -1, 1323, 1327, 1324, 1320, -1, 1324, 1327, 1326, 1325, 1328, 1329, 1330, 1331, -1, 1328, 1332, 1333, 1329, -1, 1329, 1333, 1334, 1330, -1, 1330, 1334, 1335, 1331, -1, 1331, - 1335, 1332, 1328, -1, 1332, 1335, 1334, 1333, 1336, 1337, 1338, 1339, -1, 1336, 1340, 1341, 1337, -1, 1337, 1341, 1342, 1338, -1, 1338, 1342, 1343, 1339, -1, 1339, 1343, 1340, 1336, -1, 1340, - 1343, 1342, 1341, 1344, 1345, 1346, 1347, -1, 1344, 1348, 1349, 1345, -1, 1345, 1349, 1350, 1346, -1, 1346, 1350, 1351, 1347, -1, 1347, 1351, 1348, 1344, -1, 1348, 1351, 1350, 1349, 1352, 1353, - 1354, 1355, -1, 1352, 1356, 1357, 1353, -1, 1353, 1357, 1358, 1354, -1, 1354, 1358, 1359, 1355, -1, 1355, 1359, 1356, 1352, -1, 1356, 1359, 1358, 1357, 1360, 1361, 1362, 1363, -1, 1360, 1364, - 1365, 1361, -1, 1361, 1365, 1366, 1362, -1, 1362, 1366, 1367, 1363, -1, 1363, 1367, 1364, 1360, -1, 1364, 1367, 1366, 1365, 1368, 1369, 1370, 1371, -1, 1368, 1372, 1373, 1369, -1, 1369, 1373, - 1374, 1370, -1, 1370, 1374, 1375, 1371, -1, 1371, 1375, 1372, 1368, -1, 1372, 1375, 1374, 1373, 1376, 1377, 1378, 1379, -1, 1376, 1380, 1381, 1377, -1, 1377, 1381, 1382, 1378, -1, 1378, 1382, - 1383, 1379, -1, 1379, 1383, 1380, 1376, -1, 1380, 1383, 1382, 1381, 1384, 1385, 1386, 1387, -1, 1384, 1388, 1389, 1385, -1, 1385, 1389, 1390, 1386, -1, 1386, 1390, 1391, 1387, -1, 1387, 1391, - 1388, 1384, -1, 1388, 1391, 1390, 1389, 1392, 1393, 1394, 1395, -1, 1392, 1396, 1397, 1393, -1, 1393, 1397, 1398, 1394, -1, 1394, 1398, 1399, 1395, -1, 1395, 1399, 1396, 1392, -1, 1396, 1399, - 1398, 1397, 1400, 1401, 1402, 1403, -1, 1400, 1404, 1405, 1401, -1, 1401, 1405, 1406, 1402, -1, 1402, 1406, 1407, 1403, -1, 1403, 1407, 1404, 1400, -1, 1404, 1407, 1406, 1405, 1408, 1409, - 1410, 1411, -1, 1408, 1412, 1413, 1409, -1, 1409, 1413, 1414, 1410, -1, 1410, 1414, 1415, 1411, -1, 1411, 1415, 1412, 1408, -1, 1412, 1415, 1414, 1413, 1416, 1417, 1418, 1419, -1, 1416, - 1420, 1421, 1417, -1, 1417, 1421, 1422, 1418, -1, 1418, 1422, 1423, 1419, -1, 1419, 1423, 1420, 1416, -1, 1420, 1423, 1422, 1421, 1424, 1425, 1426, 1427, -1, 1424, 1428, 1429, 1425, -1, - 1425, 1429, 1430, 1426, -1, 1426, 1430, 1431, 1427, -1, 1427, 1431, 1428, 1424, -1, 1428, 1431, 1430, 1429, 1432, 1433, 1434, 1435, -1, 1432, 1436, 1437, 1433, -1, 1433, 1437, 1438, 1434, - -1, 1434, 1438, 1439, 1435, -1, 1435, 1439, 1436, 1432, -1, 1436, 1439, 1438, 1437, 1440, 1441, 1442, 1443, -1, 1440, 1444, 1445, 1441, -1, 1441, 1445, 1446, 1442, -1, 1442, 1446, 1447, 1443, - -1, 1443, 1447, 1444, 1440, -1, 1444, 1447, 1446, 1445, 1448, 1449, 1450, 1451, -1, 1448, 1452, 1453, 1449, -1, 1449, 1453, 1454, 1450, -1, 1450, 1454, 1455, 1451, -1, 1451, 1455, 1452, 1448, - -1, 1452, 1455, 1454, 1453, 1456, 1457, 1458, 1459, -1, 1456, 1460, 1461, 1457, -1, 1457, 1461, 1462, 1458, -1, 1458, 1462, 1463, 1459, -1, 1459, 1463, 1460, 1456, -1, 1460, 1463, 1462, 1461, - 1464, 1465, 1466, 1467, -1, 1464, 1468, 1469, 1465, -1, 1465, 1469, 1470, 1466, -1, 1466, 1470, 1471, 1467, -1, 1467, 1471, 1468, 1464, -1, 1468, 1471, 1470, 1469, 1472, 1473, 1474, 1475, -1, - 1472, 1476, 1477, 1473, -1, 1473, 1477, 1478, 1474, -1, 1474, 1478, 1479, 1475, -1, 1475, 1479, 1476, 1472, -1, 1476, 1479, 1478, 1477, 1480, 1481, 1482, 1483, -1, 1480, 1484, 1485, 1481, -1, - 1481, 1485, 1486, 1482, -1, 1482, 1486, 1487, 1483, -1, 1483, 1487, 1484, 1480, -1, 1484, 1487, 1486, 1485, 1488, 1489, 1490, 1491, -1, 1488, 1492, 1493, 1489, -1, 1489, 1493, 1494, 1490, -1, - 1490, 1494, 1495, 1491, -1, 1491, 1495, 1492, 1488, -1, 1492, 1495, 1494, 1493, 1496, 1497, 1498, 1499, -1, 1496, 1500, 1501, 1497, -1, 1497, 1501, 1502, 1498, -1, 1498, 1502, 1503, 1499, -1, - 1499, 1503, 1500, 1496, -1, 1500, 1503, 1502, 1501, 1504, 1505, 1506, 1507, -1, 1504, 1508, 1509, 1505, -1, 1505, 1509, 1510, 1506, -1, 1506, 1510, 1511, 1507, -1, 1507, 1511, 1508, 1504, -1, - 1508, 1511, 1510, 1509, 1512, 1513, 1514, 1515, -1, 1512, 1516, 1517, 1513, -1, 1513, 1517, 1518, 1514, -1, 1514, 1518, 1519, 1515, -1, 1515, 1519, 1516, 1512, -1, 1516, 1519, 1518, 1517, 1520, - 1521, 1522, 1523, -1, 1520, 1524, 1525, 1521, -1, 1521, 1525, 1526, 1522, -1, 1522, 1526, 1527, 1523, -1, 1523, 1527, 1524, 1520, -1, 1524, 1527, 1526, 1525, 1528, 1529, 1530, 1531, -1, 1528, 1532, - 1533, 1529, -1, 1529, 1533, 1534, 1530, -1, 1530, 1534, 1535, 1531, -1, 1531, 1535, 1532, 1528, -1, 1532, 1535, 1534, 1533, 1536, 1537, 1538, 1539, -1, 1536, 1540, 1541, 1537, -1, 1537, 1541, 1542, - 1538, -1, 1538, 1542, 1543, 1539, -1, 1539, 1543, 1540, 1536, -1, 1540, 1543, 1542, 1541, 1544, 1545, 1546, 1547, -1, 1544, 1548, 1549, 1545, -1, 1545, 1549, 1550, 1546, -1, 1546, 1550, 1551, 1547, - -1, 1547, 1551, 1548, 1544, -1, 1548, 1551, 1550, 1549, 1552, 1553, 1554, 1555, -1, 1552, 1556, 1557, 1553, -1, 1553, 1557, 1558, 1554, -1, 1554, 1558, 1559, 1555, -1, 1555, 1559, 1556, 1552, -1, 1556, - 1559, 1558, 1557, 1560, 1561, 1562, 1563, -1, 1560, 1564, 1565, 1561, -1, 1561, 1565, 1566, 1562, -1, 1562, 1566, 1567, 1563, -1, 1563, 1567, 1564, 1560, -1, 1564, 1567, 1566, 1565, 1568, 1569, 1570, 1571, - -1, 1568, 1572, 1573, 1569, -1, 1569, 1573, 1574, 1570, -1, 1570, 1574, 1575, 1571, -1, 1571, 1575, 1572, 1568, -1, 1572, 1575, 1574, 1573, 1576, 1577, 1578, 1579, -1, 1576, 1580, 1581, 1577, -1, - 1577, 1581, 1582, 1578, -1, 1578, 1582, 1583, 1579, -1, 1579, 1583, 1580, 1576, -1, 1580, 1583, 1582, 1581, 1584, 1585, 1586, 1587, -1, 1584, 1588, 1589, 1585, -1, 1585, 1589, 1590, 1586, -1, - 1586, 1590, 1591, 1587, -1, 1587, 1591, 1588, 1584, -1, 1588, 1591, 1590, 1589, 1592, 1593, 1594, 1595, -1, 1592, 1596, 1597, 1593, -1, 1593, 1597, 1598, 1594, -1, 1594, 1598, 1599, 1595, -1, - 1595, 1599, 1596, 1592, -1, 1596, 1599, 1598, 1597, 1600, 1601, 1602, 1603, -1, 1600, 1604, 1605, 1601, -1, 1601, 1605, 1606, 1602, -1, 1602, 1606, 1607, 1603, -1, 1603, 1607, 1604, 1600, -1, - 1604, 1607, 1606, 1605, 1608, 1609, 1610, 1611, -1, 1608, 1612, 1613, 1609, -1, 1609, 1613, 1614, 1610, -1, 1610, 1614, 1615, 1611, -1, 1611, 1615, 1612, 1608, -1, 1612, 1615, 1614, 1613, 1616, - 1617, 1618, 1619, -1, 1616, 1620, 1621, 1617, -1, 1617, 1621, 1622, 1618, -1, 1618, 1622, 1623, 1619, -1, 1619, 1623, 1620, 1616, -1, 1620, 1623, 1622, 1621, 1624, 1625, 1626, 1627, -1, 1624, - 1628, 1629, 1625, -1, 1625, 1629, 1630, 1626, -1, 1626, 1630, 1631, 1627, -1, 1627, 1631, 1628, 1624, -1, 1628, 1631, 1630, 1629, 1632, 1633, 1634, 1635, -1, 1632, 1636, 1637, 1633, -1, 1633, - 1637, 1638, 1634, -1, 1634, 1638, 1639, 1635, -1, 1635, 1639, 1636, 1632, -1, 1636, 1639, 1638, 1637, 1640, 1641, 1642, 1643, -1, 1640, 1644, 1645, 1641, -1, 1641, 1645, 1646, 1642, -1, 1642, - 1646, 1647, 1643, -1, 1643, 1647, 1644, 1640, -1, 1644, 1647, 1646, 1645, 1648, 1649, 1650, 1651, -1, 1648, 1652, 1653, 1649, -1, 1649, 1653, 1654, 1650, -1, 1650, 1654, 1655, 1651, -1, 1651, - 1655, 1652, 1648, -1, 1652, 1655, 1654, 1653, 1656, 1657, 1658, 1659, -1, 1656, 1660, 1661, 1657, -1, 1657, 1661, 1662, 1658, -1, 1658, 1662, 1663, 1659, -1, 1659, 1663, 1660, 1656, -1, 1660, - 1663, 1662, 1661, 1664, 1665, 1666, 1667, -1, 1664, 1668, 1669, 1665, -1, 1665, 1669, 1670, 1666, -1, 1666, 1670, 1671, 1667, -1, 1667, 1671, 1668, 1664, -1, 1668, 1671, 1670, 1669, 1672, 1673, - 1674, 1675, -1, 1672, 1676, 1677, 1673, -1, 1673, 1677, 1678, 1674, -1, 1674, 1678, 1679, 1675, -1, 1675, 1679, 1676, 1672, -1, 1676, 1679, 1678, 1677, 1680, 1681, 1682, 1683, -1, 1680, 1684, - 1685, 1681, -1, 1681, 1685, 1686, 1682, -1, 1682, 1686, 1687, 1683, -1, 1683, 1687, 1684, 1680, -1, 1684, 1687, 1686, 1685, 1688, 1689, 1690, 1691, -1, 1688, 1692, 1693, 1689, -1, 1689, 1693, - 1694, 1690, -1, 1690, 1694, 1695, 1691, -1, 1691, 1695, 1692, 1688, -1, 1692, 1695, 1694, 1693, 1696, 1697, 1698, 1699, -1, 1696, 1700, 1701, 1697, -1, 1697, 1701, 1702, 1698, -1, 1698, 1702, - 1703, 1699, -1, 1699, 1703, 1700, 1696, -1, 1700, 1703, 1702, 1701, 1704, 1705, 1706, 1707, -1, 1704, 1708, 1709, 1705, -1, 1705, 1709, 1710, 1706, -1, 1706, 1710, 1711, 1707, -1, 1707, 1711, - 1708, 1704, -1, 1708, 1711, 1710, 1709, 1712, 1713, 1714, 1715, -1, 1712, 1716, 1717, 1713, -1, 1713, 1717, 1718, 1714, -1, 1714, 1718, 1719, 1715, -1, 1715, 1719, 1716, 1712, -1, 1716, 1719, 1718, 1717}; - -double coordsTT[5160]={ - 0.0054015000000000044, 0.0054015000000000053, 0, 0.2106585, 0.0054015000000000053, 0, 0.2106585, 0.039611, 0, 0.2106585, 0.10803, 0, 0.2106585, - 0.17644899999999999, 0, 0.2106585, 0.2106585, 0, 0.0054015000000000044, 0.2106585, 0, 0.0054015000000000044, 0.0054015000000000053, 0.21364999999999998, - 0.2106585, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.039611, 0.21364999999999998, 0.2106585, 0.10803, 0.21364999999999998, 0.2106585, - 0.17644899999999999, 0.21364999999999998, 0.2106585, 0.2106585, 0.21364999999999998, 0.0054015000000000044, 0.2106585, 0.21364999999999998, - 0.0054015000000000044, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.039611, - 0.21364999999999998, 0.2106585, 0.10803, 0.21364999999999998, 0.2106585, 0.17644899999999999, 0.21364999999999998, 0.2106585, 0.2106585, 0.21364999999999998, - 0.0054015000000000044, 0.2106585, 0.21364999999999998, 0.0054015000000000044, 0.0054015000000000053, 0.42729999999999996, 0.2106585, 0.0054015000000000053, - 0.42729999999999996, 0.2106585, 0.039611, 0.42729999999999996, 0.2106585, 0.10803, 0.42729999999999996, 0.2106585, 0.17644899999999999, 0.42729999999999996, - 0.2106585, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.0054015000000000053, - 0.42729999999999996, 0.2106585, 0.0054015000000000053, 0.42729999999999996, 0.2106585, 0.039611, 0.42729999999999996, 0.2106585, 0.10803, 0.42729999999999996, - 0.2106585, 0.17644899999999999, 0.42729999999999996, 0.2106585, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.2106585, 0.42729999999999996, - 0.0054015000000000044, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.039611, - 0.64094999999999991, 0.2106585, 0.10803, 0.64094999999999991, 0.2106585, 0.17644899999999999, 0.64094999999999991, 0.2106585, 0.2106585, 0.64094999999999991, - 0.0054015000000000044, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.0054015000000000053, - 0.64094999999999991, 0.2106585, 0.039611, 0.64094999999999991, 0.2106585, 0.10803, 0.64094999999999991, 0.2106585, 0.17644899999999999, 0.64094999999999991, - 0.2106585, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.0054015000000000053, - 0.85459999999999992, 0.2106585, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.039611, 0.85459999999999992, 0.2106585, 0.10803, 0.85459999999999992, - 0.2106585, 0.17644899999999999, 0.85459999999999992, 0.2106585, 0.2106585, 0.85459999999999992, 0.0054015000000000044, 0.2106585, 0.85459999999999992, - 0.0054015000000000044, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.039611, - 0.85459999999999992, 0.2106585, 0.10803, 0.85459999999999992, 0.2106585, 0.17644899999999999, 0.85459999999999992, 0.2106585, 0.2106585, 0.85459999999999992, - 0.0054015000000000044, 0.2106585, 0.85459999999999992, 0.0054015000000000044, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.0054015000000000053, - 1.0682499999999999, 0.2106585, 0.039611, 1.0682499999999999, 0.2106585, 0.10803, - 1.0682499999999999, 0.2106585, 0.17644899999999999, 1.0682499999999999, 0.2106585, 0.2106585, 1.0682499999999999, 0.0054015000000000044, 0.2106585, - 1.0682499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.039611, - 1.0682499999999999, 0.2106585, 0.10803, 1.0682499999999999, 0.2106585, 0.17644899999999999, 1.0682499999999999, 0.2106585, 0.2106585, 1.0682499999999999, - 0.0054015000000000044, 0.2106585, 1.0682499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.2818999999999998, 0.2106585, 0.0054015000000000053, - 1.2818999999999998, 0.2106585, 0.039611, 1.2818999999999998, 0.2106585, 0.10803, 1.2818999999999998, 0.2106585, 0.17644899999999999, 1.2818999999999998, - 0.2106585, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.0054015000000000053, 1.2818999999999998, - 0.2106585, 0.0054015000000000053, 1.2818999999999998, 0.2106585, 0.039611, 1.2818999999999998, 0.2106585, 0.10803, 1.2818999999999998, 0.2106585, - 0.17644899999999999, 1.2818999999999998, 0.2106585, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.2106585, 1.2818999999999998, 0.0054015000000000044, - 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.039611, 1.4955499999999999, 0.2106585, 0.10803, - 1.4955499999999999, 0.2106585, 0.17644899999999999, 1.4955499999999999, 0.2106585, 0.2106585, 1.4955499999999999, 0.0054015000000000044, 0.2106585, - 1.4955499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.039611, - 1.4955499999999999, 0.2106585, 0.10803, 1.4955499999999999, 0.2106585, 0.17644899999999999, 1.4955499999999999, 0.2106585, 0.2106585, 1.4955499999999999, - 0.0054015000000000044, 0.2106585, 1.4955499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.7091999999999998, 0.2106585, 0.0054015000000000053, - 1.7091999999999998, 0.2106585, 0.039611, 1.7091999999999998, 0.2106585, 0.10803, 1.7091999999999998, 0.2106585, 0.17644899999999999, 1.7091999999999998, - 0.2106585, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.0054015000000000053, 1.7091999999999998, - 0.2106585, 0.0054015000000000053, 1.7091999999999998, 0.2106585, 0.039611, 1.7091999999999998, 0.2106585, 0.10803, 1.7091999999999998, 0.2106585, - 0.17644899999999999, 1.7091999999999998, 0.2106585, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.2106585, 1.7091999999999998, 0.0054015000000000044, - 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.039611, 1.9228499999999997, 0.2106585, 0.10803, - 1.9228499999999997, 0.2106585, 0.17644899999999999, 1.9228499999999997, 0.2106585, 0.2106585, 1.9228499999999997, 0.0054015000000000044, 0.2106585, - 1.9228499999999997, 0.0054015000000000044, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.039611, - 1.9228499999999997, 0.2106585, 0.10803, 1.9228499999999997, 0.2106585, 0.17644899999999999, 1.9228499999999997, 0.2106585, 0.2106585, 1.9228499999999997, - 0.0054015000000000044, 0.2106585, 1.9228499999999997, 0.0054015000000000044, - 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.039611, 2.1364999999999998, 0.2106585, - 0.10803, 2.1364999999999998, 0.2106585, 0.17644899999999999, 2.1364999999999998, 0.2106585, 0.2106585, 2.1364999999999998, 0.0054015000000000044, 0.2106585, - 2.1364999999999998, 0.0054015000000000044, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.039611, - 2.1364999999999998, 0.2106585, 0.10803, 2.1364999999999998, 0.2106585, 0.17644899999999999, 2.1364999999999998, 0.2106585, 0.2106585, 2.1364999999999998, - 0.0054015000000000044, 0.2106585, 2.1364999999999998, 0.0054015000000000044, 0.0054015000000000053, 2.3501499999999997, 0.2106585, 0.0054015000000000053, - 2.3501499999999997, 0.2106585, 0.039611, 2.3501499999999997, 0.2106585, 0.10803, 2.3501499999999997, 0.2106585, 0.17644899999999999, 2.3501499999999997, - 0.2106585, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.0054015000000000053, 2.3501499999999997, - 0.2106585, 0.0054015000000000053, 2.3501499999999997, 0.2106585, 0.039611, 2.3501499999999997, 0.2106585, 0.10803, 2.3501499999999997, 0.2106585, - 0.17644899999999999, 2.3501499999999997, 0.2106585, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.2106585, 2.3501499999999997, 0.0054015000000000044, - 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.039611, 2.5637999999999996, 0.2106585, 0.10803, - 2.5637999999999996, 0.2106585, 0.17644899999999999, 2.5637999999999996, 0.2106585, 0.2106585, 2.5637999999999996, 0.0054015000000000044, 0.2106585, - 2.5637999999999996, 0.0054015000000000044, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.039611, - 2.5637999999999996, 0.2106585, 0.10803, 2.5637999999999996, 0.2106585, 0.17644899999999999, 2.5637999999999996, 0.2106585, 0.2106585, 2.5637999999999996, - 0.0054015000000000044, 0.2106585, 2.5637999999999996, 0.0054015000000000044, 0.0054015000000000053, 2.7774499999999995, 0.2106585, 0.0054015000000000053, - 2.7774499999999995, 0.2106585, 0.039611, 2.7774499999999995, 0.2106585, 0.10803, 2.7774499999999995, 0.2106585, 0.17644899999999999, 2.7774499999999995, - 0.2106585, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.0054015000000000053, 2.7774499999999995, - 0.2106585, 0.0054015000000000053, 2.7774499999999995, 0.2106585, 0.039611, 2.7774499999999995, 0.2106585, 0.10803, 2.7774499999999995, 0.2106585, - 0.17644899999999999, 2.7774499999999995, 0.2106585, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.2106585, 2.7774499999999995, 0.0054015000000000044, - 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.039611, 2.9910999999999999, 0.2106585, 0.10803, - 2.9910999999999999, 0.2106585, 0.17644899999999999, 2.9910999999999999, 0.2106585, 0.2106585, 2.9910999999999999, 0.0054015000000000044, 0.2106585, - 2.9910999999999999, 0.0054015000000000044, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.039611, - 2.9910999999999999, 0.2106585, 0.10803, 2.9910999999999999, - 0.2106585, 0.17644899999999999, 2.9910999999999999, 0.2106585, 0.2106585, 2.9910999999999999, 0.0054015000000000044, 0.2106585, 2.9910999999999999, - 0.0054015000000000044, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.039611, 3.2047499999999998, - 0.2106585, 0.10803, 3.2047499999999998, 0.2106585, 0.17644899999999999, 3.2047499999999998, 0.2106585, 0.2106585, 3.2047499999999998, 0.0054015000000000044, - 0.2106585, 3.2047499999999998, 0.0054015000000000044, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.0054015000000000053, 3.2047499999999998, 0.2106585, - 0.039611, 3.2047499999999998, 0.2106585, 0.10803, 3.2047499999999998, 0.2106585, 0.17644899999999999, 3.2047499999999998, 0.2106585, 0.2106585, - 3.2047499999999998, 0.0054015000000000044, 0.2106585, 3.2047499999999998, 0.0054015000000000044, 0.0054015000000000053, 3.4183999999999997, 0.2106585, - 0.0054015000000000053, 3.4183999999999997, 0.2106585, 0.039611, 3.4183999999999997, 0.2106585, 0.10803, 3.4183999999999997, 0.2106585, 0.17644899999999999, - 3.4183999999999997, 0.2106585, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.0054015000000000053, - 3.4183999999999997, 0.2106585, 0.0054015000000000053, 3.4183999999999997, 0.2106585, 0.039611, 3.4183999999999997, 0.2106585, 0.10803, 3.4183999999999997, - 0.2106585, 0.17644899999999999, 3.4183999999999997, 0.2106585, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.2106585, 3.4183999999999997, - 0.0054015000000000044, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.039611, 3.6320499999999996, - 0.2106585, 0.10803, 3.6320499999999996, 0.2106585, 0.17644899999999999, 3.6320499999999996, 0.2106585, 0.2106585, 3.6320499999999996, 0.0054015000000000044, - 0.2106585, 3.6320499999999996, 0.0054015000000000044, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.0054015000000000053, 3.6320499999999996, 0.2106585, - 0.039611, 3.6320499999999996, 0.2106585, 0.10803, 3.6320499999999996, 0.2106585, 0.17644899999999999, 3.6320499999999996, 0.2106585, 0.2106585, - 3.6320499999999996, 0.0054015000000000044, 0.2106585, 3.6320499999999996, 0.0054015000000000044, 0.0054015000000000053, 3.8456999999999995, 0.2106585, - 0.0054015000000000053, 3.8456999999999995, 0.2106585, 0.039611, 3.8456999999999995, 0.2106585, 0.10803, 3.8456999999999995, 0.2106585, 0.17644899999999999, - 3.8456999999999995, 0.2106585, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.0054015000000000053, - 3.8456999999999995, 0.2106585, 0.0054015000000000053, 3.8456999999999995, 0.2106585, 0.039611, 3.8456999999999995, 0.2106585, 0.10803, 3.8456999999999995, - 0.2106585, 0.17644899999999999, 3.8456999999999995, 0.2106585, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.2106585, 3.8456999999999995, - 0.0054015000000000044, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.039611, 4.0593499999999993, - 0.2106585, 0.10803, 4.0593499999999993, 0.2106585, 0.17644899999999999, 4.0593499999999993, 0.2106585, 0.2106585, 4.0593499999999993, 0.0054015000000000044, - 0.2106585, 4.0593499999999993, 0.0054015000000000044, 0.0054015000000000053, - 4.0593499999999993, 0.2106585, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.039611, 4.0593499999999993, 0.2106585, 0.10803, 4.0593499999999993, - 0.2106585, 0.17644899999999999, 4.0593499999999993, 0.2106585, 0.2106585, 4.0593499999999993, 0.0054015000000000044, 0.2106585, 4.0593499999999993, - 0.0054015000000000044, 0.0054015000000000053, 4.2729999999999997, 0.2106585, 0.0054015000000000053, 4.2729999999999997, 0.2106585, 0.039611, 4.2729999999999997, - 0.2106585, 0.10803, 4.2729999999999997, 0.2106585, 0.17644899999999999, 4.2729999999999997, 0.2106585, 0.2106585, 4.2729999999999997, 0.0054015000000000044, - 0.2106585, 4.2729999999999997, 0.24197569714517145, 0.025915697145171439, 0, 0.26483839536511933, 0.025915697145171439, 0, 0.26483839536511933, - 0.048778395365119298, 0, 0.24197569714517145, 0.048778395365119298, 0, 0.24197569714517145, 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, - 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, 0.048778395365119298, - 0.21364999999999998, 0.24197569714517145, 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, 0.025915697145171439, 0.21364999999999998, - 0.26483839536511933, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, - 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.048778395365119298, - 0.42729999999999996, 0.24197569714517145, 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, 0.025915697145171439, 0.42729999999999996, - 0.26483839536511933, 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, - 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, 0.025915697145171439, - 0.64094999999999991, 0.26483839536511933, 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.048778395365119298, 0.64094999999999991, - 0.24197569714517145, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, - 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.025915697145171439, - 0.85459999999999992, 0.26483839536511933, 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, 0.048778395365119298, 0.85459999999999992, - 0.24197569714517145, 0.048778395365119298, 0.85459999999999992, 0.24197569714517145, 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, - 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, 0.048778395365119298, 0.85459999999999992, 0.24197569714517145, 0.048778395365119298, - 0.85459999999999992, 0.24197569714517145, 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.025915697145171439, 1.0682499999999999, - 0.26483839536511933, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, - 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.048778395365119298, - 1.0682499999999999, 0.24197569714517145, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, 0.025915697145171439, 1.2818999999999998, - 0.26483839536511933, 0.025915697145171439, 1.2818999999999998, 0.26483839536511933, 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, - 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, 0.025915697145171439, 1.2818999999999998, 0.26483839536511933, 0.025915697145171439, - 1.2818999999999998, 0.26483839536511933, 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, 0.048778395365119298, 1.2818999999999998, - 0.24197569714517145, 0.025915697145171439, 1.4955499999999999, 0.26483839536511933,0.025915697145171439, 1.4955499999999999, 0.26483839536511933, - 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, 0.048778395365119298, - 1.4955499999999999, 0.24197569714517145, 0.025915697145171439, 1.4955499999999999, 0.26483839536511933, 0.025915697145171439, 1.4955499999999999, - 0.26483839536511933, 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, - 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.048778395365119298, - 1.7091999999999998, 0.24197569714517145, 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, 0.025915697145171439, 1.7091999999999998, - 0.26483839536511933, 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, - 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, 0.025915697145171439, - 1.9228499999999997, 0.26483839536511933, 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.048778395365119298, 1.9228499999999997, - 0.24197569714517145, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, - 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.025915697145171439, - 2.1364999999999998, 0.26483839536511933, 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, 0.048778395365119298, 2.1364999999999998, - 0.24197569714517145, 0.048778395365119298, 2.1364999999999998, 0.24197569714517145, 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, - 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, 0.048778395365119298, 2.1364999999999998, 0.24197569714517145, 0.048778395365119298, - 2.1364999999999998, 0.24197569714517145, 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.025915697145171439, 2.3501499999999997, - 0.26483839536511933, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, - 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.048778395365119298, - 2.3501499999999997, 0.24197569714517145, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, 0.025915697145171439, 2.5637999999999996, - 0.26483839536511933, 0.025915697145171439, 2.5637999999999996, 0.26483839536511933, 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, - 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, 0.025915697145171439, 2.5637999999999996, 0.26483839536511933, 0.025915697145171439, - 2.5637999999999996, 0.26483839536511933, 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, 0.048778395365119298, 2.5637999999999996, - 0.24197569714517145, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, - 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.025915697145171439, - 2.7774499999999995, 0.26483839536511933, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, 0.048778395365119298, 2.7774499999999995, - 0.24197569714517145, 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, - 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, 0.048778395365119298, - 2.9910999999999999, 0.24197569714517145, 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, 0.025915697145171439, 2.9910999999999999, - 0.26483839536511933, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, - 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.048778395365119298, - 3.2047499999999998, 0.24197569714517145, 0.048778395365119298, 3.2047499999999998, - 0.24197569714517145, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, - 0.048778395365119298, 3.2047499999999998, 0.24197569714517145, 0.048778395365119298, 3.2047499999999998, 0.24197569714517145, 0.025915697145171439, - 3.4183999999999997, 0.26483839536511933, 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, 0.048778395365119298, 3.4183999999999997, - 0.24197569714517145, 0.048778395365119298, 3.4183999999999997, 0.24197569714517145, 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, - 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, 0.048778395365119298, 3.4183999999999997, 0.24197569714517145, 0.048778395365119298, - 3.4183999999999997, 0.24197569714517145, 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.025915697145171439, 3.6320499999999996, - 0.26483839536511933, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, - 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.048778395365119298, - 3.6320499999999996, 0.24197569714517145, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, 0.025915697145171439, 3.8456999999999995, - 0.26483839536511933, 0.025915697145171439, 3.8456999999999995, 0.26483839536511933, 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, - 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, 0.025915697145171439, 3.8456999999999995, 0.26483839536511933, 0.025915697145171439, - 3.8456999999999995, 0.26483839536511933, 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, 0.048778395365119298, 3.8456999999999995, - 0.24197569714517145, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, - 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.025915697145171439, - 4.0593499999999993, 0.26483839536511933, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, 0.048778395365119298, 4.0593499999999993, - 0.24197569714517145, 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.025915697145171439, 4.2729999999999997, 0.26483839536511933, - 0.025915697145171439, 4.2729999999999997, 0.26483839536511933, 0.048778395365119298, 4.2729999999999997, 0.24197569714517145, 0.048778395365119298, - 4.2729999999999997, 0.31132160463488068, 0.029625802317440348, 0, 0.3368583953651193, 0.029625802317440348, 0, 0.3368583953651193, 0.046104302854828562, 0, - 0.31132160463488068, 0.046104302854828562, 0, 0.31132160463488068, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, 0.029625802317440348, - 0.21364999999999998, 0.3368583953651193, 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.046104302854828562, 0.21364999999999998, - 0.31132160463488068, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, - 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.029625802317440348, - 0.42729999999999996, 0.3368583953651193, 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, 0.046104302854828562, 0.42729999999999996, - 0.31132160463488068, 0.046104302854828562, 0.42729999999999996, 0.31132160463488068, 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, - 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, 0.046104302854828562, 0.42729999999999996, 0.31132160463488068, 0.046104302854828562, - 0.42729999999999996, 0.31132160463488068, 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.029625802317440348, 0.64094999999999991, - 0.3368583953651193, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, - 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.046104302854828562, - 0.64094999999999991, 0.31132160463488068, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, 0.029625802317440348, 0.85459999999999992, - 0.3368583953651193, 0.029625802317440348, 0.85459999999999992, 0.3368583953651193, 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, - 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, 0.029625802317440348, 0.85459999999999992, 0.3368583953651193, 0.029625802317440348, - 0.85459999999999992, 0.3368583953651193, 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, 0.046104302854828562, 0.85459999999999992, - 0.31132160463488068, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, - 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.029625802317440348, - 1.0682499999999999, 0.3368583953651193, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, 0.046104302854828562, 1.0682499999999999, - 0.31132160463488068, 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, - 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, 0.046104302854828562, - 1.2818999999999998, 0.31132160463488068, 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, 0.029625802317440348, 1.2818999999999998, - 0.3368583953651193, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, - 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.046104302854828562, - 1.4955499999999999, 0.31132160463488068, 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, 0.029625802317440348, 1.4955499999999999, - 0.3368583953651193, 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, - 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, 0.029625802317440348, - 1.7091999999999998, 0.3368583953651193, 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.046104302854828562, 1.7091999999999998, - 0.31132160463488068, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, - 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.029625802317440348, - 1.9228499999999997, 0.3368583953651193, 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, 0.046104302854828562, 1.9228499999999997, - 0.31132160463488068, 0.046104302854828562, 1.9228499999999997, 0.31132160463488068, 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, - 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, 0.046104302854828562, 1.9228499999999997, 0.31132160463488068, 0.046104302854828562, - 1.9228499999999997, 0.31132160463488068, 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.029625802317440348, 2.1364999999999998, - 0.3368583953651193, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, - 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.046104302854828562, - 2.1364999999999998, 0.31132160463488068, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, 0.029625802317440348, 2.3501499999999997, - 0.3368583953651193, 0.029625802317440348, 2.3501499999999997, 0.3368583953651193, 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, - 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, 0.029625802317440348, 2.3501499999999997, 0.3368583953651193, 0.029625802317440348, - 2.3501499999999997, 0.3368583953651193, 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, 0.046104302854828562, 2.3501499999999997, - 0.31132160463488068, 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, - 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, 0.046104302854828562, - 2.5637999999999996, 0.31132160463488068, 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, 0.029625802317440348, 2.5637999999999996, - 0.3368583953651193, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, - 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.046104302854828562, - 2.7774499999999995, 0.31132160463488068, 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, 0.029625802317440348, 2.7774499999999995, - 0.3368583953651193, 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, - 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, 0.029625802317440348, - 2.9910999999999999, 0.3368583953651193, 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.046104302854828562, 2.9910999999999999, - 0.31132160463488068, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, - 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.029625802317440348, - 3.2047499999999998, 0.3368583953651193, 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, 0.046104302854828562, 3.2047499999999998, - 0.31132160463488068, 0.046104302854828562, 3.2047499999999998, 0.31132160463488068, 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, - 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, 0.046104302854828562, 3.2047499999999998, 0.31132160463488068, 0.046104302854828562, - 3.2047499999999998, 0.31132160463488068, 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.029625802317440348, 3.4183999999999997, - 0.3368583953651193, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, - 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.046104302854828562, - 3.4183999999999997, 0.31132160463488068, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, 0.029625802317440348, 3.6320499999999996, - 0.3368583953651193, 0.029625802317440348, 3.6320499999999996, 0.3368583953651193, 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, - 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, 0.029625802317440348, 3.6320499999999996, 0.3368583953651193, 0.029625802317440348, - 3.6320499999999996, 0.3368583953651193, 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, 0.046104302854828562, 3.6320499999999996, - 0.31132160463488068, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, - 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.029625802317440348, - 3.8456999999999995, 0.3368583953651193, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, 0.046104302854828562, 3.8456999999999995, - 0.31132160463488068, 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, - 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, 0.046104302854828562, - 4.0593499999999993, 0.31132160463488068, 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, 0.029625802317440348, 4.0593499999999993, - 0.3368583953651193, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, - 0.029625802317440348, 4.2729999999999997, 0.3368583953651193, 0.029625802317440348, 4.2729999999999997, 0.3368583953651193, 0.046104302854828562, - 4.2729999999999997, 0.31132160463488068, 0.046104302854828562, 4.2729999999999997, - 0.38334160463488065, 0.025915697145171453, 0, 0.40620430285482856, 0.025915697145171453, 0, 0.40620430285482856, 0.048778395365119291, 0, - 0.38334160463488065, 0.048778395365119291, 0, 0.38334160463488065, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, 0.025915697145171453, - 0.21364999999999998, 0.40620430285482856, 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.048778395365119291, 0.21364999999999998, - 0.38334160463488065, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, - 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.025915697145171453, - 0.42729999999999996, 0.40620430285482856, 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, 0.048778395365119291, 0.42729999999999996, - 0.38334160463488065, 0.048778395365119291, 0.42729999999999996, 0.38334160463488065, 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, - 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, 0.048778395365119291, 0.42729999999999996, 0.38334160463488065, 0.048778395365119291, - 0.42729999999999996, 0.38334160463488065, 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.025915697145171453, 0.64094999999999991, - 0.40620430285482856, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, - 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.048778395365119291, - 0.64094999999999991, 0.38334160463488065, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, 0.025915697145171453, 0.85459999999999992, - 0.40620430285482856, 0.025915697145171453, 0.85459999999999992, 0.40620430285482856, 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, - 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, 0.025915697145171453, 0.85459999999999992, 0.40620430285482856, 0.025915697145171453, - 0.85459999999999992, 0.40620430285482856, 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, 0.048778395365119291, 0.85459999999999992, - 0.38334160463488065, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, - 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.025915697145171453, - 1.0682499999999999, 0.40620430285482856, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, 0.048778395365119291, 1.0682499999999999, - 0.38334160463488065, 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, - 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, 0.048778395365119291, - 1.2818999999999998, 0.38334160463488065, 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, 0.025915697145171453, 1.2818999999999998, - 0.40620430285482856, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, - 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.048778395365119291, - 1.4955499999999999, 0.38334160463488065, 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, 0.025915697145171453, 1.4955499999999999, - 0.40620430285482856, 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, - 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, 0.025915697145171453, - 1.7091999999999998, 0.40620430285482856, 0.048778395365119291, 1.7091999999999998, 0.38334160463488065, 0.048778395365119291, 1.7091999999999998, - 0.38334160463488065, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, - 0.048778395365119291, - 1.7091999999999998, 0.38334160463488065, 0.048778395365119291, 1.7091999999999998, 0.38334160463488065, 0.025915697145171453, 1.9228499999999997, - 0.40620430285482856, 0.025915697145171453, 1.9228499999999997, 0.40620430285482856, 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, - 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, 0.025915697145171453, 1.9228499999999997, 0.40620430285482856, 0.025915697145171453, - 1.9228499999999997, 0.40620430285482856, 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, 0.048778395365119291, 1.9228499999999997, - 0.38334160463488065, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, - 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.025915697145171453, - 2.1364999999999998, 0.40620430285482856, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, 0.048778395365119291, 2.1364999999999998, - 0.38334160463488065, 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, - 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, 0.048778395365119291, - 2.3501499999999997, 0.38334160463488065, 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, 0.025915697145171453, 2.3501499999999997, - 0.40620430285482856, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, - 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.048778395365119291, - 2.5637999999999996, 0.38334160463488065, 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, 0.025915697145171453, 2.5637999999999996, - 0.40620430285482856, 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, - 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, 0.025915697145171453, - 2.7774499999999995, 0.40620430285482856, 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.048778395365119291, 2.7774499999999995, - 0.38334160463488065, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, - 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.025915697145171453, - 2.9910999999999999, 0.40620430285482856, 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, 0.048778395365119291, 2.9910999999999999, - 0.38334160463488065, 0.048778395365119291, 2.9910999999999999, 0.38334160463488065, 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, - 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, 0.048778395365119291, 2.9910999999999999, 0.38334160463488065, 0.048778395365119291, - 2.9910999999999999, 0.38334160463488065, 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.025915697145171453, 3.2047499999999998, - 0.40620430285482856, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, - 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.048778395365119291, - 3.2047499999999998, 0.38334160463488065, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, 0.025915697145171453, 3.4183999999999997, - 0.40620430285482856, 0.025915697145171453, 3.4183999999999997, 0.40620430285482856, 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, - 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, 0.025915697145171453, 3.4183999999999997, 0.40620430285482856, 0.025915697145171453, - 3.4183999999999997, 0.40620430285482856, 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, 0.048778395365119291, 3.4183999999999997, - 0.38334160463488065, 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, - 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, 0.048778395365119291, - 3.6320499999999996, 0.38334160463488065, 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, 0.025915697145171453, 3.6320499999999996, - 0.40620430285482856, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, - 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.048778395365119291, - 3.8456999999999995, 0.38334160463488065, 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, 0.025915697145171453, 3.8456999999999995, - 0.40620430285482856, 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, - 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, 0.025915697145171453, - 4.0593499999999993, 0.40620430285482856, 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.048778395365119291, 4.0593499999999993, - 0.38334160463488065, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, - 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.025915697145171453, - 4.2729999999999997, 0.40620430285482856, 0.025915697145171453, 4.2729999999999997, 0.40620430285482856, 0.048778395365119291, 4.2729999999999997, - 0.38334160463488065, 0.048778395365119291, 4.2729999999999997, 0.24568580231744036, 0.095261604634880703, 0, 0.26216430285482856, 0.095261604634880703, 0, - 0.26216430285482856, 0.1207983953651193, 0, 0.24568580231744036, 0.1207983953651193, 0, 0.24568580231744036, 0.095261604634880703, 0.21364999999999998, - 0.26216430285482856, 0.095261604634880703, 0.21364999999999998, 0.26216430285482856, 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, - 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, 0.095261604634880703, 0.21364999999999998, 0.26216430285482856, 0.095261604634880703, - 0.21364999999999998, 0.26216430285482856, 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, 0.1207983953651193, 0.21364999999999998, - 0.24568580231744036, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, - 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.095261604634880703, - 0.42729999999999996, 0.26216430285482856, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, 0.1207983953651193, 0.42729999999999996, - 0.24568580231744036, 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, - 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, 0.1207983953651193, - 0.64094999999999991, 0.24568580231744036, 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, 0.095261604634880703, 0.64094999999999991, - 0.26216430285482856, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, - 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.1207983953651193, - 0.85459999999999992, 0.24568580231744036, 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, 0.095261604634880703, 0.85459999999999992, - 0.26216430285482856, 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, - 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, 0.095261604634880703, - 1.0682499999999999, 0.26216430285482856, 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.1207983953651193, 1.0682499999999999, - 0.24568580231744036, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, - 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.095261604634880703, - 1.2818999999999998, 0.26216430285482856, 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, 0.1207983953651193, 1.2818999999999998, - 0.24568580231744036, 0.1207983953651193, 1.2818999999999998, 0.24568580231744036, 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, - 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, 0.1207983953651193, 1.2818999999999998, 0.24568580231744036, 0.1207983953651193, - 1.2818999999999998, 0.24568580231744036, 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.095261604634880703, 1.4955499999999999, - 0.26216430285482856, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, - 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.1207983953651193, - 1.4955499999999999, 0.24568580231744036, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, 0.095261604634880703, 1.7091999999999998, - 0.26216430285482856, 0.095261604634880703, 1.7091999999999998, 0.26216430285482856, 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, - 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, 0.095261604634880703, 1.7091999999999998, 0.26216430285482856, 0.095261604634880703, - 1.7091999999999998, 0.26216430285482856, 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, 0.1207983953651193, 1.7091999999999998, - 0.24568580231744036, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, - 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.095261604634880703, - 1.9228499999999997, 0.26216430285482856, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, 0.1207983953651193, 1.9228499999999997, - 0.24568580231744036, 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, - 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, 0.1207983953651193, - 2.1364999999999998, 0.24568580231744036, 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, 0.095261604634880703, 2.1364999999999998, - 0.26216430285482856, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, - 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.1207983953651193, - 2.3501499999999997, 0.24568580231744036, 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, 0.095261604634880703, 2.3501499999999997, - 0.26216430285482856, 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, - 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, 0.095261604634880703, - 2.5637999999999996, 0.26216430285482856, 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.1207983953651193, 2.5637999999999996, - 0.24568580231744036, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, - 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.095261604634880703, - 2.7774499999999995, 0.26216430285482856, 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, 0.1207983953651193, 2.7774499999999995, - 0.24568580231744036, 0.1207983953651193, 2.7774499999999995, 0.24568580231744036, 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, - 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, 0.1207983953651193, - 2.7774499999999995, 0.24568580231744036, 0.1207983953651193, 2.7774499999999995, 0.24568580231744036, 0.095261604634880703, 2.9910999999999999, - 0.26216430285482856, 0.095261604634880703, 2.9910999999999999, 0.26216430285482856, 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, - 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, 0.095261604634880703, 2.9910999999999999, 0.26216430285482856, 0.095261604634880703, - 2.9910999999999999, 0.26216430285482856, 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, 0.1207983953651193, 2.9910999999999999, - 0.24568580231744036, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, - 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.095261604634880703, - 3.2047499999999998, 0.26216430285482856, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, 0.1207983953651193, 3.2047499999999998, - 0.24568580231744036, 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, - 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, 0.1207983953651193, - 3.4183999999999997, 0.24568580231744036, 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, 0.095261604634880703, 3.4183999999999997, - 0.26216430285482856, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, - 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.1207983953651193, - 3.6320499999999996, 0.24568580231744036, 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, 0.095261604634880703, 3.6320499999999996, - 0.26216430285482856, 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, - 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, 0.095261604634880703, - 3.8456999999999995, 0.26216430285482856, 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.1207983953651193, 3.8456999999999995, - 0.24568580231744036, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, - 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.095261604634880703, - 4.0593499999999993, 0.26216430285482856, 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, 0.1207983953651193, 4.0593499999999993, - 0.24568580231744036, 0.1207983953651193, 4.0593499999999993, 0.24568580231744036, 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, - 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, 0.1207983953651193, 4.0593499999999993, 0.24568580231744036, 0.1207983953651193, - 4.0593499999999993, 0.24568580231744036, 0.095261604634880703, 4.2729999999999997, 0.26216430285482856, 0.095261604634880703, 4.2729999999999997, - 0.26216430285482856, 0.1207983953651193, 4.2729999999999997, 0.24568580231744036, 0.1207983953651193, 4.2729999999999997, 0.31399569714517145, - 0.097935697145171446, 0, 0.33418430285482853, 0.097935697145171446, 0, 0.33418430285482853, 0.11812430285482856, 0, 0.31399569714517145, 0.11812430285482856, 0, - 0.31399569714517145, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, - 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.097935697145171446, - 0.21364999999999998, 0.33418430285482853, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, 0.11812430285482856, 0.21364999999999998, - 0.31399569714517145, 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, - 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, 0.11812430285482856, - 0.42729999999999996, 0.31399569714517145, 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, 0.097935697145171446, 0.42729999999999996, - 0.33418430285482853, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, - 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.11812430285482856, - 0.64094999999999991, 0.31399569714517145, 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, 0.097935697145171446, 0.64094999999999991, - 0.33418430285482853, 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, - 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, 0.097935697145171446, - 0.85459999999999992, 0.33418430285482853, 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.11812430285482856, 0.85459999999999992, - 0.31399569714517145, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, - 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.097935697145171446, - 1.0682499999999999, 0.33418430285482853, 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, 0.11812430285482856, 1.0682499999999999, - 0.31399569714517145, 0.11812430285482856, 1.0682499999999999, 0.31399569714517145, 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, - 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, 0.11812430285482856, 1.0682499999999999, 0.31399569714517145, 0.11812430285482856, - 1.0682499999999999, 0.31399569714517145, 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.097935697145171446, 1.2818999999999998, - 0.33418430285482853, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, - 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.11812430285482856, - 1.2818999999999998, 0.31399569714517145, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, 0.097935697145171446, 1.4955499999999999, - 0.33418430285482853, 0.097935697145171446, 1.4955499999999999, 0.33418430285482853, 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, - 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, 0.097935697145171446, 1.4955499999999999, 0.33418430285482853, 0.097935697145171446, - 1.4955499999999999, 0.33418430285482853, 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, 0.11812430285482856, 1.4955499999999999, - 0.31399569714517145, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, - 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.097935697145171446, - 1.7091999999999998, 0.33418430285482853, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, 0.11812430285482856, 1.7091999999999998, - 0.31399569714517145, 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, - 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, 0.11812430285482856, - 1.9228499999999997, 0.31399569714517145, 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, 0.097935697145171446, 1.9228499999999997, - 0.33418430285482853, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, - 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.11812430285482856, - 2.1364999999999998, 0.31399569714517145, 0.11812430285482856, 2.1364999999999998, - 0.31399569714517145, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, - 0.11812430285482856, 2.1364999999999998, 0.31399569714517145, 0.11812430285482856, 2.1364999999999998, 0.31399569714517145, 0.097935697145171446, - 2.3501499999999997, 0.33418430285482853, 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, 0.11812430285482856, 2.3501499999999997, - 0.31399569714517145, 0.11812430285482856, 2.3501499999999997, 0.31399569714517145, 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, - 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, 0.11812430285482856, 2.3501499999999997, 0.31399569714517145, 0.11812430285482856, - 2.3501499999999997, 0.31399569714517145, 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.097935697145171446, 2.5637999999999996, - 0.33418430285482853, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, - 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.11812430285482856, - 2.5637999999999996, 0.31399569714517145, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, 0.097935697145171446, 2.7774499999999995, - 0.33418430285482853, 0.097935697145171446, 2.7774499999999995, 0.33418430285482853, 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, - 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, 0.097935697145171446, 2.7774499999999995, 0.33418430285482853, 0.097935697145171446, - 2.7774499999999995, 0.33418430285482853, 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, 0.11812430285482856, 2.7774499999999995, - 0.31399569714517145, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, - 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.097935697145171446, - 2.9910999999999999, 0.33418430285482853, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, 0.11812430285482856, 2.9910999999999999, - 0.31399569714517145, 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, - 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, 0.11812430285482856, - 3.2047499999999998, 0.31399569714517145, 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, 0.097935697145171446, 3.2047499999999998, - 0.33418430285482853, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, - 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.11812430285482856, - 3.4183999999999997, 0.31399569714517145, 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, 0.097935697145171446, 3.4183999999999997, - 0.33418430285482853, 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, - 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, 0.097935697145171446, - 3.6320499999999996, 0.33418430285482853, 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.11812430285482856, 3.6320499999999996, - 0.31399569714517145, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, - 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.097935697145171446, - 3.8456999999999995, 0.33418430285482853, 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, 0.11812430285482856, 3.8456999999999995, - 0.31399569714517145, 0.11812430285482856, 3.8456999999999995, 0.31399569714517145, 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, - 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, 0.11812430285482856, - 3.8456999999999995, 0.31399569714517145, 0.11812430285482856, 3.8456999999999995, 0.31399569714517145, 0.097935697145171446, 4.0593499999999993, - 0.33418430285482853, 0.097935697145171446, 4.0593499999999993, 0.33418430285482853, 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, - 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, 0.097935697145171446, 4.0593499999999993, 0.33418430285482853, 0.097935697145171446, - 4.0593499999999993, 0.33418430285482853, 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, 0.11812430285482856, 4.0593499999999993, - 0.31399569714517145, 0.097935697145171446, 4.2729999999999997, 0.33418430285482853, 0.097935697145171446, 4.2729999999999997, 0.33418430285482853, - 0.11812430285482856, 4.2729999999999997, 0.31399569714517145, 0.11812430285482856, 4.2729999999999997, 0.38601569714517142, 0.095261604634880703, 0, - 0.40249419768255962, 0.095261604634880703, 0, 0.40249419768255962, 0.1207983953651193, 0, 0.38601569714517142, 0.1207983953651193, 0, 0.38601569714517142, - 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.1207983953651193, - 0.21364999999999998, 0.38601569714517142, 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, 0.095261604634880703, 0.21364999999999998, - 0.40249419768255962, 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, - 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, 0.095261604634880703, - 0.42729999999999996, 0.40249419768255962, 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.1207983953651193, 0.42729999999999996, - 0.38601569714517142, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, - 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.095261604634880703, - 0.64094999999999991, 0.40249419768255962, 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, 0.1207983953651193, 0.64094999999999991, - 0.38601569714517142, 0.1207983953651193, 0.64094999999999991, 0.38601569714517142, 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, - 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, 0.1207983953651193, 0.64094999999999991, 0.38601569714517142, 0.1207983953651193, - 0.64094999999999991, 0.38601569714517142, 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.095261604634880703, 0.85459999999999992, - 0.40249419768255962, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, - 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.1207983953651193, - 0.85459999999999992, 0.38601569714517142, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, 0.095261604634880703, 1.0682499999999999, - 0.40249419768255962, 0.095261604634880703, 1.0682499999999999, 0.40249419768255962, 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, - 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, 0.095261604634880703, 1.0682499999999999, 0.40249419768255962, 0.095261604634880703, - 1.0682499999999999, 0.40249419768255962, 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, 0.1207983953651193, 1.0682499999999999, - 0.38601569714517142, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, - 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.095261604634880703, - 1.2818999999999998, 0.40249419768255962, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, 0.1207983953651193, 1.2818999999999998, - 0.38601569714517142, 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, - 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, 0.1207983953651193, - 1.4955499999999999, 0.38601569714517142, 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, 0.095261604634880703, 1.4955499999999999, - 0.40249419768255962, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, - 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.1207983953651193, - 1.7091999999999998, 0.38601569714517142, 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, 0.095261604634880703, 1.7091999999999998, - 0.40249419768255962, 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, - 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, 0.095261604634880703, - 1.9228499999999997, 0.40249419768255962, 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.1207983953651193, 1.9228499999999997, - 0.38601569714517142, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, - 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.095261604634880703, - 2.1364999999999998, 0.40249419768255962, 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, 0.1207983953651193, 2.1364999999999998, - 0.38601569714517142, 0.1207983953651193, 2.1364999999999998, 0.38601569714517142, 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, - 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, 0.1207983953651193, 2.1364999999999998, 0.38601569714517142, 0.1207983953651193, - 2.1364999999999998, 0.38601569714517142, 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.095261604634880703, 2.3501499999999997, - 0.40249419768255962, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, - 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.1207983953651193, - 2.3501499999999997, 0.38601569714517142, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, 0.095261604634880703, 2.5637999999999996, - 0.40249419768255962, 0.095261604634880703, 2.5637999999999996, 0.40249419768255962, 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, - 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, 0.095261604634880703, 2.5637999999999996, 0.40249419768255962, 0.095261604634880703, - 2.5637999999999996, 0.40249419768255962, 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, 0.1207983953651193, 2.5637999999999996, - 0.38601569714517142, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, - 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.095261604634880703, - 2.7774499999999995, 0.40249419768255962, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, 0.1207983953651193, 2.7774499999999995, - 0.38601569714517142, 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, - 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, 0.1207983953651193, - 2.9910999999999999, 0.38601569714517142, 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, 0.095261604634880703, 2.9910999999999999, - 0.40249419768255962, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, - 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.1207983953651193, - 3.2047499999999998, 0.38601569714517142, 0.1207983953651193, 3.2047499999999998, - 0.38601569714517142, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, - 0.1207983953651193, 3.2047499999999998, 0.38601569714517142, 0.1207983953651193, 3.2047499999999998, 0.38601569714517142, 0.095261604634880703, - 3.4183999999999997, 0.40249419768255962, 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, 0.1207983953651193, 3.4183999999999997, - 0.38601569714517142, 0.1207983953651193, 3.4183999999999997, 0.38601569714517142, 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, - 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, 0.1207983953651193, 3.4183999999999997, 0.38601569714517142, 0.1207983953651193, - 3.4183999999999997, 0.38601569714517142, 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.095261604634880703, 3.6320499999999996, - 0.40249419768255962, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, - 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.1207983953651193, - 3.6320499999999996, 0.38601569714517142, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, 0.095261604634880703, 3.8456999999999995, - 0.40249419768255962, 0.095261604634880703, 3.8456999999999995, 0.40249419768255962, 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, - 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, 0.095261604634880703, 3.8456999999999995, 0.40249419768255962, 0.095261604634880703, - 3.8456999999999995, 0.40249419768255962, 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, 0.1207983953651193, 3.8456999999999995, - 0.38601569714517142, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, - 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.095261604634880703, - 4.0593499999999993, 0.40249419768255962, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, 0.1207983953651193, 4.0593499999999993, - 0.38601569714517142, 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.095261604634880703, 4.2729999999999997, 0.40249419768255962, - 0.095261604634880703, 4.2729999999999997, 0.40249419768255962, 0.1207983953651193, 4.2729999999999997, 0.38601569714517142, 0.1207983953651193, - 4.2729999999999997, 0.24197569714517148, 0.16728160463488068, 0, 0.26483839536511933, 0.16728160463488068, 0, 0.26483839536511933, 0.19014430285482856, 0, - 0.24197569714517148, 0.19014430285482856, 0, 0.24197569714517148, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, 0.16728160463488068, - 0.21364999999999998, 0.26483839536511933, 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.19014430285482856, 0.21364999999999998, - 0.24197569714517148, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, - 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.16728160463488068, - 0.42729999999999996, 0.26483839536511933, 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, 0.19014430285482856, 0.42729999999999996, - 0.24197569714517148, 0.19014430285482856, 0.42729999999999996, 0.24197569714517148, 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, - 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, 0.19014430285482856, 0.42729999999999996, 0.24197569714517148, 0.19014430285482856, - 0.42729999999999996, 0.24197569714517148, 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.16728160463488068, 0.64094999999999991, - 0.26483839536511933, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, - 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.19014430285482856, - 0.64094999999999991, 0.24197569714517148, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, 0.16728160463488068, 0.85459999999999992, - 0.26483839536511933, 0.16728160463488068, 0.85459999999999992, 0.26483839536511933, 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, - 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, 0.16728160463488068, 0.85459999999999992, 0.26483839536511933, 0.16728160463488068, - 0.85459999999999992, 0.26483839536511933, 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, 0.19014430285482856, 0.85459999999999992, - 0.24197569714517148, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, - 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.16728160463488068, - 1.0682499999999999, 0.26483839536511933, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, 0.19014430285482856, 1.0682499999999999, - 0.24197569714517148, 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, - 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, 0.19014430285482856, - 1.2818999999999998, 0.24197569714517148, 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, 0.16728160463488068, 1.2818999999999998, - 0.26483839536511933, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, - 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.19014430285482856, - 1.4955499999999999, 0.24197569714517148, 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, 0.16728160463488068, 1.4955499999999999, - 0.26483839536511933, 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, - 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, 0.16728160463488068, - 1.7091999999999998, 0.26483839536511933, 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.19014430285482856, 1.7091999999999998, - 0.24197569714517148, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, - 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.16728160463488068, - 1.9228499999999997, 0.26483839536511933, 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, 0.19014430285482856, 1.9228499999999997, - 0.24197569714517148, 0.19014430285482856, 1.9228499999999997, 0.24197569714517148, 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, - 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, 0.19014430285482856, 1.9228499999999997, 0.24197569714517148, 0.19014430285482856, - 1.9228499999999997, 0.24197569714517148, 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.16728160463488068, 2.1364999999999998, - 0.26483839536511933, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, - 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.19014430285482856, - 2.1364999999999998, 0.24197569714517148, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, 0.16728160463488068, 2.3501499999999997, - 0.26483839536511933, 0.16728160463488068, 2.3501499999999997, 0.26483839536511933, 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, - 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, 0.16728160463488068, 2.3501499999999997, 0.26483839536511933, 0.16728160463488068, - 2.3501499999999997, 0.26483839536511933, 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, 0.19014430285482856, 2.3501499999999997, - 0.24197569714517148, 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, - 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, 0.19014430285482856, - 2.5637999999999996, 0.24197569714517148, 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, 0.16728160463488068, 2.5637999999999996, - 0.26483839536511933, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, - 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.19014430285482856, - 2.7774499999999995, 0.24197569714517148, 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, 0.16728160463488068, 2.7774499999999995, - 0.26483839536511933, 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, - 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, 0.16728160463488068, - 2.9910999999999999, 0.26483839536511933, 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.19014430285482856, 2.9910999999999999, - 0.24197569714517148, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, - 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.16728160463488068, - 3.2047499999999998, 0.26483839536511933, 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, 0.19014430285482856, 3.2047499999999998, - 0.24197569714517148, 0.19014430285482856, 3.2047499999999998, 0.24197569714517148, 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, - 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, 0.19014430285482856, 3.2047499999999998, 0.24197569714517148, 0.19014430285482856, - 3.2047499999999998, 0.24197569714517148, 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.16728160463488068, 3.4183999999999997, - 0.26483839536511933, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, - 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.19014430285482856, - 3.4183999999999997, 0.24197569714517148, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, 0.16728160463488068, 3.6320499999999996, - 0.26483839536511933, 0.16728160463488068, 3.6320499999999996, 0.26483839536511933, 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, - 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, 0.16728160463488068, 3.6320499999999996, 0.26483839536511933, 0.16728160463488068, - 3.6320499999999996, 0.26483839536511933, 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, 0.19014430285482856, 3.6320499999999996, - 0.24197569714517148, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, - 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.16728160463488068, - 3.8456999999999995, 0.26483839536511933, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, 0.19014430285482856, 3.8456999999999995, - 0.24197569714517148, 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, - 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, 0.19014430285482856, - 4.0593499999999993, 0.24197569714517148, 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, 0.16728160463488068, 4.0593499999999993, - 0.26483839536511933, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, - 0.16728160463488068, 4.2729999999999997, 0.26483839536511933, 0.16728160463488068, 4.2729999999999997, 0.26483839536511933, 0.19014430285482856, - 4.2729999999999997, 0.24197569714517148, 0.19014430285482856, 4.2729999999999997, - 0.31132160463488068, 0.16995569714517142, 0, 0.3368583953651193, 0.16995569714517142, 0, 0.3368583953651193, 0.18643419768255964, 0, 0.31132160463488068, - 0.18643419768255964, 0, 0.31132160463488068, 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.16995569714517142, 0.21364999999999998, - 0.3368583953651193, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, - 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.18643419768255964, - 0.21364999999999998, 0.31132160463488068, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, 0.16995569714517142, 0.42729999999999996, - 0.3368583953651193, 0.16995569714517142, 0.42729999999999996, 0.3368583953651193, 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, - 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, 0.16995569714517142, 0.42729999999999996, 0.3368583953651193, 0.16995569714517142, - 0.42729999999999996, 0.3368583953651193, 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, 0.18643419768255964, 0.42729999999999996, - 0.31132160463488068, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, - 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.16995569714517142, - 0.64094999999999991, 0.3368583953651193, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, 0.18643419768255964, 0.64094999999999991, - 0.31132160463488068, 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, - 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, 0.18643419768255964, - 0.85459999999999992, 0.31132160463488068, 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, 0.16995569714517142, 0.85459999999999992, - 0.3368583953651193, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, - 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.18643419768255964, - 1.0682499999999999, 0.31132160463488068, 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, 0.16995569714517142, 1.0682499999999999, - 0.3368583953651193, 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, - 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, 0.16995569714517142, - 1.2818999999999998, 0.3368583953651193, 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.18643419768255964, 1.2818999999999998, - 0.31132160463488068, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, - 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.16995569714517142, - 1.4955499999999999, 0.3368583953651193, 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, 0.18643419768255964, 1.4955499999999999, - 0.31132160463488068, 0.18643419768255964, 1.4955499999999999, 0.31132160463488068, 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, - 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, 0.18643419768255964, 1.4955499999999999, 0.31132160463488068, 0.18643419768255964, - 1.4955499999999999, 0.31132160463488068, 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.16995569714517142, 1.7091999999999998, - 0.3368583953651193, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, - 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.18643419768255964, - 1.7091999999999998, 0.31132160463488068, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, 0.16995569714517142, 1.9228499999999997, - 0.3368583953651193, 0.16995569714517142, 1.9228499999999997, 0.3368583953651193, 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, - 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, 0.16995569714517142, 1.9228499999999997, 0.3368583953651193, 0.16995569714517142, - 1.9228499999999997, 0.3368583953651193, 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, 0.18643419768255964, 1.9228499999999997, - 0.31132160463488068, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, - 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.16995569714517142, - 2.1364999999999998, 0.3368583953651193, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, 0.18643419768255964, 2.1364999999999998, - 0.31132160463488068, 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, - 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, 0.18643419768255964, - 2.3501499999999997, 0.31132160463488068, 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, 0.16995569714517142, 2.3501499999999997, - 0.3368583953651193, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, - 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.18643419768255964, - 2.5637999999999996, 0.31132160463488068, 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, 0.16995569714517142, 2.5637999999999996, - 0.3368583953651193, 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, - 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, 0.16995569714517142, - 2.7774499999999995, 0.3368583953651193, 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.18643419768255964, 2.7774499999999995, - 0.31132160463488068, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, - 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.16995569714517142, - 2.9910999999999999, 0.3368583953651193, 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, 0.18643419768255964, 2.9910999999999999, - 0.31132160463488068, 0.18643419768255964, 2.9910999999999999, 0.31132160463488068, 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, - 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, 0.18643419768255964, 2.9910999999999999, 0.31132160463488068, 0.18643419768255964, - 2.9910999999999999, 0.31132160463488068, 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.16995569714517142, 3.2047499999999998, - 0.3368583953651193, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, - 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.18643419768255964, - 3.2047499999999998, 0.31132160463488068, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, 0.16995569714517142, 3.4183999999999997, - 0.3368583953651193, 0.16995569714517142, 3.4183999999999997, 0.3368583953651193, 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, - 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, 0.16995569714517142, 3.4183999999999997, 0.3368583953651193, 0.16995569714517142, - 3.4183999999999997, 0.3368583953651193, 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, 0.18643419768255964, 3.4183999999999997, - 0.31132160463488068, 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, - 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, 0.18643419768255964, - 3.6320499999999996, 0.31132160463488068, 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, 0.16995569714517142, 3.6320499999999996, - 0.3368583953651193, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, - 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.18643419768255964, - 3.8456999999999995, 0.31132160463488068, 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, 0.16995569714517142, 3.8456999999999995, - 0.3368583953651193, 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, - 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, 0.16995569714517142, - 4.0593499999999993, 0.3368583953651193, 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.18643419768255964, 4.0593499999999993, - 0.31132160463488068, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, - 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.16995569714517142, - 4.2729999999999997, 0.3368583953651193, 0.16995569714517142, 4.2729999999999997, 0.3368583953651193, 0.18643419768255964, 4.2729999999999997, - 0.31132160463488068, 0.18643419768255964, 4.2729999999999997, 0.38334160463488065, 0.1672816046348807, 0, 0.40620430285482856, 0.1672816046348807, 0, - 0.40620430285482856, 0.19014430285482853, 0, 0.38334160463488065, 0.19014430285482853, 0, 0.38334160463488065, 0.1672816046348807, 0.21364999999999998, - 0.40620430285482856, 0.1672816046348807, 0.21364999999999998, 0.40620430285482856, 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, - 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, 0.1672816046348807, 0.21364999999999998, 0.40620430285482856, 0.1672816046348807, - 0.21364999999999998, 0.40620430285482856, 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, 0.19014430285482853, 0.21364999999999998, - 0.38334160463488065, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, - 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.1672816046348807, - 0.42729999999999996, 0.40620430285482856, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, 0.19014430285482853, 0.42729999999999996, - 0.38334160463488065, 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, - 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, 0.19014430285482853, - 0.64094999999999991, 0.38334160463488065, 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, 0.1672816046348807, 0.64094999999999991, - 0.40620430285482856, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, - 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.19014430285482853, - 0.85459999999999992, 0.38334160463488065, 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, 0.1672816046348807, 0.85459999999999992, - 0.40620430285482856, 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, - 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, 0.1672816046348807, - 1.0682499999999999, 0.40620430285482856, 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.19014430285482853, 1.0682499999999999, - 0.38334160463488065, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, - 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.1672816046348807, - 1.2818999999999998, 0.40620430285482856, 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, 0.19014430285482853, 1.2818999999999998, - 0.38334160463488065, 0.19014430285482853, 1.2818999999999998, 0.38334160463488065, 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, - 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, 0.19014430285482853, 1.2818999999999998, 0.38334160463488065, 0.19014430285482853, - 1.2818999999999998, 0.38334160463488065, 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.1672816046348807, 1.4955499999999999, - 0.40620430285482856, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, - 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.19014430285482853, - 1.4955499999999999, 0.38334160463488065, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, 0.1672816046348807, 1.7091999999999998, - 0.40620430285482856, 0.1672816046348807, 1.7091999999999998, 0.40620430285482856, 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, - 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, 0.1672816046348807, 1.7091999999999998, 0.40620430285482856, 0.1672816046348807, - 1.7091999999999998, 0.40620430285482856, 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, 0.19014430285482853, 1.7091999999999998, - 0.38334160463488065, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, - 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.1672816046348807, - 1.9228499999999997, 0.40620430285482856, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, 0.19014430285482853, 1.9228499999999997, - 0.38334160463488065, 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, - 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, 0.19014430285482853, - 2.1364999999999998, 0.38334160463488065, 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, 0.1672816046348807, 2.1364999999999998, - 0.40620430285482856, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, - 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.19014430285482853, - 2.3501499999999997, 0.38334160463488065, 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, 0.1672816046348807, 2.3501499999999997, - 0.40620430285482856, 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, - 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, 0.1672816046348807, - 2.5637999999999996, 0.40620430285482856, 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.19014430285482853, 2.5637999999999996, - 0.38334160463488065, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, - 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.1672816046348807, - 2.7774499999999995, 0.40620430285482856, 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, 0.19014430285482853, 2.7774499999999995, - 0.38334160463488065, 0.19014430285482853, 2.7774499999999995, 0.38334160463488065, 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, - 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, 0.19014430285482853, - 2.7774499999999995, 0.38334160463488065, 0.19014430285482853, 2.7774499999999995, 0.38334160463488065, 0.1672816046348807, 2.9910999999999999, - 0.40620430285482856, 0.1672816046348807, 2.9910999999999999, 0.40620430285482856, 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, - 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, 0.1672816046348807, 2.9910999999999999, 0.40620430285482856, 0.1672816046348807, - 2.9910999999999999, 0.40620430285482856, 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, 0.19014430285482853, 2.9910999999999999, - 0.38334160463488065, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, - 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.1672816046348807, - 3.2047499999999998, 0.40620430285482856, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, 0.19014430285482853, 3.2047499999999998, - 0.38334160463488065, 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, - 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, 0.19014430285482853, - 3.4183999999999997, 0.38334160463488065, 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, 0.1672816046348807, 3.4183999999999997, - 0.40620430285482856, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, - 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.19014430285482853, - 3.6320499999999996, 0.38334160463488065, 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, 0.1672816046348807, 3.6320499999999996, - 0.40620430285482856, 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, - 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, 0.1672816046348807, - 3.8456999999999995, 0.40620430285482856, 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.19014430285482853, 3.8456999999999995, - 0.38334160463488065, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, - 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.1672816046348807, - 4.0593499999999993, 0.40620430285482856, 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, 0.19014430285482853, 4.0593499999999993, - 0.38334160463488065, 0.19014430285482853, 4.0593499999999993, 0.38334160463488065, 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, - 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, 0.19014430285482853, 4.0593499999999993, 0.38334160463488065, 0.19014430285482853, - 4.0593499999999993, 0.38334160463488065, 0.1672816046348807, 4.2729999999999997, 0.40620430285482856, 0.1672816046348807, 4.2729999999999997, - 0.40620430285482856, 0.19014430285482853, 4.2729999999999997, 0.38334160463488065, 0.19014430285482853, 4.2729999999999997 - }; - - -const int connTFH8[2560]={ - 1, 2, 7, 6, 28, 29, 34, 33, 2, 3, 8, 7, 29, 30, 35, 34, 3, 4, 9, 8, 30, 31, 36, 35, 4, 5, 10, 9, 31, 32, 37, 36, 6, 7, 12, 11, 33, 34, 39, 38, 7, 8, 13, 12, 34, 35, 40, 39, - 8, 9, 14, 13, 35, 36, 41, 40, 9, 10, 15, 14, 36, 37, 42, 41, 11, 12, 17, 16, 38, 39, 44, 43, 12, 13, 18, 17, 39, 40, 45, 44, 13, 14, 19, 18, 40, 41, 46, 45, 14, 15, 20, 19, - 41, 42, 47, 46, 16, 17, 21, 26, 43, 44, 48, 53, 17, 18, 22, 21, 44, 45, 49, 48, 18, 19, 23, 22, 45, 46, 50, 49, 19, 20, 24, 23, 46, 47, 51, 50, 28, 29, 34, 33, 55, 56, 61, 60, - 29, 30, 35, 34, 56, 57, 62, 61, 30, 31, 36, 35, 57, 58, 63, 62, 31, 32, 37, 36, 58, 59, 64, 63, 33, 34, 39, 38, 60, 61, 66, 65, 34, 35, 40, 39, 61, 62, 67, 66, 35, 36, 41, 40, - 62, 63, 68, 67, 36, 37, 42, 41, 63, 64, 69, 68, 38, 39, 44, 43, 65, 66, 71, 70, 39, 40, 45, 44, 66, 67, 72, 71, 40, 41, 46, 45, 67, 68, 73, 72, 41, 42, 47, 46, 68, 69, 74, 73, - 43, 44, 48, 53, 70, 71, 75, 80, 44, 45, 49, 48, 71, 72, 76, 75, 45, 46, 50, 49, 72, 73, 77, 76, 46, 47, 51, 50, 73, 74, 78, 77, 55, 56, 61, 60, 82, 83, 88, 87, 56, 57, 62, 61, - 83, 84, 89, 88, 57, 58, 63, 62, 84, 85, 90, 89, 58, 59, 64, 63, 85, 86, 91, 90, 60, 61, 66, 65, 87, 88, 93, 92, 61, 62, 67, 66, 88, 89, 94, 93, 62, 63, 68, 67, 89, 90, 95, 94, - 63, 64, 69, 68, 90, 91, 96, 95, 65, 66, 71, 70, 92, 93, 98, 97, 66, 67, 72, 71, 93, 94, 99, 98, 67, 68, 73, 72, 94, 95, 100, 99, 68, 69, 74, 73, 95, 96, 101, 100, 70, 71, 75, - 80, 97, 98, 102, 107, 71, 72, 76, 75, 98, 99, 103, 102, 72, 73, 77, 76, 99, 100, 104, 103, 73, 74, 78, 77, 100, 101, 105, 104, 82, 83, 88, 87, 109, 110, 115, 114, 83, 84, 89, - 88, 110, 111, 116, 115, 84, 85, 90, 89, 111, 112, 117, 116, 85, 86, 91, 90, 112, 113, 118, 117, 87, 88, 93, 92, 114, 115, 120, 119, 88, 89, 94, 93, 115, 116, 121, 120, 89, 90, - 95, 94, 116, 117, 122, 121, 90, 91, 96, 95, 117, 118, 123, 122, 92, 93, 98, 97, 119, 120, 125, 124, 93, 94, 99, 98, 120, 121, 126, 125, 94, 95, 100, 99, 121, 122, 127, 126, 95, - 96, 101, 100, 122, 123, 128, 127, 97, 98, 102, 107, 124, 125, 129, 134, 98, 99, 103, 102, 125, 126, 130, 129, 99, 100, 104, 103, 126, 127, 131, 130, 100, 101, 105, 104, 127, 128, - 132, 131, 109, 110, 115, 114, 136, 137, 142, 141, 110, 111, 116, 115, 137, 138, 143, 142, 111, 112, 117, 116, 138, 139, 144, 143, 112, 113, 118, 117, 139, 140, 145, 144, 114, 115, - 120, 119, 141, 142, 147, 146, 115, 116, 121, 120, 142, 143, 148, 147, 116, 117, 122, 121, 143, 144, 149, 148, 117, 118, 123, 122, 144, 145, 150, 149, 119, 120, 125, 124, 146, 147, - 152, 151, 120, 121, 126, 125, 147, 148, 153, 152, 121, 122, 127, 126, 148, 149, 154, 153, 122, 123, 128, 127, 149, 150, 155, 154, 124, 125, 129, 134, 151, 152, 156, 161, 125, 126, 130, - 129, 152, 153, 157, 156, 126, 127, 131, 130, 153, 154, 158, 157, 127, 128, 132, 131, 154, 155, 159, 158, 136, 137, 142, 141, 163, 164, 169, 168, 137, 138, 143, 142, 164, 165, 170, 169, 138, 139, 144, 143, 165, 166, 171, 170, 139, - 140, 145, 144, 166, 167, 172, 171, 141, 142, 147, 146, 168, 169, 174, 173, 142, 143, 148, 147, 169, 170, 175, 174, 143, 144, 149, 148, 170, 171, 176, 175, 144, 145, 150, 149, 171, 172, 177, 176, 146, 147, 152, 151, 173, 174, 179, - 178, 147, 148, 153, 152, 174, 175, 180, 179, 148, 149, 154, 153, 175, 176, 181, 180, 149, 150, 155, 154, 176, 177, 182, 181, 151, 152, 156, 161, 178, 179, 183, 188, 152, 153, 157, 156, 179, 180, 184, 183, 153, 154, 158, 157, 180, - 181, 185, 184, 154, 155, 159, 158, 181, 182, 186, 185, 163, 164, 169, 168, 190, 191, 196, 195, 164, 165, 170, 169, 191, 192, 197, 196, 165, 166, 171, 170, 192, 193, 198, 197, 166, 167, 172, 171, 193, 194, 199, 198, 168, 169, 174, - 173, 195, 196, 201, 200, 169, 170, 175, 174, 196, 197, 202, 201, 170, 171, 176, 175, 197, 198, 203, 202, 171, 172, 177, 176, 198, 199, 204, 203, 173, 174, 179, 178, 200, 201, 206, 205, 174, 175, 180, 179, 201, 202, 207, 206, 175, - 176, 181, 180, 202, 203, 208, 207, 176, 177, 182, 181, 203, 204, 209, 208, 178, 179, 183, 188, 205, 206, 210, 215, 179, 180, 184, 183, 206, 207, 211, 210, 180, 181, 185, 184, 207, 208, 212, 211, 181, 182, 186, 185, 208, 209, 213, - 212, 190, 191, 196, 195, 217, 218, 223, 222, 191, 192, 197, 196, 218, 219, 224, 223, 192, 193, 198, 197, 219, 220, 225, 224, 193, 194, 199, 198, 220, 221, 226, 225, 195, 196, 201, 200, 222, 223, 228, 227, 196, 197, 202, 201, 223, - 224, 229, 228, 197, 198, 203, 202, 224, 225, 230, 229, 198, 199, 204, 203, 225, 226, 231, 230, 200, 201, 206, 205, 227, 228, 233, 232, 201, 202, 207, 206, 228, 229, 234, 233, 202, 203, 208, 207, 229, 230, 235, 234, 203, 204, 209, - 208, 230, 231, 236, 235, 205, 206, 210, 215, 232, 233, 237, 242, 206, 207, 211, 210, 233, 234, 238, 237, 207, 208, 212, 211, 234, 235, 239, 238, 208, 209, 213, 212, 235, 236, 240, 239, 217, 218, 223, 222, 244, 245, 250, 249, 218, - 219, 224, 223, 245, 246, 251, 250, 219, 220, 225, 224, 246, 247, 252, 251, 220, 221, 226, 225, 247, 248, 253, 252, 222, 223, 228, 227, 249, 250, 255, 254, 223, 224, 229, 228, 250, 251, 256, 255, 224, 225, 230, 229, 251, 252, 257, - 256, 225, 226, 231, 230, 252, 253, 258, 257, 227, 228, 233, 232, 254, 255, 260, 259, 228, 229, 234, 233, 255, 256, 261, 260, 229, 230, 235, 234, 256, 257, 262, 261, 230, 231, 236, 235, 257, 258, 263, 262, 232, 233, 237, 242, 259, - 260, 264, 269, 233, 234, 238, 237, 260, 261, 265, 264, 234, 235, 239, 238, 261, 262, 266, 265, 235, 236, 240, 239, 262, 263, 267, 266, 244, 245, 250, 249, 271, 272, 277, 276, 245, 246, 251, 250, 272, 273, 278, 277, 246, 247, 252, - 251, 273, 274, 279, 278, 247, 248, 253, 252, 274, 275, 280, 279, 249, 250, 255, 254, 276, 277, 282, 281, 250, 251, 256, 255, 277, 278, 283, 282, 251, 252, 257, 256, 278, 279, 284, 283, 252, 253, 258, 257, 279, 280, 285, 284, 254, - 255, 260, 259, 281, 282, 287, 286, 255, 256, 261, 260, 282, 283, 288, 287, 256, 257, 262, 261, 283, 284, 289, 288, 257, 258, 263, 262, 284, 285, 290, 289, 259, 260, 264, 269, 286, 287, 291, 296, 260, 261, 265, 264, 287, 288, 292, - 291, 261, 262, 266, 265, 288, 289, 293, 292, 262, 263, 267, 266, 289, 290, 294, 293, 271, 272, 277, 276, 298, 299, 304, 303, 272, 273, 278, 277, 299, 300, 305, 304, 273, 274, 279, 278, 300, 301, 306, 305, 274, 275, 280, 279, 301, - 302, 307, 306, 276, 277, 282, 281, 303, 304, 309, 308, 277, 278, 283, 282, 304, 305, 310, 309, 278, 279, 284, 283, 305, 306, 311, 310, 279, 280, 285, 284, 306, 307, 312, 311, 281, 282, 287, 286, 308, 309, 314, 313, 282, 283, 288, - 287, 309, 310, 315, 314, 283, 284, 289, 288, 310, 311, 316, 315, 284, 285, 290, 289, 311, 312, 317, 316, 286, 287, 291, 296, 313, 314, 318, 323, 287, 288, 292, 291, 314, 315, 319, 318, 288, 289, 293, 292, 315, 316, 320, 319, 289, - 290, 294, 293, 316, 317, 321, 320, 298, 299, 304, 303, 325, 326, 331, 330, 299, 300, 305, 304, 326, 327, 332, 331, 300, 301, 306, 305, 327, 328, 333, 332, 301, 302, 307, 306, 328, 329, 334, 333, 303, 304, 309, 308, 330, 331, 336, - 335, 304, 305, 310, 309, 331, 332, 337, 336, 305, 306, 311, 310, 332, 333, 338, 337, 306, 307, 312, 311, 333, 334, 339, 338, 308, 309, 314, 313, 335, 336, 341, 340, 309, 310, 315, 314, 336, 337, 342, 341, 310, 311, 316, 315, 337, - 338, 343, 342, 311, 312, 317, 316, 338, 339, 344, 343, 313, 314, 318, 323, 340, 341, 345, 350, 314, 315, 319, 318, 341, 342, 346, 345, 315, 316, 320, 319, 342, 343, 347, 346, 316, 317, 321, 320, 343, 344, 348, 347, 325, 326, 331, - 330, 352, 353, 358, 357, 326, 327, 332, 331, 353, 354, 359, 358, 327, 328, 333, 332, 354, 355, 360, 359, 328, 329, 334, 333, 355, 356, 361, 360, 330, 331, 336, 335, 357, 358, 363, 362, 331, 332, 337, 336, 358, 359, 364, 363, 332, - 333, 338, 337, 359, 360, 365, 364, 333, 334, 339, 338, 360, 361, 366, 365, 335, 336, 341, 340, 362, 363, 368, 367, 336, 337, 342, 341, 363, 364, 369, 368, 337, 338, 343, 342, 364, 365, 370, 369, 338, 339, 344, 343, 365, 366, 371, - 370, 340, 341, 345, 350, 367, 368, 372, 377, 341, 342, 346, 345, 368, 369, 373, 372, 342, 343, 347, 346, 369, 370, 374, 373, 343, 344, 348, 347, 370, 371, 375, 374, 352, 353, 358, 357, 379, 380, 385, 384, 353, 354, 359, 358, 380, - 381, 386, 385, 354, 355, 360, 359, 381, 382, 387, 386, 355, 356, 361, 360, 382, 383, 388, 387, 357, 358, 363, 362, 384, 385, 390, 389, 358, 359, 364, 363, 385, 386, 391, 390, 359, 360, 365, 364, 386, 387, 392, 391, 360, 361, 366, - 365, 387, 388, 393, 392, 362, 363, 368, 367, 389, 390, 395, 394, 363, 364, 369, 368, 390, 391, 396, 395, 364, 365, 370, 369, 391, 392, 397, 396, 365, 366, 371, 370, 392, 393, 398, 397, 367, 368, 372, 377, 394, 395, 399, 404, 368, - 369, 373, 372, 395, 396, 400, 399, 369, 370, 374, 373, 396, 397, 401, 400, 370, 371, 375, 374, 397, 398, 402, 401, 379, 380, 385, 384, 406, 407, 412, 411, 380, 381, 386, 385, 407, 408, 413, 412, 381, 382, 387, 386, 408, 409, 414, - 413, 382, 383, 388, 387, 409, 410, 415, 414, 384, 385, 390, 389, 411, 412, 417, 416, 385, 386, 391, 390, 412, 413, 418, 417, 386, 387, 392, 391, 413, 414, 419, 418, 387, 388, 393, 392, 414, 415, 420, 419, 389, 390, 395, 394, 416, - 417, 422, 421, 390, 391, 396, 395, 417, 418, 423, 422, 391, 392, 397, 396, 418, 419, 424, 423, 392, 393, 398, 397, 419, 420, 425, 424, 394, 395, 399, 404, 421, 422, 426, 431, 395, 396, 400, 399, 422, 423, 427, 426, 396, 397, 401, - 400, 423, 424, 428, 427, 397, 398, 402, 401, 424, 425, 429, 428, 406, 407, 412, 411, 433, 434, 439, 438, 407, 408, 413, 412, 434, 435, 440, 439, 408, 409, 414, 413, 435, 436, 441, 440, 409, 410, 415, 414, 436, 437, 442, 441, 411, - 412, 417, 416, 438, 439, 444, 443, 412, 413, 418, 417, 439, 440, 445, 444, 413, 414, 419, 418, 440, 441, 446, 445, 414, 415, 420, 419, 441, 442, 447, 446, 416, 417, 422, 421, 443, 444, 449, 448, 417, 418, 423, 422, 444, 445, 450, - 449, 418, 419, 424, 423, 445, 446, 451, 450, 419, 420, 425, 424, 446, 447, 452, 451, 421, 422, 426, 431, 448, 449, 453, 458, 422, 423, 427, 426, 449, 450, 454, 453, 423, 424, 428, 427, 450, 451, 455, 454, 424, 425, 429, 428, 451, - 452, 456, 455, 433, 434, 439, 438, 460, 461, 466, 465, 434, 435, 440, 439, 461, 462, 467, 466, 435, 436, 441, 440, 462, 463, 468, 467, 436, 437, 442, 441, 463, 464, 469, 468, 438, 439, 444, 443, 465, 466, 471, 470, 439, 440, 445, - 444, 466, 467, 472, 471, 440, 441, 446, 445, 467, 468, 473, 472, 441, 442, 447, 446, 468, 469, 474, 473, 443, 444, 449, 448, 470, 471, 476, 475, 444, 445, 450, 449, 471, 472, 477, 476, 445, 446, 451, 450, 472, 473, 478, 477, 446, - 447, 452, 451, 473, 474, 479, 478, 448, 449, 453, 458, 475, 476, 480, 485, 449, 450, 454, 453, 476, 477, 481, 480, 450, 451, 455, 454, 477, 478, 482, 481, 451, 452, 456, 455, 478, 479, 483, 482, 460, 461, 466, 465, 487, 488, 493, - 492, 461, 462, 467, 466, 488, 489, 494, 493, 462, 463, 468, 467, 489, 490, 495, 494, 463, 464, 469, 468, 490, 491, 496, 495, 465, 466, 471, 470, 492, 493, 498, 497, 466, 467, 472, 471, 493, 494, 499, 498, 467, 468, 473, 472, 494, - 495, 500, 499, 468, 469, 474, 473, 495, 496, 501, 500, 470, 471, 476, 475, 497, 498, 503, 502, 471, 472, 477, 476, 498, 499, 504, 503, 472, 473, 478, 477, 499, 500, 505, 504, 473, 474, 479, 478, 500, 501, 506, 505, 475, 476, 480, - 485, 502, 503, 507, 512, 476, 477, 481, 480, 503, 504, 508, 507, 477, 478, 482, 481, 504, 505, 509, 508, 478, 479, 483, 482, 505, 506, 510, 509, 487, 488, 493, 492, 514, 515, 520, 519, 488, 489, 494, 493, 515, 516, 521, 520, 489, - 490, 495, 494, 516, 517, 522, 521, 490, 491, 496, 495, 517, 518, 523, 522, 492, 493, 498, 497, 519, 520, 525, 524, 493, 494, 499, 498, 520, 521, 526, 525, 494, 495, 500, 499, 521, 522, 527, 526, 495, 496, 501, 500, 522, 523, 528, - 527, 497, 498, 503, 502, 524, 525, 530, 529, 498, 499, 504, 503, 525, 526, 531, 530, 499, 500, 505, 504, 526, 527, 532, 531, 500, 501, 506, 505, 527, 528, 533, 532, 502, 503, 507, 512, 529, 530, 534, 539, 503, 504, 508, 507, 530, - 531, 535, 534, 504, 505, 509, 508, 531, 532, 536, 535, 505, 506, 510, 509, 532, 533, 537, 536, 514, 515, 520, 519, 541, 542, 547, 546, 515, 516, 521, 520, 542, 543, 548, 547, 516, 517, 522, 521, 543, 544, 549, 548, 517, 518, 523, - 522, 544, 545, 550, 549, 519, 520, 525, 524, 546, 547, 552, 551, 520, 521, 526, 525, 547, 548, 553, 552, 521, 522, 527, 526, 548, 549, 554, 553, 522, 523, 528, 527, 549, 550, 555, 554, 524, 525, 530, 529, 551, 552, 557, 556, 525, - 526, 531, 530, 552, 553, 558, 557, 526, 527, 532, 531, 553, 554, 559, 558, 527, 528, 533, 532, 554, 555, 560, 559, 529, 530, 534, 539, 556, 557, 561, 566, 530, 531, 535, 534, 557, 558, 562, 561, 531, 532, 536, 535, 558, 559, 563, - 562, 532, 533, 537, 536, 559, 560, 564, 563}; - -const int connTFPOLH[1000]={ - 0, 25, 26, 16, 11, 6, 1, -1, 27, 28, 33, 38, 43, 53, 52, -1, 0, 1, 28, 27, -1, 1, 6, 33, 28, -1, 6, 11, 38, 33, -1, 11, 16, 43, 38, -1, 16, 26, 53, 43, -1, 26, 25, 52, 53, -1, 25, 0, 27, 52, 27, 52, 53, 43, 38, 33, 28, -1, 54, 55, - 60, 65, 70, 80, 79, -1, 27, 28, 55, 54, -1, 28, 33, 60, 55, -1, 33, 38, 65, 60, -1, 38, 43, 70, 65, -1, 43, 53, 80, 70, -1, 53, 52, 79, 80, -1, 52, 27, 54, 79, 54, 79, 80, 70, 65, 60, 55, -1, 81, 82, 87, 92, 97, 107, 106, -1, 54, - 55, 82, 81, -1, 55, 60, 87, 82, -1, 60, 65, 92, 87, -1, 65, 70, 97, 92, -1, 70, 80, 107, 97, -1, 80, 79, 106, 107, -1, 79, 54, 81, 106, 81, 106, 107, 97, 92, 87, 82, -1, 108, 109, 114, 119, 124, 134, 133, -1, 81, 82, 109, 108, -1, - 82, 87, 114, 109, -1, 87, 92, 119, 114, -1, 92, 97, 124, 119, -1, 97, 107, 134, 124, -1, 107, 106, 133, 134, -1, 106, 81, 108, 133, 108, 133, 134, 124, 119, 114, 109, -1, 135, 136, 141, 146, 151, 161, 160, -1, 108, 109, 136, 135, - -1, 109, 114, 141, 136, -1, 114, 119, 146, 141, -1, 119, 124, 151, 146, -1, 124, 134, 161, 151, -1, 134, 133, 160, 161, -1, 133, 108, 135, 160, 135, 160, 161, 151, 146, 141, 136, -1, 162, 163, 168, 173, 178, 188, 187, -1, 135, 136, - 163, 162, -1, 136, 141, 168, 163, -1, 141, 146, 173, 168, -1, 146, 151, 178, 173, -1, 151, 161, 188, 178, -1, 161, 160, 187, 188, -1, 160, 135, 162, 187, 162, 187, 188, 178, 173, 168, 163, -1, 189, 190, 195, 200, 205, 215, 214, -1, - 162, 163, 190, 189, -1, 163, 168, 195, 190, -1, 168, 173, 200, 195, -1, 173, 178, 205, 200, -1, 178, 188, 215, 205, -1, 188, 187, 214, 215, -1, 187, 162, 189, 214, 189, 214, 215, 205, 200, 195, 190, -1, 216, 217, 222, 227, 232, 242, - 241, -1, 189, 190, 217, 216, -1, 190, 195, 222, 217, -1, 195, 200, 227, 222, -1, 200, 205, 232, 227, -1, 205, 215, 242, 232, -1, 215, 214, 241, 242, -1, 214, 189, 216, 241, 216, 241, 242, 232, 227, 222, 217, -1, 243, 244, 249, 254, -259, 269, 268, -1, 216, 217, 244, 243, -1, 217, 222, 249, 244, -1, 222, 227, 254, 249, -1, 227, 232, 259, 254, -1, 232, 242, 269, 259, -1, 242, 241, 268, 269, -1, 241, 216, 243, 268, 243, 268, 269, 259, 254, 249, 244, -1, 270, 271, 276, - 281, 286, 296, 295, -1, 243, 244, 271, 270, -1, 244, 249, 276, 271, -1, 249, 254, 281, 276, -1, 254, 259, 286, 281, -1, 259, 269, 296, 286, -1, 269, 268, 295, 296, -1, 268, 243, 270, 295, 270, 295, 296, 286, 281, 276, 271, -1, 297, 298, - 303, 308, 313, 323, 322, -1, 270, 271, 298, 297, -1, 271, 276, 303, 298, -1, 276, 281, 308, 303, -1, 281, 286, 313, 308, -1, 286, 296, 323, 313, -1, 296, 295, 322, 323, -1, 295, 270, 297, 322, 297, 322, 323, 313, 308, 303, 298, -1, 324, - 325, 330, 335, 340, 350, 349, -1, 297, 298, 325, 324, -1, 298, 303, 330, 325, -1, 303, 308, 335, 330, -1, 308, 313, 340, 335, -1, 313, 323, 350, 340, -1, 323, 322, 349, 350, -1, 322, 297, 324, 349, 324, 349, 350, 340, 335, 330, 325, -1, - 351, 352, 357, 362, 367, 377, 376, -1, 324, 325, 352, 351, -1, 325, 330, 357, 352, -1, 330, 335, 362, 357, -1, 335, 340, 367, 362, -1, 340, 350, 377, 367, -1, 350, 349, 376, 377, -1, 349, 324, 351, 376, 351, 376, 377, 367, 362, 357, 352, - -1, 378, 379, 384, 389, 394, 404, 403, -1, 351, 352, 379, 378, -1, 352, 357, 384, 379, -1, 357, 362, 389, 384, -1, 362, 367, 394, 389, -1, 367, 377, 404, 394, -1, 377, 376, 403, 404, -1, 376, 351, 378, 403, 378, 403, 404, 394, 389, 384, - 379, -1, 405, 406, 411, 416, 421, 431, 430, -1, 378, 379, 406, 405, -1, 379, 384, 411, 406, -1, 384, 389, 416, 411, -1, 389, 394, 421, 416, -1, 394, 404, 431, 421, -1, 404, 403, 430, 431, -1, 403, 378, 405, 430, 405, 430, 431, 421, 416, - 411, 406, -1, 432, 433, 438, 443, 448, 458, 457, -1, 405, 406, 433, 432, -1, 406, 411, 438, 433, -1, 411, 416, 443, 438, -1, 416, 421, 448, 443, -1, 421, 431, 458, 448, -1, 431, 430, 457, 458, -1, 430, 405, 432, 457, 432, 457, 458, 448, - 443, 438, 433, -1, 459, 460, 465, 470, 475, 485, 484, -1, 432, 433, 460, 459, -1, 433, 438, 465, 460, -1, 438, 443, 470, 465, -1, 443, 448, 475, 470, -1, 448, 458, 485, 475, -1, 458, 457, 484, 485, -1, 457, 432, 459, 484, 459, 484, 485, - 475, 470, 465, 460, -1, 486, 487, 492, 497, 502, 512, 511, -1, 459, 460, 487, 486, -1, 460, 465, 492, 487, -1, 465, 470, 497, 492, -1, 470, 475, 502, 497, -1, 475, 485, 512, 502, -1, 485, 484, 511, 512, -1, 484, 459, 486, 511, 486, 511, - 512, 502, 497, 492, 487, -1, 513, 514, 519, 524, 529, 539, 538, -1, 486, 487, 514, 513, -1, 487, 492, 519, 514, -1, 492, 497, 524, 519, -1, 497, 502, 529, 524, -1, 502, 512, 539, 529, -1, 512, 511, 538, 539, -1, 511, 486, 513, 538, 513, - 538, 539, 529, 524, 519, 514, -1, 540, 541, 546, 551, 556, 566, 565, -1, 513, 514, 541, 540, -1, 514, 519, 546, 541, -1, 519, 524, 551, 546, -1, 524, 529, 556, 551, -1, 529, 539, 566, 556, -1, 539, 538, 565, 566, -1, 538, 513, 540, 565 -}; - -const double coordsTF[1701]={ - 0, 0, 0, 0.21606, 0, 0, 0.25207000000000002, 0, 0, 0.32408999999999999, 0, 0, 0.39610999999999996, 0, 0, 0.43212, 0, 0, 0.21606, 0.03601, 0, - 0.25207000000000002, 0.03601, 0, 0.32408999999999999, 0.03601, 0, 0.39610999999999996, 0.03601, 0, 0.43212, 0.03601, 0, 0.21606, 0.10803, 0, 0.25207000000000002, - 0.10803, 0, 0.32408999999999999, 0.10803, 0, 0.39610999999999996, 0.10803, 0, 0.43212, 0.10803, 0, 0.21606, 0.18004999999999999, 0, 0.25207000000000002, - 0.18004999999999999, 0, 0.32408999999999999, 0.18004999999999999, 0, 0.39610999999999996, 0.18004999999999999, 0, 0.43212, 0.18004999999999999, 0, - 0.25207000000000002, 0.21605999999999997, 0, 0.32408999999999999, 0.21605999999999997, 0, 0.39610999999999996, 0.21605999999999997, 0, 0.43212, - 0.21605999999999997, 0, 0, 0.21606, 0, 0.21606, 0.21606, 0, 0, 0, 0.21364999999999998, 0.21606, 0, 0.21364999999999998, 0.25207000000000002, 0, - 0.21364999999999998, 0.32408999999999999, 0, 0.21364999999999998, 0.39610999999999996, 0, 0.21364999999999998, 0.43212, 0, 0.21364999999999998, 0.21606, 0.03601, - 0.21364999999999998, 0.25207000000000002, 0.03601, 0.21364999999999998, 0.32408999999999999, 0.03601, 0.21364999999999998, 0.39610999999999996, 0.03601, - 0.21364999999999998, 0.43212, 0.03601, 0.21364999999999998, 0.21606, 0.10803, 0.21364999999999998, 0.25207000000000002, 0.10803, 0.21364999999999998, - 0.32408999999999999, 0.10803, 0.21364999999999998, 0.39610999999999996, 0.10803, 0.21364999999999998, 0.43212, 0.10803, 0.21364999999999998, 0.21606, - 0.18004999999999999, 0.21364999999999998, 0.25207000000000002, 0.18004999999999999, 0.21364999999999998, 0.32408999999999999, 0.18004999999999999, - 0.21364999999999998, 0.39610999999999996, 0.18004999999999999, 0.21364999999999998, 0.43212, 0.18004999999999999, 0.21364999999999998, 0.25207000000000002, - 0.21605999999999997, 0.21364999999999998, 0.32408999999999999, 0.21605999999999997, 0.21364999999999998, 0.39610999999999996, 0.21605999999999997, - 0.21364999999999998, 0.43212, 0.21605999999999997, 0.21364999999999998, 0, 0.21606, 0.21364999999999998, 0.21606, 0.21606, 0.21364999999999998, 0, 0, - 0.42729999999999996, 0.21606, 0, 0.42729999999999996, 0.25207000000000002, 0, 0.42729999999999996, 0.32408999999999999, 0, 0.42729999999999996, - 0.39610999999999996, 0, 0.42729999999999996, 0.43212, 0, 0.42729999999999996, 0.21606, 0.03601, 0.42729999999999996, 0.25207000000000002, 0.03601, - 0.42729999999999996, 0.32408999999999999, 0.03601, 0.42729999999999996, 0.39610999999999996, 0.03601, 0.42729999999999996, 0.43212, 0.03601, 0.42729999999999996, - 0.21606, 0.10803, 0.42729999999999996, 0.25207000000000002, 0.10803,0.42729999999999996, 0.32408999999999999, 0.10803, 0.42729999999999996, 0.39610999999999996, 0.10803, 0.42729999999999996, 0.43212, 0.10803, - 0.42729999999999996, 0.21606, 0.18004999999999999, 0.42729999999999996, 0.25207000000000002, 0.18004999999999999, 0.42729999999999996, 0.32408999999999999, - 0.18004999999999999, 0.42729999999999996, 0.39610999999999996, 0.18004999999999999, 0.42729999999999996, 0.43212, 0.18004999999999999, 0.42729999999999996, - 0.25207000000000002, 0.21605999999999997, 0.42729999999999996, 0.32408999999999999, 0.21605999999999997, 0.42729999999999996, 0.39610999999999996, - 0.21605999999999997, 0.42729999999999996, 0.43212, 0.21605999999999997, 0.42729999999999996, 0, 0.21606, 0.42729999999999996, 0.21606, 0.21606, - 0.42729999999999996, 0, 0, 0.64094999999999991, 0.21606, 0, 0.64094999999999991, 0.25207000000000002, 0, 0.64094999999999991, 0.32408999999999999, 0, - 0.64094999999999991, 0.39610999999999996, 0, 0.64094999999999991, 0.43212, 0, 0.64094999999999991, 0.21606, 0.03601, 0.64094999999999991, 0.25207000000000002, - 0.03601, 0.64094999999999991, 0.32408999999999999, 0.03601, 0.64094999999999991, 0.39610999999999996, 0.03601, 0.64094999999999991, 0.43212, 0.03601, - 0.64094999999999991, 0.21606, 0.10803, 0.64094999999999991, 0.25207000000000002, 0.10803, 0.64094999999999991, 0.32408999999999999, 0.10803, 0.64094999999999991, - 0.39610999999999996, 0.10803, 0.64094999999999991, 0.43212, 0.10803, 0.64094999999999991, 0.21606, 0.18004999999999999, 0.64094999999999991, 0.25207000000000002, - 0.18004999999999999, 0.64094999999999991, 0.32408999999999999, 0.18004999999999999, 0.64094999999999991, 0.39610999999999996, 0.18004999999999999, - 0.64094999999999991, 0.43212, 0.18004999999999999, 0.64094999999999991, 0.25207000000000002, 0.21605999999999997, 0.64094999999999991, 0.32408999999999999, - 0.21605999999999997, 0.64094999999999991, 0.39610999999999996, 0.21605999999999997, 0.64094999999999991, 0.43212, 0.21605999999999997, 0.64094999999999991, 0, - 0.21606, 0.64094999999999991, 0.21606, 0.21606, 0.64094999999999991, 0, 0, 0.85459999999999992, 0.21606, 0, 0.85459999999999992, 0.25207000000000002, 0, - 0.85459999999999992, 0.32408999999999999, 0, 0.85459999999999992, 0.39610999999999996, 0, 0.85459999999999992, 0.43212, 0, 0.85459999999999992, 0.21606, 0.03601, - 0.85459999999999992, 0.25207000000000002, 0.03601, 0.85459999999999992, 0.32408999999999999, 0.03601, 0.85459999999999992, 0.39610999999999996, 0.03601, - 0.85459999999999992, 0.43212, 0.03601, 0.85459999999999992, 0.21606, 0.10803, 0.85459999999999992, 0.25207000000000002, 0.10803, 0.85459999999999992, - 0.32408999999999999, 0.10803, 0.85459999999999992, 0.39610999999999996, 0.10803, 0.85459999999999992, 0.43212, 0.10803, 0.85459999999999992, 0.21606, - 0.18004999999999999, 0.85459999999999992, 0.25207000000000002, 0.18004999999999999, 0.85459999999999992, 0.32408999999999999, 0.18004999999999999, - 0.85459999999999992, 0.39610999999999996, 0.18004999999999999, 0.85459999999999992, 0.43212, 0.18004999999999999, 0.85459999999999992, 0.25207000000000002, - 0.21605999999999997, 0.85459999999999992, 0.32408999999999999, 0.21605999999999997, 0.85459999999999992, 0.39610999999999996, 0.21605999999999997, - 0.85459999999999992, 0.43212, 0.21605999999999997, 0.85459999999999992, 0,0.21606, 0.85459999999999992, 0.21606, 0.21606, 0.85459999999999992, 0, 0, 1.0682499999999999, 0.21606, 0, 1.0682499999999999, 0.25207000000000002, 0, - 1.0682499999999999, 0.32408999999999999, 0, 1.0682499999999999, 0.39610999999999996, 0, 1.0682499999999999, 0.43212, 0, 1.0682499999999999, 0.21606, 0.03601, - 1.0682499999999999, 0.25207000000000002, 0.03601, 1.0682499999999999, 0.32408999999999999, 0.03601, 1.0682499999999999, 0.39610999999999996, 0.03601, - 1.0682499999999999, 0.43212, 0.03601, 1.0682499999999999, 0.21606, 0.10803, 1.0682499999999999, 0.25207000000000002, 0.10803, 1.0682499999999999, - 0.32408999999999999, 0.10803, 1.0682499999999999, 0.39610999999999996, 0.10803, 1.0682499999999999, 0.43212, 0.10803, 1.0682499999999999, 0.21606, - 0.18004999999999999, 1.0682499999999999, 0.25207000000000002, 0.18004999999999999, 1.0682499999999999, 0.32408999999999999, 0.18004999999999999, - 1.0682499999999999, 0.39610999999999996, 0.18004999999999999, 1.0682499999999999, 0.43212, 0.18004999999999999, 1.0682499999999999, 0.25207000000000002, - 0.21605999999999997, 1.0682499999999999, 0.32408999999999999, 0.21605999999999997, 1.0682499999999999, 0.39610999999999996, 0.21605999999999997, - 1.0682499999999999, 0.43212, 0.21605999999999997, 1.0682499999999999, 0, 0.21606, 1.0682499999999999, 0.21606, 0.21606, 1.0682499999999999, 0, 0, - 1.2818999999999998, 0.21606, 0, 1.2818999999999998, 0.25207000000000002, 0, 1.2818999999999998, 0.32408999999999999, 0, 1.2818999999999998, 0.39610999999999996, - 0, 1.2818999999999998, 0.43212, 0, 1.2818999999999998, 0.21606, 0.03601, 1.2818999999999998, 0.25207000000000002, 0.03601, 1.2818999999999998, - 0.32408999999999999, 0.03601, 1.2818999999999998, 0.39610999999999996, 0.03601, 1.2818999999999998, 0.43212, 0.03601, 1.2818999999999998, 0.21606, 0.10803, - 1.2818999999999998, 0.25207000000000002, 0.10803, 1.2818999999999998, 0.32408999999999999, 0.10803, 1.2818999999999998, 0.39610999999999996, 0.10803, - 1.2818999999999998, 0.43212, 0.10803, 1.2818999999999998, 0.21606, 0.18004999999999999, 1.2818999999999998, 0.25207000000000002, 0.18004999999999999, - 1.2818999999999998, 0.32408999999999999, 0.18004999999999999, 1.2818999999999998, 0.39610999999999996, 0.18004999999999999, 1.2818999999999998, 0.43212, - 0.18004999999999999, 1.2818999999999998, 0.25207000000000002, 0.21605999999999997, 1.2818999999999998, 0.32408999999999999, 0.21605999999999997, - 1.2818999999999998, 0.39610999999999996, 0.21605999999999997, 1.2818999999999998, 0.43212, 0.21605999999999997, 1.2818999999999998, 0, 0.21606, - 1.2818999999999998, 0.21606, 0.21606, 1.2818999999999998, 0, 0, 1.4955499999999999, 0.21606, 0, 1.4955499999999999, 0.25207000000000002, 0, 1.4955499999999999, - 0.32408999999999999, 0, 1.4955499999999999, 0.39610999999999996, 0, 1.4955499999999999, 0.43212, 0, 1.4955499999999999, 0.21606, 0.03601, 1.4955499999999999, - 0.25207000000000002, 0.03601, 1.4955499999999999, 0.32408999999999999, 0.03601, 1.4955499999999999, 0.39610999999999996, 0.03601, 1.4955499999999999, 0.43212, - 0.03601, 1.4955499999999999,0.21606, 0.10803, 1.4955499999999999, 0.25207000000000002, 0.10803, 1.4955499999999999, 0.32408999999999999, 0.10803, 1.4955499999999999, - 0.39610999999999996, 0.10803, 1.4955499999999999, 0.43212, 0.10803, 1.4955499999999999, 0.21606, 0.18004999999999999, 1.4955499999999999, 0.25207000000000002, - 0.18004999999999999, 1.4955499999999999, 0.32408999999999999, 0.18004999999999999, 1.4955499999999999, 0.39610999999999996, 0.18004999999999999, - 1.4955499999999999, 0.43212, 0.18004999999999999, 1.4955499999999999, 0.25207000000000002, 0.21605999999999997, 1.4955499999999999, 0.32408999999999999, - 0.21605999999999997, 1.4955499999999999, 0.39610999999999996, 0.21605999999999997, 1.4955499999999999, 0.43212, 0.21605999999999997, 1.4955499999999999, 0, - 0.21606, 1.4955499999999999, 0.21606, 0.21606, 1.4955499999999999, 0, 0, 1.7091999999999998, 0.21606, 0, 1.7091999999999998, 0.25207000000000002, 0, - 1.7091999999999998, 0.32408999999999999, 0, 1.7091999999999998, 0.39610999999999996, 0, 1.7091999999999998, 0.43212, 0, 1.7091999999999998, 0.21606, 0.03601, - 1.7091999999999998, 0.25207000000000002, 0.03601, 1.7091999999999998, 0.32408999999999999, 0.03601, 1.7091999999999998, 0.39610999999999996, 0.03601, - 1.7091999999999998, 0.43212, 0.03601, 1.7091999999999998, 0.21606, 0.10803, 1.7091999999999998, 0.25207000000000002, 0.10803, 1.7091999999999998, - 0.32408999999999999, 0.10803, 1.7091999999999998, 0.39610999999999996, 0.10803, 1.7091999999999998, 0.43212, 0.10803, 1.7091999999999998, 0.21606, - 0.18004999999999999, 1.7091999999999998, 0.25207000000000002, 0.18004999999999999, 1.7091999999999998, 0.32408999999999999, 0.18004999999999999, - 1.7091999999999998, 0.39610999999999996, 0.18004999999999999, 1.7091999999999998, 0.43212, 0.18004999999999999, 1.7091999999999998, 0.25207000000000002, - 0.21605999999999997, 1.7091999999999998, 0.32408999999999999, 0.21605999999999997, 1.7091999999999998, 0.39610999999999996, 0.21605999999999997, - 1.7091999999999998, 0.43212, 0.21605999999999997, 1.7091999999999998, 0, 0.21606, 1.7091999999999998, 0.21606, 0.21606, 1.7091999999999998, 0, 0, - 1.9228499999999997, 0.21606, 0, 1.9228499999999997, 0.25207000000000002, 0, 1.9228499999999997, 0.32408999999999999, 0, 1.9228499999999997, 0.39610999999999996, - 0, 1.9228499999999997, 0.43212, 0, 1.9228499999999997, 0.21606, 0.03601, 1.9228499999999997, 0.25207000000000002, 0.03601, 1.9228499999999997, - 0.32408999999999999, 0.03601, 1.9228499999999997, 0.39610999999999996, 0.03601, 1.9228499999999997, 0.43212, 0.03601, 1.9228499999999997, 0.21606, 0.10803, - 1.9228499999999997, 0.25207000000000002, 0.10803, 1.9228499999999997, 0.32408999999999999, 0.10803, 1.9228499999999997, 0.39610999999999996, 0.10803, - 1.9228499999999997, 0.43212, 0.10803, 1.9228499999999997, 0.21606, 0.18004999999999999, 1.9228499999999997, 0.25207000000000002, 0.18004999999999999, - 1.9228499999999997, 0.32408999999999999, 0.18004999999999999, 1.9228499999999997, 0.39610999999999996, 0.18004999999999999, 1.9228499999999997, 0.43212, - 0.18004999999999999, 1.9228499999999997, 0.25207000000000002, 0.21605999999999997, 1.9228499999999997, 0.32408999999999999, 0.21605999999999997, - 1.9228499999999997, 0.39610999999999996, 0.21605999999999997,1.9228499999999997, 0.43212, 0.21605999999999997, 1.9228499999999997, 0, 0.21606, 1.9228499999999997, 0.21606, 0.21606, 1.9228499999999997, 0, 0, - 2.1364999999999998, 0.21606, 0, 2.1364999999999998, 0.25207000000000002, 0, 2.1364999999999998, 0.32408999999999999, 0, 2.1364999999999998, 0.39610999999999996, - 0, 2.1364999999999998, 0.43212, 0, 2.1364999999999998, 0.21606, 0.03601, 2.1364999999999998, 0.25207000000000002, 0.03601, 2.1364999999999998, - 0.32408999999999999, 0.03601, 2.1364999999999998, 0.39610999999999996, 0.03601, 2.1364999999999998, 0.43212, 0.03601, 2.1364999999999998, 0.21606, 0.10803, - 2.1364999999999998, 0.25207000000000002, 0.10803, 2.1364999999999998, 0.32408999999999999, 0.10803, 2.1364999999999998, 0.39610999999999996, 0.10803, - 2.1364999999999998, 0.43212, 0.10803, 2.1364999999999998, 0.21606, 0.18004999999999999, 2.1364999999999998, 0.25207000000000002, 0.18004999999999999, - 2.1364999999999998, 0.32408999999999999, 0.18004999999999999, 2.1364999999999998, 0.39610999999999996, 0.18004999999999999, 2.1364999999999998, 0.43212, - 0.18004999999999999, 2.1364999999999998, 0.25207000000000002, 0.21605999999999997, 2.1364999999999998, 0.32408999999999999, 0.21605999999999997, - 2.1364999999999998, 0.39610999999999996, 0.21605999999999997, 2.1364999999999998, 0.43212, 0.21605999999999997, 2.1364999999999998, 0, 0.21606, - 2.1364999999999998, 0.21606, 0.21606, 2.1364999999999998, 0, 0, 2.3501499999999997, 0.21606, 0, 2.3501499999999997, 0.25207000000000002, 0, 2.3501499999999997, - 0.32408999999999999, 0, 2.3501499999999997, 0.39610999999999996, 0, 2.3501499999999997, 0.43212, 0, 2.3501499999999997, 0.21606, 0.03601, 2.3501499999999997, - 0.25207000000000002, 0.03601, 2.3501499999999997, 0.32408999999999999, 0.03601, 2.3501499999999997, 0.39610999999999996, 0.03601, 2.3501499999999997, 0.43212, - 0.03601, 2.3501499999999997, 0.21606, 0.10803, 2.3501499999999997, 0.25207000000000002, 0.10803, 2.3501499999999997, 0.32408999999999999, 0.10803, - 2.3501499999999997, 0.39610999999999996, 0.10803, 2.3501499999999997, 0.43212, 0.10803, 2.3501499999999997, 0.21606, 0.18004999999999999, 2.3501499999999997, - 0.25207000000000002, 0.18004999999999999, 2.3501499999999997, 0.32408999999999999, 0.18004999999999999, 2.3501499999999997, 0.39610999999999996, - 0.18004999999999999, 2.3501499999999997, 0.43212, 0.18004999999999999, 2.3501499999999997, 0.25207000000000002, 0.21605999999999997, 2.3501499999999997, - 0.32408999999999999, 0.21605999999999997, 2.3501499999999997, 0.39610999999999996, 0.21605999999999997, 2.3501499999999997, 0.43212, 0.21605999999999997, - 2.3501499999999997, 0, 0.21606, 2.3501499999999997, 0.21606, 0.21606, 2.3501499999999997, 0, 0, 2.5637999999999996, 0.21606, 0, 2.5637999999999996, - 0.25207000000000002, 0, 2.5637999999999996, 0.32408999999999999, 0, 2.5637999999999996, 0.39610999999999996, 0, 2.5637999999999996, 0.43212, 0, - 2.5637999999999996, 0.21606, 0.03601, 2.5637999999999996, 0.25207000000000002, 0.03601, 2.5637999999999996, 0.32408999999999999, 0.03601, 2.5637999999999996, - 0.39610999999999996,0.03601, 2.5637999999999996, 0.43212, 0.03601, 2.5637999999999996, 0.21606, 0.10803, 2.5637999999999996, 0.25207000000000002, 0.10803, 2.5637999999999996, - 0.32408999999999999, 0.10803, 2.5637999999999996, 0.39610999999999996, 0.10803, 2.5637999999999996, 0.43212, 0.10803, 2.5637999999999996, 0.21606, - 0.18004999999999999, 2.5637999999999996, 0.25207000000000002, 0.18004999999999999, 2.5637999999999996, 0.32408999999999999, 0.18004999999999999, - 2.5637999999999996, 0.39610999999999996, 0.18004999999999999, 2.5637999999999996, 0.43212, 0.18004999999999999, 2.5637999999999996, 0.25207000000000002, - 0.21605999999999997, 2.5637999999999996, 0.32408999999999999, 0.21605999999999997, 2.5637999999999996, 0.39610999999999996, 0.21605999999999997, - 2.5637999999999996, 0.43212, 0.21605999999999997, 2.5637999999999996, 0, 0.21606, 2.5637999999999996, 0.21606, 0.21606, 2.5637999999999996, 0, 0, - 2.7774499999999995, 0.21606, 0, 2.7774499999999995, 0.25207000000000002, 0, 2.7774499999999995, 0.32408999999999999, 0, 2.7774499999999995, 0.39610999999999996, - 0, 2.7774499999999995, 0.43212, 0, 2.7774499999999995, 0.21606, 0.03601, 2.7774499999999995, 0.25207000000000002, 0.03601, 2.7774499999999995, - 0.32408999999999999, 0.03601, 2.7774499999999995, 0.39610999999999996, 0.03601, 2.7774499999999995, 0.43212, 0.03601, 2.7774499999999995, 0.21606, 0.10803, - 2.7774499999999995, 0.25207000000000002, 0.10803, 2.7774499999999995, 0.32408999999999999, 0.10803, 2.7774499999999995, 0.39610999999999996, 0.10803, - 2.7774499999999995, 0.43212, 0.10803, 2.7774499999999995, 0.21606, 0.18004999999999999, 2.7774499999999995, 0.25207000000000002, 0.18004999999999999, - 2.7774499999999995, 0.32408999999999999, 0.18004999999999999, 2.7774499999999995, 0.39610999999999996, 0.18004999999999999, 2.7774499999999995, 0.43212, - 0.18004999999999999, 2.7774499999999995, 0.25207000000000002, 0.21605999999999997, 2.7774499999999995, 0.32408999999999999, 0.21605999999999997, - 2.7774499999999995, 0.39610999999999996, 0.21605999999999997, 2.7774499999999995, 0.43212, 0.21605999999999997, 2.7774499999999995, 0, 0.21606, - 2.7774499999999995, 0.21606, 0.21606, 2.7774499999999995, 0, 0, 2.9910999999999999, 0.21606, 0, 2.9910999999999999, 0.25207000000000002, 0, 2.9910999999999999, - 0.32408999999999999, 0, 2.9910999999999999, 0.39610999999999996, 0, 2.9910999999999999, 0.43212, 0, 2.9910999999999999, 0.21606, 0.03601, 2.9910999999999999, - 0.25207000000000002, 0.03601, 2.9910999999999999, 0.32408999999999999, 0.03601, 2.9910999999999999, 0.39610999999999996, 0.03601, 2.9910999999999999, 0.43212, - 0.03601, 2.9910999999999999, 0.21606, 0.10803, 2.9910999999999999, 0.25207000000000002, 0.10803, 2.9910999999999999, 0.32408999999999999, 0.10803, - 2.9910999999999999, 0.39610999999999996, 0.10803, 2.9910999999999999, 0.43212, 0.10803, 2.9910999999999999, 0.21606, 0.18004999999999999, 2.9910999999999999, - 0.25207000000000002, 0.18004999999999999, 2.9910999999999999, 0.32408999999999999, 0.18004999999999999, 2.9910999999999999, 0.39610999999999996, - 0.18004999999999999, 2.9910999999999999, 0.43212, 0.18004999999999999, 2.9910999999999999, 0.25207000000000002, 0.21605999999999997, 2.9910999999999999, - 0.32408999999999999, 0.21605999999999997, 2.9910999999999999, 0.39610999999999996, 0.21605999999999997, 2.9910999999999999, 0.43212, 0.21605999999999997, - 2.9910999999999999, 0, 0.21606, 2.9910999999999999, 0.21606, 0.21606, 2.9910999999999999, 0, 0, 3.2047499999999998, 0.21606, 0, 3.2047499999999998, - 0.25207000000000002, 0, 3.2047499999999998, 0.32408999999999999, 0, 3.2047499999999998, 0.39610999999999996, 0, 3.2047499999999998, 0.43212, 0, - 3.2047499999999998, 0.21606, 0.03601, 3.2047499999999998, 0.25207000000000002, 0.03601, 3.2047499999999998, 0.32408999999999999, 0.03601, 3.2047499999999998, - 0.39610999999999996, 0.03601, 3.2047499999999998, 0.43212, 0.03601, 3.2047499999999998, 0.21606, 0.10803, 3.2047499999999998, 0.25207000000000002, 0.10803, - 3.2047499999999998, 0.32408999999999999, 0.10803, 3.2047499999999998, 0.39610999999999996, 0.10803, 3.2047499999999998, 0.43212, 0.10803, 3.2047499999999998, - 0.21606, 0.18004999999999999, 3.2047499999999998, 0.25207000000000002, 0.18004999999999999, 3.2047499999999998, 0.32408999999999999, 0.18004999999999999, - 3.2047499999999998, 0.39610999999999996, 0.18004999999999999, 3.2047499999999998, 0.43212, 0.18004999999999999, 3.2047499999999998, 0.25207000000000002, - 0.21605999999999997, 3.2047499999999998, 0.32408999999999999, 0.21605999999999997, 3.2047499999999998, 0.39610999999999996, 0.21605999999999997, - 3.2047499999999998, 0.43212, 0.21605999999999997, 3.2047499999999998, 0, 0.21606, 3.2047499999999998, 0.21606, 0.21606, 3.2047499999999998, 0, 0, - 3.4183999999999997, 0.21606, 0, 3.4183999999999997, 0.25207000000000002, 0, 3.4183999999999997, 0.32408999999999999, 0, 3.4183999999999997, 0.39610999999999996, - 0, 3.4183999999999997, 0.43212, 0, 3.4183999999999997, 0.21606, 0.03601, 3.4183999999999997, 0.25207000000000002, 0.03601, 3.4183999999999997, - 0.32408999999999999, 0.03601, 3.4183999999999997, 0.39610999999999996, 0.03601, 3.4183999999999997, 0.43212, 0.03601, 3.4183999999999997, 0.21606, 0.10803, - 3.4183999999999997, 0.25207000000000002, 0.10803, 3.4183999999999997, 0.32408999999999999, 0.10803, 3.4183999999999997, 0.39610999999999996, 0.10803, - 3.4183999999999997, 0.43212, 0.10803, 3.4183999999999997, 0.21606, 0.18004999999999999, 3.4183999999999997, 0.25207000000000002, 0.18004999999999999, - 3.4183999999999997, 0.32408999999999999, 0.18004999999999999, 3.4183999999999997, 0.39610999999999996, 0.18004999999999999, 3.4183999999999997, 0.43212, - 0.18004999999999999, 3.4183999999999997, 0.25207000000000002, 0.21605999999999997, 3.4183999999999997, 0.32408999999999999, 0.21605999999999997, - 3.4183999999999997, 0.39610999999999996, 0.21605999999999997, 3.4183999999999997, 0.43212, 0.21605999999999997, 3.4183999999999997, 0, 0.21606, - 3.4183999999999997, 0.21606, 0.21606, 3.4183999999999997, 0, 0, 3.6320499999999996, 0.21606, 0, 3.6320499999999996, 0.25207000000000002, 0, 3.6320499999999996, - 0.32408999999999999, 0, 3.6320499999999996, 0.39610999999999996, 0, 3.6320499999999996, 0.43212, 0, 3.6320499999999996, 0.21606, 0.03601, 3.6320499999999996, - 0.25207000000000002, 0.03601, 3.6320499999999996, 0.32408999999999999, 0.03601, 3.6320499999999996, 0.39610999999999996, 0.03601, 3.6320499999999996, 0.43212, 0.03601, - 3.6320499999999996, 0.21606, 0.10803, 3.6320499999999996, 0.25207000000000002, 0.10803, 3.6320499999999996, 0.32408999999999999, 0.10803, 3.6320499999999996, - 0.39610999999999996, 0.10803, 3.6320499999999996, 0.43212, 0.10803, 3.6320499999999996, 0.21606, 0.18004999999999999, 3.6320499999999996, 0.25207000000000002, - 0.18004999999999999, 3.6320499999999996, 0.32408999999999999, 0.18004999999999999, 3.6320499999999996, 0.39610999999999996, 0.18004999999999999, - 3.6320499999999996, 0.43212, 0.18004999999999999, 3.6320499999999996, 0.25207000000000002, 0.21605999999999997, 3.6320499999999996, 0.32408999999999999, - 0.21605999999999997, 3.6320499999999996, 0.39610999999999996, 0.21605999999999997, 3.6320499999999996, 0.43212, 0.21605999999999997, 3.6320499999999996, 0, - 0.21606, 3.6320499999999996, 0.21606, 0.21606, 3.6320499999999996, 0, 0, 3.8456999999999995, 0.21606, 0, 3.8456999999999995, 0.25207000000000002, 0, - 3.8456999999999995, 0.32408999999999999, 0, 3.8456999999999995, 0.39610999999999996, 0, 3.8456999999999995, 0.43212, 0, 3.8456999999999995, 0.21606, 0.03601, - 3.8456999999999995, 0.25207000000000002, 0.03601, 3.8456999999999995, 0.32408999999999999, 0.03601, 3.8456999999999995, 0.39610999999999996, 0.03601, - 3.8456999999999995, 0.43212, 0.03601, 3.8456999999999995, 0.21606, 0.10803, 3.8456999999999995, 0.25207000000000002, 0.10803, 3.8456999999999995, - 0.32408999999999999, 0.10803, 3.8456999999999995, 0.39610999999999996, 0.10803, 3.8456999999999995, 0.43212, 0.10803, 3.8456999999999995, 0.21606, - 0.18004999999999999, 3.8456999999999995, 0.25207000000000002, 0.18004999999999999, 3.8456999999999995, 0.32408999999999999, 0.18004999999999999, - 3.8456999999999995, 0.39610999999999996, 0.18004999999999999, 3.8456999999999995, 0.43212, 0.18004999999999999, 3.8456999999999995, 0.25207000000000002, - 0.21605999999999997, 3.8456999999999995, 0.32408999999999999, 0.21605999999999997, 3.8456999999999995, 0.39610999999999996, 0.21605999999999997, - 3.8456999999999995, 0.43212, 0.21605999999999997, 3.8456999999999995, 0, 0.21606, 3.8456999999999995, 0.21606, 0.21606, 3.8456999999999995, 0, 0, - 4.0593499999999993, 0.21606, 0, 4.0593499999999993, 0.25207000000000002, 0, 4.0593499999999993, 0.32408999999999999, 0, 4.0593499999999993, 0.39610999999999996, - 0, 4.0593499999999993, 0.43212, 0, 4.0593499999999993, 0.21606, 0.03601, 4.0593499999999993, 0.25207000000000002, 0.03601, 4.0593499999999993, - 0.32408999999999999, 0.03601, 4.0593499999999993, 0.39610999999999996, 0.03601, 4.0593499999999993, 0.43212, 0.03601, 4.0593499999999993, 0.21606, 0.10803, - 4.0593499999999993, 0.25207000000000002, 0.10803, 4.0593499999999993, 0.32408999999999999, 0.10803, 4.0593499999999993, 0.39610999999999996, 0.10803, - 4.0593499999999993, 0.43212, 0.10803, 4.0593499999999993, 0.21606, 0.18004999999999999, 4.0593499999999993, 0.25207000000000002, 0.18004999999999999, - 4.0593499999999993, 0.32408999999999999, 0.18004999999999999, 4.0593499999999993, 0.39610999999999996, 0.18004999999999999, 4.0593499999999993, 0.43212, - 0.18004999999999999, 4.0593499999999993, 0.25207000000000002, 0.21605999999999997, 4.0593499999999993, 0.32408999999999999, 0.21605999999999997, - 4.0593499999999993, 0.39610999999999996, 0.21605999999999997, 4.0593499999999993, 0.43212, 0.21605999999999997, 4.0593499999999993, 0, 0.21606, - 4.0593499999999993, 0.21606, 0.21606, 4.0593499999999993, 0, 0, 4.2729999999999997, 0.21606, 0, 4.2729999999999997, 0.25207000000000002, 0, 4.2729999999999997, - 0.32408999999999999, 0, 4.2729999999999997, 0.39610999999999996, 0, 4.2729999999999997, 0.43212, 0, 4.2729999999999997, 0.21606, 0.03601, 4.2729999999999997, - 0.25207000000000002, 0.03601, 4.2729999999999997, 0.32408999999999999, 0.03601, 4.2729999999999997, 0.39610999999999996, 0.03601, 4.2729999999999997, 0.43212, - 0.03601, 4.2729999999999997, 0.21606, 0.10803, 4.2729999999999997, 0.25207000000000002, 0.10803, 4.2729999999999997, 0.32408999999999999, 0.10803, - 4.2729999999999997, 0.39610999999999996, 0.10803, 4.2729999999999997, 0.43212, 0.10803, 4.2729999999999997, 0.21606, 0.18004999999999999, 4.2729999999999997, - 0.25207000000000002, 0.18004999999999999, 4.2729999999999997, 0.32408999999999999, 0.18004999999999999, 4.2729999999999997, 0.39610999999999996, - 0.18004999999999999, 4.2729999999999997, 0.43212, 0.18004999999999999, 4.2729999999999997, 0.25207000000000002, 0.21605999999999997, 4.2729999999999997, - 0.32408999999999999, 0.21605999999999997, 4.2729999999999997, 0.39610999999999996, 0.21605999999999997, 4.2729999999999997, 0.43212, 0.21605999999999997, - 4.2729999999999997, 0, 0.21606, 4.2729999999999997, 0.21606, 0.21606, 4.2729999999999997 -}; - -const int connTFPOLH_I[21]={0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000}; diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx deleted file mode 100644 index f50b74de9..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx +++ /dev/null @@ -1,2694 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTestInterp.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3DSurf.hxx" -#include "Interpolation3D.txx" -#include "Interpolation2D1D.txx" -#include "Interpolation3D2D.txx" -#include "InterpolationCC.txx" -#include "InterpolationCU.txx" -#include "Interpolation2DCurve.hxx" -#include "Interpolation1D.txx" - -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingNormalizedCartesianMesh.txx" - -#include -#include - -using namespace ParaMEDMEM; - -typedef std::vector > IntersectionMatrix; - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Convex, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<3;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_2() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_3() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_4() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - cellsIds.resize(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P1_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P1PL_2() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - cellsIds.resize(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0PL_2() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vectorcellsIds(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P1_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334,res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665,res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666,res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334,res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665,res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668,res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666,res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999,res[4][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999,res[4][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999,res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666,res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333,res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333,res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667,res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331,res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668,res[8][3],1.e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[8][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2.),res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2.),res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2.),res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667*sqrt(2.),res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668*sqrt(2.),res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666*sqrt(2.),res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999*sqrt(2.),res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333*sqrt(2.),res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333*sqrt(2.),res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667*sqrt(2.),res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331*sqrt(2.),res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668*sqrt(2.),res[8][3],1.e-12); - res.clear(); - } - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[8][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_2() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMeshPerm_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation); - { - myInterpolator.setOrientation(2); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - { - myInterpolator.setOrientation(0); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - { - myInterpolator.setOrientation(1); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.875*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - { - myInterpolator.setOrientation(-1); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -/*! - * Test of precision option implemented by Fabien that represents distance of "barycenter" to the other cell. - */ -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_3() -{ - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - double vecTrans[3]={0.,0.,1.e-10}; - double vec[3]={0.,-1.,0.}; - double pt[3]={-0.3,-0.3,5.e-11}; - const int N=32; - const double deltaA=M_PI/N; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation); - myInterpolator.setMaxDistance3DSurfIntersect(1e-9); - for(int i=0;irotate(pt,vec,i*deltaA); - MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - targetMesh->rotate(pt,vec,i*deltaA); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - } - // - myInterpolator.setMaxDistance3DSurfIntersect(1e-11); - for(int i=0;irotate(pt,vec,i*deltaA); - MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - targetMesh->rotate(pt,vec,i*deltaA); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - } - // - res.clear(); - myInterpolator.setMaxDistance3DSurfIntersect(-1.);//unactivate fabien lookup - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - myInterpolator.setBoundingBoxAdjustment(1e-11); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper0(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper0(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper0,targetWrapper0,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // - res.clear(); - sourceMesh=build3DSurfSourceMesh_2(); - targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - myInterpolator.setBoundingBoxAdjustment(1e-9); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper1(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper1(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper1,targetWrapper1,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //keeping the same bbox adj == 1.e-11 but trying rotation - res.clear(); - sourceMesh=build3DSurfSourceMesh_2(); - sourceMesh->rotate(pt,vec,M_PI/4.); - targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - targetMesh->rotate(pt,vec,M_PI/4.); - myInterpolator.setBoundingBoxAdjustment(1e-11); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper2(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper2(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper2,targetWrapper2,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.e6,sumAll(res),1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(41666.66666666667,res[0][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(41666.66666666667,res[1][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[1][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[1][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[2][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[2][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][11],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[3][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[3][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333331,res[3][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[3][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[3][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[4][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[4][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[5][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333331,res[5][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[5][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[5][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[5][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[6][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(250000,res[6][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(541666.6666666667,res[6][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[6][11],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(333333.3333333333,res[7][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(624999.9999999997,res[7][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][11],1e-7); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_2() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - std::vector cellsIds(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_3() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_4() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - cellsIds.resize(targetMesh->getNumberOfCells()); - for(int j=0;jgetNumberOfCells();j++) - cellsIds[j]=j; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[0][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[0][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[0][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[0][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[1][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(140277.7777777778,res[1][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[1][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[1][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[1][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[1][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888889,res[1][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(348611.1111111111,res[2][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888888,res[2][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444444,res[3][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333334,res[3][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[3][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[3][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.111111111,res[4][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[4][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(223611.1111111111,res[5][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888892,res[5][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[6][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[7][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[7][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.1111111111,res[8][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[8][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[8][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[8][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[8][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[8][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1466666.666666668,res[8][7],1e-7); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[0][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(140277.7777777778,res[1][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(223611.1111111111,res[1][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.1111111111,res[1][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[2][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[2][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[2][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[3][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[3][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[3][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[3][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[3][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[4][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444445,res[4][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[4][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[5][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[5][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[5][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[5][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[6][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888889,res[6][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(348611.1111111112,res[6][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666667,res[6][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[6][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[7][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888892,res[7][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[7][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222222,res[7][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1466666.666666668,res[7][8],1e-7); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.75,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[5][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[5][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,res[7][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.75,res[7][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - double res3D[8][28]= {{124999.999883775978, 245370.370390364464, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 203703.703634892299, 187500.000094145857, 0.0, 0.0, 4629.6296266718, 0.0, 215277.777751402784, 209722.222322299582, 0.0, 0.0, 0.0, 0.0, 104166.666590829205, 121296.296368812196, 0.0, 250000.000003472145}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 120370.370368827047, 0.0, 0.0, 38888.888897777797, 0.0, 0.0, 45370.3703701697596, 0.0, 0.0, 45370.3703701697596, 83333.3333263888926, 0.0}, - {0.0, 0.0, 0.0, 97222.2222222221753, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 97222.2222222221608, 0.0, 97222.2222222222044, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 277777.777787084982, 199074.074074073927, 0.0, 0.0, 0.0, 4629.62962962962774, 0.0, 321759.259254934732, 83333.3333333333139, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4629.62962667180363, 0.0, 0.0, 251388.88888319055, 194444.444454861077, 0.0, 79629.6296194135939, 250000.000003472145, 0.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 0.0, 85185.1851851851534, 4629.62962962962774, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 118518.518518518511, 0.0, 41666.6666666666642, 83333.3333333333285, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 324074.07407629228, 0.0, 0.0, 0.0, 247685.185185184964, 6481.48148148147993, 0.0, 173611.11111196311, 0.0, 164814.814814814832, 0.0, 4629.62962962962865, 208333.33333418527, 0.0, 83333.3333333333285, 203703.703697273799, 249999.999999999767, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {125000.000000000015, 423611.111111110775, 134259.259259259241, 194444.444444444351, 164814.814814814745, 164351.851851851825, 203703.703703703592, 249999.999999999825, 0.0, 0.0, 0.0, 0.0, 6481.48148148147902, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 118518.518518518453, 0.0, 4629.62962962962956, 83333.3333333333139, 85185.1851851851825, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; - int i=0; - double sum = 0; - //cout.precision(18); - for(std::vector >::const_iterator iter1=res.begin();iter1!=res.end();iter1++,i++) - { - //cout<< "res3D[" <::const_iterator iter2=(*iter1).find(j); - if(iter2!=(*iter1).end()) - { - //cout<< iter2->second<< ", "; - sum += iter2->second; - CPPUNIT_ASSERT_DOUBLES_EQUAL(res3D[i][j],(*iter2).second,1.e-5); - } - else - { - //cout << "0.0, "; - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res3D[i][j],1e-14); - } - } - //cout << "}" << endl; - } - //cout << "Sum = " << sum << endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000,sum,1.e-5); - //clean-up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20.,res[0][24],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[1][26],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][21],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[3][23],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][14],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[5][17],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[6][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(97.,sumAll(res),1e-12); - //clean-up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0Empty() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(0); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(0,0); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(0); - targetMesh->finishInsertingCells(); - myCoords=DataArrayDouble::New(); - myCoords->alloc(0,2); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCC() -{ - double arr1[3] = { 0/2., 1/2., 2/2. }; - double arr2[4] = { 0/3, 1/3., 2/3., 3/3. }; - MEDCouplingCMesh* mesh[2]; - for ( int i = 0; i < 2; ++i ) - { - const double* arr = i ? arr1 : arr2; - const int nb_coord = i ? 3 : 4; - DataArrayDouble* coords = DataArrayDouble::New(); - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, nb_coord, 1 ); - - mesh[i] = MEDCouplingCMesh::New(); - mesh[i]->setCoords( coords, coords, coords ); - coords->decrRef(); - } - MEDCouplingNormalizedCartesianMesh<3> targetWrapper(mesh[1]); - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(mesh[0]); - CPPUNIT_ASSERT_EQUAL( 27,int( sourceWrapper.getNumberOfElements())); - CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(0))); - CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(1))); - CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(2))); - CPPUNIT_ASSERT_THROW( sourceWrapper.nbCellsAlongAxis(3), INTERP_KERNEL::Exception); - - INTERP_KERNEL::InterpolationCC myInterpolator; - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - CPPUNIT_ASSERT_EQUAL(8,int( res.size())); - CPPUNIT_ASSERT_EQUAL(8,int( res[0].size())); - const double precis = 1e-7; - std::set vals; - double sum = 0; - for ( int i = 0; i < (int)res.size(); ++i ) - for ( std::map::iterator s_v = res[i].begin(); s_v != res[i].end(); ++s_v) - { - sum += s_v->second; - double vvv; -#ifdef WIN32 - double vv = s_v->second / precis; - if(vv>=0.0) - { - vvv = floor(vv+0.5); - } - else - { - vvv = ceil(vv-0.5); - } -#else - vvv = round( s_v->second / precis ); -#endif - vals.insert( precis * vvv ); - } - //cout << "tgt: " << i << " src: " << s_v->first << " - w: " << s_v->second << endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, sum, precis ); - - std::set::iterator v = vals.begin(); - CPPUNIT_ASSERT_EQUAL( 4, int( vals.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00462963, *v++, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00925926, *v++, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.01851850, *v++, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703700, *v++, precis ); - - mesh[0]->decrRef(); - mesh[1]->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCU1D() -{ - MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); - DataArrayDouble* coords = DataArrayDouble::New(); - double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); - meshC->setCoords( coords ); - coords->decrRef(); - - MEDCouplingUMesh * meshU = buildCU1DMesh_U(); - - MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(meshC); - MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(meshU); - INTERP_KERNEL::InterpolationCU myInterpolator; - std::vector > res; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - -// std::cout.precision(18); -// for ( int i = 0; i < (int)res.size(); ++i ) -// for ( std::map::iterator s_v = res[i].begin(); s_v != res[i].end(); ++s_v) -// { -// std::cout << "CPPUNIT_ASSERT_DOUBLES_EQUAL( "<second<<" ,res["<first<<"],precis);"<decrRef(); - meshU->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCU2D() -{ - MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); - DataArrayDouble* coords = DataArrayDouble::New(); - double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); - meshC->setCoords( coords, coords ); - coords->decrRef(); - - MEDCouplingUMesh * meshU = buildCU2DMesh_U(); - - MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(meshC); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(meshU); - INTERP_KERNEL::InterpolationCU myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - const double precis = 1e-7; - double sum = sumAll(res); - CPPUNIT_ASSERT_EQUAL(5,int( res.size())); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[0][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[0][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[0][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[0][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[1][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[1][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[1][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[1][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[2][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[2][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[2][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[2][8],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0416667 ,res[3][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[3][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[3][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0416667 ,res[3][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[4][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0972222 ,res[4][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[4][5],precis); - - std::vector > resRev; - myInterpolator.interpolateMeshesRev(targetWrapper,sourceWrapper,resRev,"P0P0"); - - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][0] ,resRev[0][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][1] ,resRev[1][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][1] ,resRev[1][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][1] ,resRev[1][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][2] ,resRev[2][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][2] ,resRev[2][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][3] ,resRev[3][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][3] ,resRev[3][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][4] ,resRev[4][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][4] ,resRev[4][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][4] ,resRev[4][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][4] ,resRev[4][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][5] ,resRev[5][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][5] ,resRev[5][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][5] ,resRev[5][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][6] ,resRev[6][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][7] ,resRev[7][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][7] ,resRev[7][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][8] ,resRev[8][2],precis); - - meshC->decrRef(); - meshU->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCU3D() -{ - MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); - DataArrayDouble* coords = DataArrayDouble::New(); - double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); - meshC->setCoords( coords, coords, coords ); - coords->decrRef(); - - MEDCouplingUMesh * meshU = buildCU3DMesh_U(); - - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(meshC); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(meshU); - INTERP_KERNEL::InterpolationCU myInterpolator; - std::vector > res; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - double sum = sumAll(res); - CPPUNIT_ASSERT_EQUAL(8,int( res.size())); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02700000000000 ,res[0][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00299999999999 ,res[1][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[1][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03000000000000 ,res[1][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00300000000000 ,res[2][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[2][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[2][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[3][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][8],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00299999999999 ,res[4][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[4][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03000000000000 ,res[4][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[5][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][10],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][11],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][19],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][20],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[6][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][12],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][15],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][21],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][24],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.7037037037e-05 ,res[7][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][8],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][10],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][11],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][12],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][13],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][14],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][15],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][16],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][17],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][19],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][20],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][21],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][22],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][23],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][24],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][25],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][26],precis); - - - meshC->decrRef(); - meshU->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - CPPUNIT_ASSERT_EQUAL(5,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - targetMesh->decrRef(); - // - targetMesh=build2DTargetMeshPerm_1(); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper2(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator2; - CPPUNIT_ASSERT(myInterpolator2.getMeasureAbsStatus()); - CPPUNIT_ASSERT_EQUAL(5,myInterpolator2.toIntegralUniform(targetWrapper2,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - myInterpolator2.setMeasureAbsStatus(false); - CPPUNIT_ASSERT(!myInterpolator2.getMeasureAbsStatus()); - CPPUNIT_ASSERT_EQUAL(5,myInterpolator2.toIntegralUniform(targetWrapper2,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,sumAll(res),1e-12); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - std::vector > res; - CPPUNIT_ASSERT_EQUAL(5,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - INTERP_KERNEL::Interpolation3D myInterpolator; - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - std::vector > res; - CPPUNIT_ASSERT_EQUAL(8,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000.,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][1],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][2],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][3],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][4],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][5],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][6],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3375000.,res[0][7],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000.,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[1][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[2][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[3][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[4][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[5][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[6][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3375000.,res[7][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - res.clear(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build2DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - CPPUNIT_ASSERT_EQUAL(4,myInterpolator.toIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][3],1e-12); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(4,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[3][0],1e-12); - res.clear(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1IntegralUniform() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(sourceMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - CPPUNIT_ASSERT_EQUAL(9,myInterpolator.toIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][1],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[0][2],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][3],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][4],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[0][5],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][6],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][7],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2000000.,res[0][8],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[1][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[2][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[3][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[4][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[5][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[6][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[7][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2000000.,res[8][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - sourceMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0Bary_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Barycentric,INTERP_KERNEL::BarycentricGeo2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666669,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0Bary_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Barycentric,INTERP_KERNEL::BarycentricGeo2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666669*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -#include -void MEDCouplingBasicsTestInterp::test3DInterpP1P0Bary_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Barycentric); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - - double res3D[5][28]={{104166.66658918398, 885416.666685817763, 135416.666666666541, 36458.3333333335031, 31249.9999999999018, 145833.333333333256, 41666.6666666667516, 124999.999999999971, 177083.333326388849, 0.0, 31249.9999999999636, 0.0, 41666.666620792399, 159722.22229009436, 0.0, 0.0, 41666.6666631944681, 125000, 43499.2283723790752, 164351.851924000395, 36458.3333372396883, 0.0, 0.0, 125000.000001736029, 34722.2221800900952, 13599.5370788455439, 0.0, 167438.27159690368}, - {0.0, 41666.6664479170649, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 125000.000161457952, 0.0, 0.0, 0.0, 0.0, 111111.11112005508, 0.0, 0.0, 291666.666656249959, 41666.6666666666933, 6944.4444415638809, 270833.333520485845, 0.0, 0.0, 124999.999989583303, 41666.6665798612958, 20833.3333186342825, 145833.333354303701, 83333.3333263888198, 27777.7777501651799}, - {0.0, 93750.0000000000728, 125000.000000000058, 0.0, 0.0, 72916.666666666526, 291666.666666666628, 41666.6666666667152, 197916.66666666657, 166666.666666666802, 218750.000000000116, 41666.6666666665697, 0.0, 0.0, 0.0, 0.0, 0.0, 41666.6666666666861, 0.0, 0.0, 0.0, 0.0, 0.0, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0}, - {72916.6666484848247, 82465.2777799315081, 0.0, 0.0, 217447.916666666686, 197916.666666666802, 0.0, 41666.6666666666715, 0.0, 0.0, 0.0, 0.0, 290364.583310396119, 125000.000018181803, 41666.6666666666351, 166666.666666666599, 0.0, 41666.6666666665551, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 27777.7777734705051, 0.0, 0.0, 27777.7778028684952}, - {72916.6666461071727, 172309.027782170655, 70312.5000000000437, 253906.250000000029, 0.0, 0.0, 0.0, 41666.666666666657, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 258246.527775988478, 71180.5555571812583, 253906.250006944378, 41666.6666666666861, 0.0, 41666.6666649305407, 20833.3333186342534, 6944.44445267237552, 0.0, 27777.7777953707919}}; - - double sum = 0; - int i=0; - for(std::vector >::const_iterator iter1=res.begin();iter1!=res.end();iter1++,i++) - { - for(int j=0;j<28;j++) - { - std::map::const_iterator iter2=(*iter1).find(j); - if(iter2!=(*iter1).end()) - { - sum += iter2->second; - CPPUNIT_ASSERT_DOUBLES_EQUAL(res3D[i][j],(*iter2).second,1.e-5); - } - else - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res3D[i][j],1e-14); - } - } - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000,sum,1.e-5); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DTo1DInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); - MEDCouplingUMesh *targetMesh=build1DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test1DInterp_1() -{ - // c1 c0 c2 - pay attention to cell order! - // S: o---o------o---o - // T: o---o------o---o - // n0 n1 n2 n3 - // - // ---+---+------+---+---> X - // 0. 1. 3. 4. - MEDCouplingUMesh *sourceMesh=build1DMesh(0); - MEDCouplingUMesh *targetMesh=build1DMesh(0.5); - // - MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation1D myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - - // P0P0 - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - // P1P0 - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[0][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][3], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - // P0P1 - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - - CPPUNIT_ASSERT_EQUAL( 4, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - // P1P1 - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL( 4, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][3], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P0_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( sqrt(2.),res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.+sqrt(2.), sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P0_2() -{ - // equal meshes shifted one from another along X by 0.5 - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0.5,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - myInterpolator.setMedianPlane(1.);// median line on target - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - double tolInters = myInterpolator.getBoundingBoxAdjustmentAbs() * sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0,res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( tolInters,res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5+tolInters, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P1_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - - const double len1 = 1., len0 = sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[2][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP1P0_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - - const double len1 = 1., len0 = sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[0][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP1P1_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - - const double len1 = 1., len0 = sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*(len0+len1), res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2D1DBasicInterpP0P0() -{ - MEDCouplingUMesh *sourceMesh=build2D1DSourceMesh(); - MEDCouplingUMesh *targetMesh=build2D1DTargetMesh(); - - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D1D myInterpolator; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); - std::vector > matrix; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - CPPUNIT_ASSERT_EQUAL(2,(int)matrix.size()); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(3., matrix[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8., matrix[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5., matrix[0][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6., matrix[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][7],1e-12); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4., matrix[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5., matrix[1][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6., matrix[1][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3., matrix[1][7],1e-12); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - CPPUNIT_ASSERT_EQUAL(1,(int)duplicateFaces.size()); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType correctDuplicateFaces; - std::set face6; - face6.insert(0); - face6.insert(1); - correctDuplicateFaces[6] = face6; - - CPPUNIT_ASSERT(correctDuplicateFaces == duplicateFaces); - - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 16., 0, 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 16., 4, 2 * 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 0, 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 20., 4, 2 * 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 12., 0, 3); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 10., 0, 2); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 16., 0, 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 16., 4, 2 * 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 0, 8); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 20., 4, 8); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 12., 0, 6); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 2, 4); -} - -void MEDCouplingBasicsTestInterp::test3D2DBasicInterpP0P0() -{ - MEDCouplingUMesh *sourceMesh=build3D2DSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DTargetMesh(); - - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D2D myInterpolator; - myInterpolator.setPrecision(1e-12); - std::vector > matrix; - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( size_t i = 0; i < sizeof(sp)/sizeof(sp[0]); ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - matrix.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - CPPUNIT_ASSERT_EQUAL(3,(int)matrix.size()); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(40. ,matrix[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8. ,matrix[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5 ,matrix[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(32. ,matrix[0][6],1e-12); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.*sqrt(3.),matrix[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(40. ,matrix[1][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[1][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][6],1e-12); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(32. ,matrix[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[2][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(112. ,matrix[2][6],1e-12); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - CPPUNIT_ASSERT_EQUAL(3,(int)duplicateFaces.size()); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType correctDuplicateFaces; - std::set face2; - face2.insert(0); - face2.insert(1); - correctDuplicateFaces[2] = face2; - std::set face5; - face5.insert(1); - face5.insert(2); - correctDuplicateFaces[5] = face5; - std::set face6; - face6.insert(0); - face6.insert(1); - face6.insert(2); - correctDuplicateFaces[6] = face6; - - CPPUNIT_ASSERT(correctDuplicateFaces == duplicateFaces); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 20, 2 * 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 20, 2 * 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 15); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 10); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 40, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 40, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 30); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 20, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 20, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 100); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 20, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 45); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 30); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 40, 40 + 80); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 40, 40 + 80); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0); -} - diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx deleted file mode 100644 index a10bd00b3..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGBASICSTESTINTERP_HXX__ -#define __MEDCOUPLINGBASICSTESTINTERP_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTestInterp : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTestInterp); - CPPUNIT_TEST( test2DInterpP0P0_1 ); - CPPUNIT_TEST( test2DInterpP0P0PL_1 ); - CPPUNIT_TEST( test2DInterpP0P0PL_2 ); - CPPUNIT_TEST( test2DInterpP0P0PL_3 ); - CPPUNIT_TEST( test2DInterpP0P0PL_4 ); - CPPUNIT_TEST( test2DInterpP0P1_1 ); - CPPUNIT_TEST( test2DInterpP0P1PL_1 ); - CPPUNIT_TEST( test2DInterpP0P1PL_2 ); - CPPUNIT_TEST( test2DInterpP1P0_1 ); - CPPUNIT_TEST( test2DInterpP1P0PL_1 ); - CPPUNIT_TEST( test2DInterpP1P0PL_2 ); - CPPUNIT_TEST( test2DInterpP1P1_1 ); - CPPUNIT_TEST( test2DInterpP1P1PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P0_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P0PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P1_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P1PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P0_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P0PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P1_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P1PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P0_2 ); - CPPUNIT_TEST( test3DSurfInterpP0P0_3 ); - - CPPUNIT_TEST( testInterpolationCC ); - CPPUNIT_TEST( testInterpolationCU1D ); - CPPUNIT_TEST( testInterpolationCU2D ); - CPPUNIT_TEST( testInterpolationCU3D ); - - CPPUNIT_TEST( test3DInterpP0P0_1 ); - CPPUNIT_TEST( test3DInterpP0P0PL_1 ); - CPPUNIT_TEST( test3DInterpP0P0PL_2 ); - CPPUNIT_TEST( test3DInterpP0P0PL_3 ); - CPPUNIT_TEST( test3DInterpP0P0PL_4 ); - CPPUNIT_TEST( test3DInterpP0P1_1 ); - CPPUNIT_TEST( test3DInterpP0P1PL_1 ); - CPPUNIT_TEST( test3DInterpP1P0_1 ); - CPPUNIT_TEST( test3DInterpP1P0PL_1 ); - CPPUNIT_TEST( test3DInterpP1P1_1 ); - CPPUNIT_TEST( test3DInterpP1P1PL_1 ); - CPPUNIT_TEST( test3DInterpP0P0Empty ); - CPPUNIT_TEST( test2DInterpP0IntegralUniform ); - CPPUNIT_TEST( test3DSurfInterpP0IntegralUniform ); - CPPUNIT_TEST( test3DInterpP0IntegralUniform ); - CPPUNIT_TEST( test2DInterpP1IntegralUniform ); - CPPUNIT_TEST( test3DInterpP1IntegralUniform ); - CPPUNIT_TEST( test2DInterpP1P0Bary_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P0Bary_1 ); - CPPUNIT_TEST( test3DInterpP1P0Bary_1 ); - CPPUNIT_TEST( test3DTo1DInterpP0P0PL_1 ); - - CPPUNIT_TEST( test2D1DBasicInterpP0P0 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_1 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_2 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_3 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_4 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_5 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_6 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_1 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_2 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_3 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_4 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_5 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DBasicInterpP0P0 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_6 ); - - CPPUNIT_TEST( test1DInterp_1 ); - CPPUNIT_TEST( test2DCurveInterpP0P0_1 ); - CPPUNIT_TEST( test2DCurveInterpP0P0_2 ); - CPPUNIT_TEST( test2DCurveInterpP0P1_1 ); - CPPUNIT_TEST( test2DCurveInterpP1P0_1 ); - CPPUNIT_TEST( test2DCurveInterpP1P1_1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test2DInterpP0P0_1(); - void test2DInterpP0P0PL_1(); - void test2DInterpP0P0PL_2(); - void test2DInterpP0P0PL_3(); - void test2DInterpP0P0PL_4(); - void test2DInterpP0P1_1(); - void test2DInterpP0P1PL_1(); - void test2DInterpP0P1PL_2(); - void test2DInterpP1P0_1(); - void test2DInterpP1P0PL_1(); - void test2DInterpP1P0PL_2(); - void test2DInterpP1P1_1(); - void test2DInterpP1P1PL_1(); - void test3DSurfInterpP0P0_1(); - void test3DSurfInterpP0P0PL_1(); - void test3DSurfInterpP0P1_1(); - void test3DSurfInterpP0P1PL_1(); - void test3DSurfInterpP1P0_1(); - void test3DSurfInterpP1P0PL_1(); - void test3DSurfInterpP1P1_1(); - void test3DSurfInterpP1P1PL_1(); - void test3DSurfInterpP0P0_2(); - void test3DSurfInterpP0P0_3(); - void test3DInterpP0P0_1(); - void test3DInterpP0P0PL_1(); - void test3DInterpP0P0PL_2(); - void test3DInterpP0P0PL_3(); - void test3DInterpP0P0PL_4(); - void test3DInterpP0P1_1(); - void test3DInterpP0P1PL_1(); - void test3DInterpP1P0_1(); - void test3DInterpP1P0PL_1(); - void test3DInterpP1P1_1(); - void test3DInterpP1P1PL_1(); - - void testInterpolationCC(); - void testInterpolationCU1D(); - void testInterpolationCU2D(); - void testInterpolationCU3D(); - - void test3DInterpP0P0Empty(); - void test2DInterpP0IntegralUniform(); - void test3DSurfInterpP0IntegralUniform(); - void test3DInterpP0IntegralUniform(); - void test2DInterpP1IntegralUniform(); - void test3DInterpP1IntegralUniform(); - void test2DInterpP1P0Bary_1(); - void test3DSurfInterpP1P0Bary_1(); - void test3DInterpP1P0Bary_1(); - void test3DTo1DInterpP0P0PL_1(); - - void test2D1DBasicInterpP0P0(); - void test2D1DSegQuadInterpP0P0_1(); - void test2D1DSegQuadInterpP0P0_2(); - void test2D1DSegQuadInterpP0P0_3(); - void test2D1DSegQuadInterpP0P0_4(); - void test2D1DSegQuadInterpP0P0_5(); - void test2D1DSegQuadInterpP0P0_6(); - void test2D1DSegTriInterpP0P0_1(); - void test2D1DSegTriInterpP0P0_2(); - void test2D1DSegTriInterpP0P0_3(); - void test2D1DSegTriInterpP0P0_4(); - void test2D1DSegTriInterpP0P0_5(); - void test2D1DSegTriInterpP0P0_6(); - void test3D2DBasicInterpP0P0(); - void test3D2DQuadHexaInterpP0P0_1(); - void test3D2DQuadHexaInterpP0P0_2(); - void test3D2DQuadHexaInterpP0P0_3(); - void test3D2DQuadHexaInterpP0P0_4(); - void test3D2DQuadHexaInterpP0P0_5(); - void test3D2DQuadHexaInterpP0P0_6(); - void test3D2DTriHexaInterpP0P0_1(); - void test3D2DTriHexaInterpP0P0_2(); - void test3D2DTriHexaInterpP0P0_3(); - void test3D2DTriHexaInterpP0P0_4(); - void test3D2DTriHexaInterpP0P0_5(); - void test3D2DTriHexaInterpP0P0_6(); - void test3D2DQuadTetraInterpP0P0_1(); - void test3D2DQuadTetraInterpP0P0_2(); - void test3D2DQuadTetraInterpP0P0_3(); - void test3D2DQuadTetraInterpP0P0_4(); - void test3D2DQuadTetraInterpP0P0_5(); - void test3D2DQuadTetraInterpP0P0_6(); - void test3D2DTriTetraInterpP0P0_1(); - void test3D2DTriTetraInterpP0P0_2(); - void test3D2DTriTetraInterpP0P0_3(); - void test3D2DTriTetraInterpP0P0_4(); - void test3D2DTriTetraInterpP0P0_5(); - void test3D2DTriTetraInterpP0P0_6(); - - void test1DInterp_1(); - void test2DCurveInterpP0P0_1(); - void test2DCurveInterpP0P0_2(); - void test2DCurveInterpP0P1_1(); - void test2DCurveInterpP1P0_1(); - void test2DCurveInterpP1P1_1(); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx deleted file mode 100644 index f749b2f4b..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx +++ /dev/null @@ -1,2579 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - - -void CppExample_MEDCouplingFieldDouble_WriteVTK() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_WriteVTK_1] - // mesh1 - const double coords[3] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingCMesh::New(); - mesh1->setCoords(coordsArr,coordsArr); // mesh becomes a 2D one - - // 3 fields (lying on the same mesh!) - MEDCouplingAutoRefCountObjectPtr field1 = - mesh1->getMeasureField( true ); - MEDCouplingAutoRefCountObjectPtr field2 = - mesh1->buildOrthogonalField(); - MEDCouplingAutoRefCountObjectPtr field3 = - mesh1->fillFromAnalytic( ON_CELLS, 1, "x"); - field2->setName( "Normal" ); // name is necessary! - field3->setName( "Barycenter" ); // name is necessary! - - // WriteVTK - const char fileName[] = "testExample_MEDCouplingFieldDouble_WriteVTK.vtk"; - std::vector fs( 3 ); // field series - fs[0] = field1; - fs[1] = field2; - fs[2] = field3; - MEDCouplingFieldDouble::WriteVTK( fileName, fs ); - //! [CppSnippet_MEDCouplingFieldDouble_WriteVTK_1] - remove(fileName); -} - -void CppExample_MEDCouplingFieldDouble_MaxFields() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_MaxFields_1] - const double vals1[4] = {0.,2., 4.,6.}; // for field 1 - const double vals2[4] = {2.,0., 6.,4.}; // for field 2 - const double valsMax[4] = {2.,2., 6.,6.}; // expected max field - const double valsMin[4] = {0.,0., 4.,4.}; // expected min field - // field 1 - MEDCouplingAutoRefCountObjectPtr valsArr1 = DataArrayDouble::New(); - valsArr1->useExternalArrayWithRWAccess( vals1, 2,2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field1 = MEDCouplingFieldDouble::New( ON_NODES ); - field1->setArray( valsArr1 ); - // field 2 - MEDCouplingAutoRefCountObjectPtr valsArr2 = DataArrayDouble::New(); - valsArr2->useExternalArrayWithRWAccess( vals2, 2,2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field2 = MEDCouplingFieldDouble::New( ON_NODES ); - field2->setArray( valsArr2 ); - // max field - MEDCouplingAutoRefCountObjectPtr fieldMax = MEDCouplingFieldDouble::MaxFields( field1, field2 ); - CPPUNIT_ASSERT( std::equal( valsMax, valsMax+4, fieldMax->getArray()->getConstPointer() )); // fieldMax == valsMax - // min field - MEDCouplingAutoRefCountObjectPtr fieldMin = MEDCouplingFieldDouble::MinFields( field1, field2 ); - CPPUNIT_ASSERT( std::equal( valsMin, valsMin+4, fieldMin->getArray()->getConstPointer() )); // fieldMin == valsMin - //! [CppSnippet_MEDCouplingFieldDouble_MaxFields_1] -} - -void CppExample_MEDCouplingFieldDouble_MergeFields() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_MergeFields_1] - // mesh1 - const double coords[3] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingCMesh::New(); - mesh1->setCoords(coordsArr); // mesh becomes a 1D - // field1 - MEDCouplingAutoRefCountObjectPtr field1 = - mesh1->fillFromAnalytic( ON_CELLS, 1, "x"); - - // mesh2 and field2 - MEDCouplingAutoRefCountObjectPtr field2 = - field1->cloneWithMesh( true ); - double vec[1] = { 5. }; - (const_cast(field2->getMesh()))->translate(vec); // translate mesh2 - field2->applyFunc("x + 5"); // "translate" field2 - - // concatenate field1 and field2 - MEDCouplingAutoRefCountObjectPtr field3 = - MEDCouplingFieldDouble::MergeFields( field1, field2 ); - std::vector fields( 2 ); - fields[0] = field1; - fields[1] = field2; - MEDCouplingAutoRefCountObjectPtr field4 = - MEDCouplingFieldDouble::MergeFields( fields ); - //! [CppSnippet_MEDCouplingFieldDouble_MergeFields_1] -} - -void CppExample_MEDCouplingFieldDouble_substractInPlaceDM() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - const double coords1[4] = {0.,1.,2.,3.}; - const double coords2[4] = {2.,1.,0.,3.}; // #0 <==> #2 - // mesh 1 - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords1, 4, 1 ); - mesh1->setCoords(coordsArr); - mesh1->setMeshDimension(0); - mesh1->allocateCells(0); - mesh1->finishInsertingCells(); - // mesh 2 - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*) mesh1->deepCpy(); - mesh2->getCoords()->useExternalArrayWithRWAccess( coords2, 4, 1 ); - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - MEDCouplingAutoRefCountObjectPtr field1 = - mesh1->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field1 values == coords1 - MEDCouplingAutoRefCountObjectPtr field2 = - mesh2->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field2 values == coords2 - const double levOfCheck = 10; // nodes can be permuted - field1->substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ); // values #0 and #2 must swap - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] - field2->applyFunc( 1, 0.0 ); // all field2 values == 0.0 - CPPUNIT_ASSERT( field1->isEqual( field2, 1e-13, 1e-13 )); // field1 == field2 == 0.0 - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] -} - -void CppExample_MEDCouplingFieldDouble_changeUnderlyingMesh() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - const double coords1[4] = {0.,1.,2.,3.}; - const double coords2[4] = {2.,1.,0.,3.}; // #0 <==> #2 - // mesh 1 - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords1, 4, 1 ); - mesh1->setCoords(coordsArr); - mesh1->setMeshDimension(0); - mesh1->allocateCells(0); - mesh1->finishInsertingCells(); - // mesh 2 - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*) mesh1->deepCpy(); - mesh2->getCoords()->useExternalArrayWithRWAccess( coords2, 4, 1 ); - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] - MEDCouplingAutoRefCountObjectPtr field = - mesh1->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field values == coords1 - const double levOfCheck = 10; // nodes can be permuted - field->changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ); // values #0 and #2 must swap - CPPUNIT_ASSERT( std::equal( coords2, coords2+4, field->getArray()->getConstPointer() )); - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - const double v[4] = {1.,2., 3.,4.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( v, 2, 2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - const char func[] = "IVec * v + JVec * w*w + 10"; - field->applyFunc( 2, func ); - CPPUNIT_ASSERT( field->getNumberOfComponents() == 2 ); // 2 components remains - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] - const double* v2 = field->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[0], 10 + v[0], 13 ); // "10 + IVec * v" - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[1], 10 + v[1]*v[1], 13 ); // "10 + JVec * v*v" - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[2], 10 + v[2], 13 ); // "10 + IVec * v" - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[3], 10 + v[3]*v[3], 13 ); // "10 + JVec * v*v" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc3() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_1] - // create a 2D vector field - const double values[4] = {1.,1., 2.,1.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - // transform the field to a 3D vector field - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y components - std::vector varNamesVec( varNames, varNames+2 ); - field->applyFunc3( 3, varNamesVec, func ); // require 3 components - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_2] - double vec1[3]; // vector #1 - field->getArray()->getTuple( 1, vec1 ); - const double a = values[2], b = values[3]; // initial components of the vector #1 - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_1] - // create a 2D vector field - const double values[4] = {1.,1., 2.,1.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components - array->setInfoOnComponent(0,"a"); // name used to refer to X component within a function - array->setInfoOnComponent(1,"b"); // name used to refer to Y component within a function - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - // transform the field to a 3D vector field - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - field->applyFunc2( 3, func ); // require 3 components - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_2] - double vec1[3]; // vector #1 - field->getArray()->getTuple( 1, vec1 ); - const double a = values[2], b = values[3]; // initial components of the vector #1 - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_1] - // create a 2D vector field - const double values[4] = {1.,1., 2.,1.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - // transform the field to a 3D vector field - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - field->applyFunc( 3, func ); // require 3 components - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_2] - double vec1[3]; // vector #1 - field->getArray()->getTuple( 1, vec1 ); - const double a = values[2], b = values[3]; // initial components of the vector #1 - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc_val() -{ - using namespace ParaMEDMEM; - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_1] - // mesh - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh - // field - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - field->fillFromAnalytic(2,"IVec * x + JVec * y"); // 2 components - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_1] - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_2] - const double newValue = 7.; - field->applyFunc( 3, newValue ); // # 3 components are required - CPPUNIT_ASSERT( field->getIJ(1,0) == newValue ); // a value is as expected - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); - CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_2] -} - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic3() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components - std::vector varNamesVec( varNames, varNames+2 ); - field->fillFromAnalytic3( 3, varNamesVec, func ); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] -} - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function - y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - field->fillFromAnalytic( 3, func ); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] -} - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - const double coords[3] = {0.,2.,4}; - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - field->fillFromAnalytic( 3, func ); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] -} - -//! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0] -bool getNewValue(const double *pos, double *res) -{ - res[0] = pos[0]; - res[1] = pos[1]; - res[2] = sqrt( pos[0]*pos[0] + pos[1]*pos[1] ); - return true; -} -//! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0] - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic_c_func() -{ - using namespace ParaMEDMEM; - //! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1] - // mesh - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh - // field - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - field->fillFromAnalytic( 3, &getNewValue ); // 3 components are required - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); - CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); - //! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc_c_func() -{ - using namespace ParaMEDMEM; - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1] - // mesh - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh - // field - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - field->setArray( bc ); // 2 components here as the mesh is 2D - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1] - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2] - field->applyFunc( 3, &getNewValue ); // 3 components are required - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); - CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2] -} - -void CppExample_MEDCouplingFieldDouble_getValueOn_time() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2] - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS, ParaMEDMEM::LINEAR_TIME ); - field->setMesh( mesh ); - field->fillFromAnalytic( 1,"10"); // all values == 10. - MEDCouplingAutoRefCountObjectPtr array2 = - DataArrayDouble::Add( field->getArray(), field->getArray() ); // == 2 * field->getArray() - field->setEndArray( array2 ); // all values == 20. - const double time1 = 1.1, time2 = 22.; - field->setStartTime( time1, 0, 0 ); - field->setEndTime ( time2, 0, 0 ); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3] - const double pos[2] = { 1., 1. }; // we are in 2D space - double value[1]; // the field is scalar <-> 1 component - field->getValueOn( pos, 0.5*( time1 + time2 ), value ); - CPPUNIT_ASSERT( fabs( value[0] - 0.5*( 10. + 20. )) < 1e-13 ); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3] -} - -void CppExample_MEDCouplingFieldDouble_getValueOnMulti() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2] - // field values are located at cell barycenters - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - MEDCouplingAutoRefCountObjectPtr valArray = - field->getValueOnMulti( bc->getConstPointer(), bc->getNumberOfTuples() ); - CPPUNIT_ASSERT( valArray->isEqual( * field->getArray(), 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2] -} - -void CppExample_MEDCouplingFieldDouble_getValueOn() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_2] - // field values are located at cell barycenters - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - std::vector vals( field->getNumberOfTuples() ); // array to collect values returned by getValueOn() - double cellBC[2]; // we are in 2D space - for ( int i = 0; i < bc->getNumberOfTuples(); ++i ) - { - bc->getTuple( i, cellBC ); - field->getValueOn( cellBC, & vals[i] ); - } - CPPUNIT_ASSERT( std::equal( vals.begin(), vals.end(), field->getArray()->getConstPointer() )); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_2] -} - -void CppExample_MEDCouplingFieldDouble_getValueOnPos() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2] - double val11[1]; // 1 == field->getNumberOfComponents() - field->getValueOnPos( 1,1,-1, val11 ); - // field values are located at cell barycenters - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT( val11[0] == bc->getIJ(3,0) + bc->getIJ(3,1) ); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2] -} - -void CppExample_MEDCouplingFieldDouble_renumberNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr cmesh = MEDCouplingCMesh::New(); - cmesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr mesh = cmesh->buildUnstructured(); - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_1] - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_2] - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_NODES,2,"IVec*x+JVec*y"); - const DataArrayDouble* values = field->getArray(); - const DataArrayDouble* nodeCoords = mesh->getCoords(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *nodeCoords, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_2] - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_3] - const int renumber[9] = { 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - field->renumberNodes(renumber,false); - const MEDCouplingMesh* mesh2 = field->getMesh(); // field now refers to another mesh - values = field->getArray(); - nodeCoords = (static_cast(mesh2))->getCoords(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *nodeCoords, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_3] -} - -void CppExample_MEDCouplingFieldDouble_renumberCells() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr cmesh = MEDCouplingCMesh::New(); - cmesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr mesh = cmesh->buildUnstructured(); - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_1] - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_2] - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,2,"IVec*x+JVec*y"); - const DataArrayDouble* values = field->getArray(); - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *bc, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_2] - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_3] - const int renumber[4] = { 3, 2, 1, 0 }; - field->renumberCells(renumber,false); - const MEDCouplingMesh* mesh2 = field->getMesh(); // field now refers to another mesh - values = field->getArray(); - bc = mesh2->getBarycenterAndOwner(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *bc, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_3] -} - -void CppExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field1 = - mesh->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x+y"); - CPPUNIT_ASSERT( field1->getTimeDiscretization() == ParaMEDMEM::ONE_TIME ); - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] - MEDCouplingAutoRefCountObjectPtr field2 = - field1->buildNewTimeReprFromThis( ParaMEDMEM::NO_TIME, false ); - CPPUNIT_ASSERT( field2->getTimeDiscretization() == ParaMEDMEM::NO_TIME ); - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] -} - -void CppExample_MEDCouplingMesh_fillFromAnalytic3() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components - std::vector varNamesVec( varNames, varNames+2 ); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic3( ParaMEDMEM::ON_CELLS, 3, varNamesVec, func ); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] -} - -void CppExample_MEDCouplingMesh_fillFromAnalytic2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function - y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic2( ParaMEDMEM::ON_CELLS, 3, func ); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] -} - -void CppExample_MEDCouplingMesh_fillFromAnalytic() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS, 3, func ); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] -} - -void CppExample_MEDCouplingCMesh_getCoordsAt() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingCMesh_getCoordsAt_1] - const double coords[3] = {1.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoordsAt(0,x); - const DataArrayDouble* x2=mesh->getCoordsAt(0); - CPPUNIT_ASSERT( x2->isEqual( *x, 1e-13 )); - //! [CppSnippet_MEDCouplingCMesh_getCoordsAt_1] -} - -void CppExample_MEDCouplingUMesh_areCellsIncludedIn() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - MEDCouplingAutoRefCountObjectPtr mesh1=MEDCouplingUMesh::New(); - mesh1->setMeshDimension(2); - mesh1->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // #0 - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // #1 - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // #2 - mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // #3 - mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // #4 - mesh1->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh1->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - const int cells2[3] = { 4,2,0 }; // even cells selected - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*) mesh1->buildPartOfMySelf( cells2, cells2+3, true ); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - int compType = 0; // the strongest policy - DataArrayInt *corr2to1, *corr1to2; - // a larger mesh1 includes a smaller mesh2 - CPPUNIT_ASSERT( mesh1->areCellsIncludedIn( mesh2, compType, corr2to1 )); - CPPUNIT_ASSERT( std::equal( cells2, cells2+3, corr2to1->getConstPointer() )); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - // the smaller mesh2 does NOT include the larger mesh1 - CPPUNIT_ASSERT( ! mesh2->areCellsIncludedIn( mesh1, compType, corr1to2 )); - const int corr1to2Expected[5] = {2, 3, 1, 4, 0}; - CPPUNIT_ASSERT(std::equal( corr1to2Expected, corr1to2Expected+5, corr1to2->getConstPointer() )); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - corr2to1->decrRef(); - corr1to2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - // 2D coordinates of 5 base nodes - const double coords[5*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 5, 2 ); - // coordinates of 5 top nodes - MEDCouplingAutoRefCountObjectPtr coordsArr2 = coordsArr->deepCpy(); - // 3D coordinates of base + top nodes - coordsArr = coordsArr-> changeNbOfComponents( 3, 0 ); - coordsArr2 = coordsArr2->changeNbOfComponents( 3, 1 ); - coordsArr = DataArrayDouble::Aggregate( coordsArr, coordsArr2 ); - // mesh - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - mesh->setMeshDimension(3); - mesh->allocateCells(2); - // connectivity of reversed HEXA8 and PENTA6 - const int conn[8+6]={0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9}; - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8, 8,conn+0); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+8); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] - MEDCouplingAutoRefCountObjectPtr fixedCells = - mesh->findAndCorrectBadOriented3DExtrudedCells(); - CPPUNIT_ASSERT( fixedCells->getNumberOfTuples() == 2 ); // 2 cells fixed - fixedCells = mesh->findAndCorrectBadOriented3DExtrudedCells(); - CPPUNIT_ASSERT( fixedCells->getNumberOfTuples() == 0 ); // no bad cells - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] -} - -void CppExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - // 2D coordinates of 5 base nodes - const double coords[5*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 5, 2 ); - // coordinates of 5 top nodes - MEDCouplingAutoRefCountObjectPtr coordsArr2 = coordsArr->deepCpy(); - // 3D coordinates of base + top nodes - coordsArr = coordsArr-> changeNbOfComponents( 3, 0 ); - coordsArr2 = coordsArr2->changeNbOfComponents( 3, 1 ); - coordsArr = DataArrayDouble::Aggregate( coordsArr, coordsArr2 ); - // mesh - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - mesh->setMeshDimension(3); - mesh->allocateCells(2); - // connectivity of a HEXA8 + a reversed PENTA6 - const int conn[8+6]={0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9}; - mesh->insertNextCell(INTERP_KERNEL::NORM_POLYHED,8,conn); // "extruded" polyhedron - mesh->insertNextCell(INTERP_KERNEL::NORM_POLYHED,6,conn+8); - mesh->finishInsertingCells(); - // fix connectivity of NORM_POLYHED's - mesh->convertExtrudedPolyhedra(); - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] - std::vector badCellIds; - mesh->arePolyhedronsNotCorrectlyOriented( badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 1 ); // one polyhedron is KO - // fix invalid rolyherdons - mesh->orientCorrectlyPolyhedrons(); - // re-check orientation - badCellIds.clear(); // as badCellIds is not cleared by arePolyhedronsNotCorrectlyOriented() - mesh->arePolyhedronsNotCorrectlyOriented( badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 0 ); // connectivity is OK - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] -} - -void CppExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - mesh->changeSpaceDimension(3); - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] - const double vec[3] = {0.,0.,-1.}; - std::vector badCellIds; - mesh->are2DCellsNotCorrectlyOriented( vec, false, badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 1 ); // one cell is reversed - // fix orientation - mesh->orientCorrectly2DCells( vec, false ); - // re-check orientation - badCellIds.clear(); // as badCellIds is not cleared by are2DCellsNotCorrectlyOriented() - mesh->are2DCellsNotCorrectlyOriented( vec, false, badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 0 ); // the orientation is OK - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] -} - -void CppExample_MEDCouplingUMesh_getCellsContainingPoints() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2] - const double pos[3*2] = { 10., 10, // point out of the mesh - 0.3, 0.3, // point located somewhere inside the mesh - coords[2], coords[3]}; // point at the node #1 - const double eps = 1e-4; // ball radius - MEDCouplingAutoRefCountObjectPtr cells, cellsIndex; - mesh->getCellsContainingPoints( pos, 3, eps, cells, cellsIndex ); - const int cellsExpected[3]={4, 0, 1}; - const int cellsIndexExpected[4]={0, 0, 1, 3}; - CPPUNIT_ASSERT(std::equal( cellsExpected, cellsExpected+3, cells->begin())); - CPPUNIT_ASSERT(std::equal( cellsIndexExpected, cellsIndexExpected+4, cellsIndex->begin())); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2] -} - -void CppExample_MEDCouplingUMesh_getCellsContainingPoint() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2] - const double* coords4 = coords + 4*2; // coordinates of the node #4 - const double eps = 1e-4; // ball radius - const double pos[2] = { coords4[0] + eps, coords4[1] - eps }; // ball center - std::vector cellIds; - mesh->getCellsContainingPoint( pos, eps, cellIds ); - CPPUNIT_ASSERT ( (int)cellIds.size() == mesh->getNumberOfCells() ); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2] -} - -void CppExample_MEDCouplingUMesh_buildPartOrthogonalField() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] - const int part[4] = {1,2,3,4}; // cell #0 is omitted - MEDCouplingAutoRefCountObjectPtr vecField= - mesh->buildPartOrthogonalField( part, part+4 ); - CPPUNIT_ASSERT ( vecField->getArray()->getNumberOfTuples() == 4 ); - CPPUNIT_ASSERT ( vecField->getArray()->getNumberOfComponents() == 3 ); - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] -} - -void CppExample_MEDCouplingUMesh_getPartMeasureField() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_1] - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_2] - const bool isAbs = true; - const int part[4] = {1,2,3,4}; // cell #0 is omitted - MEDCouplingAutoRefCountObjectPtr areaArr= - mesh->getPartMeasureField( isAbs, part, part+4 ); - CPPUNIT_ASSERT( areaArr->getIJ(0,0) > 0 ); // orientation ignored - areaArr=mesh->getPartMeasureField( !isAbs, part, part+4 ); - CPPUNIT_ASSERT( areaArr->getIJ(0,0) < 0 ); // orientation considered - CPPUNIT_ASSERT ( areaArr->getNumberOfTuples() == 4 ); - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_2] - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_3] - const int cellIds[4] = {1,2,3,4}; // cell #0 is omitted - MEDCouplingAutoRefCountObjectPtr baryCenters= - mesh->getPartBarycenterAndOwner( cellIds, cellIds+4 ); - CPPUNIT_ASSERT( baryCenters->getNumberOfTuples() == 4 ); - CPPUNIT_ASSERT( baryCenters->getNumberOfComponents() == mesh->getSpaceDimension() ); - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_3] -} - -void CppExample_MEDCouplingUMesh_getCellsInBoundingBox() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(1); - const double coords[3*2]={0.,0., 0.,1., 1.,1}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 3,2); - mesh->setCoords(coordsArr); - mesh->allocateCells(1); - const int conn[3]={0,1,2}; - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] - const double bbox[] = {1., 1., 1.001,1.001}; // xMin, xMax, yMin, yMax - MEDCouplingAutoRefCountObjectPtr cellIdsArr = - mesh->getCellsInBoundingBox( bbox, 0.0 ); - CPPUNIT_ASSERT( cellIdsArr->getNumberOfTuples() == 0 ); - cellIdsArr = mesh->getCellsInBoundingBox( bbox, 0.1 ); - CPPUNIT_ASSERT( cellIdsArr->getNumberOfTuples() == 1 ); - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] -} - -void CppExample_MEDCouplingUMesh_renumberNodesInConn() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(1); - const int conn[4]={4,3,2,1}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1] - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2] - const int old2newIds[] = {-1,3,2,1,0}; - mesh->renumberNodesInConn( old2newIds ); - const int nodes0Expected[] = {0,1,2,3}; - std::vector nodes0; - mesh->getNodeIdsOfCell( 0, nodes0 ); - CPPUNIT_ASSERT(std::equal( nodes0Expected, nodes0Expected+4, &nodes0[0] )); - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2] -} - -void CppExample_MEDCouplingUMesh_renumberNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - const double coords[4*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - mesh->setCoords(coordsArr); - mesh->allocateCells(0); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_1] - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_2] - const int newIds[] = { 2,1,0,-1 }; - mesh->renumberNodes(newIds, 3); - coordsArr = mesh->getCoordinatesAndOwner(); // get a shorten array - const double coordsExpected[3*2]={0.7,-0.3, 0.2,-0.3, -0.3,-0.3}; - MEDCouplingAutoRefCountObjectPtr coordsExpectedArr=DataArrayDouble::New(); - coordsExpectedArr->useExternalArrayWithRWAccess(coordsExpected, 3,2); - CPPUNIT_ASSERT( coordsExpectedArr->isEqual( *coordsArr, 1e-13 )); - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_2] - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_3] - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); // restore old nodes - const int newIds2[] = { 2,1,0,2 }; - mesh->renumberNodes2(newIds2, 3); - coordsArr = mesh->getCoordinatesAndOwner(); // get a shorten array - const double coordsExpected2[3*2]={0.7,-0.3, 0.2,-0.3, -0.3, 0.0}; - MEDCouplingAutoRefCountObjectPtr coordsExpectedArr2=DataArrayDouble::New(); - coordsExpectedArr2->useExternalArrayWithRWAccess(coordsExpected2, 3,2); - CPPUNIT_ASSERT( coordsExpectedArr2->isEqual( *coordsArr, 1e-13 )); - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_3] -} - -void CppExample_MEDCouplingUMesh_findBoundaryNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1] - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2] - MEDCouplingAutoRefCountObjectPtr nodeIdsArr=mesh->findBoundaryNodes(); - CPPUNIT_ASSERT( nodeIdsArr->getNumberOfTuples() == mesh->getNumberOfNodes() - 1 ); - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2] -} - -void CppExample_MEDCouplingUMesh_buildBoundaryMesh() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2] - MEDCouplingAutoRefCountObjectPtr mesh1=mesh->buildBoundaryMesh(true); - MEDCouplingAutoRefCountObjectPtr mesh2=mesh->buildBoundaryMesh(false); - CPPUNIT_ASSERT( coordsArr->isEqual( *mesh1->getCoords(), 1e-13 )); // same nodes - CPPUNIT_ASSERT( !coordsArr->isEqual( *mesh2->getCoords(), 1e-13 )); // different nodes - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2] -} - -void CppExample_MEDCouplingUMesh_buildFacePartOfMySelfNode() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] - std::vector nodes; - mesh->getNodeIdsOfCell( 0, nodes ); - const bool allNodes = true; - MEDCouplingAutoRefCountObjectPtr mesh1 = - (MEDCouplingUMesh*)mesh->buildFacePartOfMySelfNode( &nodes[0],&nodes[0]+nodes.size(),allNodes); - CPPUNIT_ASSERT( mesh1->getNumberOfCells() == 4 ); // 4 segments bounding QUAD4 #0 only - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*)mesh->buildFacePartOfMySelfNode( &nodes[0],&nodes[0]+nodes.size(),!allNodes); - CPPUNIT_ASSERT( mesh2->getNumberOfCells() == 9 ); // more segments added - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] -} - -void CppExample_MEDCouplingUMesh_buildPartOfMySelfNode() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] - std::vector nodes; - mesh->getNodeIdsOfCell( 0, nodes ); - const bool allNodes = true; - MEDCouplingAutoRefCountObjectPtr mesh1 = - (MEDCouplingUMesh*)mesh->buildPartOfMySelfNode( &nodes[0], &nodes[0]+nodes.size(), allNodes); - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*)mesh->buildPartOfMySelfNode( &nodes[0], &nodes[0]+nodes.size(),!allNodes); - CPPUNIT_ASSERT_EQUAL( mesh1->getNumberOfCells(), 1 ); - CPPUNIT_ASSERT_EQUAL( mesh2->getNumberOfCells(), mesh->getNumberOfCells() ); - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] -} - -void CppExample_MEDCouplingUMesh_getCellIdsLyingOnNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - std::vector nodes; - mesh->getNodeIdsOfCell( 0, nodes ); - const bool allNodes = true; - DataArrayInt* cellIdsArr1 = mesh->getCellIdsLyingOnNodes( &nodes[0], &nodes[0]+nodes.size(), allNodes); - DataArrayInt* cellIdsArr2 = mesh->getCellIdsLyingOnNodes( &nodes[0], &nodes[0]+nodes.size(),!allNodes); - CPPUNIT_ASSERT_EQUAL( cellIdsArr1->getNumberOfTuples(), 1 ); - CPPUNIT_ASSERT_EQUAL( cellIdsArr2->getNumberOfTuples(), mesh->getNumberOfCells() ); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - cellIdsArr1->decrRef(); - cellIdsArr2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - const int cellIds[2]={1,2}; - std::vector nodes; - mesh->getNodeIdsOfCell( cellIds[0], nodes ); - mesh->getNodeIdsOfCell( cellIds[1], nodes ); - DataArrayInt* cellIdsArr = mesh->getCellIdsFullyIncludedInNodeIds( &nodes[0], &nodes[0]+nodes.size()); - CPPUNIT_ASSERT(std::equal( cellIds, cellIds+2, cellIdsArr->getPointer() )); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - cellIdsArr->decrRef(); -} - -void CppExample_MEDCouplingUMesh_buildPartOfMySelf() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - const int cellIds[2]={1,2}; - MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); - MEDCouplingUMesh* mesh3=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,false); - CPPUNIT_ASSERT( coordsArr->isEqual( *mesh2->getCoords(), 1e-13 )); // same nodes - CPPUNIT_ASSERT( !coordsArr->isEqual( *mesh3->getCoords(), 1e-13 )); // different nodes - for ( int i = 0; i < 2; ++i ) - { - std::vector nodes1, nodes2; - mesh ->getNodeIdsOfCell(cellIds[i], nodes1); - mesh2->getNodeIdsOfCell(i, nodes2); - CPPUNIT_ASSERT( nodes1 == nodes2 ); // cell #cellIds[i] was copied - } - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - mesh2->decrRef(); - mesh3->decrRef(); -} - -void CppExample_MEDCouplingUMesh_mergeNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->finishInsertingCells(); - const double coords[6*2]={0.3,-0.301, // #0 - 0.2,-0.3, // #1 - 0.3,-0.302, // #2 ~~ #0 - 1.1,0.0, // #3 - 1.1,0.0, // #4 == #3 - 0.3,-0.303}; // #5 ~~ #0 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(6,2); - std::copy(coords,coords+6*2,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_1] - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_2] - bool areNodesMerged; int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr arr= - mesh->mergeNodes(0.004,areNodesMerged,newNbOfNodes); - const int idsExpected[6] = {0, 1, 0, 2, 2, 0}; - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+6,arr->getPointer())); - CPPUNIT_ASSERT( areNodesMerged ); - CPPUNIT_ASSERT_EQUAL( 3, newNbOfNodes ); - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_2] - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_3] - const double* baryCoords2 = coords + 2*2; // initial coordinates of node #2 - coordsArr=mesh->getCoordinatesAndOwner(); // retrieve a new shorten coord array - CPPUNIT_ASSERT( fabs( baryCoords2[1] - coordsArr->getIJ(0,1)) > 1e-4 ); // Y of node #0 differs from that of baryCoords2 - // restore coordinates - coordsArr->alloc(6,2); - std::copy(coords,coords+6*2,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - // call mergeNodes2() - arr = mesh->mergeNodes2(0.004,areNodesMerged,newNbOfNodes); - coordsArr=mesh->getCoordinatesAndOwner(); // retrieve a new shorten coord array - CPPUNIT_ASSERT_DOUBLES_EQUAL( baryCoords2[1], coordsArr->getIJ(0,1), 13 ); // Y of node #0 equals to that of baryCoords2 - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_3] -} - -void CppExample_MEDCouplingUMesh_zipConnectivityTraducer() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[11]={0,3,4,1, 1,4,2, 4,1,0,3}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+0); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 2 == 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+0); // 3 == 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+7); // 4 ~~ 0 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - const int oldNbCells = mesh->getNumberOfCells(); - DataArrayInt *arr = mesh->zipConnectivityTraducer(0); - CPPUNIT_ASSERT_EQUAL( oldNbCells-2, mesh->getNumberOfCells() ); - const int idsExpected[5] = {0, 1, 1, 0, 2}; - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+5,arr->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - arr->decrRef(); -} - -void CppExample_MEDCouplingUMesh_zipCoordsTraducer() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - const int cellIds[2]={1,2}; - MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); - DataArrayInt *arr=mesh2->zipCoordsTraducer(); - CPPUNIT_ASSERT_EQUAL( 4, mesh2->getNumberOfNodes() ); // nb of nodes decreased - CPPUNIT_ASSERT_EQUAL( mesh->getNumberOfNodes(), arr->getNumberOfTuples() ); - const int idsExpected[9] = {-1,0,1,-1,2,3,-1,-1,-1}; // -1 for unused nodes - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+9,arr->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - mesh2->decrRef(); - arr->decrRef(); -} - -void CppExample_MEDCouplingUMesh_getNodeIdsInUse() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - const int cellIds[2]={1,2}; - MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); - int newNbOfNodes = 0; - DataArrayInt *arr=mesh2->getNodeIdsInUse( newNbOfNodes ); - const int idsExpected[9] = {-1,0,1,-1,2,3,-1,-1,-1}; - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+9,arr->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - DataArrayInt *arr2=arr->invertArrayO2N2N2O(newNbOfNodes); - const int idsExpected2[4] = {1,2,4,5}; - CPPUNIT_ASSERT(std::equal(idsExpected2,idsExpected2+4,arr2->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - mesh2->decrRef(); - arr->decrRef(); - arr2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_convertToPolyTypes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1] - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2] - const int cells[2]={1,3}; - mesh->convertToPolyTypes(cells, cells+2); - CPPUNIT_ASSERT( mesh->getTypeOfCell(0) == INTERP_KERNEL::NORM_QUAD4 ); - CPPUNIT_ASSERT( mesh->getTypeOfCell(1) == INTERP_KERNEL::NORM_POLYGON ); - CPPUNIT_ASSERT( mesh->getTypeOfCell(2) == INTERP_KERNEL::NORM_TRI3 ); - CPPUNIT_ASSERT( mesh->getTypeOfCell(3) == INTERP_KERNEL::NORM_POLYGON ); - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2] -} - -void CppExample_MEDCouplingUMesh_buildDescendingConnectivity2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - DataArrayInt *desc =DataArrayInt::New(); - DataArrayInt *descIndx =DataArrayInt::New(); - DataArrayInt *revDesc =DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - MEDCouplingUMesh * mesh2 = mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); - const int descExpected[] = {1,2,3,4,-3,5,6,7,8,-5,9,10,-2,11,12,13,-7,-10}; - const int descIndxExpected[] = {0,4,7,10,14,18}; - const int revDescExpected[] = {0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - const int revDescIndxExpected[] = {0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(descExpected,descExpected+18,desc->getPointer())); - CPPUNIT_ASSERT(std::equal(descIndxExpected,descIndxExpected+6,descIndx->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescExpected,revDescExpected+18,revDesc->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescIndxExpected,revDescIndxExpected+14,revDescIndx->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - const int cell2ConnExpect[] = {4,1}; - std::vector cell2Conn; - mesh2->getNodeIdsOfCell( 3-1, cell2Conn ); // cell #3 in FORTRAN mode - CPPUNIT_ASSERT(std::equal(cell2ConnExpect,cell2ConnExpect+2,&cell2Conn[0])); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_buildDescendingConnectivity() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - DataArrayInt *desc =DataArrayInt::New(); - DataArrayInt *descIndx =DataArrayInt::New(); - DataArrayInt *revDesc =DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - MEDCouplingUMesh * mesh2 = mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - const int descExpected[] = {0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9}; - const int descIndxExpected[] = {0,4,7,10,14,18}; - const int revDescExpected[] = {0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - const int revDescIndxExpected[] = {0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(descExpected,descExpected+18,desc->getPointer())); - CPPUNIT_ASSERT(std::equal(descIndxExpected,descIndxExpected+6,descIndx->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescExpected,revDescExpected+18,revDesc->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescIndxExpected,revDescIndxExpected+14,revDescIndx->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_getReverseNodalConnectivity() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - DataArrayInt *revNodal=DataArrayInt::New(); - DataArrayInt *revNodalIndx=DataArrayInt::New(); - mesh->getReverseNodalConnectivity(revNodal,revNodalIndx); - const int revNodalExpected[18]={0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4}; - const int revNodalIndexExpected[10]={0,1,3,5,7,12,14,15,17,18}; - CPPUNIT_ASSERT(std::equal(revNodalExpected,revNodalExpected+18,revNodal->getPointer())); - CPPUNIT_ASSERT(std::equal(revNodalIndexExpected,revNodalIndexExpected+10,revNodalIndx->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - revNodal->decrRef(); - revNodalIndx->decrRef(); -} - -void CppExample_MEDCouplingUMesh_checkDeepEquivalWith() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - // mesh 1 - MEDCouplingUMesh *mesh1=MEDCouplingUMesh::New(); - const double coords[4*2]={0.0,0.0, // #0 - 1.0,0.0, // #1 - 1.0,1.0, // #2 - 0.0,1.0}; // #3 - { - mesh1->setMeshDimension(2); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 4, 2 ); - mesh1->setCoords(coordsArr); - mesh1->allocateCells(2); - const int conn[6]={0,1,2, 1,2,3}; - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+0); // #0 - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+3); // #1 - mesh1->finishInsertingCells(); - } - // mesh 2 - MEDCouplingUMesh *mesh2=MEDCouplingUMesh::New(); - const double coords2[4*2]={0.0,1.0, // #0 = #3 - 0.0,0.0, // #1 = #0 - 1.0,0.0, // #2 = #1 - 1.0,1.001}; // #3 ~ #2 - { - mesh2->setMeshDimension(2); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords2, 4, 2 ); - mesh2->setCoords(coordsArr); - mesh2->allocateCells(2); - const int conn[6]={2,3,0, 3,1,2}; - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+0); // #0 = #1 - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+3); // #1 ~ #0 - mesh2->finishInsertingCells(); - } - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - int cellCompPol = 1; // "permuted same orientation" - policy of medium severity - DataArrayInt *nOld2New, *cOld2New; - mesh1->checkDeepEquivalWith( mesh2, cellCompPol, 0.002, cOld2New, nOld2New ); - const int nOld2NewExpected[4] = { 3, 0, 1, 2 }; - const int cOld2NewExpected[2] = { 1, 0 }; - CPPUNIT_ASSERT(std::equal(nOld2NewExpected,nOld2NewExpected+4,nOld2New->getConstPointer())); - CPPUNIT_ASSERT(std::equal(cOld2NewExpected,cOld2NewExpected+2,cOld2New->getConstPointer())); - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - cOld2New->decrRef(); // else memory leaks - CPPUNIT_ASSERT_THROW ( mesh1->checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0.002, cOld2New ), INTERP_KERNEL::Exception ); - mesh2->setCoords( mesh1->getCoords() ); // make meshes share the same coordinates array - mesh2->allocateCells(2); - const int conn[6]={1,2,3, 1,0,2}; - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+0); // #0 = #1 - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+3); // #1 ~ #0 - mesh2->finishInsertingCells(); - cellCompPol = 2; // the weakest policy - mesh1->checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0, cOld2New ); - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - nOld2New->decrRef(); - cOld2New->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); -} - -void CppExample_MEDCouplingPointSet_scale() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_scale_1] - double coords[4*2]={0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; // 2D coordinates of 4 nodes - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - DataArrayDouble *initCoords = coordsArr->deepCpy(); - //! [CppSnippet_MEDCouplingPointSet_scale_1] - //! [CppSnippet_MEDCouplingPointSet_scale_2] - const double center[2] = {0.,0.}; - const double factor = 2.; - mesh->scale( center, factor ); - //! [CppSnippet_MEDCouplingPointSet_scale_2] - //! [CppSnippet_MEDCouplingPointSet_scale_3] - const DataArrayDouble * coordsArr2 = mesh->getCoords(); - CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *initCoords, 1.0 )); - CPPUNIT_ASSERT( !coordsArr2->isEqualWithoutConsideringStr( *initCoords, 0.9 )); - // release data - initCoords->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_scale_3] -} - -void CppExample_MEDCouplingPointSet_translate() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_translate_1] - double coords[4*2]={0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; // 2D coordinates of 4 nodes - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - DataArrayDouble *initCoords = coordsArr->deepCpy(); - //! [CppSnippet_MEDCouplingPointSet_translate_1] - //! [CppSnippet_MEDCouplingPointSet_translate_2] - double vector[2] = {1.,1.}; - mesh->translate( vector ); - //! [CppSnippet_MEDCouplingPointSet_translate_2] - //! [CppSnippet_MEDCouplingPointSet_translate_3] - const DataArrayDouble * coordsArr2 = mesh->getCoords(); - CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *initCoords, 1.0 )); - CPPUNIT_ASSERT( !coordsArr2->isEqualWithoutConsideringStr( *initCoords, 0.9 )); - // release data - initCoords->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_translate_3] -} - -void CppExample_MEDCouplingPointSet_rotate() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_rotate_1] - double coords[4*2]={0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1}; // 2D coordinates of 4 nodes - double coordsOrig[4*2]; - std::copy(coords,coords+sizeof(coords)/sizeof(double),coordsOrig);//keep tracks of initial values - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_rotate_1] - //! [CppSnippet_MEDCouplingPointSet_rotate_2] - double center[3] = {0.,0.,0.}; // it suits for 2D as well - double vector[3] = {0.,0.,1.}; // it is not used in 2D - mesh->rotate( center, vector, -M_PI/2); // warning here C++ 'coords' array (defined above) has been modified ! - //! [CppSnippet_MEDCouplingPointSet_rotate_2] - //! [CppSnippet_MEDCouplingPointSet_rotate_3] - mesh->changeSpaceDimension(3); - mesh->rotate( center, vector, +M_PI/2); - //! [CppSnippet_MEDCouplingPointSet_rotate_3] - //! [CppSnippet_MEDCouplingPointSet_rotate_4] - mesh->changeSpaceDimension(2); - const DataArrayDouble * coordsArr2 = mesh->getCoords(); - coordsArr->useExternalArrayWithRWAccess(coordsOrig, 4,2); - CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *coordsArr, 1e-13 )); - //! [CppSnippet_MEDCouplingPointSet_rotate_4] -} - -void CppExample_MEDCouplingPointSet_getBoundingBox() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_1] - double cc[2*3]={0.0, 0.1, 0.2, // 3D coordinates of 2 nodes - 2.0, 2.1, 2.2}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(cc, 2,3); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_1] - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_2] - double bbox[3][2]; - mesh->getBoundingBox( (double*) bbox ); - - // check the returned coordinates of extremum points of the bounding box - for ( int i = 0; i < 2; ++i ) // point id - for ( int j = 0; j < 3; ++j ) // component - CPPUNIT_ASSERT_DOUBLES_EQUAL( cc[ i*3 + j ], bbox[j][i], 1e-13); - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_2] -} - -void CppExample_MEDCouplingPointSet_getNodeIdsNearPoint() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - // 2D coordinates of 5 nodes - double coords[5*2]={0.3,-0.30001, // #0 - 0.2,-0.3, // #1 - 0.3,-0.30002, // #2 - 1.1,0.0, // #3 - 0.3,-0.30003};// #4 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 5,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] - double point [2]={0.3, -0.3}; // point close to nodes #0, #2 and #4 - DataArrayInt *ids = mesh->getNodeIdsNearPoint(point, 1e-2); - - // check found ids - const int expectedIDs[3] = {0,2,4}; - DataArrayInt * okIDs = ids->getIdsEqualList ( expectedIDs, expectedIDs+3 ); - CPPUNIT_ASSERT_EQUAL(3, okIDs->getNumberOfTuples()); - - // release data - ids->decrRef(); - okIDs->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] -} -void CppExample_MEDCouplingPointSet_getNodeIdsNearPoints() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - // 2D coordinates of 7 nodes - double coords[7*2]={0.3,-0.301, // #0 - 0.2,-0.3, // #1 - 0.3,-0.302, // #2 - 1.1,0.0, // #3 - 1.1,0.0, // #4 - 1.1,0.002, // #5 - 0.3,-0.303};// #6 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 7,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] - const int nbOfPoints = 3; - double points [nbOfPoints*2]={0.2,-0.30001, // ~ node #1 - 0.0, 0.0, - 1.1, 0.002}; // ~ nodes #3, #4 and #5 - DataArrayInt *ids, *idsIndex; - mesh->getNodeIdsNearPoints(points, nbOfPoints, 1e-1,ids,idsIndex); - - // check found ids (i.e. contents of 'ids' array) - const int expectedIDs[4] = {1, 3, 4, 5}; - DataArrayInt * okIDs = ids->getIdsEqualList ( expectedIDs, expectedIDs+4 ); - CPPUNIT_ASSERT_EQUAL(4, okIDs->getNumberOfTuples()); - - // release data - ids->decrRef(); - idsIndex->decrRef(); - okIDs->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] -} - -void CppExample_MEDCouplingPointSet_findCommonNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_1] - double coords[6*2]={0.3,-0.301, // 0 - 0.2,-0.3, // 1 - 0.3,-0.302, // 2 - 1.1,0.0, // 3 - 1.1,0.0, // 4 - 0.3,-0.303};// 5 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 6,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_1] - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_2] - DataArrayInt *com, *comI; - mesh->findCommonNodes(1e-13,-1,com,comI); - CPPUNIT_ASSERT_EQUAL(2, com->getNumberOfTuples()); - com->decrRef(); comI->decrRef(); - mesh->findCommonNodes(0.004,-1,com,comI); - CPPUNIT_ASSERT_EQUAL(5, com->getNumberOfTuples()); - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_2] - com->decrRef(); comI->decrRef(); -} - -void CppExample_MEDCouplingPointSet_getCoordinatesOfNode() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] - double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 3,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] - std::vector coords2; - mesh->getCoordinatesOfNode(1,coords2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[2],coords2[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[3],coords2[1],1e-13); - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] -} - -void CppExample_DataArrayInt_buildPermutationArr() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_buildPermutationArr_1] - DataArrayInt *a=DataArrayInt::New(); - const int vala[5]={4,5,6,7,8}; - a->alloc(5,1); - std::copy(vala,vala+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - const int valb[5]={5,4,8,6,7}; - b->alloc(5,1); - std::copy(valb,valb+5,b->getPointer()); - DataArrayInt *c=a->buildPermutationArr(*b); - //! [CppSnippet_DataArrayInt_buildPermutationArr_1] - const int expect1[5]={1,0,4,2,3}; - CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); - CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); - a->decrRef(); - b->decrRef(); - c->decrRef(); -} - -void CppExample_DataArrayInt_invertArrayO2N2N2O() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] - const int arr1[6]={2,0,4,1,5,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(6,1); - std::copy(arr1,arr1+6,da->getPointer()); - DataArrayInt *da2=da->invertArrayO2N2N2O(6); - const int expected1[6]={1,3,0,5,2,4}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] - da->decrRef(); - da2->decrRef(); -} - -void CppExample_DataArrayInt_invertArrayN2O2O2N() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] - const int arr1[6]={2,0,4,1,5,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(6,1); - std::copy(arr1,arr1+6,da->getPointer()); - DataArrayInt *da2=da->invertArrayN2O2O2N(6); - const int expected1[6]={1,3,0,5,2,4}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] - da->decrRef(); - da2->decrRef(); -} - -void CppExample_DataArrayDouble_getIdsInRange() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayDouble_getIdsInRange_1] - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(10,1); - da->iota(); - - DataArrayInt* da2 = da->getIdsInRange( 2.5, 6 ); - //! [CppSnippet_DataArrayDouble_getIdsInRange_1] - da->decrRef(); - da2->decrRef(); -} - -void CppExample_DataArrayDouble_findCommonTuples() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayDouble_findCommonTuples1] - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,2); - const double array2[12]={2.3,2.3, // 0 - 1.2,1.2, // 1 - 1.3,1.3, // 2 - 2.3,2.3, // 3 - 2.301, // 4 - 2.301, // 5 - 0.8,0.8};// 6 - std::copy(array2,array2+12,da->getPointer()); - //! [CppSnippet_DataArrayDouble_findCommonTuples1] - //! [CppSnippet_DataArrayDouble_findCommonTuples2] - DataArrayInt *c=0,*cI=0; - da->findCommonTuples(1.01e-1,-1,c,cI); - - const int expected3[5]={0,3,4,1,2}; - const int expected4[3]={0,3,5}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - da->decrRef(); - //! [CppSnippet_DataArrayDouble_findCommonTuples2] -} - -void CppExample_DataArrayDouble_Meld1() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayDouble_Meld1_1] - const int sameNbTuples = 7; - - DataArrayDouble *da1=DataArrayDouble::New(); - da1->alloc(sameNbTuples,2); - da1->fillWithValue(7.); - da1->setInfoOnComponent(0,"c0da1"); - da1->setInfoOnComponent(1,"c1da1"); - - DataArrayDouble *da2=DataArrayDouble::New(); - da2->alloc(sameNbTuples,1); - da2->iota(0.); - da2->setInfoOnComponent(0,"c0da2"); - - da1->meldWith(da2); - //! [CppSnippet_DataArrayDouble_Meld1_1] - //! [CppSnippet_DataArrayDouble_Meld1_2] - da1->decrRef(); - da2->decrRef(); - //! [CppSnippet_DataArrayDouble_Meld1_2] -} - -void CppExample_DataArrayInt_Meld1() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_Meld1_1] - const int sameNbTuples = 7; - - DataArrayInt *da1=DataArrayInt::New(); - da1->alloc(sameNbTuples,2); - da1->fillWithValue(7); - da1->setInfoOnComponent(0,"c0da1"); - da1->setInfoOnComponent(1,"c1da1"); - - DataArrayInt *da2=DataArrayInt::New(); - da2->alloc(sameNbTuples,1); - da2->iota(0); - da2->setInfoOnComponent(0,"c0da2"); - - da1->meldWith(da2); - //! [CppSnippet_DataArrayInt_Meld1_1] - //! [CppSnippet_DataArrayInt_Meld1_2] - da1->decrRef(); - da2->decrRef(); - //! [CppSnippet_DataArrayInt_Meld1_2] -} - -void CppExampleFieldDoubleBuildSubPart1() -{ - //! [CppSnippetFieldDoubleBuildSubPart1_1] - ParaMEDMEM::MEDCouplingUMesh *mesh1=ParaMEDMEM::MEDCouplingBasicsTest::build2DTargetMesh_1(); - ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; - std::copy(arr1,arr1+10,array->getPointer()); - f1->setArray(array); - array->decrRef(); - //! [CppSnippetFieldDoubleBuildSubPart1_1] - //! [CppSnippetFieldDoubleBuildSubPart1_2] - const int part1[3]={2,1,4}; - ParaMEDMEM::MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); - //! [CppSnippetFieldDoubleBuildSubPart1_2] - f2->zipCoords(); - CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - ParaMEDMEM::MEDCouplingUMesh *m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); - const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); - const double expected4[4]={0,4,8,13}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - f1->decrRef(); - //! [CppSnippetFieldDoubleBuildSubPart1_3] - f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),2); - const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; - std::copy(arr2,arr2+18,array->getPointer()); - f1->setArray(array); - array->decrRef(); - //! [CppSnippetFieldDoubleBuildSubPart1_3] - //! [CppSnippetFieldDoubleBuildSubPart1_4] - const int part2[2]={1,2}; - f2=f1->buildSubPart(part2,part2+2); - //! [CppSnippetFieldDoubleBuildSubPart1_4] - f2->decrRef(); - //idem previous because nodes of cell#4 are not fully present in part3 - const int part3[2]={1,2}; - ParaMEDMEM::DataArrayInt *arrr=ParaMEDMEM::DataArrayInt::New(); - arrr->alloc(2,1); - std::copy(part3,part3+2,arrr->getPointer()); - f2=f1->buildSubPart(arrr); - arrr->decrRef(); - f2->decrRef(); - // - const int part4[3]={1,2,4}; - f2=f1->buildSubPart(part4,part4+3); - f2->decrRef(); - // - f1->decrRef(); - mesh1->decrRef(); - return; -} - -void CppSnippetUMeshStdBuild1() -{ - //! [CppSnippetUMeshStdBuild1_1] - double coords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; - int nodalConnPerCell[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - //! [CppSnippetUMeshStdBuild1_1] - //! [CppSnippetUMeshStdBuild1_2] - ParaMEDMEM::MEDCouplingUMesh *mesh=ParaMEDMEM::MEDCouplingUMesh::New("My2DMesh",2); - //! [CppSnippetUMeshStdBuild1_2] - //! [CppSnippetUMeshStdBuild1_3] - mesh->allocateCells(5);//You can put more than 5 if you want but not less. - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell+14); - mesh->finishInsertingCells(); - //! [CppSnippetUMeshStdBuild1_3] - //! [CppSnippetUMeshStdBuild1_4] - ParaMEDMEM::DataArrayDouble *coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(9,3);//here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - std::copy(coords,coords+27,coordsArr->getPointer()); - mesh->setCoords(coordsArr);//coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. - coordsArr->decrRef(); - //! [CppSnippetUMeshStdBuild1_4] - mesh->checkCoherency(); - //! [CppSnippetUMeshStdBuild1_5] - mesh->decrRef(); - //! [CppSnippetUMeshStdBuild1_5] -} - -void CppSnippetCMeshStdBuild1() -{ - //! [CppSnippetCMeshStdBuild1_1] - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); - arrX->alloc(9,1); - std::copy(XCoords,XCoords+9,arrX->getPointer()); - arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); - arrY->alloc(7,1); - std::copy(YCoords,YCoords+7,arrY->getPointer()); - arrY->setInfoOnComponent(0,"Y [m]"); - //! [CppSnippetCMeshStdBuild1_1] - //! [CppSnippetCMeshStdBuild1_2] - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); - arrX->decrRef(); - arrY->decrRef(); - //! [CppSnippetCMeshStdBuild1_2] - //! [CppSnippetCMeshStdBuild1_3] - CPPUNIT_ASSERT_EQUAL(8*6,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9*7,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - //! [CppSnippetCMeshStdBuild1_3] - mesh->decrRef(); - mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - //! [CppSnippetCMeshStdBuild1_2bis] - mesh->setCoordsAt(0,arrX); - arrX->decrRef(); - mesh->setCoordsAt(1,arrY); - arrY->decrRef(); - //! [CppSnippetCMeshStdBuild1_2bis] - CPPUNIT_ASSERT_EQUAL(8*6,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9*7,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - //! [CppSnippetCMeshStdBuild1_4] - mesh->decrRef(); - //! [CppSnippetCMeshStdBuild1_4] -} - -void CppSnippetUMeshAdvBuild1() -{ - //! [CppSnippetUMeshAdvBuild1_1] - double coords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; - int nodalConnPerCell[23]={4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4}; - int nodalConnPerCellIndex[6]={0,5,9,13,18,23}; - //! [CppSnippetUMeshAdvBuild1_1] - //! [CppSnippetUMeshAdvBuild1_2] - ParaMEDMEM::MEDCouplingUMesh *mesh=ParaMEDMEM::MEDCouplingUMesh::New("My2DMesh",2); - //! [CppSnippetUMeshAdvBuild1_2] - //! [CppSnippetUMeshAdvBuild1_3] - ParaMEDMEM::DataArrayInt *nodalConn=ParaMEDMEM::DataArrayInt::New(); - nodalConn->alloc(23,1); - std::copy(nodalConnPerCell,nodalConnPerCell+23,nodalConn->getPointer()); - ParaMEDMEM::DataArrayInt *nodalConnI=ParaMEDMEM::DataArrayInt::New(); - nodalConnI->alloc(6,1); - std::copy(nodalConnPerCellIndex,nodalConnPerCellIndex+6,nodalConnI->getPointer()); - mesh->setConnectivity(nodalConn,nodalConnI,true); - nodalConn->decrRef();// nodalConn DataArrayInt instance is owned by mesh after call to setConnectivity method. No more need here -> decrRef() - nodalConnI->decrRef();// nodalConnI DataArrayInt instance is owned by mesh after call to setConnectivity method. No more need here -> decrRef() - //! [CppSnippetUMeshAdvBuild1_3] - //! [CppSnippetUMeshAdvBuild1_4] - ParaMEDMEM::DataArrayDouble *coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(9,3);//here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - std::copy(coords,coords+27,coordsArr->getPointer()); - mesh->setCoords(coordsArr);//coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. - coordsArr->decrRef(); - //! [CppSnippetUMeshAdvBuild1_4] - mesh->checkCoherency(); - //! [CppSnippetUMeshAdvBuild1_5] - mesh->decrRef(); - //! [CppSnippetUMeshAdvBuild1_5] -} - -void CppSnippetDataArrayBuild1() -{ - //! [CppSnippetDataArrayBuild1_0] - const int nbOfNodes=12; - double coords[3*nbOfNodes]={2.,3.,4.,3.,4.,5.,4.,5.,6.,5.,6.,7.,6.,7.,8.,7.,8.,9.,8.,9.,10.,9.,10.,11.,10.,11.,12.,11.,12.,13.,12.,13.,14.,13.,14.,15.}; - // - ParaMEDMEM::DataArrayDouble *coordsArr=0; - double *tmp=0; - //! [CppSnippetDataArrayBuild1_0] - // - //! [CppSnippetDataArrayBuild1_1] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->useArray(coords,false,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); - //now use coordsArr as you need - //... - //coordsArr is no more useful here : release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_1] - //! [CppSnippetDataArrayBuild1_2] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - tmp=new double[3*nbOfNodes]; - std::copy(coords,coords+3*nbOfNodes,tmp); - coordsArr->useArray(tmp,true,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); - //now use coordsArr as you need - //... - //coordsArr is no more useful, release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_2] - //! [CppSnippetDataArrayBuild1_3] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); - std::copy(coords,coords+3*nbOfNodes,tmp); - coordsArr->useArray(tmp,true,ParaMEDMEM::C_DEALLOC,nbOfNodes,3); - //now use coordsArr as you need - //... - //coordsArr is no more useful here : release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_3] - //! [CppSnippetDataArrayBuild1_4] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(nbOfNodes,3); - tmp=coordsArr->getPointer(); - std::copy(coords,coords+3*nbOfNodes,tmp); - coordsArr->declareAsNew();//you have modified data pointed by internal pointer notify object - //now use coordsArr as you need - //... - //coordsArr is no more useful here : release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_4] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(nbOfNodes,3); - tmp=coordsArr->getPointer(); - std::copy(coords,coords+3*nbOfNodes,tmp); - ParaMEDMEM::DataArrayDouble *coordsArrCpy=0; - //! [CppSnippetDataArrayBuild1_5] - coordsArrCpy=coordsArr->deepCpy(); - //! [CppSnippetDataArrayBuild1_5] - //! [CppSnippetDataArrayBuild1_6] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,1000.); - CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified - //! [CppSnippetDataArrayBuild1_6] - //! [CppSnippetDataArrayBuild1_7] - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_7] - //! [CppSnippetDataArrayBuild1_5bis] - coordsArrCpy=coordsArr->performCpy(true); - //! [CppSnippetDataArrayBuild1_5bis] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,1000.); - CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_8] - coordsArrCpy=coordsArr->performCpy(false); - //! [CppSnippetDataArrayBuild1_8] - //! [CppSnippetDataArrayBuild1_9] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,1000.); - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArr and coordsArrCpy have been modified simultaneously - //! [CppSnippetDataArrayBuild1_9] - //! [CppSnippetDataArrayBuild1_10] - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_10] - //! [CppSnippetDataArrayBuild1_11] - coordsArrCpy=ParaMEDMEM::DataArrayDouble::New(); - //! [CppSnippetDataArrayBuild1_11] - //! [CppSnippetDataArrayBuild1_12] - coordsArrCpy->cpyFrom(*coordsArr); - //! [CppSnippetDataArrayBuild1_12] - //! [CppSnippetDataArrayBuild1_13] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,2000.); - CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified - //! [CppSnippetDataArrayBuild1_13] - //! [CppSnippetDataArrayBuild1_14] - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_14] - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_14] -} - -void CppSnippetFieldDoubleBuild1() -{ - double XCoords[9]={-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.07,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild1_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnCells=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); - fieldOnCells->setName("MyTensorFieldOnCellNoTime"); - fieldOnCells->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnCells - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnCells->getMesh()->getNumberOfCells(),9);//Implicitely fieldOnCells will be a 9 components field. - array->fillWithValue(7.); - fieldOnCells->setArray(array); - array->decrRef(); - // fieldOnCells is now usable - // ... - // fieldOnCells is no more useful here : release it - fieldOnCells->decrRef(); - //! [CppSnippetFieldDoubleBuild1_1] - arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild1_2] - ParaMEDMEM::MEDCouplingFieldDouble *f1=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,1,"x*x+y*y*3+2.*x");//f1 is scalar - ParaMEDMEM::MEDCouplingFieldDouble *f2=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,1,"cos(x+y/x)");//f2 is scalar too - ParaMEDMEM::MEDCouplingFieldDouble *f2bis=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,2,"x*x*IVec+3*y*JVec");//f2bis is a vectors field - ParaMEDMEM::MEDCouplingFieldDouble *f3=(*f1)+(*f2);//f3 scalar - ParaMEDMEM::MEDCouplingFieldDouble *f4=(*f3)/(*f2);//f4 scalar - f2bis->applyFunc(1,"sqrt(x*x+y*y)");//f2bis becomes scalar - ParaMEDMEM::MEDCouplingFieldDouble *f5=(*f2bis)*(*f4);//f5 scalar - const double pos1[2]={0.48,0.38}; - double res; - f4->getValueOn(pos1,&res);//f4 is scalar so the returned value is of size 1. - // ... - //! [CppSnippetFieldDoubleBuild1_2] - mesh->decrRef(); - //! [CppSnippetFieldDoubleBuild1_3] - // f1, f2, f2bis, f3, f4, f5 are no more useful here : release them - f1->decrRef(); - f2->decrRef(); - f2bis->decrRef(); - f3->decrRef(); - f4->decrRef(); - f5->decrRef(); - //! [CppSnippetFieldDoubleBuild1_3] -} - -void CppSnippetFieldDoubleBuild2() -{ - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild2_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnNodes=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::NO_TIME); - fieldOnNodes->setName("MyScalarFieldOnNodeNoTime"); - fieldOnNodes->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),1);//Implicitely fieldOnNodes will be a 1 component field. - array->fillWithValue(8.); - fieldOnNodes->setArray(array); - array->decrRef(); - // fieldOnNodes is now usable - // ... - // fieldOnNodes is no more useful here : release it - fieldOnNodes->decrRef(); - //! [CppSnippetFieldDoubleBuild2_1] -} - -void CppSnippetFieldDoubleBuild3() -{ - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild3_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnCells=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - fieldOnCells->setName("MyTensorFieldOnCellNoTime"); - fieldOnCells->setTimeUnit("ms"); // Time unit is ms. - fieldOnCells->setTime(4.22,2,-1); // Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1 - fieldOnCells->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnCells - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnCells->getMesh()->getNumberOfCells(),2);//Implicitely fieldOnCells will be a 2 components field. - array->fillWithValue(7.); - fieldOnCells->setArray(array); - array->decrRef(); - // fieldOnCells is now usable - // ... - // fieldOnCells is no more useful here : release it - fieldOnCells->decrRef(); - //! [CppSnippetFieldDoubleBuild3_1] -} - -void CppSnippetFieldDoubleBuild4() -{ - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild4_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnNodes=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::CONST_ON_TIME_INTERVAL); - fieldOnNodes->setName("MyVecFieldOnNodeWithConstTime"); - fieldOnNodes->setTimeUnit("ms"); // Time unit is ms. - fieldOnNodes->setStartTime(4.22,2,-1); - fieldOnNodes->setEndTime(6.44,4,-1); // fieldOnNodes is defined in interval [4.22 ms,6.44 ms] - fieldOnNodes->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),3);//Implicitely fieldOnNodes will be a 3 components field. - array->fillWithValue(8.); - fieldOnNodes->setArray(array); - array->decrRef(); - // fieldOnNodes is now usable - // ... - // fieldOnNodes is no more useful here : release it - fieldOnNodes->decrRef(); - //! [CppSnippetFieldDoubleBuild4_1] -} - -int main(int argc, char *argv[]) -{ - CppExample_MEDCouplingFieldDouble_WriteVTK(); - CppExample_MEDCouplingFieldDouble_MaxFields(); - CppExample_MEDCouplingFieldDouble_MergeFields(); - CppExample_MEDCouplingFieldDouble_substractInPlaceDM(); - CppExample_MEDCouplingFieldDouble_changeUnderlyingMesh(); - CppExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(); - CppExample_MEDCouplingFieldDouble_applyFunc3(); - CppExample_MEDCouplingFieldDouble_applyFunc2(); - CppExample_MEDCouplingFieldDouble_applyFunc(); - CppExample_MEDCouplingFieldDouble_applyFunc_val(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic3(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic2(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic_c_func(); - CppExample_MEDCouplingFieldDouble_applyFunc_c_func(); - CppExample_MEDCouplingFieldDouble_getValueOn_time(); - CppExample_MEDCouplingFieldDouble_getValueOnMulti(); - CppExample_MEDCouplingFieldDouble_getValueOn(); - CppExample_MEDCouplingFieldDouble_getValueOnPos(); - CppExample_MEDCouplingFieldDouble_renumberNodes(); - CppExample_MEDCouplingFieldDouble_renumberCells(); - CppExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(); - CppExample_MEDCouplingMesh_fillFromAnalytic3(); - CppExample_MEDCouplingMesh_fillFromAnalytic2(); - CppExample_MEDCouplingMesh_fillFromAnalytic(); - CppExample_MEDCouplingCMesh_getCoordsAt(); - CppExample_MEDCouplingUMesh_areCellsIncludedIn(); - CppExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(); - CppExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(); - CppExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(); - CppExample_MEDCouplingUMesh_getCellsContainingPoints(); - CppExample_MEDCouplingUMesh_getCellsContainingPoint(); - CppExample_MEDCouplingUMesh_buildPartOrthogonalField(); - CppExample_MEDCouplingUMesh_getPartMeasureField(); - CppExample_MEDCouplingUMesh_getCellsInBoundingBox(); - CppExample_MEDCouplingUMesh_renumberNodesInConn(); - CppExample_MEDCouplingUMesh_renumberNodes(); - CppExample_MEDCouplingUMesh_findBoundaryNodes(); - CppExample_MEDCouplingUMesh_buildBoundaryMesh(); - CppExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(); - CppExample_MEDCouplingUMesh_buildPartOfMySelfNode(); - CppExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(); - CppExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(); - CppExample_MEDCouplingUMesh_buildPartOfMySelf(); - CppExample_MEDCouplingUMesh_mergeNodes(); - CppExample_MEDCouplingUMesh_zipConnectivityTraducer(); - CppExample_MEDCouplingUMesh_zipCoordsTraducer(); - CppExample_MEDCouplingUMesh_getNodeIdsInUse(); - CppExample_MEDCouplingUMesh_convertToPolyTypes(); - CppExample_MEDCouplingUMesh_buildDescendingConnectivity2(); - CppExample_MEDCouplingUMesh_buildDescendingConnectivity(); - CppExample_MEDCouplingUMesh_getReverseNodalConnectivity(); - CppExample_MEDCouplingUMesh_checkDeepEquivalWith(); - CppExample_MEDCouplingPointSet_scale(); - CppExample_MEDCouplingPointSet_translate(); - CppExample_MEDCouplingPointSet_rotate(); - CppExample_MEDCouplingPointSet_getBoundingBox(); - CppExample_MEDCouplingPointSet_getNodeIdsNearPoint(); - CppExample_MEDCouplingPointSet_getNodeIdsNearPoints(); - CppExample_MEDCouplingPointSet_findCommonNodes(); - CppExample_MEDCouplingPointSet_getCoordinatesOfNode(); - CppExample_DataArrayInt_buildPermutationArr(); - CppExample_DataArrayInt_invertArrayO2N2N2O(); - CppExample_DataArrayInt_invertArrayN2O2O2N(); - CppExample_DataArrayDouble_getIdsInRange(); - CppExample_DataArrayDouble_findCommonTuples(); - CppExample_DataArrayDouble_Meld1(); - CppExampleFieldDoubleBuildSubPart1(); - CppSnippetUMeshStdBuild1(); - CppSnippetUMeshAdvBuild1(); - CppSnippetDataArrayBuild1(); - CppSnippetCMeshStdBuild1(); - CppSnippetFieldDoubleBuild1(); - CppSnippetFieldDoubleBuild2(); - CppSnippetFieldDoubleBuild3(); - CppSnippetFieldDoubleBuild4(); - - return 0; -} diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx b/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx deleted file mode 100644 index f8a2e37ba..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx +++ /dev/null @@ -1,1318 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingRemapperTest.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingRemapper.hxx" - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingRemapperTest::test2DInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected2[5]={3.75 ,1.75 ,1.75,4.,3.75}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(ConservativeVolumic); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::test2DInterpP0P0R_1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - - MEDCouplingFieldDouble *targetField=MEDCouplingFieldDouble::New(ON_CELLS); - targetField->setNature(ConservativeVolumic); - targetField->setMesh(targetMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - targetField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - // - MEDCouplingFieldDouble *srcfield=remapper.reverseTransferField(targetField,4.57); - const double *values=srcfield->getArray()->getConstPointer(); - const double valuesExpected[2]={8.75 ,9.5}; - CPPUNIT_ASSERT_EQUAL(2,srcfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - srcfield->decrRef(); - // - targetField->setNature(IntegralGlobConstraint); - srcfield=remapper.reverseTransferField(targetField,4.57); - values=srcfield->getArray()->getConstPointer(); - const double valuesExpected2[2]={26., 19.}; - CPPUNIT_ASSERT_EQUAL(2,srcfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - srcfield->decrRef(); - // - targetField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::test1DInterp_1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build1DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_2(); - // - MEDCouplingRemapper remapper; - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - // - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected1[2]={9.0540540540540526,7.4}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); - trgfield->decrRef(); - const double valuesExpected2[2]={24.75,5.75}; - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - const double valuesExpected3[2]={24.75,9.25}; - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - // - const double valuesExpected4[2]={7.4444444444444446,7.4}; - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //2D Curve - sourceMesh=MEDCouplingBasicsTest::build2DCurveSourceMesh_2(); - targetMesh=MEDCouplingBasicsTest::build2DCurveTargetMesh_2(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - // - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::test2DInterpMultiMethods() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P1P0")); - srcField=MEDCouplingFieldDouble::New(ON_NODES); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfNodes(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfNodes();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected2[5]={7.,7.666666666666667,8.6666666666666661,8.8333333333333339,10.}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P1")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected3[4]={7.5,8.5,10.,10.625}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); - // - sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_2(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P1P1")); - srcField=MEDCouplingFieldDouble::New(ON_NODES); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfNodes(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfNodes();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected4[9]={ 7.,7.35,8.,7.7,8.2857142857142865, - 9.5333333333333332,9.,9.7666666666666657,10.}; - CPPUNIT_ASSERT_EQUAL(9,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<9;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testMultiDimCombi() -{ - // ------------- 2D - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgField=remapper.transferField(srcField,4.57); - const double *values=trgField->getArray()->getConstPointer(); - const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; - CPPUNIT_ASSERT_EQUAL(5,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 3D Surf - sourceMesh=MEDCouplingBasicsTest::build3DSurfSourceMesh_1(); - targetMesh=MEDCouplingBasicsTest::build3DSurfTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+8); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(5,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected2[5]={8.5,8.,8.,9.,8.5}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 3D - sourceMesh=MEDCouplingBasicsTest::build3DSourceMesh_1(); - targetMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected3[8]={13.166666666666668, 13.888888888888888, 10.722222222222223, 10.870370370370372, - 14.555555555555555, 13.888888888888889, 14.444444444444443, 11.72222222222222}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<8;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 3D -> 1D - sourceMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); - targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected4[8]={7.,11.,8.,12.,9.,13.,10.,14.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<8;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 1D -> 3D - sourceMesh=MEDCouplingBasicsTest::build1DTargetMesh_1(); - targetMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected5[8]={7.,9.,11.,13.,8.,10.,12.,14.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<8;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected5[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 2D -> 1D - sourceMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - targetMesh=build1DTargetMesh_2(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected8[5]={9.,8.,11.,7.,11.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected8[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 1D -> 2D - sourceMesh=build1DTargetMesh_2(); - targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected9[5]={10.,8.,7.,4.57,10.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 2D -> -1D - sourceMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - targetMesh=MEDCouplingUMesh::New("an example of -1 D mesh",-1); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - trgField=remapper.transferField(srcField,4.57); - values=trgField->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,values[0],1e-14); - srcField->decrRef(); - srcField=remapper.reverseTransferField(trgField,4.220173); - CPPUNIT_ASSERT_EQUAL(5,srcField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getNumberOfComponents()); - values=srcField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,values[i0],1e-14); - srcField->decrRef(); - trgField->setNature(Integral); - srcField=remapper.reverseTransferField(trgField,4.220173); - CPPUNIT_ASSERT_EQUAL(5,srcField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getNumberOfComponents()); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected6[5]={2.28125,1.140625,1.140625,2.28125,2.28125}; - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected6[i0],values[i0],1e-14); - srcField->decrRef(); - trgField->decrRef(); - // ------------- -1D -> 2D - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); - trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - trgField->setArray(array); - ptr=array->getPointer(); - ptr[0]=7.; - array->decrRef(); - srcField=remapper.transferField(trgField,4.221073); - values=srcField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,values[i0],1e-14); - srcField->decrRef(); - trgField->setNature(IntegralGlobConstraint); - srcField=remapper.transferField(trgField,4.221073); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected7[5]={1.75,0.875,0.875,1.75,1.75}; - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-14); - srcField->decrRef(); - trgField->setNature(Integral); - srcField=remapper.transferField(trgField,4.221073); - values=srcField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-14); - srcField->decrRef(); - trgField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //------------- 1D -> 2D - const int conn[8]={0,1,1,2,2,3,3,0}; - const int conn2[12]={6,7,5,4,2,7,6,3,0,4,5,1}; - const double coords1[]={0.17,0.93,0.56,0.93,0.56,0.25,0.17,0.52}; - const double coords2[]={0.,0.,1.,0.,1.,1.,0.,1.,0.,0.5,1.,0.5,0.,0.8,1.,0.8}; - sourceMesh=MEDCouplingUMesh::New("src1D",1); - sourceMesh->allocateCells(4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+6); - sourceMesh->finishInsertingCells(); - array=DataArrayDouble::New(); array->alloc(4,2); - std::copy(coords1,coords1+8,array->getPointer()); - sourceMesh->setCoords(array); array->decrRef(); - targetMesh=MEDCouplingUMesh::New("trg2D",2); - targetMesh->allocateCells(3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+8); - targetMesh->finishInsertingCells(); - array=DataArrayDouble::New(); array->alloc(8,2); - std::copy(coords2,coords2+16,array->getPointer()); - targetMesh->setCoords(array); array->decrRef(); - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Geometric2D); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(4,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected10[3]={3.9674868868103834, 2.8, 3.6372633449255796}; - CPPUNIT_ASSERT_EQUAL(3,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected10[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - //------------- 2D -> 1D - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Geometric2D); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(3,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected11[4]={3., 2.9264705882352944, 3.8518518518518516, 2.3170731707317076}; - CPPUNIT_ASSERT_EQUAL(4,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected11[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //------------- 2D -> 3D - sourceMesh=MEDCouplingBasicsTest::build3D2DSourceMesh(); - targetMesh=MEDCouplingBasicsTest::build3D2DTargetMesh(); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(7,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected12[3]={5.70909090909091, 6.08362715128042, 6.92857142857143}; - CPPUNIT_ASSERT_EQUAL(3,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected12[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - //------------- 3D -> 2D - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(3,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected13[7]={3., 4., 2.5, 2.909090909090909, 2., 3.5, 3.3571428571428572}; - CPPUNIT_ASSERT_EQUAL(7,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected13[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testNatureOfField() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected2[4]={2.8374999999999999, 7.3624999999999998, 4.220173, 4.7999999999999998}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected3[4]={1.24, 4.5199999999999996, 4.220173, 1.9199999999999999}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected9[4]={2.48, 3.766666666666666, 4.220173, 1.9199999999999999}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - // REVERSE *********** - trgfield=MEDCouplingFieldDouble::New(ON_CELLS); - trgfield->setNature(ConservativeVolumic); - trgfield->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - trgfield->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - srcField=remapper.reverseTransferField(trgfield,4.220173); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected4[2]={7.9375, 8.9}; - CPPUNIT_ASSERT_EQUAL(2,srcField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - srcField->decrRef(); - // - trgfield->decrRef(); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); - // REVERSE ALL - sourceMesh=build2DTargetMesh_3(); - targetMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected5[2]={7.9375, 8.9}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected5[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected6[4]={9.25, 15.75}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected6[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected7[2]={4.56, 4.3466666666666667}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected10[2]={5.08, 3.56}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected10[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - // REVERSE *********** - trgfield=MEDCouplingFieldDouble::New(ON_CELLS); - trgfield->setNature(ConservativeVolumic); - trgfield->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - trgfield->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - srcField=remapper.reverseTransferField(trgfield,4.220173); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected8[4]={7.75, 7.0625,4.220173, 8.0}; - CPPUNIT_ASSERT_EQUAL(4,srcField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected8[i0],values[i0],1e-12); - srcField->decrRef(); - // - trgfield->decrRef(); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testExtruded() -{ - MEDCouplingUMesh *mesh2DS=0; - MEDCouplingUMesh *mesh3DS=build3DExtrudedUMesh_1(mesh2DS); - MEDCouplingExtrudedMesh *extS=MEDCouplingExtrudedMesh::New(mesh3DS,mesh2DS,1); - mesh3DS->decrRef(); - mesh2DS->decrRef(); - MEDCouplingUMesh *mesh2DT=0; - MEDCouplingUMesh *mesh3DT=build3DExtrudedUMesh_1(mesh2DT); - MEDCouplingExtrudedMesh *extT=MEDCouplingExtrudedMesh::New(mesh3DT,mesh2DT,1); - // - // - mesh3DT->decrRef(); - mesh2DT->decrRef(); - // - extS->decrRef(); - extT->decrRef(); -} - -void MEDCouplingRemapperTest::testExtruded2() -{ - MEDCouplingUMesh *meshN,*meshTT,*meshTF; - MEDCouplingBasicsTest::build3DExtrudedUMesh_2(meshN,meshTT,meshTF); - std::vector n; - double pt[3]={300.,300.,0.}; - double v[3]={0.,0.,2.}; - meshN->findNodesOnPlane(pt,v,1e-12,n); - MEDCouplingUMesh *meshN2D=(MEDCouplingUMesh *)meshN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - n.clear(); - bool b=false; - int newNbOfNodes; - DataArrayInt *da=meshTT->mergeNodes(1e-12,b,newNbOfNodes); - CPPUNIT_ASSERT(b); - da->decrRef(); - meshTT->findNodesOnPlane(pt,v,1e-12,n); - MEDCouplingUMesh *meshTT2D=(MEDCouplingUMesh *)meshTT->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - n.clear(); - meshTF->findNodesOnPlane(pt,v,1e-12,n); - MEDCouplingUMesh *meshTF2D=(MEDCouplingUMesh *)meshTF->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - n.clear(); - // - MEDCouplingExtrudedMesh *meshNE=MEDCouplingExtrudedMesh::New(meshN,meshN2D,0); - MEDCouplingExtrudedMesh *meshTTE=MEDCouplingExtrudedMesh::New(meshTT,meshTT2D,0); - MEDCouplingExtrudedMesh *meshTFE=MEDCouplingExtrudedMesh::New(meshTF,meshTF2D,0); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTTE,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(IntegralGlobConstraint); - srcField->setMesh(meshNE); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(meshNE->getNumberOfCells(),1); - srcField->setArray(array); - double vals1[40]={ - 1000.,1000.,1020.,1030.,1040.,1000.,1000.,1070.,1080.,1090.,1000.,1000.,1120.,1130.,1140.,1000.,1000.,1170.,1180.,1190., - 2000.,2000.,2020.,2030.,2040.,2000.,2000.,2070.,2080.,2090.,2000.,2000.,2120.,2130.,2140.,2000.,2000.,2170.,2180.,2190., - }; - CPPUNIT_ASSERT_EQUAL((int)(sizeof(vals1)/sizeof(double)),meshNE->getNumberOfCells()); - std::copy(vals1,vals1+meshNE->getNumberOfCells(),array->getPointer()); - array->decrRef(); - MEDCouplingFieldDouble *trgField=remapper.transferField(srcField,4.220173); - double expected1[200]={ - 800.,800.,800.,800.,800.,800.,800.,800.,800.,800.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600., - 102.,102.,102.,102.,102.,102.,102.,102.,102.,102.,202.,202.,202.,202.,202.,202.,202.,202.,202.,202., - 103.,103.,103.,103.,103.,103.,103.,103.,103.,103.,203.,203.,203.,203.,203.,203.,203.,203.,203.,203., - 104.,104.,104.,104.,104.,104.,104.,104.,104.,104.,204.,204.,204.,204.,204.,204.,204.,204.,204.,204., - 219.,219.,219.,219.,219.,219.,219.,219.,219.,219.,419.,419.,419.,419.,419.,419.,419.,419.,419.,419., - 221.,221.,221.,221.,221.,221.,221.,221.,221.,221.,421.,421.,421.,421.,421.,421.,421.,421.,421.,421., - 223.,223.,223.,223.,223.,223.,223.,223.,223.,223.,423.,423.,423.,423.,423.,423.,423.,423.,423.,423., - 117.,117.,117.,117.,117.,117.,117.,117.,117.,117.,217.,217.,217.,217.,217.,217.,217.,217.,217.,217., - 118.,118.,118.,118.,118.,118.,118.,118.,118.,118.,218.,218.,218.,218.,218.,218.,218.,218.,218.,218., - 119.,119.,119.,119.,119.,119.,119.,119.,119.,119.,219.,219.,219.,219.,219.,219.,219.,219.,219.,219. - }; - for(int i=0;i<200;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],trgField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected1,expected1+200,0.),std::accumulate(vals1,vals1+40,0.),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected1,expected1+200,0.),std::accumulate(trgField->getArray()->getConstPointer(),trgField->getArray()->getConstPointer()+200,0.),1e-10); - trgField->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTFE,"P0P0")); - trgField=remapper.transferField(srcField,4.220173); - double expected2[340]={25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, - 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, - 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, - 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, - 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, - 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, - 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, - 29.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., - 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, - 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, - 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, - 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, - 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, - 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, - 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 800., 800., 800., 800., 800., 800., 800., 800., 800., 800., 1600., 1600., 1600., 1600., 1600., 1600., 1600., - 1600., 1600., 1600.}; - for(int i=0;i<340;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],trgField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected2,expected2+340,0.),std::accumulate(vals1,vals1+40,0.),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected2,expected2+340,0.),std::accumulate(trgField->getArray()->getConstPointer(),trgField->getArray()->getConstPointer()+340,0.),1e-10); - trgField->decrRef(); - srcField->decrRef(); - // - double vals2[200]={ - 100., 200., 300., 400., 500., 600., 700., 800., 900., 1000., 1100., 1200., 1300., 1400., 1500., 1600., 1700., 1800., 1900., 2000, - 101., 201., 301., 401., 501., 601., 701., 801., 901., 1001., 1101., 1201., 1301., 1401., 1501., 1601., 1701., 1801., 1901., 2001, - 102., 202., 302., 402., 502., 602., 702., 802., 902., 1002., 1102., 1202., 1302., 1402., 1502., 1602., 1702., 1802., 1902., 2002, - 103., 203., 303., 403., 503., 603., 703., 803., 903., 1003., 1103., 1203., 1303., 1403., 1503., 1603., 1703., 1803., 1903., 2003, - 104., 204., 304., 404., 504., 604., 704., 804., 904., 1004., 1104., 1204., 1304., 1404., 1504., 1604., 1704., 1804., 1904., 2004, - 105., 205., 305., 405., 505., 605., 705., 805., 905., 1005., 1105., 1205., 1305., 1405., 1505., 1605., 1705., 1805., 1905., 2005, - 106., 206., 306., 406., 506., 606., 706., 806., 906., 1006., 1106., 1206., 1306., 1406., 1506., 1606., 1706., 1806., 1906., 2006, - 107., 207., 307., 407., 507., 607., 707., 807., 907., 1007., 1107., 1207., 1307., 1407., 1507., 1607., 1707., 1807., 1907., 2007, - 108., 208., 308., 408., 508., 608., 708., 808., 908., 1008., 1108., 1208., 1308., 1408., 1508., 1608., 1708., 1808., 1908., 2008, - 109., 209., 309., 409., 509., 609., 709., 809., 909., 1009., 1109., 1209., 1309., 1409., 1509., 1609., 1709., 1809., 1909., 2009. - }; - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTTE,"P0P0")); - trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(meshTTE); - array=DataArrayDouble::New(); - array->alloc(meshTTE->getNumberOfCells(),1); - trgField->setArray(array); - std::copy(vals2,vals2+meshTTE->getNumberOfCells(),array->getPointer()); - array->decrRef(); - srcField=remapper.reverseTransferField(trgField,4.220173); - double expected3[40]={ - 550.,550.,551.,552.,553.,550.,550.,554.,555.,556.,550.,550.,554.,555.,556.,550.,550.,557.,558.,559., - 1550.,1550.,1551.,1552.,1553.,1550.,1550.,1554.,1555.,1556.,1550.,1550.,1554.,1555.,1556.,1550.,1550.,1557.,1558.,1559. - }; - for(int i=0;i<40;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],srcField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - srcField->decrRef(); - trgField->decrRef(); - // - double vals3[340]={ - 100., 101., 102., 103., 104., 105., 106., 107., 108., 109., 110., 111., 112., 113., 114., 115., - 200., 201., 202., 203., 204., 205., 206., 207., 208., 209., 210., 211., 212., 213., 214., 215., - 300., 301., 302., 303., 304., 305., 306., 307., 308., 309., 310., 311., 312., 313., 314., 315., - 400., 401., 402., 403., 404., 405., 406., 407., 408., 409., 410., 411., 412., 413., 414., 415., - 500., 501., 502., 503., 504., 505., 506., 507., 508., 509., 510., 511., 512., 513., 514., 515., - 600., 601., 602., 603., 604., 605., 606., 607., 608., 609., 610., 611., 612., 613., 614., 615., - 700., 701., 702., 703., 704., 705., 706., 707., 708., 709., 710., 711., 712., 713., 714., 715., - 800., 801., 802., 803., 804., 805., 806., 807., 808., 809., 810., 811., 812., 813., 814., 815., - 900., 901., 902., 903., 904., 905., 906., 907., 908., 909., 910., 911., 912., 913., 914., 915., - 1000., 1001., 1002., 1003., 1004., 1005., 1006., 1007., 1008., 1009., 1010., 1011., 1012., 1013., 1014., 1015., - 1100., 1101., 1102., 1103., 1104., 1105., 1106., 1107., 1108., 1109., 1110., 1111., 1112., 1113., 1114., 1115., - 1200., 1201., 1202., 1203., 1204., 1205., 1206., 1207., 1208., 1209., 1210., 1211., 1212., 1213., 1214., 1215., - 1300., 1301., 1302., 1303., 1304., 1305., 1306., 1307., 1308., 1309., 1310., 1311., 1312., 1313., 1314., 1315., - 1400., 1401., 1402., 1403., 1404., 1405., 1406., 1407., 1408., 1409., 1410., 1411., 1412., 1413., 1414., 1415., - 1500., 1501., 1502., 1503., 1504., 1505., 1506., 1507., 1508., 1509., 1510., 1511., 1512., 1513., 1514., 1515., - 1600., 1601., 1602., 1603., 1604., 1605., 1606., 1607., 1608., 1609., 1610., 1611., 1612., 1613., 1614., 1615., - 1700., 1701., 1702., 1703., 1704., 1705., 1706., 1707., 1708., 1709., 1710., 1711., 1712., 1713., 1714., 1715., - 1800., 1801., 1802., 1803., 1804., 1805., 1806., 1807., 1808., 1809., 1810., 1811., 1812., 1813., 1814., 1815., - 1900., 1901., 1902., 1903., 1904., 1905., 1906., 1907., 1908., 1909., 1910., 1911., 1912., 1913., 1914., 1915., - 2000., 2001., 2002., 2003., 2004., 2005., 2006., 2007., 2008., 2009., 2010., 2011., 2012., 2013., 2014., 2015., - 116.,216.,316.,416.,516.,616.,716.,816.,916.,1016.,1116.,1216.,1316.,1416.,1516.,1616.,1716.,1816.,1916.,2016. - }; - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTFE,"P0P0")); - trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(meshTFE); - array=DataArrayDouble::New(); - array->alloc(meshTFE->getNumberOfCells(),1); - trgField->setArray(array); - std::copy(vals3,vals3+meshTFE->getNumberOfCells(),array->getPointer()); - array->decrRef(); - srcField=remapper.reverseTransferField(trgField,4.220173); - double expected4[40]={ - 566.,566.,552.5,553.5,554.5,566.,566.,554.5,555.5,556.5,566.,566.,558.5,559.5,560.5,566.,566.,560.5,561.5,562.5, - 1566.,1566.,1552.5,1553.5,1554.5,1566.,1566.,1554.5,1555.5,1556.5,1566.,1566.,1558.5,1559.5,1560.5,1566.,1566.,1560.5,1561.5,1562.5 - }; - for(int i=0;i<40;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],srcField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - srcField->decrRef(); - trgField->decrRef(); - // - meshN2D->decrRef(); - meshTT2D->decrRef(); - meshTF2D->decrRef(); - meshNE->decrRef(); - meshTTE->decrRef(); - meshTFE->decrRef(); - meshN->decrRef(); - meshTT->decrRef(); - meshTF->decrRef(); -} - -void MEDCouplingRemapperTest::testPrepareEx1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - MEDCouplingFieldTemplate *srcFt=MEDCouplingFieldTemplate::New(ON_CELLS); - MEDCouplingFieldTemplate *trgFt=MEDCouplingFieldTemplate::New(ON_CELLS); - srcFt->setMesh(sourceMesh); - trgFt->setMesh(targetMesh); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepareEx(srcFt,trgFt)); - srcFt->decrRef(); - trgFt->decrRef(); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -MEDCouplingUMesh *MEDCouplingRemapperTest::build1DTargetMesh_2() -{ - double targetCoords[20]={ - 0.59,0.09, 0.69,0.19, 0.21,-0.29,0.31,-0.19, 0.45,0.25,0.65,0.45, - -0.2,-0.2,0.11,0.11, 0.25,0.25, 0.45,0.45 - }; - int targetConn[10]={0,1, 2,3, 4,5, 6,7, 8,9}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("my name of mesh 1D 2",1); - targetMesh->allocateCells(5); - for(int i=0;i<5;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingRemapperTest::build2DTargetMesh_3() -{ - double targetCoords[20]={-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, - -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, - -0.6,1.1, -0.1,1.1}; - int targetConn[16]={0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(4); - for(int i=0;i<4;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+4*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingRemapperTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D) -{ - double coords[180]={ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; - - int conn[354]={ - // 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - // 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - // 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58 - }; - int conn2[28]={7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3}; - // - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setMeshDimension(3); - ret->allocateCells(18); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); - // - ret->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(60,3); - std::copy(coords,coords+180,myCoords->getPointer()); - ret->setCoords(myCoords); - // - mesh2D=MEDCouplingUMesh::New(); - mesh2D->setMeshDimension(2); - mesh2D->allocateCells(6); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+4); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+10); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+14); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+18); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+24); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -void MEDCouplingRemapperTest::testPartialTransfer1() -{ - MEDCouplingRemapper remapper; - MEDCouplingUMesh *sourceMesh=build1DTargetMesh_2(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - ptr=array->getPointer(); - std::fill(ptr,ptr+targetMesh->getNumberOfCells(),96.3); - trgField->setArray(array); - array->decrRef(); - remapper.partialTransfer(srcField,trgField); - const double valuesExpected9[5]={10.,8.,7.,96.3,10.}; - const double *values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testBugNonRegression1() -{ - // source - DataArrayDouble *coordsSrc(DataArrayDouble::New()); - const double coordsSrcData[18]={-6.25,3.6084391824351605,264.85199999999998,-6.25,3.6084391824351605,289.05200000000002,-6.2499999999999991,-3.6084391824351618,264.85199999999998,-6.2499999999999991,-3.6084391824351618,289.05200000000002,-1.7763568394002505e-15,4.4408920985006262e-15,264.85199999999998,-1.7763568394002505e-15,4.4408920985006262e-15,289.05200000000002}; - coordsSrc->useArray(coordsSrcData,false,CPP_DEALLOC,6,3); - DataArrayInt *connSrc(DataArrayInt::New()),*connISrc(DataArrayInt::New()); - const int connSrcData[7]={16,2,0,4,3,1,5}; - connSrc->useArray(connSrcData,false,CPP_DEALLOC,7,1); - const int connISrcData[2]={0,7}; - connISrc->useArray(connISrcData,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *srcMesh(MEDCouplingUMesh::New("source",3)); - srcMesh->setCoords(coordsSrc); - srcMesh->setConnectivity(connSrc,connISrc,true); - coordsSrc->decrRef(); connSrc->decrRef(); connISrc->decrRef(); - // target - DataArrayDouble *coordsTrg(DataArrayDouble::New()); -const double coordsTrgData[36]={-2,1.1547005383792521,264.85199999999998,-2,0.57735026918962618,264.85199999999998,-2.5,0.2886751345948132,264.85199999999998,-2.5,1.443375672974065,264.85199999999998,-3.0000000000000004,1.1547005383792526,264.85199999999998,-3.0000000000000004,0.57735026918962662,264.85199999999998,-2,1.1547005383792521,289.05200000000002,-2,0.57735026918962618,289.05200000000002,-2.5,0.2886751345948132,289.05200000000002,-2.5,1.443375672974065,289.05200000000002,-3.0000000000000004,1.1547005383792526,289.05200000000002,-3.0000000000000004,0.57735026918962662,289.05200000000002}; - coordsTrg->useArray(coordsTrgData,false,CPP_DEALLOC,12,3); - DataArrayInt *connTrg=DataArrayInt::New(); - const int connTrgData[44]={31,0,1,2,5,4,3,-1,7,6,9,10,11,8,-1,3,9,6,0,-1,4,10,9,3,-1,5,11,10,4,-1,2,8,11,5,-1,1,7,8,2,-1,0,6,7,1}; - connTrg->useArray(connTrgData,false,CPP_DEALLOC,44,1); - DataArrayInt *connITrg=DataArrayInt::New(); - const int connITrgData[2]={0,44}; - connITrg->useArray(connITrgData,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *trgMesh=MEDCouplingUMesh::New("target",3); - trgMesh->setCoords(coordsTrg); - trgMesh->setConnectivity(connTrg,connITrg,true); - coordsTrg->decrRef(); connTrg->decrRef(); connITrg->decrRef(); - // Go ! - const double valExpected(20.957814771583468); - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(srcMesh,trgMesh,"P0P0")); - std::vector > matrx(remapper.getCrudeMatrix()); - CPPUNIT_ASSERT_EQUAL(1,(int)matrx.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)matrx[0].size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valExpected,matrx[0][0],1e-13); - // - srcMesh->decrRef(); trgMesh->decrRef(); -} - diff --git a/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx b/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx deleted file mode 100644 index 72a4f45fc..000000000 --- a/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDCOUPLINGREMAPPERTEST_HXX__ -#define __MEDCOUPLINGREMAPPERTEST_HXX__ - -#include - -#include -#include - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - - class MEDCouplingRemapperTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE(MEDCouplingRemapperTest); - CPPUNIT_TEST( test2DInterpP0P0_1 ); - CPPUNIT_TEST( test2DInterpP0P0R_1 ); - CPPUNIT_TEST( test1DInterp_1 ); - CPPUNIT_TEST( test2DInterpMultiMethods ); - CPPUNIT_TEST( testMultiDimCombi ); - CPPUNIT_TEST( testNatureOfField ); - CPPUNIT_TEST( testExtruded ); - CPPUNIT_TEST( testExtruded2 ); - CPPUNIT_TEST( testPrepareEx1 ); - CPPUNIT_TEST( testPartialTransfer1 ); - CPPUNIT_TEST( testBugNonRegression1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test2DInterpP0P0_1(); - void test2DInterpP0P0R_1(); - void test1DInterp_1(); - void test2DInterpMultiMethods(); - void testMultiDimCombi(); - void testNatureOfField(); - void testExtruded(); - void testExtruded2(); - void testPrepareEx1(); - void testPartialTransfer1(); - // - void testBugNonRegression1(); - private: - static MEDCouplingUMesh *build1DTargetMesh_2(); - static MEDCouplingUMesh *build2DTargetMesh_3(); - static MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D); - }; -} - -#endif diff --git a/medtool/src/MEDCoupling/Test/TestMEDCoupling.cxx b/medtool/src/MEDCoupling/Test/TestMEDCoupling.cxx deleted file mode 100644 index 0d017ae0d..000000000 --- a/medtool/src/MEDCoupling/Test/TestMEDCoupling.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingBasicsTest1.hxx" -#include "MEDCouplingBasicsTest2.hxx" -#include "MEDCouplingBasicsTest3.hxx" -#include "MEDCouplingBasicsTest4.hxx" -#include "MEDCouplingBasicsTest5.hxx" -#include "MEDCouplingBasicsTestInterp.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest1 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest2 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest3 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest4 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest5 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTestInterp ); - -#include "BasicMainTest.hxx" diff --git a/medtool/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx b/medtool/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx deleted file mode 100644 index cbcb2d22b..000000000 --- a/medtool/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingRemapperTest.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingRemapperTest ); - -#include "BasicMainTest.hxx" diff --git a/medtool/src/MEDCoupling_Swig/CMakeLists.txt b/medtool/src/MEDCoupling_Swig/CMakeLists.txt deleted file mode 100644 index 7b167250c..000000000 --- a/medtool/src/MEDCoupling_Swig/CMakeLists.txt +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -SET_SOURCE_FILES_PROPERTIES(MEDCoupling.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDCoupling.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDCoupling_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -SET (MEDCoupling_SWIG_DPYS_FILES - MEDCouplingCommon.i - MEDCouplingMemArray.i - MEDCouplingFieldDiscretization.i - MEDCouplingFinalize.i - MEDCouplingTypemaps.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ${PROJECT_BINARY_DIR}/doc - ) - -# _ABR_ Ensure dependency mechanism on all SWIG files and headers -SET (SWIG_MODULE_MEDCoupling_EXTRA_DEPS ${MEDCoupling_SWIG_DPYS_FILES} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -# SWIG must run after the doc if we want to have the docstrings extracted from Doxygen -# into the Python module: -IF(MEDCOUPLING_BUILD_DOC) - LIST(APPEND SWIG_MODULE_MEDCoupling_EXTRA_FLAGS -DWITH_DOCSTRINGS) - LIST(APPEND SWIG_MODULE_MEDCoupling_EXTRA_DEPS - ${PROJECT_BINARY_DIR}/doc/MEDCoupling_doc.i - swig_ready) -ENDIF() - -SWIG_ADD_MODULE(MEDCoupling python MEDCoupling.i) -SWIG_LINK_LIBRARIES(MEDCoupling ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medcoupling) - -SET_SOURCE_FILES_PROPERTIES(MEDCouplingRemapper.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDCouplingRemapper.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDCouplingRemapper_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -# _ABR_ Ensure dependency mechanism on all SWIG files and headers -SET (SWIG_MODULE_MEDCouplingRemapper_EXTRA_DEPS ${MEDCoupling_SWIG_DPYS_FILES} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -SWIG_ADD_MODULE(MEDCouplingRemapper python MEDCouplingRemapper.i) -SWIG_LINK_LIBRARIES(MEDCouplingRemapper ${PYTHON_LIBRARIES} medcouplingremapper) - -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDCouplingRemapper PROPERTIES DEBUG_OUTPUT_NAME _MEDCouplingRemapper_d) - SET_TARGET_PROPERTIES(_MEDCoupling PROPERTIES DEBUG_OUTPUT_NAME _MEDCoupling_d) -ENDIF(WIN32) -INSTALL(TARGETS ${SWIG_MODULE_MEDCoupling_REAL_NAME} ${SWIG_MODULE_MEDCouplingRemapper_REAL_NAME} DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) - -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling.py ${CMAKE_CURRENT_BINARY_DIR}/MEDCouplingRemapper.py DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) - -INSTALL(FILES MEDCoupling.i MEDCouplingCommon.i MEDCouplingRefCountObject.i MEDCouplingMemArray.i MEDCouplingFieldDiscretization.i MEDCouplingTimeDiscretization.i MEDCouplingFinalize.i MEDCouplingRemapper.i MEDCouplingTypemaps.i MEDCouplingDataArrayTypemaps.i DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) -INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) -INSTALL(FILES MEDCouplingExamplesTest.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) - -ADD_TEST(MEDCouplingBasicsTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingBasicsTest.py) -ADD_TEST(MEDCouplingExamplesTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingExamplesTest.py) -ADD_TEST(MEDCouplingRemapperTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingRemapperTest.py) - -IF(NUMPY_FOUND) - ADD_TEST(MEDCouplingNumPyTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingNumPyTest.py) - ADD_TEST(MEDCouplingPickleTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingPickleTest.py) -ENDIF(NUMPY_FOUND) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDCoupling_Swig) -INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py MEDCouplingExamplesTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/MEDCoupling_Swig/CTestTestfileInstall.cmake b/medtool/src/MEDCoupling_Swig/CTestTestfileInstall.cmake deleted file mode 100644 index c1f34cca8..000000000 --- a/medtool/src/MEDCoupling_Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(MEDCouplingBasicsTest python MEDCouplingBasicsTest.py) -SET_TESTS_PROPERTIES(MEDCouplingBasicsTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDCouplingExamplesTest python MEDCouplingExamplesTest.py) -SET_TESTS_PROPERTIES(MEDCouplingExamplesTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDCouplingRemapperTest python MEDCouplingRemapperTest.py) -SET_TESTS_PROPERTIES(MEDCouplingRemapperTest PROPERTIES LABELS "${COMPONENT_NAME}") - -# if numpy is used -ADD_TEST(MEDCouplingNumPyTest python MEDCouplingNumPyTest.py) -SET_TESTS_PROPERTIES(MEDCouplingNumPyTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDCouplingPickleTest python MEDCouplingPickleTest.py) -SET_TESTS_PROPERTIES(MEDCouplingPickleTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/MEDCoupling_Swig/MEDCoupling.i b/medtool/src/MEDCoupling_Swig/MEDCoupling.i deleted file mode 100644 index d6450452e..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCoupling.i +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include "MEDCouplingCommon.i" - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____imod___(self, self, *args) -def ParaMEDMEMDenseMatrixIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DenseMatrix____iadd___(self, self, *args) -def ParaMEDMEMDenseMatrixIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DenseMatrix____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCoupling1DGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCoupling1SGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingCurveLinearMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingCMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingIMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingExtrudedMesh____new___(cls,args) -%} - -%include "MEDCouplingFinalize.i" diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/medtool/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py deleted file mode 100644 index 18118dc75..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ /dev/null @@ -1,16776 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDCoupling import * -import unittest -from math import pi,e,sqrt,cos,sin -from datetime import datetime -from MEDCouplingDataForTest import MEDCouplingDataForTest -import rlcompleter,readline # this line has to be here, to ensure a usability of MEDCoupling/MEDLoader. B4 removing it please notify to anthony.geay@cea.fr - -class MEDCouplingBasicsTest(unittest.TestCase): - def testArray2(self): - arr=DataArrayDouble.New() - arr.setValues([12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.],3,4) - arr.setInfoOnComponent(0,"ggg"); - arr.setInfoOnComponent(1,"hhhh"); - arr.setInfoOnComponent(2,"jj"); - arr.setInfoOnComponent(3,"kkkkkk"); - arr2=arr.convertToIntArr(); - arr3=arr2.convertToDblArr(); - self.assertTrue(arr.isEqual(arr3,1e-14)) - pass - - def testArray3(self): - arr1=DataArrayInt.New(); - arr1Ref=[0,10,1,11,2,12,3,13,4,14,5,15,6,16] - arr1.setValues(arr1Ref,7,2); - self.assertEqual(7,arr1.getNumberOfTuples()); - self.assertEqual(2,arr1.getNumberOfComponents()); - self.assertEqual(arr1Ref,list(arr1.getValues())); - arr2=arr1.substr(3); - self.assertEqual(4,arr2.getNumberOfTuples()); - self.assertEqual(2,arr2.getNumberOfComponents()); - self.assertEqual(arr1Ref[6:],list(arr2.getValues())); - arr3=arr1.substr(2,5); - self.assertEqual(3,arr3.getNumberOfTuples()); - self.assertEqual(2,arr3.getNumberOfComponents()); - self.assertEqual(arr1Ref[4:10],list(arr3.getValues())); - # - arr4=DataArrayDouble.New(); - arr4Ref=[0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5] - arr4.setValues(arr4Ref,7,2); - self.assertEqual(7,arr4.getNumberOfTuples()); - self.assertEqual(2,arr4.getNumberOfComponents()); - tmp=arr4.getValues() - for i in xrange(14): - self.assertTrue(abs(arr4Ref[i]-tmp[i])<1e-14); - pass - arr5=arr4.substr(3); - self.assertEqual(4,arr5.getNumberOfTuples()); - self.assertEqual(2,arr5.getNumberOfComponents()); - tmp=arr5.getValues() - for i in xrange(8): - self.assertTrue(abs(arr4Ref[6+i]-tmp[i])<1e-14); - pass - arr6=arr4.substr(2,5); - self.assertEqual(3,arr6.getNumberOfTuples()); - self.assertEqual(2,arr6.getNumberOfComponents()); - tmp=arr6.getValues() - for i in xrange(6): - self.assertTrue(abs(arr4Ref[4+i]-tmp[i])<1e-14); - pass - pass - - def testMesh(self): - tab4=[1, 2, 8, 7, 2, 3, 9, 8, 3, - 4, 10, 9, 4, 5, 11, 10, 5, - 0, 6, 11, 0, 1, 7, 6 ] - nbOfNodes=12 - nbOfCells=6 - coords=[ 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, - -0.305, 0.09662000000000001, -1.832979297858306e-18, -0.305, 0.120775, 0.04183768725682623, - -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, 0.08367537451365246, - -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, - 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, - 0.08367537451365245, -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863 ] - self.assertEqual(MEDCouplingMesh.GetNumberOfNodesOfGeometricType(NORM_TRI3),3) - self.assertTrue(MEDCouplingMesh.IsStaticGeometricType(NORM_TRI3)) - self.assertTrue(MEDCouplingMesh.IsLinearGeometricType(NORM_TRI3)) - self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_TRI3),2) - self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_TRI3),"NORM_TRI3") - self.assertRaises(InterpKernelException,MEDCouplingMesh.GetNumberOfNodesOfGeometricType,NORM_POLYGON) - self.assertTrue(not MEDCouplingMesh.IsStaticGeometricType(NORM_POLYGON)) - self.assertTrue(MEDCouplingMesh.IsLinearGeometricType(NORM_POLYGON)) - self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_POLYGON),2) - self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_POLYGON),"NORM_POLYGON") - self.assertEqual(MEDCouplingMesh.GetNumberOfNodesOfGeometricType(NORM_TRI6),6) - self.assertTrue(MEDCouplingMesh.IsStaticGeometricType(NORM_TRI6)) - self.assertTrue(not MEDCouplingMesh.IsLinearGeometricType(NORM_TRI6)) - self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_TRI6),2) - self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_TRI6),"NORM_TRI6") - mesh=MEDCouplingUMesh.New() - mesh.setMeshDimension(2) - mesh.allocateCells(8); - mesh.setName("mesh1") - self.assertTrue(mesh.getName()=="mesh1") - for i in range(nbOfCells): - mesh.insertNextCell(NORM_QUAD4,4,tab4[4*i:4*(i+1)]); - pass - mesh.finishInsertingCells() - self.assertTrue(mesh.getNumberOfCells()==nbOfCells) - self.assertTrue(mesh.getNodalConnectivity().getNbOfElems()==30) - self.assertTrue(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1) - myCoords=DataArrayDouble.New() - myCoords.setValues(coords,nbOfNodes,3); - self.assertTrue(myCoords.getIJ(3,2)==-0.305) - mesh.setCoords(myCoords); - mesh.checkCoherency(); - self.assertTrue(mesh.getAllGeoTypes()==[4]) - myFalseConn=DataArrayInt.New() - myFalseConn.setValues(tab4,6,4) - self.assertTrue(myFalseConn.getIJ(1,1)==3) - # - field=MEDCouplingFieldDouble.New(ON_CELLS) - field.setMesh(mesh) - field.setNature(Integral) - myCoords=DataArrayDouble.New() - sampleTab=[] - for i in range(nbOfCells*9): - sampleTab.append(float(i)) - myCoords.setValues(sampleTab,nbOfCells,9); - field.setArray(myCoords) - self.assertTrue(3==mesh.getSpaceDimension()) - field.checkCoherency() - mesh2=mesh.clone(False) - mesh3=mesh.clone(True) - mesh3=0 - mesh2=0 - ## deep full recursively copy of field -> both field and mesh underneath copied - field2=field.clone(True) - field2.setMesh(field.getMesh().clone(True)) - mesh3=mesh.clone(True) - field3=mesh3.fillFromAnalytic(ON_CELLS,2,"x*IVec+(y+z)*JVec") - field3.applyFunc("u*u*u+cos(u)") - pass - - def testMeshPointsCloud(self): - targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, - -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(0); - targetMesh.allocateCells(8); - targetMesh.insertNextCell(NORM_POINT1,1,[0]); - targetMesh.insertNextCell(NORM_POINT1,1,[1]); - targetMesh.insertNextCell(NORM_POINT1,1,[2]); - targetMesh.insertNextCell(NORM_POINT1,1,[3]); - targetMesh.insertNextCell(NORM_POINT1,1,[4]); - targetMesh.insertNextCell(NORM_POINT1,1,[5]); - targetMesh.insertNextCell(NORM_POINT1,1,[7]); - targetMesh.insertNextCell(NORM_POINT1,1,[6]); - targetMesh.finishInsertingCells(); - self.assertRaises(InterpKernelException,targetMesh.checkCoherency); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,3); - targetMesh.setCoords(myCoords); - self.assertEqual(targetMesh.getSpaceDimension(),3) - self.assertEqual(targetMesh.getNumberOfCells(),8) - self.assertEqual(targetMesh.getNumberOfNodes(),9) - self.assertEqual(targetMesh.getMeshDimension(),0) - pass - - def testMeshM1D(self): - meshM1D=MEDCouplingUMesh.New(); - self.assertRaises(InterpKernelException,meshM1D.getMeshDimension); - self.assertRaises(InterpKernelException,meshM1D.getNumberOfNodes); - self.assertRaises(InterpKernelException,meshM1D.getNumberOfCells); - self.assertRaises(InterpKernelException,meshM1D.setMeshDimension,-2) - self.assertRaises(InterpKernelException,meshM1D.setMeshDimension,-10) - meshM1D.setMeshDimension(-1); - meshM1D.checkCoherency(); - self.assertEqual(meshM1D.getMeshDimension(),-1); - self.assertEqual(meshM1D.getNumberOfCells(),1); - self.assertRaises(InterpKernelException,meshM1D.getNumberOfNodes); - self.assertRaises(InterpKernelException,meshM1D.getSpaceDimension); - cpy=meshM1D.clone(True); - self.assertTrue(cpy.isEqual(meshM1D,1e-12)); - fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); - fieldOnCells.setMesh(meshM1D); - array=DataArrayDouble.New(); - array.setValues(6*[7.],1,6); - fieldOnCells.setArray(array); - fieldOnCells.checkCoherency(); - pass - - def testDeepCopy(self): - array=DataArrayDouble.New(); - array.setValues(5*3*[7.],5,3); - self.assertEqual(array.getIJ(3,2),7.); - array2=array.deepCpy(); - self.assertEqual(array2.getIJ(3,2),7.) - # - array3=DataArrayInt.New(); - array3.setValues(5*3*[17],5,3); - self.assertEqual(array3.getIJ(3,2),17); - array4=array3.deepCpy(); - self.assertEqual(array4.getIJ(3,2),17); - pass - - def testRevNodal(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1() - revNodal,revNodalIndx=mesh.getReverseNodalConnectivity(); - revNodalExpected=[0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4]; - revNodalIndexExpected=[0,1,3,5,7,12,14,15,17,18]; - self.assertEqual(revNodal.getNbOfElems(),18) - self.assertEqual(revNodalIndx.getNbOfElems(),10) - self.assertEqual(list(revNodal.getValues()),revNodalExpected) - self.assertEqual(list(revNodalIndx.getValues()),revNodalIndexExpected) - pass - - def testConvertToPolyTypes(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - elts=[1,3]; - mesh.convertToPolyTypes(elts); - mesh.checkCoherency(); - self.assertEqual(5,mesh.getNumberOfCells()); - self.assertEqual(23,mesh.getNodalConnectivity().getNumberOfTuples()); - expected1=[4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4] - self.assertEqual(expected1,list(mesh.getNodalConnectivity().getValues())); - # - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh.convertToPolyTypes(elts); - mesh.checkCoherency(); - self.assertEqual(8,mesh.getNumberOfCells()); - self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); - mesh.convertToPolyTypes(elts); - mesh.checkCoherency(); - self.assertEqual(8,mesh.getNumberOfCells()); - self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); - pass - - def testDescConn2D(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(1,mesh2.getMeshDimension()); - self.assertEqual(13,mesh2.getNumberOfCells()); - self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); - self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); - self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); - self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); - expected1=[0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9]; - self.assertEqual(expected1,list(desc.getValues())); - expected2=[0,4,7,10,14,18]; - self.assertEqual(expected2,list(descIndx.getValues())); - expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18]; - self.assertEqual(expected3,list(revDescIndx.getValues())); - expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]; - self.assertEqual(expected4,list(revDesc.getValues())); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39]; - self.assertEqual(expected5,list(connIndex.getValues())); - expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5]; - self.assertEqual(expected6,list(conn.getValues())); - # - eltsV=[1,3]; - mesh.convertToPolyTypes(eltsV); - mesh.checkCoherency(); - # - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - # - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(1,mesh2.getMeshDimension()); - self.assertEqual(13,mesh2.getNumberOfCells()); - self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); - self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); - self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); - self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); - self.assertEqual(expected1,list(desc.getValues())); - self.assertEqual(expected2,list(descIndx.getValues())); - self.assertEqual(expected3,list(revDescIndx.getValues())); - self.assertEqual(expected4,list(revDesc.getValues())); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - self.assertEqual(expected5,list(connIndex.getValues())); - self.assertEqual(expected6,list(conn.getValues())); - pass - - def testDescConn3D(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - # - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(2,mesh2.getMeshDimension()); - self.assertEqual(36,mesh2.getNumberOfCells()); - self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); - self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); - self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); - self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); - expected1=[0, 6, 12, 18, 24, 30, 36, 42, 48] - expected2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30] - expected3=[0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48] - expected4=[0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7] - expected5=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180] - expected6=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, - 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] - expected7=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, - 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] - - self.assertEqual(expected1,list(descIndx.getValues())); - self.assertEqual(expected2,list(desc.getValues())); - self.assertEqual(expected3,list(revDescIndx.getValues())); - self.assertEqual(expected4,list(revDesc.getValues())); - self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); - self.assertEqual(expected6,list(mesh2.getNodalConnectivity().getValues())); - # - eltsV=[1,3] - mesh.convertToPolyTypes(eltsV); - mesh.checkCoherency(); - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(2,mesh2.getMeshDimension()); - self.assertEqual(36,mesh2.getNumberOfCells()); - self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); - self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); - self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); - self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); - self.assertEqual(expected1,list(descIndx.getValues())); - self.assertEqual(expected2,list(desc.getValues())); - self.assertEqual(expected3,list(revDescIndx.getValues())); - self.assertEqual(expected4,list(revDesc.getValues())); - self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); - self.assertEqual(expected7,list(mesh2.getNodalConnectivity().getValues())); - pass - - def testFindBoundaryNodes(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - boundaryNodes=mesh.findBoundaryNodes(); - expected1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]; - self.assertEqual(expected1,boundaryNodes.getValues()); - pass - - def testBoundaryMesh(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh2=mesh.buildBoundaryMesh(False); - self.assertEqual(24,mesh2.getNumberOfCells()); - self.assertEqual(26,mesh2.getNumberOfNodes()); - pass - - def testBuildPartOfMySelf(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh.setName("Toto"); - tab1=[0,4] - tab2=[0,2,3] - # - subMesh=mesh.buildPart(tab1) - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - subMesh=mesh.buildPartOfMySelf(tab1,True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - name=subMesh.getName(); - self.assertEqual(2,len(mesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,mesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,mesh.getAllGeoTypes()[1]); - self.assertEqual(1,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(name,"Toto"); - self.assertEqual(2,subMesh.getNumberOfCells()); - subConn=[4,0,3,4,1,4,7,8,5,4]; - subConnIndex=[0,5,10]; - self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn[0:10],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex[0:3],list(subMesh.getNodalConnectivityIndex().getValues())); - # - subMesh=mesh.buildPartOfMySelf(tab2[0:3],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)); - name=subMesh.getName(); - self.assertEqual(2,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); - self.assertEqual(name,"Toto"); - self.assertEqual(3,subMesh.getNumberOfCells()); - subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3] - subConnIndex2=[0,5,9,14] - self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); - dd=DataArrayInt.New() - dd.alloc(3,1) - dd.iota(0) - dd.setName("coucou") - subMesh=subMesh.buildPartOfMySelf(dd,True); - self.assertEqual("coucou",subMesh.getName()); - pass - - def testBuildPartOfMySelfNode(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - tab1=[5,7,8,4] - subMesh=mesh.buildPartOfMySelfNode(tab1[0:4],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(1,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(1,subMesh.getNumberOfCells()); - self.assertEqual(5,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(2,subMesh.getNodalConnectivityIndex().getNbOfElems()); - subConn=[4,7,8,5,4] - subConnIndex=[0,5] - self.assertEqual(subConn[0:5],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex[0:2],list(subMesh.getNodalConnectivityIndex().getValues())); - # - ddd=DataArrayInt.New() - ddd.setValues(tab1[0:2],2,1) - ddd.setName("ddd") - subMesh=mesh.buildPartOfMySelfNode(ddd,False); - self.assertEqual("ddd",subMesh.getName()) - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(2,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); - self.assertEqual(3,subMesh.getNumberOfCells()); - self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); - subConn2=[3,4,5,2,4,6,7,4,3,4,7,8,5,4] - subConnIndex2=[0,4,9,14] - self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); - #testing the case where length of tab2 is greater than max number of node per cell. - tab2=[0,3,2,1,4,5,6] - subMesh=mesh.buildPartOfMySelfNode(tab2[0:7],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(2,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); - self.assertEqual(3,subMesh.getNumberOfCells()); - pass - - def testZipCoords(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertEqual(2,len(mesh.getAllGeoTypes())); - self.assertEqual(2,mesh.getSpaceDimension()); - self.assertEqual(9,mesh.getNumberOfNodes()); - self.assertEqual(5,mesh.getNumberOfCells()); - oldConn=mesh.getNodalConnectivity().getValues()[0:mesh.getNodalConnectivity().getNbOfElems()]; - oldConnIndex=mesh.getNodalConnectivityIndex().getValues()[0:mesh.getNumberOfCells()+1] - oldCoords=mesh.getCoords(); - mesh.zipCoords(); - self.assertEqual(2,len(mesh.getAllGeoTypes())); - self.assertEqual(2,mesh.getSpaceDimension()); - self.assertEqual(9,mesh.getNumberOfNodes()); - self.assertEqual(5,mesh.getNumberOfCells()); - self.assertEqual(mesh.getCoords().getValues()[0:2*9],oldCoords.getValues()); - self.assertEqual(list(oldConn),list(mesh.getNodalConnectivity().getValues())); - self.assertEqual(list(oldConnIndex),list(mesh.getNodalConnectivityIndex().getValues())); - # - tab1=[0,4] - subMesh=mesh.buildPartOfMySelf(tab1,True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - traducer=subMesh.zipCoordsTraducer(); - expectedTraducer=[0, 1, -1, 2, 3, 4, -1, 5, 6] - self.assertEqual(expectedTraducer,list(traducer.getValues())); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(2,subMesh.getNumberOfCells()); - subConn=[4,0,2,3,1,4,5,6,4,3] - subConnIndex=[0,5,10] - self.assertEqual(7,subMesh.getNumberOfNodes()); - self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); - # - subMesh=mesh.buildPartOfMySelf(tab1,False); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(2,subMesh.getNumberOfCells()); - self.assertEqual(7,subMesh.getNumberOfNodes()); - self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); - pass - - def testZipConnectivity(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m3=m2.buildPartOfMySelf(cells1,True); - self.assertTrue(isinstance(m3,MEDCouplingUMesh)) - m4=MEDCouplingDataForTest.build2DSourceMesh_1(); - m5=MEDCouplingUMesh.MergeUMeshes(m1,m3); - m6=MEDCouplingUMesh.MergeUMeshes(m5,m4); - # - self.assertEqual(10,m6.getNumberOfCells()); - self.assertEqual(22,m6.getNumberOfNodes()); - (arr,areNodesMerged,newNbOfNodes)=m6.mergeNodes(1e-13); - self.assertTrue(areNodesMerged); - self.assertEqual(10,m6.getNumberOfCells()); - self.assertEqual(9,m6.getNumberOfNodes()); - # - arr=m6.zipConnectivityTraducer(0); - self.assertEqual(7,m6.getNumberOfCells()); - m7=m6.clone(True); - arr=m6.zipConnectivityTraducer(0); - self.assertTrue(m7.isEqual(m6,1e-12)); - self.assertEqual(7,m6.getNumberOfCells()); - pass - - def testEqualMesh(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - self.assertTrue(mesh1.isEqual(mesh1,1e-12)); - # - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - pt=mesh2.getCoords().getValues(); - tmp=pt[1] - mesh2.getCoords().setIJ(0,1,5.999); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh2.getCoords().setIJ(0,1,tmp); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - pt2=mesh1.getNodalConnectivity().getValues(); - mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])+1); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - pt2=mesh1.getNodalConnectivityIndex().getValues(); - mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1]+1)); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1])); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - tmp3=mesh1.getName(); - mesh1.setName("lllll"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh1.setName(tmp3); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - tmp3=mesh2.getCoords().getInfoOnComponent(1); - mesh2.getCoords().setInfoOnComponent(1,"kkkkkk"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh2.getCoords().setInfoOnComponent(1,tmp3); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - pass - - def testEqualFieldDouble(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - fieldOnCells1.setMesh(mesh1); - fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - fieldOnCells2.setMesh(mesh2); - # - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - fieldOnNodes1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnNodes1,1e-12,1e-15)); - self.assertTrue(not fieldOnNodes1.isEqual(fieldOnCells1,1e-12,1e-15)); - # - fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - self.assertEqual(fieldOnCells2.getMesh(),None) # to check that convertMesh wrapping do not raise but return Py_None - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1.setTime(4.,6,7); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setTime(4.,6,7); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1.setName("Power"); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setName("Power"); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - fieldOnCells1.setMesh(mesh1); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setMesh(mesh1); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr=DataArrayDouble.New(); - arr.setName("popo"); - arr.setValues(mesh1.getNumberOfCells()*3*[6.],mesh1.getNumberOfCells(),3); - fieldOnCells1.setArray(arr); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setArray(arr); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - arr2=arr.deepCpy(); - fieldOnCells2.setArray(arr2); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr.setIJ(1,2,6.1); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr.setIJ(1,2,6.); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr2.setName("popo2"); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - arr2.setName("popo"); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - arr2.setInfoOnComponent(2,"jjj"); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr.setInfoOnComponent(2,"jjj"); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - pass - - def testNatureChecking(self): - field=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - field.setNature(Integral); - field.setNature(ConservativeVolumic); - field.setNature(IntegralGlobConstraint); - field=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - field.setNature(ConservativeVolumic); - self.assertRaises(InterpKernelException,field.setNature,Integral); - self.assertRaises(InterpKernelException,field.setNature,IntegralGlobConstraint); - pass - - def testNatureOperations(self): - """ Check nature constraints on field operations """ - m = MEDCouplingCMesh() - m.setCoordsAt(0, DataArrayDouble([1.0,2.0,3.0])) - m.setCoordsAt(1, DataArrayDouble([1.0,2.0,3.0])) - m = m.buildUnstructured() - f1, f2 = MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME), MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME) - f1.setNature(Integral) - f2.setNature(ConservativeVolumic) - self.assertEqual(Integral, f1.getNature()) - self.assertEqual(ConservativeVolumic, f2.getNature()) - - da = DataArrayDouble([1.0,2.0,3.0,4.0]) - f1.setMesh(m); f2.setMesh(m) - f1.setArray(da); f2.setArray(da.deepCpy()) - # All this should complain about nature: - self.assertRaises(InterpKernelException, f1.__add__, f2) - self.assertRaises(InterpKernelException, f1.__iadd__, f2) - self.assertRaises(InterpKernelException, f1.__sub__, f2) - self.assertRaises(InterpKernelException, f1.__isub__, f2) - self.assertRaises(InterpKernelException, f1.__radd__, f2) - self.assertRaises(InterpKernelException, f1.__rsub__, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.AddFields, f1, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.SubstractFields, f1, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MaxFields, f1, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MinFields, f1, f2) - # Not those ones: - f3 = MEDCouplingFieldDouble.MultiplyFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1*f2 - self.assertEqual(NoNature, f3.getNature()) - f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp *= f2 - self.assertEqual(NoNature, f1Tmp.getNature()) - f3 = MEDCouplingFieldDouble.DivideFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1/f2 - self.assertEqual(NoNature, f3.getNature()) - f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp /= f2 - self.assertEqual(NoNature, f1Tmp.getNature()) -# f3 = MEDCouplingFieldDouble.PowFields(f1,f2) -# self.assertEqual(NoNature, f3.getNature()) - f3 = f1**f2 - self.assertEqual(NoNature, f3.getNature()) - f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp **= f2 - self.assertEqual(NoNature, f1Tmp.getNature()) - f3 = MEDCouplingFieldDouble.DotFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1.dot(f2) - self.assertEqual(NoNature, f3.getNature()) - - da = DataArrayDouble.Meld([da, da, da]) - f1.setArray(da); f2.setArray(da.deepCpy()) - f3 = MEDCouplingFieldDouble.CrossProductFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1.crossProduct(f2) - - def testBuildSubMeshData(self): - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1() - #check buildSubMesh on field on cells - fieldCells=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - fieldCells.setMesh(targetMesh); - elts=[1,2,4] - ret1,di=fieldCells.buildSubMeshData(elts); - self.assertTrue(isinstance(ret1,MEDCouplingUMesh)) - self.assertEqual(3,ret1.getNumberOfCells()); - self.assertEqual(9,ret1.getNumberOfNodes()); - self.assertEqual(3,di.getNumberOfTuples()); - self.assertEqual(1,di.getNumberOfComponents()); - toCheck=di.getValues(); - self.assertTrue(elts,toCheck); - #check buildSubMesh on field on nodes - fieldNodes=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - fieldNodes.setMesh(targetMesh); - ret2,di=fieldNodes.buildSubMeshData(elts); - self.assertTrue(isinstance(ret2,MEDCouplingUMesh)) - self.assertEqual(3,ret2.getNumberOfCells()); - self.assertEqual(6,ret2.getNumberOfNodes()); - self.assertEqual(6,di.getNumberOfTuples()); - self.assertEqual(1,di.getNumberOfComponents()); - toCheck=di.getValues(); - expected=[1,2,4,5,7,8] - self.assertEqual(expected,list(toCheck)); - pass - - def testExtrudedMesh1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - ext=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,1); - self.assertEqual(18,ext.getNumberOfCells()); - self.assertEqual(60,ext.getNumberOfNodes()); - ids3D=ext.getMesh3DIds(); - ids3DExpected=[5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12] - self.assertEqual(18,ids3D.getNumberOfTuples()); - self.assertEqual(1,ids3D.getNumberOfComponents()); - self.assertEqual(ids3DExpected,list(ids3D.getValues())); - mesh1D=ext.getMesh1D(); - self.assertEqual(4,mesh1D.getNumberOfNodes()); - self.assertEqual(3,mesh1D.getNumberOfCells()); - mesh1DExpected=[0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, - 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, - 2, 0.66666666666666663, 1.4583333333333333, 3] - mesh1DCoords=mesh1D.getCoords(); - self.assertEqual(4,mesh1DCoords.getNumberOfTuples()); - self.assertEqual(3,mesh1DCoords.getNumberOfComponents()); - self.assertEqual(mesh1DExpected,mesh1DCoords.getValues()); - conn1D=mesh1D.getNodalConnectivity(); - self.assertEqual(9,conn1D.getNumberOfTuples()); - self.assertEqual(1,conn1D.getNumberOfComponents()); - conn1DExpected=[1,0,1,1,1,2,1,2,3] - self.assertEqual(conn1DExpected,list(conn1D.getValues())); - pass - - def testExtrudedMesh3(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.changeSpaceDimension(3); - m2=MEDCouplingDataForTest.buildCU1DMesh_U(); - m2.changeSpaceDimension(3); - center=[0.,0.,0.] - vector=[0.,1.,0.] - m2.rotate(center,vector,-pi/2.); - m3=m1.buildExtrudedMesh(m2,0); - # - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(15,m4.getNumberOfCells()); - self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); - self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); - m3DIds=m4.getMesh3DIds().getValues(); - self.assertEqual(range(15),list(m3DIds)); - #some random in cells to check that extrusion alg find it correctly - expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] - m3.renumberCells(expected1,False); - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(15,m4.getNumberOfCells()); - self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); - self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); - m3DIds=m4.getMesh3DIds().getValues(); - self.assertEqual(expected1,list(m3DIds)); - #play with polygons and polyedrons - cells=[2,3] - m1.convertToPolyTypes(cells); - m3=m1.buildExtrudedMesh(m2,0); - self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(0)); - self.assertEqual(NORM_PENTA6,m3.getTypeOfCell(1)); - self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(2)); - self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(3)); - self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(4)); - m3.renumberCells(expected1,False); - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(15,m4.getNumberOfCells()); - self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); - self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); - m3DIds=m4.getMesh3DIds().getValues(); - self.assertEqual(expected1,list(m3DIds)); - pass - - def testExtrudedMesh4(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells=[2,4]; - m1.convertToPolyTypes(cells); - m1.changeSpaceDimension(3); - m2=MEDCouplingDataForTest.buildCU1DMesh_U(); - m2.changeSpaceDimension(3); - center=[0.,0.,0.] - vector=[0.,1.,0.] - m2.rotate(center,vector,-pi/2.); - m1.zipCoords() - m3=m1.buildExtrudedMesh(m2,0); - expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] - rexpected1=[3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12] - m3.renumberCells(expected1,False); - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(0)); - self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(1)); - self.assertEqual(NORM_POLYHED,m4.getTypeOfCell(2)); - self.assertEqual(NORM_PENTA6,m4.getTypeOfCell(7)); - f=m4.getMeasureField(True); - arr=f.getArray(); - self.assertEqual(15,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - arrPtr=arr.getValues(); - expected2=[0.075,0.0375,0.0375,0.075,0.075, - 0.1125,0.05625,0.05625,0.1125,0.1125, - 0.0625,0.03125,0.03125,0.0625,0.0625] - for i in xrange(15): - self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],16); - pass - m5=m4.build3DUnstructuredMesh(); - m5.zipCoords() - self.assertTrue(m5.isEqual(m3,1e-12)); - f=m5.getMeasureField(True); - f.setMesh(m4) - self.assertTrue(isinstance(f.getMesh(),MEDCouplingExtrudedMesh)) - arr=f.getArray(); - arrPtr=arr.getValues(); - for i in xrange(15): - self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],15); - pass - pass - - def testFindCommonNodes(self): - targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - comm,commI=targetMesh.findCommonNodes(1e-10,-1); - self.assertEqual(1,commI.getNumberOfTuples()); - self.assertEqual(0,comm.getNumberOfTuples()); - o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); - self.assertEqual(27,newNbOfNodes); - self.assertEqual(27,o2n.getNumberOfTuples()); - o2nExp1=range(27) - self.assertEqual(o2nExp1,list(o2n.getValues())); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - self.assertEqual(31,targetMesh.getNumberOfNodes()); - comm,commI=targetMesh.findCommonNodes(1e-10);# testing default parameter - self.assertEqual(3,commI.getNumberOfTuples()); - self.assertEqual(6,comm.getNumberOfTuples()); - commExpected=[1,27,28,29,23,30] - commIExpected=[0,4,6] - self.assertEqual(commExpected,list(comm.getValues())); - self.assertEqual(commIExpected,list(commI.getValues())); - o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); - self.assertEqual(31,o2n.getNumberOfTuples()); - self.assertEqual(27,newNbOfNodes); - o2nExp2=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26,1,1,1,23] - self.assertEqual(o2nExp2,list(o2n.getValues())); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - time=targetMesh.getTimeOfThis(); - o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); - targetMesh.updateTime(); - self.assertEqual(time,targetMesh.getTimeOfThis()); - self.assertTrue(not areNodesMerged); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - time=targetMesh.getTimeOfThis(); - o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); - targetMesh.updateTime(); - self.assertTrue(time!=targetMesh.getTimeOfThis()); - self.assertTrue(areNodesMerged); - connExp=[18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, - 18,4,5,8,7,13,14,17,16, - 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, - 18,13,14,17,16,22,23,26,25] - self.assertEqual(72,targetMesh.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(connExp,list(targetMesh.getNodalConnectivity().getValues())); - self.assertEqual(27,targetMesh.getCoords().getNumberOfTuples()); - coordsExp=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , - 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., - 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , - 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. - , 0., 50., 200., 50., 50., 200. , 200., 50., 200., - 0., 200., 200., 50., 200., 200. , 200., 200., 200. ] - self.assertEqual(coordsExp,targetMesh.getCoords().getValues()); - # 2D - targetMesh=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); - self.assertEqual(18,targetMesh.getNumberOfNodes()); - time=targetMesh.getTimeOfThis(); - o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); - self.assertTrue(time!=targetMesh.getTimeOfThis()); - self.assertTrue(areNodesMerged); - self.assertEqual(9,targetMesh.getNumberOfNodes()); - connExp2=[4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3] - self.assertEqual(23,targetMesh.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(connExp2,list(targetMesh.getNodalConnectivity().getValues())); - coordsExp2=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7] - self.assertEqual(9,targetMesh.getCoords().getNumberOfTuples()); - self.assertEqual(coordsExp2,targetMesh.getCoords().getValues()); - pass - - def testCheckButterflyCells(self): - sourceMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - conn=sourceMesh.getNodalConnectivity() - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(1,len(cells)); - self.assertEqual([3],cells.getValues()); - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - # 3D surf - sourceMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - conn=sourceMesh.getNodalConnectivity() - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(1,len(cells)); - self.assertEqual([3],cells.getValues()); - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - pass - - def testMergeMesh1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DSourceMesh_1(); - vec=[1.,0.] - m2.translate(vec); - m3=m1.mergeMyselfWith(m2); - self.assertTrue(isinstance(m3,MEDCouplingUMesh)); - m3.checkCoherency(); - m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); - self.assertTrue(m3.isEqual(m4,1.e-12)); - da,isMerged,newNbOfNodes=m3.mergeNodes(1.e-12); - self.assertEqual(11,m3.getNumberOfNodes()); - self.assertTrue(isMerged); - pass - - def testMergeMeshOnSameCoords1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells=range(5); - m2.convertToPolyTypes(cells); - m1.tryToShareSameCoords(m2,1e-12); - m3=MEDCouplingDataForTest.build2DTargetMesh_1(); - m3.tryToShareSameCoords(m2,1e-12); - meshes=[m1,m2,m3] - m4=MEDCouplingUMesh.MergeUMeshesOnSameCoords(meshes); - m4.checkCoherency(); - self.assertEqual(15,m4.getNumberOfCells()); - cells1=[0,1,2,3,4] - m1_1=m4.buildPartOfMySelf(cells1,True); - m1_1.setName(m1.getName()); - self.assertTrue(m1.isEqual(m1_1,1e-12)); - cells2=[5,6,7,8,9] - m2_1=m4.buildPartOfMySelf(cells2,True); - m2_1.setName(m2.getName()); - self.assertTrue(m2.isEqual(m2_1,1e-12)); - cells3=[10,11,12,13,14] - m3_1=m4.buildPartOfMySelf(cells3,True); - m3_1.setName(m3.getName()); - self.assertTrue(m3.isEqual(m3_1,1e-12)); - pass - - def testMergeField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DSourceMesh_1(); - vec=[1.,0.] - m2.translate(vec); - f1=m1.getMeasureField(True); - f2=m2.getMeasureField(True); - f3=MEDCouplingFieldDouble.MergeFields(f1,f2); - f3.checkCoherency(); - m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); - self.assertTrue(f3.getMesh().isEqual(m4,1.e-12)); - name=f3.getName(); - self.assertEqual(name,"MeasureOfMesh_"); - self.assertEqual(f3.getTypeOfField(),ON_CELLS); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f3.getNumberOfComponents()); - self.assertEqual(7,f3.getNumberOfTuples()); - values=[0.25,0.125,0.125,0.25,0.25,0.5,0.5] - tmp=f3.getArray().getValues(); - self.assertEqual(len(values),len(tmp)) - for i in xrange(7): - self.assertTrue(abs(values[i]-tmp[i])<1e-12) - pass - pass - - def testFillFromAnalytic(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.setTime(3.4,5,6); m.setTimeUnit("us"); - f1=m.fillFromAnalytic(ON_CELLS,1,"x+y"); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - # - f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) - pass - # - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) - pass - values4=f1.accumulate(); - self.assertEqual(2,len(values4)) - self.assertTrue(abs(3.6-values4[0])<1.e-12); - self.assertTrue(abs(7.2-values4[1])<1.e-12); - values4=f1.integral(True); - self.assertEqual(2,len(values4)) - self.assertTrue(abs(0.5-values4[0])<1.e-12); - self.assertTrue(abs(1.-values4[1])<1.e-12); - # - self.assertRaises(InterpKernelException,m.fillFromAnalytic,ON_NODES,1,"1./(x-0.2)"); - pass - - def testFillFromAnalytic2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_CELLS,1,"y+x"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(values1)): - self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); - pass - # - f1=m.fillFromAnalytic(ON_NODES,1,"y+2*x"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(values2)): - self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); - pass - f1=m.fillFromAnalytic(ON_NODES,1,"2.*x+y"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - tmp=f1.getArray().getValues(); - values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - self.assertEqual(len(values2Bis),len(tmp)) - for i in xrange(len(values2Bis)): - self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); - pass - # - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(values3)): - self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); - pass - values4=f1.accumulate(); - self.assertTrue(abs(3.6-values4[0])<1.e-12); - self.assertTrue(abs(7.2-values4[1])<1.e-12); - values4=f1.integral(True); - self.assertTrue(abs(0.5-values4[0])<1.e-12); - self.assertTrue(abs(1.-values4[1])<1.e-12); - pass - - def testApplyFunc(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - f1.applyFunc(1,"x+y"); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - pass - - def testApplyFunc2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - # - f2=f1.clone(True); - self.assertRaises(InterpKernelException, f2.applyFunc, 1, "a+b+c+d"); - self.assertRaises(InterpKernelException, f2.applyFunc, 1, "a/0"); - self.assertRaises(InterpKernelException, f2.applyFunc, "a/0"); - f2.applyFunc("abs(u)^2.4+2*u"); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 5.0423700574830965, 17.435300118916864] - tmp=f2.getArray().getValues(); - self.assertEqual(len(tmp),len(values2)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) - pass - # - f1.applyFunc(1,"x+y"); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] - tmp=f1.getArray().getValues(); - self.assertEqual(len(tmp),len(values1)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - pass - - def testOperationsOnFields(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); - f2=m.fillFromAnalytic(ON_NODES,1,"x+y"); - f1.checkCoherency(); - f2.checkCoherency(); - f3=f1+f2; - f3.checkCoherency(); - self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - values1=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] - tmp=f3.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - # - f3=f1*f2; - f3.checkCoherency(); - self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - values2=[0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96] - tmp=f3.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) - pass - # - f3=f1+f2; - f4=f1-f3; - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); - values3=[0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4] - tmp=f4.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) - pass - # - f3=f1+f2; - f4=f3/f2; - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); - tmp=f4.getArray().getValues(); - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-2.)<1.e-12) - pass - # - f4=f2.buildNewTimeReprFromThis(NO_TIME,False); - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),NO_TIME); - self.assertRaises(InterpKernelException,f1.__add__,f4); - f5=f4.buildNewTimeReprFromThis(ONE_TIME,False); - self.assertEqual(f5.getTypeOfField(),ON_NODES); - self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); - f3=f1+f5; - tmp=f3.getArray().getValues(); - values4=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values4[i])<1.e-12) - pass - # - f4=f2.buildNewTimeReprFromThis(NO_TIME,True); - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),NO_TIME); - self.assertRaises(InterpKernelException,f1.__add__,f4); - f5=f4.buildNewTimeReprFromThis(ONE_TIME,True); - self.assertEqual(f5.getTypeOfField(),ON_NODES); - self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); - f3=f1+f5; - tmp=f3.getArray().getValues(); - values5=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] - self.assertEqual(len(values5),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values5[i])<1.e-12) - pass - pass - - def testOperationsOnFields2(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.setTime(3.4,5,6); m.setTimeUnit("us"); - f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); - f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - f3=f1/f2; - f3.checkCoherency(); - self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] - self.assertEqual(1,f3.getNumberOfComponents()); - self.assertEqual(9,f3.getNumberOfTuples()); - val=f3.getArray().getValues(); - for i in xrange(9): - self.assertTrue(abs(expected1[i]-val[i])<1.e-12); - # - f1=m.buildOrthogonalField(); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - f2=m.fillFromAnalytic(ON_CELLS,1,"x"); - f3=f1*f2; - expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] - val=f3.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected2[i]-val[i])<1.e-12); - pass - # - f3=f2*f1; - val=f3.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected2[i]-val[i])<1.e-12); - pass - pass - - def testOperationsOnFields3(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); - f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - f1/=f2 - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - val=f1.getArray().getValues(); - for i in xrange(9): - self.assertTrue(abs(expected1[i]-val[i])<1.e-12); - pass - # - f1=m.buildOrthogonalField(); - f2=m.fillFromAnalytic(ON_CELLS,1,"x"); - f1*=f2 - expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] - val=f1.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected2[i]-val[i])<1.e-12); - pass - # - f1=m.buildOrthogonalField(); - # to avoid valgrind leaks - # self.assertRaises(InterpKernelException,f2.__imul__,f1); - pass - - def testOperationsOnFields4(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - nbOfCells=m.getNumberOfCells(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1.setMesh(m); - array=DataArrayDouble.New(); - f1.setArray(array); - self.assertRaises(InterpKernelException,f1.setEndArray,array); - self.assertRaises(InterpKernelException,f1.getEndArray); - arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] - arr2=[5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.] - array.setValues(arr1,nbOfCells,3); - f1.setStartTime(2.,0,0); - f1.setEndTime(3.,0,0); - f1.checkCoherency(); - pos=[0.3,-0.2] - res=f1.getValueOn(pos); - self.assertTrue(abs(arr1[3]-res[0])<1.e-12); - self.assertTrue(abs(arr1[4]-res[1])<1.e-12); - self.assertTrue(abs(arr1[5]-res[2])<1.e-12); - res=None - res=f1.getValueOn(pos,2.2); - self.assertTrue(abs(arr1[3]-res[0])<1.e-12); - self.assertTrue(abs(arr1[4]-res[1])<1.e-12); - self.assertTrue(abs(arr1[5]-res[2])<1.e-12); - res=None - self.assertRaises(InterpKernelException,f1.getValueOn,pos,3.2) - f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f2.setMesh(m); - f2.setArray(f1.getArray()); - f2.setStartTime(2.,3,0); - f2.setEndTime(4.,13,0); - self.assertRaises(InterpKernelException,f2.checkCoherency) - array2=DataArrayDouble.New(); - array2.setValues(arr2,nbOfCells,3); - f2.setEndArray(array2); - f2.checkCoherency(); - # - res=None - res=f2.getValueOn(pos,3.21); - self.assertTrue(abs(4.025-res[0])<1.e-12); - self.assertTrue(abs(14.025-res[1])<1.e-12); - self.assertTrue(abs(24.025-res[2])<1.e-12); - f3=f2.clone(True); - self.assertTrue(f2.isEqual(f3,1e-12,1e-12)); - f3.getEndArray().setIJ(0,0,5.001); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-12)); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.1,3,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,3,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,4,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,3,1); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,3,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.1,13,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,13,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,14,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,13,1); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,13,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f4=f2+f2 - res=None - res=f4.getValueOn(pos,3.21); - self.assertTrue(abs(8.05-res[0])<1.e-12); - self.assertTrue(abs(28.05-res[1])<1.e-12); - self.assertTrue(abs(48.05-res[2])<1.e-12); - f4+=f2; - res=None - res=f4.getValueOn(pos,3.21); - self.assertTrue(abs(12.075-res[0])<1.e-12); - self.assertTrue(abs(42.075-res[1])<1.e-12); - self.assertTrue(abs(72.075-res[2])<1.e-12); - pass - - def testMergeNodesOnField(self): - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); - f1.mergeNodes(1e-10); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); - tmp=f1.getArray() - tmp.setIJ(0,0,1000.); - f1.mergeNodes(1e-10); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); - tmp=f1.getArray() - tmp.setIJ(1,0,1000.); - self.assertRaises(InterpKernelException,f1.mergeNodes,1.e-10) - pass - - def testCheckConsecutiveCellTypes(self): - sourceMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertTrue(sourceMesh.checkConsecutiveCellTypes()); - order1=[NORM_TRI3,NORM_QUAD4] - order2=[NORM_QUAD4,NORM_TRI3] - self.assertTrue(not targetMesh.checkConsecutiveCellTypes()); - self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order1)); - self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); - da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order1); - self.assertEqual(5,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - expected1=[2,0,1,3,4] - self.assertTrue(expected1==list(da.getValues())); - da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order2); - self.assertEqual(5,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - expected2=[0,3,4,1,2] - self.assertTrue(expected2==list(da.getValues())); - renumber1=[4,0,1,2,3] - targetMesh.renumberCells(renumber1,False); - self.assertTrue(targetMesh.checkConsecutiveCellTypes()); - self.assertTrue(targetMesh.checkConsecutiveCellTypesAndOrder(order1)); - self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); - pass - - def testRearrange2ConsecutiveCellTypes(self): - m1_1=MEDCouplingDataForTest.build2DSourceMesh_1(); - m2_1=MEDCouplingDataForTest.build2DTargetMesh_1(); - arr1=m1_1.rearrange2ConsecutiveCellTypes(); - m1_2=MEDCouplingDataForTest.build2DSourceMesh_1(); - self.assertTrue(m1_2.isEqual(m1_1,1e-12)); - expected1=[0,1] - self.assertEqual(2,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected1,arr1.getValues()); - expected2=[0,3,4,1,2] - arr1=m2_1.rearrange2ConsecutiveCellTypes(); - self.assertEqual(5,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected2,list(arr1.getValues())); - m2_2=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertEqual(5,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected2,list(arr1.getValues())); - self.assertTrue(not m2_2.isEqual(m2_1,1e-12)); - m2_2.renumberCells(expected2,False); - self.assertTrue(m2_2.isEqual(m2_1,1e-12)); - pass - - def testSplitByType(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - v=m1.splitByType(); - self.assertEqual(3,len(v)); - m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(v); - m2.setName(m1.getName()); - self.assertTrue(m1.isEqual(m2,1.e-12)); - pass - - def testFuseUMeshesOnSameCoords(self): - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m3=m2.buildPartOfMySelf(cells1,True); - self.assertTrue(isinstance(m3,MEDCouplingUMesh)) - cells2=[1,2,4] - m4=m2.buildPartOfMySelf(cells2,True); - self.assertTrue(isinstance(m4,MEDCouplingUMesh)) - cells3=[1,2] - m5=m2.buildPartOfMySelf(cells3,True); - self.assertTrue(isinstance(m5,MEDCouplingUMesh)) - meshes=[m3,m4,m5] - # - m7,corr=MEDCouplingUMesh.FuseUMeshesOnSameCoords(meshes,0); - self.assertEqual(4,m7.getNumberOfCells()); - self.assertEqual(3,len(corr)); - expectedVals1=[3,3,2] - expectedVals2=[[0,1,2],[3,0,2],[3,0]] - for i in xrange(3): - arr=corr[i]; - self.assertEqual(1,arr.getNumberOfComponents()); - nbOfVals=expectedVals1[i]; - self.assertEqual(nbOfVals,arr.getNumberOfTuples()); - vals=arr.getValues(); - self.assertEqual(expectedVals2[i],list(vals)); - pass - arr2,fidsOfGroups=DataArrayInt.MakePartition(corr,m7.getNumberOfCells()); - fidExp=[5,1,3,4] - fidsGrp=[[1,3,5],[3,4,5],[4,5]] - self.assertEqual(3,len(fidsOfGroups)); - self.assertEqual(1,arr2.getNumberOfComponents()); - self.assertEqual(4,arr2.getNumberOfTuples()); - self.assertEqual(fidExp,list(arr2.getValues())); - for i in xrange(3): - nbOfVals=expectedVals1[i]; - self.assertEqual(list(fidsOfGroups[i]),fidsGrp[i]); - pass - pass - - def testFuseUMeshesOnSameCoords2(self): - m1,m2=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - part1=[2,3,6,4,10] - m3=m1.buildPartOfMySelf(part1,True); - part2=[5,6,4,7] - m4=m1.buildPartOfMySelf(part2,True); - meshes=[m1,m3,m3,m4] - m5,corr=MEDCouplingUMesh.FuseUMeshesOnSameCoords(meshes,0); - self.assertEqual(18,m5.getNumberOfCells()); - exp2=[ - [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17], - [2,3,6,4,10], - [2,3,6,4,10], - [5,6,4,7]] - i=0; - for it in corr: - self.assertEqual(exp2[i],list(it.getValues())); - i+=1 - pass - pass - - def testBuildOrthogonalField(self): - targetMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - field=targetMesh.buildOrthogonalField(); - expected=[0.70710678118654746,0.,-0.70710678118654746] - self.assertEqual(5,field.getNumberOfTuples()); - self.assertEqual(3,field.getNumberOfComponents()); - vals=field.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected[i%3]-vals[i])<1e-12); - # testing - targetCoords=[0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.] - targetConn=[0,1,2,3] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(1); - targetMesh.insertNextCell(NORM_QUAD4,targetConn[0:4]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,4,3); - targetMesh.setCoords(myCoords); - field=targetMesh.buildOrthogonalField(); - self.assertEqual(1,field.getNumberOfTuples()); - self.assertEqual(3,field.getNumberOfComponents()); - vals=field.getArray().getValues(); - self.assertTrue(abs(-0.70710678118654746-vals[0])<1e-12); - self.assertTrue(abs(0.-vals[1])<1e-12); - self.assertTrue(abs(0.70710678118654746-vals[2])<1e-12); - pass - - def testGetCellsContainingPoint(self): - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pos=[0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.] - #2D basic - t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12); - self.assertEqual(6,t1.getNumberOfTuples()); - self.assertEqual(1,t1.getNumberOfComponents()); - self.assertEqual(7,t2.getNumberOfTuples()); - self.assertEqual(1,t2.getNumberOfComponents()); - expectedValues1=[0,4,3,0,1,2] - expectedValues2=[0,1,2,3,4,5,6] - self.assertEqual(list(t1.getValues()),expectedValues1); - self.assertEqual(list(t2.getValues()),expectedValues2); - #2D with no help of bounding box. - center=[0.2,0.2] - MEDCouplingPointSet.Rotate2DAlg(center,0.78539816339744830962,6,pos); - targetMesh.rotate(center,0.78539816339744830962); - t1=None - t2=None - t1,t2=targetMesh.getCellsContainingPoints(pos,1e-12); - self.assertEqual(6,t1.getNumberOfTuples()); - self.assertEqual(7,t2.getNumberOfTuples()); - self.assertEqual(list(t1.getValues()),expectedValues1); - self.assertEqual(list(t2.getValues()),expectedValues2); - t1,t2=targetMesh.getCellsContainingPoints(DataArrayDouble.New(pos,6,2),1e-12); - self.assertEqual(6,t1.getNumberOfTuples()); - self.assertEqual(7,t2.getNumberOfTuples()); - self.assertEqual(list(t1.getValues()),expectedValues1); - self.assertEqual(list(t2.getValues()),expectedValues2); - self.assertRaises(InterpKernelException,targetMesh.getCellsContainingPoints,DataArrayDouble.New(pos,4,3),1e-12); - #2D outside - pos1bis=[-0.3303300858899107,-0.11819805153394641] - self.assertEqual(-1,targetMesh.getCellContainingPoint(pos1bis,1e-12)); - #test limits 2D - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pos2=[0.2,-0.05] - t1=None - t1=targetMesh.getCellsContainingPoint(pos2,1e-12) - self.assertEqual(2,len(t1)); - expectedValues3=[0,1] - self.assertEqual(list(t1.getValues()),expectedValues3); - pos3=[0.2,0.2] - t1=None - t1=targetMesh.getCellsContainingPoint(pos3,1e-12); - self.assertEqual(5,len(t1)); - expectedValues4=[0,1,2,3,4] - self.assertEqual(list(t1.getValues()),expectedValues4); - self.assertEqual(0,targetMesh.getCellContainingPoint(pos3,1e-12)); - #3D - targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - pos4=[25.,25.,25.] - self.assertEqual(0,targetMesh.getCellContainingPoint(pos4,1e-12)); - pos5=[50.,50.,50.] - t1=None - t1=targetMesh.getCellsContainingPoint(pos5,1e-12); - self.assertEqual(8,len(t1)); - expectedValues5=[0,1,2,3,4,5,6,7] - self.assertEqual(list(t1.getValues()),expectedValues5); - pos6=[0., 50., 0.] - t1=None - t1=targetMesh.getCellsContainingPoint(pos6,1e-12); - self.assertEqual(2,len(t1)); - expectedValues6=[0,2] - self.assertEqual(list(t1.getValues()),expectedValues6); - #3D outside - pos7=[-1.0,-1.0,0.] - self.assertEqual(-1,targetMesh.getCellContainingPoint(pos7,1e-12)); - #3D outside 2 - center2=[0.,0.,0.] - vec2=[0.,-1.,0.] - targetMesh.rotate(center2,vec2,0.78539816339744830962); - pos8=[-25.,25.,12.] - self.assertEqual(-1,targetMesh.getCellContainingPoint(pos8,1e-12)); - pass - - def testGetValueOn1(self): - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); - nbOfCells=targetMesh.getNumberOfCells(); - fieldOnCells.setMesh(targetMesh); - array=DataArrayDouble.New(); - tmp=2*nbOfCells*[None] - for i in xrange(nbOfCells): - tmp[2*i]=7.+float(i); - tmp[2*i+1]=17.+float(i) - pass - array.setValues(tmp,nbOfCells,2); - fieldOnCells.setArray(array); - # - pos1=[0.25,0.] - res=fieldOnCells.getValueOn(pos1); - self.assertEqual(2,len(res)) - self.assertTrue(abs(8.-res[0])<1e-12); - self.assertTrue(abs(18.-res[1])<1e-12); - # - # - targetMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); - fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES); - nbOfNodes=targetMesh.getNumberOfNodes(); - fieldOnNodes.setMesh(targetMesh); - array=DataArrayDouble.New(); - tmp=2*nbOfNodes*[None] - for i in xrange(nbOfNodes): - tmp[2*i]=17.+float(i); - tmp[2*i+1]=27.+float(i) - pass - array.setValues(tmp,nbOfNodes,2); - fieldOnNodes.setArray(array); - # - pos2=[-0.13333333333333333,-0.13333333333333333] - res=None - res=fieldOnNodes.getValueOn(pos2); - self.assertEqual(2,len(res)) - self.assertTrue(abs(17.5-res[0])<1e-12); - self.assertTrue(abs(27.5-res[1])<1e-12); - pos3=[0.033333333333333326,0.36666666666666664] - res=None - res=fieldOnNodes.getValueOn(pos3); - self.assertEqual(2,len(res)) - self.assertTrue(abs(18.666666666666667-res[0])<1e-12); - self.assertTrue(abs(28.666666666666667-res[1])<1e-12); - pass - - def testCMesh0(self): - mesh=MEDCouplingCMesh.New(); - meshEmpty=mesh.clone(True); - self.assertTrue(meshEmpty.isEqual(mesh, 1e-12)); - - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4. ] - coordsX.setValues(arrX, 4, 1); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8. ] - coordsY.setValues(arrY, 4, 1); - coordsZ=DataArrayDouble.New(); - arrZ=[ -3., 3., 6., 12. ] - coordsZ.setValues(arrZ, 4, 1); - mesh.setCoords(coordsX, coordsY, coordsZ); - # - fieldOnNodes=mesh.fillFromAnalytic(ON_NODES, 1, "x+y/2.+z/3."); - self.assertEqual(1, fieldOnNodes.getNumberOfComponents()); - self.assertEqual(64, fieldOnNodes.getNumberOfTuples()); - expected1=[-3., -1., 0., 2., -1., 1., 2., 4., 0., 2., 3., 5., 2., 4., 5., 7., -1., 1., 2., - 4., 1., 3., 4., 6., 2., 4., 5., 7., 4., 6., 7., 9., 0., 2., 3., 5., 2., 4., 5., - 7., 3., 5., 6., 8., 5., 7., 8., 10., 2., 4., 5., - 7., 4., 6., 7., 9., 5., 7., 8., 10., 7., 9., 10., 12.]; - - val=fieldOnNodes.getArray().getValues(); - for i in xrange(64): - self.assertAlmostEqual(expected1[i], val[i], 12) - res=fieldOnNodes.getValueOnPos(1, 3, 2); - self.assertAlmostEqual(7., res[0], 12); - # - fieldOnCells=mesh.fillFromAnalytic(ON_CELLS, 1, "x+y/2.+z/3."); - self.assertEqual(1, fieldOnCells.getNumberOfComponents()); - self.assertEqual(27, fieldOnCells.getNumberOfTuples()); - val=fieldOnCells.getArray().getValues(); - expected2=[0, 1.5, 3, 1.5, 3, 4.5, 3, 4.5, 6, 1.5, 3, 4.5, 3, 4.5, - 6, 4.5, 6, 7.5, 3, 4.5, 6, 4.5, 6, 7.5, 6, 7.5, 9]; - for i in xrange(27): - self.assertAlmostEqual(expected2[i], val[i], 12); - #res=fieldOnCells.getValueOnPos(1,2,1); - #self.assertAlmostEqual(6.,res,12); - # - meshDeepCopy=mesh.deepCpy(); - meshClone=mesh.clone(False); - - meshEmpty.copyTinyStringsFrom(mesh); - #no data in meshEmpty, expected False - self.assertTrue(not meshEmpty.isEqual(mesh, 1e-12)); - - self.assertTrue(meshDeepCopy.isEqual(mesh, 1e-12)); - meshDeepCopy.copyTinyStringsFrom(mesh); - self.assertTrue(meshDeepCopy.isEqual(mesh, 1e-12)); - self.assertTrue(meshClone.isEqual(mesh, 1e-12)); - - self.assertEqual(CARTESIAN, mesh.getType()); - self.assertEqual(CARTESIAN, meshEmpty.getType()); - self.assertEqual(CARTESIAN, meshDeepCopy.getType()); - self.assertEqual(CARTESIAN, meshClone.getType()); - pass - - def testCMesh1(self): - mesh1=MEDCouplingCMesh.New(); - coordsX1=DataArrayDouble.New(); - arrX1=[ -1., 1., 2., 4. ] - coordsX1.setValues(arrX1, 4, 1); - coordsY1=DataArrayDouble.New(); - arrY1=[ -2., 2., 4., 8. ] - coordsY1.setValues(arrY1, 4, 1); - coordsZ1=DataArrayDouble.New(); - arrZ1=[ -3., 3., 6., 12. ] - coordsZ1.setValues(arrZ1, 4, 1); - mesh1.setCoords(coordsX1, coordsY1, coordsZ1); - - mesh2=MEDCouplingCMesh.New(); - coordsX2=DataArrayDouble.New(); - arrX2=[ -1., 1., 2., 4. ] - coordsX2.setValues(arrX2, 4, 1); - coordsY2=DataArrayDouble.New(); - arrY2=[ -2., 2., 4., 8. ] - coordsY2.setValues(arrY2, 4, 1); - coordsZ2=DataArrayDouble.New(); - arrZ2=[ -3., 3., 6., 12.+1e-6 ] - coordsZ2.setValues(arrZ2, 4, 1); - mesh2.setCoords(coordsX2, coordsY2, coordsZ2); - - mesh3=MEDCouplingCMesh.New(); - coordsX3=DataArrayDouble.New(); - arrX3=[-1.] - coordsX3.setValues(arrX3, 1, 1); - coordsY3=DataArrayDouble.New(); - arrY3=[-2.] - coordsY3.setValues(arrY3, 1, 1); - coordsZ3=DataArrayDouble.New(); - arrZ3=[-3.] - coordsZ3.setValues(arrZ3, 1, 1); - mesh3.setCoords(coordsX3, coordsY3, coordsZ3); - - self.assertEqual(3, mesh1.getSpaceDimension()); - self.assertEqual(3, mesh1.getMeshDimension()); - - self.assertTrue(not mesh1.isEqual(mesh2, 1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1, 1e-12)); - self.assertTrue(not mesh2.isEqualWithoutConsideringStr(mesh1, 1e-12)); - self.assertTrue(mesh1.isEqual(mesh2, 1e-5)); - self.assertTrue(not mesh1.isEqual(mesh2, 1e-7)); - - self.assertRaises(InterpKernelException, mesh3.checkCoherency1, 1e-12); - mesh1.checkCoherency2(1e-12); - self.assertEqual(NORM_HEXA8, mesh1.getTypeOfCell(1)); - - self.assertEqual(NORM_HEXA8, mesh1.getAllGeoTypes()[0]); - self.assertEqual(27, mesh1.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertRaises(InterpKernelException, mesh1.getNumberOfCellsWithType, NORM_QUAD4); - - coo=mesh1.getCoordinatesOfNode(0); - self.assertEqual(3, len(coo)); - self.assertAlmostEqual(-1., coo[0], 14); - self.assertAlmostEqual(-2., coo[1], 14); - self.assertAlmostEqual(-3., coo[2], 14); - coo=mesh1.getCoordinatesOfNode(63); - self.assertEqual(3, len(coo)); - self.assertAlmostEqual(4., coo[0], 14); - self.assertAlmostEqual(8., coo[1], 14); - self.assertAlmostEqual(12., coo[2], 14); - - a=str(mesh1) - repr=mesh1.simpleRepr(); - repr=mesh1.advancedRepr(); - self.assertTrue("Cartesian" in repr); - self.assertTrue("Number of components : 1" in repr); - self.assertTrue("Number of tuples : 4" in repr); - self.assertTrue("Z Array :" in repr); - pass - - def testCMesh2(self): - mesh1=MEDCouplingCMesh.New(); - coordsX1=DataArrayDouble.New(); - arrX1=[ -1., 1., 2., 4. ] - coordsX1.setValues(arrX1, 4, 1); - coordsY1=DataArrayDouble.New(); - arrY1=[ -2., 2., 4., 8. ] - coordsY1.setValues(arrY1, 4, 1); - coordsZ1=DataArrayDouble.New(); - arrZ1=[ -3., 3., 6., 12. ] - coordsZ1.setValues(arrZ1, 4, 1); - mesh1.setCoords(coordsX1, coordsY1, coordsZ1); - - dis=mesh1.getDistributionOfTypes(); - self.assertEqual(1, len(dis)); - self.assertEqual(NORM_HEXA8, dis[0][0]); - self.assertEqual(27, dis[0][1]); - self.assertEqual(-1, dis[0][2]); - - idsPerType=[] - self.assertTrue(not mesh1.checkTypeConsistencyAndContig(dis, idsPerType)); - dis[0][0]=NORM_QUAD4; - self.assertRaises(InterpKernelException, mesh1.checkTypeConsistencyAndContig, dis, idsPerType); - dis[0][0]=NORM_HEXA8; - dis[0][2]=0; - ids=DataArrayInt.New(); - ids.alloc(10, 1); - ids.fillWithValue(23); - idsPerType=[ids]; - check=mesh1.checkTypeConsistencyAndContig(dis, idsPerType); - self.assertTrue(check); - self.assertTrue(check.isEqual(ids)); - - code, idsInPflPerType, pfls=mesh1.splitProfilePerType(ids); - self.assertEqual(1, len(code)); - self.assertEqual(NORM_HEXA8, code[0][0]); - self.assertEqual(10, code[0][1]); - self.assertEqual(0, code[0][2]); - self.assertEqual(1, len(idsInPflPerType)); - self.assertEqual(1, len(pfls)); - self.assertTrue(idsInPflPerType[0].isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9]))); - self.assertTrue(pfls[0].isEqual(ids)); - - cells1=[0, 1, 25, 26] - partMesh1=mesh1.buildPart(cells1) - self.assertTrue(isinstance(partMesh1,MEDCouplingMesh)) - self.assertEqual(4, partMesh1.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertEqual(64, mesh1.getNumberOfNodes()); - self.assertEqual(64, partMesh1.getNumberOfNodes()); - - cells2=[25, 26] - partMesh2, arr1=mesh1.buildPartAndReduceNodes(cells2) - self.assertTrue(isinstance(partMesh2,MEDCouplingCMesh)) - self.assertEqual(2,partMesh2.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertEqual(12,partMesh2.getNumberOfNodes()); - - cells3=[2, 3] - partMesh3, arr2=partMesh1.buildPartAndReduceNodes(cells3) - self.assertTrue(isinstance(partMesh3,MEDCouplingUMesh)) - self.assertEqual(2, partMesh3.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertEqual(12, partMesh3.getNumberOfNodes()); - - self.assertRaises(InterpKernelException, mesh1.simplexize, 0); - self.assertRaises(InterpKernelException, mesh1.getMeasureFieldOnNode, True); - - #double bbox1[6]; - #double bbox2[6]; - bbox1=mesh1.getBoundingBox(); #[(-1.0, 4.0), (-2.0, 8.0), (-3.0, 12.0)] - bbox2=partMesh1.getBoundingBox(); - self.assertTrue(bbox1==bbox2); - bbox1=partMesh3.getBoundingBox(); - bbox2=partMesh2.getBoundingBox(); - self.assertTrue(bbox1==bbox2); - - self.assertRaises(InterpKernelException, mesh1.buildOrthogonalField); - mesh2d=MEDCouplingCMesh.New(); - mesh2d.setCoords(coordsX1, coordsY1); - f1=mesh2d.buildOrthogonalField(); - - pass - - def testScale(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pos=[0.2,0.2] - mesh.scale(pos,0.5); - expected1=[-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, - -0.05,0.45, 0.2,0.45, 0.45,0.45] - val=mesh.getCoords().getValues(); - self.assertEqual(18,len(val)) - for i in xrange(18): - self.assertTrue(abs(expected1[i]-val[i])<1e-12); - pass - pass - - def testTryToShareSameCoords(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m2.tryToShareSameCoords(m1,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - # - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_2(); - self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m2.tryToShareSameCoords(m1,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - # - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DSourceMesh_1(); - self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); - self.assertRaises(InterpKernelException,m1.tryToShareSameCoords,m2,1e-12) - pass - - def testFindNodeOnPlane(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - pt=[300.,300.,0.] - v=[0.,0.,2.] - n=mesh.findNodesOnPlane(pt,v,1e-12); - self.assertEqual(9,len(n)); - m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); - self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) - me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); - da=me.getMesh3DIds(); - self.assertEqual(8,me.getNumberOfCells()); - expected=[0,1,2,3,4,5,6,7] - val=da.getValues(); - self.assertEqual(expected,list(val)); - # - m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); - self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) - me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); - da=me.getMesh3DIds(); - self.assertEqual(8,me.getNumberOfCells()); - expected=[0,1,2,3,4,5,6,7] - val=da.getValues(); - self.assertEqual(expected,list(val)); - pass - - def testRenumberCells(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - self.assertTrue(m.isEqual(m2,0)); - arr=[12,3,25,2,26] - m.renumberCells(arr,True); - self.assertTrue(not m.isEqual(m2,0)); - self.assertEqual(NORM_QUAD4,m.getTypeOfCell(0)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); - self.assertEqual(NORM_QUAD4,m.getTypeOfCell(2)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); - self.assertEqual(NORM_QUAD4,m.getTypeOfCell(4)); - arr2=[5,-1,-5,4,8] - m.renumberCells(arr2,True); - self.assertTrue(m.isEqual(m2,0)); - pass - - def testChangeSpaceDimension(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - self.assertEqual(3,m1.getSpaceDimension()); - m1.changeSpaceDimension(2); - self.assertEqual(2,m1.getSpaceDimension()); - m1.setName(m2.getName()); - self.assertTrue(m1.isEqual(m2,1e-12)); - m1.changeSpaceDimension(3); - self.assertEqual(3,m1.getSpaceDimension()); - expected=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.] - val=m1.getCoords().getValues(); - for i in xrange(27): - self.assertTrue(abs(expected[i]-val[i])<1e-14); - pass - pass - - def testGaussPointField1(self): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1 - _gsCoo1=gsCoo1 - _wg1=wg1 - # - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - self.assertEqual(0,f.getNbOfGaussLocalization()); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) - self.assertEqual(1,f.getNbOfGaussLocalization()); - refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo2=refCoo2 - _gsCoo1=_gsCoo1[0:4] - _wg1=_wg1[0:2] - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - array=DataArrayDouble.New(); - ptr=18*2*[None] - for i in xrange(18*2): - ptr[i]=float(i+1) - array.setValues(ptr,18,2); - ptr=array.getPointer(); - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - f.checkCoherency(); - self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); - self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); - # - f.clearGaussLocalizations(); - self.assertEqual(0,f.getNbOfGaussLocalization()); - self.assertRaises(InterpKernelException,f.checkCoherency); - ids1=[0,1,3,4] - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(0,f.getNbOfGaussLocalization()); - ids2=[0,4] - f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(1,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneCell,1); - ids3=[1,2] - f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- cell 3 has no localization - ids4=[3] - _gsCoo2=_gsCoo1; - _wg2=_wg1; - _gsCoo2[0]=0.8888777776666; - _wg2[0]=0.1234567892377; - f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); - self.assertEqual(3,f.getNbOfGaussLocalization()); - tmpIds=f.getCellIdsHavingGaussLocalization(0); - self.assertEqual(ids2,list(tmpIds.getValues())); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. - array2=f.getArray().substr(0,10); - f.setArray(array2); - f.checkCoherency();#<- here it is OK - f2=f.clone(True); - self.assertTrue(f.isEqual(f2,1e-14,1e-14)); - gl1=f2.getGaussLocalization(0); - tmp=gl1.getGaussCoord(1,1); - self.assertAlmostEqual(2.07*_b-1,tmp,14); - gl1.setGaussCoord(1,1,0.07); - self.assertTrue(not f.isEqual(f2,1e-14,1e-14)); - gl1.setGaussCoord(1,1,tmp); - self.assertTrue(f.isEqual(f2,1e-14,1e-14)); - f2.checkCoherency(); - pass - - def testGaussPointNEField1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - f.setName("MyFirstFieldOnNE"); - f.setDescription("MyDescriptionNE"); - array=DataArrayDouble.New(); - tmp=18*2*[None] - for i in xrange(18*2): - tmp[i]=float(i+7) - pass - array.setValues(tmp,18,2); - ptr=array.getPointer(); - f.setArray(array); - # - f.checkCoherency(); - f2=f.clone(True); - self.assertTrue(f.isEqual(f2,1e-14,1e-14)); - self.assertAlmostEqual(21.,f.getIJK(2,0,0),14); - self.assertAlmostEqual(18.,f.getIJK(1,1,1),14); - pass - - def testCellOrientation1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - vec=[0.,0.,-1.] - self.assertRaises(InterpKernelException,m.are2DCellsNotCorrectlyOriented,vec,False); - m.changeSpaceDimension(3); - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertTrue(len(res1)==0); - vec[2]=1.; - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertEqual(5,len(res1)); - # - vec[2]=-1.; - # connectivity inversion - conn=m.getNodalConnectivity().getValues(); - tmp=conn[11]; - conn[11]=conn[12]; - conn[12]=tmp; - m.getNodalConnectivity().setValues(conn,len(conn),1) - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertEqual(1,len(res1)); - self.assertEqual(2,res1.getValues()[0]); - m.orientCorrectly2DCells(vec,False); - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertTrue(len(res1)==0); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2.changeSpaceDimension(3); - self.assertTrue(m.isEqual(m2,1e-12)); - pass - - def testCellOrientation2(self): - m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - res1=m2.arePolyhedronsNotCorrectlyOriented(); - self.assertEqual(6,len(res1)); - m2.orientCorrectlyPolyhedrons(); - res1=m2.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - m2.checkCoherency(); - self.assertEqual(18,m2.getNumberOfCells()); - cellIds2=[0,6,12] - m2.convertToPolyTypes(cellIds2); - m2.orientCorrectlyPolyhedrons(); - res1=m2.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - f2=m2.getMeasureField(False); - f2Ptr=f2.getArray().getValues(); - #Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation - m3=MEDCouplingDataForTest.build2DTargetMesh_1(); - vec=[0.,0.,1.] - m3.changeSpaceDimension(3); - ids2=[0,1,2,3,4] - m3.convertToPolyTypes(ids2); - m3.orientCorrectly2DCells(vec,False); - m4=MEDCouplingDataForTest.buildCU1DMesh_U(); - m4.changeSpaceDimension(3); - center=[0.,0.,0.] - vector=[0.,1.,0.] - m4.rotate(center,vector,-pi/2.); - m5=m3.buildExtrudedMesh(m4,0); - res1=m5.arePolyhedronsNotCorrectlyOriented(); - self.assertEqual(15,len(res1)); - m5.orientCorrectlyPolyhedrons(); - res1=m5.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - f3=m5.getMeasureField(False); - self.assertEqual(15,f3.getArray().getNumberOfTuples()); - self.assertEqual(1,f3.getNumberOfComponents()); - f3Ptr=f3.getArray().getValues(); - expected1=[0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625]; - for i in xrange(15): - self.assertTrue(abs(expected1[i]-f3Ptr[i])<1e-12); - pass - f4=m5.getBarycenterAndOwner(); - self.assertEqual(15,f4.getNumberOfTuples()); - self.assertEqual(3,f4.getNumberOfComponents()); - f4Ptr=f4.getValues(); - expected2=[-0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15,-0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525,-0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875]; - for i in xrange(45): - self.assertTrue(abs(expected2[i]-f4Ptr[i])<1e-12); - pass - pass - - def testCellOrientation3(self): - from cmath import rect - - c = [rect(1.0, i*pi/4.0) for i in range(8)] - coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, - c[5].real,c[5].imag, c[1].real,c[1].imag] - connec = [0,1,2,3] - baseMesh = MEDCouplingUMesh.New("circle", 2) - baseMesh.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, 4, 2) - baseMesh.setCoords(meshCoords) - baseMesh.insertNextCell(NORM_QPOLYG, connec) # a circle - baseMesh.finishInsertingCells() - baseMesh.changeSpaceDimension(3) - Oz = [0.0, 0.0, -1.0] - cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) - self.assertEqual(cell_lst.getNumberOfTuples(), 0) - Oz[2] = 1.0 - cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) - self.assertEqual(cell_lst.getNumberOfTuples(), 1) - - def testPolyhedronBarycenter(self): - connN=[0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0]; - coords=[0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5]; - meshN=MEDCouplingUMesh.New(); - meshN.setName("ForBary"); - meshN.setMeshDimension(3); - meshN.allocateCells(4); - meshN.insertNextCell(NORM_POLYHED,29,connN[0:29]) - meshN.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,9,3); - meshN.setCoords(myCoords); - meshN.checkCoherency(); - # - res1=meshN.arePolyhedronsNotCorrectlyOriented(); - meshN.orientCorrectlyPolyhedrons(); - self.assertTrue(len(res1)==0); - da=meshN.getBarycenterAndOwner(); - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); - pass - # - center=[0.,0.,0.] - vec=[0.,2.78,0.] - da=meshN.getBarycenterAndOwner(); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); - pass - # - meshN.rotate(center,vec,pi/7.); - meshN.translate(vec); - da=meshN.getBarycenterAndOwner(); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); - pass - # - center2=[1.12,3.45,6.78] - vec2=[4.5,9.3,2.8] - meshN.rotate(center2,vec2,e); - meshN.translate(vec2); - da=meshN.getBarycenterAndOwner(); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-10); - pass - pass - - def testNormL12Integ1D(self): - m1=MEDCouplingDataForTest.build1DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(m1); - array=DataArrayDouble.New(); - arr=[-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72] - array.setValues(arr,m1.getNumberOfCells(),3); - f1.setArray(array); - # - f3=m1.getBarycenterAndOwner(); - self.assertEqual(4,f3.getNumberOfTuples()); - self.assertEqual(1,f3.getNumberOfComponents()); - expected9=[0.75,5.105,0.8,5.155] - ptr=f3.getValues(); - for i in xrange(4): - self.assertTrue(abs(expected9[i]-ptr[i])<1e-12); - pass - # - f2=m1.getMeasureField(False); - self.assertEqual(4,f2.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getNumberOfComponents()); - expected1=[0.5,0.21,-0.6,-0.31] - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); - pass - expected2=[0.5,0.21,0.6,0.31] - f2=m1.getMeasureField(True); - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); - pass - #integral - self.assertTrue(4,f1.getNumberOfTuples()) - res=f1.integral(False); - self.assertTrue(3,len(res)) - expected3=[0.9866,-0.3615,0.4217] - for i in xrange(3): - self.assertTrue(abs(expected3[i]-res[i])<1e-12); - pass - self.assertTrue(abs(expected3[0]-f1.integral(0,False))<1e-12); - self.assertTrue(abs(expected3[1]-f1.integral(1,False))<1e-12); - self.assertTrue(abs(expected3[2]-f1.integral(2,False))<1e-12); - res=f1.integral(True); - expected4=[-3.4152,8.7639,-14.6879] - for i in xrange(3): - self.assertTrue(abs(expected4[i]-res[i])<1e-12); - pass - #normL1 - res=f1.normL1(); - self.assertTrue(3,len(res)) - expected5=[6.979506172839505, 16.89018518518518, 27.02969135802469] - for i in xrange(3): - self.assertTrue(abs(expected5[i]-res[i])<1e-12); - pass - self.assertTrue(abs(expected5[0]-f1.normL1(0))<1e-12); - self.assertTrue(abs(expected5[1]-f1.normL1(1))<1e-12); - self.assertTrue(abs(expected5[2]-f1.normL1(2))<1e-12); - #normL2 - res=f1.normL2(); - self.assertTrue(3,len(res)) - expected7=[7.090910979452395, 16.9275542960123, 27.053271464160858] - for i in xrange(3): - self.assertTrue(abs(expected7[i]-res[i])<1e-9); - pass - self.assertTrue(abs(expected7[0]-f1.normL2(0))<1e-9); - self.assertTrue(abs(expected7[1]-f1.normL2(1))<1e-9); - self.assertTrue(abs(expected7[2]-f1.normL2(2))<1e-9); - #buildMeasureField - f4=f1.buildMeasureField(False); - self.assertTrue(abs(-0.2-f4.accumulate(0))<1e-12); - f4=f1.buildMeasureField(True); - self.assertTrue(abs(1.62-f4.accumulate(0))<1e-12); - # Testing with 2D Curve - m1=MEDCouplingDataForTest.build2DCurveTargetMesh_3(); - f2=m1.getMeasureField(False); - self.assertEqual(4,f2.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getNumberOfComponents()); - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(sqrt(2.)*expected2[i]-ptr[i])<1e-12); - pass - f2=m1.getMeasureField(True); - self.assertEqual(4,f2.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getNumberOfComponents()); - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(expected2[i]*sqrt(2.)-ptr[i])<1e-12); - pass - #bary - f3=m1.getBarycenterAndOwner(); - self.assertEqual(4,f3.getNumberOfTuples()); - self.assertEqual(2,f3.getNumberOfComponents()); - expected10=[0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155] - ptr=f3.getValues(); - for i in xrange(8): - self.assertTrue(abs(expected10[i]-ptr[i])<1e-12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(m1); - array=DataArrayDouble.New(); - array.setValues(arr,m1.getNumberOfCells(),3); - f1.setArray(array); - res=f1.integral(False); - for i in xrange(3): - self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); - pass - res=f1.integral(True); - for i in xrange(3): - self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); - pass - res=f1.normL1(); - for i in xrange(3): - self.assertTrue(abs(expected5[i]-res[i])<1e-12); - pass - res=f1.normL2(); - for i in xrange(3): - self.assertTrue(abs(expected7[i]-res[i])<1e-12); - pass - pass - - def testAreaBary2D(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=m1.getMeasureField(False); - self.assertEqual(10,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - expected1=[-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1] - ptr=f1.getArray().getValues(); - for i in xrange(10): - self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); - pass - f1=m1.getMeasureField(True); - ptr=f1.getArray().getValues(); - for i in xrange(10): - self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); - pass - f2=m1.getBarycenterAndOwner(); - self.assertEqual(10,f2.getNumberOfTuples()); - self.assertEqual(2,f2.getNumberOfComponents()); - expected2=[0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5] - ptr=f2.getValues(); - for i in xrange(20): - self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); - pass - m1.changeSpaceDimension(3); - f1=m1.getMeasureField(False); - self.assertEqual(10,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - ptr=f1.getArray().getValues(); - for i in xrange(10): - self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); - pass - f2=m1.getBarycenterAndOwner(); - self.assertEqual(10,f2.getNumberOfTuples()); - self.assertEqual(3,f2.getNumberOfComponents()); - ptr=f2.getValues(); - expected3=[0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.] - for i in xrange(30): - self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); - pass - pass - - def testAreaBary3D(self): - coords=[ 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , - 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , - 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , - 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , - -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , - -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , - 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , - 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , - -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , - 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , - -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , - -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , - -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , - -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , - -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , - -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , - 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , - 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , - 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , - -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , - -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , - -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , - -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , - 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , - 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , - 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , - -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , - -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , - 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , - 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , - -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , - 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , - 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , - 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , - -0.0372812069535 , -0.286740286332 , 0.00963701291166 ] - - connN = [ #polyhedron 0 - 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 - , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 - , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 - , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, - # polyhedron 1 - 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 - , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 - , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 - , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, - # polyhedron 2 - 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 - , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, - # polyhedron 3 - 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 - , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 - , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 - , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65] - - barys = [ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , - 0.0287618656076 , 0.135874379934 , -0.14601588119 , - -0.147128055553 , 0.0465995097041 , -0.049391174453 , - -0.00142506732317 , -0.0996953090351 , -0.115159183132 ] - meshN=MEDCouplingUMesh.New(); - meshN.setName("ForBary"); - meshN.setMeshDimension(3); - meshN.allocateCells(4); - meshN.insertNextCell(NORM_POLYHED,113,connN); - meshN.insertNextCell(NORM_POLYHED,99,connN[113:]); - meshN.insertNextCell(NORM_POLYHED,43,connN[212:]); - meshN.insertNextCell(NORM_POLYHED,92,connN[255:]); - meshN.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,69,3); - meshN.setCoords(myCoords); - meshN.checkCoherency(); - res1=meshN.arePolyhedronsNotCorrectlyOriented(); - meshN.orientCorrectlyPolyhedrons(); - res1=meshN.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - # - da=meshN.getBarycenterAndOwner(); - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - daPtr=da.getValues(); - for i in xrange(12): - self.assertTrue(abs(barys[i]-daPtr[i])<1e-12); - pass - pass - - def testRenumberCellsForFields(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - nbOfCells=m.getNumberOfCells(); - values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] - arr.setValues(values1,nbOfCells,3); - f.setArray(arr); - renumber1=[3,1,0,4,2] - loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] - for j in xrange(5): - res=f.getValueOn(loc[2*j:2*j+2]); - for i in xrange(3): - self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); - pass - pass - f.renumberCells(renumber1,False); - ptr=f.getArray().getValues(); - expected1=[9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.] - for i in xrange(15): - self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); - pass - #check that fields remains the same geometrically - for j in xrange(5): - res=f.getValueOn(loc[2*j:2*(j+1)]); - for i in xrange(3): - self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); - pass - pass - #On gauss - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); - f.setMesh(m); - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1[0:6]; - _gsCoo1=gsCoo1[0:12]; - _wg1=wg1[0:6]; - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo2=refCoo2[0:8]; - _gsCoo1=_gsCoo1[0:4] - _wg1=_wg1[0:2] - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - arr=DataArrayDouble.New(); - values2=[1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.] - arr.setValues(values2,18,2); - f.setArray(arr); - f.checkCoherency(); - fCpy=f.clone(True); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - f.renumberCells(renumber1,False); - self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); - expected2=[21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.] - ptr=f.getArray().getValues(); - for i in xrange(36): - self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); - pass - renumber2=[2,1,4,0,3] - f.renumberCells(renumber2,False); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - #GaussNE - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - values3=[1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.] - arr.setValues(values3,18,2); - f.setArray(arr); - f.checkCoherency(); - fCpy=f.clone(True); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - f.renumberCells(renumber1,False); - self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); - expected3=[21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.] - ptr=f.getArray().getValues(); - for i in xrange(36): - self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); - pass - f.renumberCells(renumber2,False);#perform reverse operation of renumbering to check that the resulting field is equal. - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - # - pass - - def testRenumberNodesForFields(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f.setMesh(m); - self.assertEqual(9,f.getNumberOfMeshPlacesExpected()); - arr=DataArrayDouble.New(); - nbOfNodes=m.getNumberOfNodes(); - values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] - arr.setValues(values1,nbOfNodes,3); - f.setArray(arr); - f.checkCoherency(); - renumber1=[0,4,1,3,5,2,6,7,8] - loc=[0.5432,-0.2432, 0.5478,0.1528] - expected1=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124] - for j in xrange(2): - res=f.getValueOn(loc[2*j:2*j+2]); - for i in xrange(3): - self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); - pass - pass - fCpy=f.clone(True); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - f.renumberNodes(renumber1); - self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); - for j in xrange(2): - res=f.getValueOn(loc[2*j:2*j+2]); - for i in xrange(3): - self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); - pass - pass - expected2=[7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] - for i in xrange(27): - self.assertTrue(abs(expected2[i]-f.getArray().getValues()[i])<1e-12); - pass - renumber2=[0,2,5,3,1,4,6,7,8] - f.renumberNodes(renumber2); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - pass - - def testConvertQuadraticCellsToLinear(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh.checkCoherency(); - types=mesh.getAllGeoTypes(); - types.sort() - self.assertEqual(5,len(types)); - expected1=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4, NORM_TRI6, NORM_QUAD8] - expected1.sort() - self.assertEqual(expected1,types); - self.assertTrue(mesh.isPresenceOfQuadratic()); - self.assertEqual(62,mesh.getMeshLength()); - f1=mesh.getMeasureField(False); - # - mesh.convertQuadraticCellsToLinear(); - self.assertTrue(not mesh.isPresenceOfQuadratic()); - # - mesh.checkCoherency(); - f2=mesh.getMeasureField(False); - self.assertTrue(f1.getArray().isEqual(f2.getArray(),1e-12)); - self.assertEqual(48,mesh.getMeshLength()); - types2=mesh.getAllGeoTypes(); - types2.sort() - self.assertEqual(3,len(types2)); - expected2=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4] - expected2.sort() - self.assertEqual(expected2,types2); - pass - - def testCheckGeoEquivalWith(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - #First test mesh1 - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,0,1e-12);#deepEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,1,1e-12);#fastEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - #Second test mesh1 and mesh2 are 2 different meshes instance - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,0,1e-12);#deepEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - #Third test : cell permutation by keeping the first the middle and the last as it is. - renum=[0,2,1,3,4,5,6,8,7,9] - mesh2.renumberCells(renum,False); - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor); - self.assertEqual(10,cellCor.getNumberOfTuples()); - self.assertEqual(1,cellCor.getNumberOfComponents()); - self.assertEqual(renum,list(cellCor.getValues())) - self.assertTrue(nodeCor==None); - cellCor=0; - self.assertTrue(nodeCor==None); - a,b=mesh1.checkDeepEquivalWith(mesh2,0,1e-12); - self.assertEqual(renum,list(a.getValues())) - self.assertTrue(b==None); - mesh2.setCoords(mesh1.getCoords()) - a=mesh1.checkDeepEquivalOnSameNodesWith(mesh2,0,1e-12); - self.assertEqual(renum,list(a.getValues())) - #4th test : cell and node permutation by keeping the first the middle and the last as it is. - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - renum2=[0,2,1,3,4,5,6,8,7,9,10] - mesh2.renumberCells(renum,False); - mesh2.renumberNodes(renum2,11); - cellCor=None - nodeCor=None - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor); - self.assertEqual(10,cellCor.getNumberOfTuples()); - self.assertEqual(1,cellCor.getNumberOfComponents()); - self.assertEqual(renum,list(cellCor.getValues())) - self.assertTrue(nodeCor); - self.assertEqual(11,nodeCor.getNumberOfTuples()); - self.assertEqual(1,nodeCor.getNumberOfComponents()); - self.assertEqual(renum2,list(nodeCor.getValues())) - cellCor=0; - nodeCor=0; - #5th test : modification of the last cell to check fastCheck detection. - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - renum3=[0,2,1,3,4,5,6,8,9,7] - mesh2.renumberCells(renum3,False); - mesh2.renumberNodes(renum2,11); - cellCor=None - nodeCor=None - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12) - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,1,1e-12) - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh2.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor!=None); - self.assertEqual(10,cellCor.getNumberOfTuples()); - self.assertEqual(1,cellCor.getNumberOfComponents()); - self.assertEqual(renum3,list(cellCor.getValues())) - self.assertTrue(nodeCor!=None); - self.assertEqual(11,nodeCor.getNumberOfTuples()); - self.assertEqual(1,nodeCor.getNumberOfComponents()); - self.assertEqual(renum2,list(nodeCor.getValues())); - pass - - def testCheckGeoEquivalWith2(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_4(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12); - self.assertEqual(None,cellCor); - self.assertNotEqual(None,nodeCor); - expected1=[0, 1, 3, 4, 5, 6, 7, 8, 9] - for i in xrange(9): - self.assertEqual(expected1[i],nodeCor.getIJ(i,0)); - pass - pass - - def testSwig2CheckDeepEquivalWith1(self): - eps = 1.0e-8 - mcart = MEDCouplingCMesh() - mcart.setCoordsAt(0, DataArrayDouble([0.0,1.5,2.0])) - mcart.setCoordsAt(1, DataArrayDouble([1.0,2.5,3.0,4.0])) - m = mcart.buildUnstructured() - m2 = m[1:m.getNumberOfCells()] - self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 0, eps) - self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 1, eps) - self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 2, eps) - pass - - def testSwig2CheckDeepEquivalWith2(self): - eps = 1.0e-8 - m = MEDCouplingUMesh("tst", 2) - m.setCoords(DataArrayDouble([], 0,2)) - m.setConnectivity(DataArrayInt([]), DataArrayInt([0])) - m2 = m.deepCpy() - m.checkDeepEquivalWith(m2, 0, eps) # Should not raise! - pass - - def testCopyTinyStringsFromOnFields(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - nbOfCells=m.getNumberOfCells(); - f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - f.setName("a"); - f.setDescription("b"); - a1=DataArrayDouble.New(); - a1.alloc(nbOfCells,2); - a1.fillWithZero(); - a1.setInfoOnComponent(0,"c"); - a1.setInfoOnComponent(1,"d"); - a2=a1.deepCpy(); - a2.setInfoOnComponent(0,"e"); - a2.setInfoOnComponent(1,"f"); - f.setArray(a1); - f.setEndArray(a2); - f.setEndTime(3.,3,4); - m.setName("g"); - m.getCoords().setInfoOnComponent(0,"h"); - m.getCoords().setInfoOnComponent(1,"i"); - m.getCoords().setInfoOnComponent(2,"j"); - # - f.checkCoherency(); - f2=f.clone(True); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.setName("smth"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.setDescription("GGG"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.getArray().setInfoOnComponent(0,"mmmm"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.getEndArray().setInfoOnComponent(1,"mmmm"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - m2=m.clone(True); - self.assertTrue(m2.isEqual(m,1e-12)); - m2.setName("123"); - self.assertTrue(not m2.isEqual(m,1e-12)); - m2.copyTinyStringsFrom(m); - self.assertTrue(m2.isEqual(m,1e-12)); - m2.getCoords().setInfoOnComponent(1,"eee"); - self.assertTrue(not m2.isEqual(m,1e-12)); - m2.copyTinyStringsFrom(m); - self.assertTrue(m2.isEqual(m,1e-12)); - pass - - def testTryToShareSameCoordsPermute(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - #self.assertTrue(m.getCoords()!=m2.getCoords()); - m.tryToShareSameCoordsPermute(m2,1e-12); - #self.assertTrue(m.getCoords()==m2.getCoords()); - self.assertTrue(m2.isEqual(m,1e-12)); - renum1=[1,2,0,5,8,7,4,3,6] - r1=DataArrayInt.New() - r1.setValues(renum1,len(renum1),1) - m.renumberNodes(r1,9); - #self.assertTrue(m.getCoords()!=m2.getCoords()); - self.assertTrue(not m2.isEqual(m,1e-12)); - m.tryToShareSameCoordsPermute(m2,1e-12); - #self.assertTrue(m.getCoords()==m2.getCoords()); - self.assertTrue(m2.isEqual(m,1e-12)); - pass - - def testTryToShareSameCoordsPermute2(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_4(); - targetCoords=[-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 ] - targetConn=[0,2,3,1] - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(2); - m2.allocateCells(1); - m2.insertNextCell(NORM_QUAD4,targetConn[0:4]) - m2.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,4,2); - m2.setCoords(myCoords); - m2.checkCoherency(); - m1.checkCoherency(); - # - expected1=[0.25,0.125,0.125,0.25,0.25] - f1=m1.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(5,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getArray().getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); - pass - self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); - self.assertRaises(InterpKernelException,m1.tryToShareSameCoordsPermute,m2,1e-12);# <- here in this order the sharing is impossible. - # Let's go for deeper test of tryToShareSameCoordsPermute - m2.tryToShareSameCoordsPermute(m1,1e-12); - f1=m1.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(5,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getArray().getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); - pass - self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); - pass - - def testChangeUnderlyingMesh1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr=[7., 107., 8., 108., 9., 109., 10., 110., 11., 111., 12., 112., 13., 113., 14., 114., 15., 115., 16., 116.] - array.setValues(arr,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - renum=[0,2,1,3,4,5,6,8,7,9] - mesh2.renumberCells(renum,False); - #self.assertTrue(f1.getMesh()==mesh1); - f1.changeUnderlyingMesh(mesh1,10,1e-12);# nothing done only to check that nothing done. - #self.assertTrue(f1.getMesh()==mesh1); - f1.changeUnderlyingMesh(mesh2,10,1e-12); - #self.assertTrue(f1.getMesh()==mesh2); - expected1=[7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.] - for i in xrange(20): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.] - array.setValues(arr2,mesh1.getNumberOfNodes(),2); - f1.setArray(array); - # - renum2=[0,2,10,3,4,5,6,8,7,9,1] - mesh2.renumberNodes(renum2,11); - #self.assertTrue(f1.getMesh()==mesh1); - f1.changeUnderlyingMesh(mesh2,10,1e-12); - #self.assertTrue(f1.getMesh()==mesh2); - expected2=[7.,107.,17.,117.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,9.,109.] - for i in xrange(22): - self.assertAlmostEqual(expected2[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testGetMaxValue1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - nbOfCells=m.getNumberOfCells(); - f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f.setMesh(m); - a1=DataArrayDouble.New(); - val1=[3.,4.,5.,6.,7.] - a1.setValues(val1,nbOfCells,1); - a2=DataArrayDouble.New(); - val2=[0.,1.,2.,8.,7.] - a2.setValues(val2,nbOfCells,1); - f.setArray(a1); - f.setEndArray(a2); - f.setEndTime(3.,3,4); - f.checkCoherency(); - # - self.assertAlmostEqual(8.,f.getMaxValue(),14); - self.assertAlmostEqual(0.,f.getMinValue(),14); - self.assertAlmostEqual(5.,f.getAverageValue(),14); - self.assertAlmostEqual(5.125,f.getWeightedAverageValue(0,True),14); - a1.setIJ(0,2,9.5); - self.assertAlmostEqual(9.5,f.getMaxValue(),14); - self.assertAlmostEqual(0.,f.getMinValue(),14); - a2.setIJ(0,0,9.); - self.assertAlmostEqual(9.5,f.getMaxValue(),14); - self.assertAlmostEqual(1.,f.getMinValue(),14); - pass - - def testSubstractInPlaceDM1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] - array.setValues(arr,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - self.assertEqual(10,f1.getNumberOfTuples()); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(20,f1.getNumberOfValues()); - # - renum=[0,2,3,1,4,5,6,8,7,9] - mesh2.renumberCells(renum,False); - # - f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f2.setMesh(mesh2); - array=DataArrayDouble.New(); - arr2=[7.1,107.1,10.1,110.1,8.1,108.1,9.1,109.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1] - array.setValues(arr2,mesh2.getNumberOfCells(),2); - f2.setArray(array); - # - f1.substractInPlaceDM(f2,10,1e-12); - f1.applyFunc(1,"abs(x+y+0.2)"); - self.assertAlmostEqual(0.,f1.getMaxValue(),13); - pass - - def testDotCrossProduct1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] - array.setValues(arr1,mesh1.getNumberOfCells(),3); - f1.setArray(array); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setTime(7.8,4,5); - f2.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.] - array.setValues(arr2,mesh1.getNumberOfCells(),3); - f2.setArray(array); - # - f3=f1.dot(f2); - expected1=[842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],f3.getIJ(i,0),9); - pass - # - f4=f1.crossProduct(f2); - expected2=[-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); - pass - pass - - def testMinMaxFields1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] - array.setValues(arr1,mesh1.getNumberOfCells(),3); - f1.setArray(array); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setTime(7.8,4,5); - f2.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.] - array.setValues(arr2,mesh1.getNumberOfCells(),3); - f2.setArray(array); - # - f3=f1.max(f2); - expected1=[7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),9); - pass - # - f4=f1.min(f2); - expected2=[6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); - pass - # - pass - - def testApplyLin1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] - array.setValues(arr,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - f1.applyLin(2.,3.,0); - expected1=[17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.] - for i in xrange(20): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),9); - pass - # - arr2=[2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] - array=DataArrayDouble.New(); - array.setValues(arr2,mesh1.getNumberOfCells(),2); - f1.setEndArray(array); - # - f1.applyLin(4.,5.,1); - # - expected2=[17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.] - for i in xrange(20): - self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),9); - pass - expected3=[2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.] - for i in xrange(20): - self.assertAlmostEqual(expected3[i],f1.getEndArray().getIJ(0,i),9); - pass - # - pass - - def testGetIdsInRange1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[2.,8.,6.,5.,11.,7.,9.,3.,10.,4.] - array.setValues(arr1,mesh1.getNumberOfCells(),1); - f1.setArray(array); - # - f1.checkCoherency(); - da=f1.getIdsInRange(2.9,7.1); - self.failUnlessEqual(5,da.getNbOfElems()); - expected1=[2,3,5,7,9] - self.failUnlessEqual(expected1,list(da.getValues())); - da=f1.getIdsInRange(8.,12.); - self.failUnlessEqual(4,da.getNbOfElems()); - expected2=[1,4,6,8] - self.failUnlessEqual(expected2,list(da.getValues())); - # - pass - - def testBuildSubPart1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] - array.setValues(arr1,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - part1=[2,1,4] - f2=f1[part1]; - f2.zipCoords() - self.failUnlessEqual(3,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - expected1=[5.,105.,4.,104.,7.,107.] - for i in xrange(6): - self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12); - pass - self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(13,m2C.getMeshLength()); - expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] - self.failUnlessEqual(expected3,list(m2C.getNodalConnectivity().getValues())); - expected4=[0,4,8,13] - self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); - # Test with field on nodes. - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] - array.setValues(arr2,mesh1.getNumberOfNodes(),2); - f1.setArray(array); - part2=[1,2] - f2=f1.buildSubPart(part2); - self.failUnlessEqual(4,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - expected5=[4.,104.,5.,105.,7.,107.,8.,108.] - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); - pass - self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(8,m2C.getMeshLength()); - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:]); - self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); - self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); - #idem previous because nodes of cell#4 are not fully present in part3 - part3=[1,2] - arrr=DataArrayInt.New(); - arrr.setValues(part3,2,1); - f2=f1.buildSubPart(arrr); - self.failUnlessEqual(4,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); - pass - self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(8,m2C.getMeshLength()); - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:8]); - self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); - self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); - # - part4=[1,2,4] - f2=f1.buildSubPart(part4); - self.failUnlessEqual(6,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] - for i in xrange(12): - self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12); - pass - self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(13,m2C.getMeshLength()); - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - self.failUnlessEqual(expected3[0:4],list(m2C.getNodalConnectivity().getValues())[4:8]); - self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[0:4]); - self.failUnlessEqual(expected3[8:13],list(m2C.getNodalConnectivity().getValues())[8:13]); - self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); - pass - - def testDoublyContractedProduct1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.doublyContractedProduct(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9); - pass - # - pass - - def testDeterminant1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1.setTime(2.3,5,6); - f1.setEndTime(3.8,7,3); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] - array.setValues(arr1,mesh1.getNumberOfCells(),4); - f1.setArray(array); - #4 components - f1.checkCoherency(); - f2=f1.determinant(); - f2.checkCoherency(); - self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfValues()); - for i in xrange(5): - self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13); - pass - #6 components multi arrays with end array not defined - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setTime(2.3,5,6); - f1.setEndTime(3.8,7,3); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, - 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr2,mesh1.getNumberOfNodes(),6); - f1.setArray(array); - self.assertRaises(InterpKernelException,f1.checkCoherency);#no end array specified ! - # - f2=f1.determinant(); - self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getArray().getNumberOfComponents()); - self.assertEqual(9,f2.getNumberOfTuples()); - for i in xrange(9): - self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); - pass - #6 components multi arrays with end array defined - array=DataArrayDouble.New(); - arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, - 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr3,mesh1.getNumberOfNodes(),6); - f1.setEndArray(array); - f1.checkCoherency(); - f2=f1.determinant(); - f2.checkCoherency(); - self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(9,f2.getNumberOfTuples()); - time2,it,order=f2.getTime() - self.assertAlmostEqual(2.3,time2,12); - self.assertEqual(5,it); - self.assertEqual(6,order); - time2,it,order=f2.getEndTime() - self.assertAlmostEqual(3.8,time2,12); - self.assertEqual(7,it); - self.assertEqual(3,order); - for i in xrange(9): - self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); - self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9); - pass - #9 components - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(7.8,10,2); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] - array.setValues(arr4,mesh1.getNumberOfCells(),9); - f1.setArray(array); - # - f1.checkCoherency(); - f2=f1.determinant(); - f2.checkCoherency(); - self.assertEqual(ONE_TIME,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - time2,it,order=f2.getTime() - self.assertAlmostEqual(7.8,time2,12); - self.assertEqual(10,it); - self.assertEqual(2,order); - for i in xrange(5): - self.assertAlmostEqual(3.267,f2.getIJ(i,0),13); - pass - pass - - def testEigenValues1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.eigenValues(); - f2.checkCoherency(); - self.assertEqual(3,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - pass - pass - - def testEigenVectors1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.eigenVectors(); - f2.checkCoherency(); - self.assertEqual(9,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0 - 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1 - -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2 - ] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); - self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); - self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); - self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); - pass - # - pass - - def testInverse1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] - array.setValues(arr1,mesh1.getNumberOfCells(),9); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.inverse(); - f2.checkCoherency(); - self.assertEqual(9,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); - self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); - self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); - self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); - pass - # - array=DataArrayDouble.New(); - arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr3,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.inverse(); - f2.checkCoherency(); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887] - for i in xrange(5): - self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13); - pass - # - array=DataArrayDouble.New(); - arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] - array.setValues(arr2,mesh1.getNumberOfCells(),4); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.inverse(); - f2.checkCoherency(); - self.assertEqual(4,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156] - for i in xrange(5): - self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13); - pass - # - pass - - def testTrace1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] - array.setValues(arr1,mesh1.getNumberOfCells(),9); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.trace(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(15.9,f2.getIJ(i,0),13); - pass - # - array=DataArrayDouble.New(); - arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr3,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.trace(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(25.8,f2.getIJ(i,0),13); - pass - # - array=DataArrayDouble.New(); - arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] - array.setValues(arr2,mesh1.getNumberOfCells(),4); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.trace(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(5.7,f2.getIJ(i,0),13); - pass - # - pass - - def testDeviator1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.deviator(); - f2.checkCoherency(); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[-1.1,0.,1.1,4.5,5.6,6.7] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); - pass - # - pass - - def testMagnitude1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.magnitude(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13); - pass - # - pass - - def testMaxPerTuple1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.maxPerTuple(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(5.6,f2.getIJ(i,0),13); - pass - # - d2,d2I=array.maxPerTupleWithCompoId() - self.assertEqual(1,d2.getNumberOfComponents()); - self.assertEqual(5,d2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(5.6,d2.getIJ(i,0),13); - pass - self.assertTrue(d2I.isEqual(DataArrayInt([4,3,2,0,1]))) - pass - - def testChangeNbOfComponents(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f1.changeNbOfComponents(3,7.77); - f1.checkCoherency(); - self.assertEqual(3,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2] - for i in xrange(15): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13); - pass - f1.changeNbOfComponents(4,7.77); - f1.checkCoherency(); - self.assertEqual(4,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77] - for i in xrange(20): - self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13); - pass - # - pass - - def testSortPerTuple1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f1.sortPerTuple(True); - f1.checkCoherency(); - self.assertEqual(5,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13); - self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13); - self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); - self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13); - self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13); - pass - # - f1.sortPerTuple(False); - f1.checkCoherency(); - self.assertEqual(5,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13); - self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13); - self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); - self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13); - self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13); - pass - # - pass - - def testIsEqualWithoutConsideringStr1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.setName("rr"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - da1,da2=mesh1.checkGeoEquivalWith(mesh2,2,1e-12); - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12); - mesh2.setName(""); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(0,"tty"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(0,""); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(1,"tty"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(1,""); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - tmp=mesh2.getCoords().getIJ(0,3); - mesh2.getCoords().setIJ(0,3,9999.); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setIJ(0,3,tmp); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - tmp2=mesh2.getNodalConnectivity().getIJ(0,4); - mesh2.getNodalConnectivity().setIJ(0,4,0); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getNodalConnectivity().setIJ(0,4,tmp2); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - # - f1=mesh1.getMeasureField(True); - f2=mesh2.getMeasureField(True); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2.setName("ftest"); - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f1.setName("ftest"); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - # - f2.getArray().setInfoOnComponent(0,"eee"); - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2.getArray().setInfoOnComponent(0,""); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - # - f2.getArray().setIJ(1,0,0.123); - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(not f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2.getArray().setIJ(1,0,0.125); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - # - pass - - def testGetNodeIdsOfCell1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - li=mesh1.getNodeIdsOfCell(1) - expected1=[1, 4, 2] - self.assertEqual(expected1,list(li)) - li=mesh1.getCoordinatesOfNode(4) - self.assertEqual(2,len(li)) - self.assertAlmostEqual(0.2,li[0],13); - self.assertAlmostEqual(0.2,li[1],13); - li=mesh1.getCoords().getValuesAsTuple() - self.assertEqual(9,len(li)) - li2=mesh1.getNodalConnectivityIndex().getValuesAsTuple() - self.assertEqual(6,len(li2)) - pass - - def testGetEdgeRatioField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.setTime(3.4,5,6); m1.setTimeUnit("us"); - f1=m1.getEdgeRatioField(); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); - self.assertEqual(5,f1.getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - expected1=[1.,1.4142135623730951, 1.4142135623730951,1.,1.] - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),14); - pass - # - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=m1.getEdgeRatioField(); - self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); - self.assertEqual(5,f1.getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - expected2=[1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951] - for i in xrange(5): - self.assertAlmostEqual(expected2[i],f1.getIJ(i,0),14); - pass - pass - - def testFillFromAnalytic3(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - self.assertRaises(InterpKernelException,f1.fillFromAnalytic,1,"y+x"); - f1.setMesh(m) - f1.setName("myField"); - f1.fillFromAnalytic(1,"y+x"); - f1.checkCoherency(); - self.assertEqual(f1.getName(),"myField"); - self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(values1)): - self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,CONST_ON_TIME_INTERVAL) - f1.setMesh(m) - f1.fillFromAnalytic(1,"y+2*x"); - f1.setEndTime(1.2,3,4); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),CONST_ON_TIME_INTERVAL); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(values2)): - self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); - pass - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setMesh(m) - f1.fillFromAnalytic(1,"2.*x+y"); - f1.setEndTime(1.2,3,4); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),LINEAR_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - tmp=f1.getArray().getValues(); - values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - self.assertEqual(len(values2Bis),len(tmp)) - for i in xrange(len(values2Bis)): - self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); - pass - tmp=f1.getEndArray().getValues(); - self.assertEqual(len(values2Bis),len(tmp)) - for i in xrange(len(values2Bis)): - self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f1.setMesh(m) - f1.fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(values3)): - self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); - pass - values4=f1.accumulate(); - self.assertTrue(abs(3.6-values4[0])<1.e-12); - self.assertTrue(abs(7.2-values4[1])<1.e-12); - values4=f1.integral(True); - self.assertTrue(abs(0.5-values4[0])<1.e-12); - self.assertTrue(abs(1.-values4[1])<1.e-12); - # - f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f1.setMesh(m); - self.assertRaises(InterpKernelException,f1.fillFromAnalytic,1,"1./(x-0.2)"); - pass - - def testFieldDoubleOpEqual1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - self.assertRaises(InterpKernelException,f1.assign,0.07); - f1.setMesh(m); - f1.assign(0.07); - f1.checkCoherency(); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(0.07,f1.getIJ(i,0),16); - pass - f1.assign(0.09); - f1.checkCoherency(); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(0.09,f1.getIJ(i,0),16); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setEndTime(4.5,2,3); - f1.setMesh(m); - f1.assign(0.08); - f1.checkCoherency(); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - for i in xrange(9): - self.assertAlmostEqual(0.08,f1.getIJ(i,0),16); - pass - self.assertEqual(1,f1.getEndArray().getNumberOfComponents()); - self.assertEqual(9,f1.getEndArray().getNumberOfTuples()); - for i in xrange(9): - self.assertAlmostEqual(0.08,f1.getEndArray().getIJ(i,0),16); - pass - pass - - def testAreaBary3D2(self): - coordsForHexa8=[-75.45749305371, 180.95495078401, 39.515472018008, - -9.755591679144, 23.394927935279, 5.108794294848, - 14.337630157832, 61.705351002702, 160.42422501908, - -27.273893776752, 167.567731083961, 192.830034145464, - 99.857193154796,264.499264735586,-8.287335493412, - 144.939882761126,156.38626563134,-31.896173894226, - 161.34096835726,182.4654895809,73.832387065572, - 132.680430393685,255.37973247196,96.15235602819]; - volHexa8=3258520.29637466; - baryHexa8=[43.925705821778, 155.31893955289, 65.874418109644] - - coordsForPenta6=[-68.199829618726,178.938498373416,62.608505919588, - 8.461744647847,76.653979804423,165.00018874933, - -27.273893776752,167.567731083961,192.830034145464, - 106.586501038965,262.629609408327,13.124533008813, - 155.465082847275,197.414118382622,78.408350795821, - 132.680430393685,255.37973247196,96.15235602819]; - volPenta6=944849.868507338; - baryPenta6=[39.631002313543,182.692711783428,106.98540473964] - - coordsForPyra5=[132.680430393685,255.37973247196,96.15235602819, - -27.273893776752,167.567731083961,192.830034145464, - 8.461744647847,76.653979804423,165.00018874933, - 155.465082847275,197.414118382622,78.408350795821, - -68.199829618726,178.938498373416,62.608505919588]; - volPyra5=756943.92980254; - baryPyra5=[29.204294116618,172.540129749156,118.01035951483] - mesh=MEDCouplingUMesh.New("Bary3D2",3); - coo=DataArrayDouble.New(); - tmp=coordsForHexa8+coordsForPenta6+coordsForPyra5 - coo.setValues(tmp,19,3); - mesh.setCoords(coo); - # - tmpConn=[0,1,2,3,4,5,6,7] - mesh.allocateCells(3); - self.assertRaises(InterpKernelException,mesh.insertNextCell,NORM_HEXA8,9,tmpConn[0:8]) - mesh.insertNextCell(NORM_HEXA8,tmpConn[0:8]) - mesh.insertNextCell(NORM_PENTA6,6,[i+8 for i in tmpConn]) - mesh.insertNextCell(NORM_PYRA5,5,[i+14 for i in tmpConn]) - mesh.finishInsertingCells(); - mesh.checkCoherency(); - mesh.mergeNodes(1e-7) - self.assertEqual(12,mesh.getNumberOfNodes()); - vols=mesh.getMeasureField(True); - self.assertEqual(3,vols.getNumberOfTuples()); - self.assertEqual(1,vols.getNumberOfComponents()); - self.assertAlmostEqual(volHexa8,vols.getIJ(0,0),6); - self.assertAlmostEqual(volPenta6,vols.getIJ(1,0),7); - self.assertAlmostEqual(volPyra5,vols.getIJ(2,0),7); - bary=mesh.getBarycenterAndOwner(); - self.assertEqual(3,bary.getNumberOfTuples()); - self.assertEqual(3,bary.getNumberOfComponents()); - self.assertAlmostEqual(baryHexa8[0],bary.getIJ(0,0),11); - self.assertAlmostEqual(baryHexa8[1],bary.getIJ(0,1),11); - self.assertAlmostEqual(baryHexa8[2],bary.getIJ(0,2),11); - self.assertAlmostEqual(baryPenta6[0],bary.getIJ(1,0),11); - self.assertAlmostEqual(baryPenta6[1],bary.getIJ(1,1),11); - self.assertAlmostEqual(baryPenta6[2],bary.getIJ(1,2),11); - self.assertAlmostEqual(baryPyra5[0],bary.getIJ(2,0),11); - self.assertAlmostEqual(baryPyra5[1],bary.getIJ(2,1),11); - self.assertAlmostEqual(baryPyra5[2],bary.getIJ(2,2),11); - pass - - def testGetMeasureFieldCMesh1(self): - m=MEDCouplingCMesh.New(); - da=DataArrayDouble.New(); - discX=[2.3,3.4,5.8,10.2] - discY=[12.3,23.4,45.8] - discZ=[-0.7,1.2,1.25,2.13,2.67] - da.setValues(discX,4,1); - m.setCoordsAt(0,da); - m.checkCoherency(); - self.assertEqual(4,m.getNumberOfNodes()); - self.assertEqual(3,m.getNumberOfCells()); - self.assertEqual(1,m.getSpaceDimension()); - f=m.getMeasureField(True); - self.assertEqual(3,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected1=[1.1,2.4,4.4] - for i in xrange(3): - self.assertAlmostEqual(expected1[i],f.getIJ(i,0),12); - pass - coords=m.getCoordinatesAndOwner(); - self.assertEqual(4,coords.getNumberOfTuples()); - self.assertEqual(1,coords.getNumberOfComponents()); - for i in xrange(4): - self.assertAlmostEqual(discX[i],coords.getIJ(i,0),12); - pass - coords=m.getBarycenterAndOwner(); - self.assertEqual(3,coords.getNumberOfTuples()); - self.assertEqual(1,coords.getNumberOfComponents()); - expected1_3=[2.85,4.6,8.] - for i in xrange(3): - self.assertAlmostEqual(expected1_3[i],coords.getIJ(i,0),12); - pass - # - da=DataArrayDouble.New(); - da.setValues(discY,3,1); - m.setCoordsAt(1,da); - m.checkCoherency(); - self.assertEqual(12,m.getNumberOfNodes()); - self.assertEqual(6,m.getNumberOfCells()); - self.assertEqual(2,m.getSpaceDimension()); - f=m.getMeasureField(True); - self.assertEqual(6,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected2=[12.21,26.64,48.84,24.64,53.76,98.56] - for i in xrange(6): - self.assertAlmostEqual(expected2[i],f.getIJ(i,0),12); - pass - coords=m.getCoordinatesAndOwner(); - self.assertEqual(12,coords.getNumberOfTuples()); - self.assertEqual(2,coords.getNumberOfComponents()); - expected2_2=[2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8] - for i in xrange(24): - self.assertAlmostEqual(expected2_2[i],coords.getIJ(0,i),12); - pass - coords=m.getBarycenterAndOwner(); - self.assertEqual(6,coords.getNumberOfTuples()); - self.assertEqual(2,coords.getNumberOfComponents()); - expected2_3=[2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6] - for i in xrange(12): - self.assertAlmostEqual(expected2_3[i],coords.getIJ(0,i),12); - pass - # - da=DataArrayDouble.New(); - da.setValues(discZ,5,1); - m.setCoordsAt(2,da); - m.checkCoherency(); - self.assertEqual(60,m.getNumberOfNodes()); - self.assertEqual(24,m.getNumberOfCells()); - self.assertEqual(3,m.getSpaceDimension()); - f=m.getMeasureField(True); - self.assertEqual(24,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected3=[23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224] - for i in xrange(24): - self.assertAlmostEqual(expected3[i],f.getIJ(i,0),12); - pass - coords=m.getCoordinatesAndOwner(); - self.assertEqual(60,coords.getNumberOfTuples()); - self.assertEqual(3,coords.getNumberOfComponents()); - expected3_2=[ - 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, - 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, - 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, - 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, - 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67]; - for i in xrange(180): - self.assertAlmostEqual(expected3_2[i],coords.getIJ(0,i),12); - pass - coords=m.getBarycenterAndOwner(); - self.assertEqual(24,coords.getNumberOfTuples()); - self.assertEqual(3,coords.getNumberOfComponents()); - expected3_3=[ - 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, - 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, - 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, - 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4]; - for i in xrange(72): - self.assertAlmostEqual(expected3_3[i],coords.getIJ(0,i),12); - pass - pass - - def testFieldDoubleZipCoords1(self): - m=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); - f=m.fillFromAnalytic(ON_NODES,2,"x*2."); - f.getArray().setInfoOnComponent(0,"titi"); - f.getArray().setInfoOnComponent(1,"tutu"); - f.checkCoherency(); - self.assertEqual(18,f.getNumberOfTuples()); - self.assertEqual(2,f.getNumberOfComponents()); - expected1=[-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] - for i in xrange(36): - self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); - pass - self.assertTrue(f.zipCoords()); - f.checkCoherency(); - expected2=[-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); - pass - self.assertTrue(not f.zipCoords()); - f.checkCoherency(); - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); - pass - self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); - self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); - pass - - def testFieldDoubleZipConnectivity1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m3_1=m2.buildPartOfMySelf(cells1,True); - m3=m3_1; - m4=MEDCouplingDataForTest.build2DSourceMesh_1(); - m5=MEDCouplingUMesh.MergeUMeshes(m1,m3); - m6=MEDCouplingUMesh.MergeUMeshes(m5,m4); - # - self.assertEqual(10,m6.getNumberOfCells()); - self.assertEqual(22,m6.getNumberOfNodes()); - arr,areNodesMerged,newNbOfNodes=m6.mergeNodes(1e-13); - self.assertEqual(9,m6.getNumberOfNodes()); - f=m6.fillFromAnalytic(ON_CELLS,2,"x"); - f2=m6.fillFromAnalytic(ON_NODES,2,"x"); - self.assertEqual(10,f.getNumberOfTuples()); - self.assertEqual(2,f.getNumberOfComponents()); - expected1=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, - 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; - for i in xrange(20): - self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); - pass - f.getArray().setInfoOnComponent(0,"titi"); - f.getArray().setInfoOnComponent(1,"tutu"); - f.checkCoherency(); - self.assertTrue(f.zipConnectivity(0)); - expected2=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; - self.assertEqual(7,f.getNumberOfTuples()); - self.assertEqual(2,f.getNumberOfComponents()); - for i in xrange(14): - self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); - pass - self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); - self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); - self.assertTrue(not f.zipConnectivity(0)); - # - expected3=[-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, - -0.3, -0.3, 0.2, 0.2, 0.7, 0.7]; - self.assertEqual(9,f2.getNumberOfTuples()); - self.assertEqual(2,f2.getNumberOfComponents()); - for i in xrange(18): - self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); - pass - self.assertTrue(f2.zipConnectivity(0)); - self.assertEqual(9,f2.getNumberOfTuples()); - self.assertEqual(2,f2.getNumberOfComponents()); - for i in xrange(18): - self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); - pass - pass - - def testDaDoubleRenumber1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[3,1,0,6,5,4,2] - b=a.renumber(arr2); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.renumber(arr2); - self.assertEqual(7,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] - for i in xrange(14): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberAndReduce1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[2,-1,1,-1,0,4,3] - b=a.renumberAndReduce(arr2,5); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.renumberAndReduce(arr2,5); - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[5,15,3,13,1,11,7,17,6,16] - for i in xrange(10): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberInPlace1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - # - arr2=[3,1,0,6,5,4,2] - a.renumberInPlace(arr2); - self.assertEqual(7,a.getNumberOfTuples()); - self.assertEqual(2,a.getNumberOfComponents()); - expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.renumberInPlace(arr2); - self.assertEqual(7,c.getNumberOfTuples()); - self.assertEqual(2,c.getNumberOfComponents()); - expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] - for i in xrange(14): - self.assertEqual(expected2[i],c.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberR1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[3,1,0,6,5,4,2] - b=a.renumberR(arr2); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.renumberR(arr2); - self.assertEqual(7,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] - for i in xrange(14): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberInPlaceR1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - # - arr2=[3,1,0,6,5,4,2] - a.renumberInPlaceR(arr2); - self.assertEqual(7,a.getNumberOfTuples()); - self.assertEqual(2,a.getNumberOfComponents()); - expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.renumberInPlaceR(arr2); - self.assertEqual(7,c.getNumberOfTuples()); - self.assertEqual(2,c.getNumberOfComponents()); - expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] - for i in xrange(14): - self.assertEqual(expected2[i],c.getIJ(0,i)); - pass - pass - - def testDaDoubleSelectByTupleId1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[4,2,0,6,5] - b=a.selectByTupleId(arr2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.selectByTupleId(arr2); - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[5,15,3,13,1,11,7,17,6,16] - for i in xrange(10): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleGetMinMaxValues1(self): - a=DataArrayDouble.New(); - arr1=[2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56] - a.setValues(arr1,9,1); - m,where=a.getMaxValue(); - self.assertEqual(1,where); - self.assertAlmostEqual(4.56,m,12); - m,ws=a.getMaxValue2(); - self.assertAlmostEqual(4.56,m,12); - self.assertEqual(3,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - expected1=[1,4,8] - for i in xrange(3): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - a=DataArrayDouble.New(); - arr2=[-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56] - a.setValues(arr2,9,1); - m,where=a.getMinValue(); - self.assertEqual(1,where); - self.assertAlmostEqual(-4.56,m,12); - m,ws=a.getMinValue2(); - self.assertAlmostEqual(-4.56,m,12); - self.assertEqual(3,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - for i in xrange(3): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - pass - - def testFieldDoubleGetMinMaxValues2(self): - m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - self.assertEqual(18,m2.getNumberOfCells()); - arr1=[8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71] - f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - a=DataArrayDouble.New(); - a.setValues(arr1,18,1); - f.setArray(a); - f.setMesh(m2); - # - f.checkCoherency(); - m=f.getMaxValue(); - self.assertAlmostEqual(8.71,m,12); - m,ws=f.getMaxValue2(); - self.assertAlmostEqual(8.71,m,12); - self.assertEqual(4,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - expected1=[0,3,7,17] - for i in xrange(4): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - # - arr2=[-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71] - a.setValues(arr2,18,1); - f.checkCoherency(); - m=f.getMinValue(); - self.assertAlmostEqual(-8.71,m,12); - m,ws=f.getMinValue2(); - self.assertAlmostEqual(-8.71,m,12); - self.assertEqual(4,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - for i in xrange(4): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - pass - - def testBuildUnstructuredCMesh1(self): - m=MEDCouplingCMesh.New(); - da=DataArrayDouble.New(); - discX=[2.3,3.4,5.8,10.2] - discY=[12.3,23.4,45.8] - discZ=[-0.7,1.2,1.25,2.13,2.67] - da.setValues(discX,4,1); - m.setCoordsAt(0,da); - m.checkCoherency(); - self.assertEqual(0,m.getCellContainingPoint([2.4],1e-12)); - self.assertEqual(1,m.getCellContainingPoint([3.7],1e-12)); - self.assertEqual(2,m.getCellContainingPoint([5.9],1e-12)); - self.assertEqual(-1,m.getCellContainingPoint([10.3],1e-12)); - self.assertEqual(-1,m.getCellContainingPoint([1.3],1e-12)); - # - m2=m.buildUnstructured(); - m2.checkCoherency(); - f1=m.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertTrue(isinstance(f1.getMesh(),MEDCouplingCMesh)) - self.assertEqual(f1.getNumberOfTuples(),3); - self.assertEqual(f2.getNumberOfTuples(),3); - self.assertEqual(1,m2.getMeshDimension()); - self.assertEqual(1,m2.getSpaceDimension()); - for i in xrange(3): - self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); - pass - da=DataArrayDouble.New(); - da.setValues(discY,3,1); - m.setCoordsAt(1,da); - # - m2=m.buildUnstructured(); - m2.checkCoherency(); - f1=m.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(f1.getNumberOfTuples(),6); - self.assertEqual(f2.getNumberOfTuples(),6); - self.assertEqual(2,m2.getMeshDimension()); - self.assertEqual(2,m2.getSpaceDimension()); - for i in xrange(6): - self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); - pass - # - da=DataArrayDouble.New(); - da.setValues(discZ,5,1); - m.setCoordsAt(2,da); - m2=m.buildUnstructured(); - m2.checkCoherency(); - f1=m.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(f1.getNumberOfTuples(),24); - self.assertEqual(f2.getNumberOfTuples(),24); - self.assertEqual(3,m2.getMeshDimension()); - self.assertEqual(3,m2.getSpaceDimension()); - for i in xrange(24): - self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); - pass - # - pos1=[5.,30.,2.] - self.assertEqual(16,m.getCellContainingPoint(pos1,1e-12)); - # - elems=m2.getCellsInBoundingBox([3.5,6.,12.2,25.,0.,1.5],1e-7) - self.assertEqual([1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17],elems.getValues()) - # - pt=[2.4,12.7,-3.4] - m.scale(pt,3.7); - m3=m.buildUnstructured(); - m2.scale(pt,3.7); - self.assertTrue(m3.isEqual(m2,1e-12)); - pass - - def testDataArrayIntInvertO2NNO21(self): - arr1=[2,0,4,1,5,3] - da=DataArrayInt.New(); - da.setValues(arr1,6,1); - da2=da.invertArrayO2N2N2O(6); - self.assertEqual(6,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[1,3,0,5,2,4] - for i in xrange(6): - self.assertEqual(expected1[i],da2.getIJ(i,0)); - pass - da3=da2.invertArrayN2O2O2N(6); - for i in xrange(6): - self.assertEqual(arr1[i],da3.getIJ(i,0)); - pass - # - arr2=[3,-1,5,4,-1,0,-1,1,2,-1] - da=DataArrayInt.New(); - da.setValues(arr2,10,1); - da2=da.invertArrayO2N2N2O(6); - self.assertEqual(6,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected2=[5,7,8,0,3,2] - for i in xrange(6): - self.assertEqual(expected2[i],da2.getIJ(i,0)); - pass - da3=da2.invertArrayN2O2O2N(10); - for i in xrange(10): - self.assertEqual(arr2[i],da3.getIJ(i,0)); - pass - pass - - def testKeepSetSelectedComponent1(self): - arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] - a1=DataArrayDouble.New(); - a1.setValues(arr1,5,4); - expp=[21.,22.,23.,24.] - self.assertEqual(4,len(a1.getTuple(2))); - for i in xrange(4): - self.assertAlmostEqual(expp[i],a1.getTuple(2)[i],12) - pass - a1.setInfoOnComponent(0,"aaaa"); - a1.setInfoOnComponent(1,"bbbb"); - a1.setInfoOnComponent(2,"cccc"); - a1.setInfoOnComponent(3,"dddd"); - arr2V=[1,2,1,2,0,0] - a2=a1.keepSelectedComponents(arr2V); - self.assertEqual(6,a2.getNumberOfComponents()); - self.assertEqual(5,a2.getNumberOfTuples()); - self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a2.getInfoOnComponent(1)=="cccc"); - self.assertTrue(a2.getInfoOnComponent(2)=="bbbb"); - self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); - expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],a2.getIJ(0,i),14); - pass - a3=a1.convertToIntArr(); - self.assertEqual([21,22,23,24],a3.getTuple(2)) - a4=a3.keepSelectedComponents(arr2V); - self.assertEqual(6,a4.getNumberOfComponents()); - self.assertEqual(5,a4.getNumberOfTuples()); - self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a4.getInfoOnComponent(1)=="cccc"); - self.assertTrue(a4.getInfoOnComponent(2)=="bbbb"); - self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); - for i in xrange(30): - self.assertEqual(int(expected1[i]),a4.getIJ(0,i)); - pass - # setSelectedComponents - arr3V=[3,2] - a5=a1.keepSelectedComponents(arr3V); - a5.setInfoOnComponent(0,"eeee"); - a5.setInfoOnComponent(1,"ffff"); - arr4V=[1,2] - a2.setSelectedComponents(a5,arr4V); - self.assertEqual(6,a2.getNumberOfComponents()); - self.assertEqual(5,a2.getNumberOfTuples()); - self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a2.getInfoOnComponent(1)=="eeee"); - self.assertTrue(a2.getInfoOnComponent(2)=="ffff"); - self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); - expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],a2.getIJ(0,i),14); - pass - a6=a5.convertToIntArr(); - a6.setInfoOnComponent(0,"eeee"); - a6.setInfoOnComponent(1,"ffff"); - a4.setSelectedComponents(a6,arr4V); - self.assertEqual(6,a4.getNumberOfComponents()); - self.assertEqual(5,a4.getNumberOfTuples()); - self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a4.getInfoOnComponent(1)=="eeee"); - self.assertTrue(a4.getInfoOnComponent(2)=="ffff"); - self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); - for i in xrange(30): - self.assertEqual(int(expected2[i]),a4.getIJ(0,i)); - pass - # test of throw - arr5V=[2,3,6] - arr6V=[2,7,5] - arr7V=[2,1,4,6] - self.assertRaises(InterpKernelException,a2.keepSelectedComponents,arr5V); - self.assertRaises(InterpKernelException,a2.keepSelectedComponents,arr6V); - self.assertRaises(InterpKernelException,a2.setSelectedComponents,a1,arr7V); - arr7V=arr7V[0:3] - self.assertRaises(InterpKernelException,a2.setSelectedComponents,a1,arr7V); - # - pass - - def testKeepSetSelectedComponent2(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] - a1=DataArrayDouble.New(); - a1.setValues(arr1,5,4); - a1.setInfoOnComponent(0,"aaaa"); - a1.setInfoOnComponent(1,"bbbb"); - a1.setInfoOnComponent(2,"cccc"); - a1.setInfoOnComponent(3,"dddd"); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,4,5); - f1.setMesh(m1); - f1.setName("f1"); - f1.setArray(a1); - f1.checkCoherency(); - # - arr2V=[1,2,1,2,0,0] - f2=f1.keepSelectedComponents(arr2V); - self.assertTrue(f2.getTimeDiscretization()==ONE_TIME); - t,dt,it=f2.getTime() - self.assertAlmostEqual(2.3,t,13); - self.assertEqual(4,dt); - self.assertEqual(5,it); - f2.checkCoherency(); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); - self.assertTrue(f2.getArray().getInfoOnComponent(1)=="cccc"); - self.assertTrue(f2.getArray().getInfoOnComponent(2)=="bbbb"); - self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); - self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); - self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); - expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],f2.getIJ(0,i),14); - pass - #setSelectedComponents - arr3V=[3,2] - f5=f1.keepSelectedComponents(arr3V); - f5.setTime(6.7,8,9); - f5.getArray().setInfoOnComponent(0,"eeee"); - f5.getArray().setInfoOnComponent(1,"ffff"); - f5.checkCoherency(); - arr4V=[1,2] - f2.setSelectedComponents(f5,arr4V); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - f2.checkCoherency(); - t,dt,it=f2.getTime() - self.assertAlmostEqual(2.3,t,13); - self.assertEqual(4,dt); - self.assertEqual(5,it); - self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); - self.assertTrue(f2.getArray().getInfoOnComponent(1)=="eeee"); - self.assertTrue(f2.getArray().getInfoOnComponent(2)=="ffff"); - self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); - self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); - self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); - expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),14); - pass - # - pass - - def testElementaryDAThrowAndSpecialCases(self): - da=DataArrayInt.New(); - self.assertRaises(InterpKernelException, da.checkAllocated); - self.assertRaises(InterpKernelException, da.fillWithValue, 1); - self.assertRaises(InterpKernelException, da.iota, 1); - da.alloc(7,1); - da.fillWithValue(11); #11,11,11,11... - da.iota(10); #10,11,12,13... - - db=DataArrayInt.New(); - db.alloc(7,2); - - dbl2=DataArrayDouble.New(); - dbl2.alloc(7,2); - self.assertRaises(InterpKernelException, dbl2.isUniform, 10., 1e-15); - self.assertRaises(InterpKernelException, dbl2.sort); - self.assertRaises(InterpKernelException, dbl2.iota, 10.); - - dbl=DataArrayDouble.New(); - #DataArrayDouble not allocated yet - self.assertRaises(InterpKernelException, dbl.iota, 10.); - self.assertRaises(InterpKernelException, dbl.isUniform, 10., 1e-15); - self.assertRaises(InterpKernelException, dbl.sort); - self.assertRaises(InterpKernelException, dbl.fromNoInterlace); - self.assertRaises(InterpKernelException, dbl.toNoInterlace); - - dbl.alloc(7,1); - dbl.iota(10.); - self.assertTrue(not dbl.isUniform(10.,1e-15)); - dbl.sort(); - self.assertTrue(dbl.isMonotonic(True, .99)); - self.assertTrue(dbl.isMonotonic(True, -.99)); - self.assertTrue(not dbl.isMonotonic(True, 1.1)); - self.assertTrue(not dbl.isMonotonic(True, -1.1)); - dbl.reverse(); - self.assertTrue(dbl.isMonotonic(False, .99)); - self.assertTrue(not dbl.isMonotonic(False, 1.1)); - self.assertTrue(not dbl.isMonotonic(False, -1.1)); - - dc=DataArrayInt.New(); - dc.alloc(14,1); - - dd=DataArrayDouble.New(); - self.assertRaises(InterpKernelException, dd.checkAllocated); - self.assertRaises(InterpKernelException, dd.fillWithValue, 1.); - self.assertRaises(InterpKernelException, dd.iota, 1.); - self.assertTrue(not ((dd.repr().find("No data"))==-1)); - - dd.alloc(0,1); #Allocated but nbOfElements==0! - self.assertTrue(not ((dd.repr().find("Number of tuples : 0"))==-1)); - self.assertTrue(not ((dd.repr().find("Empty Data"))==-1)); - dd.fillWithValue(11); #?!...ok - dd.iota(10); #?!...ok - self.assertTrue(dd.isMonotonic(True, 1.)); #nothing is monotonic - self.assertTrue(dd.isMonotonic(False, 1.)); - - self.assertRaises(InterpKernelException, db.copyStringInfoFrom, da); - self.assertRaises(InterpKernelException, db.copyStringInfoFrom, da); - cIds=[2,2] - self.assertRaises(InterpKernelException, da.copyPartOfStringInfoFrom, db, cIds); - cIds[0]=1; - cIds[0]=-1; - self.assertRaises(InterpKernelException, da.copyPartOfStringInfoFrom, db, cIds); - - info=["infoOfOneComponent"]*2; - self.assertRaises(InterpKernelException, da.setInfoOnComponents, info); - self.assertRaises(InterpKernelException, da.setInfoOnComponent, 1, info[0]); - db.setInfoOnComponents(info); - - self.assertRaises(InterpKernelException, da.getInfoOnComponent, -1); - self.assertRaises(InterpKernelException, da.getInfoOnComponent, 2); - self.assertTrue(db.getInfoOnComponent(1)==db.getInfoOnComponent(0)); - self.assertRaises(InterpKernelException, db.getVarOnComponent, -1); - self.assertRaises(InterpKernelException, db.getVarOnComponent, 2); - self.assertRaises(InterpKernelException, db.getUnitOnComponent, -1); - self.assertRaises(InterpKernelException, db.getUnitOnComponent, 2); - - self.assertTrue(da.GetVarNameFromInfo("varname unit ")=="varname unit "); - self.assertTrue(da.GetVarNameFromInfo("varname]unit[")=="varname]unit["); - self.assertTrue(da.GetVarNameFromInfo("[unit]")==""); - self.assertTrue(da.GetVarNameFromInfo("varname [unit]")=="varname"); - - self.assertTrue(da.GetUnitFromInfo("varname unit ")==""); - self.assertTrue(da.GetUnitFromInfo("varname]unit[")==""); - self.assertTrue(da.GetUnitFromInfo("[unit]")=="unit"); - self.assertTrue(da.GetUnitFromInfo("varname [unit]")=="unit"); - - self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, db, "theMessageInThrow"); - self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, dc, "theMessageInThrow"); - self.assertRaises(InterpKernelException, db.checkNbOfTuplesAndComp, dc, "theMessageInThrow"); - - self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, 7, 2, "theMessageInThrow"); - da.checkNbOfTuplesAndComp(7,1,"theMessageInThrow"); - - self.assertRaises(InterpKernelException, db.checkNbOfElems, 7*2+1, "theMessageInThrow"); - db.checkNbOfElems(7*2,"theMessageInThrow"); - - self.assertRaises(InterpKernelException, db.GetNumberOfItemGivenBES, 10, 9, 1, "theMessageInThrow"); - self.assertRaises(InterpKernelException, db.GetNumberOfItemGivenBES, 0, 1, -1, "theMessageInThrow"); - self.assertEqual(10,db.GetNumberOfItemGivenBES(0,10,1,"theMessageInThrow")); - self.assertEqual(5,db.GetNumberOfItemGivenBES(0,10,2,"theMessageInThrow")); - self.assertEqual(6,db.GetNumberOfItemGivenBES(0,11,2,"theMessageInThrow")); - - self.assertTrue(not ((da.repr().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dd.repr().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dbl.repr().find("Number of components : 1"))==-1)); - - self.assertTrue(not ((da.reprZip().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dd.reprZip().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dbl.reprZip().find("Number of components : 1"))==-1)); - - self.assertRaises(InterpKernelException, dbl.selectByTupleId2, 0, 1, -1); - self.assertRaises(InterpKernelException, dbl.substr, -1, 1); - self.assertRaises(InterpKernelException, dbl.substr, 8, 1); - self.assertRaises(InterpKernelException, dbl.substr, 0, 8); - self.assertRaises(InterpKernelException, dbl.meldWith, dd); - - self.assertRaises(InterpKernelException, dbl.setPartOfValuesAdv, dbl2, da); #dbl dbl2 not have the same number of components - self.assertRaises(InterpKernelException, dbl.setPartOfValuesAdv, dd, da); #da tuple selector DataArrayInt instance not have exactly 2 components - - dbl3=DataArrayDouble.New(); - dbl3.alloc(6,2); - dbl3.fillWithValue(11.); - #bad number of components - self.assertRaises(InterpKernelException, dbl3.getMaxValue); - self.assertRaises(InterpKernelException, dd.getMaxValue); - self.assertRaises(InterpKernelException, dbl3.getMinValue); - self.assertRaises(InterpKernelException, dd.getMinValue); - self.assertRaises(InterpKernelException, dbl3.getAverageValue); - self.assertRaises(InterpKernelException, dd.getAverageValue); - self.assertRaises(InterpKernelException, dd.accumulate, 100); - self.assertRaises(InterpKernelException, dbl.fromPolarToCart); - self.assertRaises(InterpKernelException, dbl3.fromCylToCart); - self.assertRaises(InterpKernelException, dbl3.fromSpherToCart); - self.assertRaises(InterpKernelException, dbl3.doublyContractedProduct); - self.assertRaises(InterpKernelException, dbl3.determinant); - self.assertRaises(InterpKernelException, dbl3.eigenValues); - self.assertRaises(InterpKernelException, dbl3.eigenVectors); - self.assertRaises(InterpKernelException, dbl3.inverse); - self.assertRaises(InterpKernelException, dbl3.trace); - self.assertRaises(InterpKernelException, dbl3.deviator); - - dbl3.setIJ(5,1,12.); - self.assertTrue(dbl3.getMaxValueInArray()==12.); - self.assertTrue(dbl3.getMinValueInArray()==11.); - - db.fillWithValue(100); #bad Ids - self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); - db.fillWithValue(-1); #bad Ids - self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); - db.fillWithValue(6); #bad Ids for dbl3 - self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); - - dbl3.checkNoNullValues(); - dbl3.setIJ(5,0,0.); - self.assertRaises(InterpKernelException, dbl3.checkNoNullValues); - self.assertRaises(InterpKernelException, dbl3.applyInv, 1.); #div by zero - self.assertRaises(InterpKernelException, dbl2.getIdsInRange, 1., 2.); - a=[] - self.assertRaises(InterpKernelException, DataArrayDouble_Aggregate, a); - self.assertRaises(InterpKernelException, DataArrayDouble_Meld, a); - - a=[dbl2,dbl]; #Nb of components mismatch - self.assertRaises(InterpKernelException, DataArrayDouble_Aggregate, a); - - self.assertRaises(InterpKernelException, DataArrayDouble_Dot, dbl2, dbl); - - self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl2, dbl); #Nb of components mismatch - self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl2, dbl2); #Nb of components must be equal to 3 - dbl4=DataArrayDouble.New(); - dbl4.alloc(6,3); - dbl5=DataArrayDouble.New(); - dbl5.alloc(7,3); - self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl4, dbl5); #Nb of tuples mismatch - - a[0]=dbl4; #Nb of tuple mismatch - a[1]=dbl5; #Nb of tuple mismatch - self.assertRaises(InterpKernelException, DataArrayDouble_Meld, a); - self.assertRaises(InterpKernelException, DataArrayDouble_Dot, dbl4, dbl5); - pass - - def testDAIGetIdsEqual1(self): - tab1=[5,-2,-4,-2,3,2,-2]; - da=DataArrayInt.New(); - da.setValues(tab1,7,1); - da2=da.getIdsEqual(-2); - self.assertEqual(3,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[1,3,6]; - self.assertEqual(expected1,da2.getValues()); - pass - - def testDAIGetIdsEqualList1(self): - tab1=[5,-2,-4,-2,3,2,-2]; - da=DataArrayInt.New(); - da.setValues(tab1,7,1); - da2=da.getIdsEqualList([3,-2,0]); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[1,3,4,6]; - self.assertEqual(expected1,da2.getValues()); - pass - - def testDAFromNoInterlace1(self): - tab1=[1,11,21,31,41,2,12,22,32,42,3,13,23,33,43] - da=DataArrayInt.New(); - da.setValues(tab1,5,3); - da2=da.fromNoInterlace(); - expected1=[1,2,3,11,12,13,21,22,23,31,32,33,41,42,43] - self.assertEqual(5,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - self.assertEqual(expected1,da2.getValues()); - da3=da.convertToDblArr(); - da4=da3.fromNoInterlace(); - self.assertEqual(5,da4.getNumberOfTuples()); - self.assertEqual(3,da4.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - for i in xrange(15): - self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),14); - pass - pass - - def testDAToNoInterlace1(self): - tab1=[1,2,3,11,12,13,21,22,23,31,32,33,41,42,43] - da=DataArrayInt.New(); - da.setValues(tab1,5,3); - da2=da.toNoInterlace(); - expected1=[1,11,21,31,41,2,12,22,32,42,3,13,23,33,43] - self.assertEqual(5,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - self.assertEqual(expected1,da2.getValues()); - da3=da.convertToDblArr(); - da4=da3.toNoInterlace(); - self.assertEqual(5,da4.getNumberOfTuples()); - self.assertEqual(3,da4.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - for i in xrange(15): - self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),14); - pass - pass - - def testDAIsUniform1(self): - tab1=[1,1,1,1,1] - da=DataArrayInt.New(); - da.setValues(tab1,5,1); - self.assertTrue(da.isUniform(1)); - da.setIJ(2,0,2); - self.assertTrue(not da.isUniform(1)); - da.setIJ(2,0,1); - self.assertTrue(da.isUniform(1)); - da2=da.convertToDblArr(); - self.assertTrue(da2.isUniform(1.,1.e-12)); - da2.setIJ(1,0,1.+1.e-13); - self.assertTrue(da2.isUniform(1.,1.e-12)); - da2.setIJ(1,0,1.+1.e-11); - self.assertTrue(not da2.isUniform(1.,1.e-12)); - pass - - def testDADFromPolarToCart1(self): - tab1=[2.,0.2,2.5,0.7] - da=DataArrayDouble.New(); - da.setValues(tab1,2,2); - da2=da.fromPolarToCart(); - expected1=[1.9601331556824833,0.39733866159012243, 1.9121054682112213,1.6105442180942275] - for i in xrange(4): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); - pass - pass - - def testDADFromCylToCart1(self): - tab1=[2.,0.2,4.,2.5,0.7,9.] - da=DataArrayDouble.New(); - da.setValues(tab1,2,3); - da2=da.fromCylToCart(); - expected1=[1.9601331556824833,0.39733866159012243,4., 1.9121054682112213,1.6105442180942275,9.] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); - pass - pass - - def testDADFromSpherToCart1(self): - tab1=[2.,0.2,0.3,2.5,0.7,0.8] - da=DataArrayDouble.New(); - da.setValues(tab1,2,3); - da2=da.fromSpherToCart(); - expected1=[0.37959212195737485,0.11742160338765303,1.9601331556824833, 1.1220769624465328,1.1553337045129035,1.9121054682112213] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); - pass - pass - - def testUnPolyze1(self): - elts=[0,1,2,3,4,5,6,7] - eltsV=elts; - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh.convertToPolyTypes(eltsV); - mesh.unPolyze(); - mesh2=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh.checkCoherency(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - mesh.convertToPolyTypes(eltsV); - self.assertTrue(not mesh.isEqual(mesh2,1e-12)); - mesh.getNodalConnectivity().setIJ(0,6,10); - mesh.getNodalConnectivity().setIJ(0,7,9); - mesh.getNodalConnectivity().setIJ(0,8,12); - mesh.getNodalConnectivity().setIJ(0,9,13); - mesh.unPolyze(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - mesh.convertToPolyTypes(eltsV); - mesh.getNodalConnectivity().setIJ(0,6,12); - mesh.getNodalConnectivity().setIJ(0,7,13); - mesh.getNodalConnectivity().setIJ(0,8,10); - mesh.getNodalConnectivity().setIJ(0,9,9); - mesh.unPolyze(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - mesh.convertToPolyTypes(eltsV); - mesh.getNodalConnectivity().setIJ(0,6,12); - mesh.getNodalConnectivity().setIJ(0,7,10); - mesh.getNodalConnectivity().setIJ(0,8,13); - mesh.getNodalConnectivity().setIJ(0,9,9); - mesh.unPolyze(); - self.assertTrue(not mesh.isEqual(mesh2,1e-12)); - # Test for 2D mesh - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - eltsV=eltsV[:5]; - mesh.convertToPolyTypes(eltsV); - self.assertTrue(not mesh.isEqual(mesh2,1e-12)); - mesh.unPolyze(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - pass - - def testConvertDegeneratedCells1(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - conn=[0,1,3,3,9,10,12,12, 0,1,3,4,9,9,9,9, 1,1,1,1,10,12,9,10, 10,11,12,9,1,1,1,1] - mesh.allocateCells(4); - mesh.insertNextCell(NORM_HEXA8,8,conn[0:8]) - mesh.insertNextCell(NORM_HEXA8,8,conn[8:16]) - mesh.insertNextCell(NORM_HEXA8,8,conn[16:24]) - mesh.insertNextCell(NORM_HEXA8,8,conn[24:32]) - mesh.finishInsertingCells(); - mesh.checkCoherency(); - self.assertEqual(4,mesh.getNumberOfCells()); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(0)); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(1)); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(2)); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(3)); - f1=mesh.getMeasureField(True); - mesh.convertDegeneratedCells(); - mesh.checkCoherency(); - f2=mesh.getMeasureField(True); - self.assertEqual(4,mesh.getNumberOfCells()); - self.assertEqual(NORM_PENTA6,mesh.getTypeOfCell(0)); - self.assertEqual(NORM_PYRA5,mesh.getTypeOfCell(1)); - self.assertEqual(NORM_TETRA4,mesh.getTypeOfCell(2)); - self.assertEqual(NORM_PYRA5,mesh.getTypeOfCell(3)); - for i in xrange(4): - self.assertAlmostEqual(f1.getArray().getIJ(0,i),f2.getArray().getIJ(0,i),5); - pass - pass - - def testGetNodeIdsNearPoints1(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - coords=mesh.getCoords(); - tmp=DataArrayDouble.New(); - vals=[0.2,0.2,0.1,0.2,0.2,0.2] - tmp.setValues(vals,3,2); - tmp2=DataArrayDouble.Aggregate(coords,tmp); - mesh.setCoords(tmp2); - pts=[0.2,0.2,0.1,0.3,-0.3,0.7] - c=mesh.getNodeIdsNearPoint(pts[:2],1e-7); - self.assertEqual([4,9,11],c.getValues()); - c,cI=mesh.getNodeIdsNearPoints(pts,3,1e-7); - self.assertEqual([0,3,3,4],cI.getValues()); - self.assertEqual([4,9,11,6],c.getValues()); - c,cI=mesh.getNodeIdsNearPoints(pts,1e-7); - self.assertEqual([0,3,3,4],cI.getValues()); - self.assertEqual([4,9,11,6],c.getValues()); - c,cI=mesh.getNodeIdsNearPoints(DataArrayDouble.New(pts,3,2),1e-7); - self.assertEqual([0,3,3,4],cI.getValues()); - self.assertEqual([4,9,11,6],c.getValues()); - self.assertRaises(InterpKernelException,mesh.getNodeIdsNearPoints,DataArrayDouble.New(pts,2,3),1e-7); - pass - - def testFieldCopyTinyAttrFrom1(self): - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f1.setTime(1.23,4,5); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTime(6.78,9,10); - f2.setTimeTolerance(4.556e-12); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - t,dt,it=f1.getTime() - self.assertAlmostEqual(6.78,t,12); - self.assertEqual(9,dt); - self.assertEqual(10,it); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTimeTolerance(4.556e-12); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f1.setTime(1.23,4,5); - f1.setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTimeTolerance(4.556e-12); - f2.setTime(6.78,9,10); - f2.setEndTime(10.98,7,6); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - t,dt,it=f1.getTime() - self.assertAlmostEqual(6.78,t,12); - self.assertEqual(9,dt); - self.assertEqual(10,it); - t,dt,it=f1.getEndTime() - self.assertAlmostEqual(10.98,t,12); - self.assertEqual(7,dt); - self.assertEqual(6,it); - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f1.setTime(1.23,4,5); - f1.setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTimeTolerance(4.556e-12); - f2.setTime(6.78,9,10); - f2.setEndTime(10.98,7,6); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - t,dt,it=f1.getTime() - self.assertAlmostEqual(6.78,t,12); - self.assertEqual(9,dt); - self.assertEqual(10,it); - t,dt,it=f1.getEndTime() - self.assertAlmostEqual(10.98,t,12); - self.assertEqual(7,dt); - self.assertEqual(6,it); - pass - - def testExtrudedMesh5(self): - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - c=b.buildUnstructured(); - self.assertEqual(1,c.getSpaceDimension()); - c.changeSpaceDimension(2); - # - d=DataArrayDouble.New(); - d.alloc(13,1); - d.iota(); - e=MEDCouplingCMesh.New(); - e.setCoordsAt(0,d); - f=e.buildUnstructured(); - g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - self.assertRaises(InterpKernelException,f.getCoords().applyFunc,2,"3.5*IVec+x/6*3.14159265359*KVec"); # KVec refers to component #2 and there is only 2 components ! - h=g.fromPolarToCart(); - f.setCoords(h); - i=c.buildExtrudedMesh(f,1); - self.assertEqual(52,i.getNumberOfNodes()); - tmp,tmp2,tmp3=i.mergeNodes(1e-9); - self.assertTrue(tmp2); - self.assertEqual(37,tmp3); - i.convertDegeneratedCells(); - i.checkCoherency(); - self.assertEqual(36,i.getNumberOfCells()); - self.assertEqual(37,i.getNumberOfNodes()); - self.assertEqual(12,i.getNumberOfCellsWithType(NORM_TRI3)); - self.assertEqual(24,i.getNumberOfCellsWithType(NORM_QUAD4)); - expected1=[0.25,0.75,2.0625] - j=i.getMeasureField(True); - for ii in xrange(12): - for k in xrange(3): - self.assertAlmostEqual(expected1[k],j.getIJ(0,ii*3+k),10); - pass - pass - expected2=[0.62200846792814113, 0.16666666666681595, 1.4513530918323276, 0.38888888888923495, 2.6293994326053212, 0.7045454545460802, 0.45534180126145435, 0.45534180126150181, 1.0624642029433926, 1.0624642029435025, 1.9248539780597826, 1.9248539780599816, 0.16666666666661334, 0.62200846792815856, 0.38888888888876294, 1.4513530918323678, 0.70454545454522521, 2.629399432605394, -0.16666666666674007, 0.62200846792812436, -0.38888888888906142, 1.4513530918322881, -0.70454545454576778, 2.6293994326052488, -0.45534180126154766, 0.45534180126140844, -1.0624642029436118, 1.0624642029432834, -1.9248539780601803, 1.9248539780595841, -0.62200846792817499, 0.1666666666665495, -1.451353091832408, 0.388888888888613, -2.6293994326054668, 0.70454545454495332, -0.62200846792810593, -0.16666666666680507, -1.451353091832247, -0.38888888888921297, -2.6293994326051746, -0.70454545454604123, -0.45534180126135926, -0.45534180126159562, -1.0624642029431723, -1.0624642029437235, -1.9248539780593836, -1.9248539780603811, -0.1666666666664828, -0.62200846792819242, -0.38888888888846079, -1.4513530918324489, -0.70454545454467987, -2.6293994326055397, 0.16666666666687083, -0.62200846792808862, 0.38888888888936374, -1.4513530918322073, 0.70454545454631357, -2.6293994326051022, 0.45534180126164348, -0.45534180126131207, 1.0624642029438327, -1.0624642029430627, 1.9248539780605791, -1.9248539780591853, 0.62200846792821063, -0.16666666666641802, 1.4513530918324888, -0.38888888888831086, 2.6293994326056125, -0.70454545454440853] - m=i.getBarycenterAndOwner(); - for i in xrange(72): - self.assertAlmostEqual(expected2[i],m.getIJ(0,i),10); - pass - # - pass - - def testExtrudedMesh6(self): - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - c=b.buildUnstructured(); - self.assertEqual(1,c.getSpaceDimension()); - c.changeSpaceDimension(2); - # - d=DataArrayDouble.New(); - d.alloc(5); - d.iota(); - e=MEDCouplingCMesh.New(); - e.setCoordsAt(0,d); - f=e.buildUnstructured(); - d2=f.getCoords().applyFunc("x*x/2"); - f.setCoords(d2); - f.changeSpaceDimension(2); - # - center=[0.,0.] - f.rotate(center,None,pi/3); - g=c.buildExtrudedMesh(f,0); - g.checkCoherency(); - expected1=[ 0.4330127018922193, 0.4330127018922193, 0.649519052838329, 1.2990381056766578, 1.299038105676658, 1.948557158514987, 2.1650635094610955, 2.1650635094610964, 3.2475952641916446, 3.031088913245533, 3.0310889132455352, 4.546633369868303 ] - f1=g.getMeasureField(True); - for i in xrange(12): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),12); - pass - expected2=[0.625, 0.21650635094610962, 1.625, 0.21650635094610959, 2.8750000000000004, 0.21650635094610965, 1.1250000000000002, 1.0825317547305482, 2.125, 1.0825317547305482, 3.3750000000000004, 1.0825317547305484, 2.125, 2.8145825622994254, 3.125, 2.8145825622994254, 4.375, 2.8145825622994254, 3.6250000000000009, 5.4126587736527414, 4.625, 5.4126587736527414, 5.875, 5.4126587736527414] - f2=g.getBarycenterAndOwner(); - for i in xrange(24): - self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),12); - pass - pass - - def testExtrudedMesh7(self): - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - c=b.buildUnstructured(); - self.assertEqual(1,c.getSpaceDimension()); - c.changeSpaceDimension(2); - # - d=DataArrayDouble.New(); - d.alloc(13,1); - d.iota(); - e=MEDCouplingCMesh.New(); - e.setCoordsAt(0,d); - f=e.buildUnstructured(); - g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - h=g.fromPolarToCart(); - f.setCoords(h); - i=c.buildExtrudedMesh(f,1); - self.assertEqual(52,i.getNumberOfNodes()); - tmp,tmp2,tmp3=i.mergeNodes(1e-9); - self.assertTrue(tmp2); - self.assertEqual(37,tmp3); - i.convertDegeneratedCells(); - vec1=[10.,0] - i.translate(vec1); - g2=h.applyFunc(3,"13.5/3.5*x*IVec+0*JVec+13.5/3.5*y*KVec"); - f.setCoords(g2); - i.changeSpaceDimension(3); - i3=i.buildExtrudedMesh(f,1); - f2=i3.getMeasureField(True); - tmp,tmp2,tmp3=i.mergeNodes(1e-9); - self.assertTrue(tmp2); - self.assertEqual(444,tmp3); - expected1=[1.327751058489274, 4.2942574094314701, 13.024068164857139, 1.3069177251569044, 4.1484240761012954, 12.297505664866796, 1.270833333332571, 3.8958333333309674, 11.039062499993179, 1.2291666666659207, 3.6041666666644425, 9.585937499993932, 1.1930822748415895, 3.3515759238941376, 8.3274943351204556, 1.1722489415082769, 3.2057425905609289, 7.6009318351210622, 1.1722489415082862, 3.2057425905609884, 7.6009318351213713, 1.1930822748416161, 3.3515759238943001, 8.3274943351212727, 1.2291666666659564, 3.6041666666646734, 9.5859374999950777, 1.2708333333326081, 3.8958333333311868, 11.039062499994293, 1.3069177251569224, 4.1484240761014384, 12.297505664867627, 1.3277510584902354, 4.2942574094346071, 13.024068164866796] - for ii in xrange(12): - for jj in xrange(36): - self.assertAlmostEqual(expected1[jj],f2.getIJ(0,ii*36+jj),9); - pass - # - pass - - def testSimplexize1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.convertToPolyTypes([3]); - da=m.simplexize(0); - self.assertEqual(7,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - expected2=[0,0,1,2,3,4,4] - for i in xrange(7): - self.assertEqual(expected2[i],da.getIJ(i,0)); - pass - m.checkCoherency(); - self.assertEqual(7,m.getNumberOfCells()); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(0)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(2)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); - self.assertEqual(NORM_POLYGON,m.getTypeOfCell(4)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(5)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(6)); - expected1=[0.125,0.125,0.125,0.125,0.25,0.125,0.125] - f=m.getMeasureField(False); - for i in xrange(7): - self.assertAlmostEqual(expected1[i]*sqrt(2.),f.getIJ(i,0),10); - pass - types=m.getAllGeoTypes(); - self.assertEqual([NORM_TRI3,NORM_POLYGON],types); - # - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.convertToPolyTypes([3]); - da=m.simplexize(1); - self.assertEqual(7,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(7): - self.assertEqual(expected2[i],da.getIJ(i,0)); - pass - m.checkCoherency(); - types=m.getAllGeoTypes(); - self.assertEqual([NORM_TRI3,NORM_POLYGON],types); - self.assertEqual(7,m.getNumberOfCells()); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(0)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(2)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); - self.assertEqual(NORM_POLYGON,m.getTypeOfCell(4)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(5)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(6)); - f=m.getMeasureField(False); - for i in xrange(7): - self.assertAlmostEqual(expected1[i]*sqrt(2.),f.getIJ(i,0),10); - pass - pass - - def testSimplexize2(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.convertToPolyTypes([3]); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m); - arr=DataArrayDouble.New(); - arr1=[10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] - arr.setValues(arr1,5,2); - f1.setArray(arr); - # - f1.checkCoherency(); - self.assertTrue(f1.simplexize(0)); - f1.checkCoherency(); - expected1=[10.,110.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.,50.,150.] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),10); - pass - self.assertTrue(not f1.simplexize(0)); - for i in xrange(14): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),10); - pass - # - pass - - def testDAMeld1(self): - da1=DataArrayDouble.New(); - da1.alloc(7,2); - da2=DataArrayDouble.New(); - da2.alloc(7,1); - # - da1.fillWithValue(7.); - da2.iota(0.); - da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); - # - da1.setInfoOnComponent(0,"c0da1"); - da1.setInfoOnComponent(1,"c1da1"); - da3.setInfoOnComponent(0,"c0da3"); - da3.setInfoOnComponent(1,"c1da3"); - da3.setInfoOnComponent(2,"c2da3"); - # - da1C=da1.deepCpy(); - da1.meldWith(da3); - self.assertEqual(5,da1.getNumberOfComponents()); - self.assertEqual(7,da1.getNumberOfTuples()); - self.assertTrue(da1.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(da1.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(da1.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(da1.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(da1.getInfoOnComponent(4)=="c2da3"); - # - expected1=[7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.] - for i in xrange(35): - self.assertAlmostEqual(expected1[i],da1.getIJ(0,i),10); - pass - # - dai1=da1C.convertToIntArr(); - dai3=da3.convertToIntArr(); - dai1.meldWith(dai3); - self.assertEqual(5,dai1.getNumberOfComponents()); - self.assertEqual(7,dai1.getNumberOfTuples()); - self.assertTrue(dai1.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(dai1.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(dai1.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(dai1.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(dai1.getInfoOnComponent(4)=="c2da3"); - for i in xrange(35): - self.assertEqual(int(expected1[i]),dai1.getIJ(0,i)); - pass - # test of static method DataArrayDouble::meld - da4=DataArrayDouble.Meld(da1C,da3); - tmp=DataArrayDouble.Meld([da1C,da3]); - self.assertTrue(da4.isEqual(tmp,1e-10)) - self.assertEqual(5,da4.getNumberOfComponents()); - self.assertEqual(7,da4.getNumberOfTuples()); - self.assertTrue(da4.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(da4.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(da4.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(da4.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(da4.getInfoOnComponent(4)=="c2da3"); - for i in xrange(35): - self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),10); - pass - # test of static method DataArrayInt::meld - dai1=da1C.convertToIntArr(); - dai4=DataArrayInt.Meld(dai1,dai3); - tmp=DataArrayInt.Meld([dai1,dai3]); - self.assertTrue(dai4.isEqual(tmp)) - self.assertEqual(5,dai4.getNumberOfComponents()); - self.assertEqual(7,dai4.getNumberOfTuples()); - self.assertTrue(dai4.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(dai4.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(dai4.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(dai4.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(dai4.getInfoOnComponent(4)=="c2da3"); - for i in xrange(35): - self.assertEqual(int(expected1[i]),dai4.getIJ(0,i)); - pass - pass - - def testFieldMeld1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m); - da1=DataArrayDouble.New(); - arr1=[12.,23.,34.,45.,56.] - da1.setValues(arr1,5,1); - da1.setInfoOnComponent(0,"aaa"); - f1.setArray(da1); - f1.setTime(3.4,2,1); - f1.checkCoherency(); - # - f2=f1.deepCpy(); - f2.setMesh(f1.getMesh()); - f2.checkCoherency(); - f2.changeNbOfComponents(2,5.); - f2.assign(5.); - f2.getArray().setInfoOnComponent(0,"bbb"); - f2.getArray().setInfoOnComponent(1,"ccc"); - f2.checkCoherency(); - # - f3=MEDCouplingFieldDouble.MeldFields(f2,f1); - f3.checkCoherency(); - self.assertEqual(5,f3.getNumberOfTuples()); - self.assertEqual(3,f3.getNumberOfComponents()); - self.assertTrue(f3.getArray().getInfoOnComponent(0)=="bbb"); - self.assertTrue(f3.getArray().getInfoOnComponent(1)=="ccc"); - self.assertTrue(f3.getArray().getInfoOnComponent(2)=="aaa"); - expected1=[5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.] - for i in xrange(15): - self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),12); - pass - time,dt,it=f3.getTime(); - self.assertAlmostEqual(3.4,time,14); - self.assertEqual(2,dt); - self.assertEqual(1,it); - # - f4=f2.buildNewTimeReprFromThis(NO_TIME,False); - f5=f1.buildNewTimeReprFromThis(NO_TIME,False); - f6=MEDCouplingFieldDouble.MeldFields(f4,f5); - f6.checkCoherency(); - self.assertEqual(5,f6.getNumberOfTuples()); - self.assertEqual(3,f6.getNumberOfComponents()); - self.assertTrue(f6.getArray().getInfoOnComponent(0)=="bbb"); - self.assertTrue(f6.getArray().getInfoOnComponent(1)=="ccc"); - self.assertTrue(f6.getArray().getInfoOnComponent(2)=="aaa"); - for i in xrange(15): - self.assertAlmostEqual(expected1[i],f6.getIJ(0,i),12); - pass - # - pass - - def testMergeNodes2(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - vec=[0.002,0.] - m2.translate(vec); - # - m3=MEDCouplingUMesh.MergeUMeshes([m1,m2]); - da,b,newNbOfNodes=m3.mergeNodes2(0.01); - self.assertEqual(9,m3.getNumberOfNodes()); - expected1=[-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7] - for i in xrange(18): - self.assertAlmostEqual(expected1[i],m3.getCoords().getIJ(0,i),13); - pass - # - pass - - def testMergeField2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.fillWithValue(2.); - f1.setArray(arr); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.fillWithValue(5.); - f2.setArray(arr); - f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f3.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.fillWithValue(7.); - f3.setArray(arr); - # - f4=MEDCouplingFieldDouble.MergeFields([f1,f2,f3]); - self.assertEqual(15,f4.getMesh().getNumberOfCells()); - expected1=[2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],f4.getIJ(0,i),13); - pass - # - pass - - def testDAIBuildComplement1(self): - a=DataArrayInt.New(); - tab=[3,1,7,8] - a.setValues(tab,4,1); - b=a.buildComplement(12); - self.assertEqual(8,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[0,2,4,5,6,9,10,11] - for i in xrange(8): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDAIBuildUnion1(self): - a=DataArrayInt.New(); - tab1=[3,1,7,8] - a.setValues(tab1,4,1); - c=DataArrayInt.New(); - tab2=[5,3,0,18,8] - c.setValues(tab2,5,1); - b=a.buildUnion(c); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[0,1,3,5,7,8,18] - for i in xrange(7): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - b=DataArrayInt.BuildUnion([a,c]); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[0,1,3,5,7,8,18] - for i in xrange(7): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDAIBuildIntersection1(self): - a=DataArrayInt.New(); - tab1=[3,1,7,8] - a.setValues(tab1,4,1); - c=DataArrayInt.New(); - tab2=[5,3,0,18,8] - c.setValues(tab2,5,1); - b=a.buildIntersection(c); - self.assertEqual(2,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[3,8] - for i in xrange(2): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - b=DataArrayInt.BuildIntersection([a,c]); - self.assertEqual(2,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[3,8] - for i in xrange(2): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDAIDeltaShiftIndex1(self): - a=DataArrayInt.New(); - tab=[1,3,6,7,7,9,15] - a.setValues(tab,7,1); - b=a.deltaShiftIndex(); - self.assertEqual(6,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[2,3,1,0,2,6] - for i in xrange(6): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDaDoubleSelectByTupleIdSafe1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[4,2,0,6,5] - b=a.selectByTupleIdSafe(arr2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - arr4=[4,-1,0,6,5] - self.assertRaises(InterpKernelException,a.selectByTupleIdSafe,arr4); - arr5=[4,2,0,6,7] - self.assertRaises(InterpKernelException,a.selectByTupleIdSafe,arr5); - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.selectByTupleIdSafe(arr2); - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[5,15,3,13,1,11,7,17,6,16] - for i in xrange(10): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - self.assertRaises(InterpKernelException,c.selectByTupleIdSafe,arr4); - self.assertRaises(InterpKernelException,c.selectByTupleIdSafe,arr5); - pass - - def testAreCellsIncludedIn1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - pt=[1,3] - m2=m.buildPartOfMySelf(pt,True); - ret,tmp=m.areCellsIncludedIn(m2,0) - self.assertTrue(ret); - self.assertEqual(2,tmp.getNumberOfTuples()); - self.assertEqual(1,tmp.getNumberOfComponents()); - self.assertEqual(pt[0],tmp.getIJ(0,0)); - self.assertEqual(pt[1],tmp.getIJ(0,1)); - ret,tmp=m2.areCellsIncludedIn(m,0) - self.assertTrue(not ret); - m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m,m2) - c,cI=m3.findCommonCells(2,m.getNumberOfCells()) - self.assertTrue(c.isEqual(DataArrayInt([1,5,3,6]))) - self.assertTrue(cI.isEqual(DataArrayInt([0,2,4]))) - pass - - def testSwigErrorProtection1(self): - m=MEDCouplingDataForTest.build3DTargetMesh_1(); - m.rotate([0.,0.,0.],[0.3,0.6,1.2],0.37) - m.rotate([0.,0.,0.],[0.3,6,1.2],0.37) - self.assertRaises(InterpKernelException,m.rotate,[0.,0.,0.],(0.3,6,"1.2"),0.37) - self.assertRaises(InterpKernelException,m.rotate,[0.,"0.",0.],[0.3,0.6,1.2],0.37) - self.assertRaises(InterpKernelException,m.rotate,[0.,0.,0.],[0.3,'0.6',1.2],0.37) - m2=m.buildPartOfMySelf([2,5],True) - m3=m.buildPartOfMySelf((2,5),True) - self.assertTrue(m2.isEqual(m3,1e-12)) - self.assertRaises(InterpKernelException,m.buildPartOfMySelf,[2,5.],True) - da1=m.getCoords().keepSelectedComponents([1]) - da2=m.getCoords().keepSelectedComponents((1,)) - self.assertTrue(da1.isEqual(da2,1e-12)) - self.assertRaises(InterpKernelException,m.getCoords().keepSelectedComponents,["1"]) - pass - - def testDAIBuildSubstraction1(self): - a=DataArrayInt.New() - aa=[2,3,6,8,9] - a.setValues(aa,5,1) - b=DataArrayInt.New() - bb=[1,3,5,9,11] - b.setValues(bb,5,1) - self.assertEqual([2,6,8],a.buildSubstraction(b).getValues()) - pass - - def testBuildOrthogonalField2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - d1=DataArrayInt.New(); - d2=DataArrayInt.New(); - d3=DataArrayInt.New(); - d4=DataArrayInt.New(); - m1=m.buildDescendingConnectivity(d1,d2,d3,d4); - # - f1=m1.buildOrthogonalField(); - da1=f1.getArray(); - self.assertEqual(2,da1.getNumberOfComponents()); - self.assertEqual(13,da1.getNumberOfTuples()); - # - expected1=[-1.,0.,0.,1.,1.,0.,0.,-1.,0.707106781186548,0.707106781186548,0.,-1.,0.,1.,1.,0.,0.,1.,1.,0.,-1.,0.,0.,1.,1.,0.]; - for i in xrange(26): - self.assertAlmostEqual(expected1[i],da1.getIJ(0,i),14); - pass - pass - - def testSwigErrorProtection2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - coo=m.getCoords() - c=m.getNodalConnectivity() - ci=m.getNodalConnectivityIndex() - del m - self.assertEqual(2,coo.getNumberOfComponents()); - self.assertEqual(6,ci.getNumberOfTuples()); - self.assertEqual(23,c.getNumberOfTuples()); - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=m.getMeasureField(True) - c=f.getArray() - del f - self.assertEqual(1,c.getNumberOfComponents()); - m=MEDCouplingCMesh.New() - x=DataArrayDouble.New() - x.setValues([1.,2.,4.],3,1) - m.setCoordsAt(0,x) - del x - xx=m.getCoordsAt(0) - del m - self.assertEqual(3,xx.getNumberOfTuples()); - # - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=m.getMeasureField(True) - m2=f.getMesh() - del m - del f - self.assertEqual(5,m2.getNumberOfCells()); - pass - - def testUMInsertNextCell1(self): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.allocateCells(5); - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_QUAD4,4,targetConn[0:4]) - targetMesh.setMeshDimension(2); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_TETRA4,4,targetConn[0:4]) - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_SEG2,2,targetConn[0:2]) - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_POINT1,1,targetConn[0:1]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - targetMesh.checkCoherency(); - pass - - def testFieldOperatorDivDiffComp1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1,d0,d1,d2,d3=m.buildDescendingConnectivity(); - # - f1=m1.buildOrthogonalField(); - arr1=[2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.] - arr=DataArrayDouble.New(); - arr.setValues(arr1,13,1); - f2=MEDCouplingFieldDouble.New(ON_CELLS); - f2.setArray(arr); - f2.setMesh(m1); - f2.checkCoherency(); - # - f3=f1/f2; - self.assertRaises(InterpKernelException,f2.__div__,f1) - f3.checkCoherency(); - f1/=f2; - #self.assertRaises(InterpKernelException,f2.__idiv__,f1) # mem leaks - self.assertTrue(f1.isEqual(f3,1e-10,1e-10)); - expected1=[-0.5, 0.0, 0.0, 0.33333333333333331, 0.25, 0.0, 0.0, -0.20000000000000001, 0.117851130197758, 0.117851130197758, 0.0, -0.14285714285714285, 0.0, 0.125, 0.1111111111111111, 0.0, 0.0, 0.10000000000000001, 0.090909090909090912, 0.0, -0.083333333333333329, 0.0, 0.0, 0.076923076923076927, 0.071428571428571425, 0.0] - for i in xrange(26): - self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),10); - pass - pass - - def testDARearrange1(self): - da1=DataArrayInt.New(); - da1.alloc(12,1); - da1.iota(0); - # - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(1,da1.getNumberOfComponents()); - self.assertEqual(12,da1.getNumberOfTuples()); - da1.rearrange(4); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(4,da1.getNumberOfComponents()); - self.assertEqual(3,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - # - da1.rearrange(6); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(6,da1.getNumberOfComponents()); - self.assertEqual(2,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - # - self.assertRaises(InterpKernelException,da1.rearrange,7); - # - da1.rearrange(12); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(12,da1.getNumberOfComponents()); - self.assertEqual(1,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - # - da1.rearrange(3); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(3,da1.getNumberOfComponents()); - self.assertEqual(4,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - #double - da2=da1.convertToDblArr(); - st=da2.getHiddenCppPointer() - # - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(3,da2.getNumberOfComponents()); - self.assertEqual(4,da2.getNumberOfTuples()); - da2.rearrange(4); - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(4,da2.getNumberOfComponents()); - self.assertEqual(3,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - # - da2.rearrange(6); - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(6,da2.getNumberOfComponents()); - self.assertEqual(2,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - # - self.assertRaises(InterpKernelException,da2.rearrange,7); - # - da2.rearrange(1); - self.assertEqual(st,da2.getHiddenCppPointer()) - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(1,da2.getNumberOfComponents()); - self.assertEqual(12,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - # - da2.rearrange(3); - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(3,da2.getNumberOfComponents()); - self.assertEqual(4,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - pass - - def testDARearrange2(self): - da1=DataArrayInt.New(); - arr=[1,2,3,2,2,3,5,1,5,5,2,2] - da1.setValues(arr,4,3); - s=da1.getDifferentValues(); - expected1=DataArrayInt([1,2,3,5]) - self.assertTrue(expected1.isEqual(s)); - pass - - def testSwigErrorProtection3(self): - da=DataArrayInt.New() - da.setValues([1,2,3,4,0,0,0,0,0,0,0,0],4,3) - self.assertEqual([1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da=DataArrayInt.New() - da.setValues(((1,2,3),(4,4,3),(0,0,0),(0,0,0)),4,3) - self.assertEqual([1, 2, 3, 4, 4, 3, 0, 0, 0, 0, 0, 0],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da.setValues((10*[1]+290*[2])[:12],4,3) - self.assertEqual(10*[1]+[2,2],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - # - da=DataArrayDouble.New() - da.setValues([1,2,3.,4,0,0,0,0,0,0,0,0],4,3) - self.assertEqual([1., 2., 3., 4., 0., 0., 0., 0., 0., 0., 0., 0.],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da=DataArrayDouble.New() - da.setValues(((1,2,3),(4.,4,3),(0,0,0),(0,0,0)),4,3) - self.assertEqual([1., 2., 3., 4., 4., 3., 0., 0., 0., 0., 0., 0.],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da.setValues((10*[1]+290*[2])[:12],4,3) - self.assertEqual(10*[1.]+[2.,2.],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - pass - - def testDAIBuildPermutationArr1(self): - a=DataArrayInt.New() - a.setValues([4,5,6,7,8],5,1) - b=DataArrayInt.New() - b.setValues([5,4,8,6,7],5,1) - c=a.buildPermutationArr(b) - self.assertEqual([1,0,4,2,3],c.getValues()) - self.assertTrue(a.isEqualWithoutConsideringStrAndOrder(b)) - b.setIJ(0,0,9) - self.assertTrue(not a.isEqualWithoutConsideringStrAndOrder(b)) - self.assertRaises(InterpKernelException,a.buildPermutationArr,b) - a.setIJ(3,0,4) - b.setIJ(0,0,5) - b.setIJ(4,0,4)#a==[4,5,6,4,8] and b==[5,4,8,6,4] - self.assertTrue(a.isEqualWithoutConsideringStrAndOrder(b)) - c=a.buildPermutationArr(b) - self.assertEqual([1,3,4,2,3],c.getValues()) - d=b.convertToDblArr() - expect3=[4,4,5,6,8] - b.sort() - self.assertEqual(expect3,b.getValues()) - d.sort() - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - for i in xrange(5): - self.assertAlmostEqual(float(expect3[i]),d.getIJ(i,0),14); - pass - pass - - def testAreCellsIncludedIn2(self): - myName="Vitoo"; - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=m.buildPartOfMySelf([],True); - self.assertEqual(0,m2.getNumberOfCells()); - self.assertEqual(3,m2.getSpaceDimension()); - self.assertEqual(2,m2.getMeshDimension()); - m2.setName(myName); - test,tmp=m.areCellsIncludedIn(m2,0) - self.assertTrue(test); - self.assertEqual(myName,tmp.getName()); - self.assertEqual(0,tmp.getNumberOfTuples()) - self.assertEqual(1,tmp.getNumberOfComponents()) - pass - - def testUMeshGetPartBarycenterAndOwner1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[1,0,4]; - part=DataArrayInt.New(); - part.setValues(part1,3,1); - b=m1.getPartBarycenterAndOwner(part); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertEqual(3,b.getNumberOfTuples()); - expected1=[0.36666666666666665,-0.13333333333333333,-0.05,-0.05,0.45,0.45]; - for i in xrange(6): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - pass - - def testUMeshGetPartMeasureField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[1,0,4]; - part=DataArrayInt.New(); - part.setValues(part1,3,1); - b=m1.getPartMeasureField(True,part); - self.assertEqual(1,b.getNumberOfComponents()); - self.assertEqual(3,b.getNumberOfTuples()); - expected1=[0.125,0.25,0.25]; - for i in xrange(3): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - pass - - def testUMeshBuildPartOrthogonalField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.changeSpaceDimension(3); - part1=[1,0,4]; - part=DataArrayInt.New(); - part.setValues(part1,3,1); - b=m1.buildPartOrthogonalField(part); - self.assertEqual(3,b.getArray().getNumberOfComponents()); - self.assertEqual(3,b.getArray().getNumberOfTuples()); - expected1=[0.,0.,-1.,0.,0.,-1.,0.,0.,-1.]; - for i in xrange(9): - self.assertAlmostEqual(expected1[i],b.getArray().getIJ(0,i),14); - pass - pass - - def testUMeshGetTypesOfPart1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[0,3,4]; - p1=DataArrayInt.New() - p1.setValues(part1,3,1) - s=m1.getTypesOfPart(p1); - self.assertEqual([NORM_QUAD4],s); - part2=[2,2,2,1]; - p2=DataArrayInt.New() - p2.setValues(part2,4,1) - s=m1.getTypesOfPart(p2); - self.assertEqual([NORM_TRI3],s); - part3=[3,2,1]; - p3=DataArrayInt.New() - p3.setValues(part3,3,1) - s=m1.getTypesOfPart(p3); - self.assertEqual(s,[NORM_TRI3,NORM_QUAD4]); - pass - - def testUMeshKeepCellIdsByType1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[0,3,4] - p1=DataArrayInt.New() - p1.setValues(part1,3,1) - p1.setName("p1") - a=m1.keepCellIdsByType(NORM_TRI3,p1); - self.assertEqual("p1",a.getName()) - self.assertEqual(1,a.getNumberOfComponents()); - self.assertEqual(0,a.getNumberOfTuples()); - # - part2=[3,2,0,2,4] - p2=DataArrayInt.New() - p2.setValues(part2,5,1) - p2.setName("p2") - a=m1.keepCellIdsByType(NORM_TRI3,p2); - self.assertEqual("p2",a.getName()) - self.assertEqual(1,a.getNumberOfComponents()); - self.assertEqual(2,a.getNumberOfTuples()); - self.assertEqual(2,a.getIJ(0,0)); - self.assertEqual(2,a.getIJ(1,0)); - # - a=m1.keepCellIdsByType(NORM_QUAD4,p2); - self.assertEqual("p2",a.getName()) - self.assertEqual(1,a.getNumberOfComponents()); - self.assertEqual(3,a.getNumberOfTuples()); - self.assertEqual(3,a.getIJ(0,0)); - self.assertEqual(0,a.getIJ(1,0)); - self.assertEqual(4,a.getIJ(2,0)); - pass - - def testSwigErrorDaIntSelectByTupleId1(self): - a=DataArrayInt.New(); - arr1=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[4,2,0,6,5] - b=a.selectByTupleId(arr2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5,15,3,13,1,11,7,17,6,16] - self.assertEqual(expected1,b.getValues()) - # - a2=DataArrayInt.New() - a2.setValues(arr2,5,1) - b=a.selectByTupleId(a2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5,15,3,13,1,11,7,17,6,16] - self.assertEqual(expected1,b.getValues()) - pass - - def testSwigErrorRenum(self): - da=DataArrayDouble.New() - da.setValues([7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.],10,2) - d=DataArrayInt.New() - d.setValues([0,2,3,1,4,5,6,8,7,9],10,1) - da.renumberInPlace(d) - da.renumber(d) - pass - - def testSwigGetItem1(self): - da=DataArrayInt.New() - da.alloc(16,3) - da.rearrange(1) - da.iota(7) - da.rearrange(3) - da.setInfoOnComponent(0,"X [m]") - da.setInfoOnComponent(1,"Y [m]") - da.setInfoOnComponent(2,"Z [km]") - da2=da[5:-1] - self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51],da2.getValues()) - da2=da[4] - self.assertEqual([19, 20, 21],da2.getValues()) - try: - da2=da[4:17] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:-2,2] - self.assertEqual([24, 27, 30, 33, 36, 39, 42, 45, 48],da2.getValues()) - da2=da[5:8,:] - self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30],da2.getValues()) - da2=da[:] - self.assertTrue(da2.isEqual(da)) - da2=da[:,:] - self.assertTrue(da2.isEqual(da)) - try: - da2=da[:,:,:] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayInt([23,26,29]))) - da2=da[5:8,:-2] - self.assertEqual([22, 25, 28],da2.getValues()) - try: - da2=da[5:-18,2] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:5,2] - self.assertEqual([],da2.getValues()) - pass - - def testSwigGetItem2(self): - da=DataArrayDouble.New() - da.alloc(16,3) - da.rearrange(1) - da.iota(7) - da.rearrange(3) - da.setInfoOnComponent(0,"X [m]") - da.setInfoOnComponent(1,"Y [m]") - da.setInfoOnComponent(2,"Z [km]") - da2=da[5:-1] - self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.],da2.getValues()) - da2=da[4] - self.assertEqual([19., 20., 21],da2.getValues()) - try: - da2=da[4:17] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:-2,2] - self.assertEqual([24., 27., 30., 33., 36., 39., 42., 45., 48.],da2.getValues()) - da2=da[5:8,:] - self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30.],da2.getValues()) - da2=da[:] - self.assertTrue(da2.isEqual(da,1e-12)) - da2=da[:,:] - self.assertTrue(da2.isEqual(da,1e-12)) - try: - da2=da[:,:,:] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayDouble([23.,26.,29.]),1e-12)) - da2=da[5:8,:-2] - self.assertEqual([22., 25., 28.],da2.getValues()) - try: - da2=da[5:-18,2] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:5,2] - self.assertEqual([],da2.getValues()) - pass - - def testSwigSetItem1(self): - da=DataArrayInt.New() - da.alloc(20,1) - da.iota(7) - da.rearrange(5) - da.setInfoOnComponent(0,"X [m]") ; da.setInfoOnComponent(1,"Y [km]") ; da.setInfoOnComponent(2,"Y [m]") - da.setInfoOnComponent(3,"Z [W]") ; da.setInfoOnComponent(4,"ZZ [km]") ; - da[:,2]=3 - self.assertEqual([7, 8, 3, 10, 11, 12, 13, 3, 15, 16, 17, 18, 3, 20, 21, 22, 23, 3, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[2]=3 - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 3, 3, 3, 3, 22, 23, 24, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[[0,3]]=-1 - self.assertEqual([-1, -1, -1, -1, -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, -1, -1, -1, -1],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[:,[1,3,4]]=-3 - self.assertEqual([7, -3, 9, -3, -3, 12, -3, 14, -3, -3, 17, -3, 19, -3, -3, 22, -3, 24, -3, -3],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da2=DataArrayInt.New() ; da2.setValues([0,2,3],3,1) - da[da2]=-7 - self.assertEqual([-7, -7, -7, -7, -7, 12, 13, 14, 15, 16, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=-7 - self.assertEqual([7, 8, 9, -7, -7, 12, 13, 14, 15, 16, 17, 18, 19, -7, -7, 22, 23, 24, -7, -7],da.getValues()) - # Let's test with DAI right hand side - da1=DataArrayInt.New() - da1.setValues([25,26,27,125,126,127],2,3) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[-2:,1:4]=da1 - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 25, 26, 27, 21, 22, 125, 126, 127, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1:,3]=[225,226,227] - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 225, 16, 17, 18, 19, 226, 21, 22, 23, 24, 227, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1,2:]=[225,226,227] - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 225, 226, 227, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=[88,99,1010,1111,1212,1313] - self.assertEqual([7, 8, 9, 88, 99, 12, 13, 14, 15, 16, 17, 18, 19, 1010, 1111, 22, 23, 24, 1212, 1313],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da3=DataArrayInt.New(); da3.setValues([88,99,1010,1111,1212,1313],3,2) - da[da2,-2:]=da3 - self.assertEqual([7, 8, 9, 88, 99, 12, 13, 14, 15, 16, 17, 18, 19, 1010, 1111, 22, 23, 24, 1212, 1313],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,[0,2]]=da3 - self.assertEqual([88, 8, 99, 10, 11, 12, 13, 14, 15, 16, 1010, 18, 1111, 20, 21, 1212, 23, 1313, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=da3 - self.assertEqual([88, 8, 99, 10, 11, 12, 13, 14, 15, 16, 1010, 18, 1111, 20, 21, 1212, 23, 1313, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=-8 - self.assertEqual([-8, 8, -8, 10, 11, 12, 13, 14, 15, 16, -8, 18, -8, 20, 21, -8, 23, -8, 25, 26],da.getValues()) - pass - - def testSwigSetItem2(self): - da=DataArrayDouble.New() - da.alloc(20,1) - da.iota(7) - da.rearrange(5) - da.setInfoOnComponent(0,"X [m]") ; da.setInfoOnComponent(1,"Y [km]") ; da.setInfoOnComponent(2,"Y [m]") - da.setInfoOnComponent(3,"Z [W]") ; da.setInfoOnComponent(4,"ZZ [km]") ; - da[:,2]=3. - self.assertEqual([7., 8., 3., 10., 11., 12., 13., 3., 15., 16., 17., 18., 3., 20., 21., 22., 23., 3., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[2]=3. - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 3., 3., 3., 3., 3., 22., 23., 24., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[[0,3]]=-1. - self.assertEqual([-1., -1., -1., -1., -1., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., -1., -1., -1., -1., -1.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[:,[1,3,4]]=-3. - self.assertEqual([7., -3., 9., -3., -3., 12., -3., 14., -3., -3., 17., -3., 19., -3., -3., 22., -3., 24., -3., -3.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da2=DataArrayInt.New() ; da2.setValues([0,2,3],3,1) - da[da2]=-7. - self.assertEqual([-7., -7., -7., -7., -7., 12., 13., 14., 15., 16., -7., -7., -7., -7., -7., -7., -7., -7., -7., -7.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=-7 - self.assertEqual([7., 8., 9., -7., -7., 12., 13., 14., 15., 16., 17., 18., 19., -7., -7., 22., 23., 24., -7., -7.],da.getValues()) - # Let's test with DAI right hand side - da1=DataArrayDouble.New() - da1.setValues([25,26,27,125,126,127],2,3) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[-2:,1:4]=da1 - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 25., 26., 27., 21., 22., 125., 126., 127., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1:,3]=[225.,226.,227.] - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 225., 16., 17., 18., 19., 226., 21., 22., 23., 24., 227., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1,2:]=[225,226,227] - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 225., 226., 227., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=[88,99,1010,1111,1212,1313] - self.assertEqual([7., 8., 9., 88., 99., 12., 13., 14., 15., 16., 17., 18., 19., 1010., 1111., 22., 23., 24., 1212., 1313.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da3=DataArrayDouble.New(); da3.setValues([88,99,1010,1111,1212,1313],3,2) - da[da2,-2:]=da3 - self.assertEqual([7., 8., 9., 88., 99., 12., 13., 14., 15., 16., 17., 18., 19., 1010., 1111., 22., 23., 24., 1212., 1313.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,[0,2]]=da3 - self.assertEqual([88., 8., 99., 10., 11., 12., 13., 14., 15., 16., 1010., 18., 1111., 20., 21., 1212., 23., 1313., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=da3 - self.assertEqual([88., 8., 99., 10., 11., 12., 13., 14., 15., 16., 1010., 18., 1111., 20., 21., 1212., 23., 1313., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=-8. - self.assertEqual([-8., 8., -8., 10., 11., 12., 13., 14., 15., 16., -8., 18., -8., 20., 21., -8., 23., -8., 25., 26.],da.getValues()) - pass - - def testSwigDADOp(self): - da=DataArrayDouble.New() - da.alloc(12,1) - da.iota(7.) - da1=DataArrayDouble.New() - da1.alloc(12,1) - da1.iota(8.) - da2=da+da1 - self.assertEqual([15., 17., 19., 21., 23., 25., 27., 29., 31., 33., 35., 37.],da2.getValues()) - da2=da+3 - da3=3+da - self.assertTrue(da2.isEqual(da3,1e-12)) - da2=da-1. - self.assertEqual([6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0],da2.getValues()) - da2=1-da - self.assertEqual([-6.0, -7.0, -8.0, -9.0, -10.0, -11.0, -12.0, -13.0, -14.0, -15.0, -16.0, -17.0],da2.getValues()) - da2=da*3 - self.assertEqual([21.0, 24.0, 27.0, 30.0, 33.0, 36.0, 39.0, 42.0, 45.0, 48.0, 51.0, 54.0],da2.getValues()) - da2=3.*da - self.assertEqual([21.0, 24.0, 27.0, 30.0, 33.0, 36.0, 39.0, 42.0, 45.0, 48.0, 51.0, 54.0],da2.getValues()) - da2=da*da1 - self.assertEqual([56.0, 72.0, 90.0, 110.0, 132.0, 156.0, 182.0, 210.0, 240.0, 272.0, 306.0, 342.0],da2.getValues()) - da2=da/4. - self.assertEqual([1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5],da2.getValues()) - da3=4./da - da4=da3*da2 - self.assertTrue(da4.isUniform(1.,1e-12)) - st1=da.getHiddenCppPointer() - da+=1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertTrue(da.isEqual(da1,1e-12)) - da-=8 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual(range(12),da.getValues()) - da+=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0],da.getValues()) - da*=0.5 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],da.getValues()) - da*=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([32.0, 45.0, 60.0, 77.0, 96.0, 117.0, 140.0, 165.0, 192.0, 221.0, 252.0, 285.0],da.getValues()) - da/=da1 - self.assertEqual(st1,st2) - self.assertEqual([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],da.getValues()) - da/=2 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5],da.getValues()) - da.rearrange(3) - da5=DataArrayDouble.New() - da5.setValues([5.,4.,3.,2.],4,1) - da*=da5 # it works with unmathing number of compo - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([10.0, 12.5, 15.0, 14.0, 16.0, 18.0, 15.0, 16.5, 18.0, 13.0, 14.0, 15.0],da.getValues()) - # - da.alloc(30,1) - da.iota(7.) - da.rearrange(3) - ids=DataArrayInt.New() - ids.setValues([3,4,7],3,1) - da[ids,:]=[5.,8.,9.] - self.assertEqual([7.,8.,9.,10.,11.,12.,13.,14.,15.,5.,8.,9.,5.,8.,9.,22.,23.,24.,25.,26.,27.,5.,8.,9.,31.,32.,33.,34.,35.,36.0],da.getValues()) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(3) - da[ids,[1,2]]=[5,8] - self.assertEqual([7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,5.,8.,19.,5.,8.,22.,23.,24.,25.,26.,27.,28.,5.,8.,31.,32.,33.,34.,35.,36.],da.getValues()) - pass - - def testSwigDAIOp(self): - da=DataArrayInt.New() - da.alloc(12,1) - da.iota(7) - da1=DataArrayInt.New() - da1.alloc(12,1) - da1.iota(8) - da2=da+da1 - self.assertEqual([15,17,19,21,23,25,27,29,31,33,35,37],da2.getValues()) - da2=da+3 - da3=3+da - self.assertTrue(da2.isEqual(da3)) - da2=da-1 - self.assertEqual([6,7,8,9,10,11,12,13,14,15,16,17],da2.getValues()) - da2=1-da - self.assertEqual([-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17],da2.getValues()) - da2=da*3 - self.assertEqual([21,24,27,30,33,36,39,42,45,48,51,54.0],da2.getValues()) - da2=3*da - self.assertEqual([21,24,27,30,33,36,39,42,45,48,51,54.0],da2.getValues()) - da2=da*da1 - self.assertEqual([56,72,90,110,132,156,182,210,240,272,306,342.0],da2.getValues()) - da2=da/4 - self.assertEqual([1,2,2,2,2,3,3,3,3,4,4,4],da2.getValues()) - da3=4/da - da4=da3*da2 - self.assertTrue(da4.isUniform(0)) - st1=da.getHiddenCppPointer() - da+=1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertTrue(da.isEqual(da1)) - da-=8 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual(range(12),da.getValues()) - da+=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([8,10,12,14,16,18,20,22,24,26,28,30],da.getValues()) - da/=2 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([4,5,6,7,8,9,10,11,12,13,14,15],da.getValues()) - da*=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([32,45,60,77,96,117,140,165,192,221,252,285],da.getValues()) - da/=da1 - self.assertEqual(st1,st2) - self.assertEqual([4,5,6,7,8,9,10,11,12,13,14,15],da.getValues()) - da/=2 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([2,2, 3,3, 4,4, 5,5, 6,6, 7,7],da.getValues()) - da.rearrange(3) - da5=DataArrayInt.New() - da5.setValues([5,4,3,2],4,1) - da*=da5 # it works with unmathing number of compo - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([10,10, 15,12,16,16,15,15, 18,12,14,14],da.getValues()) - da%=6 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([4,4,3,0,4,4,3,3,0,0,2,2],da.getValues()) - # - da.alloc(30,1) - da.iota(7) - da.rearrange(3) - ids=DataArrayInt.New() - ids.setValues([3,4,7],3,1) - da[ids,:]=[5,8,9] - self.assertEqual([7,8,9,10,11,12,13,14,15,5,8,9,5,8,9,22,23,24,25,26,27,5,8,9,31,32,33,34,35,36],da.getValues()) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(3) - da[ids,[1,2]]=[5,8] - self.assertEqual([7,8,9,10,11,12,13,14,15,16,5,8,19,5,8,22,23,24,25,26,27,28,5,8,31,32,33,34,35,36],da.getValues()) - pass - - def testSwigDAIOp2(self): - da=DataArrayInt.New() - st=da.getHiddenCppPointer() - da.alloc(10,3) - da.rearrange(1) - da.iota(0) - da.rearrange(3) - da[:,1]+=4 - da[-2:,2]+=10 - da[-2:,2]+=10 - da[:,2]+=da[:,0] - da[da[0],:]=7 - self.assertEqual(st,da.getHiddenCppPointer()) - self.assertEqual(da.getValues(),[7,7,7,3,8,8,7,7,7,9,14,20,12,17,26,7,7,7,18,23,38,21,26,44,24,29,70,27,32,76]) - pass - - def testSwigDAIOp3(self): - da=DataArrayInt.New() - self.assertRaises(InterpKernelException,da.__len__) - self.assertRaises(InterpKernelException,da.__int__) - for elt in da: - self.assertTrue(False) - pass - da.alloc(12,3) - da.rearrange(1) ; da.fillWithZero() - l1=list(da) - self.assertEqual(36,len(da)); - da.rearrange(3) - tmp=da[0] - self.assertRaises(InterpKernelException,tmp.__int__) - self.assertEqual(12,len(da)); - l=list(da) - for elt in enumerate(l): - elt[1][2]=elt[0] - pass - ref=[0,0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,9,0,0,10,0,0,11] - self.assertEqual(ref,da.getValues()); - da.rearrange(1) - l=[int(elt) for elt in l1] - self.assertEqual(ref,da.getValues()); - self.assertEqual(11,int(da[-1:])) - pass - - def testSwigDADOp3(self): - da=DataArrayDouble.New() - self.assertRaises(InterpKernelException,da.__len__) - self.assertRaises(InterpKernelException,da.__float__) - for elt in da: - self.assertTrue(False) - pass - da.alloc(12,3) - da.rearrange(1) ; da.fillWithZero() - l1=list(da) - self.assertEqual(36,len(da)); - da.rearrange(3) - tmp=da[0] - self.assertRaises(InterpKernelException,tmp.__float__) - self.assertEqual(12,len(da)); - l=list(da) - for elt in enumerate(l): - elt[1][2]=elt[0] - pass - ref=[0.,0.,0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,6.,0.,0.,7.,0.,0.,8.,0.,0.,9.,0.,0.,10.,0.,0.,11.] - self.assertEqual(ref,da.getValues()); - da.rearrange(1) - l=[float(elt) for elt in l1] - self.assertEqual(ref,da.getValues()); - self.assertEqual(11.,float(da[-1:])) - pass - - def testSwigDataArrayIntIterator1(self): - da=DataArrayInt.New() - da.alloc(12,1) - da.iota(2) - da.rearrange(3) - # __getitem__ testing - li=[] - for it in da: - li+=it[1:] - pass - self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li) - li=[] - for it in da: - li+=[it[-1]] - pass - self.assertEqual([4, 7, 10, 13],li) - li=[] - for it in da: - li+=it[[2,1,0]] - pass - self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li) - # __setitem__ testing - da3=da.deepCpy() - da2=DataArrayInt.New() - da2.alloc(12,1) - da2.iota(2002) - da2.rearrange(3) - it2=da2.__iter__() - i=0 - for it in da: - pt=it2.next() - it[:]=pt - pass - self.assertTrue(da.isEqual(da2)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=5 - pass - da.rearrange(1) - self.assertTrue(da.isUniform(5)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=[8,9,12] - pass - self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues()) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[2]=[7] - pass - self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues()) - pass - - def testSwigDataArrayDoubleIterator1(self): - da=DataArrayDouble.New() - da.alloc(12,1) - da.iota(2) - da.rearrange(3) - # __getitem__ testing - li=[] - for it in da: - li+=it[1:] - pass - self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li) - li=[] - for it in da: - li+=[it[-1]] - pass - self.assertEqual([4, 7, 10, 13],li) - li=[] - for it in da: - li+=it[[2,1,0]] - pass - self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li) - # __setitem__ testing - da3=da.deepCpy() - da2=DataArrayDouble.New() - da2.alloc(12,1) - da2.iota(2002) - da2.rearrange(3) - it2=da2.__iter__() - i=0 - for it in da: - pt=it2.next() - it[:]=pt - pass - self.assertTrue(da.isEqual(da2,1e-12)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=5 - pass - da.rearrange(1) - self.assertTrue(da.isUniform(5,1e-12)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=[8,9,12] - pass - self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues()) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[2]=[7] - pass - self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues()) - pass - - def testSwigUMeshIterator1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - li1=[] - li2=[] - for cell in m: - li1+=cell.getAllConn()[1:] - li2+=[cell.getType()] - pass - self.assertEqual(li1,[0, 3, 4, 1, 1, 4, 2, 4, 5, 2, 6, 7, 4, 3, 7, 8, 5, 4]) - self.assertEqual(li2,[4, 3, 3, 4, 4]) - pass - - def testSwigUMeshIterator2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - self.assertRaises(InterpKernelException,m.cellsByType); - m.rearrange2ConsecutiveCellTypes() - li1=[] - li2=[] - li3=[] - for cellsByType in m.cellsByType(): - li1.append(cellsByType.getType()) - li2.append(cellsByType.getNumberOfElems()) - temp=[] - for cell in cellsByType: - t=[None,None] - t[0]=cell.getType() - t[1]=cell.getAllConn()[1:] - temp.append(t) - pass - li3.append(temp) - pass - self.assertEqual(li1,[4, 3]) - self.assertEqual(li2,[3, 2]) - self.assertEqual(li3,[[[4, (0, 3, 4, 1)], [4, (6, 7, 4, 3)], [4, (7, 8, 5, 4)]], [[3, (1, 4, 2)], [3, (4, 5, 2)]]]) - pass - - def testDAIAggregateMulti1(self): - a=DataArrayInt.New() - a.setValues(range(4),2,2) - a.setName("aa") - b=DataArrayInt.New() - b.setValues(range(6),3,2) - c=DataArrayInt.Aggregate([a,b]) - self.assertEqual(range(4)+range(6),c.getValues()) - self.assertEqual("aa",c.getName()) - self.assertEqual(5,c.getNumberOfTuples()) - self.assertEqual(2,c.getNumberOfComponents()) - pass - - def testMergeUMeshes2(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m3=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - # - vec1=[0,2,3] - m2_2=m2.buildPartOfMySelf(vec1,False); - vec2=[1,1] - m3_2=m3.buildPartOfMySelf(vec2,False); - # - ms=[m1,m2_2,m3_2]; - # - self.assertRaises(InterpKernelException,MEDCouplingUMesh.MergeUMeshes,ms+[None]); - self.assertRaises(InterpKernelException,MEDCouplingUMesh.MergeUMeshes,ms+[3.4]) - m4=MEDCouplingUMesh.MergeUMeshes(ms); - m4.checkCoherency(); - self.assertEqual(10,m4.getNumberOfCells()); - self.assertEqual(20,m4.getNumberOfNodes()); - self.assertEqual(45,m4.getMeshLength()); - m4bis=MEDCouplingMesh.MergeMeshes(ms); - self.assertTrue(m4.isEqual(m4bis,1e-12)) - del m4bis - # - vec3=[0,1,2,3,4] - m4_1=m4.buildPartOfMySelf(vec3,False); - m4_1.setName(m1.getName()); - self.assertTrue(m4_1.isEqual(m1,1e-12)); - # - vec4=[5,6,7] - m4_2=m4.buildPartOfMySelf(vec4,False); - cellCor,nodeCor=m4_2.checkGeoEquivalWith(m2_2,10,1e-12); - # - vec5=[8,9] - m4_3=m4.buildPartOfMySelf(vec5,False); - self.assertEqual(2,m4_3.getNumberOfCells()); - self.assertEqual(3,m4_3.getNumberOfNodes()); - m3_2.zipCoords(); - m4_3.setName(m3_2.getName()); - self.assertTrue(m4_3.isEqual(m3_2,1e-12)); - # - pass - - def testBuild0DMeshFromCoords1(self): - sourceCoords=[-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.] - coo=DataArrayDouble.New(); - coo.setValues(sourceCoords,4,3); - coo.setName("My0D"); - m=MEDCouplingUMesh.Build0DMeshFromCoords(coo); - m.checkCoherency(); - self.assertEqual(4,m.getNumberOfNodes()); - self.assertEqual(4,m.getNumberOfCells()); - self.assertEqual(3,m.getSpaceDimension()); - self.assertEqual(0,m.getMeshDimension()); - types1=m.getAllGeoTypes(); - self.assertEqual([NORM_POINT1],types1); - for i in xrange(4): - conn=m.getNodeIdsOfCell(i); - self.assertEqual([i],conn); - self.assertTrue(NORM_POINT1==m.getTypeOfCell(i)); - pass - self.assertEqual(m.getName(),"My0D"); - pass - - def testDescriptionInMeshTimeUnit1(self): - text1="totoTTEDD"; - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.setDescription(text1); - self.assertEqual(m.getDescription(),text1); - m2=m.deepCpy(); - self.assertTrue(m.isEqual(m2,1e-12)); - self.assertEqual(m2.getDescription(),text1); - m2.setDescription("ggg"); - self.assertTrue(not m.isEqual(m2,1e-12)); - # - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f.setTimeUnit(text1); - self.assertEqual(f.getTimeUnit(),text1); - f2=f.deepCpy(); - self.assertEqual(f2.getTimeUnit(),text1); - # - pass - - def testMultiFields1(self): - mfs=MEDCouplingDataForTest.buildMultiFields_1(); - ms=mfs.getMeshes(); - dms,refs=mfs.getDifferentMeshes() - das=mfs.getArrays(); - das2,refs2=mfs.getDifferentArrays() - self.assertEqual(5,len(mfs.getFields())) - self.assertEqual(1,len(mfs.getFields()[0].getArrays())); - self.assertEqual(2,len(mfs.getFields()[1].getArrays())); - self.assertEqual(1,len(mfs.getFields()[2].getArrays())); - self.assertEqual(1,len(mfs.getFields()[3].getArrays())); - self.assertEqual(1,len(mfs.getFields()[4].getArrays())); - self.assertEqual(5,len(ms)); - self.assertEqual(2,len(dms)); - self.assertEqual(6,len(das)); - self.assertEqual(5,len(das2)); - mfs2=mfs.deepCpy(); - self.assertTrue(mfs.isEqual(mfs2,1e-12,1e-12)) - pass - - def testFieldOverTime1(self): - fs=MEDCouplingDataForTest.buildMultiFields_2(); - self.assertRaises(InterpKernelException,MEDCouplingFieldOverTime.New,fs); - f4bis=fs[4].buildNewTimeReprFromThis(ONE_TIME,False); - fs[4]=f4bis; - self.assertRaises(InterpKernelException,MEDCouplingFieldOverTime.New,fs); - f4bis.setTime(2.7,20,21); - fot=MEDCouplingFieldOverTime.New(fs); - dt=fot.getDefinitionTimeZone(); - hs=dt.getHotSpotsTime(); - self.assertEqual(6,len(hs)); - expected1=[0.2,0.7,1.2,1.35,1.7,2.7] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],hs[i],12); - pass - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(0.2); - self.assertEqual(0,meshId); - self.assertEqual(0,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(0,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(0.7); - self.assertEqual(0,meshId); - self.assertEqual(1,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(1,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeLeft(1.2);#**** WARNING left here - self.assertEqual(0,meshId); - self.assertEqual(2,arrId); - self.assertEqual(1,arrIdInField); - self.assertEqual(1,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.2);#**** WARNING right again here - self.assertEqual(1,meshId); - self.assertEqual(3,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(2,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.35); - self.assertEqual(1,meshId); - self.assertEqual(3,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(2,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.7); - self.assertEqual(0,meshId); - self.assertEqual(3,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(3,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(2.7); - self.assertEqual(1,meshId); - self.assertEqual(4,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(4,fieldId); - # - dt2=MEDCouplingDefinitionTime(); - self.assertTrue(not dt2.isEqual(dt)); - dt2.assign(dt); - dt2.assign(dt);#to check memory management - self.assertTrue(dt2.isEqual(dt)); - # - dt3=MEDCouplingDefinitionTime(); - # - pass - - def testDAICheckAndPreparePermutation1(self): - vals1=[9,10,0,6,4,11,3,7]; - expect1=[5,6,0,3,2,7,1,4]; - vals2=[9,10,0,6,10,11,3,7]; - da=DataArrayInt.New(); - da.setValues(vals1,8,1); - da2=da.checkAndPreparePermutation(); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(8): - self.assertEqual(expect1[i],da2.getIJ(i,0)); - pass - # - da=DataArrayInt.New(); - da.alloc(8,1); - da.iota(0); - da2=da.checkAndPreparePermutation(); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - self.assertTrue(da2.isIdentity()); - # - da=DataArrayInt.New(); - da.alloc(8,1); - da.setValues(vals2,8,1); - self.assertRaises(InterpKernelException,da.checkAndPreparePermutation); - pass - - def testDAIChangeSurjectiveFormat1(self): - vals1=[0,3,2,3,2,2,1,2] - expected1=[0,1,2,6,8] - expected2=[0, 6, 2,4,5,7, 1,3] - da=DataArrayInt.New(); - da.setValues(vals1,8,1); - # - da2,da2I=da.changeSurjectiveFormat(4); - self.assertEqual(5,da2I.getNumberOfTuples()); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(expected1,da2I.getValues()); - self.assertEqual(expected2,da2.getValues()); - # - self.assertRaises(InterpKernelException,da.changeSurjectiveFormat,3); - # - pass - - def testUMeshGetCellIdsLyingOnNodes1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - nodeIds1=[1,2,3,4,6] - nodeIds2=[6,7] - da=m.getCellIdsLyingOnNodes(nodeIds1,True); - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(1,da.getIJ(0,0)); - da2=DataArrayInt.New() - da2.setValues(nodeIds2,2,1) - da=m.getCellIdsLyingOnNodes(da2,False); - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(3,da.getIJ(0,0)); - self.assertEqual(4,da.getIJ(1,0)); - pass - - def testUMeshFindCellIdsOnBoundary1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - da5=m.findCellIdsOnBoundary(); - self.assertEqual(5,da5.getNumberOfTuples()); - self.assertTrue(da5.isIdentity()); - pass - - def testMeshSetTime1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - # - self.assertTrue(m1.isEqual(m2,1e-12)); - m1.setTime(3.14,6,7); - tmp3,tmp1,tmp2=m1.getTime(); - self.assertEqual(6,tmp1); - self.assertEqual(7,tmp2); - self.assertAlmostEqual(3.14,tmp3,12); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTime(3.14,6,7); - self.assertTrue(m1.isEqual(m2,1e-12)); - m1.setTimeUnit("ms"); - self.assertTrue(m1.getTimeUnit()=="ms"); - m1.setTimeUnit("us"); - self.assertTrue(m1.getTimeUnit()=="us"); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTimeUnit("us"); - self.assertTrue(m1.isEqual(m2,1e-12)); - m2.setTime(3.14,6,8); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTime(3.14,7,7); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTime(3.15,6,7); - self.assertTrue(not m1.isEqual(m2,1e-12)); - # - m1.setTime(10.34,55,12); - m3=m1.deepCpy(); - self.assertTrue(m1.isEqual(m3,1e-12)); - tmp3,tmp1,tmp2=m3.getTime(); - self.assertEqual(55,tmp1); - self.assertEqual(12,tmp2); - self.assertAlmostEqual(10.34,tmp3,12); - # - # testing CMesh - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - # - b.setTime(5.67,8,100); - tmp3,tmp1,tmp2=b.getTime(); - self.assertEqual(8,tmp1); - self.assertEqual(100,tmp2); - self.assertAlmostEqual(5.67,tmp3,12); - c=b.deepCpy(); - self.assertTrue(c.isEqual(b,1e-12)); - tmp3,tmp1,tmp2=c.getTime(); - self.assertEqual(8,tmp1); - self.assertEqual(100,tmp2); - self.assertAlmostEqual(5.67,tmp3,12); - pass - - def testApplyFuncTwo1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m1); - # - vals=[1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] - da=DataArrayDouble.New(); - da.setValues(vals,5,3); - f1.setArray(da); - # - self.assertRaises(InterpKernelException,da.applyFunc2,1,"y+z"); - da.setInfoOnComponent(0,"x [m]"); - da.setInfoOnComponent(1,"y [mm]"); - da.setInfoOnComponent(2,"z [km]"); - - self.assertRaises(InterpKernelException, da.applyFunc2, 1, "x+y+zz+zzz"); - self.assertRaises(InterpKernelException, da.applyFunc2, 1, "toto(x+y)"); - self.assertRaises(InterpKernelException, da.applyFunc2, 1, "x/0"); - - da2=da.applyFunc2(1,"y+z"); - self.assertEqual(1,da2.getNumberOfComponents()); - self.assertEqual(5,da2.getNumberOfTuples()); - expected1=[32.,34.,36.,38.,40.] - for i in xrange(5): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); - pass - da2=da.applyFunc(1,"y+z"); - expected2=[12.,14.,16.,18.,20.] - for i in xrange(5): - self.assertAlmostEqual(expected2[i],da2.getIJ(0,i),12); - pass - # - self.assertEqual(3,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - f1.applyFunc2(1,"y+z"); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - # - pass - - def testApplyFuncThree1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m1); - # - vals=[1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] - da=DataArrayDouble.New(); - da.setValues(vals,5,3); - f1.setArray(da); - # - vs=3*[None]; - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "y+z"); - self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "x+Y+z+zz+zzz"); - self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "x/0"); - vs[1]="y"; - da2=da.applyFunc3(1,vs,"y+z"); - expected1=[32.,34.,36.,38.,40.] - for i in xrange(5): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); - pass - self.assertRaises(InterpKernelException, da.applyFunc3, 1, ["x","y","z","a"],"x+a") - f1.setArray(da); - self.assertEqual(3,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - f1.applyFunc3(1,vs,"y+z"); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testFillFromAnalyticTwo1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m1.setTime(3.4,5,6); m1.setTimeUnit("us"); - self.assertRaises(InterpKernelException,m1.fillFromAnalytic2,ON_NODES,1,"y+z"); - m1.getCoords().setInfoOnComponent(0,"x [m]"); - m1.getCoords().setInfoOnComponent(1,"y"); - m1.getCoords().setInfoOnComponent(2,"z"); - f1=m1.fillFromAnalytic2(ON_NODES,1,"y+z"); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] - for i in xrange(9): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testFillFromAnalyticThree1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m1.setTime(3.4,5,6); m1.setTimeUnit("us"); - vs=3*[None]; - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - self.assertRaises(InterpKernelException,m1.fillFromAnalytic3,ON_NODES,1,vs,"y+z"); - vs[1]="y"; - f1=m1.fillFromAnalytic3(ON_NODES,1,vs,"y+z"); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] - for i in xrange(9): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testDAUnitVar1(self): - da=DataArrayDouble.New(); - da.alloc(1,3); - da.setInfoOnComponent(0,"XPS [m]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPS"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2=="m"); - # - da.setInfoOnComponent(0,"XPS [m]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPS"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2=="m"); - # - da.setInfoOnComponent(0,"XPP [m]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPP"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2=="m"); - # - da.setInfoOnComponent(0,"XPP kdep kefer [ m ]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPP kdep kefer"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==" m "); - # - da.setInfoOnComponent(0," XPP k[ dep k]efer [ m^ 2/s^3*kJ ]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1==" XPP k[ dep k]efer"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==" m^ 2/s^3*kJ "); - # - da.setInfoOnComponent(0," XPP kefer "); - st1=da.getVarOnComponent(0); - self.assertTrue(st1==" XPP kefer "); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==""); - # - da.setInfoOnComponent(0,"temperature( bof)"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="temperature( bof)"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==""); - # - da.setInfoOnComponent(0,"kkk [m]"); - da.setInfoOnComponent(1,"ppp [m^2/kJ]"); - da.setInfoOnComponent(2,"abcde [MW/s]"); - # - vs=da.getVarsOnComponent(); - self.assertEqual(3,len(vs)); - self.assertTrue(vs[0]=="kkk"); - self.assertTrue(vs[1]=="ppp"); - self.assertTrue(vs[2]=="abcde"); - vs=da.getUnitsOnComponent(); - self.assertEqual(3,len(vs)); - self.assertTrue(vs[0]=="m"); - self.assertTrue(vs[1]=="m^2/kJ"); - self.assertTrue(vs[2]=="MW/s"); - pass - - def testGaussCoordinates1(self): - #Testing 1D cell types - m1=MEDCouplingDataForTest.build1DMultiTypes_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setMesh(m1); - wg1=[0.3]; - gsCoo1=[0.2]; - refCoo1=[-1.0,1.0]; - f.setGaussLocalizationOnType(NORM_SEG2,refCoo1,gsCoo1,wg1); - wg2=wg1; - gsCoo2=[0.2]; - refCoo2=[-1.0,1.0,0.0]; - f.setGaussLocalizationOnType(NORM_SEG3,refCoo2,gsCoo2,wg2); - # - resToTest=f.getLocalizationOfDiscr(); - self.assertEqual(3,resToTest.getNumberOfComponents()); - self.assertEqual(2,resToTest.getNumberOfTuples()); - expected1=[0.6,0.6,0.6, 0.6,0.6,0.6] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],resToTest.getIJ(0,i),14); - pass - # - #Testing 2D cell types - m2=MEDCouplingDataForTest.build2DMultiTypes_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setMesh(m2); - wg3=[0.3,0.3]; - tria3CooGauss=[ 0.1, 0.8, 0.2, 0.7 ] - gsCoo3=tria3CooGauss - tria3CooRef=[ 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0 ] - refCoo3=tria3CooRef; - f.setGaussLocalizationOnType(NORM_TRI3,refCoo3,gsCoo3,wg3); - wg4=[0.3,0.3,0.3]; - tria6CooGauss=[ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4 ] - gsCoo4=tria6CooGauss; - tria6CooRef=[0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5] - refCoo4=tria6CooRef; - f.setGaussLocalizationOnType(NORM_TRI6,refCoo4,gsCoo4,wg4); - wg5=[0.3,0.3,0.3,0.3]; - quad4CooGauss=[ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27 ] - gsCoo5=quad4CooGauss; - quad4CooRef=[-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0] - refCoo5=quad4CooRef; - f.setGaussLocalizationOnType(NORM_QUAD4,refCoo5,gsCoo5,wg5); - wg6=[0.3,0.3,0.3,0.3]; - quad8CooGauss=[ 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37 ] - gsCoo6=quad8CooGauss; - quad8CooRef=[ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0] - refCoo6=quad8CooRef; - f.setGaussLocalizationOnType(NORM_QUAD8,refCoo6,gsCoo6,wg6); - # - resToTest=f.getLocalizationOfDiscr(); - self.assertEqual(3,resToTest.getNumberOfComponents()); - self.assertEqual(13,resToTest.getNumberOfTuples());#2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - expected2=[5.1,1.55,0.0, 4.7,1.65,0.0, - 2.32,1.52,0.0, 1.6,1.32,0.0, 3.52,1.26,0.0,#TRI6 - 2.6,1.6,0.0, 2.4,1.8,0.0, 2.4,1.2,0.0, 2.3,1.46,0.0,#QUAD4 - 2.32,2.68,0.0, 2.6,2.42,0.0, 2.8,2.46,0.0, 2.74,2.28,0.0 ];#QUAD8 - for i in xrange(39): - self.assertAlmostEqual(expected2[i],resToTest.getIJ(0,i),14); - pass - # - #Testing 3D cell types - m3=MEDCouplingDataForTest.build3DMultiTypes_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setMesh(m3); - # - wg7=[0.3]; - tetra4CooGauss=[0.34, 0.16, 0.21] - gsCoo7=tetra4CooGauss; - tetra4CooRef=[0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,0.0,0.0, 1.0,0.0,0.0] - refCoo7=tetra4CooRef; - f.setGaussLocalizationOnType(NORM_TETRA4,refCoo7,gsCoo7,wg7); - wg8=[0.3]; - tetra10CooGauss=[0.2, 0.3, 0.1] - gsCoo8=tetra10CooGauss; - tetra10CooRef=[0.0,1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 0.0,0.5,0.0, 0.0,0.0,0.5, 0.0,0.5,0.5, 0.5,0.5,0.0, 0.5,0.0,0.0, 0.5,0.0,0.5] - refCoo8=tetra10CooRef; - f.setGaussLocalizationOnType(NORM_TETRA10,refCoo8,gsCoo8,wg8); - wg9=[0.3]; - pyra5CooGauss=[0.2, 0.3, 0.1] - gsCoo9=pyra5CooGauss; - pyra5CooRef=[1.0,0.0,0.0, 0.0,1.0,0.0, -1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,1.0] - refCoo9=pyra5CooRef; - f.setGaussLocalizationOnType(NORM_PYRA5,refCoo9,gsCoo9,wg9); - wg10=[0.3]; - pyra13CooGauss=[0.1, 0.2, 0.7] - gsCoo10=pyra13CooGauss; - pyra13CooRef=[1.0,0.0,0.0, 0.0,1.0,0.0,-1.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.0,1.0,0.5,0.5,0.0,-0.5,0.5,0.0,-0.5,-0.5,0.0,0.5,-0.5,0.0,0.5,0.0,0.5,0.0,0.5,0.5,-0.5,0.0,0.5,0.0,-0.5,0.5] - refCoo10=pyra13CooRef; - f.setGaussLocalizationOnType(NORM_PYRA13,refCoo10,gsCoo10,wg10); - wg11=[0.3]; - penta6CooGauss=[0.2, 0.3, 0.1] - gsCoo11=penta6CooGauss; - penta6CooRef=[-1.0,1.0,0.0,-1.0,-0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0] - refCoo11=penta6CooRef; - f.setGaussLocalizationOnType(NORM_PENTA6,refCoo11,gsCoo11,wg11); - wg12=[0.3]; - penta15CooGauss=[0.2, 0.3,0.15] - gsCoo12=penta15CooGauss; - penta15CooRef=[-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0,-1.0,0.5,0.5,-1.0,0.0,0.5,-1.0,0.5,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.5,0.5,1.0,0.0, 0.5,1.0,0.5,0.0] - refCoo12=penta15CooRef; - f.setGaussLocalizationOnType(NORM_PENTA15,refCoo12,gsCoo12,wg12); - wg13=[0.3]; - hexa8CooGauss=[0.2,0.3,0.15] - gsCoo13=hexa8CooGauss; - hexa8CooRef=[-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0] - refCoo13=hexa8CooRef; - f.setGaussLocalizationOnType(NORM_HEXA8,refCoo13,gsCoo13,wg13); - wg14=[0.3]; - hexa20CooGauss=[0.11,0.3,0.55] - gsCoo14=hexa20CooGauss; - hexa20CooRef=[-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,0.0,-1.0,-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,-1.0,0.0,-1.0,-1.0,-1.0,0.0,1.0,-1.0,0.0,1.0,1.0,0.0,-1.0,1.0,0.0,0.0,-1.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,-1.0,0.0,1.0] - refCoo14=hexa20CooRef; - f.setGaussLocalizationOnType(NORM_HEXA20,refCoo14,gsCoo14,wg14); - # - resToTest=f.getLocalizationOfDiscr(); - self.assertEqual(3,resToTest.getNumberOfComponents()); - self.assertEqual(8,resToTest.getNumberOfTuples());#2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - expected3=[1.312,3.15,1.02, 0.56,3.3,0.6, 2.18,1.1,0.2, 1.18,1.54,0.98, 1.56,0.3,3.6, 1.613,0.801,4.374, 2.6,2.4,2.3, 2.31232,2.3933985,1.553255] - for i in xrange(24): - self.assertAlmostEqual(expected3[i],resToTest.getIJ(0,i),14); - pass - # - pass - - def testP2Localization1(self): - m=MEDCouplingUMesh.New("testP2",2); - coords=[0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4] - conn=[0,1,2,3,4,5] - coo=DataArrayDouble.New(); - coo.setValues(coords,6,2); - m.setCoords(coo); - m.allocateCells(1); - m.insertNextCell(NORM_TRI6,6,conn[0:6]) - m.finishInsertingCells(); - # - f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f.setMesh(m); - da=DataArrayDouble.New(); - vals1=[1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4] - da.setValues(vals1,6,3); - f.setArray(da); - # - loc=[2.27,1.3] - locs=f.getValueOnMulti(loc); - expected1=[6.0921164547752236, 7.1921164547752232, 8.2921164547752255] - for i in xrange(3): - self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); - pass - pass - - def testP2Localization2(self): - m=MEDCouplingUMesh.New("testP2_2",3); - coords=[0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891] - conn=[0,1,2,3,4,5,6,7,8,9] - coo=DataArrayDouble.New(); - coo.setValues(coords,10,3); - m.setCoords(coo); - m.allocateCells(1); - m.insertNextCell(NORM_TETRA10,10,conn[0:10]) - m.finishInsertingCells(); - # - f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f.setMesh(m); - da=DataArrayDouble.New(); - vals1=[1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2] - da.setValues(vals1,10,1); - f.setArray(da); - # - loc=[0.64637931739890486, -0.16185896817550552, 0.22678966365273748] - locs=f.getValueOnMulti(loc); - expected1=[10.0844021968047] - for i in xrange(1): - self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); - pass - pass - - def testGetValueOn2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - nbOfCells=m.getNumberOfCells(); - f.setArray(arr); - values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] - arr.setValues(values1,nbOfCells,3); - loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] - f.checkCoherency(); - locs=f.getValueOnMulti(loc); - self.assertEqual(5,locs.getNumberOfTuples()); - self.assertEqual(3,locs.getNumberOfComponents()); - for j in xrange(15): - self.assertAlmostEqual(values1[j],locs.getIJ(0,j),12); - pass - # Testing ON_NODES - f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - nbOfNodes=m.getNumberOfNodes(); - f.setArray(arr); - values2=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] - arr.setValues(values2,nbOfNodes,3); - loc2=[0.5432,-0.2432, 0.5478,0.1528, 0.5432,-0.2432, 0.5432,-0.2432] - expected2=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124, 9.0272, 109.0272, 10009.0272, 9.0272, 109.0272, 10009.0272] - f.checkCoherency(); - loc3=DataArrayDouble.New() - loc3.setValues(loc2,4,2); - locs=f.getValueOnMulti(loc3); - self.assertEqual(4,locs.getNumberOfTuples()); - self.assertEqual(3,locs.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(expected2[i],locs.getIJ(0,i),12); - pass - # - pass - - def testDAIGetIdsNotEqual1(self): - d=DataArrayInt.New(); - vals1=[2,3,5,6,8,5,5,6,1,-5] - d.setValues(vals1,10,1); - d2=d.getIdsNotEqual(5); - self.assertEqual(7,d2.getNumberOfTuples()); - self.assertEqual(1,d2.getNumberOfComponents()); - expected1=[0,1,3,4,7,8,9] - for i in xrange(7): - self.assertEqual(expected1[i],d2.getIJ(0,i)); - pass - d.rearrange(2); - self.assertRaises(InterpKernelException,d.getIdsNotEqual,5); - vals2=[-4,5,6] - vals3=vals2; - d.rearrange(1); - d3=d.getIdsNotEqualList(vals3); - self.assertEqual(5,d3.getNumberOfTuples()); - self.assertEqual(1,d3.getNumberOfComponents()); - expected2=[0,1,4,8,9] - for i in xrange(5): - self.assertEqual(expected2[i],d3.getIJ(0,i)); - pass - pass - - def testDAIComputeOffsets1(self): - d=DataArrayInt.New(); - vals1=[3,5,1,2,0,8] - expected1=[0,3,8,9,11,11] - d.setValues(vals1,6,1); - d.computeOffsets(); - self.assertEqual(6,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected1[i],d.getIJ(0,i)); - pass - pass - - def testUMeshHexagonPrism1(self): - coords=[0.8660254037844386, 0.5, 0.0, 0.0, 1.0, 0.0, -0.8660254037844386, 0.5, 0.0, -0.8660254037844386, -0.5, 0.0, 0.0, -1.0, 0.0, 0.8660254037844386, -0.5, 0.0, - 0.8660254037844386, 0.5, 2.0, 0.0, 1.0, 2.0, -0.8660254037844386, 0.5, 2.0, -0.8660254037844386, -0.5, 2.0, 0.0, -1.0, 2.0, 0.8660254037844386, -0.5, 2.0]; - conn=[1,2,3,4,5,0,7,8,9,10,11,6] - mesh=MEDCouplingUMesh.New("MyFirstHexagonalPrism",3); - coo=DataArrayDouble.New(); - coo.setValues(coords,12,3); - mesh.setCoords(coo); - mesh.allocateCells(1); - mesh.insertNextCell(NORM_HEXGP12,12,conn[0:12]) - mesh.finishInsertingCells(); - # - mesh.checkCoherency(); - vols=mesh.getMeasureField(False); - self.assertEqual(1,vols.getNumberOfTuples()); - self.assertEqual(1,vols.getNumberOfComponents()); - self.assertAlmostEqual(-5.196152422706632,vols.getIJ(0,0),12); - bary=mesh.getBarycenterAndOwner(); - self.assertEqual(1,bary.getNumberOfTuples()); - self.assertEqual(3,bary.getNumberOfComponents()); - expected1=[0.,0.,1.] - for i in xrange(3): - self.assertAlmostEqual(expected1[i],bary.getIJ(0,i),12); - pass - d1=DataArrayInt.New(); - d2=DataArrayInt.New(); - d3=DataArrayInt.New(); - d4=DataArrayInt.New(); - m2=mesh.buildDescendingConnectivity(d1,d2,d3,d4); - self.assertEqual(8,m2.getNumberOfCells()); - expected4=[[1,2,3,4,5,0],[7,6,11,10,9,8],[1,7,8,2],[2,8,9,3],[3,9,10,4],[4,10,11,5],[5,11,6,0],[0,6,7,1]]; - expected2=[NORM_POLYGON, NORM_POLYGON, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4]; - expected3=[6,6,4,4,4,4,4,4] - for i in xrange(8): - self.assertTrue(m2.getTypeOfCell(i)==expected2[i]); - v=m2.getNodeIdsOfCell(i); - self.assertTrue(len(v)==expected3[i]); - self.assertEqual(expected4[i],v); - # - mesh.convertAllToPoly(); - self.assertTrue(NORM_POLYHED==mesh.getTypeOfCell(0)); - mesh.unPolyze(); - self.assertTrue(NORM_HEXGP12==mesh.getTypeOfCell(0)); - self.assertEqual(13,mesh.getMeshLength()); - # - pass - - def testDADCheckIsMonotonic(self): - da=DataArrayDouble.New(); - da.setValues([-1.,1.01,2.03,6.],2,2); - self.assertRaises(InterpKernelException,da.isMonotonic,True,1e-12); - da.rearrange(1); - self.assertTrue(da.isMonotonic(True,1e-12)); - da.checkMonotonic(True,1e-12); - da.setIJ(2,0,6.1); - self.assertTrue(not da.isMonotonic(True,1e-12)); - self.assertRaises(InterpKernelException,da.checkMonotonic,True,1e-12); - da.setIJ(2,0,5.99); - self.assertTrue(da.isMonotonic(True,1e-12)); - self.assertTrue(not da.isMonotonic(True,1e-1)); - pass - - def testCheckCoherencyDeeper1(self): - m=MEDCouplingDataForTest.build3DSourceMesh_1(); - m.checkCoherency(); - m.checkCoherency1(); - m.getNodalConnectivity().setIJ(8,0,-1); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(8,0,-6); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(8,0,9);#9>=NbOfNodes - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(8,0,8);#OK - m.checkCoherency(); - m.checkCoherency1(); - elts=[1,5] - m.convertToPolyTypes(elts); - m.checkCoherency(); - m.checkCoherency1(); - m.getNodalConnectivity().setIJ(2,0,9);#9>=NbOfNodes - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(2,0,-3); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(2,0,-1); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw because cell#0 is not a polyhedron - m.getNodalConnectivity().setIJ(2,0,4); - m.checkCoherency(); - m.checkCoherency1(); - m.getNodalConnectivity().setIJ(7,0,-1); - m.checkCoherency(); - m.checkCoherency1();#OK because we are in polyhedron connec - m.getNodalConnectivity().setIJ(36,0,14); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. - pass - - def testUnPolyze2(self): - m=MEDCouplingUMesh.New("jjj",3); - coo=DataArrayDouble.New(); - coo.alloc(4,3); - coo.rearrange(1); - coo.iota(0); - coo.rearrange(3); - m.setCoords(coo); - m.allocateCells(2); - m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); - m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); - m.finishInsertingCells(); - m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(4*[m]); - m2.convertToPolyTypes([2]); - m2.unPolyze(); - self.assertEqual(NORM_TETRA4,m2.getTypeOfCell(2)); - self.assertEqual(40,m2.getMeshLength()); - temp2=m2.getNodeIdsOfCell(2); - self.assertEqual(temp2,[0,1,2,3]); - m2.checkCoherency1(); - m3=m2.deepCpy(); - m2.unPolyze(); - self.assertTrue(m3.isEqual(m2,1e-12)); - pass - - def testDACpyFrom1(self): - d=DataArrayDouble.New(); - d.alloc(12,1); - d.iota(14.); - d.rearrange(3); - d.setName("Toto"); - d.setInfoOnComponent(0,"X [m]"); - d.setInfoOnComponent(1,"Y [m]"); - d.setInfoOnComponent(2,"Z [m]"); - # - d1=DataArrayDouble.New(); - self.assertTrue(not d.isEqual(d1,1e-12)); - d1.cpyFrom(d); - self.assertTrue(d.isEqual(d1,1e-12)); - d1.cpyFrom(d); - self.assertTrue(d.isEqual(d1,1e-12)); - d1.rearrange(2); - self.assertTrue(not d.isEqual(d1,1e-12)); - d1.cpyFrom(d); - self.assertTrue(d.isEqual(d1,1e-12)); - # - d2=d.convertToIntArr(); - d4=DataArrayInt.New(); - self.assertTrue(not d2.isEqual(d4)); - d4.cpyFrom(d2); - self.assertTrue(d2.isEqual(d4)); - d4.cpyFrom(d2); - self.assertTrue(d2.isEqual(d4)); - d4.rearrange(2); - self.assertTrue(not d2.isEqual(d4)); - d4.cpyFrom(d2); - self.assertTrue(d2.isEqual(d4)); - pass - - def testDAITransformWithIndArr1(self): - tab1=[17,18,22,19] - tab2=[0,1,1,3,3,0,1,3,2,2,3,0] - expected=[17,18,18,19,19,17,18,19,22,22,19,17] - d=DataArrayInt.New(); - d.setValues(tab1,4,1); - d1=DataArrayInt.New(); - d1.setValues(tab2,12,1); - d2=d1[:] - # - d1.transformWithIndArr(d); - self.assertEqual(12,d1.getNumberOfTuples()); - self.assertEqual(1,d1.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected[i],d1.getIJ(i,0)); - pass - # - d1=d2 - d1.transformWithIndArr(tab1) - self.assertEqual(12,d1.getNumberOfTuples()); - self.assertEqual(1,d1.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected[i],d1.getIJ(i,0)); - pass - pass - - def testDAIBuildPermArrPerLevel1(self): - arr=[2,0,1,1,0,1,2,0,1,1,0,0] - expected1=[10,0,5,6,1,7,11,2,8,9,3,4] - da=DataArrayInt.New(); - da.setValues(arr,12,1); - da2=da.buildPermArrPerLevel(); - self.assertEqual(12,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected1[i],da2.getIJ(i,0)); - pass - pass - - def testDAIOperations1(self): - arr1=[-1,-2,4,7,3,2,6,6,4,3,0,1] - da=DataArrayInt.New(); - da.setValues(arr1,4,3); - da1=DataArrayInt.New(); - da1.alloc(12,1); - da1.iota(2); - self.assertRaises(InterpKernelException,DataArrayInt.Add,da,da1);#not same number of tuples/Components - da1.rearrange(3); - da2=DataArrayInt.Add(da,da1); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents()); - expected1=[1,1,8,12,9,9,14,15,14,14,12,14] - for i in xrange(12): - self.assertEqual(expected1[i],da2.getIJ(0,i)); - pass - da1.substractEqual(da); - expected2=[3,5,0,-2,3,5,2,3,6,8,12,12] - for i in xrange(12): - self.assertEqual(expected2[i],da1.getIJ(0,i)); - pass - da1.rearrange(1); da1.iota(2); da1.rearrange(3); - da1.addEqual(da); - for i in xrange(12): - self.assertEqual(expected1[i],da1.getIJ(0,i)); - pass - da1.rearrange(1); da1.iota(2); da1.rearrange(3); - da2=DataArrayInt.Multiply(da,da1); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents()); - expected3=[-2,-6,16,35,18,14,48,54,40,33,0,13] - for i in xrange(12): - self.assertEqual(expected3[i],da2.getIJ(0,i)); - pass - da.divideEqual(da1); - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - expected4=[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] - for i in xrange(12): - self.assertEqual(expected4[i],da.getIJ(0,i)); - pass - da.setValues(arr1,4,3); - da1.multiplyEqual(da); - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected3[i],da1.getIJ(0,i)); - pass - da1.rearrange(1); da1.iota(2); da1.rearrange(3); - da2=DataArrayInt.Divide(da,da1); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected4[i],da2.getIJ(0,i)); - pass - da1.applyInv(321); - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - expected5=[160,107,80,64,53,45,40,35,32,29,26,24] - for i in xrange(12): - self.assertEqual(expected5[i],da1.getIJ(0,i)); - pass - da1.applyDivideBy(2); - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - expected6=[80,53,40,32,26,22,20,17,16,14,13,12] - for i in xrange(12): - self.assertEqual(expected6[i],da1.getIJ(0,i)); - pass - expected7=[3,4,5,4,5,1,6,3,2,0,6,5] - da1.applyModulus(7); - for i in xrange(12): - self.assertEqual(expected7[i],da1.getIJ(0,i)); - pass - da1.applyLin(1,1); - expected8=[3,3,3,3,3,1,3,3,0,0,3,3] - da1.applyRModulus(3); - for i in xrange(12): - self.assertEqual(expected8[i],da1.getIJ(0,i)); - pass - pass - - def testEmulateMEDMEMBDC1(self): - m,m1=MEDCouplingDataForTest.buildPointe_1(); - m2,da1,da2,da3,da4,da5,da0=m.emulateMEDMEMBDC(m1) - expected0=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46] - expected1=[1,32,29,23,41,36] - self.assertEqual(47,da0.getNumberOfTuples()); - self.assertEqual(1,da0.getNumberOfComponents()); - for i in xrange(47): - self.assertEqual(expected0[i],da0.getIJ(0,i)); - pass - self.assertEqual(6,da5.getNumberOfTuples()); - self.assertEqual(1,da5.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected1[i],da5.getIJ(0,i)); - pass - expected2=[0,1,2,3,4,0,5,6,7,4,8,9,1,7,10,11,12,13,14,5,15,16,17,8,18,19,20,10,21,22,23,2,13,24,25,21,16,26,27,12,19,28,29,15,22,30,31,18,36,26,28,30,24,37,32,33,34,35,38,36,39,40,41,42,37,38,43,44,45,46] - self.assertEqual(70,da1.getNumberOfTuples()); - self.assertEqual(1,da1.getNumberOfComponents()); - for i in xrange(70): - self.assertEqual(expected2[i],da1.getIJ(0,i)); - pass - expected3=[0,4,8,12,16,20,24,28,32,36,40,44,48,53,58,64,70] - self.assertEqual(17,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(17): - self.assertEqual(expected3[i],da2.getIJ(0,i)); - pass - expected4=[0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,53,54,55,56,58,60,62,63,64,65,66,67,68,69,70] - #expected4=[0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,54,56,57,58,59,60,62,63,64,65,66,67,68,69,70]; - self.assertEqual(48,da4.getNumberOfTuples()); - self.assertEqual(1,da4.getNumberOfComponents()); - for i in xrange(48): - self.assertEqual(expected4[i],da4.getIJ(0,i)); - pass - expected5=[0,1,0,3,0,7,0,1,2,1,4,1,2,3,2,5,2,3,6,3,4,9,4,8,4,5,10,5,9,5,6,11,6,10,6,7,8,7,11,7,8,12,8,9,12,9,10,12,10,11,12,11,13,13,13,13,12,14,13,15,14,15,14,14,14,14,15,15,15,15] - self.assertEqual(70,da3.getNumberOfTuples()); - self.assertEqual(1,da3.getNumberOfComponents()); - for i in xrange(70): - self.assertEqual(expected5[i],da3.getIJ(0,i)); - pass - pass - - def testGetLevArrPerCellTypes1(self): - m,m1=MEDCouplingDataForTest.buildPointe_1(); - m1,d0,d1,d2,d3=m.buildDescendingConnectivity(); - order=[NORM_TRI3,NORM_QUAD4]; - da0,da1=m1.getLevArrPerCellTypes(order); - expected0=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1] - expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46] - self.assertEqual(47,da0.getNumberOfTuples()); - self.assertEqual(1,da0.getNumberOfComponents()); - for i in xrange(47): - self.assertEqual(expected0[i],da0.getIJ(0,i)); - pass - self.assertEqual(2,da1.getNumberOfTuples()); - self.assertEqual(1,da1.getNumberOfComponents()); - self.assertEqual(36,da1.getIJ(0,0));#36 TRI3 - self.assertEqual(11,da1.getIJ(1,0));#11 QUAD4 - # - da2=da0.buildPermArrPerLevel(); - # - self.assertEqual(47,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(47): - self.assertEqual(expected1[i],da2.getIJ(0,i)); - pass - pass - - def testSortCellsInMEDFileFrmt1(self): - m,m1=MEDCouplingDataForTest.buildPointe_1(); - m2=m.deepCpy() - da=DataArrayInt.New() - da.setValues([0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13],16,1) - daa=da.invertArrayN2O2O2N(16) - m.renumberCells(daa,False) - da2=m.sortCellsInMEDFileFrmt() - self.assertEqual(da2.getValues(),[0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13]) - self.assertTrue(m.isEqual(m2,1e-12)) - self.assertTrue(da.isEqual(da2)) - pass - - def testBuildPartAndReduceNodes1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - arr=[1,0] - m2,da=m.buildPartAndReduceNodes(arr); - self.assertEqual(5,m2.getNumberOfNodes()); - self.assertEqual(2,m2.getNumberOfCells()); - f=m2.getMeasureField(True); - self.assertAlmostEqual(0.125,f.getArray().getIJ(0,0),12); - self.assertAlmostEqual(0.25,f.getArray().getIJ(1,0),12); - # - arr2=DataArrayInt.New() - arr2.setValues(arr,2,1) - m2,da=m.buildPartAndReduceNodes(arr2); - self.assertEqual(5,m2.getNumberOfNodes()); - self.assertEqual(2,m2.getNumberOfCells()); - f=m2.getMeasureField(True); - self.assertAlmostEqual(0.125,f.getArray().getIJ(0,0),12); - self.assertAlmostEqual(0.25,f.getArray().getIJ(1,0),12); - pass - - def testDAITransformWithIndArrR1(self): - tab1=[2,4,5,3,6,7] - tab2=[-1,-1,0,1,2,3,4,5,-1,-1,-1,-1] - expected=[0,3,1,2,4,5] - d=DataArrayInt.New(); - d.setValues(tab1,6,1); - d1=DataArrayInt.New(); - d1.setValues(tab2,12,1); - d2=d1[:] - # - d3=d.transformWithIndArrR(d1); - self.assertEqual(6,d3.getNumberOfTuples()); - self.assertEqual(1,d3.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected[i],d3.getIJ(i,0)); - pass - # - d1=d2 - d3=d.transformWithIndArrR(tab2) - self.assertEqual(6,d3.getNumberOfTuples()); - self.assertEqual(1,d3.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected[i],d3.getIJ(i,0)); - pass - pass - - def testDAISplitByValueRange1(self): - val1=[6,5,0,3,2,7,8,1,4] - val2=[0,4,9] - d=DataArrayInt.New(); - d.setValues(val1,9,1); - e,f,g=d.splitByValueRange(val2); - self.assertEqual(9,e.getNumberOfTuples()); - self.assertEqual(1,e.getNumberOfComponents()); - self.assertEqual(9,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - self.assertEqual(2,g.getNumberOfTuples()); - self.assertEqual(1,g.getNumberOfComponents()); - # - expected1=[1,1,0,0,0,1,1,0,1] - expected2=[2,1,0,3,2,3,4,1,0] - for i in xrange(9): - self.assertEqual(expected1[i],e.getIJ(i,0)); - self.assertEqual(expected2[i],f.getIJ(i,0)); - pass - self.assertEqual(0,g.getIJ(0,0)); - self.assertEqual(1,g.getIJ(1,0)); - # - d.setIJ(6,0,9); - self.assertRaises(InterpKernelException,d.splitByValueRange,val2); - pass - - def testUMeshSplitProfilePerType1(self): - val0=[2,0,1,3,4] - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.renumberCells(val0,False); - # - val1=[0,2,3] - d=DataArrayInt.New(); - d.setValues(val1,3,1); - d.setName("sup") - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(2,len(code)); - self.assertEqual(2,len(idsInPflPerType)); - expected1=[[3,1,0], [4,2,1]] - self.assertEqual(expected1,code) - self.assertEqual(2,len(idsInPflPerType)); - self.assertEqual(1,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(2,idsInPflPerType[1].getNumberOfTuples()); - self.assertEqual(1,idsInPflPerType[1].getIJ(0,0)); - self.assertEqual(2,idsInPflPerType[1].getIJ(1,0)); - # - self.assertEqual(2,len(pfls)); - self.assertEqual("sup",pfls[0].getName()) - self.assertEqual(1,pfls[0].getNumberOfTuples()); - self.assertEqual(0,pfls[0].getIJ(0,0)); - self.assertEqual("sup",pfls[1].getName()) - self.assertEqual(2,pfls[1].getNumberOfTuples()); - self.assertEqual(0,pfls[1].getIJ(0,0)); - self.assertEqual(1,pfls[1].getIJ(1,0)); - # - val2=[0,2,3,4] - d=DataArrayInt.New(); - d.setValues(val2,4,1); - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(2,len(code)); - self.assertEqual(2,len(idsInPflPerType)); - expected2=[[3,1,0], [4,3,-1]] - self.assertEqual(expected2,code); - self.assertEqual(2,len(idsInPflPerType)); - self.assertEqual(1,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(3,idsInPflPerType[1].getNumberOfTuples()); - self.assertEqual(1,idsInPflPerType[1].getIJ(0,0)); - self.assertEqual(2,idsInPflPerType[1].getIJ(1,0)); - self.assertEqual(3,idsInPflPerType[1].getIJ(2,0)); - # - self.assertEqual(1,len(pfls)); - self.assertEqual(1,pfls[0].getNumberOfTuples()); - self.assertEqual(0,pfls[0].getIJ(0,0)); - # - val3=[1,0,2] - d=DataArrayInt.New(); - d.setValues(val3,3,1); - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(2,len(code)); - self.assertEqual(2,len(idsInPflPerType)); - expected3=[[3,2,0], [4,1,1]] - self.assertEqual(expected3,code); - self.assertEqual(2,len(idsInPflPerType)); - self.assertEqual(2,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(1,idsInPflPerType[0].getIJ(1,0)); - self.assertEqual(1,idsInPflPerType[1].getNumberOfTuples()); - self.assertEqual(2,idsInPflPerType[1].getIJ(0,0)); - # - self.assertEqual(2,len(pfls)); - self.assertEqual(2,pfls[0].getNumberOfTuples()); - self.assertEqual(1,pfls[0].getIJ(0,0)); - self.assertEqual(0,pfls[0].getIJ(1,0)); - self.assertEqual(0,pfls[1].getIJ(0,0)); - # - val4=[3,4] - d=DataArrayInt.New(); - d.setValues(val4,2,1); - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(1,len(code)); - self.assertEqual(1,len(idsInPflPerType)); - expected4=[[4,2,0]] - self.assertEqual(expected4,code); - self.assertEqual(1,len(idsInPflPerType)); - self.assertEqual(2,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(1,idsInPflPerType[0].getIJ(1,0)); - # - self.assertEqual(1,len(pfls)); - self.assertEqual(2,pfls[0].getNumberOfTuples()); - self.assertEqual(1,pfls[0].getIJ(0,0)); - self.assertEqual(2,pfls[0].getIJ(1,0)); - pass - - def testDAIBuildExplicitArrByRanges1(self): - d=DataArrayInt.New(); - vals1=[0,2,3] - d.setValues(vals1,3,1); - e=DataArrayInt.New(); - vals2=[0,3,6,10,14,20] - e.setValues(vals2,6,1); - # - f=d.buildExplicitArrByRanges(e); - self.assertEqual(11,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected1=[0,1,2,6,7,8,9,10,11,12,13] - for i in xrange(11): - self.assertEqual(expected1[i],f.getIJ(i,0)); - pass - pass - - def testDAIComputeOffsets2(self): - d=DataArrayInt.New(); - vals1=[3,5,1,2,0,8] - expected1=[0,3,8,9,11,11,19] - d.setValues(vals1,6,1); - d.computeOffsets2(); - self.assertEqual(7,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - for i in xrange(7): - self.assertEqual(expected1[i],d.getIJ(0,i)); - pass - pass - - def testMergeField3(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.getCoords().setInfoOnComponent(0,"x [m]"); - m.getCoords().setInfoOnComponent(1,"z [km]"); - m.setName("m"); - m.setDescription("desc"); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("f1"); - f1.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.setInfoOnComponent(0,"X [m]"); - arr.setInfoOnComponent(1,"YY [mm]"); - arr.fillWithValue(2.); - f1.setArray(arr); - # - f2=MEDCouplingFieldDouble.MergeFields([f1]); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - pass - - def testGetDistributionOfTypes1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - tab1=[2,0,1,3,4] - self.assertRaises(InterpKernelException,m.getDistributionOfTypes); - m.renumberCells(tab1,False); - code=m.getDistributionOfTypes(); - self.assertEqual(2,len(code)); - self.assertEqual(3,code[0][0]); - self.assertEqual(2,code[0][1]); - self.assertEqual(-1,code[0][2]); - self.assertEqual(4,code[1][0]); - self.assertEqual(3,code[1][1]); - self.assertEqual(-1,code[1][2]); - pass - - def testNorm2_1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f.setMesh(m); - # - d=DataArrayDouble.New(); - tab=[1.2,1.3,2.2,2.3,3.2,3.3,4.2,4.3,5.2,5.3] - d.setValues(tab,5,2); - f.setArray(d); - f.checkCoherency(); - # - self.assertAlmostEqual(11.209371079592289,f.norm2(),14); - # - pass - - def testNormMax1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f.setMesh(m); - # - d=DataArrayDouble.New(); - tab=[2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6] - d.setValues(tab,5,2); - f.setArray(d); - f.checkCoherency(); - # - self.assertAlmostEqual(7.8,f.normMax(),14); - # - pass - - def testFindAndCorrectBadOriented3DExtrudedCells1(self): - coords=[0.0011180339887498999, -0.0011755705045849499, 0.0, -0.0012331070204200001, -0.0011755705045849499, 0.0, -0.00067557050458494599, -0.00145964954842536, 0.0, -0.00050000000000000001, -0.00086602540378443902, 0.0, 0.00140211303259031, -0.00061803398874989504, 0.0, 0.00086602540378443902, -0.00050000000000000001, 0.0, 0.001, 0.0, 0.0, 0.00034561537182258202, 0.000269164072574575, 0.0, 0.0, 0.001, 0.0, -0.00050000000000000001, 0.00086602540378443902, 0.0, -0.000269164072574575, 0.00034561537182258202, 0.0, -0.001, 0.0, 0.0, -0.00086602540378443902, -0.00050000000000000001, 0.0, -0.00034561537182258202, -0.000269164072574575, 0.0, 0.0, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, 0.0, 0.000269164072574575, -0.00034561537182258202, 0.0, 0.0015, -6.01853107621011e-36, 0.0, 0.00056049747291484397, -0.00145964954842536, 0.0, 0.0011180339887498999, -0.0011755705045849499, 0.00050000000000000001, -0.0012331070204200001, -0.0011755705045849499, 0.00050000000000000001, -0.00067557050458494599, -0.00145964954842536, 0.00050000000000000001, -0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.00140211303259031, -0.00061803398874989504, 0.00050000000000000001, 0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, 0.001, 0.0, 0.00050000000000000001, 0.00034561537182258202, 0.000269164072574575, 0.00050000000000000001, 0.0, 0.001, 0.00050000000000000001, -0.00050000000000000001, 0.00086602540378443902, 0.00050000000000000001, -0.000269164072574575, 0.00034561537182258202, 0.00050000000000000001, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, -0.00034561537182258202, -0.000269164072574575, 0.00050000000000000001, 0.0, -0.001, 0.00050000000000000001, 0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.000269164072574575, -0.00034561537182258202, 0.00050000000000000001, 0.0015, -6.01853107621011e-36, 0.00050000000000000001, 0.00056049747291484397, -0.00145964954842536, 0.00050000000000000001]; - conn=[2, 1, 3, 21, 20, 22, 4, 0, 5, 23, 19, 24, 8, 9, 10, 27, 28, 29, 11, 12, 13, 30, 31, 32, 0, 18, 15, 5, 19, 37, 34, 24, 6, 17, 4, 5, 25, 36, 23, 24, 3, 14, 16, 13, 22, 33, 35, 32, 13, 16, 7, 10, 32, 35, 26, 29] - connExp=[16, 2, 1, 3, 21, 20, 22, 16, 4, 0, 5, 23, 19, 24, 16, 8, 10, 9, 27, 29, 28, 16, 11, 13, 12, 30, 32, 31, 18, 0, 18, 15, 5, 19, 37, 34, 24,18, 6, 17, 4, 5, 25, 36, 23, 24, 18, 3, 13, 16, 14, 22, 32, 35, 33, 18, 13, 10, 7, 16, 32, 29, 26, 35] - invalidCells=[2,3,6,7] - m=MEDCouplingUMesh.New("Example",3); - coo=DataArrayDouble.New(); - coo.setValues(coords,38,3); - m.setCoords(coo); - m.allocateCells(8); - m.insertNextCell(NORM_PENTA6,6,conn[0:6]) - m.insertNextCell(NORM_PENTA6,6,conn[6:12]) - m.insertNextCell(NORM_PENTA6,6,conn[12:18]) - m.insertNextCell(NORM_PENTA6,6,conn[18:24]) - m.insertNextCell(NORM_HEXA8,8,conn[24:32]) - m.insertNextCell(NORM_HEXA8,8,conn[32:40]) - m.insertNextCell(NORM_HEXA8,8,conn[40:48]) - m.insertNextCell(NORM_HEXA8,8,conn[48:56]) - m.finishInsertingCells(); - # - v=m.findAndCorrectBadOriented3DExtrudedCells(); - self.assertEqual(4,len(v)); - self.assertEqual(v.getValues(),invalidCells); - self.assertEqual(connExp,m.getNodalConnectivity().getValues()); - self.assertTrue(m.findAndCorrectBadOriented3DExtrudedCells().empty()) - # - pass - - def testConvertExtrudedPolyhedra1(self): - conn=[1,2,3,4, 5,6,7,8,9,10,11,12, 13,14,15,16, 17,18,19,20,21,22, 23,24,25,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,65,66,67,68,69,70,71,72] - m=MEDCouplingUMesh.New("Example",3); - coo=DataArrayDouble.New(); - coo.alloc(73,3); - coo.rearrange(1); coo.iota(0); coo.rearrange(3); - m.setCoords(coo); - m.allocateCells(9); - m.insertNextCell(NORM_TETRA4,4,conn[0:4]) - m.insertNextCell(NORM_HEXA8,8,conn[4:12]) - m.insertNextCell(NORM_TETRA4,4,conn[12:16]) - m.insertNextCell(NORM_POLYHED,6,conn[16:22]) - m.insertNextCell(NORM_PENTA6,6,conn[22:28]) - m.insertNextCell(NORM_POLYHED,10,conn[28:38]) - m.insertNextCell(NORM_HEXA8,8,conn[38:46]) - m.insertNextCell(NORM_HEXGP12,12,conn[46:58]) - m.insertNextCell(NORM_POLYHED,14,conn[58:72]) - m.finishInsertingCells(); - # - m.convertExtrudedPolyhedra(); - da=m.getNodalConnectivity(); - dai=m.getNodalConnectivityIndex(); - self.assertEqual(10,dai.getNbOfElems()); - self.assertEqual(159,da.getNbOfElems()); - # - expected1=[14,1,2,3,4,18,5,6,7,8,9,10,11,12,14,13,14,15,16,31,17,18,19,-1,20,22,21,-1,17,20,21,18,-1,18,21,22,19,-1,19,22,20,17,16,23,24,25,26,27,28,31,29,30,31,32,33,-1,34,38,37,36,35,-1,29,34,35,30,-1,30,35,36,31,-1,31,36,37,32,-1,32,37,38,33,-1,33,38,34,29,18,39,40,41,42,43,44,45,46,22,47,48,49,50,51,52,53,54,55,56,57,58,31,59,60,61,62,63,64,65,-1,66,72,71,70,69,68,67,-1,59,66,67,60,-1,60,67,68,61,-1,61,68,69,62,-1,62,69,70,63,-1,63,70,71,64,-1,64,71,72,65,-1,65,72,66,59]; - expected2=[0,5,14,19,42,49,86,95,108,159] - self.assertEqual(expected1,da.getValues()); - self.assertEqual(expected2,dai.getValues()); - m.checkCoherency2() - pass - - def testNonRegressionCopyTinyStrings(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f1=m.getMeasureField(True) - f1.getArray().setInfoOnComponent(0,"P [N/m^2]") - bary=m.getBarycenterAndOwner() - f2=f1.buildNewTimeReprFromThis(NO_TIME,False) - f2.setArray(bary) - self.assertRaises(InterpKernelException,f1.copyTinyAttrFrom,f2) - pass - - def testDaDSetPartOfValuesAdv1(self): - tab1=[3.,4.,5., 13.,14.,15., 23.,24.,25., 33.,34.,35., 43.,44.,45., 53.,54.,55.] - tab2=[6.,7.,8., 16.,17.,18., 26.,27.,28.] - tab3=[4,1, 2,2, 3,0] - a=DataArrayDouble.New(); - a.setValues(tab1,6,3); - b=DataArrayDouble.New(); - b.setValues(tab2,3,3); - c=DataArrayInt.New(); - c.setValues(tab3,3,2); - # - a.setPartOfValuesAdv(b,c); - expected1=[3.,4.,5., 13.,14.,15., 26.,27.,28., 6.,7.,8., 16.,17.,18., 53.,54.,55.] - self.assertEqual(expected1,a.getValues()); - pass - - def testUMeshBuildSetInstanceFromThis1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=m.buildSetInstanceFromThis(3); - self.assertTrue(m.isEqual(m2,1e-12)); - # - m=MEDCouplingUMesh.New("toto",2); - m2=m.buildSetInstanceFromThis(3); - self.assertEqual(0,m2.getNumberOfNodes()); - self.assertEqual(0,m2.getNumberOfCells()); - pass - - def testUMeshMergeMeshesCVW1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingUMesh.New("toto",2); - m3=MEDCouplingUMesh.MergeUMeshes([m,m2]); - m3.setName(m.getName()); - self.assertTrue(m.isEqual(m3,1e-12)); - pass - - def testChangeUnderlyingMeshWithCMesh1(self): - mesh=MEDCouplingCMesh.New(); - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4. ] - coordsX.setValues(arrX,4,1); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8. ] - coordsY.setValues(arrY,4,1); - coordsZ=DataArrayDouble.New(); - arrZ=[ -3., 3., 6., 12. ] - coordsZ.setValues(arrZ,4,1); - mesh.setCoords(coordsX,coordsY,coordsZ); - f=mesh.getMeasureField(True) - mesh2=mesh.deepCpy() - for myId in [0,1,2,10,11,12,20,21,22]: - f=mesh.getMeasureField(True) - f.changeUnderlyingMesh(mesh2,myId,1e-12); - pass - mesh2.setName("uuuu") - for myId in [1,2,10,11,12,20,21,22]: - f=mesh.getMeasureField(True) - f.changeUnderlyingMesh(mesh2,myId,1e-12); - pass - pass - - def testDADFindCommonTuples1(self): - da=DataArrayDouble.New(); - # nbOftuples=1 - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da.setValues(array1,6,1) - c,cI=da.findCommonTuples(1e-2); - expected1=[0,3,4] - expected2=[0,3] - self.assertEqual(3,c.getNbOfElems()); - self.assertEqual(2,cI.getNbOfElems()); - self.assertEqual(expected1,c.getValues()) - self.assertEqual(expected2,cI.getValues()) - c,cI=da.findCommonTuples(2e-1) - expected3=[0,3,4,1,2] - expected4=[0,3,5] - self.assertEqual(5,c.getNbOfElems()); - self.assertEqual(3,cI.getNbOfElems()); - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) - # nbOftuples=2 - array2=[2.3,2.3,1.2,1.2,1.3,1.3,2.3,2.3,2.301,2.301,0.8,0.8] - da.setValues(array2,6,2) - c,cI=da.findCommonTuples(1e-2); - self.assertEqual(3,c.getNbOfElems()); - self.assertEqual(2,cI.getNbOfElems()); - self.assertEqual(expected1,c.getValues()) - self.assertEqual(expected2,cI.getValues()) - c,cI=da.findCommonTuples(2e-1) - self.assertEqual(5,c.getNbOfElems()); - self.assertEqual(3,cI.getNbOfElems()); - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) - # nbOftuples=3 - array3=[2.3,2.3,2.3,1.2,1.2,1.2,1.3,1.3,1.3,2.3,2.3,2.3,2.301,2.301,2.301,0.8,0.8,0.8] - da.setValues(array3,6,3) - c,cI=da.findCommonTuples(1e-2); - self.assertEqual(3,c.getNbOfElems()); - self.assertEqual(2,cI.getNbOfElems()); - self.assertEqual(expected1,c.getValues()) - self.assertEqual(expected2,cI.getValues()) - c,cI=da.findCommonTuples(2e-1) - self.assertEqual(5,c.getNbOfElems()); - self.assertEqual(3,cI.getNbOfElems()); - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) - # nbOftuples=1, no common groups - array11=[2.3,1.2,1.3,2.4,2.5,0.8] - da.setValues(array11,6,1) - c,cI=da.findCommonTuples(1e-2); - self.assertEqual(0,c.getNbOfElems()); - self.assertEqual(1,cI.getNbOfElems()); - self.assertEqual([0],cI.getValues()) - - array12=[0.]*(6*5) - da.setValues(array12,6,5) #bad NumberOfComponents - self.assertRaises(InterpKernelException, da.findCommonTuples, 1e-2); - pass - - def testDABack1(self): - da=DataArrayDouble.New(); - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da.setValues(array1,6,1); - self.assertAlmostEqual(0.8,da.back(),14); - da.rearrange(2); - self.assertRaises(InterpKernelException,da.back); - da.alloc(0,1); - self.assertRaises(InterpKernelException,da.back); - # - da=DataArrayInt.New(); - array2=[4,7,8,2] - da.setValues(array2,4,1); - self.assertEqual(2,da.back()); - da.rearrange(2); - self.assertRaises(InterpKernelException,da.back); - da.alloc(0,1); - self.assertRaises(InterpKernelException,da.back); - pass - - def testDADGetDifferentValues1(self): - da=DataArrayDouble.New(); - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da.setValues(array1,6,1) - # - expected1=[2.301,1.2,1.3,0.8] - dv=da.getDifferentValues(1e-2); - self.assertEqual(4,dv.getNbOfElems()); - for i in xrange(4): - self.assertAlmostEqual(expected1[i],dv.getIJ(i,0),14); - pass - # - dv=da.getDifferentValues(2e-1); - expected2=[2.301,1.3,0.8] - self.assertEqual(3,dv.getNbOfElems()); - for i in xrange(3): - self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14); - pass - pass - - def testDAIBuildOld2NewArrayFromSurjectiveFormat2(self): - arr=[0,3, 5,7,9] - arrI=[0,2,5] - a=DataArrayInt.New(); - a.setValues(arr,5,1); - b=DataArrayInt.New(); - b.setValues(arrI,3,1); - ret,newNbTuple=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(10,a,b); - expected=[0,1,2,0,3,4,5,4,6,4] - self.assertEqual(10,ret.getNbOfElems()); - self.assertEqual(7,newNbTuple); - self.assertEqual(1,ret.getNumberOfComponents()); - self.assertEqual(expected,ret.getValues()); - self.assertRaises(InterpKernelException,DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2,9,a,b); - pass - - def testDADIReverse1(self): - arr=[0,3,5,7,9,2] - a=DataArrayInt.New(); - a.setValues(arr,6,1); - self.assertEqual(2,a.back()); - a.reverse(); - for i in xrange(6): - self.assertEqual(arr[5-i],a.getIJ(i,0)); - pass - a.setValues(arr[:-1],5,1); - a.reverse(); - for i in xrange(5): - self.assertEqual(arr[4-i],a.getIJ(i,0)); - pass - # - arr2=[0.,3.,5.,7.,9.,2.] - b=DataArrayDouble.New(); - b.setValues(arr2,6,1); - b.reverse(); - for i in xrange(6): - self.assertAlmostEqual(arr2[5-i],b.getIJ(i,0),14); - pass - b.setValues(arr2[:5],5,1); - self.assertAlmostEqual(9.,b.back(),14) - b.reverse(); - for i in xrange(5): - self.assertAlmostEqual(arr2[4-i],b.getIJ(i,0),14); - pass - pass - - def testGetNodeIdsInUse1(self): - m0=MEDCouplingDataForTest.build2DTargetMesh_1(); - CellIds=[1,2] - m1=m0.buildPartOfMySelf(CellIds,True); - arr,newNbOfNodes=m1.getNodeIdsInUse(); - expected=[-1,0,1,-1,2,3,-1,-1,-1] - self.assertEqual(4,newNbOfNodes); - self.assertEqual(9,arr.getNbOfElems()); - self.assertEqual(expected,arr.getValues()); - arr2=arr.invertArrayO2N2N2O(newNbOfNodes); - self.assertEqual(4,arr2.getNbOfElems()); - expected2=[1,2,4,5] - self.assertEqual(expected2,arr2.getValues()); - pass - - def testBuildDescendingConnec2(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2(); - mesh2.checkCoherency(); - self.assertEqual(1,mesh2.getMeshDimension()); - self.assertEqual(13,mesh2.getNumberOfCells()); - self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); - self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); - self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); - self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); - expected1=[1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10] - self.assertEqual(expected1,desc.getValues()); - expected2=[0,4,7,10,14,18] - self.assertEqual(expected2,descIndx.getValues()); - expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18] - self.assertEqual(expected3,revDescIndx.getValues()); - expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] - self.assertEqual(expected4,revDesc.getValues()); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39] - self.assertEqual(expected5,connIndex.getValues()); - expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5] - self.assertEqual(expected6,conn.getValues()); - pass - - def testIntersect2DMeshesTmp1(self): - m1c=MEDCouplingCMesh.New(); - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4. ] - coordsX.setValues(arrX,4,1); - m1c.setCoordsAt(0,coordsX); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8. ] - coordsY.setValues(arrY,4,1); - m1c.setCoordsAt(1,coordsY); - m1=m1c.buildUnstructured() - m1bis=m1.buildPartOfMySelf([3,4,5],False) - m2=m1.deepCpy() - m2=m2.buildPartOfMySelf([0,1,2],False) - m2.translate([0.5,0.5]) - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1bis,m2,1e-10) - expected1=[0,0,1,1,1,2,2,2] - expected2=[0,-1,0,1,-1,1,2,-1] - self.assertEqual(8,d1.getNumberOfTuples()); - self.assertEqual(8,d2.getNumberOfTuples()); - self.assertEqual(8,m3.getNumberOfCells()); - self.assertEqual(22,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14] - expected4=[0,5,12,17,22,28,33,38,44] - expected5=[-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5] - self.assertEqual(44,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(9,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(44): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testFindNodesOnLine1(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pt=[-0.3,-0.3] - pt2=[0.,0.,0.] - pt3=[-0.3,0.,0.] - vec=[0.,1.] - vec2=[1.,0.,0.] - vec3=[0.,1.,1.] - expected1=[0,3,6] - res=mesh.findNodesOnLine(pt,vec,1e-12); - self.assertEqual(3,len(res)); - self.assertEqual(expected1,res.getValues()); - # - mesh.changeSpaceDimension(3); - mesh.rotate(pt2,vec2,pi/4.); - res=mesh.findNodesOnLine(pt3,vec3,1e-12); - self.assertEqual(3,len(res)); - self.assertEqual(expected1,res.getValues()); - pass - - def testIntersect2DMeshesTmp2(self): - m1c=MEDCouplingCMesh.New(); - coordsX1=DataArrayDouble.New(); - arrX1=[ 0., 1., 1.5, 2. ] - coordsX1.setValues(arrX1,4,1); - m1c.setCoordsAt(0,coordsX1); - coordsY1=DataArrayDouble.New(); - arrY1=[ 0., 1.5, 3.] - coordsY1.setValues(arrY1,3,1); - m1c.setCoordsAt(1,coordsY1); - m1=m1c.buildUnstructured(); - m2c=MEDCouplingCMesh.New(); - coordsX2=DataArrayDouble.New(); - arrX2=[ 0., 1., 2. ] - coordsX2.setValues(arrX2,3,1); - m2c.setCoordsAt(0,coordsX2); - coordsY2=DataArrayDouble.New(); - arrY2=[ 0., 1., 3.] - coordsY2.setValues(arrY2,3,1); - m2c.setCoordsAt(1,coordsY2); - m2=m2c.buildUnstructured(); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10) - # - expected1=[0,0,1,1,2,2,3,4,5] - expected2=[0,2,1,3,1,3,2,3,3] - self.assertEqual(9,d1.getNumberOfTuples()); - self.assertEqual(9,d2.getNumberOfTuples()); - self.assertEqual(9,m3.getNumberOfCells()); - self.assertEqual(22,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[5,16,13,12,15,5,15,4,5,16,5,21,2,13,16,5,16,5,6,21,5,17,14,2,21,5,21,6,7,17,5,4,18,19,5,5,5,19,10,6,5,6,10,20,7] - expected4=[0,5,10,15,20,25,30,35,40,45] - expected5=[0.0,0.0,1.0,0.0,1.5,0.0,2.0,0.0,0.0,1.5,1.0,1.5,1.5,1.5,2.0,1.5,0.0,3.0,1.0,3.0,1.5,3.0,2.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,2.0,1.0,0.0,3.0,1.0,3.0,2.0,3.0,1.5,1.0] - self.assertEqual(45,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(10,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(44): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testBuildPartOfMySelfSafe1(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1() - self.assertRaises(InterpKernelException,mesh.buildPartOfMySelf,[0,-1,4,2],True) - self.assertRaises(InterpKernelException,mesh.buildPartOfMySelf,[0,4,5,4],True) - pass - - def testIntersect2DMeshesTmp3(self): - m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; - m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(8); - m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,25,2); - m1.setCoords(myCoords1); - # - m2Coords=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.] - m2Conn=[0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13] - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(2); - m2.allocateCells(8); - for i in xrange(8): - m2.insertNextCell(NORM_QUAD4,4,m2Conn[4*i:4*(i+1)]) - pass - m2.finishInsertingCells(); - myCoords2=DataArrayDouble.New(); - myCoords2.setValues(m2Coords,15,2); - m2.setCoords(myCoords2); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10) - m3.unPolyze() - # - expected1=[0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7] - expected2=[0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1] - self.assertEqual(16,d1.getNumberOfTuples()); - self.assertEqual(16,d2.getNumberOfTuples()); - self.assertEqual(16,m3.getNumberOfCells()); - self.assertEqual(104,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103] - expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136] - expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0] - self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(208): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testUMeshTessellate2D1(self): - m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; - m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(8); - m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,25,2); - m1.setCoords(myCoords1); - # - m11=m1.deepCpy(); - m11.tessellate2D(1.); - self.assertTrue(m11.getCoords().isEqual(m11.getCoords(),1e-12)); - expected1=[5,0,3,11,1,5,3,4,12,2,1,11,5,5,15,3,0,5,6,16,4,3,15,5,5,5,0,7,19,5,6,5,19,7,8,20,5,0,1,23,7,5,1,2,24,8,7,23] - expected2=[0,5,12,17,24,29,36,41,48] - self.assertEqual(48,m11.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(9,m11.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,m11.getNodalConnectivity().getValues()); - self.assertEqual(expected2,m11.getNodalConnectivityIndex().getValues()); - # - m12=m1.deepCpy(); - m12.tessellate2D(0.5); - self.assertEqual(41,m12.getNumberOfNodes()); - expected3=[5,0,3,25,26,1,5,3,4,27,28,2,1,26,25,5,5,29,30,3,0,5,6,31,32,4,3,30,29,5,5,5,0,7,33,34,5,6,5,34,33,7,8,35,36,5,0,1,37,38,7,5,1,2,39,40,8,7,38,37] - expected4=[0,6,15,21,30,36,45,51,60] - expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.479425538604203,0.8775825618903728,0.8414709848078964,0.54030230586814,0.7191383079063044,1.3163738428355591,1.2622064772118446,0.8104534588022099,-0.877582561890373,0.4794255386042027,-0.5403023058681399,0.8414709848078964,-1.3163738428355596,0.7191383079063038,-0.8104534588022098,1.2622064772118446,-0.4794255386042031,-0.8775825618903728,-0.8414709848078965,-0.5403023058681399,-0.7191383079063045,-1.3163738428355591,-1.2622064772118449,-0.8104534588022098,0.8775825618903729,-0.47942553860420295,0.54030230586814,-0.8414709848078964,1.3163738428355594,-0.7191383079063043,0.8104534588022099,-1.2622064772118446] - for i in xrange(82): - self.assertAlmostEqual(expected5[i],m12.getCoords().getIJ(0,i),12); - pass - self.assertEqual(60,m12.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(9,m12.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m12.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m12.getNodalConnectivityIndex().getValues()); - pass - - def testUMeshTessellate2DCurve1(self): - # A quarter of circle: - mcoords = [0.4,0.0, 0.0,-0.4, 0.283,-0.283] - mconnec = [0,1,2] - - m1 = MEDCouplingUMesh.New() - m1.setMeshDimension(1) - m1.allocateCells(1) - m1.insertNextCell(NORM_SEG3, mconnec) - - myCoords = DataArrayDouble.New(mcoords, 3, 2) - m1.setCoords(myCoords) - - m2 = m1.deepCpy() - m2.tessellate2DCurve(0.1) - # If the following raises, the test will fail automatically: - m2.checkCoherency1(0.0) # eps param not used - - def testIntersect2DMeshesTmp4(self): - m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; - m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(8); - m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,25,2); - m1.setCoords(myCoords1); - # - m2Coords=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.] - m2Conn=[0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13] - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(2); - m2.allocateCells(8); - for i in xrange(8): - m2.insertNextCell(NORM_QUAD4,4,m2Conn[4*i:4*(i+1)]) - pass - m2.finishInsertingCells(); - myCoords2=DataArrayDouble.New(); - myCoords2.setValues(m2Coords,15,2); - m2.setCoords(myCoords2); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m2,m1,1e-10) - m3.unPolyze() - # - expected1=[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] - expected2=[0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1] - self.assertEqual(16,d1.getNumberOfTuples()); - self.assertEqual(16,d2.getNumberOfTuples()); - self.assertEqual(16,m3.getNumberOfCells()); - self.assertEqual(104,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103] - expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136] - expected5=[0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635] - self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(208): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testGetCellIdsCrossingPlane1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - vec=[-0.07,1.,0.07] - origin=[1.524,1.4552,1.74768] - ids1=mesh3D.getCellIdsCrossingPlane(origin,vec,1e-10) - self.assertEqual([1,3,4,7,9,10,13,15,16],ids1.getValues()) - vec2=[0.,0.,1.] - ids2=mesh3D.getCellIdsCrossingPlane(origin,vec2,1e-10) - self.assertEqual([6,7,8,9,10,11],ids2.getValues()) - pass - - def testBuildSlice3D1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - vec1=[-0.07,1.,0.07] - origin1=[1.524,1.4552,1.74768] - slice1,ids=mesh3D.buildSlice3D(origin1,vec1,1e-10); - expected1=[1,3,4,7,9,10,13,15,16] - expected2=[5,42,41,40,43,44,5,42,46,45,41,5,44,43,40,47,48,5,49,42,44,50,5,49,51,46,42,5,50,44,48,52,5,53,49,50,54,5,53,55,51,49,5,54,50,52,56] - expected3=[0,6,11,17,22,27,32,37,42,47] - expected4=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.] - self.assertEqual(2,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(57,slice1.getNumberOfNodes()); - self.assertEqual(9,slice1.getNumberOfCells()); - self.assertEqual(9,ids.getNumberOfTuples()); - self.assertEqual(47,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(10,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,ids.getValues()); - self.assertEqual(expected2,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected3,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(171): - self.assertAlmostEqual(expected4[i],slice1.getCoords().getIJ(0,i),12); - pass - # 2nd slice based on already existing nodes of mesh3D. - vec2=[0.,3.,1.] - origin2=[2.5,1.,3.] - slice1,ids=mesh3D.buildSlice3D(origin2,vec2,1e-10); - expected5=[5,50,10,4,51,5,50,52,7,10,5,51,4,5,53,5,54,50,51,55,56,5,54,57,52,50,5,56,55,51,53,58,5,38,59,56,54,43,5,54,57,46,43,5,38,59,56,58,48] - expected6=[0,5,10,15,21,26,32,38,43,49] - expected7=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,1.,3.,0.,2.,2.,0.,2.,3.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,2.,1.6666666666666667,1.,1.,1.6666666666666667,1.,3.,1.6666666666666667,1.,0.,1.6666666666666667,1.,2.,1.3333333333333335,2.,1.,1.5,1.5,1.,1.3333333333333333,2.,3.,1.3333333333333335,2.,0.,1.3333333333333335,2.,1.,1.25,2.25] - self.assertEqual(2,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(60,slice1.getNumberOfNodes()); - self.assertEqual(9,slice1.getNumberOfCells()); - self.assertEqual(9,ids.getNumberOfTuples()); - self.assertEqual(49,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(10,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,ids.getValues()); - self.assertEqual(expected5,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected6,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(180): - self.assertAlmostEqual(expected7[i],slice1.getCoords().getIJ(0,i),12); - pass - # 3rd slice based on shared face of mesh3D. - vec3=[0.,0.,1.] - origin3=[2.5,1.,2.] - slice1,ids=mesh3D.buildSlice3D(origin3,vec3,1e-10); - expected8=[6,7,8,9,10,11,12,13,14,15,16,17] - expected9=[5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28,5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28] - expected10=[0,5,12,17,22,29,34,39,46,51,56,63,68] - expected11=[0.,0.,1.,1.,1.,1.,1.,1.25,1.,1.,0.,1.,1.,1.5,1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.] - self.assertEqual(2,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(45,slice1.getNumberOfNodes()); - self.assertEqual(12,slice1.getNumberOfCells()); - self.assertEqual(12,ids.getNumberOfTuples()); - self.assertEqual(68,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(13,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected8,ids.getValues()); - self.assertEqual(expected9,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected10,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(135): - self.assertAlmostEqual(expected11[i],slice1.getCoords().getIJ(0,i),12); - pass - pass - - def testBuildSlice3DSurf1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - mesh2D=mesh3D.buildDescendingConnectivity()[0]; - vec1=[-0.07,1.,0.07] - origin1=[1.524,1.4552,1.74768] - slice1,ids=mesh2D.buildSlice3DSurf(origin1,vec1,1e-10); - expected1=[6,8,10,11,13,18,19,21,23,25,26,38,41,43,47,49,52,53,64,67,69,73,75,78,79] - expected2=[1,40,41,1,42,41,1,40,43,1,44,43,1,42,44,1,45,41,1,42,46,1,46,45,1,47,40,1,47,48,1,44,48,1,49,42,1,44,50,1,49,50,1,49,51,1,51,46,1,48,52,1,50,52,1,53,49,1,50,54,1,53,54,1,53,55,1,55,51,1,52,56,1,54,56] - expected3=[0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75]; - expected4=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.] - self.assertEqual(1,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(57,slice1.getNumberOfNodes()); - self.assertEqual(25,slice1.getNumberOfCells()); - self.assertEqual(25,ids.getNumberOfTuples()); - self.assertEqual(75,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(26,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,ids.getValues()); - self.assertEqual(expected2,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected3,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(171): - self.assertAlmostEqual(expected4[i],slice1.getCoords().getIJ(0,i),12); - pass - # - vec2=[0.,0.,1.] - origin2=[2.5,1.,2.] - slice1,ids=mesh2D.buildSlice3DSurf(origin2,vec2,1e-10); - expected5=[32,32,32,32,33,34,35,36,37,38,39,40,41,42,43,43,43,43,43,43,44,44,44,44,45,46,47,47,47,47,48,49,50,51,52,53,53,53,53,53,53,54,54,54,54,55,56,57,59,60,61,62,63,64,65,66,67,68,71,72,74,75,76,77,78,81,82,83] - expected6=[1,15,18,1,18,16,1,16,26,1,26,15,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,16,21,1,21,28,1,28,22,1,22,19,1,19,17,1,17,16,1,16,18,1,18,20,1,20,21,1,21,16,1,20,21,1,18,20,1,28,21,1,21,24,1,24,25,1,25,28,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,26,16,1,16,17,1,17,19,1,19,22,1,22,23,1,23,26,1,22,28,1,28,29,1,29,27,1,27,22,1,27,22,1,29,27,1,28,29,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,20,21,1,18,20,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,27,22,1,29,27,1,28,29] - expected7=[0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204]; - expected8=[0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.] - self.assertEqual(1,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(45,slice1.getNumberOfNodes()); - self.assertEqual(68,slice1.getNumberOfCells()); - self.assertEqual(68,ids.getNumberOfTuples()); - self.assertEqual(204,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(69,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected5,ids.getValues()); - self.assertEqual(expected6,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected7,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(135): - self.assertAlmostEqual(expected8[i],slice1.getCoords().getIJ(0,i),12); - pass - pass - - def testDataArrayDoubleAdvSetting1(self): - data1=[1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.] - data2=[8.,38.,9.,39.,0.,30.,11.,41.,12.,42.] - compsCpp=["comp1","comp2"] - da=DataArrayDouble.New(); - da.setInfoAndChangeNbOfCompo(compsCpp); - da.setName("da"); - da.alloc(7,2); - compsCpp=compsCpp[:-1] - self.assertRaises(InterpKernelException,da.setInfoAndChangeNbOfCompo,compsCpp); - da.setValues(data1,7,2) - # - p=[(0,3),(3,5),(5,7)] - tmp=da.selectByTupleRanges(p); - self.assertTrue(tmp.isEqual(da,1e-14)); - p=[(0,2),(3,4),(5,7)] - tmp=da.selectByTupleRanges(p); - expected1=[1.,11.,2.,12.,4.,14.,6.,16.,7.,17.] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertAlmostEqual(expected1[i],tmp.getIJ(0,i),14); - pass - p=[(0,2),(0,2),(5,6)] - tmp=da.selectByTupleRanges(p); - expected2=[1.,11.,2.,12.,1.,11.,2.,12.,6.,16.] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertAlmostEqual(expected2[i],tmp.getIJ(0,i),14); - pass - p=[(0,2),(-1,2),(5,6)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - p=[(0,2),(0,2),(5,8)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - # - da2=DataArrayDouble.New(); - da2.setValues(data2,5,2); - # - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues2(1,da2,2,4,1); - expected3=[1.,11.,0.,30.,11.,41.,4.,14.,5.,15.,6.,16.,7.,17.] - for i in xrange(14): - self.assertAlmostEqual(expected3[i],dac.getIJ(0,i),14); - pass - # - dac=da.deepCpy(); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,0,5,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,0,da2,4,6,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,5,0,1); - dac.setContigPartOfSelectedValues2(3,da2,1,5,1); - expected4=[1.,11.,2.,12.,3.,13.,9.,39.,0.,30.,11.,41.,12.,42.] - for i in xrange(14): - self.assertAlmostEqual(expected4[i],dac.getIJ(0,i),14); - pass - # - ids=DataArrayInt.New(); - ids.alloc(3,1); - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,0); ids.setIJ(2,0,4); - dac.setContigPartOfSelectedValues(2,da2,ids); - expected5=[1.,11.,2.,12.,0.,30.,8.,38.,12.,42.,6.,16.,7.,17.] - for i in xrange(14): - self.assertAlmostEqual(expected5[i],dac.getIJ(0,i),14); - pass - # - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,5); ids.setIJ(2,0,4); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,-1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,5,da2,ids); - # - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues(4,da2,ids); - expected6=[1.,11.,2.,12.,3.,13.,4.,14.,0.,30.,0.,30.,9.,39.] - for i in xrange(14): - self.assertAlmostEqual(expected6[i],dac.getIJ(0,i),14); - pass - pass - - def testDataArrayIntAdvSetting1(self): - data1=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - data2=[8,38,9,39,0,30,11,41,12,42] - compsCpp=["comp1","comp2"] - da=DataArrayInt.New(); - da.setInfoAndChangeNbOfCompo(compsCpp); - da.setName("da"); - da.alloc(7,2); - compsCpp=compsCpp[:-1] - self.assertRaises(InterpKernelException,da.setInfoAndChangeNbOfCompo,compsCpp); - da.setValues(data1,7,2) - # - p=[(0,3),(3,5),(5,7)] - tmp=da.selectByTupleRanges(p); - self.assertTrue(tmp.isEqual(da)); - p=[(0,2),(3,4),(5,7)] - tmp=da.selectByTupleRanges(p); - expected1=[1,11,2,12,4,14,6,16,7,17] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertEqual(expected1[i],tmp.getIJ(0,i)); - pass - p=[(0,2),(0,2),(5,6)] - tmp=da.selectByTupleRanges(p); - expected2=[1,11,2,12,1,11,2,12,6,16] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertEqual(expected2[i],tmp.getIJ(0,i)); - pass - p=[(0,2),(-1,2),(5,6)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - p=[(0,2),(0,2),(5,8)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - # - da2=DataArrayInt.New(); - da2.setValues(data2,5,2); - # - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues2(1,da2,2,4,1); - expected3=[1,11,0,30,11,41,4,14,5,15,6,16,7,17] - for i in xrange(14): - self.assertEqual(expected3[i],dac.getIJ(0,i)); - pass - # - dac=da.deepCpy(); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,0,5,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,0,da2,4,6,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,5,0,1); - dac.setContigPartOfSelectedValues2(3,da2,1,5,1); - expected4=[1,11,2,12,3,13,9,39,0,30,11,41,12,42] - for i in xrange(14): - self.assertEqual(expected4[i],dac.getIJ(0,i)); - pass - # - ids=DataArrayInt.New(); - ids.alloc(3,1); - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,0); ids.setIJ(2,0,4); - dac.setContigPartOfSelectedValues(2,da2,ids); - expected5=[1,11,2,12,0,30,8,38,12,42,6,16,7,17] - for i in xrange(14): - self.assertEqual(expected5[i],dac.getIJ(0,i)); - pass - # - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,5); ids.setIJ(2,0,4); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,-1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,5,da2,ids); - # - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues(4,da2,ids); - expected6=[1,11,2,12,3,13,4,14,0,30,0,30,9,39] - for i in xrange(14): - self.assertEqual(expected6[i],dac.getIJ(0,i)); - pass - pass - - def testBuildDescendingConnec2Of3DMesh1(self): - mesh=MEDCouplingDataForTest.build3DSourceMesh_1(); - # - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2(); - mesh2.checkCoherency(); - self.assertEqual(2,mesh2.getMeshDimension()); - self.assertEqual(30,mesh2.getNumberOfCells()); - self.assertEqual(31,revDescIndx.getNbOfElems()); self.assertEqual(31,revDescIndx.getNumberOfTuples()); - self.assertEqual(13,descIndx.getNbOfElems()); self.assertEqual(13,descIndx.getNumberOfTuples()); - self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); - self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); - expected1=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,-10,15,-5,-13,16,17,-14,18,-4,19,-2,20,21,22,23,24,25,-11,26,-1,-12,-25,-22,27,28,-7,-20,-24,29,-16,-18,30,-8,-28] - self.assertEqual(expected1,desc.getValues()); - expected2=[0,4,8,12,16,20,24,28,32,36,40,44,48] - self.assertEqual(expected2,descIndx.getValues()); - expected3=[0,2,4,5,7,9,10,12,14,15,17,19,21,23,25,26,28,29,31,32,34,35,37,38,40,42,43,44,46,47,48] - self.assertEqual(expected3,revDescIndx.getValues()); - expected4=[0,8,0,6,0,0,5,1,4,1,1,9,1,11,2,2,3,2,7,2,8,3,4,3,5,3,4,10,4,5,11,5,6,10,6,6,9,7,7,10,7,8,8,9,9,11,10,11] - self.assertEqual(expected4,revDesc.getValues()); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - expected5=[0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120] - self.assertEqual(expected5,connIndex.getValues()); - expected6=[3,8,1,7,3,8,3,1,3,1,3,7,3,7,3,8,3,6,0,8,3,6,2,0,3,0,2,8,3,8,2,6,3,7,4,5,3,7,8,4,3,4,8,5,3,5,8,7,3,6,8,4,3,6,7,8,3,4,7,6,3,8,4,0,3,0,4,6,3,6,3,8,3,7,3,6,3,8,0,1,3,1,0,3,3,3,0,8,3,4,1,5,3,4,8,1,3,1,8,5,3,1,7,5,3,0,2,3,3,3,2,8,3,1,4,0,3,3,2,6] - self.assertEqual(expected6,conn.getValues()); - pass - - def testAre2DCellsNotCorrectlyOriented1(self): - m1Coords=[1.,1.,-1.,-1.,-1.,-1.,1.,-1.] - m1Conn=[0,3,1,2] - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(1); - m1.insertNextCell(NORM_QUAD4,4,m1Conn[0:4]) - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,4,2); - m1.setCoords(myCoords1); - # - vec1=[0.,0.,1.] - for i in xrange(18): - vec2=[3.*cos(pi/9.*i),3.*sin(pi/9.*i)]; - m1Cpy=m1.deepCpy(); - m1Cpy.translate(vec2); - self.assertRaises(InterpKernelException,m1Cpy.are2DCellsNotCorrectlyOriented,vec1,False); - m1Cpy.changeSpaceDimension(3); - res=m1Cpy.are2DCellsNotCorrectlyOriented(vec1,False) - self.assertEqual([0],res.getValues()); - pass - pass - - def testDataArrayAbs1(self): - d1=DataArrayDouble.New(); - val1=[2.,-3.,-5.,6.,-7.,-8.,9.,10.,-11.,-12.,-13.,-15.] - expected1=[2.,3.,5.,6.,7.,8.,9.,10.,11.,12.,13.,15.] - d1.setValues(val1,6,2); - d2=d1.convertToIntArr(); - # - d1.abs(); - for i in xrange(12): - self.assertAlmostEqual(expected1[i],d1.getIJ(0,i),14); - pass - # - expected2=[2,3,5,6,7,8,9,10,11,12,13,15] - d2.abs(); - for i in xrange(12): - self.assertEqual(expected2[i],d2.getIJ(0,i)); - pass - # - pass - - # test on 1D - def testGetValueOn3(self): - v=[0.,1.,1.5,2.] - v2=[0.7,1.25,0.,2.,1.5] - disp=[5.,50.,500.,6.,60.,600.,7.,70.,700.,8.,80.,800.] - m=MEDCouplingUMesh.New("myMesh",1) - nbNodes=len(v) - nbCells=nbNodes-1 - m.allocateCells(nbCells) - coords=DataArrayDouble.New() ; coords.setValues(v,nbNodes,1) - m.setCoords(coords) - m.insertNextCell(NORM_SEG2,2,[0,1]) - m.insertNextCell(NORM_SEG2,2,[2,1]) - m.insertNextCell(NORM_SEG2,2,[2,3]) - m.finishInsertingCells() - f=MEDCouplingFieldDouble.New(ON_NODES) - f.setMesh(m) - array=DataArrayDouble.New(); array.setValues(disp,m.getNumberOfNodes(),3) - f.setArray(array) - arr1=f.getValueOnMulti(v2) - self.assertEqual(5,arr1.getNumberOfTuples()); - self.assertEqual(3,arr1.getNumberOfComponents()); - expected1=[5.7,57.,570.,6.5,65.,650.,5.,50.,500.,8.,80.,800.,7.,70.,700.] - for i in xrange(15): - self.assertAlmostEqual(expected1[i],arr1.getIJ(0,i),14); - pass - pass - - def testGetNodeIdsOfCell2(self): - m1c=MEDCouplingCMesh.New(); - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4., 4.5 ] - coordsX.setValues(arrX,5,1); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8.] - coordsY.setValues(arrY,4,1); - coordsZ=DataArrayDouble.New(); - arrZ=[ -2., 2., 4.] - coordsZ.setValues(arrZ,3,1); - # test in 1D - m1c.setCoordsAt(0,coordsX); - expected1=[[0,1],[1,2],[2,3],[3,4]] - self.assertEqual(4,m1c.getNumberOfCells()) - for i in xrange(m1c.getNumberOfCells()): - self.assertEqual(expected1[i],m1c.getNodeIdsOfCell(i)) - pass - # test in 2D - m1c.setCoordsAt(1,coordsY); - self.assertEqual(12,m1c.getNumberOfCells()) - self.assertEqual(20,m1c.getNumberOfNodes()) - expected2=[[0,1,6,5],[1,2,7,6],[2,3,8,7],[3,4,9,8],[5,6,11,10],[6,7,12,11],[7,8,13,12],[8,9,14,13],[10,11,16,15],[11,12,17,16],[12,13,18,17],[13,14,19,18]] - for i in xrange(m1c.getNumberOfCells()): - self.assertEqual(expected2[i],m1c.getNodeIdsOfCell(i)) - pass - # test in 3D - m1c.setCoordsAt(2,coordsZ); - self.assertEqual(24,m1c.getNumberOfCells()) - self.assertEqual(60,m1c.getNumberOfNodes()) - expected3=[[0,1,6,5,20,21,26,25],[1,2,7,6,21,22,27,26],[2,3,8,7,22,23,28,27],[3,4,9,8,23,24,29,28],[5,6,11,10,25,26,31,30],[6,7,12,11,26,27,32,31],[7,8,13,12,27,28,33,32],[8,9,14,13,28,29,34,33],[10,11,16,15,30,31,36,35],[11,12,17,16,31,32,37,36],[12,13,18,17,32,33,38,37],[13,14,19,18,33,34,39,38],[20,21,26,25,40,41,46,45],[21,22,27,26,41,42,47,46],[22,23,28,27,42,43,48,47],[23,24,29,28,43,44,49,48],[25,26,31,30,45,46,51,50],[26,27,32,31,46,47,52,51],[27,28,33,32,47,48,53,52],[28,29,34,33,48,49,54,53],[30,31,36,35,50,51,56,55],[31,32,37,36,51,52,57,56],[32,33,38,37,52,53,58,57],[33,34,39,38,53,54,59,58]] - self.assertEqual(24,m1c.getNumberOfCells()) - for i in xrange(m1c.getNumberOfCells()): - self.assertEqual(expected3[i],m1c.getNodeIdsOfCell(i)) - pass - pass - - def testSwigDADOp4(self): - da=DataArrayDouble.New(range(6,30),12,2) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),float(i+6),13) - pass - # operator transpose - da.transpose() - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),float(i+6),13) - pass - da.transpose() - # operator __neg__ - da2=DataArrayDouble.New(12,1) - da2.iota(0.) - dabis=-da - for i in xrange(24): - self.assertAlmostEqual(dabis.getIJ(0,i),-float(i+6),13) - pass - # operator+= - da+=da2 - expected1=[6.,7.,9.,10.,12.,13.,15.,16.,18.,19.,21.,22.,24.,25.,27.,28.,30.,31.,33.,34.,36.,37.,39.,40.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da+=[100.,101.] - expected2=[106.,108.,108.,110.,110.,112.,112.,114.,114.,116.,116.,118.,118.,120.,120.,122.,122.,124.,124.,126.,126.,128.,128.,130.] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]+=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for elt in da: - li=elt[:] - self.assertAlmostEqual(li[0],100.,13) ; self.assertAlmostEqual(li[1],101.,13) - pass - # operator-= - da=DataArrayDouble.New(range(6,30),12,2) - da2=DataArrayDouble.New(range(12),12,1) - dabis=-da - da-=da2 - expected1=[6.,7.,7.,8.,8.,9.,9.,10.,10.,11.,11.,12.,12.,13.,13.,14.,14.,15.,15.,16.,16.,17.,17.,18.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da-=[100.,101.] - expected2=[-94.,-94.,-92.,-92.,-90.,-90.,-88.,-88.,-86.,-86.,-84.,-84.,-82.,-82.,-80.,-80.,-78.,-78.,-76.,-76.,-74.,-74.,-72.,-72.] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]-=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-88.,-87.,-84.,-83.,-80.,-79.,-76.,-75.,-72.,-71.,-68.,-67.,-64.,-63.,-60.,-59.,-56.,-55.,-52.,-51.,-48.,-47.,-44.,-43.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) - pass - # operator*= - da=DataArrayDouble.New(range(6,30),12,2) - da2=DataArrayDouble.New(range(12),12,1) - dabis=-da - da*=da2 - expected1=[0.,0.,8.,9.,20.,22.,36.,39.,56.,60.,80.,85.,108.,114.,140.,147.,176.,184.,216.,225.,260.,270.,308.,319.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da*=[100.,101.] - expected2=[600.,707.,800.,909.,1000.,1111.,1200.,1313.,1400.,1515.,1600.,1717.,1800.,1919.,2000.,2121.,2200.,2323.,2400.,2525.,2600.,2727.,2800.,2929.] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]*=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-3600.,-4949.,-6400.,-8181.,-10000.,-12221.,-14400.,-17069.,-19600.,-22725.,-25600.,-29189.,-32400.,-36461.,-40000.,-44541.,-48400.,-53429.,-57600.,-63125.,-67600.,-73629.,-78400.,-84941.0] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) - pass - # operator/= - da=DataArrayDouble.New(range(6,30),12,2) - da2=DataArrayDouble.New(range(1,13),12,1) - dabis=-da - da/=da2 - expected1=[6.0,7.0,4.0,4.5,3.3333333333333335,3.6666666666666665,3.0,3.25,2.8,3.0,2.6666666666666665,2.8333333333333335,2.5714285714285716,2.7142857142857144,2.5,2.625,2.4444444444444446,2.5555555555555554,2.4,2.5,2.3636363636363638,2.4545454545454546,2.3333333333333335,2.4166666666666665] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da/=[100.,101.] - expected2=[0.06,0.06930693069306931,0.08,0.0891089108910891,0.1,0.10891089108910891,0.12,0.12871287128712872,0.14,0.1485148514851485,0.16,0.16831683168316833,0.18,0.18811881188118812,0.2,0.2079207920792079,0.22,0.22772277227722773,0.24,0.24752475247524752,0.26,0.26732673267326734,0.28,0.2871287128712871] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]/=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.0099009900990099] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) - pass - pass - - def testSwigDAIOp4(self): - da=DataArrayInt.New(range(6,30),12,2) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),i+6) - pass - # operator transpose - da.transpose() - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),i+6) - pass - da.transpose() - # operator __neg__ - da2=DataArrayInt.New(12,1) - da2.iota(0) - dabis=-da - for i in xrange(24): - self.assertEqual(dabis.getIJ(0,i),-(i+6)) - pass - # operator+= - da+=da2 - expected1=[6,7,9,10,12,13,15,16,18,19,21,22,24,25,27,28,30,31,33,34,36,37,39,40] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da+=[100,101] - expected2=[106,108,108,110,110,112,112,114,114,116,116,118,118,120,120,122,122,124,124,126,126,128,128,130] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - for pos,elt in enumerate(dabis): - da[pos]+=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for elt in da: - li=elt[:] - self.assertEqual(li[0],100) ; self.assertEqual(li[1],101) - pass - # operator-= - da=DataArrayInt.New(range(6,30),12,2) - da2=DataArrayInt.New(range(12),12,1) - dabis=-da - da-=da2 - expected1=[6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da-=[100,101] - expected2=[-94,-94,-92,-92,-90,-90,-88,-88,-86,-86,-84,-84,-82,-82,-80,-80,-78,-78,-76,-76,-74,-74,-72,-72] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - for pos,elt in enumerate(dabis): - da[pos]-=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-88,-87,-84,-83,-80,-79,-76,-75,-72,-71,-68,-67,-64,-63,-60,-59,-56,-55,-52,-51,-48,-47,-44,-43] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected3[i]) - pass - # operator*= - da=DataArrayInt.New(range(6,30),12,2) - da2=DataArrayInt.New(range(12),12,1) - dabis=-da - da*=da2 - expected1=[0,0,8,9,20,22,36,39,56,60,80,85,108,114,140,147,176,184,216,225,260,270,308,319] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da*=[100,101] - expected2=[600,707,800,909,1000,1111,1200,1313,1400,1515,1600,1717,1800,1919,2000,2121,2200,2323,2400,2525,2600,2727,2800,2929] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - for pos,elt in enumerate(dabis): - da[pos]*=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-3600,-4949,-6400,-8181,-10000,-12221,-14400,-17069,-19600,-22725,-25600,-29189,-32400,-36461,-40000,-44541,-48400,-53429,-57600,-63125,-67600,-73629,-78400,-84941.0] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected3[i]) - pass - # operator/= - da=DataArrayInt.New(range(6,30),12,2) - da2=DataArrayInt.New(range(1,13),12,1) - dabis=-da - da/=da2 - expected1=[6,7,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da/=DataArrayInt.New([2,3],1,2) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected2=[3,2,4,3,5,3,6,4,7,5,8,5,9,6,10,7,11,7,12,8,13,9,14,9] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - pass - - def testSwigDADOp5(self): - da=DataArrayDouble.New([5,6,7,8,9,6,7,-2,3,9,8,10]) - da.rearrange(3) - da2=DataArrayDouble.New([5.,8.,10.,12]) - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - da3=da+da2 - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - expected1=[10.,11.,12.,16.,17.,14.,17.,8.,13.,21.,20.,22.] - for i in xrange(12): - self.assertAlmostEqual(da3.getIJ(0,i),expected1[i],13) - pass - da3=da2+da - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da3.getIJ(0,i),expected1[i],13) - pass - # Test new API of classmethod DataArrayDouble.New - vals=[5,6,7,8,9,6,7,-2,3,9,8,10] - da=DataArrayDouble.New(vals) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,12) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,1,12) - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,6,2) - self.assertEqual(6,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,4,3) - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,11); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,13); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,5,2); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2); - pass - - def testSwigDADOp6(self): - da=DataArrayInt.New([5,6,7,8,9,6,7,-2,3,9,8,10]) - da.rearrange(3) - da2=DataArrayInt.New([5,8,10,12]) - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - da3=da+da2 - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - expected1=[10,11,12,16,17,14,17,8,13,21,20,22] - for i in xrange(12): - self.assertEqual(da3.getIJ(0,i),expected1[i]) - pass - da3=da2+da - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da3.getIJ(0,i),expected1[i]) - pass - da3=da+DataArrayInt.New(da2.getValues()) - # Test new API of classmethod DataArrayInt.New - vals=[5,6,7,8,9,6,7,-2,3,9,8,10] - da=DataArrayDouble.New(vals) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,12) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,1,12) - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,6,2) - self.assertEqual(6,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,4,3) - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,11); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,13); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,5,2); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2); - pass - - def testSwigDADOp9(self): - l1=[(1.,2.,3),(4.,5.,6.),(7.,8.,9.),[10.,11.,12.]] - da1=DataArrayDouble(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4); - da3=DataArrayDouble(l1,4) - self.assertTrue(da3.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5); - l1=[(1.,2.,3),(4.,(5.),((6.))),(7.,8.,9.),[10.,11.,12.]] - da1=DataArrayDouble(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4); - da3=DataArrayDouble(l1,4) - self.assertTrue(da3.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5); - # - l1=[(1,2,3),(4,5,6),(7,8,9),[10,11,12]] - da1=DataArrayInt(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4); - da3=DataArrayInt(l1,4) - self.assertTrue(da3.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5); - l1=[(1,[2],3),(4,[(5)],6),((([7])),8,9),[10,11,12]] - da1=DataArrayInt(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4); - da3=DataArrayInt(l1,4) - self.assertTrue(da3.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5); - pass - - def testRenumberNodesInConn1(self): - mesh2DCoords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] - mesh2DConn=[1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4] - mesh2D=MEDCouplingUMesh.New("mesh",2); - mesh2D.allocateCells(5); - mesh2D.insertNextCell(NORM_TRI3,3,mesh2DConn[0:3]) - mesh2D.insertNextCell(NORM_TRI3,3,mesh2DConn[3:6]) - mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[6:10]) - mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[10:14]) - mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[14:18]) - mesh2D.finishInsertingCells(); - myCoords=DataArrayDouble.New(mesh2DCoords,9,3); - mesh2D.setCoords(myCoords); - mesh2D.checkCoherency(); - # - mesh3DCoords=[-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1. ] - mesh3DConn=[0,1,2,3,4,5,6,7] - mesh3D=MEDCouplingUMesh.New("mesh",3); - mesh3D.allocateCells(1); - mesh3D.insertNextCell(NORM_HEXA8,8,mesh3DConn[:]) - mesh3D.finishInsertingCells(); - myCoords3D=DataArrayDouble.New(mesh3DCoords,8,3); - mesh3D.setCoords(myCoords3D); - mesh3D.checkCoherency(); - # - mesh3D_2=mesh3D.deepCpy(); - mesh2D_2=mesh2D.deepCpy(); - mesh3D_4=mesh3D.deepCpy(); - mesh2D_4=mesh2D.deepCpy(); - oldNbOf3DNodes=mesh3D.getNumberOfNodes(); - renumNodes=DataArrayInt.New(); - renumNodes.alloc(mesh2D.getNumberOfNodes(),1); - renumNodes.iota(oldNbOf3DNodes); - coo=DataArrayDouble.Aggregate(mesh3D.getCoords(),mesh2D.getCoords()); - mesh3D.setCoords(coo); - mesh2D.setCoords(coo); - mesh2DCpy=mesh2D.deepCpy() - mesh2D_3=mesh2D.deepCpy(); - mesh2D_3.shiftNodeNumbersInConn(oldNbOf3DNodes); - mesh2D.renumberNodesInConn(renumNodes); - mesh2DCpy.renumberNodesInConn(renumNodes.getValues()); - self.assertTrue(mesh2D.isEqual(mesh2DCpy,1e-12)) - self.assertTrue(mesh2D.isEqual(mesh2D_3,1e-12)) - # - da1,da2=mesh3D.checkGeoEquivalWith(mesh3D_2,10,1e-12); - self.assertTrue(da1==None); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[8,11,12,9,4,5,6,7] - for i in xrange(8): - self.assertEqual(expected1[i],da2.getIJ(i,0)); - pass - # - da1,da2=mesh2D.checkGeoEquivalWith(mesh2D_2,10,1e-12); - self.assertTrue(da1==None); - self.assertEqual(9,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(9): - self.assertEqual(8+i,da2.getIJ(i,0)); - pass - # - mesh2D_5=mesh2D_4.deepCpy(); - mesh2D_5.translate([1.,0.,0.]); - meshes=[mesh3D_4,mesh2D_4,mesh2D_5]; - MEDCouplingUMesh.PutUMeshesOnSameAggregatedCoords(meshes); - self.assertTrue(mesh3D_4.getCoords().getHiddenCppPointer()==mesh2D_4.getCoords().getHiddenCppPointer()); - self.assertTrue(mesh2D_4.getCoords().getHiddenCppPointer()==mesh2D_5.getCoords().getHiddenCppPointer()); - mesh3D_4.checkCoherency(); mesh2D_4.checkCoherency(); mesh2D_5.checkCoherency(); - self.assertEqual(26,mesh3D_4.getNumberOfNodes()); - self.assertEqual(3,mesh3D_4.getSpaceDimension()); - self.assertEqual(9,mesh3D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_5.getNodalConnectivity().getNumberOfTuples()); - expected2=[18,0,1,2,3,4,5,6,7] - expected3=[3,9,12,10, 3,12,13,10, 4,8,11,12,9, 4,14,15,12,11, 4,15,16,13,12] - expected4=[3,18,21,19, 3,21,22,19, 4,17,20,21,18, 4,23,24,21,20, 4,24,25,22,21] - expected5=[-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1., -0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0., 0.7, -0.3, 0.0, 1.2, -0.3, 0.0, 1.7, -0.3, 0.0, 0.7, 0.2, 0.0, 1.2, 0.2, 0.0, 1.7, 0.2, 0.0, 0.7, 0.7, 0.0, 1.2, 0.7, 0.0, 1.7, 0.7, 0.0] - self.assertEqual(expected2,mesh3D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected3,mesh2D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected4,mesh2D_5.getNodalConnectivity().getValues()); - for i in xrange(78): - self.assertAlmostEqual(expected5[i],mesh3D_4.getCoords().getIJ(0,i),12); - pass - # - MEDCouplingUMesh.MergeNodesOnUMeshesSharingSameCoords(meshes,1e-12); - mesh3D_4.checkCoherency(); mesh2D_4.checkCoherency(); mesh2D_5.checkCoherency(); - self.assertTrue(mesh3D_4.getCoords().getHiddenCppPointer()==mesh2D_4.getCoords().getHiddenCppPointer()); - self.assertTrue(mesh2D_4.getCoords().getHiddenCppPointer()==mesh2D_5.getCoords().getHiddenCppPointer()); - self.assertEqual(19,mesh3D_4.getNumberOfNodes()); - self.assertEqual(3,mesh3D_4.getSpaceDimension()); - self.assertEqual(9,mesh3D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_5.getNodalConnectivity().getNumberOfTuples()); - expected6=[18,0,1,2,3,4,5,6,7] - expected7=[3,3,2,8, 3,2,9,8, 4,0,1,2,3, 4,10,11,2,1, 4,11,12,9,2] - expected8=[3,13,15,14, 3,15,16,14, 4,8,9,15,13, 4,12,17,15,9, 4,17,18,16,15] - expected9=[-0.3, -0.3, 0., -0.3, 0.2, 0., 0.2, 0.2, 0., 0.2, -0.3, 0., -0.3, -0.3, 1., -0.3, 0.2, 1., - 0.2, 0.2, 1., 0.2, -0.3, 1., 0.7, -0.3, 0., 0.7, 0.2, 0., -0.3, 0.7, 0., 0.2, 0.7, 0., - 0.7, 0.7, 0., 1.2, -0.3, 0., 1.7, -0.3, 0., 1.2, 0.2, 0., 1.7, 0.2, 0., 1.2, 0.7, 0., 1.7, 0.7, 0.] - self.assertEqual(expected6,mesh3D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected7,mesh2D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected8,mesh2D_5.getNodalConnectivity().getValues()); - for i in xrange(57): - self.assertAlmostEqual(expected9[i],mesh3D_4.getCoords().getIJ(0,i),12); - pass - # - pass - - def testComputeNeighborsOfCells1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - d1,d2=m.computeNeighborsOfCells(); - self.assertEqual(6,d2.getNumberOfTuples()); - self.assertEqual(10,d1.getNumberOfTuples()); - expected1=[0,2,4,6,8,10] - expected2=[3,1,0,2,4,1,4,0,2,3] - self.assertEqual(expected1,d2.getValues()); - self.assertEqual(expected2,d1.getValues()); - pass - - def testCheckButterflyCellsBug1(self): - mesh2DCoords=[323.85,120.983748908684,317.5,131.982271536747,336.55,120.983748908686,330.2,131.982271536751,323.85,142.98079416481] - mesh2DConn=[4,1,0,2,3] - mesh2D=MEDCouplingUMesh.New("mesh",2); - mesh2D.allocateCells(1); - mesh2D.insertNextCell(NORM_POLYGON,5,mesh2DConn[0:5]) - mesh2D.finishInsertingCells(); - myCoords=DataArrayDouble.New(mesh2DCoords,5,2); - mesh2D.setCoords(myCoords); - mesh2D.checkCoherency(); - # - v=mesh2D.checkButterflyCells(); - self.assertTrue(v.empty()); - pass - - def testDataArrayIntRange1(self): - d=DataArrayInt.Range(2,17,7); - expected1=[2,9,16] - self.assertEqual(3,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected1,d.getValues()); - # - d=DataArrayInt.Range(2,23,7); - self.assertEqual(3,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected1,d.getValues()); - # - d=DataArrayInt.Range(2,24,7); - expected2=[2,9,16,23] - self.assertEqual(4,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected2,d.getValues()); - # - d=DataArrayInt.Range(24,2,-7); - expected3=[24,17,10,3] - self.assertEqual(4,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected3,d.getValues()); - # - d=DataArrayInt.Range(23,2,-7); - expected4=[23,16,9] - self.assertEqual(3,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected4,d.getValues()); - # - d=DataArrayInt.Range(23,22,-7); - self.assertEqual(1,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(23,d.getIJ(0,0)); - # - d=DataArrayInt.Range(22,23,7); - self.assertEqual(1,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(22,d.getIJ(0,0)); - # - d=DataArrayInt.Range(22,22,7); - self.assertEqual(0,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - # - d=DataArrayInt.Range(22,22,-7); - self.assertEqual(0,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - # - self.assertRaises(InterpKernelException,DataArrayInt.Range,22,23,-7); - self.assertRaises(InterpKernelException,DataArrayInt.Range,23,22,7); - self.assertRaises(InterpKernelException,DataArrayInt.Range,23,22,0); - self.assertRaises(InterpKernelException,DataArrayInt.Range,22,23,0); - pass - - def testSwigUMeshGetItem1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - subMesh=m.buildPartOfMySelf([1,3],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - m1=m[[1,3]] - self.assertTrue(isinstance(m1,MEDCouplingUMesh)) - m2=m[(1,3)] - self.assertTrue(isinstance(m2,MEDCouplingUMesh)) - m3=m[1::2] - self.assertTrue(isinstance(m3,MEDCouplingUMesh)) - m4=m[DataArrayInt.New([1,3])] - m5_1=m[1] - self.assertTrue(isinstance(m5_1,MEDCouplingUMesh)) - m5_2=m[3] - self.assertTrue(isinstance(m5_2,MEDCouplingUMesh)) - m5=MEDCouplingUMesh.MergeUMeshesOnSameCoords([m5_1,m5_2]); - m5.setName(subMesh.getName()) - self.assertTrue(isinstance(m4,MEDCouplingUMesh)) - self.assertTrue(subMesh.isEqual(m1,1e-12)) - self.assertTrue(subMesh.isEqual(m2,1e-12)) - self.assertTrue(subMesh.isEqual(m3,1e-12)) - self.assertTrue(subMesh.isEqual(m4,1e-12)) - self.assertTrue(subMesh.isEqual(m5,1e-12)) - self.assertRaises(InterpKernelException,m.buildPartOfMySelf,[1,5],True); - pass - - def testSwigGetItem3(self): - da=DataArrayInt.New([4,5,6]) - self.assertEqual(5,da[1]) - self.assertEqual(6,da[-1]) - self.assertRaises(InterpKernelException,da.__getitem__,3) - da=DataArrayInt.New([4,5,6,7,8,9],2,3) - self.assertEqual(9,da[1,2]) - da=DataArrayDouble.New([4.1,5.2,6.3]) - self.assertAlmostEqual(5.2,da[1],12) - self.assertAlmostEqual(6.3,da[-1],12) - self.assertRaises(InterpKernelException,da.__getitem__,3) - da=DataArrayDouble.New([4.12,5.12,6.12,7.12,8.12,9.12],2,3) - self.assertAlmostEqual(9.12,da[1,2],12) - pass - - def testSwigDADISub1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - bary=mesh3D.getBarycenterAndOwner() - bary=bary[:,:2] - pts=bary.getDifferentValues(1e-12) - expected=[[0,6,12],[1,7,13],[2,8,14],[3,9,15],[4,10,16],[5,11,17]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]-=pt - norm=bary2.magnitude() - self.assertEqual(expected[pos],norm.getIdsInRange(-1.,1e-5).getValues()) - pass - expected2=[[3.,54.],[-141.,180.],[21.,54.],[39.,72.],[-15.,90.],[21.,90.]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]+=pt - self.assertAlmostEqual(expected2[pos][0],bary2.accumulate()[0],12); - self.assertAlmostEqual(expected2[pos][1],bary2.accumulate()[1],12); - pass - expected3=[[-3.,22.5],[45.,337.5],[-9., 22.5],[-15.,67.5],[3.,112.5],[-9.,112.5]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]*=pt - self.assertAlmostEqual(expected3[pos][0],bary2.accumulate()[0],12); - self.assertAlmostEqual(expected3[pos][1],bary2.accumulate()[1],12); - pass - expected4=[[-12.,90.],[0.8,6.],[-4,90.],[-2.4,30.],[12.,18],[-4,18.]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]/=pt - self.assertAlmostEqual(expected4[pos][0],bary2.accumulate()[0],12); - self.assertAlmostEqual(expected4[pos][1],bary2.accumulate()[1],12); - pass - # - d=DataArrayInt.New([1,2,0,1,0,2],3,2) - e=DataArrayInt.New([1,11,101,2,12,102,3,13,103,4,14,104],4,3) - expected5=[[1,11,101,77,77,77,77,77,77,4,14,104],[77,77,77,77,77,77,3,13,103,4,14,104],[77,77,77,2,12,102,77,77,77,4,14,104]] - expected6=[[1,77,77,2,77,77,3,77,77,4,77,77],[77,77,101,77,77,102,77,77,103,77,77,104],[77,11,77,77,12,77,77,13,77,77,14,77]] - for pos,tup in enumerate(d): - f=e[:] - self.assertTrue(isinstance(f,DataArrayInt)) - f[tup]=77 - self.assertEqual(expected5[pos],f.getValues()) - self.assertEqual(6*[77],f[tup].getValues()) - f=e[:] - f[:,tup]=77 - self.assertEqual(expected6[pos],f.getValues()) - self.assertEqual(8*[77],f[:,tup].getValues()) - pass - # - e=e.convertToDblArr() - for pos,tup in enumerate(d): - f=e[:] - self.assertTrue(isinstance(f,DataArrayDouble)) - f[tup]=77. - self.assertEqual(expected5[pos],f.convertToIntArr().getValues()) - self.assertEqual(6*[77],f[tup].convertToIntArr().getValues()) - f=e[:] - f[:,tup]=77. - self.assertEqual(expected6[pos],f.convertToIntArr().getValues()) - self.assertEqual(8*[77],f[:,tup].convertToIntArr().getValues()) - pass - pass - - def testDataArrayDoubleGetMinMaxPerComponent1(self): - values1=[1.,2.,3.,-0.9,2.1,3.,1.3,1.7,3.,1.,1.8,3.] - d1=DataArrayDouble.New(); - self.assertRaises(InterpKernelException,d1.getMinMaxPerComponent) - d1=DataArrayDouble.New(values1,4,3); - res=d1.getMinMaxPerComponent(); - self.assertTrue(isinstance(res,list)) - self.assertEqual(3,len(res)) - for i in xrange(3): - self.assertTrue(isinstance(res[i],tuple)) - self.assertEqual(2,len(res[i])) - pass - expected1=[-0.9,1.3,1.7,2.1,3.,3.] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],res[i/2][i%2],14) - pass - # - d1.rearrange(2); - res=d1.getMinMaxPerComponent(); - self.assertTrue(isinstance(res,list)) - self.assertEqual(2,len(res)) - for i in xrange(2): - self.assertTrue(isinstance(res[i],tuple)) - self.assertEqual(2,len(res[i])) - pass - expected2=[1.,3.,-0.9,3.] - for i in xrange(4): - self.assertAlmostEqual(expected2[i],res[i/2][i%2],14) - pass - # - d1.rearrange(1); - res=d1.getMinMaxPerComponent(); - self.assertTrue(isinstance(res,list)) - self.assertEqual(1,len(res)) - for i in xrange(1): - self.assertTrue(isinstance(res[i],tuple)) - self.assertEqual(2,len(res[i])) - pass - expected3=[-0.9,3.] - for i in xrange(2): - self.assertAlmostEqual(expected3[i],res[i/2][i%2],14) - pass - pass - - def testDataArrayIntGetHashCode1(self): - d1=DataArrayInt.New(range(3545)) - d2=DataArrayInt.New(range(3545)) - self.assertEqual(d2.getHashCode(),d1.getHashCode()) - self.assertEqual(232341068,d1.getHashCode()) - d1[886]=6 - self.assertEqual(232340188,d1.getHashCode()) - pass - - def testZipConnectivityPol1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m2_1=m1.buildPartOfMySelf(cells1,True); - m2=m2_1 - self.assertTrue(isinstance(m2,MEDCouplingUMesh)) - # no permutation policy 0 - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # no permutation policy 1 - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # no permutation policy 2 - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # some modification into m2 - modif1=[2,4,5] - m2.getNodalConnectivity()[1:4]=modif1 - #policy 0 fails because cell0 in m2 has same orientation be not same connectivity - expected1=[5,3,4] - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(not isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected1,arr.getValues()) - #policy 1 succeeds because cell0 in m2 has not exactly the same conn - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - #policy 2 succeeds because cell0 in m2 has same nodes in connectivity - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - #some new modification into m2 - modif2=[2,5,4] - m2.getNodalConnectivity()[1:4]=modif2 - #policy 0 fails because cell0 in m2 has not exactly the same conn - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(not isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected1,arr.getValues()) - #policy 1 fails too because cell0 in m2 has not same orientation - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(not isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected1,arr.getValues()) - #policy 2 succeeds because cell0 in m2 has same nodes in connectivity - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # Now 1D - cells2=[3,2] - m1=MEDCouplingDataForTest.build1DSourceMesh_2(); - m2_1=m1.buildPartOfMySelf(cells2,True); - m2=m2_1 - self.assertTrue(isinstance(m2,MEDCouplingUMesh)) - # no permutation policy 0 - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - # no permutation policy 1 - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - # no permutation policy 2 - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - # some modification into m2 - modif3=[4,3] - m2.getNodalConnectivity()[1:3]=modif3 - #policy 0 fails because cell0 in m2 has not exactly the same conn - expected2=[4,2] - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(not isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected2,arr.getValues()) - #policy 1 fails too because cell0 in m2 has not same orientation - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(not isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected2,arr.getValues()) - #policy 2 succeeds because cell0 in m2 has same nodes in connectivity - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - pass - - def toSeeIfDaIIopsAreOK(self,d): - d+=5 - d*=6 - d/=3 - d-=2 - d%=7 - pass - - def testSwigDAIOp5(self): - d=DataArrayInt.New([4,5,6,10,3,-1],2,3) - self.toSeeIfDaIIopsAreOK(d) - dExp=DataArrayInt.New([2,4,6,0,0,6],2,3) - self.assertTrue(d.isEqual(dExp)); - pass - - def toSeeIfDaDIopsAreOK(self,d): - d+=5 - d*=6 - d/=3 - d-=2 - pass - - def testSwigDADOp7(self): - d=DataArrayDouble.New([4.,5.,6.,10.,3.,-1.],2,3) - self.toSeeIfDaDIopsAreOK(d) - dExp=DataArrayDouble.New([16.,18.,20.,28.,14.,6.],2,3) - self.assertTrue(d.isEqual(dExp,1e-14)); - pass - - def testConvexEnvelop2D1(self): - coords=[7.54758495819e-14,-1.12270326253e-12,8.43143594193,-1.02835845055e-12,4.21571797096,7.30183771609,-4.21571797097,7.30183771609,-8.43143594193,-1.09439981894e-12,-4.21571797097,-7.30183771609,4.21571797097,-7.30183771609,16.8628718839,-1.02835845055e-12,12.6471539129,7.30183771609,8.43143594193,14.6036754322,2.26427548746e-13,14.6036754322,-8.43143594193,14.6036754322,-12.6471539129,7.30183771609,-16.8628718839,-1.39630321727e-12,-12.6471539129,-7.30183771609,-8.43143594193,-14.6036754322,3.7737924791e-14,-14.6036754322,8.43143594193,-14.6036754322,12.6471539129,-7.30183771609,25.2943078258,-1.07553085654e-12,21.0785898548,7.30183771609,16.8628718839,14.6036754322,12.6471539129,21.9055131483,4.21571797096,21.9055131483,-4.21571797097,21.9055131483,-12.6471539129,21.9055131483,-16.8628718839,14.6036754322,-21.0785898548,7.30183771609,-25.2943078258,-1.02835845055e-12,-21.0785898548,-7.30183771609,-16.8628718839,-14.6036754322,-12.6471539129,-21.9055131483,-4.21571797097,-21.9055131483,4.21571797097,-21.9055131483,12.6471539129,-21.9055131483,16.8628718839,-14.6036754322,21.0785898548,-7.30183771609,33.7257437677,-7.45324014622e-13,29.5100257968,7.30183771609,25.2943078258,14.6036754322,21.0785898548,21.9055131483,16.8628718839,29.2073508644,8.43143594193,29.2073508644,-1.20761359331e-12,29.2073508644,-8.43143594193,29.2073508644,-16.8628718839,29.2073508644,-21.0785898548,21.9055131483,-25.2943078258,14.6036754322,-29.5100257968,7.30183771609,-33.7257437677,-7.26455052226e-13,-29.5100257968,-7.30183771609,-25.2943078258,-14.6036754322,-21.0785898548,-21.9055131483,-16.8628718839,-29.2073508644,-8.43143594193,-29.2073508644,4.15117172701e-13,-29.2073508644,8.43143594193,-29.2073508644,16.8628718839,-29.2073508644,21.0785898548,-21.9055131483,25.2943078258,-14.6036754322,29.5100257968,-7.30183771609,42.1571797097,-1.86802727715e-12,37.9414617387,7.30183771609,33.7257437677,14.6036754322,29.5100257968,21.9055131483,25.2943078258,29.2073508644,21.0785898548,36.5091885805,12.6471539129,36.5091885805,4.21571797096,36.5091885805,-4.21571797096,36.5091885805,-12.6471539129,36.5091885805,-21.0785898548,36.5091885805,-25.2943078258,29.2073508644,-29.5100257968,21.9055131483,-33.7257437677,14.6036754322,-37.9414617387,7.30183771609,-42.1571797097,-9.81186044565e-13,-37.9414617387,-7.30183771609,-33.7257437677,-14.6036754322,-29.5100257968,-21.9055131483,-25.2943078258,-29.2073508644,-21.0785898548,-36.5091885805,-12.6471539129,-36.5091885805,-4.21571797097,-36.5091885805,4.21571797097,-36.5091885805,12.6471539129,-36.5091885805,21.0785898548,-36.5091885805,25.2943078258,-29.2073508644,29.5100257968,-21.9055131483,33.7257437677,-14.6036754322,37.9414617387,-7.30183771609,50.5886156516,-6.98151608633e-13,46.3728976806,7.30183771609,42.1571797097,14.6036754322,37.9414617387,21.9055131483,33.7257437677,29.2073508644,29.5100257968,36.5091885805,25.2943078258,43.8110262966,16.8628718839,43.8110262966,8.43143594193,43.8110262966,-1.84915831476e-12,43.8110262966,-8.43143594193,43.8110262966,-16.8628718839,43.8110262966,-25.2943078258,43.8110262966,-29.5100257968,36.5091885805,-33.7257437677,29.2073508644,-37.9414617387,21.9055131483,-42.1571797097,14.6036754322,-46.3728976806,7.30183771609,-50.5886156516,-1.47177906685e-12,-46.3728976806,-7.30183771609,-42.1571797097,-14.6036754322,-37.9414617387,-21.9055131483,-33.7257437677,-29.2073508644,-29.5100257968,-36.5091885805,-25.2943078258,-43.8110262966,-16.8628718839,-43.8110262966,-8.43143594193,-43.8110262966,7.54758495819e-14,-43.8110262966,8.43143594193,-43.8110262966,16.8628718839,-43.8110262966,25.2943078258,-43.8110262966,29.5100257968,-36.5091885805,33.7257437677,-29.2073508644,37.9414617387,-21.9055131483,42.1571797097,-14.6036754322,46.3728976806,-7.30183771609,59.0200515935,-7.9249642061e-13,54.8043336225,7.30183771609,50.5886156516,14.6036754322,46.3728976806,21.9055131483,42.1571797097,29.2073508644,37.9414617387,36.5091885805,33.7257437677,43.8110262966,29.5100257968,51.1128640127,21.0785898548,51.1128640127,12.6471539129,51.1128640127,4.21571797096,51.1128640127,-4.21571797096,51.1128640127,-12.6471539129,51.1128640127,-21.0785898548,51.1128640127,-29.5100257968,51.1128640127,-33.7257437677,43.8110262966,-37.9414617387,36.5091885805,-42.1571797097,29.2073508644,-46.3728976806,21.9055131483,-50.5886156516,14.6036754322,-54.8043336226,7.30183771609,-59.0200515935,-1.31139288649e-12,-54.8043336226,-7.30183771609,-50.5886156516,-14.6036754322,-46.3728976806,-21.9055131483,-42.1571797097,-29.2073508644,-37.9414617387,-36.5091885805,-33.7257437677,-43.8110262966,-29.5100257968,-51.1128640127,-21.0785898548,-51.1128640127,-12.6471539129,-51.1128640127,-4.21571797097,-51.1128640127,4.21571797097,-51.1128640127,12.6471539129,-51.1128640127,21.0785898548,-51.1128640127,29.5100257968,-51.1128640127,33.7257437677,-43.8110262966,37.9414617387,-36.5091885805,42.1571797097,-29.2073508644,46.3728976806,-21.9055131483,50.5886156516,-14.6036754322,54.8043336225,-7.30183771609,67.4514875354,-2.14162723189e-12,63.2357695645,7.30183771609,59.0200515935,14.6036754322,54.8043336226,21.9055131483,50.5886156516,29.2073508644,46.3728976806,36.5091885805,42.1571797097,43.8110262966,37.9414617387,51.1128640127,33.7257437677,58.4147017287,25.2943078258,58.4147017287,16.8628718839,58.4147017287,8.43143594193,58.4147017287,6.79282646237e-13,58.4147017287,-8.43143594193,58.4147017287,-16.8628718839,58.4147017287,-25.2943078258,58.4147017287,-33.7257437677,58.4147017287,-37.9414617387,51.1128640127,-42.1571797097,43.8110262966,-46.3728976806,36.5091885805,-50.5886156516,29.2073508644,-54.8043336226,21.9055131483,-59.0200515935,14.6036754322,-63.2357695645,7.30183771609,-67.4514875354,-1.16044118732e-12,-63.2357695645,-7.30183771609,-59.0200515935,-14.6036754322,-54.8043336226,-21.9055131483,-50.5886156516,-29.2073508644,-46.3728976806,-36.5091885805,-42.1571797097,-43.8110262966,-37.9414617387,-51.1128640127,-33.7257437677,-58.4147017287,-25.2943078258,-58.4147017287,-16.8628718839,-58.4147017287,-8.43143594193,-58.4147017287,-5.66068871864e-14,-58.4147017287,8.43143594193,-58.4147017287,16.8628718839,-58.4147017287,25.2943078258,-58.4147017287,33.7257437677,-58.4147017287,37.9414617387,-51.1128640127,42.1571797097,-43.8110262966,46.3728976806,-36.5091885805,50.5886156516,-29.2073508644,54.8043336226,-21.9055131483,59.0200515935,-14.6036754322,63.2357695645,-7.30183771609,75.8829234774,-2.29257893105e-12,71.6672055064,7.30183771609,67.4514875354,14.6036754322,63.2357695645,21.9055131483,59.0200515935,29.2073508644,54.8043336226,36.5091885805,50.5886156516,43.8110262966,46.3728976806,51.1128640127,42.1571797097,58.4147017287,37.9414617387,65.7165394448,29.5100257968,65.7165394448,21.0785898548,65.7165394448,12.6471539129,65.7165394448,4.21571797097,65.7165394448,-4.21571797096,65.7165394448,-12.6471539129,65.7165394448,-21.0785898548,65.7165394448,-29.5100257968,65.7165394448,-37.9414617387,65.7165394448,-42.1571797097,58.4147017287,-46.3728976806,51.1128640127,-50.5886156516,43.8110262966,-54.8043336226,36.5091885805,-59.0200515935,29.2073508644,-63.2357695645,21.9055131483,-67.4514875354,14.6036754322,-71.6672055064,7.30183771609,-75.8829234774,-1.31139288649e-12,-71.6672055064,-7.30183771609,-67.4514875354,-14.6036754322,-63.2357695645,-21.9055131483,-59.0200515935,-29.2073508644,-54.8043336226,-36.5091885805,-50.5886156516,-43.8110262966,-46.3728976806,-51.1128640127,-42.1571797097,-58.4147017287,-37.9414617387,-65.7165394448,-29.5100257968,-65.7165394448,-21.0785898548,-65.7165394448,-12.6471539129,-65.7165394448,-4.21571797097,-65.7165394448,4.21571797097,-65.7165394448,12.6471539129,-65.7165394448,21.0785898548,-65.7165394448,29.5100257968,-65.7165394448,37.9414617387,-65.7165394448,42.1571797097,-58.4147017287,46.3728976806,-51.1128640127,50.5886156516,-43.8110262966,54.8043336226,-36.5091885805,59.0200515935,-29.2073508644,63.2357695645,-21.9055131483,67.4514875354,-14.6036754322,71.6672055064,-7.30183771609,84.3143594193,-1.49064802924e-12,80.0986414483,7.30183771609,75.8829234774,14.6036754322,71.6672055064,21.9055131483,67.4514875354,29.2073508644,63.2357695645,36.5091885805,59.0200515935,43.8110262966,54.8043336226,51.1128640127,50.5886156516,58.4147017287,46.3728976806,65.7165394448,42.1571797097,73.0183771609,33.7257437677,73.0183771609,25.2943078258,73.0183771609,16.8628718839,73.0183771609,8.43143594193,73.0183771609,2.0755858635e-12,73.0183771609,-8.43143594193,73.0183771609,-16.8628718839,73.0183771609,-25.2943078258,73.0183771609,-33.7257437677,73.0183771609,-42.1571797097,73.0183771609,-46.3728976806,65.7165394448,-50.5886156516,58.4147017287,-54.8043336226,51.1128640127,-59.0200515935,43.8110262966,-63.2357695645,36.5091885805,-67.4514875354,29.2073508644,-71.6672055064,21.9055131483,-75.8829234774,14.6036754322,-80.0986414483,7.30183771609,-84.3143594193,-1.11326878133e-12,-80.0986414483,-7.30183771609,-75.8829234774,-14.6036754322,-71.6672055064,-21.9055131483,-67.4514875354,-29.2073508644,-63.2357695645,-36.5091885805,-59.0200515935,-43.8110262966,-54.8043336226,-51.1128640127,-50.5886156516,-58.4147017287,-46.3728976806,-65.7165394448,-42.1571797097,-73.0183771609,-33.7257437677,-73.0183771609,-25.2943078258,-73.0183771609,-16.8628718839,-73.0183771609,-8.43143594193,-73.0183771609,-5.66068871864e-14,-73.0183771609,8.43143594193,-73.0183771609,16.8628718839,-73.0183771609,25.2943078258,-73.0183771609,33.7257437677,-73.0183771609,42.1571797097,-73.0183771609,46.3728976806,-65.7165394448,50.5886156516,-58.4147017287,54.8043336226,-51.1128640127,59.0200515935,-43.8110262966,63.2357695645,-36.5091885805,67.4514875354,-29.2073508644,71.6672055064,-21.9055131483,75.8829234774,-14.6036754322,80.0986414483,-7.3018377161] - conn=[0,2,3,4,5,6,1,1,8,2,0,6,18,7,2,9,10,3,0,1,8,3,10,11,12,4,0,2,4,3,12,13,14,5,0,5,0,4,14,15,16,6,6,1,0,5,16,17,18,7,20,8,1,18,36,19,8,21,9,2,1,7,20,9,22,23,10,2,8,21,10,23,24,11,3,2,9,11,24,25,26,12,3,10,12,11,26,27,13,4,3,13,12,27,28,29,14,4,14,4,13,29,30,15,5,15,5,14,30,31,32,16,16,6,5,15,32,33,17,17,18,6,16,33,34,35,18,7,1,6,17,35,36,19,38,20,7,36,60,37,20,39,21,8,7,19,38,21,40,22,9,8,20,39,22,41,42,23,9,21,40,23,42,43,24,10,9,22,24,43,44,25,11,10,23,25,44,45,46,26,11,24,26,25,46,47,27,12,11,27,26,47,48,28,13,12,28,27,48,49,50,29,13,29,13,28,50,51,30,14,30,14,29,51,52,31,15,31,15,30,52,53,54,32,32,16,15,31,54,55,33,33,17,16,32,55,56,34,34,35,17,33,56,57,58,35,36,18,17,34,58,59,36,19,7,18,35,59,60,37,62,38,19,60,90,61,38,63,39,20,19,37,62,39,64,40,21,20,38,63,40,65,41,22,21,39,64,41,66,67,42,22,40,65,42,67,68,43,23,22,41,43,68,69,44,24,23,42,44,69,70,45,25,24,43,45,70,71,72,46,25,44,46,45,72,73,47,26,25,47,46,73,74,48,27,26,48,47,74,75,49,28,27,49,48,75,76,77,50,28,50,28,49,77,78,51,29,51,29,50,78,79,52,30,52,30,51,79,80,53,31,53,31,52,80,81,82,54,54,32,31,53,82,83,55,55,33,32,54,83,84,56,56,34,33,55,84,85,57,57,58,34,56,85,86,87,58,59,35,34,57,87,88,59,60,36,35,58,88,89,60,37,19,36,59,89,90,61,92,62,37,90,126,91,62,93,63,38,37,61,92,63,94,64,39,38,62,93,64,95,65,40,39,63,94,65,96,66,41,40,64,95,66,97,98,67,41,65,96,67,98,99,68,42,41,66,68,99,100,69,43,42,67,69,100,101,70,44,43,68,70,101,102,71,45,44,69,71,102,103,104,72,45,70,72,71,104,105,73,46,45,73,72,105,106,74,47,46,74,73,106,107,75,48,47,75,74,107,108,76,49,48,76,75,108,109,110,77,49,77,49,76,110,111,78,50,78,50,77,111,112,79,51,79,51,78,112,113,80,52,80,52,79,113,114,81,53,81,53,80,114,115,116,82,82,54,53,81,116,117,83,83,55,54,82,117,118,84,84,56,55,83,118,119,85,85,57,56,84,119,120,86,86,87,57,85,120,121,122,87,88,58,57,86,122,123,88,89,59,58,87,123,124,89,90,60,59,88,124,125,90,61,37,60,89,125,126,91,128,92,61,126,168,127,92,129,93,62,61,91,128,93,130,94,63,62,92,129,94,131,95,64,63,93,130,95,132,96,65,64,94,131,96,133,97,66,65,95,132,97,134,135,98,66,96,133,98,135,136,99,67,66,97,99,136,137,100,68,67,98,100,137,138,101,69,68,99,101,138,139,102,70,69,100,102,139,140,103,71,70,101,103,140,141,142,104,71,102,104,103,142,143,105,72,71,105,104,143,144,106,73,72,106,105,144,145,107,74,73,107,106,145,146,108,75,74,108,107,146,147,109,76,75,109,108,147,148,149,110,76,110,76,109,149,150,111,77,111,77,110,150,151,112,78,112,78,111,151,152,113,79,113,79,112,152,153,114,80,114,80,113,153,154,115,81,115,81,114,154,155,156,116,116,82,81,115,156,157,117,117,83,82,116,157,158,118,118,84,83,117,158,159,119,119,85,84,118,159,160,120,120,86,85,119,160,161,121,121,122,86,120,161,162,163,122,123,87,86,121,163,164,123,124,88,87,122,164,165,124,125,89,88,123,165,166,125,126,90,89,124,166,167,126,91,61,90,125,167,168,127,170,128,91,168,216,169,128,171,129,92,91,127,170,129,172,130,93,92,128,171,130,173,131,94,93,129,172,131,174,132,95,94,130,173,132,175,133,96,95,131,174,133,176,134,97,96,132,175,134,177,178,135,97,133,176,135,178,179,136,98,97,134,136,179,180,137,99,98,135,137,180,181,138,100,99,136,138,181,182,139,101,100,137,139,182,183,140,102,101,138,140,183,184,141,103,102,139,141,184,185,186,142,103,140,142,141,186,187,143,104,103,143,142,187,188,144,105,104,144,143,188,189,145,106,105,145,144,189,190,146,107,106,146,145,190,191,147,108,107,147,146,191,192,148,109,108,148,147,192,193,194,149,109,149,109,148,194,195,150,110,150,110,149,195,196,151,111,151,111,150,196,197,152,112,152,112,151,197,198,153,113,153,113,152,198,199,154,114,154,114,153,199,200,155,115,155,115,154,200,201,202,156,156,116,115,155,202,203,157,157,117,116,156,203,204,158,158,118,117,157,204,205,159,159,119,118,158,205,206,160,160,120,119,159,206,207,161,161,121,120,160,207,208,162,162,163,121,161,208,209,210,163,164,122,121,162,210,211,164,165,123,122,163,211,212,165,166,124,123,164,212,213,166,167,125,124,165,213,214,167,168,126,125,166,214,215,168,127,91,126,167,215,216,169,218,170,127,216,270,217,170,219,171,128,127,169,218,171,220,172,129,128,170,219,172,221,173,130,129,171,220,173,222,174,131,130,172,221,174,223,175,132,131,173,222,175,224,176,133,132,174,223,176,225,177,134,133,175,224,177,226,227,178,134,176,225,178,227,228,179,135,134,177,179,228,229,180,136,135,178,180,229,230,181,137,136,179,181,230,231,182,138,137,180,182,231,232,183,139,138,181,183,232,233,184,140,139,182,184,233,234,185,141,140,183,185,234,235,236,186,141,184,186,185,236,237,187,142,141,187,186,237,238,188,143,142,188,187,238,239,189,144,143,189,188,239,240,190,145,144,190,189,240,241,191,146,145,191,190,241,242,192,147,146,192,191,242,243,193,148,147,193,192,243,244,245,194,148,194,148,193,245,246,195,149,195,149,194,246,247,196,150,196,150,195,247,248,197,151,197,151,196,248,249,198,152,198,152,197,249,250,199,153,199,153,198,250,251,200,154,200,154,199,251,252,201,155,201,155,200,252,253,254,202,202,156,155,201,254,255,203,203,157,156,202,255,256,204,204,158,157,203,256,257,205,205,159,158,204,257,258,206,206,160,159,205,258,259,207,207,161,160,206,259,260,208,208,162,161,207,260,261,209,209,210,162,208,261,262,263,210,211,163,162,209,263,264,211,212,164,163,210,264,265,212,213,165,164,211,265,266,213,214,166,165,212,266,267,214,215,167,166,213,267,268,215,216,168,167,214,268,269,216,169,127,168,215,269,270,217,272,218,169,270,330,271,218,273,219,170,169,217,272,219,274,220,171,170,218,273,220,275,221,172,171,219,274,221,276,222,173,172,220,275,222,277,223,174,173,221,276,223,278,224,175,174,222,277,224,279,225,176,175,223,278,225,280,226,177,176,224,279,226,281,282,227,177,225,280,227,282,283,228,178,177,226,228,283,284,229,179,178,227,229,284,285,230,180,179,228,230,285,286,231,181,180,229,231,286,287,232,182,181,230,232,287,288,233,183,182,231,233,288,289,234,184,183,232,234,289,290,235,185,184,233,235,290,291,292,236,185,234,236,235,292,293,237,186,185,237,236,293,294,238,187,186,238,237,294,295,239,188,187,239,238,295,296,240,189,188,240,239,296,297,241,190,189,241,240,297,298,242,191,190,242,241,298,299,243,192,191,243,242,299,300,244,193,192,244,243,300,301,302,245,193,245,193,244,302,303,246,194,246,194,245,303,304,247,195,247,195,246,304,305,248,196,248,196,247,305,306,249,197,249,197,248,306,307,250,198,250,198,249,307,308,251,199,251,199,250,308,309,252,200,252,200,251,309,310,253,201,253,201,252,310,311,312,254,254,202,201,253,312,313,255,255,203,202,254,313,314,256,256,204,203,255,314,315,257,257,205,204,256,315,316,258,258,206,205,257,316,317,259,259,207,206,258,317,318,260,260,208,207,259,318,319,261,261,209,208,260,319,320,262,262,263,209,261,320,321,322,263,264,210,209,262,322,323,264,265,211,210,263,323,324,265,266,212,211,264,324,325,266,267,213,212,265,325,326,267,268,214,213,266,326,327,268,269,215,214,267,327,328,269,270,216,215,268,328,329,270,217,169,216,269,329,330,271,272,217,330,273,218,217,271,274,219,218,272,275,220,219,273,276,221,220,274,277,222,221,275,278,223,222,276,279,224,223,277,280,225,224,278,281,226,225,279,281,282,226,280,283,227,226,281,284,228,227,282,285,229,228,283,286,230,229,284,287,231,230,285,288,232,231,286,289,233,232,287,290,234,233,288,291,235,234,289,291,292,235,290,291,293,236,235,292,294,237,236,293,295,238,237,294,296,239,238,295,297,240,239,296,298,241,240,297,299,242,241,298,300,243,242,299,301,244,243,301,300,302,244,244,301,303,245,245,302,304,246,246,303,305,247,247,304,306,248,248,305,307,249,249,306,308,250,250,307,309,251,251,308,310,252,252,309,311,253,311,253,310,312,254,253,311,313,255,254,312,314,256,255,313,315,257,256,314,316,258,257,315,317,259,258,316,318,260,259,317,319,261,260,318,320,262,261,319,321,321,322,262,320,323,263,262,321,324,264,263,322,325,265,264,323,326,266,265,324,327,267,266,325,328,268,267,326,329,269,268,327,330,270,269,328,271,217,270,329] - connI=[0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,343,350,357,364,371,378,385,392,399,406,413,420,427,434,441,448,455,462,469,476,483,490,497,504,511,518,525,532,539,546,553,560,567,574,581,588,595,602,609,616,623,630,637,644,651,658,665,672,679,686,693,700,707,714,721,728,735,742,749,756,763,770,777,784,791,798,805,812,819,826,833,840,847,854,861,868,875,882,889,896,903,910,917,924,931,938,945,952,959,966,973,980,987,994,1001,1008,1015,1022,1029,1036,1043,1050,1057,1064,1071,1078,1085,1092,1099,1106,1113,1120,1127,1134,1141,1148,1155,1162,1169,1176,1183,1190,1197,1204,1211,1218,1225,1232,1239,1246,1253,1260,1267,1274,1281,1288,1295,1302,1309,1316,1323,1330,1337,1344,1351,1358,1365,1372,1379,1386,1393,1400,1407,1414,1421,1428,1435,1442,1449,1456,1463,1470,1477,1484,1491,1498,1505,1512,1519,1526,1533,1540,1547,1554,1561,1568,1575,1582,1589,1596,1603,1610,1617,1624,1631,1638,1645,1652,1659,1666,1673,1680,1687,1694,1701,1708,1715,1722,1729,1736,1743,1750,1757,1764,1771,1778,1785,1792,1799,1806,1813,1820,1827,1834,1841,1848,1855,1862,1869,1876,1883,1890,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,2037,2041,2045,2049,2053,2057,2061,2065,2069,2073,2077,2081,2085,2089,2093,2097,2101,2105,2109,2113,2117,2121,2125,2129,2133,2137] - # - m=MEDCouplingUMesh.New("convexhull",2); - m.allocateCells(331); - for i in xrange(331): - m.insertNextCell(NORM_POLYGON,conn[connI[i]:connI[i+1]]); - pass - m.finishInsertingCells(); - coordsDa=DataArrayDouble.New(coords,331,2); - m.setCoords(coordsDa); - m.checkCoherency(); - # - da=m.convexEnvelop2D(); - m.checkCoherency() - self.assertEqual(coordsDa.getHiddenCppPointer(),m.getCoords().getHiddenCppPointer()) - daC=da.buildComplement(m.getNumberOfCells()); - expected2=DataArrayInt.New([271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,302,303,304,305,306,307,308,309,310,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330]); - self.assertTrue(expected2.isEqual(daC)); - # - vals=m.getMeasureField(ON_CELLS).getArray() - ref=271*[184.69493088478035]+3*[-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491]+2*[61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491]+[-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491] - vals-=DataArrayDouble.New(ref) - vals.abs() - theTest=vals.getIdsInRange(-1.,1e-7) - self.assertTrue(theTest.isIdentity()) - self.assertEqual(331,len(theTest)) - pass - - def testSwigDAIOp8(self): - da=DataArrayInt.New([7,5,6,7,8,9,9,10,12,13,47,15]) - self.assertTrue(7 in da) - self.assertTrue(47 in da) - self.assertTrue(15 in da) - self.assertEqual(0,da.index(7)) - self.assertEqual(10,da.index(47)) - self.assertTrue(14 not in da) - self.assertEqual(5,da.search([9,9])) - self.assertEqual(-1,da.search([5,8])) - da.rearrange(2) - self.assertTrue([47,16] not in da) - self.assertTrue([5,6] not in da) - self.assertTrue([6,7] in da) - self.assertEqual(4,da.index([12,13])) - pass - - def testDataArraySort1(self): - arr=DataArrayInt.New(); - self.assertRaises(InterpKernelException,arr.sort,True) - self.assertRaises(InterpKernelException,arr.sort,False) - values=[2,1,6,5,4,7] - arr.alloc(3,2); - self.assertRaises(InterpKernelException,arr.sort,True) - self.assertRaises(InterpKernelException,arr.sort,False) - arr.rearrange(1); - arr.setValues(values,6,1) - arr1=arr.deepCpy(); - arr2=arr.deepCpy(); - arr1.sort(True); - expected1=[1,2,4,5,6,7] - self.assertEqual(6,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected1,arr1.getValues()); - arr2.sort(False); - expected2=[7,6,5,4,2,1] - self.assertEqual(6,arr2.getNumberOfTuples()); - self.assertEqual(1,arr2.getNumberOfComponents()); - self.assertTrue(expected2,arr2.getValues()); - # - ard=DataArrayDouble.New(); - self.assertRaises(InterpKernelException,ard.sort,True) - self.assertRaises(InterpKernelException,ard.sort,False) - valuesD=[2.,1.,6.,5.,4.,7.] - ard.alloc(3,2); - self.assertRaises(InterpKernelException,ard.sort,True) - self.assertRaises(InterpKernelException,ard.sort,False) - ard.rearrange(1); - ard.setValues(valuesD,6,1) - ard1=ard.deepCpy(); - ard2=ard.deepCpy(); - ard1.sort(True); - expected3=[1.,2.,4.,5.,6.,7.] - self.assertEqual(6,ard1.getNumberOfTuples()); - self.assertEqual(1,ard1.getNumberOfComponents()); - for i in xrange(6): - self.assertAlmostEqual(expected3[i],ard1.getIJ(i,0),12) - pass - ard2.sort(False); - expected4=[7.,6.,5.,4.,2.,1.] - self.assertEqual(6,ard2.getNumberOfTuples()); - self.assertEqual(1,ard2.getNumberOfComponents()); - for i in xrange(6): - self.assertAlmostEqual(expected4[i],ard2.getIJ(i,0),12) - pass - pass - - def testPartitionBySpreadZone1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m4=MEDCouplingUMesh.MergeUMeshes([m,m[-3:],m[0:2]]); - m4.renumberCells([5,2,9,6,4,7,0,1,3,8]); - # - v2=m4.partitionBySpreadZone(); - self.assertTrue(3,len(v2)); - self.assertTrue(v2[0].isEqual(DataArrayInt.New([0,1,7]))) - self.assertTrue(v2[1].isEqual(DataArrayInt.New([2,4,5,6,9]))) - self.assertTrue(v2[2].isEqual(DataArrayInt.New([3,8]))) - # - m5=m4.buildSpreadZonesWithPoly(); - self.assertEqual(3,m5.getNumberOfCells()); - self.assertTrue(m5.getCoords().getHiddenCppPointer()==m4.getCoords().getHiddenCppPointer()); - self.assertEqual([5,15,16,17,14,11,13,12,5,2,1,0,3,6,7,8,5,5,18,21,22,20,19],m5.getNodalConnectivity().getValues()) - self.assertEqual([0,8,17,23],m5.getNodalConnectivityIndex().getValues()) - # - pass - - def testGiveCellsWithType1(self): - expected0=[1,2] - expected1=[0,3,4] - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - da=m.giveCellsWithType(NORM_TRI3); - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(expected0,da.getValues()) - # - da=m.giveCellsWithType(NORM_QUAD4); - self.assertEqual(3,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(expected1,da.getValues()) - # - da=m.giveCellsWithType(NORM_TRI6); - self.assertEqual(0,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - # - self.assertRaises(InterpKernelException,m.giveCellsWithType,NORM_SEG2) - self.assertRaises(InterpKernelException,m.giveCellsWithType,NORM_HEXA8) - pass - - def testSwigDAOp1(self): - d=DataArrayDouble.New(5,2) - d.rearrange(1) ; d.iota(2.) ; d.rearrange(2) - d.setInfoOnComponents(["X [m]","Y [m]"]) - d.setName("AName") - # - d1=d+[8,9] - self.assertTrue(d1.isEqualWithoutConsideringStr(DataArrayDouble.New([10.0,12.0,12.0,14.0,14.0,16.0,16.0,18.0,18.0,20.0]),1e-12)) - d1bis=DataArrayDouble.New([8,9],1,2)+d - self.assertTrue(d1bis.isEqual(d1,1e-12)) - d1ter=[8,9]+d - self.assertTrue(d1ter.isEqual(d1,1e-12)) - # - d2=d1-[8,9] - self.assertTrue(d2.isEqual(d,1e-12)) - self.assertRaises(InterpKernelException,d1.__rsub__,[8,9])#[8,9]-d1 - # - d3=d*[8,9] - self.assertTrue(d3.isEqualWithoutConsideringStr(DataArrayDouble.New([16.0,27.0,32.0,45.0,48.0,63.0,64.0,81.0,80.0,99.0]),1e-12)) - d3bis=DataArrayDouble.New([8,9],1,2)*d - self.assertTrue(d3bis.isEqual(d3,1e-12)) - d3ter=[8,9]*d - self.assertTrue(d3ter.isEqual(d3,1e-12)) - # - d4=d3/[8,9] - self.assertTrue(d4.isEqual(d,1e-12)) - # - d=DataArrayInt.New(5,2) - d.rearrange(1) ; d.iota(2) ; d.rearrange(2) - d.setInfoOnComponents(["X [m]","Y [m]"]) - d.setName("AName") - # - d1=d+[8,9] - self.assertEqual(d1.getValues(),[10,12,12,14,14,16,16,18,18,20]) - d1bis=DataArrayInt.New([8,9],1,2)+d - self.assertTrue(d1bis.isEqual(d1)) - d1ter=[8,9]+d - self.assertTrue(d1ter.isEqual(d1)) - # - d2=d1-[8,9] - self.assertTrue(d2.isEqual(d)) - self.assertRaises(InterpKernelException,d1.__rsub__,[8,9]) - # - d3=d*[8,9] - self.assertEqual(d3.getValues(),[16,27,32,45,48,63,64,81,80,99]) - d3bis=DataArrayInt.New([8,9],1,2)*d - self.assertTrue(d3bis.isEqual(d3)) - d3ter=[8,9]*d - self.assertTrue(d3ter.isEqual(d3)) - # - d4=d3/[8,9] - self.assertTrue(d4.isEqual(d)) - # - d5=d%[4,5] - self.assertEqual(d5.getValues(),[2,3,0,0,2,2,0,4,2,1]) - pass - - def testSwigSelectTupleId2DAIBug1(self): - da=DataArrayInt.New([0,1,2,3,12,13,4,5,6,7,14,15,8,9,10,11,16,17]) - self.assertEqual([2,6,10],da[2::6].getValues()) - self.assertEqual([0,4,8],da[::6].getValues()) - self.assertEqual([5,9],da[7::6].getValues()) - self.assertEqual([5],da[7:-5:6].getValues()) - pass - - def testSwigCpp5Safe1(self): - m=MEDCouplingUMesh.New("toto",2) - coords=DataArrayDouble.New([0.,0.,1.,0.,1.,1.,0.,1.],4,2) - m.setCoords(coords) - vecs=DataArrayDouble.New([2.,3.,4.,5.,6.,7.],3,2) - expected1=[[2.,3.,3.,3.,3.,4.,2.,4.0],[4.,5.,5.,5.,5.,6.,4.,6.0],[6.,7.,7.,7.,7.,8.,6.,8.0]] - for pos,vec in enumerate(vecs): - m2=m.deepCpy() - m2.translate(vec) - self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.New(expected1[pos],4,2),1e-12)) - pass - for pos,vec in enumerate(vecs): - m2=m.deepCpy() - m2.translate(vec.buildDADouble()) - self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.New(expected1[pos],4,2),1e-12)) - pass - pass - - def testSwigBugNonRegressionZipDA(self): - angles=map(lambda x:pi/3*x,xrange(6)) - radius=3 - # - dad=DataArrayDouble.New(6, 2) - dad[:,0]=radius - dad[:,1]=angles - # - dad2=dad.fromPolarToCart() - dads=[dad2.deepCpy() for elt in 7*[None]] - # - translationToPerform=[[0.01,0.02],[3./2.*radius,-radius*sqrt(3.)/2],[3./2.*radius,radius*sqrt(3.)/2],[0.,radius*sqrt(3.)],[-3./2.*radius,radius*sqrt(3.)/2],[-3./2.*radius,-radius*sqrt(3.)/2],[0.,-radius*sqrt(3.)]] - for d,t in zip(dads,translationToPerform): - d+=t - pass - for elt in dads: - self.assertTrue(not dad2.isEqual(elt,1e-12)) - pass - for d,t in zip(dads,translationToPerform): - d-=t - pass - for elt in dads: - self.assertTrue(dad2.isEqual(elt,1e-12)) - pass - pass - - def testBuildSlice3D2(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - vec1=[-0.07,1.,0.07] - origin1=[1.524,1.4552,1.74768] - slice1,ids=mesh3D.buildSlice3D(origin1,vec1,1e-10); - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f.setTime(4.5,6,7) ; f.setMesh(mesh3D) - arr=DataArrayDouble(mesh3D.getNumberOfCells(),2) - arr.rearrange(1) ; arr.iota(2.) ; arr.rearrange(2) - f.setArray(arr) - f.checkCoherency() - expected1=DataArrayInt([1,3,4,7,9,10,13,15,16]) - self.assertTrue(expected1.isEqual(ids)) - arr2=arr[expected1] - # - f2=f.extractSlice3D(origin1,vec1,1e-10) - self.assertTrue(f2.getArray().isEqual(arr2,1e-12)); - self.assertTrue(slice1.isEqual(f2.getMesh(),1e-12)) - self.assertEqual(6,f2.getTime()[1]) ; self.assertEqual(7,f2.getTime()[2]) - self.assertAlmostEqual(4.5,f2.getTime()[0],12); - pass - - def testComputeTupleIdsToSelectFromCellIds1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_3() - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble(52,2) ; arr.rearrange(1) ; arr.iota(7.) ; arr.rearrange(2) - f.setArray(arr) - # - f2=f.buildSubPart([1,5,9]) - f2.checkCoherency() - cI=m.computeNbOfNodesPerCell() - cI.computeOffsets2() - sel=DataArrayInt([1,5,9]) - res=sel.buildExplicitArrByRanges(cI) - arr2=arr[res] - self.assertTrue(arr2.isEqual(DataArrayDouble([13,14,15,16,17,18,19,20,59,60,61,62,63,64,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110],15,2),1e-12)) - self.assertTrue(arr2.isEqual(f2.getArray(),1e-12)) - pass - - def testComputeSkin1(self): - arrX=DataArrayDouble([2.,3.4,5.6,7.7,8.0]) ; arrY=DataArrayDouble([2.,3.4,5.6,7.7,9.0,14.2]) - cmesh=MEDCouplingCMesh() ; cmesh.setCoordsAt(0,arrX) ; cmesh.setCoordsAt(1,arrY) - umesh=cmesh.buildUnstructured() - # - skin=umesh.computeSkin() - self.assertEqual(18,skin.getNumberOfCells()) - self.assertEqual(1,skin.getMeshDimension()) - self.assertTrue(skin.getCoords().getHiddenCppPointer()==umesh.getCoords().getHiddenCppPointer()) - self.assertEqual([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54],skin.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24],skin.getNodalConnectivity().getValues()) - ids=skin.computeFetchedNodeIds() - self.assertEqual([0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29],ids.getValues()) - part=umesh.buildFacePartOfMySelfNode(ids,True) - part.setName(skin.getName()); - self.assertTrue(part.isEqual(skin,1e-12)) - part2=part[1::2] - part[::2]=part2 - self.assertTrue(not part.isEqual(skin,1e-12)) - trad=part.zipConnectivityTraducer(0) - self.assertEqual(9,part.getNumberOfCells()) - self.assertEqual([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8],trad.getValues()) - pass - - def testUMeshSetPartOfMySelf2(self): - # resize with explicit ids list - m=MEDCouplingDataForTest.build2DTargetMesh_1() - self.assertEqual([3,4],m.getAllGeoTypes()) - part=m[[0,3,4]] - part.simplexize(0) - part2=part[[1,2,5]] - m[[0,3,4]]=part2 - self.assertEqual([3,0,4,1,3,1,4,2,3,4,5,2,3,6,7,4,3,7,5,4],m.getNodalConnectivity().getValues()) - self.assertEqual([0,4,8,12,16,20],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3],m.getAllGeoTypes()) - # no resize with explicit ids list - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[[0,3]] - part.convertAllToPoly() - m[[3,4]]=part - self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3,4,5],m.getAllGeoTypes()) - # resize with range ids - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[3:] - m[1:3]=part - self.assertEqual([4,0,3,4,1,4,6,7,4,3,4,7,8,5,4,4,6,7,4,3,4,7,8,5,4],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,10,15,20,25],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([4],m.getAllGeoTypes()) - # no resize with range ids - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[0::3] - part.convertAllToPoly() - m[3:]=part - self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3,4,5],m.getAllGeoTypes()) - # no resize with range ids negative direction - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[3::-3] - part.convertAllToPoly() - m[:-3:-1]=part - self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3,4,5],m.getAllGeoTypes()) - pass - - def testUnPolyze3(self): - coord=[0.0,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.0,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5] - conn=[1,2,5,4,-1,4,3,0,1,-1,2,0,3,5,-1,0,2,1,-1,4,5,3] - m=MEDCouplingUMesh.New("a mesh",3); - m.allocateCells(1); - m.insertNextCell(NORM_POLYHED,22,conn[0:22]) - m.finishInsertingCells(); - coords=DataArrayDouble(coord,6,3); - m.setCoords(coords); - m.checkCoherency(); - # - vol=m.getMeasureField(ON_CELLS); - self.assertEqual(1,vol.getArray().getNumberOfTuples()); - self.assertAlmostEqual(0.5,vol.getArray().getIJ(0,0),12) - # - m.unPolyze(); - # - self.assertEqual([NORM_PENTA6],m.getAllGeoTypes()) - self.assertTrue(DataArrayInt([0,7]).isEqual(m.getNodalConnectivityIndex())) - self.assertTrue(DataArrayInt([16,0,2,1,3,5,4]).isEqual(m.getNodalConnectivity())) - # - vol=m.getMeasureField(ON_CELLS); - self.assertEqual(1,vol.getArray().getNumberOfTuples()); - self.assertAlmostEqual(0.5,vol.getArray().getIJ(0,0),12) - pass - - def testKrSpatialDiscretization1(self): - srcPointCoordsX=[0.8401877171547095, 0.7830992237586059, 0.9116473579367843, 0.335222755714889, 0.2777747108031878, 0.4773970518621602, 0.3647844727918433, 0.9522297251747128, 0.6357117279599009, 0.1416025553558034] - srcFieldValsOnPoints=[2.129892434968836, 2.295320474540621, 1.931948594981134, 2.728013590937196, 2.715603240418478, 2.661778472822935, 2.695696990104364, 1.893710234970982, 2.529628016549284, 2.728432341300668] - targetPointCoordsX=[-0.5,-0.45,-0.4,-0.35,-0.3,-0.25,-0.2,-0.15,-0.1,-0.05,-6.93889390391e-17,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45] - targetFieldValsExpected=[2.975379475824351, 2.95613491917003, 2.936890362515361, 2.917645805861018, 2.898401249206574, 2.879156692552137, 2.859912135897732, 2.840667579243201, 2.821423022588731, 2.802178465934342, 2.78293390927989, 2.763689352625457, 2.744444795971001, 2.725209522098197, 2.709077577124666, 2.706677252549218, 2.727467797847971, 2.713338094723676, 2.671342424824244, 2.664877370146978, 2.653840141412181, 2.619607861392791, 2.569777214476479, 2.513263929794591, 2.450732752808528, 2.368313560985155, 2.250909795670307, 2.098194272085416, 1.954257891732065, 1.895040660973802, 1.865256788315972, 1.835475248687992, 1.80569370905998, 1.775912169431971, 1.746130629803976, 1.716349090175918, 1.686567550547855, 1.656786010919941, 1.627004471291988, 1.597222931663817] - coeffsExpected=DataArrayDouble.New([52.238272642008695, 26.186513281350948, -173.42106377948534, 324.56733663875184, -104.64968873410248, 34.375030568158316, -256.12372208190425, 105.2292032463934, -16.239907618144965, 7.838025836978943, 2.621910745077291, -0.4902609628247241]) - # - nbOfInputPoints=10; - f=MEDCouplingFieldDouble.New(ON_NODES_KR,ONE_TIME); - srcArrX=DataArrayDouble.New(srcPointCoordsX,nbOfInputPoints,1); - cmesh=MEDCouplingCMesh.New("aMesh"); - cmesh.setCoordsAt(0,srcArrX); - umesh=cmesh.buildUnstructured(); - f.setMesh(umesh); - srcVals=DataArrayDouble.New(srcFieldValsOnPoints,nbOfInputPoints,1); - f.setArray(srcVals); - f.checkCoherency(); - # - res0=f.getValueOn(targetPointCoordsX[:1]); - self.assertAlmostEqual(targetFieldValsExpected[0],res0[0],10) - # - valuesToTest=f.getValueOnMulti(targetPointCoordsX); - self.assertEqual(40,valuesToTest.getNumberOfTuples()); - self.assertEqual(1,valuesToTest.getNumberOfComponents()); - for i in xrange(40): - self.assertAlmostEqual(targetFieldValsExpected[i],valuesToTest.getIJ(i,0),10) - pass - fd=f.getDiscretization() - del f - self.assertTrue(isinstance(fd,MEDCouplingFieldDiscretizationKriging)) - coeffs,isDrift=fd.computeVectorOfCoefficients(umesh,srcVals) - self.assertEqual(2,isDrift) - self.assertTrue(coeffsExpected.isEqual(coeffs,1e-8)) - # - pass - - def testDuplicateEachTupleNTimes1(self): - d=DataArrayDouble.New([9.,8.,7.,6.],4,1) ; d.setInfoOnComponents(["mass [kg]"]) ; d.setName("aname") - d2=d.duplicateEachTupleNTimes(3) - self.assertTrue(d2.isEqualWithoutConsideringStr(DataArrayDouble.New([9.,9.,9.,8.,8.,8.,7.,7.,7.,6.,6.,6.],4*3,1),1e-14)) - self.assertEqual("aname",d2.getName()) - self.assertEqual(["mass [kg]"],d2.getInfoOnComponents()) - # - d=DataArrayInt.New([9,8,7,6],4,1) ; d.setInfoOnComponents(["mass [kg]"]) ; d.setName("aname") - d2=d.duplicateEachTupleNTimes(3) - self.assertTrue(d2.isEqualWithoutConsideringStr(DataArrayInt.New([9,9,9,8,8,8,7,7,7,6,6,6],4*3,1))) - self.assertEqual("aname",d2.getName()) - self.assertEqual(["mass [kg]"],d2.getInfoOnComponents()) - pass - - def testSwigComputeTupleIdsNearTuples1(self): - da=DataArrayDouble([5.,6.,-5.,-6.,5.,-6.,-5.,6.,5.,6.],5,2) - arr,arrI=da.computeTupleIdsNearTuples(DataArrayDouble([5.,-6.,5.,6.,-5.,-6.],3,2),1e-10) - self.assertEqual([2,0,4,1],arr.getValues()) - self.assertEqual([0,1,3,4],arrI.getValues()) - arr,arrI=da.computeTupleIdsNearTuples([5.,-6.,5.,6.,-5.,-6.],1e-10) - self.assertEqual([2,0,4,1],arr.getValues()) - self.assertEqual([0,1,3,4],arrI.getValues()) - expected0=[[2],[0,4],[1]] - expected1=[[0,1],[0,2],[0,1]] - for pos,it in enumerate(DataArrayDouble([5.,-6.,5.,6.,-5.,-6.],3,2)): - arr,arrI=da.computeTupleIdsNearTuples(it,1e-10) - self.assertEqual(expected0[pos],arr.getValues()) - self.assertEqual(expected1[pos],arrI.getValues()) - pass - pass - - def testSwigDataTupleIOp1(self): - d=DataArrayDouble(10,1) - d.iota(7.) - for elt in d: - elt+=2. - pass - toTest=DataArrayDouble([9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - for elt in d: - elt-=2. - pass - toTest=DataArrayDouble([7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - for elt in d: - elt*=2. - pass - toTest=DataArrayDouble([14.0,16.0,18.0,20.0,22.0,24.0,26.0,28.0,30.0,32.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - for elt in d: - elt/=2. - pass - toTest=DataArrayDouble([7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - # - d=DataArrayInt(10,1) - d.iota(7) - for elt in d: - elt+=2 - pass - self.assertEqual(d.getValues(),[9,10,11,12,13,14,15,16,17,18]) - for elt in d: - elt-=2 - pass - self.assertEqual(d.getValues(),[7,8,9,10,11,12,13,14,15,16]) - for elt in d: - elt*=2 - pass - self.assertEqual(d.getValues(),[14,16,18,20,22,24,26,28,30,32]) - for elt in d: - elt/=2 - pass - self.assertEqual(d.getValues(),[7,8,9,10,11,12,13,14,15,16]) - for elt in d: - elt%=3 - pass - self.assertEqual(d.getValues(),[1,2,0,1,2,0,1,2,0,1]) - pass - - def testIntersect2DMeshesTmp5(self): - coords=DataArrayDouble.New([41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818],188,2) - conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175],540) - connI=DataArrayInt.New([0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540],61) - # - m1=MEDCouplingUMesh.New("Fix",2); - m1.setCoords(coords); - m1.setConnectivity(conn,connI,True); - # - coords=DataArrayDouble([46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59],42,2) - # connectivity - conn=DataArrayInt([8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36],72); - conn.setName(""); - connI=DataArrayInt([0,9,18,27,36,45,54,63,72],9) - m2=MEDCouplingUMesh.New("Mobile",2); - m2.setCoords(coords); - m2.setConnectivity(conn,connI,True); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); - self.assertEqual(105,m3.getNumberOfCells()); - self.assertEqual(105,d1.getNumberOfTuples()); - self.assertEqual(105,d2.getNumberOfTuples()); - self.assertEqual(704,m3.getNumberOfNodes()); - # - areaExpected=[-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241] - expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59] - expected2=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] - f3=m3.getMeasureField(ON_CELLS).getArray().getValues(); - for i in xrange(105): - self.assertAlmostEqual(areaExpected[i],f3[i],10) - pass - self.assertEqual(expected1,d1.getValues()) - self.assertEqual(expected2,d2.getValues()) - pass - - def testSwig2Intersect2DMeshesQuadra1(self): - import cmath - def createDiagCircle(lX, lY, R, cells=[0,1]): - """ A circle in a square box, cut along the diagonal. - """ - c = [] - for i in range(8): - c.append(cmath.rect(R, i*pi/4)) - - coords = [0.0,0.0, c[3].real,c[3].imag, -lX/2.0, lY/2.0, - 0.0, lY/2.0, lX/2.0,lY/2.0, lX/2.0,0.0, - # 6 7 8 - lX/2.0,-lY/2.0, c[7].real,c[7].imag, c[1].real,c[1].imag, - # 9 10 11 - c[5].real,c[5].imag, -lX/2.0,-lY/2.0, 0.0, -lY/2.0, - # 12 13 14 - -lX/2.0,0.0, 0.0,0.0, 0.0, 0.0] - # Points 13 (reps. 14) are average of points (6,7) (resp (1,2)) - coords[13*2] = 0.5*(coords[6*2]+coords[7*2]) - coords[13*2+1] = 0.5*(coords[6*2+1]+coords[7*2+1]) - coords[14*2] = 0.5*(coords[1*2]+coords[2*2]) - coords[14*2+1] = 0.5*(coords[1*2+1]+coords[2*2+1]) - connec = [1,7,8,0] # half circle up right - connec3 = [6,7,1,2,4,13,8,14,3,5] - - baseMesh = MEDCouplingUMesh.New("box_circle", 2) - baseMesh.allocateCells(2) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - meshCoords.setInfoOnComponents(["X [au]", "Y [au]"]) - baseMesh.setCoords(meshCoords) - - if 0 in cells: - baseMesh.insertNextCell(NORM_QPOLYG, connec) - if 1 in cells: - baseMesh.insertNextCell(NORM_QPOLYG, connec3) - baseMesh.finishInsertingCells() - baseMesh.checkCoherency() - return baseMesh - - eps = 1.0e-7 - m1 = createDiagCircle(1.0, 1.0, 0.5*0.90, cells=[0,1]) - m2 = createDiagCircle(1.0, 1.0, 0.5*0.95, cells=[0]) - m3, _, _= MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) - m3.mergeNodes(eps) - m3.convertDegeneratedCells() - m3.zipCoords() - m4 = m3.deepCpy() - m5, _, _ = MEDCouplingUMesh.Intersect2DMeshes(m3, m4, eps) - m5.mergeNodes(eps) - # Check coordinates: - self.assertTrue(m3.getCoords().isEqual(m5.getCoords(), eps)) - - def testIntersect2DMeshesTmp7(self): - eps = 1.0e-8 - coords = [-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5] - connec = range(4) - m1 = MEDCouplingUMesh.New("box", 2) - m1.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - m1.setCoords(meshCoords) - m1.insertNextCell(NORM_POLYGON, connec) - m1.finishInsertingCells() - - m2 = MEDCouplingDataForTest.buildCircle(0.25, 0.2, 0.4) - # Was looping indefinitly: - m_intersec, resToM1, resToM2 = MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) - m_intersec.zipCoords() - coo_tgt = DataArrayDouble([-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, - -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, - -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5, - -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613], 17 ,2) - conn_tgt = [32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16] - connI_tgt = [0, 9, 22] - res1_tgt = [0, 0] - res2_tgt = [0, -1] - self.assert_(coo_tgt.isEqualWithoutConsideringStr(m_intersec.getCoords(), 1e-12)) - self.assertEqual(conn_tgt, m_intersec.getNodalConnectivity().getValues()) - self.assertEqual(connI_tgt, m_intersec.getNodalConnectivityIndex().getValues()) - self.assertEqual(res1_tgt, resToM1.getValues()) - self.assertEqual(res2_tgt, resToM2.getValues()) - - def testDAIBuildUnique1(self): - d=DataArrayInt([1,2,2,3,3,3,3,4,5,5,7,7,7,19]) - e=d.buildUnique() - self.assertTrue(e.isEqual(DataArrayInt([1,2,3,4,5,7,19]))) - pass - - def testDAIPartitionByDifferentValues1(self): - d=DataArrayInt([1,0,1,2,0,2,2,-3,2]) - expected=[[-3,[7]],[0,[1,4]],[1,[0,2]],[2,[3,5,6,8]]] - for i,elt in enumerate(zip(*d.partitionByDifferentValues())): - self.assertEqual(expected[i][0],elt[1]) - self.assertEqual(expected[i][1],elt[0].getValues()) - pass - pass - - def testFieldGaussMultiDiscPerType1(self): - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2) - mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords) - mQ8.allocateCells(1) - mQ8.insertNextCell(NORM_QUAD8,range(8)) - mQ8.finishInsertingCells() - mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords) - mQ4.allocateCells(1) - mQ4.insertNextCell(NORM_QUAD4,range(4)) - mQ4.finishInsertingCells() - mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords) - mT3.allocateCells(1) - mT3.insertNextCell(NORM_TRI3,range(3)) - mT3.finishInsertingCells() - - tr=[[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.],[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[22.,4.]] - ms=2*[mQ4]+7*[mQ8]+11*[mT3] - ms[:]=(elt.deepCpy() for elt in ms) - for m,t in zip(ms,tr): - d=m.getCoords() ; d+= t - pass - m=MEDCouplingUMesh.MergeUMeshes(ms) - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME) - f.setMesh(m) - # throw because cell 0,1 are QUAD4 and cell 3 is QUAD8 - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,[0,1,3],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([3,2,5],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9],[0.8,0.05,0.15]) - f.setGaussLocalizationOnCells([4,6,8,7],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9,-0.1,0.3],[0.7,0.05,0.15,0.1]) - f.setGaussLocalizationOnCells([9,10,11,12,13],[0.,0.,1.,0.,1.,1.],[0.4,0.4],[1.]) - f.setGaussLocalizationOnCells([14,15,16,17,18,19],[0.,0.,1.,0.,1.,1.],[0.4,0.4,0.14,0.16],[0.22,0.78]) - self.assertEqual(46,f.getNumberOfTuplesExpected()) - vals=DataArrayDouble.New(46*3,1) ; vals.iota(7.7) ; vals.rearrange(3) - f.setArray(vals) - f.checkCoherency() - #f.getLocalizationOfDiscr() - self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneType,NORM_QUAD8) #throw because several loc - self.assertEqual([1,2],f.getGaussLocalizationIdsOfOneType(NORM_QUAD8)) - self.assertEqual([0,0,1,1,2,1,2,2,2,3,3,3,3,3,4,4,4,4,4,4],f.getDiscretization().getArrayOfDiscIds().getValues()) - fc=f[[1,2,3,8]] - fc.checkCoherency() - self.assertTrue(DataArrayDouble([13.7,14.7,15.7,16.7,17.7,18.7,19.7,20.7,21.7,22.7,23.7,24.7,25.7,26.7,27.7,28.7,29.7,30.7,31.7,32.7,33.7,34.7,35.7,36.7,82.7,83.7,84.7,85.7,86.7,87.7,88.7,89.7,90.7,91.7,92.7,93.7],12,3).isEqual(fc.getArray(),1e-10)) - fc.renumberCells([3,2,0,1]) - self.assertTrue(DataArrayDouble([28.7, 29.7, 30.7, 31.7, 32.7, 33.7, 34.7, 35.7, 36.7, 82.7, 83.7, 84.7, 85.7, 86.7, 87.7, 88.7, 89.7, 90.7, 91.7, 92.7, 93.7, 19.7, 20.7, 21.7, 22.7, 23.7, 24.7, 25.7, 26.7, 27.7, 13.7, 14.7, 15.7, 16.7, 17.7, 18.7],12,3).isEqual(fc.getArray(),1e-10)) - fc.getArray() - pass - - def testSwigRotate(self): - d=DataArrayDouble([1.,2.,3.,4.,6.,5.],2,3) - MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[0.,1.,0.],1.5707963267948966,d) - self.assertTrue(d.isEqual(DataArrayDouble([3.,2.,-1.,5.,6.,-4.],2,3),1e-12)) - d=DataArrayDouble([1.,2.,3.,4.,6.,5.],3,2) - MEDCouplingPointSet.Rotate2DAlg([0.,0.],1.5707963267948966,d) - self.assertTrue(d.isEqual(DataArrayDouble([-2.,1.,-4.,3.,-5.,6.],3,2),1e-12)) - pass - - def testSwigCMeshProtection(self): - cm=MEDCouplingCMesh() - self.assertRaises(InterpKernelException,cm.setCoordsAt,0,DataArrayDouble([4.,4.5,6.,7.],2,2)) - self.assertRaises(InterpKernelException,cm.setCoords,DataArrayDouble([4.,4.5,6.,7.],2,2)) - pass - - def testSwigCellsInBoundingBox1(self): - m3D=MEDCouplingDataForTest.build3DExtrudedUMesh_1()[0] - self.assertTrue(m3D.getCellsInBoundingBox([(0,3),(0,3),(0,1)],-1e-12).isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertRaises(InterpKernelException,m3D.getCellsInBoundingBox,[(0,3,0),(3,0,1)],-1e-12) - pass - - def testDAICheckMonotonic1(self): - data1=[-1,0,2,2,4,5] - data2=[6,2,0,-8,-9,-56] - data3=[-1,0,3,2,4,6] - data4=[7,5,2,3,0,-6] - d=DataArrayInt.New(data1); - self.assertTrue(d.isMonotonic(True)); - self.assertTrue(not d.isMonotonic(False)); - d.checkMonotonic(True); - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - d=DataArrayInt.New(data2); - self.assertTrue(d.isMonotonic(False)); - self.assertTrue(not d.isMonotonic(True)); - d.checkMonotonic(False); - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - d=DataArrayInt.New(data3); - self.assertTrue(not d.isMonotonic(False)); - self.assertTrue(not d.isMonotonic(True)); - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - d=DataArrayInt.New(data4); - self.assertTrue(not d.isMonotonic(False)); - self.assertTrue(not d.isMonotonic(True)); - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - d=DataArrayInt.New(0,1) - self.assertTrue(d.isMonotonic(True)); - self.assertTrue(d.isMonotonic(False)); - d.checkMonotonic(True); - d.checkMonotonic(False); - d=DataArrayInt.New(data4,3,2);#throw because nbComp!=1 - self.assertRaises(InterpKernelException,d.isMonotonic,True) - self.assertRaises(InterpKernelException,d.isMonotonic,False) - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - pass - - def testSwigDASetItemOnEmpty1(self): - d=DataArrayInt(0,1) - isThrow=False - try: - d[0:1000:2]=4 - except InterpKernelException as e: - isThrow=True - pass - self.assertTrue(isThrow) - d[:]=4 - d[::2]=5 - # - d=DataArrayDouble(0,1) - isThrow=False - try: - d[0:1000:2]=4 - except InterpKernelException as e: - isThrow=True - pass - self.assertTrue(isThrow) - d[:]=4 - d[::2]=5 - d=DataArrayInt([],0,1) - d2=DataArrayInt(0) - self.assertTrue(d2.isEqual(d)) - d=DataArrayDouble([],0,1) - d2=DataArrayDouble(0) - self.assertTrue(d2.isEqual(d,1e-12)) - pass - - def testSwigDAITransformWithIndArr1(self): - arr=DataArrayInt([0,4,5,1]) - d=DataArrayInt([7,8,9,10]) - self.assertRaises(InterpKernelException,arr.transformWithIndArr,d) - pass - - def testIntersect2DMeshesTmp6(self): - # coordinates - coords=DataArrayDouble.New([2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15],8,2); - # connectivity - conn=DataArrayInt.New([8,0,3,5,1,4,6,7,2]) - connI=DataArrayInt.New([0,9]); - m1=MEDCouplingUMesh.New("Fixe",2); - m1.setCoords(coords); - m1.setConnectivity(conn,connI,True); - # - coords=DataArrayDouble.New([-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839],13,2); - # connectivity - conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12]); - connI=DataArrayInt.New([0,9,18]); - # - m2=MEDCouplingUMesh.New("Mobile",2); - m2.setCoords(coords); - m2.setConnectivity(conn,connI,True); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); - self.assertTrue(d1.isEqual(DataArrayInt([0,0,0,0]))); - self.assertTrue(d2.isEqual(DataArrayInt([0,1,-1,-1]))); - self.assertEqual(4,m3.getNumberOfCells()); - self.assertEqual(4,d1.getNumberOfTuples()); - self.assertEqual(4,d2.getNumberOfTuples()); - self.assertEqual(43,m3.getNumberOfNodes()); - dI,areMerged,newNbOfNodes=m3.mergeNodes(1e-12) - self.assertEqual(35,m3.getNumberOfNodes()); - m3.zipCoords(); - self.assertEqual(23,m3.getNumberOfNodes()); - # - f=m3.getMeasureField(True); - valuesExpected=DataArrayDouble([1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694]) - self.assertTrue(f.getArray().isEqual(valuesExpected,1e-12)) - pass - - def testDAPushBack(self): - d=DataArrayDouble(0,1) - for i in xrange(8): - d.pushBackSilent(i) - pass - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),8) - d.pushBackSilent(4.44) - self.assertEqual(d.getNumberOfTuples(),9) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) - e=d.deepCpy() - self.assertEqual(e.getNumberOfTuples(),9) - self.assertEqual(e.getNbOfElemAllocated(),9) - self.assertTrue(e.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) - self.assertAlmostEqual(d.popBackSilent(),4.44,12) - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.]),1e-12)) - f=DataArrayDouble() - f.reserve(1000) - f.pushBackSilent(4.) - self.assertTrue(f.isEqual(DataArrayDouble([4.]),1e-12)) - self.assertEqual(f.getNumberOfTuples(),1) - self.assertEqual(f.getNbOfElemAllocated(),1000) - ff=f[:] - self.assertTrue(ff.isEqual(DataArrayDouble([4.]),1e-12)) - self.assertEqual(ff.getNumberOfTuples(),1) - self.assertEqual(ff.getNbOfElemAllocated(),1) - d=DataArrayDouble() - d.pushBackSilent(4.44) - d.pushBackSilent(5.55) - d.pushBackSilent(6.66) - self.assertTrue(d.isEqual(DataArrayDouble([4.44,5.55,6.66]),1e-12)) - # - d=DataArrayInt(0,1) - for i in xrange(8): - d.pushBackSilent(i) - pass - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),8) - d.pushBackSilent(444) - self.assertEqual(d.getNumberOfTuples(),9) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) - e=d.deepCpy() - self.assertEqual(e.getNumberOfTuples(),9) - self.assertEqual(e.getNbOfElemAllocated(),9) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) - self.assertEqual(d.popBackSilent(),444) - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - f=DataArrayInt() - f.reserve(1000) - f.pushBackSilent(4) - self.assertTrue(f.isEqual(DataArrayInt([4]))) - self.assertEqual(f.getNumberOfTuples(),1) - self.assertEqual(f.getNbOfElemAllocated(),1000) - ff=f[:] - self.assertTrue(ff.isEqual(DataArrayInt([4]))) - self.assertEqual(ff.getNumberOfTuples(),1) - self.assertEqual(ff.getNbOfElemAllocated(),1) - d=DataArrayInt() - d.pushBackSilent(444) - d.pushBackSilent(555) - d.pushBackSilent(666) - self.assertTrue(d.isEqual(DataArrayInt([444,555,666]))) - # - d=DataArrayInt() - d.alloc(10,1) - d.setInfoOnComponent(0,"ABC") - d.setName("dEf") - d.iota(7) - e=DataArrayInt([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(10,d.getNbOfElemAllocated()) - d.pushBackSilent(55) - e=DataArrayInt([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(20,d.getNbOfElemAllocated()) - d.reserve(4) - e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(4,d.getNbOfElemAllocated()) - d.pushBackSilent(5) - e=DataArrayInt([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertEqual(5,d.popBackSilent()) - e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertRaises(OverflowError,d.reserve,-1) - e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(8,d.getNbOfElemAllocated()) - d.reserve(0) - e=DataArrayInt([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e)) - self.assertEqual(0,d.getNbOfElemAllocated()) - # - d=DataArrayDouble() - d.alloc(10,1) - d.setInfoOnComponent(0,"ABC") - d.setName("dEf") - d.iota(7) - e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(10,d.getNbOfElemAllocated()) - d.pushBackSilent(55) - e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(20,d.getNbOfElemAllocated()) - d.reserve(4) - e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(4,d.getNbOfElemAllocated()) - d.pushBackSilent(5) - e=DataArrayDouble([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertEqual(5.,d.popBackSilent()) - e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertRaises(OverflowError,d.reserve,-1) - e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(8,d.getNbOfElemAllocated()) - d.reserve(0) - e=DataArrayDouble([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(0,d.getNbOfElemAllocated()) - pass - - def testDAIBuildSubstractionOptimized1(self): - da1=DataArrayInt.New([1,3,5,6,7,9,13]) - da2=DataArrayInt.New([3,5,9]) - da3=DataArrayInt.New([1,3,5]) - da4=DataArrayInt.New([1,3,5,6,7,9,13]) - # - a=da1.buildSubstractionOptimized(da2); - self.assertTrue(a.isEqual(DataArrayInt([1,6,7,13]))); - # - a=da1.buildSubstractionOptimized(da3); - self.assertTrue(a.isEqual(DataArrayInt([6,7,9,13]))); - # - a=da1.buildSubstractionOptimized(da4); - self.assertTrue(a.isEqual(DataArrayInt([]))); - pass - - def testDAIIsStrictlyMonotonic1(self): - da1=DataArrayInt.New([1,3,5,6,7,9,13]) - self.assertTrue(da1.isStrictlyMonotonic(True)); - da1.checkStrictlyMonotonic(True); - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([1,3,5,6,6,9,13]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([1,3,5,6,5,9,13]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([13,9,7,6,5,3,1]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(da1.isStrictlyMonotonic(False)); - da1.checkStrictlyMonotonic(False); - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - # - da1=DataArrayInt.New([13,9,6,6,5,3,1]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - # - da1=DataArrayInt.New([13,9,5,6,5,3,1]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([]) - self.assertTrue(da1.isStrictlyMonotonic(True)); - da1.checkStrictlyMonotonic(True); - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(da1.isStrictlyMonotonic(False)); - da1.checkStrictlyMonotonic(False); - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - # - da1=DataArrayInt.New([13]) - self.assertTrue(da1.isStrictlyMonotonic(True)); - da1.checkStrictlyMonotonic(True); - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(da1.isStrictlyMonotonic(False)); - da1.checkStrictlyMonotonic(False); - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - pass - - def testFindAndCorrectBadOriented3DCells1(self): - nbOfDisc=20 - vects=([0,0,-1],[0.3,0.7,0.2],[-0.3,0.7,0.2],[-0.3,-0.7,0.2]) - # - m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented - m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented - m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented - m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented - m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0) - self.assertRaises(InterpKernelException,m4.insertNextCell,NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11,12]); - m4.insertNextCell(NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11]); #Well oriented - c0=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) ; m0.setCoords(c0) - c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.],5,3) ; m1.setCoords(c1) - c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,0.,1.],6,3) ; m2.setCoords(c2) - c3=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; m3.setCoords(c3) - c4=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.8,0.,0.,0.45,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.,0.8,0.,1.,0.45,0.,1.],12,3) ; m4.setCoords(c4) - m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) - expected1=DataArrayDouble([0.16666666666666666,0.3333333333333333,0.5,1.,1.]) - for v in vects: - for i in xrange(nbOfDisc): - mm=m.deepCpy() - mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) - mm2=mm.deepCpy() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - self.assertTrue(mm.findAndCorrectBadOriented3DCells().empty()) - self.assertTrue(mm.isEqual(mm2,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - mm.convertAllToPoly() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - pass - pass - # - mOK=m.deepCpy() - m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,2,1,3]); #Not well oriented - m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented - m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented - m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,3,2,1,4,7,6,5]); #Not well oriented - m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,[0,5,4,3,2,1,6,11,10,9,8,7]); #Not well oriented - m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) - m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) - expected2=DataArrayDouble([-0.16666666666666666,0.3333333333333333,0.5,-1.,-1.]) - for v in vects: - for i in xrange(nbOfDisc): - mm=m.deepCpy() - mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) - mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() - self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected2,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected2,1e-14)) - self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([0,3,4]))) - mOK.setCoords(mm.getCoords()) - self.assertTrue(mm.isEqual(mOK,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - mmm=mm.deepCpy() - self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) - mm.convertAllToPoly() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - pass - pass - # - m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented - m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,3,2,1,4]); #Not well oriented - m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,2,1,3,5,4]); #Not well oriented - m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented - m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,range(12)); #Well oriented - m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) - m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) - expected3=DataArrayDouble([0.16666666666666666,-0.3333333333333333,-0.5,1.,1.]) - for v in vects: - for i in xrange(nbOfDisc): - mm=m.deepCpy() - mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) - mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() - self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected3,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected3,1e-14)) - self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([1,2]))) - mOK.setCoords(mm.getCoords()) - self.assertTrue(mm.isEqual(mOK,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - mmm=mm.deepCpy() - self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) - mm.convertAllToPoly() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - pass - pass - pass - - def testSwig2CellOrientation1(self): - coords=DataArrayDouble([-0.21606,-0.10803,0.29999999999999999,-0.21606,-0.10803,0.37700000000000006,0,-0.10803,0.29999999999999999,0,-0.10803,0.37700000000000006,0,0.10803,0.29999999999999999,0,0.10803,0.37700000000000006,-0.21606,0.10803,0.29999999999999999,-0.21606,0.10803,0.37700000000000006,0,0.03601,0.29999999999999999,0,0.03601,0.37700000000000006,0,-0.03601,0.29999999999999999,0,-0.03601,0.37700000000000006],12,3) - conn=[[0,2,10,8,4,6],[1,3,11,9,5,7],[0,1,3,2],[2,3,11,10],[10,11,9,8],[8,9,5,4],[4,5,7,6],[6,7,1,0]] - for i in xrange(256): - mesh=MEDCouplingUMesh("FluidMesh_1",3); - mesh.allocateCells(0) - conn2=[elt[:] for elt in conn] - code=bin(i)[2:] ; code='0'*(8-len(code))+code - for face,rev in zip(conn2,code): - if bool(int(rev)): - face.reverse() - pass - pass - conn3=[elt+[-1] for elt in conn2] - conn3=sum(conn3,[])[:-1] - mesh.insertNextCell(NORM_POLYHED,conn3) - mesh.setCoords(coords) - mesh.orientCorrectlyPolyhedrons() - self.assertTrue(mesh.getBarycenterAndOwner().isEqual(DataArrayDouble([-0.10803,0.,0.3385],1,3),1e-12)) - pass - pass - - def testSwig2CheckConsecutiveCellTypesForMEDFileFrmt1(self): - m1=MEDCouplingUMesh("",2) ; m1.allocateCells(0) - m1.insertNextCell(NORM_QUAD4,[0,1,2,3]) - m1.insertNextCell(NORM_TRI3,[0,1,2]) - d=DataArrayDouble(4,3) ; d[:]=0. - m1.setCoords(d) - self.assertTrue(m1.checkConsecutiveCellTypes()) - self.assertTrue(not m1.checkConsecutiveCellTypesForMEDFileFrmt()) - m1.renumberCells([1,0]) - self.assertTrue(m1.checkConsecutiveCellTypes()) - self.assertTrue(m1.checkConsecutiveCellTypesForMEDFileFrmt()) - pass - - def testSwig2DAAccumulate1(self): - d=DataArrayInt(10) ; d.iota(0) - self.assertEqual([45],d.accumulate()) - self.assertEqual(45,d.accumulate(0)) - d=DataArrayInt(30) ; d.iota(0) ; d.rearrange(3) - self.assertEqual([135,145,155],d.accumulate()) - self.assertEqual(135,d.accumulate(0)) - self.assertEqual(145,d.accumulate(1)) - self.assertEqual(155,d.accumulate(2)) - d=DataArrayDouble(10) ; d.iota(0.) - self.assertEqual([45.],d.accumulate()) - self.assertEqual(45.,d.accumulate(0)) - d=DataArrayDouble(30) ; d.iota(0) ; d.rearrange(3) - self.assertEqual([135.,145.,155.],d.accumulate()) - self.assertEqual(135.,d.accumulate(0)) - self.assertEqual(145.,d.accumulate(1)) - self.assertEqual(155.,d.accumulate(2)) - pass - - def testSwig2UMeshDistanceToMesh1(self): - m=MEDCouplingUMesh("toto",2) - coords=DataArrayDouble([2.3,3.4,5.6,6.5,-4.3,3.2,-9.8,7.6,-5.4],3,3) - m.setCoords(coords) - m.allocateCells(0) - m.insertNextCell(NORM_TRI3,[0,1,2]) - a,b=m.distanceToPoint([-0.335,2.27,1.21]) - self.assertEqual(0,b) - self.assertAlmostEqual(0.022360988100374124,a,14); - a,b=m.distanceToPoint(DataArrayDouble([-0.335,2.27,1.21],1,3)) - self.assertEqual(0,b) - self.assertAlmostEqual(0.022360988100374124,a,14); - a,b=coords.distanceToTuple([-0.335,2.27,1.21]) - self.assertAlmostEqual(5.243302871282566,a,14) - self.assertEqual(0,b) - # - m=MEDCouplingUMesh("toto",2) - coords=DataArrayDouble([0.,0.,0., 8.,0.,0., 8.,8.,0., 0.,8.,0.],4,3) - m.setCoords(coords) - m.allocateCells(0) - m.insertNextCell(NORM_QUAD4,[0,1,2,3]) - m.checkCoherency2() - self.assertEqual([4,0,1,2,3],m.getNodalConnectivity().getValues()) - a,b=m.distanceToPoint([5.,2.,0.1]) - self.assertAlmostEqual(0.1,a,14) ; self.assertEqual(0,b) - a,b=m.distanceToPoint([5.,-2.,4.]) - self.assertAlmostEqual(sqrt(2*2+4*4),a,14) ; self.assertEqual(0,b) - m.allocateCells(0) - m.insertNextCell(NORM_POLYGON,[0,1,2,3]) - m.checkCoherency2() - self.assertEqual([5,0,1,2,3],m.getNodalConnectivity().getValues()) - a,b=m.distanceToPoint([11.,3.,4.]) - self.assertAlmostEqual(sqrt(3*3+4*4),a,14) ; self.assertEqual(0,b) - a,b=m.distanceToPoint([4.,12.,5.]) - self.assertAlmostEqual(sqrt(4*4+5*5),a,14) ; self.assertEqual(0,b) - d=DataArrayDouble([-1.2,3.,2.],1,3) - for elt in d: - a,b=m.distanceToPoint(d) - self.assertAlmostEqual(sqrt(1.2*1.2+2*2),a,14) ; self.assertEqual(0,b) - pass - # - m=MEDCouplingUMesh("toto",1) - coords=DataArrayDouble([0.,0.,4.,0.,0.,4.],3,2) ; m.setCoords(coords) - m.allocateCells(0) ; m.insertNextCell(NORM_SEG2,[0,1]) ; m.insertNextCell(NORM_SEG2,[1,2]) - a,b=m.distanceToPoint([-0.1,4.1]) - self.assertAlmostEqual(0.14142135623730925,a,14) # b==1 self.assertEqual(2,c) - a,b=m.distanceToPoint([0.,3.9]) - self.assertAlmostEqual(0.07071067811865482,a,14) ; self.assertEqual(1,b) # self.assertEqual(2,c) - pass - - def testSwig2NonRegressionPartitionBySpreadZone1(self): - m=MEDCouplingCMesh() - arr=DataArrayDouble(6) ; arr.iota(0.) - m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - mPart=m[50,80,85,87,92,122] - zones=mPart.partitionBySpreadZone() - self.assertEqual(4,len(zones)) - self.assertTrue(zones[0].isEqual(DataArrayInt([0]))) - self.assertTrue(zones[1].isEqual(DataArrayInt([1,2]))) - self.assertTrue(zones[2].isEqual(DataArrayInt([3,4]))) - self.assertTrue(zones[3].isEqual(DataArrayInt([5]))) - # - n,ni=m.computeNeighborsOfCells() - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(0,n,ni) - self.assertEqual(13,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed([1],n,ni) - self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed((2,),n,ni) - self.assertEqual(11,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(DataArrayInt([3]),n,ni) - self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - pass - - def testSwigUMeshInsertNextCell1(self): - m=MEDCouplingUMesh("toto",2) - # - coords=DataArrayDouble([0.,0.,1.,1.,1.,0.]) ; m.setCoords(coords) - da=DataArrayInt([0,1,2]) - m.allocateCells(0) - for i in xrange(5): - m.insertNextCell(NORM_TRI3,da) - pass - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) - # - da=DataArrayInt([0,1,2,3]) - m.allocateCells(0) - for i in xrange(5): - m.insertNextCell(NORM_TRI3,3,da) - pass - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) - # - da=DataArrayInt([0,1]) - m.allocateCells(0) - self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,3,da) - # - da=DataArrayInt([0,1,2,0,1,3,0,1,4,0,1,5,0,1,6],5,3) - m.allocateCells(0) - for t in da: - m.insertNextCell(NORM_TRI3,t) - pass - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,3,3,0,1,4,3,0,1,5,3,0,1,6]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) - self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,None) - pass - - def testSwigCurveLinearMesh1(self): - m=MEDCouplingCurveLinearMesh("toto") - m.setNodeGridStructure([2,3]) - coords=DataArrayDouble([0.,0., 2.,0., 0.,1., 1.9,1.1, 0.3,1.9, 2.2,2.1],6,2) - m.setCoords(coords) - m.checkCoherency() - m0=m.deepCpy() - self.assertTrue(m0.isEqual(m,1e-12)) - m.getCoords().setInfoOnComponents(["X [m]","Y [m]"]) - self.assertTrue(not m0.isEqual(m,1e-12)) - m0=m.deepCpy() - self.assertTrue(m0.isEqual(m,1e-12)) - self.assertEqual(m.getNodeGridStructure(),(2,3)) - pass - - def testSimplexize3(self): - m=MEDCouplingUMesh("toto",3) - m.allocateCells(0) - m.insertNextCell(NORM_TETRA4,[0,1,2,3]) - self.assertEqual([NORM_TETRA4],m.getAllGeoTypesSorted()) - m.insertNextCell(NORM_HEXA8,[4,5,6,7,8,9,10,11]) - self.assertEqual([NORM_TETRA4,NORM_HEXA8],m.getAllGeoTypesSorted()) - m.insertNextCell(NORM_HEXA8,[12,13,14,15,16,17,18,19]) - self.assertEqual([NORM_TETRA4,NORM_HEXA8],m.getAllGeoTypesSorted()) - m.insertNextCell(NORM_TETRA4,[20,21,22,23]) - self.assertEqual([NORM_TETRA4,NORM_HEXA8,NORM_TETRA4],m.getAllGeoTypesSorted()) - c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) - c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; c2+=[2.,0.,0.] - c3=c2+[2.,0.,0.] - c4=c1+[6.,0.,0.] - c=DataArrayDouble.Aggregate([c1,c2,c3,c4]) - m.setCoords(c) - m.checkCoherency2() - # - m1=m.deepCpy() - d1=m1.simplexize(PLANAR_FACE_5) - m1.checkCoherency2() - vol1=m1.getMeasureField(ON_CELLS).getArray() - self.assertTrue(vol1.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6]),1e-12)) - self.assertEqual(m1.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23]) - self.assertEqual(m1.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60]) - self.assertTrue(d1.isEqual(DataArrayInt([0,1,1,1,1,1,2,2,2,2,2,3]))) - # - m2=m.deepCpy() - d2=m2.simplexize(PLANAR_FACE_6) - m2.checkCoherency2() - vol2=m2.getMeasureField(ON_CELLS).getArray() - self.assertTrue(vol2.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6]),1e-12)) - self.assertEqual(m2.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23]) - self.assertEqual(m2.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70]) - self.assertTrue(d2.isEqual(DataArrayInt([0,1,1,1,1,1,1,2,2,2,2,2,2,3]))) - pass - - def testSwig2CurveLinearMesh2(self): - c=MEDCouplingCMesh() - #2D - arr1=DataArrayDouble([0,1,3,7]) - arr2=DataArrayDouble([0,1,1.5]) - c.setCoords(arr1,arr2) - u=c.buildUnstructured() - coo=u.getCoords() - cl=MEDCouplingCurveLinearMesh() - cl.setCoords(coo) - cl.setNodeGridStructure([4,3]) - cl.checkCoherency2() - li1=[1.,2.,4.,0.5,1.,2.] - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) - self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) - li1_1=[0.5,0.5,2.,0.5,5.,0.5,0.5,1.25,2.,1.25,5.,1.25] - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) - self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) - #3D - c.setCoords(arr1,arr2,arr2) - u=c.buildUnstructured() - coo=u.getCoords() - cl=MEDCouplingCurveLinearMesh() - cl.setCoords(coo) - cl.setNodeGridStructure([4,3,3]) - cl.checkCoherency2() - li2=[1.,2.,4.,0.5, 1.,2.,0.5,1.,2.,0.25,0.5,1.] - li2_1=[0.5,0.5,0.5,2.,0.5,0.5,5.,0.5,0.5,0.5,1.25,0.5,2.,1.25,0.5,5.,1.25,0.5,0.5,0.5,1.25,2.,0.5,1.25,5.,0.5,1.25,0.5,1.25,1.25,2.,1.25,1.25,5.,1.25,1.25] - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) - self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) - self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) - #1D spaceDim 1 - coo=DataArrayDouble(5) ; coo.iota(0.) - coo=coo*coo - cl.setCoords(coo) - cl.setNodeGridStructure([5]) - cl.checkCoherency2() - li3=[1.,3.,5.,7.] - li3_1=[0.5,2.5,6.5,12.5] - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) - self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) - self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) - #1D spaceDim 2 - coo=DataArrayDouble.Meld(coo,coo) - cl.setCoords(coo) - cl.checkCoherency2() - li4=[sqrt(2.)*elt for elt in [1.,3.,5.,7.]] - li4_1=[0.5,0.5,2.5,2.5,6.5,6.5,12.5,12.5] - self.assertEqual(2,cl.getSpaceDimension()) - self.assertEqual(1,cl.getMeshDimension()) - self.assertEqual(4,cl.getNumberOfCells()) - self.assertEqual(5,cl.getNumberOfNodes()) - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) - self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) - self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) - pass - - def testSwig2CurveLinearMeshNonRegression1(self): - coords=DataArrayDouble([0.0, 0.0, 0.10000000149011612, 0.6000000238418579, 0.10000000149011612, 0.30000001192092896, 1.100000023841858, 0.10000000149011612, 0.20000000298023224, 0.10000000149011612, 0.6000000238418579, 0.20000000298023224, 0.699999988079071, 0.6000000238418579, 0.10000000149011612, 1.2000000476837158, 0.6000000238418579, 0.30000001192092896, 0.10000000149011612, 1.100000023841858, 0.30000001192092896, 0.5, 1.100000023841858, 0.20000000298023224, 1.0, 1.2000000476837158, 0.10000000149011612, 0.0, 0.10000000149011612, 0.5, 0.5, 0.10000000149011612, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 0.699999988079071, 0.10000000149011612, 0.6000000238418579, 0.699999988079071, 0.6000000238418579, 0.6000000238418579, 0.5, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 0.10000000149011612, 1.0, 0.6000000238418579, 0.699999988079071, 1.2000000476837158, 0.699999988079071, 0.8999999761581421, 1.0, 0.5, 0.10000000149011612, 0.10000000149011612, 1.2000000476837158, 0.699999988079071, 0.10000000149011612, 1.0, 1.0, 0.10000000149011612, 1.100000023841858, 0.10000000149011612, 0.6000000238418579, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 1.100000023841858, 1.100000023841858, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 1.2000000476837158, 1.0, 0.5, 1.100000023841858, 1.2000000476837158, 1.2000000476837158, 1.100000023841858, 1.0],27,3) - m=MEDCouplingCurveLinearMesh("toto") - m.setCoords(coords) - m.setNodeGridStructure([3,3,3]) - # - vol=m.getMeasureField(False).getArray() - self.assertTrue(vol.isEqual(DataArrayDouble([0.11450000709295281, 0.10583334351579375,0.11149999939029423,0.08866666863113633, 0.1404166805123294,0.1250000135352219,0.1270833433481557,0.13258334288001067]),1e-12)) - self.assertTrue(vol.isEqual(m.buildUnstructured().getMeasureField(False).getArray(),1e-12)) - # - self.assertTrue(m.getBarycenterAndOwner().isEqual(m.buildUnstructured().getBarycenterAndOwner(),1e-12)) - pass - - def testSwig2NonRegressionDASetSelectedComponents1(self): - da=DataArrayDouble.New([1.,2.,3.,4.,5.,6.],3,2) - dv=DataArrayDouble.New(); - dv.alloc(4,4) - dv.fillWithZero() - # da has less tuples than dv - dv.setSelectedComponents(da,[1,0]) - # - self.assertTrue(dv.isEqual(DataArrayDouble([2.,1.,0.,0.,4.,3.,0.,0.,6.,5.,0.,0.,0.,0.,0.,0.],4,4),1e-14)) - # - da=DataArrayInt.New([1,2,3,4,5,6],3,2) - dv=DataArrayInt.New(); - dv.alloc(4,4) - dv.fillWithZero() - # da has less tuples than dv - dv.setSelectedComponents(da,[1,0]) - # - self.assertTrue(dv.isEqual(DataArrayInt([2,1,0,0,4,3,0,0,6,5,0,0,0,0,0,0],4,4))) - pass - - def testSwigSetItem3(self): - # 1-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,1,2,0,0,0,0],6,2),1e-14)) - # 2-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[5,3,2]]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,1,2,1,2,0,0,1,2],6,2),1e-14)) - # 3-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([1,2,1,2,1,2,1,2,1,2,1,2],6,2),1e-14)) - # 4-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4])]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([1,2,0,0,0,0,1,2,1,2,0,0],6,2),1e-14)) - # 5-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[5,1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,7],6,2),1e-14)) - # 6-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[3,5],1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,0,7,0,0,0,7],6,2),1e-14)) - # 7-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:-1:2,1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,7,0,0,0,7,0,0,0,7,0,0],6,2),1e-14)) - # 8-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4]),1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,7,0,0,0,0,0,7,0,7,0,0],6,2),1e-14)) - # 9-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,8,7,0,0,0,0],6,2),1e-14)) - # 10-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,3,4],[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,8,7,8,7,0,0],6,2),1e-14)) - # 11-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,8,7,0,0,8,7],6,2),1e-14)) - # 12-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([1,4]),[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,0,0,8,7,0,0],6,2),1e-14)) - # 13-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1,:-1]=[9] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,9,0,0,0,0,0,0,0,0,0],6,2),1e-14)) - # 14-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,4,5],:]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,7,8,0,0,0,0,7,8,7,8],6,2),1e-14)) - # 15-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,:]=[3,9] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,3,9,0,0,3,9,0,0,3,9],6,2),1e-14)) - # 1-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,1,2,0,0,0,0],6,2))) - # 2-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[5,3,2]]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,1,2,1,2,0,0,1,2],6,2))) - # 3-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([1,2,1,2,1,2,1,2,1,2,1,2],6,2))) - # 4-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4])]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([1,2,0,0,0,0,1,2,1,2,0,0],6,2))) - # 5-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[5,1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,7],6,2))) - # 6-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[3,5],1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,0,7,0,0,0,7],6,2))) - # 7-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:-1:2,1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,7,0,0,0,7,0,0,0,7,0,0],6,2))) - # 8-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4]),1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,7,0,0,0,0,0,7,0,7,0,0],6,2))) - # 9-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,8,7,0,0,0,0],6,2))) - # 10-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,3,4],[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,8,7,8,7,0,0],6,2))) - # 11-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,8,7,0,0,8,7],6,2))) - # 12-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([1,4]),[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,0,0,8,7,0,0],6,2))) - # 13-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1,:-1]=[9] - self.assertTrue(d.isEqual(DataArrayInt([0,0,9,0,0,0,0,0,0,0,0,0],6,2))) - # 14-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,4,5],:]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,7,8,0,0,0,0,7,8,7,8],6,2))) - # 15-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,:]=[3,9] - self.assertTrue(d.isEqual(DataArrayInt([0,0,3,9,0,0,3,9,0,0,3,9],6,2))) - pass - - def testSwig2ConvertLinearCellsToQuadratic1(self): - coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45],22,2) - # 2D - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - m2D.convertLinearCellsToQuadratic(0) - m2D.checkCoherency1() - self.assertEqual(m2D.getNodalConnectivity().getValues(),[8,0,3,4,1,9,10,11,12,6,1,4,2,11,13,14,6,4,5,2,15,16,13,8,6,7,4,3,17,18,10,19,8,7,8,5,4,20,21,15,18]) - self.assertEqual(m2D.getNodalConnectivityIndex().getValues(),[0,9,16,23,32,41]) - self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) - # 1D - m1D=MEDCouplingDataForTest.build2DTargetMesh_1().buildDescendingConnectivity()[0] - m1D.convertLinearCellsToQuadratic(0) - m1D.checkCoherency1() - self.assertEqual(m1D.getNodalConnectivity().getValues(),[2,0,3,9,2,3,4,10,2,4,1,11,2,1,0,12,2,4,2,13,2,2,1,14,2,4,5,15,2,5,2,16,2,6,7,17,2,7,4,18,2,3,6,19,2,7,8,20,2,8,5,21]) - self.assertEqual(m1D.getNodalConnectivityIndex().getValues(),[0,4,8,12,16,20,24,28,32,36,40,44,48,52]) - self.assertTrue(m1D.getCoords().isEqual(coordsExp,1e-14)) - # 3D - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - m2D.changeSpaceDimension(3) - arr=DataArrayDouble(4); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) - m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) - m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] - cooTmp=m2D.getCoords()[:] - m3D=m2D.buildExtrudedMesh(m1D,0) - m3D.convertLinearCellsToQuadratic(0) - m3D.checkCoherency1() - # check of new m3D content - coordsExp2=[coordsExp.changeNbOfComponents(3,i) for i in xrange(4)] - coordsExp3=[DataArrayDouble.Meld(cooTmp[:,[0,1]],cooTmp[:,2]+(0.5+float(i))) for i in xrange(3)] - coordsExp4=DataArrayDouble.Aggregate([coordsExp2[0],coordsExp3[0],coordsExp2[1],coordsExp3[1],coordsExp2[2],coordsExp3[2],coordsExp2[3]]) - c=DataArrayDouble.Aggregate(m3D.getCoords(),coordsExp4) - self.assertEqual(len(coordsExp4),115) - self.assertEqual(len(m3D.getCoords()),115) - a,b=c.findCommonTuples(1e-14) - self.assertEqual(len(b),len(coordsExp4)+1) - e,f=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(2*115,a,b) - self.assertEqual(f,115) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,0,1,2,3,4,5,6,7,8,36,37,38,39,48,49,53,54,58,59,60,66,67,44,47,52,45,46,57,64,65,70,9,10,11,12,13,14,15,16,17,40,41,42,43,50,51,55,56,61,62,63,68,69,75,78,81,76,77,84,88,89,92,18,19,20,21,22,23,24,25,26,71,72,73,74,79,80,82,83,85,86,87,90,91,97,100,103,98,99,106,110,111,114,27,28,29,30,31,32,33,34,35,93,94,95,96,101,102,104,105,107,108,109,112,113]))) - self.assertTrue(DataArrayInt([30,0,3,4,1,9,12,13,10,36,37,38,39,40,41,42,43,44,45,46,47,25,1,4,2,10,13,11,38,48,49,42,50,51,47,46,52,25,4,5,2,13,14,11,53,54,48,55,56,50,46,57,52,30,6,7,4,3,15,16,13,12,58,59,37,60,61,62,41,63,64,65,46,45,30,7,8,5,4,16,17,14,13,66,67,53,59,68,69,55,62,65,70,57,46,30,9,12,13,10,18,21,22,19,40,41,42,43,71,72,73,74,75,76,77,78,25,10,13,11,19,22,20,42,50,51,73,79,80,78,77,81,25,13,14,11,22,23,20,55,56,50,82,83,79,77,84,81,30,15,16,13,12,24,25,22,21,61,62,41,63,85,86,72,87,88,89,77,76,30,16,17,14,13,25,26,23,22,68,69,55,62,90,91,82,86,89,92,84,77,30,18,21,22,19,27,30,31,28,71,72,73,74,93,94,95,96,97,98,99,100,25,19,22,20,28,31,29,73,79,80,95,101,102,100,99,103,25,22,23,20,31,32,29,82,83,79,104,105,101,99,106,103,30,24,25,22,21,33,34,31,30,85,86,72,87,107,108,94,109,110,111,99,98,30,25,26,23,22,34,35,32,31,90,91,82,86,112,113,104,108,111,114,106,99]).isEqual(m3D.getNodalConnectivity())) - self.assertTrue(DataArrayInt([0,21,37,53,74,95,116,132,148,169,190,211,227,243,264,285]).isEqual(m3D.getNodalConnectivityIndex())) - # testing explode3DMeshTo1D - m3DSlice0=m3D[:5] - m3DSlice0.zipCoords() - a,b,c,d,e=m3DSlice0.explode3DMeshTo1D() - self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,2,12,13,6,14,15,11,10,16,17,18,12,19,20,14,10,21,16,22,23,1,24,25,26,5,27,28,29,10,9,30,31,17,23,32,33,19,26,29,34,21,10]))) - self.assertTrue(c.isEqual(DataArrayInt([0,12,21,30,42,54]))) - self.assertTrue(d.isEqual(DataArrayInt([0,0,3,0,1,0,0,0,3,0,1,0,0,0,3,0,1,2,3,4,0,1,1,2,1,1,2,1,1,2,2,4,2,2,4,2,2,4,3,3,4,3,3,3,4,3,3,3,4,4,4,4,4,4]))) - self.assertTrue(e.isEqual(DataArrayInt([0,1,3,5,6,7,9,11,12,13,15,20,22,24,25,27,28,30,32,33,35,36,38,39,41,42,43,45,46,47,49,50,51,52,53,54]))) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([2,0,3,18,2,3,4,19,2,4,1,20,2,1,0,21,2,9,12,22,2,12,13,23,2,13,10,24,2,10,9,25,2,0,9,26,2,3,12,27,2,4,13,28,2,1,10,29,2,4,2,30,2,2,1,31,2,13,11,32,2,11,10,33,2,2,11,34,2,4,5,35,2,5,2,36,2,13,14,37,2,14,11,38,2,5,14,39,2,6,7,40,2,7,4,41,2,3,6,42,2,15,16,43,2,16,13,44,2,12,15,45,2,6,15,46,2,7,16,47,2,7,8,48,2,8,5,49,2,16,17,50,2,17,14,51,2,8,17,52]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140]))) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,0.7,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,0.7,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,0.7,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,0.7,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,0.7,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,0.7,0.7,1.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,0.45,-0.05,0.0,0.45,-0.3,0.0,0.45,-0.05,1.0,0.45,-0.3,1.0,0.7,-0.3,0.5,0.45,0.2,0.0,0.7,-0.05,0.0,0.45,0.2,1.0,0.7,-0.05,1.0,0.7,0.2,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,0.45,0.7,0.0,0.7,0.45,0.0,0.45,0.7,1.0,0.7,0.45,1.0,0.7,0.7,0.5],53,3),1e-14)) - pass - - def testSwig2DataArrayPushBackValsSilent1(self): - d=DataArrayDouble() - d.pushBackValsSilent([4,5,6]) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.]),1e-14)) - e=DataArrayDouble([1,2,3],1,3) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.]),1e-14)) - d.pushBackValsSilent(DataArrayDouble([9,10.])) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) - d.pushBackValsSilent(DataArrayDouble(0,1)) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) - e=DataArrayDouble([1,2,3],3,1) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.]),1e-14)) - d.pushBackValsSilent(77) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.,77.]),1e-14)) - # - d=DataArrayInt() - d.pushBackValsSilent([4,5,6]) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6]))) - e=DataArrayInt([1,2,3],1,3) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3]))) - d.pushBackValsSilent(DataArrayInt([9,10])) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) - d.pushBackValsSilent(DataArrayInt(0,1)) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) - e=DataArrayInt([1,2,3],3,1) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3]))) - d.pushBackValsSilent(77) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3,77]))) - pass - - def testSwig2ConvertLinearCellsToQuadratic2(self): - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - ret=m2D.convertLinearCellsToQuadratic(1) - self.assertTrue(ret.isIdentity()) - self.assertEqual(5,len(ret)) - m2D.checkCoherency1() - coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45,-0.05,-0.05,0.3666666666666667,-0.1333333333333333,0.5333333333333332,0.03333333333333334,-0.05,0.45,0.45,0.45],27,2) - self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) - self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([9,0,3,4,1,9,10,11,12,22,7,1,4,2,11,13,14,23,7,4,5,2,15,16,13,24,9,6,7,4,3,17,18,10,19,25,9,7,8,5,4,20,21,15,18,26]))) - self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,10,18,26,36,46]))) - # - m2D=MEDCouplingDataForTest.build2DTargetMesh_1()[(0,3)] ; m2D.zipCoords() - m2D.changeSpaceDimension(3) - arr=DataArrayDouble(3); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) - m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) - m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] - cooTmp=m2D.getCoords()[:] - m3D=m2D.buildExtrudedMesh(m1D,0) - ret=m3D.convertLinearCellsToQuadratic(1) - self.assertTrue(ret.isIdentity()) - self.assertEqual(4,len(ret)) - m3D.checkCoherency1() - coordsExp2=DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,-0.3,-0.3,2.0,0.2,-0.3,2.0,-0.3,0.2,2.0,0.2,0.2,2.0,-0.3,0.7,2.0,0.2,0.7,2.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,-0.3,-0.05,2.0,-0.05,0.2,2.0,0.2,-0.05,2.0,-0.05,-0.3,2.0,-0.3,-0.3,1.5,-0.3,0.2,1.5,0.2,0.2,1.5,0.2,-0.3,1.5,-0.05,0.7,2.0,0.2,0.45,2.0,-0.3,0.45,2.0,-0.3,0.7,1.5,0.2,0.7,1.5,-0.05,-0.05,0.0,-0.3,-0.05,0.5,-0.05,0.2,0.5,0.2,-0.05,0.5,-0.05,-0.3,0.5,-0.05,-0.05,1.0,-0.05,0.45,0.0,-0.05,0.7,0.5,0.2,0.45,0.5,-0.3,0.45,0.5,-0.05,0.45,1.0,-0.3,-0.05,1.5,-0.05,0.2,1.5,0.2,-0.05,1.5,-0.05,-0.3,1.5,-0.05,-0.05,2.0,-0.05,0.7,1.5,0.2,0.45,1.5,-0.3,0.45,1.5,-0.05,0.45,2.0,-0.05,-0.05,0.5,-0.05,0.45,0.5,-0.05,-0.05,1.5,-0.05,0.45,1.5],75,3) - self.assertTrue(m3D.getCoords().isEqual(coordsExp2,1e-14)) - self.assertTrue(m3D.getNodalConnectivity().isEqual(DataArrayInt([27,0,2,3,1,6,8,9,7,18,19,20,21,22,23,24,25,26,27,28,29,51,52,53,54,55,56,71,27,4,5,3,2,10,11,9,8,30,31,19,32,33,34,23,35,36,37,28,27,57,58,59,53,60,61,72,27,6,8,9,7,12,14,15,13,22,23,24,25,38,39,40,41,42,43,44,45,56,62,63,64,65,66,73,27,10,11,9,8,16,17,15,14,33,34,23,35,46,47,39,48,49,50,44,43,61,67,68,63,69,70,74]))) - self.assertTrue(m3D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,28,56,84,112]))) - pass - - def testSwig2GaussNEIntegral1(self): - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - m0=m2D[0] ; m0.zipCoords() - m1=m2D[[1,2]] ; m1.zipCoords() - m2=m2D[[3,4]] ; m2.zipCoords() - m0.convertLinearCellsToQuadratic(1) - m1.convertLinearCellsToQuadratic(0) - m2.convertLinearCellsToQuadratic(1) - m=MEDCouplingUMesh.MergeUMeshes([m0,m1,m2]) - m.mergeNodes(1e-12) - f=MEDCouplingFieldDouble(ON_GAUSS_NE) - f.setMesh(m) - arr=DataArrayDouble([1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9, - 11.1,12.2,13.3,14.4,15.5,16.6, - 21.1,22.2,23.3,24.4,25.5,26.6, - 31.1,32.2,33.3,34.4,35.5,36.6,37.7,38.8,39.9, - 41.1,42.2,43.3,44.4,45.5,46.6,47.7,48.8,49.9]) - arr2=DataArrayDouble(len(arr),2) - arr2[:,0]=arr ; arr2[:,1]=arr+100 - f.setArray(arr2) - f.checkCoherency() - res=f.integral(False) - # a=25./81 ; b=40./81 ; c=64./81 - # p1=0.11169079483905 ; p2=0.0549758718227661 - # 1st compo - # c0=(a*(1.1+2.2+3.3+4.4)+b*(5.5+6.6+7.7+8.8)+c*9.9)*0.25/3.9999999999999978 ; c0=1.5837962962962973 - # c1=(p2*(11.1+12.2+13.3)+p1*(14.4+15.5+16.6))*0.125/0.4999999999854482 ; c1=1.8014347172346943 - # c2=(p2*(21.1+22.2+23.3)+p1*(24.4+25.5+26.6))*0.125/0.4999999999854482 ; c2=3.0514347172346943 - # c3=(a*(31.1+32.2+33.3+34.4)+b*(35.5+36.6+37.7+38.8)+c*39.9)*0.25/3.9999999999999978 ; c3=9.0837962962963 - # c4=(a*(41.1+42.2+43.3+44.4)+b*(45.5+46.6+47.7+48.8)+c*49.9)*0.25/3.9999999999999978 ; c4=11.583796296296303 - # c0+c1+c2+c3+c4=27.104258323358287 - integExp0=27.104258323358287 - self.assertAlmostEqual(res[0],integExp0,13) - # 2nd compo - # c0=(a*(101.1+102.2+103.3+104.4)+b*(105.5+106.6+107.7+108.8)+c*109.9)*0.25/3.9999999999999978 ; c0=26.58379629629631 - # c1=(p2*(111.1+112.2+113.3)+p1*(114.4+115.5+116.6))*0.125/0.4999999999854482 ; c1=14.301434717234699 - # c2=(p2*(121.1+122.2+123.3)+p1*(124.4+125.5+126.6))*0.125/0.4999999999854482 ; c2=15.5514347172347 - # c3=(a*(131.1+132.2+133.3+134.4)+b*(135.5+136.6+137.7+138.8)+c*139.9)*0.25/3.9999999999999978 ; c3=34.08379629629631 - # c4=(a*(141.1+142.2+143.3+144.4)+b*(145.5+146.6+147.7+148.8)+c*149.9)*0.25/3.9999999999999978 ; c4=36.58379629629632 - # c0+c1+c2+c3+c4=127.10425832335835 - integExp1=127.10425832335835 - self.assertAlmostEqual(res[1],integExp1,12) - meas=f.getDiscretization().getMeasureField(f.getMesh(),False) - intPerTuple=meas*f - res2=intPerTuple.accumulate() - self.assertAlmostEqual(res2[0],integExp0,13) - self.assertAlmostEqual(res2[1],integExp1,12) - # - meas2=f.buildMeasureField(False) - intPerTuple=meas2*f - res3=intPerTuple.accumulate() - self.assertAlmostEqual(res3[0],integExp0,13) - self.assertAlmostEqual(res3[1],integExp1,12) - # - res4=f.getWeightedAverageValue(False) # res4==res2 because sum of area of mesh is equal to 1 - self.assertAlmostEqual(res4[0],integExp0,13) - self.assertAlmostEqual(res4[1],integExp1,12) - # - m.scale([0,0],2.) - # - res5=f.getWeightedAverageValue() # res4==res4 because weighted average is not sensitive to the scaling - self.assertAlmostEqual(res5[0],integExp0,13) - self.assertAlmostEqual(res5[1],integExp1,12) - meas3=f.buildMeasureField(False) - delta=4*meas2.getArray()-meas3.getArray() - delta.abs() - self.assertTrue(delta.isUniform(0.,1e-16)) - res6=f.integral(False) - self.assertAlmostEqual(res6[0],4.*integExp0,12) - self.assertAlmostEqual(res6[1],4.*integExp1,11) - pass - - def testSwig2SlowDADFindClosestTupleId(self): - nbPts=[10,] - for nbPt in nbPts: - d=DataArrayDouble(nbPt) ; d.iota() ; d*=1./(nbPt-1) - c=MEDCouplingCMesh() ; c.setCoords(d,d) ; m=c.buildUnstructured() ; pts=m.getCoords() ; del m - # - d0=DataArrayDouble((nbPt-1)*(nbPt-1)) ; d0.iota() ; d0*=(3./((nbPt-1)*(nbPt-1))) ; d0=d0.applyFunc("exp(x)-1") - d1=DataArrayDouble((nbPt-1)*(nbPt-1)) ; d1.iota() - d2=DataArrayDouble.Meld(d0,d1) ; d2=d2.fromPolarToCart() ; d2+=[0.32,0.73] - ids=pts.findClosestTupleId(d2) - #print "Start of costly computation" - idsExpected=DataArrayInt(len(d2)) - tmp=1e300 - for i,elt in enumerate(d2): - l,m=(pts-elt).magnitude().getMinValue() - idsExpected.setIJSilent(i,0,m) - if l 2147483647 - pass - pass - - def testSwig2DAReverseMultiCompo1(self): - d=DataArrayDouble(6,2) - d[:,0]=range(6) - d[:,1]=range(10,16) - d.reverse() - self.assertTrue(d.isEqual(DataArrayDouble([5.,15.,4.,14.,3.,13.,2.,12.,1.,11.,0.,10.],6,2),1e-14)) - d=DataArrayDouble(7,2) - d[:,0]=range(7) - d[:,1]=range(10,17) - d.reverse() - self.assertTrue(d.isEqual(DataArrayDouble([6.,16.,5.,15.,4.,14.,3.,13.,2.,12.,1.,11.,0.,10.],7,2),1e-14)) - # - d=DataArrayInt(6,2) - d[:,0]=range(6) - d[:,1]=range(10,16) - d.reverse() - self.assertTrue(d.isEqual(DataArrayInt([5,15,4,14,3,13,2,12,1,11,0,10],6,2))) - d=DataArrayInt(7,2) - d[:,0]=range(7) - d[:,1]=range(10,17) - d.reverse() - self.assertTrue(d.isEqual(DataArrayInt([6,16,5,15,4,14,3,13,2,12,1,11,0,10],7,2))) - pass - - def testSwigDAPow1(self): - d=DataArrayInt(10) - d.iota(0) - d1=d.deepCpy() - d.setIJ(2,0,-2) - self.assertTrue((d**2).isEqual(DataArrayInt([0,1,4,9,16,25,36,49,64,81]))) - self.assertTrue((d**3).isEqual(DataArrayInt([0,1,-8,27,64,125,216,343,512,729]))) - for elt in [d]: - elt**=2 - pass - self.assertTrue(d.isEqual(DataArrayInt([0,1,4,9,16,25,36,49,64,81]))) - self.assertTrue((d1[:4]**d1[:4]).isEqual(DataArrayInt([1,1,4,27]))) - self.assertTrue((3**d1[:4]).isEqual(DataArrayInt([1,3,9,27]))) - d2=d1[:4] - d2**=d2 - self.assertTrue(d2.isEqual(DataArrayInt([1,1,4,27]))) - self.assertRaises(InterpKernelException,d2.__pow__,-1)#non supporting negative pow in DataArrayInt.__pow__ - self.assertRaises(InterpKernelException,d2.__ipow__,-1)#non supporting negative pow in DataArrayInt.__pow__ - # - d=DataArrayDouble(10) - d.iota(0) - d1=d.deepCpy() - d.setIJ(2,0,-2.) - self.assertTrue((d**2).isEqual(DataArrayDouble([0,1,4,9,16,25,36,49,64,81]),1e-12)) - self.assertTrue((d**3).isEqual(DataArrayDouble([0,1,-8,27,64,125,216,343,512,729]),1e-12)) - self.assertRaises(InterpKernelException,d.__pow__,3.1)#3.1 is double not integer -> not supporting negative values in d - for elt in [d]: - elt**=2 - pass - self.assertTrue(d.isEqual(DataArrayDouble([0,1,4,9,16,25,36,49,64,81]),1e-12)) - self.assertTrue((d1[:4]**d1[:4]).isEqual(DataArrayDouble([1,1,4,27]),1e-12)) - self.assertTrue((3**d1[:4]).isEqual(DataArrayDouble([1,3,9,27]),1e-12)) - d2=d1[:4] - d2**=d2 - self.assertTrue(d2.isEqual(DataArrayDouble([1,1,4,27]),1e-12)) - d2**=-0.5 - self.assertTrue(d2.isEqual(DataArrayDouble([1,1,1./2,1./sqrt(27.)]),1e-14)) - d3=-1./d1[1:5] - self.assertTrue((3**d3).isEqual(DataArrayDouble([0.3333333333333333,0.5773502691896257,0.6933612743506348,0.7598356856515925]),1e-14)) - d4=d3.deepCpy() ; d4.abs() - self.assertTrue((d4**d3).isEqual(DataArrayDouble([1.,sqrt(2.),1.4422495703074083,sqrt(2.)]),1e-14)) - d4**=d3 - self.assertTrue(d4.isEqual(DataArrayDouble([1.,sqrt(2.),1.4422495703074083,sqrt(2.)]),1e-14)) - pass - - def testSwig2Baryenter3DForCellsWithVolumeZero1(self): - coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) - m2=MEDCouplingUMesh("mesh",2) - m2.allocateCells(0) - m2.insertNextCell(NORM_POLYGON,[0,1,2]) - m2.setCoords(coo) - m2.checkCoherency1() - # - coo2=DataArrayDouble([0.,0.,0.,0.,0.,0.,0.,0.,2.],3,3) - m1=MEDCouplingUMesh("mesh",1) - m1.allocateCells(0) - m1.insertNextCell(NORM_SEG2,[0,1]) - m1.insertNextCell(NORM_SEG2,[1,2]) - m1.setCoords(coo2) - m1.checkCoherency1() - # - m3=m2.buildExtrudedMesh(m1,0) - m3.insertNextCell(NORM_POLYHED,[3,4,5,-1,8,7,6,-1,4,3,6,7,-1,5,4,7,8,-1,5,4,-1,3,5,8,6])# addition of face #4 with null surface - self.assertTrue(m3.getBarycenterAndOwner().isEqual(DataArrayDouble([0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,1.,0.3333333333333333,0.3333333333333333,1.],3,3),1e-13)) - m4,a,b,c,d=m3.buildDescendingConnectivity() - self.assertTrue(m4.getBarycenterAndOwner().isEqual(DataArrayDouble([0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,0.,0.5,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.3333333333333333,0.3333333333333333,2.,0.5,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.5,0.],10,3),1e-13)) - pass - - def testSwigRepr1(self): - d=DataArrayDouble() - self.assertTrue(len(d.__repr__())<120) - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - for i in xrange(100): - d.alloc(i,1) ; d.iota(1.1234567890123456) ; d*=1e123 - self.assertTrue(len(d.__repr__())<500) - pass - for i in xrange(50): - d.alloc(i,2) ; d.rearrange(1) ; d.iota(1.1234567890123456) ; d.rearrange(2) ; d*=1e123 - self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(4000,1) ; d.iota() ; self.assertTrue(len(d.__repr__())<500) - for i in xrange(2,4): - d.alloc(362880,1) ; d.iota() ; d.rearrange(i) ; self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(0,9) - self.assertTrue(len(d.__repr__())<120) - # - d=DataArrayInt() - self.assertTrue(len(d.__repr__())<100) - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - for i in xrange(100): - d.alloc(i,1) ; d.iota(123456789) - self.assertTrue(len(d.__repr__())<500) - pass - for i in xrange(50): - d.alloc(i,2) ; d.rearrange(1) ; d.iota(123456789) ; d.rearrange(2) - self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(4000,1) ; d.iota() ; self.assertTrue(len(d.__repr__())<500) - for i in xrange(2,10): - d.alloc(362880,1) ; d.iota() ; d.rearrange(i) ; self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(0,9) - self.assertTrue(len(d.__repr__())<100) - # - d=DataArrayAsciiChar() - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - d.alloc(2,16) ; d[:]='1234567890ABCDEF' - self.assertTrue(len(d.__repr__())<500) - d.alloc(2000,16) ; d[:]='1234567890ABCDEF' - self.assertTrue(len(d.__repr__())<500) - d.alloc(0,16) ; d[:]='1234567890ABCDEF' - self.assertTrue(len(d.__repr__())<120) - # - d=DataArrayByte() - self.assertTrue(len(d.__repr__())<100) - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - d.alloc(0,16) ; self.assertTrue(len(d.__repr__())<100) - d.alloc(5,1) ; d.fillWithValue(127) - self.assertTrue(len(d.__repr__())<200) - d.alloc(1000,1) ; d.fillWithValue(127) - self.assertTrue(len(d.__repr__())<500) - d.alloc(1000,3) ; d.fillWithValue(127) - self.assertTrue(len(d.__repr__())<500) - pass - - def testSwig2MeshComputeIsoBarycenterOfNodesPerCell1(self): - coo=DataArrayDouble([26.17509821414239,5.0374,200.,26.175098214142388,-5.0374,200.,17.450065476094927,20.1496,200.,8.725032738047464,25.187,200.,43.62516369023732,5.0374,200.,34.90013095218986,10.0748,200.,34.900130952189855,-10.0748,200.,43.625163690237315,-5.0374,200.,26.175098214142402,25.187,200.,26.175098214142395,35.2618,200.,17.45006547609493,40.2992,200.,8.725032738047469,35.2618,200.,26.17509821414239,5.0374,200.,26.175098214142388,-5.0374,200.,17.450065476094927,20.1496,200.,8.725032738047464,25.187,200.,43.62516369023732,5.0374,200.,34.90013095218986,10.0748,200.,34.900130952189855,-10.0748,200.,43.625163690237315,-5.0374,200.,26.175098214142402,25.187,200.,26.175098214142395,35.2618,200.,17.45006547609493,40.2992,200.,8.725032738047469,35.2618,200.],24,3) - m=MEDCouplingUMesh.New("toto",3) - m.allocateCells(0) - m.insertNextCell(NORM_POLYHED,[4,5,0,1,6,7,-1,19,18,13,12,17,16,-1,5,4,16,17,-1,0,5,17,12,-1,1,0,12,13,-1,6,1,13,18,-1,7,6,18,19,-1,4,7,19,16]) - m.insertNextCell(NORM_POLYHED,[9,10,11,3,2,8,-1,20,14,15,23,22,21,-1,10,9,21,22,-1,11,10,22,23,-1,3,11,23,15,-1,2,3,15,14,-1,8,2,14,20,-1,9,8,20,21]) - m.setCoords(coo) - m.checkCoherency1() - # - dReference=DataArrayDouble([(34.900130952189848,0.,200),(17.450065476094931,30.2244,200.)]) - self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(dReference,1e-12)) - m.getNodalConnectivity().setIJ(87,0,24) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - m.getNodalConnectivity().setIJ(87,0,-2) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - m.getNodalConnectivity().setIJ(87,0,21)# put again 21 as at the beginning - # - self.assertTrue(m.unPolyze()) - self.assertEqual([NORM_HEXGP12],m.getAllGeoTypes()) - self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(dReference,1e-12)) - m.getNodalConnectivity().setIJ(25,0,24) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - m.getNodalConnectivity().setIJ(25,0,-1) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - pass - - def testSwig2NonRegressionBugDescHexa20(self): - coo=DataArrayDouble([0.,0.,0.,1.23,0.,0.,0.615,0.,0.,0.,2.1,0.,0.615,2.1,0.,1.23,2.1,0.,1.23,1.05,0.,0.,1.05,0.,0.,0.,2.16,1.23,0.,2.16,1.23,2.1,2.16,0.,2.1,2.16,0.,0.,4.32,0.615,0.,4.32,1.23,0.,4.32,1.23,1.05,4.32,1.23,2.1,4.32,0.615,2.1,4.32,0.,2.1,4.32,0.,1.05,4.32],20,3) - m=MEDCouplingUMesh('mesh',3) - m.allocateCells(0) - m.insertNextCell(NORM_HEXA20,[0,3,5,1,12,18,16,14,7,4,6,2,19,17,15,13,8,11,10,9]) - m.setCoords(coo) - m.checkCoherency1() - # - a,b,c,d,e=m.buildDescendingConnectivity() - m2=MEDCouplingUMesh('mesh',2) - m2.allocateCells(0) - m2.setCoords(coo) - conn2=[[0,3,5,1,7,4,6,2],[12,14,16,18,13,15,17,19],[0,12,18,3,8,19,11,7],[3,18,16,5,11,17,10,4],[5,16,14,1,10,15,9,6],[1,14,12,0,9,13,8,2]] - for i in xrange(6): - m2.insertNextCell(NORM_QUAD8,conn2[i]) - pass - self.assertTrue(m2.isEqual(a,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertTrue(c.isEqual(DataArrayInt([0,6]))) - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0]))) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) - # - m.convertQuadraticCellsToLinear() ; m.zipCoords() - m.convertLinearCellsToQuadratic(1) - # - coo2=DataArrayDouble([0.,0.,0.,1.23,0.,0.,0.,2.1,0.,1.23,2.1,0.,0.,0.,4.32,1.23,0.,4.32,1.23,2.1,4.32,0.,2.1,4.32,0.,1.05,0.,0.615,2.1,0.,1.23,1.05,0.,0.615,0.,0.,0.,1.05,4.32,0.615,2.1,4.32,1.23,1.05,4.32,0.615,0.,4.32,0.,0.,2.16,0.,2.1,2.16,1.23,2.1,2.16,1.23,0.,2.16,0.615,1.05,0.,0.,1.05,2.16,0.615,2.1,2.16,1.23,1.05,2.16,0.615,0.,2.16,0.615,1.05,4.32,0.615,1.05,2.16],27,3) - m3=MEDCouplingUMesh("mesh",3) - m3.allocateCells(1) - m3.insertNextCell(NORM_HEXA27,[0,2,3,1,4,7,6,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) - m3.setCoords(coo2) - self.assertTrue(m3.isEqual(m,1e-12)) - # - a,b,c,d,e=m.buildDescendingConnectivity() - conn4=[[0,2,3,1,8,9,10,11,20],[4,5,6,7,15,14,13,12,25],[0,4,7,2,16,12,17,8,21],[2,7,6,3,17,13,18,9,22],[3,6,5,1,18,14,19,10,23],[1,5,4,0,19,15,16,11,24]] - m4=MEDCouplingUMesh("mesh",2) - m4.allocateCells(0) - for i in xrange(6): - m4.insertNextCell(NORM_QUAD9,conn4[i]) - pass - m4.setCoords(coo2) - self.assertTrue(m4.isEqual(a,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertTrue(c.isEqual(DataArrayInt([0,6]))) - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0]))) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) - pass - - def testSwigAdvGauss(self): - f=MEDCouplingFieldTemplate(ON_GAUSS_PT) - f.setDiscretization(None) - f.__repr__() ; f.__str__() - # - f=MEDCouplingFieldTemplate(ON_GAUSS_PT) - d=f.getDiscretization() - i=DataArrayInt() ; i.alloc(10,1) ; i.iota(1) - d.setArrayOfDiscIds(i) - f.__repr__() ; f.__str__() - i2=d.getArrayOfDiscIds() - self.assertEqual(i.__repr__(),i2.__repr__()) - # - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - f.setDiscretization(None) - f.__repr__() ; f.__str__() - # - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - d=f.getDiscretization() - i=DataArrayInt() ; i.alloc(10,1) ; i.iota(1) - d.setArrayOfDiscIds(i) - f.__repr__() ; f.__str__() - # - gl=MEDCouplingGaussLocalization(NORM_SEG2,[0,1],[0.5],[1.]) - gl.setWeights([3.]) - gl.__repr__() ; gl.__str__() - gl=MEDCouplingGaussLocalization(NORM_ERROR) - gl.setWeights([3.]) - gl.__repr__() ; gl.__str__() - pass - - def testSwig2NonRegressionBugSubstractInPlaceDM(self): - m0=MEDCouplingCMesh() - arr=DataArrayDouble(5,1) ; arr.iota(0.) - m0.setCoords(arr,arr) - m0=m0.buildUnstructured() - m00=m0[::2] ; m00.simplexize(0) ; m01=m0[1::2] - m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) - m0.getCoords()[:]*=1/4. - m0.setName("mesh") - # - NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) - NodeField.setName("NodeField") - NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") - proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) - proc1=proc0.buildComplement(m0.getNumberOfCells()) - # - NodeField0=NodeField[proc0] ; NodeField0.getMesh().setName(m0.getName()) - NodeField1=NodeField[proc1] ; NodeField1.getMesh().setName(m0.getName()) - # - NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0,NodeField1]) - NodeField_read.mergeNodes(1e-10) - NodeFieldCpy=NodeField.deepCpy() - NodeFieldCpy.mergeNodes(1e-10) - NodeField.checkCoherency() - self.assertTrue(not NodeField.getArray().isUniform(0.,1e-12)) - NodeField.substractInPlaceDM(NodeField_read,10,1e-12) - self.assertTrue(NodeField.getArray().isUniform(0.,1e-12)) - pass - - def testSwigFieldOperationOpen1(self): - ## MEDCouplingFieldDouble.__add__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__add__,2) - self.assertRaises(InterpKernelException,f.__add__,range(5)) - self.assertRaises(InterpKernelException,f.__add__,arr) - self.assertRaises(InterpKernelException,f.__add__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__add__,2) - self.assertRaises(InterpKernelException,f.__add__,range(5)) - self.assertRaises(InterpKernelException,f.__add__,arr) - self.assertRaises(InterpKernelException,f.__add__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=f+2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) - ff=f+arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) - self.assertRaises(InterpKernelException,f.__add__,f2) - f2.setArray(arr) - ff=f+f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) - ff=f+[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(5,15),(6,16),(7,17),(8,18),(9,19)]),1e-12)) - ### MEDCouplingFieldDouble.__sub__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__sub__,2) - self.assertRaises(InterpKernelException,f.__sub__,range(5)) - self.assertRaises(InterpKernelException,f.__sub__,arr) - self.assertRaises(InterpKernelException,f.__sub__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__sub__,2) - self.assertRaises(InterpKernelException,f.__sub__,range(5)) - self.assertRaises(InterpKernelException,f.__sub__,arr) - self.assertRaises(InterpKernelException,f.__sub__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=f-2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(-2,5),(-1,6),(0,7),(1,8),(2,9)]),1e-12)) - ff=f-arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(0,6),(0,5),(0,4),(0,3)]),1e-12)) - self.assertRaises(InterpKernelException,f.__sub__,f2) - f2.setArray(arr) - ff=f-f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(0,6),(0,5),(0,4),(0,3)]),1e-12)) - ff=f-[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(-5,-1),(-4,0),(-3,1),(-2,2),(-1,3)]),1e-12)) - ### MEDCouplingFieldDouble.__mul__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__mul__,2) - self.assertRaises(InterpKernelException,f.__mul__,range(5)) - self.assertRaises(InterpKernelException,f.__mul__,arr) - self.assertRaises(InterpKernelException,f.__mul__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__mul__,2) - self.assertRaises(InterpKernelException,f.__mul__,range(5)) - self.assertRaises(InterpKernelException,f.__mul__,arr) - self.assertRaises(InterpKernelException,f.__mul__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=f*2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) - ff=f*arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) - self.assertRaises(InterpKernelException,f.__mul__,f2) - f2.setArray(arr) - ff=f*f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) - ff=f*[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,56),(5,64),(10,72),(15,80),(20,88)]),1e-12)) - ### MEDCouplingFieldDouble.__div__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - self.assertRaises(InterpKernelException,f.__div__,0) - ff=f/2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,4),(1,4.5),(1.5,5),(2,5.5)]),1e-12)) - ff=f/arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,2),(0.6666666666666666,1.5),(0.75,1.25),(0.8,1.1)]),1e-12)) - self.assertRaises(InterpKernelException,f.__div__,f2) - f2.setArray(arr) - ff=f/f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,2),(0.6666666666666666,1.5),(0.75,1.25),(0.8,1.1)]),1e-12)) - ff=f/[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0.875),(0.2,1),(0.4,1.125),(0.6,1.25),(0.8,1.375)]),1e-12)) - ### MEDCouplingFieldDouble.__pow__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5) - arr[:]=[1,1,3,2,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,1) - f.getArray()[:]=range(2,7) - ff=f**2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([4,9,16,25,36]),1e-12)) - ff=f**arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([2,3,64,25,1]),1e-12)) - f2.setArray(arr) - ff=f**f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([2,3,64,25,1]),1e-12)) - ## MEDCouplingFieldDouble.__iadd__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__iadd__,2) - self.assertRaises(InterpKernelException,f.__iadd__,range(5)) - self.assertRaises(InterpKernelException,f.__iadd__,arr) - self.assertRaises(InterpKernelException,f.__iadd__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__iadd__,2) - self.assertRaises(InterpKernelException,f.__iadd__,range(5)) - self.assertRaises(InterpKernelException,f.__iadd__,arr) - self.assertRaises(InterpKernelException,f.__iadd__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f+=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) - f+=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(4,12),(6,15),(8,18),(10,21)]),1e-12)) - f2.setArray(arr) - f+=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(5,14),(8,19),(11,24),(14,29)]),1e-12)) - f+=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2.1,9.2),(5.1,14.2),(8.1,19.2),(11.1,24.2),(14.1,29.2)]),1e-12)) - ## MEDCouplingFieldDouble.__isub__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__isub__,2) - self.assertRaises(InterpKernelException,f.__isub__,range(5)) - self.assertRaises(InterpKernelException,f.__isub__,arr) - self.assertRaises(InterpKernelException,f.__isub__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__isub__,2) - self.assertRaises(InterpKernelException,f.__isub__,range(5)) - self.assertRaises(InterpKernelException,f.__isub__,arr) - self.assertRaises(InterpKernelException,f.__isub__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f-=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-1,6),(0,7),(1,8),(2,9)]),1e-12)) - f-=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-2,4),(-2,3),(-2,2),(-2,1)]),1e-12)) - f2.setArray(arr) - f-=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-3,2),(-4,-1),(-5,-4),(-6,-7)]),1e-12)) - f-=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2.1,4.8),(-3.1,1.8),(-4.1,-1.2),(-5.1,-4.2),(-6.1,-7.2)]),1e-12)) - ## MEDCouplingFieldDouble.__imul__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__imul__,2) - self.assertRaises(InterpKernelException,f.__imul__,range(5)) - self.assertRaises(InterpKernelException,f.__imul__,arr) - self.assertRaises(InterpKernelException,f.__imul__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__imul__,2) - self.assertRaises(InterpKernelException,f.__imul__,range(5)) - self.assertRaises(InterpKernelException,f.__imul__,arr) - self.assertRaises(InterpKernelException,f.__imul__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f*=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) - f*=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(2,32),(8,72),(18,120),(32,176)]),1e-12)) - f2.setArray(arr) - f*=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(2,64),(16,288),(54,720),(128,1408)]),1e-12)) - f*=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(0.2,12.8),(1.6,57.6),(5.4,144),(12.8,281.6)]),1e-12)) - ## MEDCouplingFieldDouble.__idiv__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__idiv__,2) - self.assertRaises(InterpKernelException,f.__idiv__,range(5)) - self.assertRaises(InterpKernelException,f.__idiv__,arr) - self.assertRaises(InterpKernelException,f.__idiv__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__idiv__,2) - self.assertRaises(InterpKernelException,f.__idiv__,range(5)) - self.assertRaises(InterpKernelException,f.__idiv__,arr) - self.assertRaises(InterpKernelException,f.__idiv__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f/=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,4),(1,4.5),(1.5,5),(2,5.5)]),1e-12)) - f/=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,1.75),(0.25,1),(0.3333333333333333,0.75),(0.375,0.625),(0.4,0.55)]),1e-12)) - f2.setArray(arr) - f/=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0.875),(0.125,0.25),(0.1111111111111111,0.125),(0.09375,0.078125),(0.08,0.055)]),1e-12)) - f/=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,4.375),(1.25,1.25),(1.1111111111111111,0.625),(0.9375,0.390625),(0.8,0.275)]),1e-12)) - ## MEDCouplingFieldDouble.__ipow__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__ipow__,2) - self.assertRaises(InterpKernelException,f.__ipow__,range(5)) - self.assertRaises(InterpKernelException,f.__ipow__,arr) - self.assertRaises(InterpKernelException,f.__ipow__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__ipow__,2) - self.assertRaises(InterpKernelException,f.__ipow__,range(5)) - self.assertRaises(InterpKernelException,f.__ipow__,arr) - self.assertRaises(InterpKernelException,f.__ipow__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f**=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,49),(1,64),(4,81),(9,100),(16,121)]),1e-12)) - ## MEDCouplingFieldDouble.__radd__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__radd__,2) - self.assertRaises(InterpKernelException,f.__radd__,range(5)) - self.assertRaises(InterpKernelException,f.__radd__,arr) - self.assertRaises(InterpKernelException,f.__radd__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__radd__,2) - self.assertRaises(InterpKernelException,f.__radd__,range(5)) - self.assertRaises(InterpKernelException,f.__radd__,arr) - self.assertRaises(InterpKernelException,f.__radd__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2+f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) - ff=arr+f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) - self.assertRaises(InterpKernelException,f.__radd__,f2) - ff=[5,8]+f - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(5,15),(6,16),(7,17),(8,18),(9,19)]),1e-12)) - ### MEDCouplingFieldDouble.__rsub__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__rsub__,2) - self.assertRaises(InterpKernelException,f.__rsub__,range(5)) - self.assertRaises(InterpKernelException,f.__rsub__,arr) - self.assertRaises(InterpKernelException,f.__rsub__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__rsub__,2) - self.assertRaises(InterpKernelException,f.__rsub__,range(5)) - self.assertRaises(InterpKernelException,f.__rsub__,arr) - self.assertRaises(InterpKernelException,f.__rsub__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2-f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,-5),(1,-6),(0,-7),(-1,-8),(-2,-9)]),1e-12)) - ff=arr-f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,-7),(0,-6),(0,-5),(0,-4),(0,-3)]),1e-12)) - self.assertRaises(InterpKernelException,f.__rsub__,f2) - ### MEDCouplingFieldDouble.__rmul__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__rmul__,2) - self.assertRaises(InterpKernelException,f.__rmul__,range(5)) - self.assertRaises(InterpKernelException,f.__rmul__,arr) - self.assertRaises(InterpKernelException,f.__rmul__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__rmul__,2) - self.assertRaises(InterpKernelException,f.__rmul__,range(5)) - self.assertRaises(InterpKernelException,f.__rmul__,arr) - self.assertRaises(InterpKernelException,f.__rmul__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2*f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) - ff=arr*f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) - self.assertRaises(InterpKernelException,f.__rmul__,f2) - ff=f*[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,56),(5,64),(10,72),(15,80),(20,88)]),1e-12)) - ### MEDCouplingFieldDouble.__rdiv__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__rdiv__,2) - self.assertRaises(InterpKernelException,f.__rdiv__,range(5)) - self.assertRaises(InterpKernelException,f.__rdiv__,arr) - self.assertRaises(InterpKernelException,f.__rdiv__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__rdiv__,2) - self.assertRaises(InterpKernelException,f.__rdiv__,range(5)) - self.assertRaises(InterpKernelException,f.__rdiv__,arr) - self.assertRaises(InterpKernelException,f.__rdiv__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(1,6) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2/f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,0.25),(1,0.22222222222222221),(0.66666666666666663,0.20000000000000001),(0.5,0.18181818181818182),(0.40000000000000002,0.16666666666666666)]),1e-12)) - ff=arr/f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(1,0.25),(1,0.44444444444444442),(1,0.59999999999999998),(1,0.72727272727272729),(1,0.83333333333333337)]),1e-12)) - self.assertRaises(InterpKernelException,f.__rdiv__,f2) - pass - - def testSwig2FieldDoubleBuildSubPartRange1(self): - #ON_CELLS - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) ; arr[:,0]=range(7,12) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[1,3]],1e-12)) - # - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) - self.assertEqual(b,slice(2,5,1)) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[2,3,4]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[3,2,1]],1e-12)) - self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[3,2,1],1],1e-12)) - #ON_NODES - f=MEDCouplingFieldDouble(ON_NODES) - f.setMesh(m) - arr=DataArrayDouble(9,2) ; arr[:,0]=range(7,16) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],False)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(6,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[1,2,3,4,6,7]],1e-12)) - # - m2=m.buildPartRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(m2,1e-12)) - m2,b=m.buildPartRangeAndReduceNodes(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],False).isEqual(m2,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([-1,-1,0,1,2,3,4,5,6]))) - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],False).isEqual(a,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([2,3,4,5,6,7,8]))) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],False)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(7,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[2,3,4,5,6,7,8]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],False)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(7,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[1,2,3,4,5,6,7]],1e-12)) - self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[1,2,3,4,5,6,7],1],1e-12)) - #ON_GAUSS_NE - f=MEDCouplingFieldDouble(ON_GAUSS_NE) - f.setMesh(m) - arr=DataArrayDouble(18,2) ; arr[:,0]=range(7,25) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[4,5,6,10,11,12,13]],1e-12)) - # - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) - self.assertEqual(b,slice(7,18,1)) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[7,8,9,10,11,12,13,14,15,16,17]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[10,11,12,13,7,8,9,4,5,6]],1e-12)) - self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[10,11,12,13,7,8,9,4,5,6],1],1e-12)) - #ON_GAUSS_PT - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - f.setMesh(m) - f.setGaussLocalizationOnCells([0,4],[0,0,1,0,1,1,1,0],[1.1,1.1,2.2,2.2],[0.2,0.8]); - f.setGaussLocalizationOnCells([3],[0,0,1,0,1,1,1,0],[1.1,1.1,2.2,2.2,3.,3.],[0.2,0.4,0.4]); - f.setGaussLocalizationOnCells([1],[0,0,1,0,1,0],[1.1,1.1,2.2,2.2,3.,3.,4.,4.],[0.1,0.1,0.4,0.4]); - f.setGaussLocalizationOnCells([2],[0,0,1,0,1,0],[1.1,1.1,2.2,2.2,3.,3.,4.,4.,5.,5.],[0.1,0.1,0.4,0.3,0.1]); - arr=DataArrayDouble(16,2) ; arr[:,0]=range(7,23) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[2,3,4,5,11,12,13]],1e-12)) - # - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) - self.assertEqual(b,slice(6,16,1)) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[6,7,8,9,10,11,12,13,14,15]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[11,12,13,6,7,8,9,10,2,3,4,5]],1e-12)) - self.assertTrue(f[-2:0:-1,0].getArray().isEqual(arr[[11,12,13,6,7,8,9,10,2,3,4,5],0],1e-12)) - pass - - def testSwig2FieldDoubleApplyFuncBug1(self): - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(MEDCouplingDataForTest.build2DTargetMesh_1()) - f.applyFunc(3,700.) - f.checkCoherency() - self.assertEqual(3,f.getArray().getNumberOfComponents()) - f.getArray().rearrange(1) - self.assertTrue(f.getArray().isUniform(700.,1e-10)) - f.getArray().rearrange(3) - f.checkCoherency() - f.applyFunc(4,800.) - f.checkCoherency() - self.assertEqual(4,f.getArray().getNumberOfComponents()) - f.getArray().rearrange(1) - self.assertTrue(f.getArray().isUniform(800.,1e-10)) - f.getArray().rearrange(4) - f.checkCoherency() - pass - - def testSwig2ComputeTupleIdsNearTupleBug1(self): - coords=[1.1,0.0, 1.1,0.0 ]; - coordsArr=DataArrayDouble(coords,2,2); - mesh=MEDCouplingUMesh(); - mesh.setCoords(coordsArr); - points=[1.1, 0.002] - c,cI=mesh.getNodeIdsNearPoints(points,0.00185); - self.assertTrue(c.isEqual(DataArrayInt([]))) - self.assertTrue(cI.isEqual(DataArrayInt([0,0]))) - c,cI=mesh.getNodeIdsNearPoints(points,0.00200000000000001); - self.assertTrue(c.isEqual(DataArrayInt([0,1]))) - self.assertTrue(cI.isEqual(DataArrayInt([0,2]))) - pass - - def testSwig2NonRegressionBugChangeUnderlyingWithZeroCells(self): - coords1=[0.,1.,2.,3.] - coords2=[2.,1.,0.,3.] #0 <==> #2 - # mesh 1 - mesh1=MEDCouplingUMesh.New(); - coordsArr=DataArrayDouble.New(coords1,4,1); - mesh1.setCoords(coordsArr); - mesh1.setMeshDimension(0); - mesh1.allocateCells(0); - mesh1.finishInsertingCells(); - # mesh 2 - mesh2=mesh1.deepCpy(); - coordsArr=DataArrayDouble.New(coords2,4,1); - mesh2.setCoords(coordsArr); - field = mesh1.fillFromAnalytic(ON_NODES,1,"x") - field.checkCoherency() - levOfCheck = 10 - field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) - self.assertTrue( field.getArray().getValues() == coords2 ) - pass - - def testSwig2UMeshDistanceToMesh2(self): - sz=5 - m=MEDCouplingCMesh() - arr=DataArrayDouble(sz+1) ; arr.iota() ; arr/=sz - m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m1=m.computeSkin() - m1.zipCoords() - c=m1.getCoords()[:] - d=2*(c-[0.5,0.5,0.5])+[0.5,0.5,0.5] - time_deb = datetime.now() - #print "go.." - a,b=m1.distanceToPoints(d) - #print 'time spent in distanceToPoints %s ' %str(datetime.now() - time_deb) - time_deb = datetime.now() - a1=DataArrayDouble(len(d)) - b1=DataArrayInt(len(d)) - m1s=[m1[i] for i in xrange(m1.getNumberOfCells())] - for j,pt in enumerate(d): - eter=1e308 - fter=-1 - for i,miter in enumerate(m1s): - e,f=miter.distanceToPoint(pt) - self.assertEqual(0,f) - if e start of specific part of the test - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,4,5,32,0,3,11,7,10,14,15,16,17,18,32,4,1,10,7,11,19,20,21,22,23]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,16,27]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,6,10,1,10,7,2,7,11,12,2,11,8,13]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,10,14]))) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:6].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[6:10].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[10:].isEqual(DataArrayDouble([(0.,0.),(0.5164175471673584,2.),(0.3796918047064557,1.43726403104512),(0.3796918047064557,2.56273596895488),(-1.,1.),(-0.24179122641632078,2.),(0.3796918047064558,1.4372640310451201),(0.,0.5),(-0.5,0.),(1.,1.),(0.5,0.),(0.,0.5),(0.3796918047064558,1.4372640310451201),(0.7582087735836792,2.)]),1e-12)) - self.assertTrue(c.isEqual(DataArrayInt([1,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(1,2),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine7(self): - """ Star pattern (a triangle intersecting another one upside down) """ - coords1 = DataArrayDouble([-2.,1., 2.,1., 0.,-2.], 3,2) - coords2 = DataArrayDouble([0.,2., 2.,-1., -2.,-1., 0.,3.], 4,2) - m1 = MEDCouplingUMesh("triangle", 2) - m2 = MEDCouplingUMesh("tri_line", 1) - m1.setCoords(coords1) - m2.setCoords(coords2) - m1.setConnectivity(DataArrayInt([NORM_TRI3, 0,1,2]), DataArrayInt([0,4])) - m2.setConnectivity(DataArrayInt([NORM_SEG2,0,1,NORM_SEG2,1,2,NORM_SEG2,2,3]), DataArrayInt([0,3,6,9])) - # End of construction of input meshes m1bis and m2 -> start of specific part of the test - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([5,1,9,7,5,2,11,10,5,0,8,12,5,7,9,10,11,12,8]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,19]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,3,7,1,7,9,1,9,4,1,4,10,1,10,11,1,11,5,1,5,12,1,12,8,1,8,6]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27]))) - self.assertTrue(a.getCoords()[:3].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[3:7].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[7:].isEqual(DataArrayDouble([(0.6666666666666666,1.),(-1.,1.),(1.3333333333333333,1.1102230246251565e-16),(0.6666666666666665,-0.9999999999999996),(-0.6666666666666667,-1.),(-1.4285714285714284,0.14285714285714302)]),1e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(c.isEqual(DataArrayInt([0,0,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(0,3),(-1,-1),(-1,-1),(1,3),(-1,-1),(-1,-1),(2,3),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine8(self): - """ Line pieces ending (or fully located) in the middle of a cell """ - m1c = MEDCouplingCMesh() - m1c.setCoordsAt(0,DataArrayDouble([-1., 1.])) - m1c.setCoordsAt(1,DataArrayDouble([-1., 1.])); - m1 = m1c.buildUnstructured() - coords2 = DataArrayDouble([0.,0., 0.,1.5, -1.5,0., 0.5,0.0, 0.0,-0.5, 1.1,-0.6], 6,2) - m2 = MEDCouplingUMesh("piecewise_line", 1) - m2.setCoords(coords2) - c = DataArrayInt([NORM_SEG2,2,1, NORM_SEG2,1,4, NORM_SEG2,4,3, NORM_SEG2,3,5]) - cI = DataArrayInt([0,3,6,9,12]) - m2.setConnectivity(c, cI) - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([5,2,11,10,5,3,13,7,8,12,5,1,0,10,11,12,8,7,13]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,10,19]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,6,10,1,10,11,1,11,5,1,5,12,1,12,8,1,8,7,1,7,13,1,13,9]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24]))) - self.assertTrue(a.getCoords()[:4].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[4:10].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[10:].isEqual(DataArrayDouble([(-1.,0.5),(-0.5,1.),(0.,1.),(1.,-0.5)]),1e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(c.isEqual(DataArrayInt([0,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(1,2),(1,2),(1,2),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine9(self): - """ Intersection with a line whose connectivity is not consecutive """ - m1c = MEDCouplingCMesh() - coordX = DataArrayDouble([-1., 1., 2]) - m1c.setCoordsAt(0,coordX) - coordY = DataArrayDouble([0., 2.]) - m1c.setCoordsAt(1,coordY); - m1 = m1c.buildUnstructured() - # A simple line: - m2 = MEDCouplingUMesh("bla", 1) - coord2 = DataArrayDouble([0.,1.5, 0.5,1., 0.0,0.5, 0.0,3.0, 0.0,-1.0], 5, 2) - conn2 = DataArrayInt([NORM_SEG2,3,0,NORM_SEG3,0,2,1,NORM_SEG2,2,4]) - connI2 = DataArrayInt([0,3,7,10]) - m2.setCoords(coord2) - m2.setConnectivity(conn2, connI2) - # End of construction of input meshes m1bis and m2 -> start of specific part of the test - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,4,5,32,4,1,11,8,6,12,14,15,16,17,18,19,32,0,3,12,6,8,11,20,21,22,23,24,25]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,18,31]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,9,12,1,12,6,2,6,8,13,1,8,11,1,11,10]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,10,13,16]))) - self.assertTrue(a.getCoords()[:6].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[6:11].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[11:].isEqual(DataArrayDouble([(0.,0.),(0.,2.),(0.5,1.),(1.,1.),(0.5,0.),(0.,0.25),(0.5,1.),(0.,1.75),(0.5,2.),(-1.,1.),(-0.5,2.),(0.,1.75),(0.5,1.),(0.,0.25),(-0.5,0.)]),1e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(c.isEqual(DataArrayInt([1,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(1,2),(1,2),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine10(self): - """ Intersection between a circle and various lines """ - eps = 1.0e-8 - m_circ = MEDCouplingDataForTest.buildCircle2(0.0, 0.0, 2.0) - coords = [0.0,3.0,0.0,-3.0] - connec = [0,1] - m_line = MEDCouplingUMesh("seg", 1) - m_line.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - m_line.setCoords(meshCoords) - m_line.insertNextCell(NORM_SEG2, connec) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m_circ, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m_circ.getNumberOfNodes()].isEqual(m_circ.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m_circ.getNumberOfNodes():m_circ.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.414213562373095),(0.,2.),(-1.414213562373095,1.4142135623730951),(-2.,0.),(-1.4142135623730954,-1.414213562373095),(0.,-2.),(1.4142135623730947,-1.4142135623730954),(0.,3.),(0.,-3.),(0.,-2.),(0.,2.),(2.,0.),(0.7653668647301797,-1.8477590650225735),(0.,0.),(0.7653668647301797,1.8477590650225735),(-2,0.),(-0.7653668647301795,1.8477590650225735),(0.,0.),(-0.7653668647301795,-1.8477590650225735)]),1e-12)) - self.assertEqual([32,1,7,10,11,12,13,14,15,32,5,3,11,10,16,17,18,19],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,18], a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,8,11,1,11,10,1,10,9],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(a.getCoords()[:8].isEqual(m_circ.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[8:10].isEqual(m_line.getCoords(),1e-12)) - coo_tgt = DataArrayDouble([2.,0.,1.4142135623730951,1.414213562373095,1.2246467991473532e-16,2.,-1.414213562373095,1.4142135623730951,-2.,0.,-1.4142135623730954,-1.414213562373095,-3.6739403974420594e-16,-2.,1.4142135623730947,-1.4142135623730954,0.,3.,0.,-3.,0.,-2.,0.,2.,2.,0.,0.7653668647301797,-1.8477590650225735,0.,0.,0.7653668647301797,1.8477590650225735,-2.,0.,-0.7653668647301795,1.8477590650225735,0.,0.,-0.7653668647301795,-1.8477590650225735]) - self.assertTrue(a.getCoords().isEqualWithoutConsideringStr(coo_tgt,1.0e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertEqual([0,0],c.getValues()) - self.assertEqual([-1,-1,0,1,-1,-1],d.getValues()) - - def testSwig2Intersect2DMeshWith1DLine11(self): - """ Quad line re-entering a square cell """ - eps = 1.0e-8 - m = MEDCouplingUMesh("box", 2) - m.setCoords(DataArrayDouble([-1., -1., -1., 1., 1., 1., 1., -1.0],4,2)) - c, cI = [NORM_POLYGON, 0, 1, 2, 3], [0, 5] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [0., 1.3, -1.3, 0., -0.6, 0.6, 0., -1.3, -0.5, -0.5] - connec2, cI2 = [NORM_SEG3, 0, 1, 2, NORM_SEG3, 1, 3, 4], [0,4,8] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(0.,1.3),(-1.3,0.),(-0.6,0.6),(0.,-1.3),(-0.5,-0.5),(-1.,0.23453685964236054),(-1.,-0.13033276368660177),(-0.2345368596423598,1.),(-0.1303327636866019,-1.),(-0.11489196370692323,1.1481421036683868),(-0.6,0.6),(-1.1481421036683859,0.11489196370692323),(-1.147455889106615,-0.0593103465193594),(-0.5,-0.5),(-0.0593103465193594,-1.147455889106615),(1.,0.),(0.4348336181566991,-1.),(-0.5651663818433009,-1.),(-1.,-0.5651663818433009),(-1.,0.05210204797787939),(-0.6,0.6),(0.3827315701788201,1.),(-0.6172684298211799,1.),(-0.6,0.6),(-1.,0.6172684298211802),(-0.6,0.6),(0.3827315701788201,1.),(1.,0.),(0.4348336181566991,-1.),(-0.5,-0.5),(-1.,0.05210204797787939),(-1.,-0.5651663818433009),(-0.5,-0.5),(-0.5651663818433009,-1.)]),1e-12)) - self.assertEqual([32,9,11,2,3,12,10,29,30,31,32,33,34,32,0,10,12,35,36,37,32,1,11,9,26,27,28],a.getNodalConnectivity().getValues()) - self.assertEqual([0,13,20,27],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([2,4,11,13,2,11,9,14,2,9,5,15,2,5,10,16,2,10,12,17,2,12,7,18],b.getNodalConnectivity().getValues()) - self.assertEqual([0,4,8,12,16,20,24],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(a.getCoords()[:4].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[4:9].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(DataArrayInt([0,0,0]).isEqual(c)) - self.assertTrue(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(0,1),(-1,-1)]).isEqual(d)) - pass - - def testSwig2Intersect2DMeshWith1DLine12(self): - """ Two squares one in the other intersected by an horizontal line """ - eps = 1.0e-8 - m = MEDCouplingUMesh("boxbox", 2) - m.setCoords(DataArrayDouble([-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,-0.25,-0.25,-0.25,0.25,0.25,0.25,0.25,-0.25],8,2)) - c = [NORM_POLYGON, 4, 5, 6, 7, NORM_POLYGON, 0, 1, 5, 4, NORM_POLYGON, 1, 2, 3, 0, 4, 7, 6, 5] - cI = [0, 5, 10, 19] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [-1., 0.25, 1., 0.25] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh.New("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - m_line2 = m_line.deepCpy() - m2 = m.deepCpy() - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-0.5,-0.5),(-0.5,0.5),(0.5,0.5),(0.5,-0.5),(-0.25,-0.25),(-0.25,0.25),(0.25,0.25),(0.25,-0.25),(-1.,0.25),(1.,0.25),(-0.5,0.25),(0.5,0.25)]),1e-12)) - self.assertEqual([5,4,5,6,7,5,1,5,10,5,4,0,10,5,5,5,1,2,11,6,5,3,0,4,7,6,11],a.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,14,20,27],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,8,10,1,10,5,1,5,6,1,6,11,1,11,9],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine13(self): - """ A square (side length) in a circle intersected by a simple horizontal line """ - import math - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - sq2 = math.sqrt(2.0) - soth = (sq2+1.0)/2.0 - coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., - 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [-2., 1., 2., 1.0] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(-2.,1.),(2.,1.),(1.7320508075688772,1.),(-1.7320508075688772,1.),(-1.2071067811865475,1.2071067811865475),(-1.3660254037844386,1.),(-1.58670668058247,1.2175228580174415),(0.,-1.),(1.,0.),(1.2071067811865475,1.2071067811865475),(1.5867066805824703,1.2175228580174413),(1.9828897227476205,-0.26105238444010315),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844386,1.),(-1.,0.),(1.5867066805824703,1.2175228580174413),(1.3660254037844386,1.),(1.2071067811865475,1.2071067811865475),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844386,1.),(-1.,0.),(0.,-1.),(1.,0.),(1.3660254037844386,1.),(1.9828897227476205,-0.26105238444010315)]),1e-12)) - self.assertEqual([32,8,9,10,11,12,13,14,15,32,3,1,10,9,2,17,13,16,32,3,9,21,22,23,24,32,1,20,10,34,35,36,32,7,5,21,9,8,11,10,20,37,38,39,40,41,42,43,44],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,18,25,32,49],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,21,1,21,9,1,9,10,1,10,20,1,20,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,2,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(2,4),(1,0),(3,4),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine14(self): - """ A circle in a circle intersected by a simple horizontal line, not tangent to the circles """ - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - coo = [2.,0.,1.4142135623730951,1.414213562373095,0.,2.,-1.414213562373095,1.4142135623730951,-2.,0.,-1.4142135623730954,-1.414213562373095,0.,-2., - 1.4142135623730947,-1.4142135623730954,1.,0.,0.7071067811865476,0.7071067811865475,0.,1.,-0.7071067811865475,0.7071067811865476,-1.,0.,-0.7071067811865477,-0.7071067811865475, - 0.,-1.,0.7071067811865474,-0.7071067811865477,1.060660171779821,-1.0606601717798214,-1.0606601717798214,-1.0606601717798212] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 15, 13, 11, 9, 14, 12, 10, 8, NORM_QPOLYG, 7, 5, 13, 15, 6, 17, 14, 16, NORM_QPOLYG, 5, 3, 1, 7, 15, 9, 11, 13, 4, 2, 0, 16, 8, 10, 12, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [-2., 0., 2., 0.] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh.New("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.414213562373095),(0.,2.),(-1.414213562373095,1.4142135623730951),(-2.,0.),(-1.4142135623730954,-1.414213562373095),(0.,-2.),(1.4142135623730947,-1.4142135623730954),(1.,0.),(0.7071067811865476,0.7071067811865475),(0.,1.),(-0.7071067811865475,0.7071067811865476),(-1.,0.),(-0.7071067811865477,-0.7071067811865475),(0.,-1.),(0.7071067811865474,-0.7071067811865477),(1.060660171779821,-1.0606601717798214),(-1.0606601717798214,-1.0606601717798212),(-2.,0.),(2.,0.),(-1.,0.),(1.,0.),(0.,2.),(1.8477590650225735,0.7653668647301795),(1.8477590650225735,-0.7653668647301797),(1.060660171779821,-1.0606601717798214),(0.9238795325112867,-0.38268343236508984),(0.9238795325112867,0.3826834323650897),(0.,1.),(-0.9238795325112867,0.3826834323650896),(-1.5,0.),(-1.8477590650225735,0.7653668647301792),(-1.0606601717798214,-1.0606601717798212),(-1.8477590650225733,-0.7653668647301799),(-1.5,0.),(-0.9238795325112866,-0.38268343236508995),(0.,1.),(-0.9238795325112867,0.3826834323650896),(-1.5,0.),(-1.8477590650225735,0.7653668647301792),(0.,2.),(1.8477590650225735,0.7653668647301795),(1.5,0.),(0.9238795325112867,0.3826834323650897),(1.060660171779821,-1.0606601717798214),(0.9238795325112867,-0.38268343236508984),(1.5,0.),(1.8477590650225735,-0.7653668647301797),(0.,1.),(0.9238795325112867,0.3826834323650897),(0.,0.),(-0.9238795325112867,0.3826834323650896),(0.,-1.),(-0.9238795325112866,-0.38268343236508995),(0.,0.),(0.9238795325112867,-0.38268343236508984)]),1e-12)) - self.assertEqual([32,7,5,13,15,6,17,14,16,32,9,11,20,18,3,1,19,21,36,37,38,39,40,41,42,43,32,7,15,21,19,44,45,46,47,32,13,5,18,20,32,33,34,35,32,11,9,21,20,48,49,50,51,32,15,13,20,21,52,53,54,55],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,26,35,44,53,62],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,20,1,20,21,1,21,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([1,2,2,2,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(1,3),(4,5),(1,2)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine15(self): - """ Same as testSwig2Intersect2DMeshWith1DLine13 except that the line is colinear AND splits on of the common edge of 2D mesh.""" - import math - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - sq2 = math.sqrt(2.0) - soth = (sq2+1.0)/2.0 - coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., - 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [(-2., 1.),(2.,1.),(0.,1)] - connec2, cI2 = [NORM_SEG2, 0, 2, NORM_SEG2, 2, 1], [0,3,6] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(-2.,1.),(2.,1.),(0.,1.),(1.7320508075688776,1.),(-1.7320508075688776,1.),(-0.5,1.),(0.5,1.),(0.5,1.),(-0.5,1.),(-1.2071067811865475,1.2071067811865475),(-1.3660254037844388,1.),(-1.58670668058247,1.2175228580174415),(0.,-1.),(1.,0.),(1.2071067811865475,1.2071067811865475),(1.5867066805824703,1.2175228580174413),(1.9828897227476205,-0.26105238444010315),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844388,1.),(-1.,0.),(1.5867066805824703,1.2175228580174413),(1.3660254037844388,1.),(1.2071067811865475,1.2071067811865475),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844388,1.),(-1.,0.),(0.,-1.),(1.,0.),(1.3660254037844388,1.),(1.9828897227476205,-0.26105238444010315)]),1e-12)) - self.assertEqual([32,8,9,20,10,11,12,23,24,14,15,32,3,1,10,20,9,2,17,25,26,16,32,3,9,22,27,28,29,32,1,21,10,39,40,41,32,7,5,22,9,8,11,10,21,42,43,44,45,46,47,48,49],a.getNodalConnectivity().getValues()) - self.assertEqual([0,11,22,29,36,53],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,22,1,22,9,1,9,20,1,20,10,1,10,21,1,21,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15,18],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,2,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(2,4),(1,0),(1,0),(3,4),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine16(self): - """ Same than testSwig2Intersect2DMeshWith1DLine13 except it is a vertical line. Non regression test.""" - import math - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - sq2 = math.sqrt(2.0) - soth = (sq2+1.0)/2.0 - coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., - 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [1., 2., 1., -2.] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2., 0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(1.,2.),(1.,-2.),(1.,1.7320508075688772),(1.,-1.7320508075688772),(1.2071067811865475,1.2071067811865475),(1.,1.3660254037844386),(1.217522858017441,1.5867066805824703),(-1.2071067811865475,1.2071067811865475),(-0.2610523844401028,1.9828897227476208),(1.,1.3660254037844386),(0.,1.),(1.2071067811865475,1.2071067811865475),(2.,0.),(1.217522858017441,-1.5867066805824703),(1.,-1.3660254037844386),(1.,0.),(-2.,0.),(-1.2071067811865475,1.2071067811865475),(-1.,0.),(0.,-1.),(1.,-1.3660254037844386),(-0.2610523844401028,-1.9828897227476208)]),1e-12)) - self.assertEqual([32,8,9,10,11,12,13,14,15,32,1,10,20,22,23,24,32,9,3,20,10,25,26,27,28,32,10,1,7,21,11,29,30,31,32,33,32,5,3,9,8,11,21,34,35,36,37,38,39],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,16,25,36,49],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,20,1,20,10,1,10,11,1,11,21,1,21,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)]))) - pass - - def testOrderConsecutiveCells1D1(self): - """A line in several unconnected pieces:""" - m2 = MEDCouplingUMesh.New("bla", 1) - c = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,3,2, NORM_SEG2,3,4, - NORM_SEG3,5,7,6, NORM_SEG3,7,9,8, NORM_SEG2,9,10, - NORM_SEG2,11,12,NORM_SEG2,12,13, - NORM_SEG2,14,15]) - cI = DataArrayInt([0,3,7,10,14,18,21,24,27,30]) - coords2 = DataArrayDouble([float(i) for i in range(32)], 16,2) - m2.setCoords(coords2); - m2.setConnectivity(c, cI); - m2.checkCoherency2(1.0e-8); - - # Shuffle a bit :-) - m2.renumberCells(DataArrayInt([0,3,6,8,1,4,7,5,2]), True); - res = m2.orderConsecutiveCells1D() - expRes = [0,3,6,8,1,4,2,7,5] - self.assertEqual(m2.getNumberOfCells(),res.getNumberOfTuples()) - self.assertEqual(expRes, res.getValues()) - - # A closed line (should also work) - m3 = MEDCouplingUMesh.New("bla3", 1) - conn3A = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,3,2, NORM_SEG2,3,0]) - coord3 = coords2[0:5] - c.reAlloc(10) - cI.reAlloc(4) - - m3.setCoords(coord3) - m3.setConnectivity(conn3A, cI) - m3.checkCoherency2(1.0e-8) - res2 = m3.orderConsecutiveCells1D() - expRes2 = [0,1,2] - self.assertEqual(m3.getNumberOfCells(),res2.getNumberOfTuples()) - self.assertEqual(expRes2, res2.getValues()) - pass - - def testDADApplyFuncOnThis1(self): - d=DataArrayDouble(5) ; d.iota(0.) - d.applyFuncOnThis("2*x+1") - self.assertTrue(d.isEqual(DataArrayDouble([1.,3.,5.,7.,9.]),1e-12)) - d=DataArrayDouble(6) ; d.iota(0.) ; d.rearrange(2) - d.applyFuncOnThis("2*x+1") - self.assertTrue(d.isEqual(DataArrayDouble([1.,3.,5.,7.,9.,11.],3,2),1e-12)) - d.applyFuncOnThis("1+2*3") - self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.)]),1e-12)) - pass - - def testSwig2PointSetComputeFetchedNodeIds1(self): - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m0=m[[0,1,5,6,25,26,30,31,124]] - ref=DataArrayInt([0,1,2,6,7,8,12,13,14,36,37,38,42,43,44,48,49,50,72,73,74,78,79,80,84,85,86,172,173,178,179,208,209,214,215]) - self.assertTrue(m0.computeFetchedNodeIds().isEqual(ref)) - self.assertTrue(MEDCoupling1SGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) - self.assertEqual(m0.getAllGeoTypes(),[NORM_HEXA8]) - m0.convertAllToPoly() - self.assertEqual(m0.getAllGeoTypes(),[NORM_POLYHED]) - self.assertTrue(MEDCoupling1DGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) - pass - - def testSwig2PartDefinition1(self): - pd=PartDefinition.New(5,22,3) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) - self.assertEqual(pd.getNumberOfElems(),6) - self.assertEqual(pd.getEffectiveStop(),23) - pd=PartDefinition.New(5,23,3) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) - self.assertEqual(pd.getNumberOfElems(),6) - self.assertEqual(pd.getEffectiveStop(),23) - self.assertEqual(pd.getSlice(),slice(5,23,3)) - pd=PartDefinition.New(5,22,1) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) - self.assertEqual(pd.getNumberOfElems(),17) - self.assertEqual(pd.getEffectiveStop(),22) - pd=PartDefinition.New(5,23,3)+PartDefinition.New(23,27,3) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertEqual(pd.getNumberOfElems(),8) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20,23,26]))) - self.assertEqual(pd.getEffectiveStop(),29) - pd=SlicePartDefinition(5,22,1) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) - self.assertEqual(pd.getNumberOfElems(),17) - self.assertEqual(pd.getEffectiveStop(),22) - d=DataArrayInt([2,4,5,6,10]) - pd=PartDefinition.New(d) - self.assertTrue(isinstance(pd,DataArrayPartDefinition)) - self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) - pd=DataArrayPartDefinition(d) - self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) - pd=DataArrayPartDefinition(d)+DataArrayPartDefinition(DataArrayInt([12,14,20])) - self.assertTrue(isinstance(pd,DataArrayPartDefinition)) - self.assertEqual(pd.getNumberOfElems(),8) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([2,4,5,6,10,12,14,20]))) - pass - - def testSwig2SortEachPairToMakeALinkedList1(self): - d=DataArrayInt([(50,49),(50,51),(51,52),(53,52),(53,54),(55,54),(55,56),(56,57),(58,57),(58,59),(60,59),(60,61),(61,62),(63,62),(63,64),(65,64),(65,66),(66,67)]) - d.sortEachPairToMakeALinkedList() - self.assertTrue(d.isEqual(DataArrayInt([(49,50),(50,51),(51,52),(52,53),(53,54),(54,55),(55,56),(56,57),(57,58),(58,59),(59,60),(60,61),(61,62),(62,63),(63,64),(64,65),(65,66),(66,67)]))) - pass - - def testSwig2DAIIsRange(self): - d=DataArrayInt([2,6,10]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(2,11,4)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([2,7,10]) - a,b=d.isRange() - self.assertTrue(not a) - self.assertTrue(b is None) - # - d=DataArrayInt([22,17,12]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(22,11,-5)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([22,16,12]) - a,b=d.isRange() - self.assertTrue(not a) - self.assertTrue(b is None) - # - d=DataArrayInt([33]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(33,34,1)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(0,0,1)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([2,6,10,2]) - a,b=d.isRange() - self.assertTrue(not a) - self.assertTrue(b is None) - pass - - def testSwig2PartDefinitionComposeWith1(self): - f=PartDefinition.New(DataArrayInt([0,1,2,3,6,7,8,9])) - g=PartDefinition.New(4,14,1) - g2=g.deepCpy() - self.assertTrue(g2.isEqual(g)[0]) - h=f.composeWith(g) - self.assertTrue(isinstance(h,DataArrayPartDefinition)) - self.assertTrue(h.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13]))) - f2=f.tryToSimplify() - g2=g.tryToSimplify() - self.assertEqual(f2.getHiddenCppPointer(),f.getHiddenCppPointer())# same because no simplification due to content of array - self.assertEqual(g2.getHiddenCppPointer(),g.getHiddenCppPointer())# same because no simplification linked to type of PartDef - p=PartDefinition.New(DataArrayInt([2,6,10])) - p2=p.tryToSimplify() - self.assertNotEqual(p2.getHiddenCppPointer(),p.getHiddenCppPointer()) - self.assertTrue(isinstance(p2,SlicePartDefinition)) - self.assertEqual(p2.getSlice(),slice(2,11,4)) - self.assertTrue(p2.isEqual(SlicePartDefinition(2,11,4))[0]) - self.assertTrue(p2.isEqual(p2.deepCpy())[0]) - self.assertTrue(not p2.isEqual(SlicePartDefinition(1,11,4))[0]) - self.assertTrue(not p2.isEqual(SlicePartDefinition(2,10,4))[0]) - self.assertTrue(not p2.isEqual(SlicePartDefinition(2,11,3))[0]) - pass - - def testSwig2DAIGetIdsStrictlyNegative1(self): - d=DataArrayInt([4,-5,-1,0,3,99,-7]) - self.assertTrue(d.getIdsStrictlyNegative().isEqual(DataArrayInt([1,2,6]))) - pass - - def testSwig2DAIReplaceOneValByInThis1(self): - d=DataArrayInt([4,-5,-1,0,-5,99,-7,5]) - d.replaceOneValByInThis(-5,900) - self.assertTrue(d.isEqual(DataArrayInt([4,900,-1,0,900,99,-7,5]))) - pass - - def testSwig2DAIGetMinMaxValues1(self): - d=DataArrayInt([4,-5,-1,0,3,99,-7]) - a,b=d.getMinMaxValues() - self.assertEqual(a,-7) - self.assertEqual(b,99) - pass - - def testSwig2DAIBuildUniqueNotSorted1(self): - d=DataArrayInt([-5,3,2,-1,2,3,-6,4,2,-5,3,7]) - self.assertTrue(d.buildUniqueNotSorted().isEqual(DataArrayInt([-5,3,2,-1,-6,4,7]))) - pass - - def testSwig2UMeshChangeOrientationOfCells1(self): - """ Here testing changeOrientationOfCell method on unstructured meshes lying on no coords.""" - m=MEDCouplingUMesh("mesh",1) - c=DataArrayInt([NORM_SEG2,4,5,NORM_SEG2,10,8,NORM_SEG3,20,7,33,NORM_SEG3,13,15,12,NORM_SEG2,3,2,NORM_SEG4,5,6,8,10,NORM_SEG4,34,33,3,2]) - cI=DataArrayInt([0,3,6,10,14,17,22,27]) - m.setConnectivity(c,cI) - m.changeOrientationOfCells() - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_SEG2,5,4,NORM_SEG2,8,10,NORM_SEG3,7,20,33,NORM_SEG3,15,13,12,NORM_SEG2,2,3,NORM_SEG4,6,5,10,8,NORM_SEG4,33,34,2,3]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(cI)) - # testing 2D cells - m=MEDCouplingUMesh("mesh",2) - c=DataArrayInt([NORM_TRI3,0,1,2,NORM_QUAD4,3,4,5,6,NORM_POLYGON,7,8,9,10,11,NORM_TRI6,12,13,14,15,16,17,NORM_QUAD8,18,19,20,21,22,23,24,25,NORM_QPOLYG,26,27,28,29,30,31,32,33,34,35]) - cI=DataArrayInt([0,4,9,15,22,31,42]) - m.setConnectivity(c,cI) - m.changeOrientationOfCells() - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_TRI3,0,2,1,NORM_QUAD4,3,6,5,4,NORM_POLYGON,7,11,10,9,8,NORM_TRI6,12,14,13,17,16,15,NORM_QUAD8,18,21,20,19,25,24,23,22,NORM_QPOLYG,26,30,29,28,27,35,34,33,32,31]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(cI)) - pass - - def testSwig2StructuredMeshCellLocation1(self): - # 3D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(3) ; arrZ.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - li=[] - liExp3D=[(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(0,0,1),(1,0,1),(2,0,1),(3,0,1),(0,1,1),(1,1,1),(2,1,1),(3,1,1),(0,2,1),(1,2,1),(2,2,1),(3,2,1)] - self.assertEqual(24,m.getNumberOfCells()) - for i in xrange(m.getNumberOfCells()): - li.append(m.getLocationFromCellId(i)) - pass - self.assertEqual(liExp3D,li) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,24) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - # 2D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - li=[] - liExp2D=[(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2)] - self.assertEqual(12,m.getNumberOfCells()) - for i in xrange(m.getNumberOfCells()): - li.append(m.getLocationFromCellId(i)) - pass - self.assertEqual(liExp2D,li) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,12) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - # 1D - arrX=DataArrayDouble(5) ; arrX.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX) - self.assertEqual(4,m.getNumberOfCells()) - for i in xrange(m.getNumberOfCells()): - self.assertEqual((i,),m.getLocationFromCellId(i)) - pass - self.assertRaises(InterpKernelException,m.getLocationFromCellId,4) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - pass - - def testSwig2StructuredMeshNodeLocation1(self): - # 3D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(3) ; arrZ.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - li=[] - liExp3D=[(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(0,0,1),(1,0,1),(2,0,1),(3,0,1),(4,0,1),(0,1,1),(1,1,1),(2,1,1),(3,1,1),(4,1,1),(0,2,1),(1,2,1),(2,2,1),(3,2,1),(4,2,1),(0,3,1),(1,3,1),(2,3,1),(3,3,1),(4,3,1),(0,0,2),(1,0,2),(2,0,2),(3,0,2),(4,0,2),(0,1,2),(1,1,2),(2,1,2),(3,1,2),(4,1,2),(0,2,2),(1,2,2),(2,2,2),(3,2,2),(4,2,2),(0,3,2),(1,3,2),(2,3,2),(3,3,2),(4,3,2)] - self.assertEqual(60,m.getNumberOfNodes()) - for i in xrange(m.getNumberOfNodes()): - li.append(m.getLocationFromNodeId(i)) - pass - self.assertEqual(liExp3D,li) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,60) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,-1) - # 2D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - li=[] - liExp2D=[(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2),(0,3),(1,3),(2,3),(3,3),(4,3)] - self.assertEqual(20,m.getNumberOfNodes()) - for i in xrange(m.getNumberOfNodes()): - li.append(m.getLocationFromNodeId(i)) - pass - self.assertEqual(liExp2D,li) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,20) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,-1) - # 1D - arrX=DataArrayDouble(5) ; arrX.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX) - self.assertEqual(5,m.getNumberOfNodes()) - for i in xrange(m.getNumberOfNodes()): - self.assertEqual((i,),m.getLocationFromNodeId(i)) - pass - self.assertRaises(InterpKernelException,m.getLocationFromCellId,5) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - pass - - def testSwig2DataArrayPrintNotTooLong1(self): - """ Now that DataArrayDouble and DataArrayInt and pickelized they can appear in YACS ports. Avoid to have too heavy string representation of them.""" - d=DataArrayDouble(2000) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertEqual(st0,st1) # 1000 tuples ( >=0 and <= 1000) -> str(d)==d.repr() - self.assertEqual(st1,st2) - # - d=DataArrayDouble(2002) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertNotEqual(st0,st1) # 1001 tuples ( > 1000) -> str(d)==d.reprNotTooLong() - self.assertEqual(st1,st2) - self.assertIn(len(st2),xrange(0,1000)) # no more than 1000 characters - ## Now for DataArrayInt - d=DataArrayInt(2000) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertEqual(st0,st1) # 1000 tuples ( >=0 and <= 1000) -> str(d)==d.repr() - self.assertEqual(st1,st2) - # - d=DataArrayInt(2002) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertNotEqual(st0,st1) # 1001 tuples ( > 1000) -> str(d)==d.reprNotTooLong() - self.assertEqual(st1,st2) - self.assertIn(len(st2),xrange(0,1000)) # no more than 1000 characters - pass - - def testExtrudedMeshWithoutZipCoords1(self): - """This test checks that MEDCouplingUMesh.buildExtrudedMesh do not perform a zipCoords.""" - arr=DataArrayDouble([(0.,0.),(1.,0.),(2.,0.),(3.,0.)]) - m=MEDCouplingUMesh("mesh",1) ; m.setCoords(arr) - m.allocateCells() - m.insertNextCell(NORM_SEG2,[1,2]) - arr1D=DataArrayDouble([(0.,0.),(0.,1.5),(0.,2.)]) - m1D=MEDCouplingUMesh("mesh1D",1) ; m1D.setCoords(arr1D) - m1D.allocateCells() - m1D.insertNextCell(NORM_SEG2,[0,1]) - m1D.insertNextCell(NORM_SEG2,[1,2]) - m2D=m.buildExtrudedMesh(m1D,0) - self.assertEqual(m.getCoords().getHiddenCppPointer(),m2D.getCoords().getHiddenCppPointer()) - coo=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(0,1.5),(1,1.5),(2,1.5),(3,1.5),(0,2),(1,2),(2,2),(3,2)]) - self.assertTrue(m.getCoords().isEqual(coo,1e-12)) - self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([4,1,2,6,5,4,5,6,10,9]))) - self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10]))) - pass - - def testPointSetAreAllNodesFetched1(self): - m=MEDCouplingCMesh() ; arr=DataArrayDouble(10) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() - self.assertTrue(m.areAllNodesFetched()) - m2=m[[0,2,3,4,5]] - self.assertTrue(not m2.areAllNodesFetched()) - m2.zipCoords() - self.assertTrue(m2.areAllNodesFetched()) - pass - - def testMEDCouplingPointSetComputeDiameterField1(self): - arrX=DataArrayDouble([0.,1.1,1.7,2.1]) - arrY=DataArrayDouble([0.,0.7,0.8,1.9]) - arrZ=DataArrayDouble([0.,1.3,2.1,2.4]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) ; m=m.buildUnstructured() - f=m.computeDiameterField() - f.checkCoherency() - exp=DataArrayDouble([1.8411952639521971,1.5937377450509227,1.5297058540778357,1.705872210923198,1.4352700094407325,1.3638181696985856,2.0273134932713295,1.8055470085267789,1.7492855684535902,1.5297058540778357,1.2206555615733703,1.1357816691600546,1.3638181696985856,1.004987562112089,0.9,1.7492855684535902,1.4866068747318506,1.4177446878757824,1.3379088160259651,0.9695359714832656,0.8602325267042626,1.1445523142259597,0.6782329983125266,0.5099019513592785,1.5842979517754858,1.2884098726725124,1.208304597359457]) - self.assertTrue(exp.isEqual(f.getArray(),1e-12)) - m1=m[::2] - m2=m[1::2] - m2.simplexize(PLANAR_FACE_5) - m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) - f=m3.computeDiameterField() - f.checkCoherency() - exp2=DataArrayDouble([1.8411952639521971,1.5297058540778357,1.4352700094407325,2.0273134932713295,1.7492855684535902,1.2206555615733703,1.3638181696985856,0.9,1.4866068747318506,1.3379088160259651,0.8602325267042626,0.6782329983125266,1.5842979517754858,1.208304597359457,1.47648230602334,1.47648230602334,1.47648230602334,1.47648230602334,1.47648230602334,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.70293863659264,1.70293863659264,1.70293863659264,1.70293863659264,1.70293863659264,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.063014581273465,1.063014581273465,1.063014581273465,1.063014581273465,1.063014581273465,1.0,1.0,1.0,1.0,1.0,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.3601470508735443,1.3601470508735443,1.3601470508735443,1.3601470508735443,1.3601470508735443,0.9219544457292886,0.9219544457292886,0.9219544457292886,0.9219544457292886,0.9219544457292886,1.140175425099138,1.140175425099138,1.140175425099138,1.140175425099138,1.140175425099138,0.5,0.5,0.5,0.5,0.5,1.2529964086141667,1.2529964086141667,1.2529964086141667,1.2529964086141667,1.2529964086141667]) - self.assertTrue(exp2.isEqual(f.getArray(),1e-12)) - # TRI3 - spacedim = 2 - coo=DataArrayDouble([(1,1),(5,1.9),(2.1,3)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TRI3) ; m.setCoords(coo) - for c in [[0,1,2],[0,2,1],[2,1,0]]: - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],4.1,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],4.1,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],4.1,12) - # TRI3 - spacedim = 3 - coo=DataArrayDouble([(1.3198537928820775,1.0991902391274959,-0.028645697595823361),(5.2486835106806335,2.2234012799688281,0.30368935050077939),(2.2973688139447361,3.1572023778066649,0.10937756365410012)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TRI3) ; m.setCoords(coo) - for c in [[0,1,2],[0,2,1],[2,1,0]]: - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],4.1,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],4.1,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],4.1,12) - # QUAD4 - spacedim = 2 - coo=DataArrayDouble([(0,2),(2,0),(6,4),(4,9)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.setCoords(coo) - exp3=sqrt(85.) - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - # QUAD4 - spacedim = 3 - coo=DataArrayDouble([(0.26570992384234871,2.0405889913271817,-0.079134238105786903),(2.3739976619218064,0.15779148692781009,0.021842842914139737),(6.1207841448393197,4.3755532938679655,0.43666375769970678),(3.8363255342943359,9.2521096041694229,0.41551170895942313)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.setCoords(coo) - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - # PENTA6 - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(0,1,0),(0,0,2),(1,0,2),(0,1,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.28594726851554486,-0.23715005500928255,-0.10268080010083136),(0.6167364988633947,-0.008923258436324799,-0.08574087516687756),(-0.6132873463333834,0.6943403970881654,-0.2806118260037991),(-0.40705974936532896,-0.05868487929989308,1.7724055544436323),(0.5505955507861958,0.19145393798144705,1.8788156352163994),(-0.6092686217773406,0.812502961290914,1.685712743757831)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_PENTA6) ; m.setCoords(coo) - exp4=2.5041256256889888 - self.assertAlmostEqual(exp4,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(3): - c=[(elt+delta)%3 for elt in xrange(3)] - c+=[elt+3 for elt in c] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp4,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp4,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp4,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp4,12) - # HEXA8 - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0,0,2),(1,0,2),(1,1,2),(0,1,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.21266406388867243,-0.3049569460042527,-0.11012394815006032),(0.7641037943272584,-0.06990814759929553,-0.0909613877456491),(0.47406560768559974,0.8681310650341907,-0.2577311403703061),(-0.5136830410871793,0.644390554940524,-0.21319015989794698),(-0.4080167737381202,-0.12853761670628505,1.7869166291979348),(0.5650318811550441,0.20476257733110748,1.8140158890821603),(0.3230844436386215,1.1660778242678538,1.7175073141333406),(-0.6656588358432984,0.918357550969698,1.7566470691880265)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_HEXA8) ; m.setCoords(coo) - exp5=2.5366409441884215 - self.assertAlmostEqual(exp5,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - c+=[elt+4 for elt in c] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp5,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp5,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp5,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp5,12) - # PYRA5 (1) 5th node is further - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0.5,0.5,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.31638393672228626,-0.3157865246451914,-0.12555467233075002),(0.7281379795666488,0.03836511217237115,-0.08431662762197323),(0.4757967840735147,0.8798897996143908,-0.2680890320119049),(-0.5386339871809047,0.5933159894201252,-0.2975311238319419),(0.012042592988768974,0.534282135495012,1.7859521682027926)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_PYRA5) ; m.setCoords(coo) - exp6=2.1558368027391386 - self.assertAlmostEqual(exp6,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - c+=[4] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp6,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp6,12) - pass - # PYRA5 (2) 5th node is closer - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0.5,0.5,0.1)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.31638393672228626,-0.3157865246451914,-0.12555467233075002),(0.7281379795666488,0.03836511217237115,-0.08431662762197323),(0.4757967840735147,0.8798897996143908,-0.2680890320119049),(-0.5386339871809047,0.5933159894201252,-0.2975311238319419),(0.092964408350795,0.33389670321297005,-0.10171764888060142)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_PYRA5) ; m.setCoords(coo) - exp7=1.4413563787228953 - self.assertAlmostEqual(exp7,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - c+=[4] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp7,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp7,12) - pass - # TETRA4 - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(0,1,0),(1,1,1)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.2256894071281369,-0.27631691290428106,-0.20266086543995965),(0.655458695100186,-0.08173323565551605,-0.19254662462061933),(-0.49893490718947264,0.5848097154568599,-0.3039928255382145),(0.2988102920828487,1.0582266398878504,0.7347375047372364)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) ; m.setCoords(coo) - exp8=1.7131322579364157 - self.assertAlmostEqual(exp8,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for c in [[0,1,2,3],[0,3,2,1],[0,1,3,2],[0,2,3,1],[0,3,1,2],[0,2,1,3]]: - for i in xrange(4): - m.setNodalConnectivity(DataArrayInt([(elt+i)%4 for elt in c])) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp8,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp8,12) - pass - pass - pass - - def testMEDCouplingSkyLineArray(self): - index = DataArrayInt([ 0, 3, 5, 6, 6 ]) - value = DataArrayInt([ 1, 2, 3, 2, 3, 3 ]) - - sla0 = MEDCouplingSkyLineArray() - self.assertEqual( -1, sla0.getNumberOf() ) - self.assertEqual( 0, sla0.getLength() ) - sla0.set( index, value ) - self.assertTrue( index.isEqual( sla0.getIndexArray() )) - self.assertTrue( value.isEqual( sla0.getValueArray() )) - self.assertEqual( 4, sla0.getNumberOf() ) - self.assertEqual( 6, sla0.getLength() ) - - sla1 = MEDCouplingSkyLineArray( index, value ) - self.assertTrue( index.isEqual( sla1.getIndexArray() )) - self.assertTrue( value.isEqual( sla1.getValueArray() )) - self.assertEqual( 4, sla1.getNumberOf() ) - self.assertEqual( 6, sla1.getLength() ) - - sla2 = MEDCouplingSkyLineArray( sla1 ) - self.assertTrue( index.isEqual( sla2.getIndexArray() )) - self.assertTrue( value.isEqual( sla2.getValueArray() )) - self.assertEqual( 4, sla2.getNumberOf() ) - self.assertEqual( 6, sla2.getLength() ) - - indexVec = ivec(); indexVec.reserve( len( index )) - for i in index: indexVec.push_back( i[0] ) - valueVec = ivec(); valueVec.reserve( len( value )) - for i in value: valueVec.push_back( i[0] ) - sla3 = MEDCouplingSkyLineArray( indexVec, valueVec ) - self.assertTrue( index.isEqual( sla3.getIndexArray() )) - self.assertTrue( value.isEqual( sla3.getValueArray() )) - self.assertEqual( 4, sla3.getNumberOf() ) - self.assertEqual( 6, sla3.getLength() ) - - pass - - def testMEDCouplingUMeshgenerateGraph(self): - # cartesian mesh 3x3 - arr=DataArrayDouble(4) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - graph = m.generateGraph() - # 0 1 2 - # 3 4 5 - # 6 7 8 - valRef=[ 0,1,3, - 0,1,2,4, - 1,2,5, - 0,3,4,6, - 1,3,4,5,7, - 2,4,5,8, - 3,6,7, - 4,6,7,8, - 5,7,8] - self.assertEqual(valRef,list(graph.getValueArray().getValues())); - - indRef=[0, 3, 7, 10, 14, 19, 23, 26, 30, 33] - self.assertEqual(indRef,list(graph.getIndexArray().getValues())); - pass - - def testSwig2MEDCouplingCurveLinearReprQuick1(self): - """Non regression test. Error in m.__str__ when m is a MEDCouplingCurveLinear with spaceDim != meshDim.""" - arr=DataArrayDouble(12) ; arr.iota() ; arr.rearrange(2) - m=MEDCouplingCurveLinearMesh() - m.setCoords(arr) - m.setNodeGridStructure([3,2]) - m.checkCoherency() - self.assertEqual(m.getMeshDimension(),2) - self.assertEqual(m.getSpaceDimension(),2) - self.assertTrue(not "mismatch" in m.__str__()) - self.assertTrue(not "mismatch" in m.__repr__()) - # - arr=DataArrayDouble(18) ; arr.iota() ; arr.rearrange(3) - m.setCoords(arr) - self.assertEqual(m.getMeshDimension(),2) - self.assertEqual(m.getSpaceDimension(),3) - self.assertTrue(not "mismatch" in m.__str__()) - self.assertTrue(not "mismatch" in m.__repr__())# bug was here ! - pass - - pass - -if __name__ == '__main__': - unittest.main() diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingCommon.i b/medtool/src/MEDCoupling_Swig/MEDCouplingCommon.i deleted file mode 100644 index 8f1717456..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ /dev/null @@ -1,5857 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -%module MEDCoupling - -#ifdef WITH_DOCSTRINGS -%include MEDCoupling_doc.i -#endif - -%include std_vector.i -%include std_string.i - -%{ -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingIMesh.hxx" -#include "MEDCouplingCurveLinearMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingField.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldOverTime.hxx" -#include "MEDCouplingDefinitionTime.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingCartesianAMRMesh.hxx" -#include "MEDCouplingAMRAttribute.hxx" -#include "MEDCouplingMatrix.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingTypemaps.i" - -#include "InterpKernelAutoPtr.hxx" -#include "BoxSplittingOptions.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - -%} - -%template(ivec) std::vector; -%template(dvec) std::vector; -%template(svec) std::vector; - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingMesh* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCouplingMesh* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingPointSet* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCouplingPointSet* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) MEDCouplingCartesianAMRPatchGen* -{ - $result=convertCartesianAMRPatch($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) MEDCouplingCartesianAMRMeshGen* -{ - $result=convertCartesianAMRMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) MEDCouplingDataForGodFather* -{ - $result=convertDataForGodFather($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCoupling1GTUMesh* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCoupling1GTUMesh* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingStructuredMesh* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCouplingStructuredMesh* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingFieldDiscretization* -{ - $result=convertFieldDiscretization($1,$owner); -} - -%typemap(out) MEDCouplingFieldDiscretization* -{ - $result=convertFieldDiscretization($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingMultiFields* -{ - $result=convertMultiFields($1,$owner); -} - -%typemap(out) MEDCouplingMultiFields* -{ - $result=convertMultiFields($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::PartDefinition* -{ - $result=convertPartDefinition($1,$owner); -} - -%typemap(out) PartDefinition* -{ - $result=convertPartDefinition($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -#ifdef WITH_NUMPY -%init %{ import_array(); %} -#endif - -%feature("autodoc", "1"); -%feature("docstring"); - -%newobject ParaMEDMEM::MEDCouplingField::buildMeasureField; -%newobject ParaMEDMEM::MEDCouplingField::getLocalizationOfDiscr; -%newobject ParaMEDMEM::MEDCouplingField::computeTupleIdsToSelectFromCellIds; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::New; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getArray; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getEndArray; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MergeFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MeldFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::doublyContractedProduct; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::determinant; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenValues; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenVectors; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::inverse; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::trace; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::deviator; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::magnitude; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxPerTuple; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::keepSelectedComponents; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::extractSlice3D; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::DotFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::dot; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::CrossProductFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProduct; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MaxFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::max; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MinFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::AddFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::SubstractFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MultiplyFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::DivideFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::min; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::negate; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getIdsInRange; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPartRange; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__getitem__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__neg__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__add__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__sub__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__mul__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__div__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__pow__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__radd__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rsub__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rmul__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rdiv__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::clone; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::deepCpy; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::nodeToCellDiscretization; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::cellToNodeDiscretization; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti; -%newobject ParaMEDMEM::MEDCouplingFieldTemplate::New; -%newobject ParaMEDMEM::MEDCouplingMesh::deepCpy; -%newobject ParaMEDMEM::MEDCouplingMesh::checkDeepEquivalOnSameNodesWith; -%newobject ParaMEDMEM::MEDCouplingMesh::checkTypeConsistencyAndContig; -%newobject ParaMEDMEM::MEDCouplingMesh::computeNbOfNodesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::computeNbOfFacesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::computeEffectiveNbOfNodesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::buildPartRange; -%newobject ParaMEDMEM::MEDCouplingMesh::giveCellsWithType; -%newobject ParaMEDMEM::MEDCouplingMesh::getCoordinatesAndOwner; -%newobject ParaMEDMEM::MEDCouplingMesh::getBarycenterAndOwner; -%newobject ParaMEDMEM::MEDCouplingMesh::computeIsoBarycenterOfNodesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::buildOrthogonalField; -%newobject ParaMEDMEM::MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds; -%newobject ParaMEDMEM::MEDCouplingMesh::mergeMyselfWith; -%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic; -%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic2; -%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic3; -%newobject ParaMEDMEM::MEDCouplingMesh::getMeasureField; -%newobject ParaMEDMEM::MEDCouplingMesh::simplexize; -%newobject ParaMEDMEM::MEDCouplingMesh::buildUnstructured; -%newobject ParaMEDMEM::MEDCouplingMesh::MergeMeshes; -%newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer; -%newobject ParaMEDMEM::MEDCouplingPointSet::getCellsInBoundingBox; -%newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes; -%newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh; -%newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray; -%newobject ParaMEDMEM::MEDCouplingPointSet::buildPartOfMySelf2; -%newobject ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType; -%newobject ParaMEDMEM::MEDCouplingPointSet::zipConnectivityTraducer; -%newobject ParaMEDMEM::MEDCouplingPointSet::mergeMyselfWithOnSameCoords; -%newobject ParaMEDMEM::MEDCouplingPointSet::fillCellIdsToKeepFromNodeIds; -%newobject ParaMEDMEM::MEDCouplingPointSet::getCellIdsLyingOnNodes; -%newobject ParaMEDMEM::MEDCouplingPointSet::deepCpyConnectivityOnly; -%newobject ParaMEDMEM::MEDCouplingPointSet::getBoundingBoxForBBTree; -%newobject ParaMEDMEM::MEDCouplingPointSet::computeFetchedNodeIds; -%newobject ParaMEDMEM::MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells; -%newobject ParaMEDMEM::MEDCouplingPointSet::computeDiameterField; -%newobject ParaMEDMEM::MEDCouplingPointSet::__getitem__; -%newobject ParaMEDMEM::MEDCouplingUMesh::New; -%newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity; -%newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex; -%newobject ParaMEDMEM::MEDCouplingUMesh::clone; -%newobject ParaMEDMEM::MEDCouplingUMesh::__iter__; -%newobject ParaMEDMEM::MEDCouplingUMesh::cellsByType; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity2; -%newobject ParaMEDMEM::MEDCouplingUMesh::explode3DMeshTo1D; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildSpreadZonesWithPoly; -%newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes; -%newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords; -%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually; -%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt; -%newobject ParaMEDMEM::MEDCouplingUMesh::conformize2D; -%newobject ParaMEDMEM::MEDCouplingUMesh::colinearize2D; -%newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes; -%newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt; -%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForMEDFileFrmt; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType; -%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildDirectionVectorField; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertLinearCellsToQuadratic; -%newobject ParaMEDMEM::MEDCouplingUMesh::getEdgeRatioField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getAspectRatioField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getWarpField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getSkewField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getPartBarycenterAndOwner; -%newobject ParaMEDMEM::MEDCouplingUMesh::computePlaneEquationOf3DFaces; -%newobject ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField; -%newobject ParaMEDMEM::MEDCouplingUMesh::keepCellIdsByType; -%newobject ParaMEDMEM::MEDCouplingUMesh::Build0DMeshFromCoords; -%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells; -%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DCells; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertIntoSingleGeoTypeMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::findCellIdsOnBoundary; -%newobject ParaMEDMEM::MEDCouplingUMesh::computeSkin; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildSetInstanceFromThis; -%newobject ParaMEDMEM::MEDCouplingUMesh::getCellIdsCrossingPlane; -%newobject ParaMEDMEM::MEDCouplingUMesh::convexEnvelop2D; -%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeRangesFromTypeDistribution; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf2DMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf3DMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::generateGraph; -%newobject ParaMEDMEM::MEDCouplingUMesh::orderConsecutiveCells1D; -%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTreeFast; -%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic; -%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic; -%newobject ParaMEDMEM::MEDCouplingUMeshCellByTypeEntry::__iter__; -%newobject ParaMEDMEM::MEDCouplingUMeshCellEntry::__iter__; -%newobject ParaMEDMEM::MEDCoupling1GTUMesh::New; -%newobject ParaMEDMEM::MEDCoupling1GTUMesh::getNodalConnectivity; -%newobject ParaMEDMEM::MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::New; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::buildSetInstanceFromThis; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::computeDualMesh; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::sortHexa8EachOther; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshes; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::New; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::getNodalConnectivityIndex; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::buildSetInstanceFromThis; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshes; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords; -%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New; -%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::buildStructuredSubPart; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTUnstructured; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTSubLevelMesh; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::BuildExplicitIdsFrom; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivity; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ComputeCornersGhost; -%newobject ParaMEDMEM::MEDCouplingCMesh::New; -%newobject ParaMEDMEM::MEDCouplingCMesh::clone; -%newobject ParaMEDMEM::MEDCouplingCMesh::getCoordsAt; -%newobject ParaMEDMEM::MEDCouplingIMesh::New; -%newobject ParaMEDMEM::MEDCouplingIMesh::asSingleCell; -%newobject ParaMEDMEM::MEDCouplingIMesh::buildWithGhost; -%newobject ParaMEDMEM::MEDCouplingIMesh::convertToCartesian; -%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::New; -%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::clone; -%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::getCoords; -%newobject ParaMEDMEM::MEDCouplingMultiFields::New; -%newobject ParaMEDMEM::MEDCouplingMultiFields::deepCpy; -%newobject ParaMEDMEM::MEDCouplingFieldOverTime::New; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRPatchGen::getMesh; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRPatchGen::__getitem__; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::deepCpy; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildUnstructured; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::extractGhostFrom; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getImageMesh; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getGodFather; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getFather; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getPatch; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getPatchAtPosition; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getMeshAtPosition; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::__getitem__; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::New; -%newobject ParaMEDMEM::MEDCouplingDataForGodFather::getMyGodFather; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::New; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpy; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpyWithoutGodFather; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::getFieldOn; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::projectTo; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithGhost; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost; -%newobject ParaMEDMEM::DenseMatrix::New; -%newobject ParaMEDMEM::DenseMatrix::deepCpy; -%newobject ParaMEDMEM::DenseMatrix::shallowCpy; -%newobject ParaMEDMEM::DenseMatrix::getData; -%newobject ParaMEDMEM::DenseMatrix::matVecMult; -%newobject ParaMEDMEM::DenseMatrix::MatVecMult; -%newobject ParaMEDMEM::DenseMatrix::__add__; -%newobject ParaMEDMEM::DenseMatrix::__sub__; -%newobject ParaMEDMEM::DenseMatrix::__mul__; -%newobject ParaMEDMEM::PartDefinition::New; -%newobject ParaMEDMEM::PartDefinition::toDAI; -%newobject ParaMEDMEM::PartDefinition::__add__; -%newobject ParaMEDMEM::PartDefinition::composeWith; -%newobject ParaMEDMEM::PartDefinition::tryToSimplify; -%newobject ParaMEDMEM::DataArrayPartDefinition::New; -%newobject ParaMEDMEM::SlicePartDefinition::New; - -%feature("unref") MEDCouplingPointSet "$this->decrRef();" -%feature("unref") MEDCouplingMesh "$this->decrRef();" -%feature("unref") MEDCouplingUMesh "$this->decrRef();" -%feature("unref") MEDCoupling1GTUMesh "$this->decrRef();" -%feature("unref") MEDCoupling1SGTUMesh "$this->decrRef();" -%feature("unref") MEDCoupling1DGTUMesh "$this->decrRef();" -%feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" -%feature("unref") MEDCouplingCMesh "$this->decrRef();" -%feature("unref") MEDCouplingIMesh "$this->decrRef();" -%feature("unref") MEDCouplingCurveLinearMesh "$this->decrRef();" -%feature("unref") MEDCouplingField "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationP0 "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationP1 "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationGauss "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationGaussNE "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationKriging "$this->decrRef();" -%feature("unref") MEDCouplingFieldDouble "$this->decrRef();" -%feature("unref") MEDCouplingMultiFields "$this->decrRef();" -%feature("unref") MEDCouplingFieldTemplate "$this->decrRef();" -%feature("unref") MEDCouplingMultiFields "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRMeshGen "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRMesh "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRMeshSub "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRPatchGen "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRPatchGF "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRPatch "$this->decrRef();" -%feature("unref") MEDCouplingDataForGodFather "$this->decrRef();" -%feature("unref") MEDCouplingAMRAttribute "$this->decrRef();" -%feature("unref") DenseMatrix "$this->decrRef();" -%feature("unref") PartDefinition "$this->decrRef();" -%feature("unref") DataArrayPartDefinition "$this->decrRef();" -%feature("unref") SlicePartDefinition "$this->decrRef();" - -%rename(assign) *::operator=; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo; - -%nodefaultctor; - -%rename (InterpKernelException) INTERP_KERNEL::Exception; - -%include "MEDCouplingRefCountObject.i" -%include "MEDCouplingMemArray.i" - -namespace INTERP_KERNEL -{ - /*! - * \class BoxSplittingOptions - * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion. - */ - class BoxSplittingOptions - { - public: - BoxSplittingOptions(); - void init() throw(INTERP_KERNEL::Exception); - double getEfficiencyGoal() const throw(INTERP_KERNEL::Exception); - void setEfficiencyGoal(double efficiency) throw(INTERP_KERNEL::Exception); - double getEfficiencyThreshold() const throw(INTERP_KERNEL::Exception); - void setEfficiencyThreshold(double efficiencyThreshold) throw(INTERP_KERNEL::Exception); - int getMinimumPatchLength() const throw(INTERP_KERNEL::Exception); - void setMinimumPatchLength(int minPatchLength) throw(INTERP_KERNEL::Exception); - int getMaximumPatchLength() const throw(INTERP_KERNEL::Exception); - void setMaximumPatchLength(int maxPatchLength) throw(INTERP_KERNEL::Exception); - int getMaximumNbOfCellsInPatch() const throw(INTERP_KERNEL::Exception); - void setMaximumNbOfCellsInPatch(int maxNbCellsInPatch) throw(INTERP_KERNEL::Exception); - void copyOptions(const BoxSplittingOptions & other) throw(INTERP_KERNEL::Exception); - std::string printOptions() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->printOptions(); - } - } - }; -} - -namespace ParaMEDMEM -{ - typedef enum - { - ON_CELLS = 0, - ON_NODES = 1, - ON_GAUSS_PT = 2, - ON_GAUSS_NE = 3, - ON_NODES_KR = 4 - } TypeOfField; - - typedef enum - { - NO_TIME = 4, - ONE_TIME = 5, - LINEAR_TIME = 6, - CONST_ON_TIME_INTERVAL = 7 - } TypeOfTimeDiscretization; - - typedef enum - { - UNSTRUCTURED = 5, - CARTESIAN = 7, - EXTRUDED = 8, - CURVE_LINEAR = 9, - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, - IMAGE_GRID = 12 - } MEDCouplingMeshType; - - class DataArrayInt; - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - %extend RefCountObject - { - std::string getHiddenCppPointer() const - { - std::ostringstream oss; oss << "C++ Pointer address is : " << self; - return oss.str(); - } - } - - %extend MEDCouplingGaussLocalization - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->getStringRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "MEDCouplingGaussLocalization C++ instance at " << self << "." << std::endl; - oss << self->getStringRepr(); - return oss.str(); - } - } - - //== MEDCouplingMesh - - class MEDCouplingMesh : public RefCountObject, public TimeLabel - { - public: - void setName(const std::string& name); - std::string getName() const; - void setDescription(const std::string& descr); - std::string getDescription() const; - void setTime(double val, int iteration, int order); - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - virtual MEDCouplingMeshType getType() const throw(INTERP_KERNEL::Exception); - bool isStructured() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingMesh *deepCpy() const; - virtual bool isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); - virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - virtual void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); - virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getBarycenterAndOwner() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - std::string writeVTK(const std::string& fileName, bool isBinary=true) const throw(INTERP_KERNEL::Exception); - virtual std::string getVTKFileExtension() const; - std::string getVTKFileNameOf(const std::string& fileName) const; - // tools - virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *buildOrthogonalField() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception); - virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); - virtual void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) throw(INTERP_KERNEL::Exception); - static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception); - static bool IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static bool IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static INTERP_KERNEL::NormalizedCellType GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static int GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - int getCellContainingPoint(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingMesh::getCellContainingPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,1,spaceDim,true); - return self->getCellContainingPoint(pos,eps); - } - - PyObject *getCellsContainingPoints(PyObject *p, int nbOfPoints, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingMesh::getCellsContainingPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,nbOfPoints,spaceDim,true); - MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; - self->getCellsContainingPoints(pos,nbOfPoints,eps,elts,eltsIndex); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elts.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(eltsIndex.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getCellsContainingPoints(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; - int spaceDim=self->getSpaceDimension(); - void *da=0; - int res1=SWIG_ConvertPtr(p,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoCPtr tmp=convertPyToNewDblArr2(p,&size); - int nbOfPoints=size/spaceDim; - if(size%spaceDim!=0) - { - throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Invalid list length ! Must be a multiple of self.getSpaceDimension() !"); - } - self->getCellsContainingPoints(tmp,nbOfPoints,eps,elts,eltsIndex); - } - else - { - DataArrayDouble *da2=reinterpret_cast< DataArrayDouble * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Not null DataArrayDouble instance expected !"); - da2->checkAllocated(); - int size=da2->getNumberOfTuples(); - int nbOfCompo=da2->getNumberOfComponents(); - if(nbOfCompo!=spaceDim) - { - throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Invalid DataArrayDouble nb of components ! Expected same as self.getSpaceDimension() !"); - } - self->getCellsContainingPoints(da2->getConstPointer(),size,eps,elts,eltsIndex); - } - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elts.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(eltsIndex.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getCellsContainingPoint(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingUMesh::getCellsContainingPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,1,spaceDim,true); - std::vector elts; - self->getCellsContainingPoint(pos,eps,elts); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)elts.size(),1); - std::copy(elts.begin(),elts.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - virtual PyObject *getReverseNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - self->getReverseNodalConnectivity(d0,d1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *ids(convertObjToPossibleCpp1_Safe(li,sw,sz,v0,v1)); - self->renumberCells(ids,check); - } - - PyObject *checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellCor, *nodeCor; - self->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); - return res; - } - - PyObject *checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellCor=0,*nodeCor=0; - self->checkDeepEquivalWith(other,cellCompPol,prec,cellCor,nodeCor); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); - return res; - } - - DataArrayInt *checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellCor=0; - self->checkDeepEquivalOnSameNodesWith(other,cellCompPol,prec,cellCor); - return cellCor; - } - - DataArrayInt *getCellIdsFullyIncludedInNodeIds(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->getCellIdsFullyIncludedInNodeIds(tmp,((const int *)tmp)+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->getCellIdsFullyIncludedInNodeIds(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - PyObject *getNodeIdsOfCell(int cellId) const throw(INTERP_KERNEL::Exception) - { - std::vector conn; - self->getNodeIdsOfCell(cellId,conn); - return convertIntArrToPyList2(conn); - } - - PyObject *getCoordinatesOfNode(int nodeId) const throw(INTERP_KERNEL::Exception) - { - std::vector coo; - self->getCoordinatesOfNode(nodeId,coo); - return convertDblArrToPyList2(coo); - } - - void scale(PyObject *point, double factor) throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::scale : "; - const double *pointPtr=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->scale(pointPtr,factor); - } - - PyObject *getBoundingBox() const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - INTERP_KERNEL::AutoPtr tmp=new double[2*spaceDim]; - self->getBoundingBox(tmp); - PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,spaceDim); - return ret; - } - - PyObject *isEqualIfNotWhy(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,prec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingMesh *ret=self->buildPart(tmp,tmp+szArr); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - DataArrayInt *arr=0; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingMesh *ret=self->buildPartAndReduceNodes(tmp,tmp+szArr,arr); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - // - PyObject *res = PyList_New(2); - PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); - PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - PyList_SetItem(res,0,obj0); - PyList_SetItem(res,1,obj1); - return res; - } - - PyObject *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) - { - int a,b,c; - DataArrayInt *arr=0; - MEDCouplingMesh *ret=self->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,a,b,c,arr); - PyObject *res = PyTuple_New(2); - PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); - PyObject *obj1=0; - if(arr) - obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - else - obj1=PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(b)); - PyTuple_SetItem(res,0,obj0); - PyTuple_SetItem(res,1,obj1); - return res; - } - - PyObject *getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector vals=self->getDistributionOfTypes(); - if(vals.size()%3!=0) - throw INTERP_KERNEL::Exception("Internal Error detected in wrap python ! code returned by MEDCouplingMesh::getDistributionOfTypes is not so that %3==0 !"); - PyObject *ret=PyList_New((int)vals.size()/3); - for(int j=0;j<(int)vals.size()/3;j++) - { - PyObject *ret1=PyList_New(3); - PyList_SetItem(ret1,0,SWIG_From_int(vals[3*j])); - PyList_SetItem(ret1,1,SWIG_From_int(vals[3*j+1])); - PyList_SetItem(ret1,2,SWIG_From_int(vals[3*j+2])); - PyList_SetItem(ret,j,ret1); - } - return ret; - } - - DataArrayInt *checkTypeConsistencyAndContig(PyObject *li, PyObject *li2) const throw(INTERP_KERNEL::Exception) - { - std::vector code; - std::vector idsPerType; - convertFromPyObjVectorOfObj(li2,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",idsPerType); - convertPyToNewIntArr4(li,1,3,code); - return self->checkTypeConsistencyAndContig(code,idsPerType); - } - - PyObject *splitProfilePerType(const DataArrayInt *profile) const throw(INTERP_KERNEL::Exception) - { - std::vector code; - std::vector idsInPflPerType; - std::vector idsPerType; - self->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); - PyObject *ret=PyTuple_New(3); - // - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("Internal Error detected in wrap python ! code returned by MEDCouplingMesh::splitProfilePerType is not so that %3==0 !"); - PyObject *ret0=PyList_New((int)code.size()/3); - for(int j=0;j<(int)code.size()/3;j++) - { - PyObject *ret00=PyList_New(3); - PyList_SetItem(ret00,0,SWIG_From_int(code[3*j])); - PyList_SetItem(ret00,1,SWIG_From_int(code[3*j+1])); - PyList_SetItem(ret00,2,SWIG_From_int(code[3*j+2])); - PyList_SetItem(ret0,j,ret00); - } - PyTuple_SetItem(ret,0,ret0); - // - PyObject *ret1=PyList_New(idsInPflPerType.size()); - for(std::size_t j=0;j bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::translate : "; - const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->translate(vectorPtr); - } - - void rotate(PyObject *center, double alpha) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Python wrap of MEDCouplingPointSet::rotate : "; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const double *centerPtr=convertObjToPossibleCpp5_Safe(center,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->rotate(centerPtr,0,alpha); - } - - void rotate(PyObject *center, PyObject *vector, double alpha) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Python wrap of MEDCouplingPointSet::rotate : "; - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - int spaceDim=self->getSpaceDimension(); - const double *centerPtr=convertObjToPossibleCpp5_Safe(center,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val2,a2,aa2,bb2,msg,1,spaceDim,false);//vectorPtr can be null in case of space dim 2 - self->rotate(centerPtr,vectorPtr,alpha); - } - - PyObject *getAllGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::set result=self->getAllGeoTypes(); - std::set::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - virtual PyObject *getTinySerializationInformation() const throw(INTERP_KERNEL::Exception) - { - std::vector a0; - std::vector a1; - std::vector a2; - self->getTinySerializationInformation(a0,a1,a2); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); - int sz(a2.size()); - PyObject *ret2(PyList_New(sz)); - { - for(int i=0;iserialize(a0Tmp,a1Tmp); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(a0Tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(a1Tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2) const throw(INTERP_KERNEL::Exception) - { - std::vector littleStrings; - self->resizeForUnserialization(tinyInfo,a1,a2,littleStrings); - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - {// put an empty dict in input to say to __new__ to call __init__... - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyTuple_SetItem(ret,0,ret0); - return ret; - } - - PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) - { - PyObject *ret0(ParaMEDMEM_MEDCouplingMesh_getTinySerializationInformation(self)); - PyObject *ret1(ParaMEDMEM_MEDCouplingMesh_serialize(self)); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,ret0); - PyTuple_SetItem(ret,1,ret1); - return ret; - } - - void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDCouplingMesh.__setstate__ : expected input is a tuple of size 2 !"; - if(!PyTuple_Check(inp)) - throw INTERP_KERNEL::Exception(MSG); - int sz(PyTuple_Size(inp)); - if(sz!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *elt0(PyTuple_GetItem(inp,0)); - PyObject *elt1(PyTuple_GetItem(inp,1)); - std::vector a0; - std::vector a1; - std::vector a2; - DataArrayInt *b0(0); - DataArrayDouble *b1(0); - { - if(!PyTuple_Check(elt0) && PyTuple_Size(elt0)!=3) - throw INTERP_KERNEL::Exception(MSG); - PyObject *a0py(PyTuple_GetItem(elt0,0)),*a1py(PyTuple_GetItem(elt0,1)),*a2py(PyTuple_GetItem(elt0,2)); - int tmp(-1); - fillArrayWithPyListDbl3(a0py,tmp,a0); - convertPyToNewIntArr3(a1py,a1); - fillStringVector(a2py,a2); - } - { - if(!PyTuple_Check(elt1) && PyTuple_Size(elt1)!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *b0py(PyTuple_GetItem(elt1,0)),*b1py(PyTuple_GetItem(elt1,1)); - void *argp(0); - int status(SWIG_ConvertPtr(b0py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - b0=reinterpret_cast(argp); - status=SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - b1=reinterpret_cast(argp); - } - // useless here to call resizeForUnserialization because arrays are well resized. - self->unserialization(a0,a1,b0,b1,a2); - } - - static MEDCouplingMesh *MergeMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMesh,"MEDCouplingMesh",tmp); - return MEDCouplingMesh::MergeMeshes(tmp); - } - } - }; -} - -//== MEDCouplingMesh End - -%include "NormalizedGeometricTypes" -%include "MEDCouplingNatureOfFieldEnum" -// -namespace ParaMEDMEM -{ - class MEDCouplingNatureOfField - { - public: - static const char *GetRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception); - static std::string GetReprNoThrow(NatureOfField nat); - static std::string GetAllPossibilitiesStr(); - }; -} - -// the MEDCouplingTimeDiscretization classes are not swigged : in case the file can help -// include "MEDCouplingTimeDiscretization.i" - -namespace ParaMEDMEM -{ - class MEDCouplingGaussLocalization - { - public: - MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& w) throw(INTERP_KERNEL::Exception); - MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); - INTERP_KERNEL::NormalizedCellType getType() const throw(INTERP_KERNEL::Exception); - void setType(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); - int getNumberOfGaussPt() const throw(INTERP_KERNEL::Exception); - int getDimension() const throw(INTERP_KERNEL::Exception); - int getNumberOfPtsInRefCell() const throw(INTERP_KERNEL::Exception); - std::string getStringRepr() const throw(INTERP_KERNEL::Exception); - void checkCoherency() const throw(INTERP_KERNEL::Exception); - bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const throw(INTERP_KERNEL::Exception); - // - const std::vector& getRefCoords() const throw(INTERP_KERNEL::Exception); - double getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception); - const std::vector& getGaussCoords() const throw(INTERP_KERNEL::Exception); - double getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception); - const std::vector& getWeights() const throw(INTERP_KERNEL::Exception); - double getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception); - void setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception); - void setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception); - void setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception); - void setRefCoords(const std::vector& refCoo) throw(INTERP_KERNEL::Exception); - void setGaussCoords(const std::vector& gsCoo) throw(INTERP_KERNEL::Exception); - void setWeights(const std::vector& w) throw(INTERP_KERNEL::Exception); - // - static bool AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps); - }; - - class MEDCouplingSkyLineArray - { - public: - MEDCouplingSkyLineArray(); - MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray ); - MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value ); - MEDCouplingSkyLineArray( const std::vector& index, const std::vector& value ); - - void set( DataArrayInt* index, DataArrayInt* value ); - int getNumberOf() const; - int getLength() const; - DataArrayInt* getIndexArray() const; - DataArrayInt* getValueArray() const; - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; -} - -%include "MEDCouplingFieldDiscretization.i" - -//== MEDCouplingPointSet - -namespace ParaMEDMEM -{ - class MEDCouplingPointSet : public ParaMEDMEM::MEDCouplingMesh - { - public: - void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); - bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const throw(INTERP_KERNEL::Exception); - void zipCoords() throw(INTERP_KERNEL::Exception); - double getCaracteristicDimension() const throw(INTERP_KERNEL::Exception); - void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); - void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); - void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); - virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step) const throw(INTERP_KERNEL::Exception); - virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception); - static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *findBoundaryNodes() const; - virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const throw(INTERP_KERNEL::Exception); - virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception); - virtual bool isEmptyMesh(const std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); - virtual void renumberNodesWithOffsetInConn(int offset) throw(INTERP_KERNEL::Exception); - virtual bool areAllNodesFetched() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *computeDiameterField() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex) const throw(INTERP_KERNEL::Exception) - { - int newNbOfNodes; - DataArrayInt *ret0=self->buildNewNumberingFromCommonNodesFormat(comm,commIndex,newNbOfNodes); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_From_int(newNbOfNodes)); - return res; - } - - PyObject *findCommonNodes(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *comm, *commIndex; - self->findCommonNodes(prec,limitTupleId,comm,commIndex); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - PyObject *getCoords() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret1=self->getCoords(); - if (ret1) - ret1->incrRef(); - return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0); - } - - PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+szArr,keepCoords); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+szArr,fullyIn); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - virtual PyObject *buildPartOfMySelfKeepCoords(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords(tmp,tmp+szArr); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - virtual PyObject *buildPartOfMySelfKeepCoords2(int start, int end, int step) const throw(INTERP_KERNEL::Exception) - { - MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords2(start,end,step); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+szArr,fullyIn); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - void renumberNodes(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodes(tmp,newNbOfNodes); - } - - void renumberNodes2(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodes2(tmp,newNbOfNodes); - } - - PyObject *findNodesOnLine(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingPointSet::findNodesOnLine : 1st paramater for point."; - const char msg2[]="Python wrap of MEDCouplingPointSet::findNodesOnLine : 2nd paramater for vector."; - const double *p=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - std::vector nodes; - self->findNodesOnLine(p,v,eps,nodes); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)nodes.size(),1); - std::copy(nodes.begin(),nodes.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - PyObject *findNodesOnPlane(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingPointSet::findNodesOnPlane : 1st paramater for point."; - const char msg2[]="Python wrap of MEDCouplingPointSet::findNodesOnPlane : 2nd paramater for vector."; - const double *p=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - std::vector nodes; - self->findNodesOnPlane(p,v,eps,nodes); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)nodes.size(),1); - std::copy(nodes.begin(),nodes.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNodeIdsNearPoint(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - DataArrayInt *ret=self->getNodeIdsNearPoint(pos,eps); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNodeIdsNearPoints(PyObject *pt, int nbOfPoints, double eps) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *c=0,*cI=0; - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoints : "; - const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,nbOfPoints,spaceDim,true); - self->getNodeIdsNearPoints(pos,nbOfPoints,eps,c,cI); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getNodeIdsNearPoints(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *c=0,*cI=0; - int spaceDim=self->getSpaceDimension(); - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int nbOfTuples=-1; - const double *ptPtr=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::getNodeIdsNearPoints",spaceDim,true,nbOfTuples); - self->getNodeIdsNearPoints(ptPtr,nbOfTuples,eps,c,cI); - // - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getCellsInBoundingBox(PyObject *bbox, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::getCellsInBoundingBox : "; - const double *tmp=convertObjToPossibleCpp5_Safe(bbox,sw,val,a,aa,bb,msg,spaceDim,2,true); - // - DataArrayInt *elems=self->getCellsInBoundingBox(tmp,eps); - return SWIG_NewPointerObj(SWIG_as_voidptr(elems),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - void duplicateNodesInCoords(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->duplicateNodesInCoords(&singleVal,&singleVal+1); - case 2: - return self->duplicateNodesInCoords(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->duplicateNodesInCoords(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - virtual PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *v0=0,*v1=0; - self->findCommonCells(compType,startCellId,v0,v1); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - - virtual void renumberNodesInConn(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->renumberNodesInConn(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->renumberNodesInConn(da2->getConstPointer()); - } - } - - virtual PyObject *getNodeIdsInUse() const throw(INTERP_KERNEL::Exception) - { - int ret1=-1; - DataArrayInt *ret0=self->getNodeIdsInUse(ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - - virtual DataArrayInt *fillCellIdsToKeepFromNodeIds(PyObject *li, bool fullyIn) const - { - DataArrayInt *ret=0; - // - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->fillCellIdsToKeepFromNodeIds(tmp,tmp+szArr,fullyIn,ret); - return ret; - } - - virtual PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception) - { - bool ret1; - int ret2; - DataArrayInt *ret0=self->mergeNodes(precision,ret1,ret2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_From_bool(ret1)); - PyList_SetItem(res,2,SWIG_From_int(ret2)); - return res; - } - - virtual PyObject *mergeNodes2(double precision) throw(INTERP_KERNEL::Exception) - { - bool ret1; - int ret2; - DataArrayInt *ret0=self->mergeNodes2(precision,ret1,ret2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_From_bool(ret1)); - PyList_SetItem(res,2,SWIG_From_int(ret2)); - return res; - } - - DataArrayInt *getCellIdsLyingOnNodes(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->getCellIdsLyingOnNodes(tmp,((const int *)tmp)+size,fullyIn); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->getCellIdsLyingOnNodes(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn); - } - } - - MEDCouplingPointSet *__getitem__(PyObject *listOrDataArrI) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbc=self->getNumberOfCells(); - convertObjToPossibleCpp2(listOrDataArrI,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - return self->buildPartOfMySelf(&singleVal,&singleVal+1,true); - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - return self->buildPartOfMySelf(&tmp,&tmp+1,true); - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - return static_cast(self->buildPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),true)); - } - case 3: - { - return self->buildPartOfMySelf2(slic.first,slic.second.first,slic.second.second,true); - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - return self->buildPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),true); - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } - } - - static void Rotate2DAlg(PyObject *center, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoCPtr c=convertPyToNewDblArr2(center,&sz); - INTERP_KERNEL::AutoCPtr coo=convertPyToNewDblArr2(coords,&sz); - ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,coo); - for(int i=0;i c=convertPyToNewDblArr2(center,&sz); - int sw,nbNodes=0; - double val0; ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0; - std::vector val3; - const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3, - "Rotate2DAlg",2,true,nbNodes); - if(sw!=2 && sw!=3) - throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate2DAlg : try another overload method !"); - ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,const_cast(coo)); - } - - static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) - { - int sz,sz2; - INTERP_KERNEL::AutoCPtr c=convertPyToNewDblArr2(center,&sz); - INTERP_KERNEL::AutoCPtr coo=convertPyToNewDblArr2(coords,&sz); - INTERP_KERNEL::AutoCPtr v=convertPyToNewDblArr2(vect,&sz2); - ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,coo); - for(int i=0;i c=convertPyToNewDblArr2(center,&sz); - int sw,nbNodes=0; - double val0; ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0; - std::vector val3; - const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3, - "Rotate3DAlg",3,true,nbNodes); - if(sw!=2 && sw!=3) - throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate3DAlg : try another overload method !"); - INTERP_KERNEL::AutoCPtr v=convertPyToNewDblArr2(vect,&sz2); - ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,const_cast(coo)); - } - } - }; - - //== MEDCouplingPointSet End - - class MEDCouplingUMeshCell - { - public: - INTERP_KERNEL::NormalizedCellType getType() const; - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - PyObject *getAllConn() const throw(INTERP_KERNEL::Exception) - { - int ret2; - const int *r=self->getAllConn(ret2); - PyObject *ret=PyTuple_New(ret2); - for(int i=0;inextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMeshCell,0|0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDCouplingUMeshCellByTypeIterator - { - public: - ~MEDCouplingUMeshCellByTypeIterator(); - %extend - { - PyObject *next() - { - MEDCouplingUMeshCellEntry *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMeshCellEntry,SWIG_POINTER_OWN | 0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDCouplingUMeshCellByTypeEntry - { - public: - ~MEDCouplingUMeshCellByTypeEntry(); - %extend - { - MEDCouplingUMeshCellByTypeIterator *__iter__() - { - return self->iterator(); - } - } - }; - - class MEDCouplingUMeshCellEntry - { - public: - INTERP_KERNEL::NormalizedCellType getType() const; - int getNumberOfElems() const; - %extend - { - MEDCouplingUMeshCellIterator *__iter__() - { - return self->iterator(); - } - } - }; - - //== MEDCouplingUMesh - - class MEDCouplingUMesh : public ParaMEDMEM::MEDCouplingPointSet - { - public: - static MEDCouplingUMesh *New() throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *New(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *clone(bool recDeepCpy) const; - void checkCoherency() const throw(INTERP_KERNEL::Exception); - void setMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); - void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); - void finishInsertingCells() throw(INTERP_KERNEL::Exception); - MEDCouplingUMeshCellByTypeEntry *cellsByType() throw(INTERP_KERNEL::Exception); - void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true) throw(INTERP_KERNEL::Exception); - INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); - void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception); - int getMeshLength() const throw(INTERP_KERNEL::Exception); - void computeTypes() throw(INTERP_KERNEL::Exception); - std::string reprConnectivityOfThis() const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); - //tools - DataArrayInt *conformize2D(double eps) throw(INTERP_KERNEL::Exception); - DataArrayInt *colinearize2D(double eps) throw(INTERP_KERNEL::Exception); - void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception); - std::vector getQuadraticStatus() const throw(INTERP_KERNEL::Exception); - DataArrayInt *findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *computeSkin() const throw(INTERP_KERNEL::Exception); - bool checkConsecutiveCellTypes() const throw(INTERP_KERNEL::Exception); - bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); - DataArrayInt *rearrange2ConsecutiveCellTypes() throw(INTERP_KERNEL::Exception); - DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception); - DataArrayInt *getRenumArrForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); - DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); - void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception); - bool isPresenceOfQuadratic() const throw(INTERP_KERNEL::Exception); - bool isFullyQuadratic() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildDirectionVectorField() const throw(INTERP_KERNEL::Exception); - bool isContiguous1D() const throw(INTERP_KERNEL::Exception); - void tessellate2D(double eps) throw(INTERP_KERNEL::Exception); - void tessellate2DCurve(double eps) throw(INTERP_KERNEL::Exception); - void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception); - DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0) throw(INTERP_KERNEL::Exception); - void convertDegeneratedCells() throw(INTERP_KERNEL::Exception); - bool areOnlySimplexCells() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getEdgeRatioField() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getAspectRatioField() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *computePlaneEquationOf3DFaces() const throw(INTERP_KERNEL::Exception); - DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception); - std::string cppRepr() const throw(INTERP_KERNEL::Exception); - DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception); - DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception); - DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception); - MEDCouplingSkyLineArray *generateGraph() const throw(INTERP_KERNEL::Exception); - DataArrayInt *orderConsecutiveCells1D() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); - void changeOrientationOfCells() throw(INTERP_KERNEL::Exception); - int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0) throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector& code) throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingUMesh() throw(INTERP_KERNEL::Exception) - { - return MEDCouplingUMesh::New(); - } - - MEDCouplingUMesh(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingUMesh::New(meshName,meshDim); - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingUMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - MEDCouplingUMeshCellIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->cellIterator(); - } - - PyObject *getAllGeoTypesSorted() const throw(INTERP_KERNEL::Exception) - { - std::vector result=self->getAllGeoTypesSorted(); - std::vector::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - void setPartOfMySelf(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbc=self->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - { - self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); - break; - } - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); - break; - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); - break; - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } - } - - void __setitem__(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbc=self->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - { - self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); - break; - } - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); - break; - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); - break; - } - case 3: - { - self->setPartOfMySelf2(slic.first,slic.second.first,slic.second.second,otherOnSameCoordsThanThis); - break; - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int, slice, DataArrayInt instance !"); - } - } - - void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - if(size>szArr) - { - std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << szArr << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - self->insertNextCell(type,size,tmp); - } - - void insertNextCell(INTERP_KERNEL::NormalizedCellType type, PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->insertNextCell(type,szArr,tmp); - } - - DataArrayInt *getNodalConnectivity() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivity(); - if(ret) - ret->incrRef(); - return ret; - } - DataArrayInt *getNodalConnectivityIndex() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivityIndex(); - if(ret) - ret->incrRef(); - return ret; - } - - static PyObject *ComputeSpreadZoneGraduallyFromSeed(PyObject *seed, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling=-1) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *seedPtr=convertObjToPossibleCpp1_Safe(seed,sw,szArr,iTypppArr,stdvecTyyppArr); - int nbOfDepthPeelingPerformed=0; - DataArrayInt *ret0=MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(seedPtr,seedPtr+szArr,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); - PyObject *res=PyTuple_New(2); - PyTuple_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(res,1,PyInt_FromLong(nbOfDepthPeelingPerformed)); - return res; - } - - static PyObject *FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *v0=0,*v1=0; - MEDCouplingUMesh::FindCommonCellsAlg(compType,startCellId,nodal,nodalI,revNodal,revNodalI,v0,v1); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - PyObject *distanceToPoint(PyObject *point) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int nbOfCompo=self->getSpaceDimension(); - const double *pt=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::distanceToPoint",1,nbOfCompo,true); - // - int cellId=-1; - double ret0=self->distanceToPoint(pt,pt+nbOfCompo,cellId); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(cellId)); - return ret; - } - - PyObject *distanceToPoints(const DataArrayDouble *pts) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->distanceToPoints(pts,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *tetrahedrize(int policy) throw(INTERP_KERNEL::Exception) - { - int ret2(-1); - DataArrayInt *ret1(0); - MEDCoupling1SGTUMesh *ret0(self->tetrahedrize(policy,ret1,ret2)); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); - return ret; - } - - PyObject *checkButterflyCells(double eps=1e-12) throw(INTERP_KERNEL::Exception) - { - std::vector cells; - self->checkButterflyCells(cells,eps); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *splitByType() const throw(INTERP_KERNEL::Exception) - { - std::vector ms=self->splitByType(); - int sz=ms.size(); - PyObject *ret = PyList_New(sz); - for(int i=0;i retCpp=self->partitionBySpreadZone(); - int sz=retCpp.size(); - PyObject *ret=PyList_New(sz); - for(int i=0;i tmp=convertPyToNewIntArr2(ids,&size); - MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,tmp,tmp+size); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ); - } - - bool checkConsecutiveCellTypesAndOrder(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoPtr order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); - bool ret=self->checkConsecutiveCellTypesAndOrder(order,order+sz); - return ret; - } - - DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoPtr order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); - DataArrayInt *ret=self->getRenumArrForConsecutiveCellTypesSpec(order,(INTERP_KERNEL::NormalizedCellType *)order+sz); - return ret; - } - - PyObject *findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp0=0,*tmp1=0,*tmp2=0; - self->findNodesToDuplicate(otherDimM1OnSameCoords,tmp0,tmp1,tmp2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(tmp2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp0=0,*tmp1=0; - self->findCellIdsLyingOn(otherDimM1OnSameCoords,tmp0,tmp1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void duplicateNodes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->duplicateNodes(&singleVal,&singleVal+1); - case 2: - return self->duplicateNodes(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->duplicateNodes(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::duplicateNodes : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - void duplicateNodesInConn(PyObject *li, int offset) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->duplicateNodesInConn(&singleVal,&singleVal+1,offset); - case 2: - return self->duplicateNodesInConn(&multiVal[0],&multiVal[0]+multiVal.size(),offset); - case 4: - return self->duplicateNodesInConn(daIntTyypp->begin(),daIntTyypp->end(),offset); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::duplicateNodesInConn : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - PyObject *getLevArrPerCellTypes(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoPtr order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); - DataArrayInt *tmp0,*tmp1=0; - tmp0=self->getLevArrPerCellTypes(order,(INTERP_KERNEL::NormalizedCellType *)order+sz,tmp1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *convertNodalConnectivityToDynamicGeoTypeMesh() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret0=0,*ret1=0; - self->convertNodalConnectivityToDynamicGeoTypeMesh(ret0,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *AggregateSortedByTypeMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) - { - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - DataArrayInt *ret1=0,*ret2=0; - MEDCouplingUMesh *ret0=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(meshes,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *MergeUMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) - { - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - MEDCouplingUMesh *ret=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshes); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - static PyObject *FuseUMeshesOnSameCoords(PyObject *ms, int compType) throw(INTERP_KERNEL::Exception) - { - int sz; - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - std::vector corr; - MEDCouplingUMesh *um=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,compType,corr); - sz=corr.size(); - PyObject *ret1=PyList_New(sz); - for(int i=0;i meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); - } - - static void MergeNodesOnUMeshesSharingSameCoords(PyObject *ms, double eps) throw(INTERP_KERNEL::Exception) - { - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,eps); - } - - static bool RemoveIdsFromIndexedArrays(PyObject *li, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndx) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : null pointer as arrIndex !"); - convertObjToPossibleCpp2(li,arrIndx->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(&singleVal,&singleVal+1,arr,arrIndx,offsetForRemoval); - case 2: - return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arr,arrIndx,offsetForRemoval); - case 4: - return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arr,arrIndx,offsetForRemoval); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - static PyObject *ExtractFromIndexedArrays(PyObject *li, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arrOut=0,*arrIndexOut=0; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : null pointer as arrIndxIn !"); - convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - MEDCouplingUMesh::ExtractFromIndexedArrays(&singleVal,&singleVal+1,arrIn,arrIndxIn,arrOut,arrIndexOut); - break; - } - case 2: - { - MEDCouplingUMesh::ExtractFromIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,arrOut,arrIndexOut); - break; - } - case 4: - { - MEDCouplingUMesh::ExtractFromIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,arrOut,arrIndexOut); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *ExtractFromIndexedArrays2(int strt, int stp, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arrOut=0,*arrIndexOut=0; - MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *ExtractFromIndexedArrays2(PyObject *slic, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : the first param is not a pyslice !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sliC=reinterpret_cast(slic); - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : last array is null !"); - arrIndxIn->checkAllocated(); - if(arrIndxIn->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : number of components of last argument must be equal to one !"); - GetIndicesOfSlice(sliC,arrIndxIn->getNumberOfTuples(),&strt,&stp,&step,"ExtractFromIndexedArrays2 (wrap) : Invalid slice regarding nb of elements !"); - DataArrayInt *arrOut=0,*arrIndexOut=0; - MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *SetPartOfIndexedArrays(PyObject *li, - const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arrOut=0,*arrIndexOut=0; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : null pointer as arrIndex !"); - convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - MEDCouplingUMesh::SetPartOfIndexedArrays(&singleVal,&singleVal+1,arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); - break; - } - case 2: - { - MEDCouplingUMesh::SetPartOfIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); - break; - } - case 4: - { - MEDCouplingUMesh::SetPartOfIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static void SetPartOfIndexedArraysSameIdx(PyObject *li, DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : null pointer as arrIndex !"); - convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(&singleVal,&singleVal+1,arrIn,arrIndxIn,srcArr,srcArrIndex); - break; - } - case 2: - { - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,srcArr,srcArrIndex); - break; - } - case 4: - { - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,srcArr,srcArrIndex); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingUMesh::are2DCellsNotCorrectlyOriented : "; - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - std::vector cells; - self->are2DCellsNotCorrectlyOriented(v,polyOnly,cells); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - void orientCorrectly2DCells(PyObject *vec, bool polyOnly) throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingUMesh::orientCorrectly2DCells : "; - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->orientCorrectly2DCells(v,polyOnly); - } - - PyObject *arePolyhedronsNotCorrectlyOriented() const throw(INTERP_KERNEL::Exception) - { - std::vector cells; - self->arePolyhedronsNotCorrectlyOriented(cells); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception) - { - double vec[3]; - double pos[3]; - self->getFastAveragePlaneOfThis(vec,pos); - double vals[6]; - std::copy(vec,vec+3,vals); - std::copy(pos,pos+3,vals+3); - return convertDblArrToPyListOfTuple(vals,3,2); - } - - static MEDCouplingUMesh *MergeUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",tmp); - return MEDCouplingUMesh::MergeUMeshes(tmp); - } - - PyObject *areCellsIncludedIn(const MEDCouplingUMesh *other, int compType) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1; - bool ret0=self->areCellsIncludedIn(other,compType,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *areCellsIncludedIn2(const MEDCouplingUMesh *other) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1; - bool ret0=self->areCellsIncludedIn2(other,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *explode3DMeshTo1D() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d3=DataArrayInt::New(); - MEDCouplingUMesh *m=self->explode3DMeshTo1D(d0,d1,d2,d3); - PyObject *ret=PyTuple_New(5); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildDescendingConnectivity() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d3=DataArrayInt::New(); - MEDCouplingUMesh *m=self->buildDescendingConnectivity(d0,d1,d2,d3); - PyObject *ret=PyTuple_New(5); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildDescendingConnectivity2() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d3=DataArrayInt::New(); - MEDCouplingUMesh *m=self->buildDescendingConnectivity2(d0,d1,d2,d3); - PyObject *ret=PyTuple_New(5); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *computeNeighborsOfCells() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *neighbors=0,*neighborsIdx=0; - self->computeNeighborsOfCells(neighbors,neighborsIdx); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *computeNeighborsOfNodes() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *neighbors=0,*neighborsIdx=0; - self->computeNeighborsOfNodes(neighbors,neighborsIdx); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *neighbors=0,*neighborsIdx=0; - MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc,descI,revDesc,revDescI,neighbors,neighborsIdx); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - DataArrayInt *d2,*d3,*d4,*dd5; - MEDCouplingUMesh *mOut=self->emulateMEDMEMBDC(nM1LevMesh,d0,d1,d2,d3,d4,dd5); - PyObject *ret=PyTuple_New(7); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mOut),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(d4),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,6,SWIG_NewPointerObj(SWIG_as_voidptr(dd5),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayDouble *getPartBarycenterAndOwner(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - return self->getPartBarycenterAndOwner(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - } - - DataArrayDouble *getPartMeasureField(bool isAbs, DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - return self->getPartMeasureField(isAbs,da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - } - - MEDCouplingFieldDouble *buildPartOrthogonalField(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - return self->buildPartOrthogonalField(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - } - - PyObject *getTypesOfPart(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - std::set result=self->getTypesOfPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - std::set::const_iterator iL=result.begin(); - PyObject *res = PyList_New(result.size()); - for (int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - DataArrayInt *ret=self->keepCellIdsByType(type,da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - ret->setName(da->getName().c_str()); - return ret; - } - - static PyObject *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellNb1=0,*cellNb2=0; - MEDCouplingUMesh *mret=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,eps,cellNb1,cellNb2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps) throw(INTERP_KERNEL::Exception) - { - MEDCouplingUMesh *splitMesh2D(0),*splitMesh1D(0); - DataArrayInt *cellIdInMesh2D(0),*cellIdInMesh1D(0); - MEDCouplingUMesh::Intersect2DMeshWith1DLine(mesh2D,mesh1D,eps,splitMesh2D,splitMesh1D,cellIdInMesh2D,cellIdInMesh1D); - PyObject *ret(PyTuple_New(4)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(splitMesh2D),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(splitMesh1D),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellIdInMesh2D),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cellIdInMesh1D),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildSlice3D(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::buildSlice3D : works only for spaceDim 3 !"); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingUMesh::buildSlice3D : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingUMesh::buildSlice3D : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - // - DataArrayInt *cellIds=0; - MEDCouplingUMesh *ret0=self->buildSlice3D(orig,vect,eps,cellIds); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildSlice3DSurf(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::buildSlice3DSurf : works only for spaceDim 3 !"); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingUMesh::buildSlice3DSurf : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingUMesh::buildSlice3DSurf : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - // - DataArrayInt *cellIds=0; - MEDCouplingUMesh *ret0=self->buildSlice3DSurf(orig,vect,eps,cellIds); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *getCellIdsCrossingPlane(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : works only for spaceDim 3 !"); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - return self->getCellIdsCrossingPlane(orig,vect,eps); - } - - void convertToPolyTypes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int pos1; - std::vector pos2; - DataArrayInt *pos3=0; - DataArrayIntTuple *pos4=0; - convertObjToPossibleCpp1(li,sw,pos1,pos2,pos3,pos4); - switch(sw) - { - case 1: - { - self->convertToPolyTypes(&pos1,&pos1+1); - return; - } - case 2: - { - if(pos2.empty()) - return; - self->convertToPolyTypes(&pos2[0],&pos2[0]+pos2.size()); - return ; - } - case 3: - { - self->convertToPolyTypes(pos3->begin(),pos3->end()); - return ; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertToPolyTypes : unexpected input array type recognized !"); - } - } - } - void convertAllToPoly(); - void convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception); - bool unPolyze() throw(INTERP_KERNEL::Exception); - void simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildSpreadZonesWithPoly() const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) throw(INTERP_KERNEL::Exception); - }; - - //== MEDCouplingUMesh End - - //== MEDCouplingExtrudedMesh - - class MEDCouplingExtrudedMesh : public ParaMEDMEM::MEDCouplingMesh - { - public: - static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *build3DUnstructuredMesh() const throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingExtrudedMesh::New(mesh3D,mesh2D,cell2DId); - } - - MEDCouplingExtrudedMesh() - { - return MEDCouplingExtrudedMesh::New(); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingExtrudedMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - PyObject *getMesh2D() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingUMesh *ret=self->getMesh2D(); - if(ret) - ret->incrRef(); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - PyObject *getMesh1D() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingUMesh *ret=self->getMesh1D(); - if(ret) - ret->incrRef(); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - PyObject *getMesh3DIds() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getMesh3DIds(); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - } - }; - - //== MEDCouplingExtrudedMesh End - - class MEDCoupling1GTUMesh : public ParaMEDMEM::MEDCouplingPointSet - { - public: - static MEDCoupling1GTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static MEDCoupling1GTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); - INTERP_KERNEL::NormalizedCellType getCellModelEnum() const throw(INTERP_KERNEL::Exception); - int getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception); - virtual void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); - virtual void checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception); - %extend - { - virtual void insertNextCell(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->insertNextCell(tmp,tmp+szArr); - } - - virtual DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivity(); - if(ret) ret->incrRef(); - return ret; - } - - static MEDCouplingUMesh *AggregateOnSameCoordsToUMesh(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< const MEDCoupling1GTUMesh *> parts; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1GTUMesh,"MEDCoupling1GTUMesh",parts); - return MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(parts); - } - } - }; - - //== MEDCoupling1SGTUMesh - - class MEDCoupling1SGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh - { - public: - static MEDCoupling1SGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static MEDCoupling1SGTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); - void setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception); - int getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); - MEDCoupling1GTUMesh *computeDualMesh() const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const throw(INTERP_KERNEL::Exception); - DataArrayInt *sortHexa8EachOther() throw(INTERP_KERNEL::Exception); - %extend - { - MEDCoupling1SGTUMesh() - { - return MEDCoupling1SGTUMesh::New(); - } - - MEDCoupling1SGTUMesh(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1SGTUMesh::New(name,type); - } - - MEDCoupling1SGTUMesh(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1SGTUMesh::New(m); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCoupling1SGTUMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - PyObject *structurizeMe(double eps=1e-12) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellPerm(0),*nodePerm(0); - MEDCouplingCMesh *retCpp(self->structurizeMe(cellPerm,nodePerm,eps)); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(retCpp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellPerm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(nodePerm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); - return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(tmp); - } - - static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); - return MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(tmp); - } - } - }; - - //== MEDCoupling1SGTUMesh End - - //== MEDCoupling1DGTUMesh - - class MEDCoupling1DGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh - { - public: - static MEDCoupling1DGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static MEDCoupling1DGTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); - void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception); - MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); - bool isPacked() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCoupling1DGTUMesh() - { - return MEDCoupling1DGTUMesh::New(); - } - MEDCoupling1DGTUMesh(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1DGTUMesh::New(name,type); - } - - MEDCoupling1DGTUMesh(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1DGTUMesh::New(m); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCoupling1DGTUMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - DataArrayInt *getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivityIndex(); - if(ret) ret->incrRef(); - return ret; - } - - PyObject *retrievePackedNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0,*ret2=0; - bool ret0=self->retrievePackedNodalConnectivity(ret1,ret2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *copyWithNodalConnectivityPacked() const throw(INTERP_KERNEL::Exception) - { - bool ret1; - MEDCoupling1DGTUMesh *ret0=self->copyWithNodalConnectivityPacked(ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=ret1?Py_True:Py_False; Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); - return MEDCoupling1DGTUMesh::Merge1DGTUMeshes(tmp); - } - - static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); - return MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(tmp); - } - - static DataArrayInt *AggregateNodalConnAndShiftNodeIds(PyObject *li, const std::vector& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(tmp,offsetInNodeIdsPerElt); - } - } - }; - - //== MEDCoupling1DGTUMeshEnd - - class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh - { - public: - int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); - int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsOfSubLevelMesh() const throw(INTERP_KERNEL::Exception); - int getSpaceDimensionOnNodeStruct() const throw(INTERP_KERNEL::Exception); - double computeSquareness() const throw(INTERP_KERNEL::Exception); - virtual std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); - std::vector getCellGridStructure() const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *build1SGTUnstructured() const throw(INTERP_KERNEL::Exception); - std::vector getLocationFromCellId(int cellId) const throw(INTERP_KERNEL::Exception); - std::vector getLocationFromNodeId(int cellId) const throw(INTERP_KERNEL::Exception); - static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const throw(INTERP_KERNEL::Exception); - static int DeduceNumberOfGivenStructure(const std::vector& st) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeCornersGhost(const std::vector& st, int ghostLev) throw(INTERP_KERNEL::Exception); - static std::vector GetSplitVectFromStruct(const std::vector& strct) throw(INTERP_KERNEL::Exception); - %extend - { - virtual MEDCouplingStructuredMesh *buildStructuredSubPart(PyObject *cellPart) const throw(INTERP_KERNEL::Exception) - { - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(cellPart,tmpp1,tmpp2); - std::vector< std::pair > inp; - if(tmpp2==2) - { - inp.resize(tmpp1); - for(int i=0;ibuildStructuredSubPart(inp); - } - - static DataArrayInt *BuildExplicitIdsFrom(PyObject *st, PyObject *part) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - // - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp4=convertObjToPossibleCpp1_Safe(st,sw,szArr,iTypppArr,stdvecTyyppArr); - std::vector tmp5(tmp4,tmp4+szArr); - // - return MEDCouplingStructuredMesh::BuildExplicitIdsFrom(tmp5,inp); - } - - static void MultiplyPartOf(const std::vector& st, PyObject *part, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - MEDCouplingStructuredMesh::MultiplyPartOf(st,inp,factor,da); - } - - static void MultiplyPartOfByGhost(const std::vector& st, PyObject *part, int ghostSize, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - MEDCouplingStructuredMesh::MultiplyPartOfByGhost(st,inp,ghostSize,factor,da); - } - - static PyObject *PutInGhostFormat(int ghostSize, const std::vector& st, PyObject *part) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - std::vector stWithGhost; - std::vector< std::pair > partWithGhost; - MEDCouplingStructuredMesh::PutInGhostFormat(ghostSize,st,inp,stWithGhost,partWithGhost); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,convertIntArrToPyList2(stWithGhost)); - PyTuple_SetItem(ret,1,convertFromVectorPairInt(partWithGhost)); - return ret; - } - - static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector& st, const DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(partCompactFormat,inp); - return MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,fieldOfDbl,inp); - } - - static void AssignPartOfFieldOfDoubleUsing(const std::vector& st, DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat, const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(partCompactFormat,inp); - MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(st,fieldOfDbl,inp,other); - } - - static int DeduceNumberOfGivenRangeInCompactFrmt(PyObject *part) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(inp); - } - - static DataArrayInt *Build1GTNodalConnectivity(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - return MEDCouplingStructuredMesh::Build1GTNodalConnectivity(tmp,tmp+szArr); - } - - static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp(convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr)); - return MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh(tmp,tmp+szArr); - } - - static std::vector GetDimensionsFromCompactFrmt(PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(partCompactFormat,inp); - return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(inp); - } - - static PyObject *GetCompactFrmtFromDimensions(const std::vector& dims) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > ret(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dims)); - PyObject *retPy=PyList_New(ret.size()); - for(std::size_t i=0;i > r1Cpp,r2Cpp; - convertPyToVectorPairInt(r1,r1Cpp); - convertPyToVectorPairInt(r2,r2Cpp); - std::vector< std::pair > ret(MEDCouplingStructuredMesh::IntersectRanges(r1Cpp,r2Cpp)); - PyObject *retPy=PyList_New(ret.size()); - for(std::size_t i=0;i > r1Cpp,r2Cpp; - convertPyToVectorPairInt(r1,r1Cpp); - convertPyToVectorPairInt(r2,r2Cpp); - return MEDCouplingStructuredMesh::AreRangesIntersect(r1Cpp,r2Cpp); - } - - static PyObject *IsPartStructured(PyObject *li, PyObject *st) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - int szArr2,sw2,iTypppArr2; - std::vector stdvecTyyppArr2; - const int *tmp2=convertObjToPossibleCpp1_Safe(st,sw2,szArr2,iTypppArr2,stdvecTyyppArr2); - std::vector tmp3(tmp2,tmp2+szArr2); - std::vector< std::pair > partCompactFormat; - bool ret0=MEDCouplingStructuredMesh::IsPartStructured(tmp,tmp+szArr,tmp3,partCompactFormat); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyObject *ret1Py=PyList_New(partCompactFormat.size()); - for(std::size_t i=0;i > param0,param1,ret; - convertPyToVectorPairInt(bigInAbs,param0); - convertPyToVectorPairInt(partOfBigInAbs,param1); - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(param0,param1,ret,check); - PyObject *retPy(PyList_New(ret.size())); - for(std::size_t i=0;i& translation) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > param0; - convertPyToVectorPairInt(part,param0); - std::vector< std::pair > ret(MEDCouplingStructuredMesh::TranslateCompactFrmt(param0,translation)); - PyObject *retPy(PyList_New(ret.size())); - for(std::size_t i=0;i FindTranslationFrom(PyObject *startingFrom, PyObject *goingTo) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > param0,param1; - convertPyToVectorPairInt(startingFrom,param0); - convertPyToVectorPairInt(goingTo,param1); - return MEDCouplingStructuredMesh::FindTranslationFrom(param0,param1); - } - - static PyObject *ChangeReferenceToGlobalOfCompactFrmt(PyObject *bigInAbs, PyObject *partOfBigRelativeToBig, bool check=true) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > param0,param1,ret; - convertPyToVectorPairInt(bigInAbs,param0); - convertPyToVectorPairInt(partOfBigRelativeToBig,param1); - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(param0,param1,ret,check); - PyObject *retPy(PyList_New(ret.size())); - for(std::size_t i=0;isimpleRepr(); - } - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - DataArrayDouble *getCoordsAt(int i) throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getCoordsAt(i); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - //== MEDCouplingCMesh End - - //== MEDCouplingCurveLinearMesh - - class MEDCouplingCurveLinearMesh : public ParaMEDMEM::MEDCouplingStructuredMesh - { - public: - static MEDCouplingCurveLinearMesh *New() throw(INTERP_KERNEL::Exception); - static MEDCouplingCurveLinearMesh *New(const std::string& meshName) throw(INTERP_KERNEL::Exception); - MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; - void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingCurveLinearMesh() throw(INTERP_KERNEL::Exception) - { - return MEDCouplingCurveLinearMesh::New(); - } - MEDCouplingCurveLinearMesh(const std::string& meshName) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingCurveLinearMesh::New(meshName); - } - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingCurveLinearMesh"); - } - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getCoords(); - if(ret) - ret->incrRef(); - return ret; - } - void setNodeGridStructure(PyObject *gridStruct) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(gridStruct,sw,szArr,iTypppArr,stdvecTyyppArr); - self->setNodeGridStructure(tmp,tmp+szArr); - } - } - }; - - //== MEDCouplingCurveLinearMesh End - - //== MEDCouplingIMesh - - class MEDCouplingIMesh : public ParaMEDMEM::MEDCouplingStructuredMesh - { - public: - static MEDCouplingIMesh *New() throw(INTERP_KERNEL::Exception); - // - void setSpaceDimension(int spaceDim) throw(INTERP_KERNEL::Exception); - std::vector getNodeStruct() const throw(INTERP_KERNEL::Exception); - std::vector getOrigin() const throw(INTERP_KERNEL::Exception); - std::vector getDXYZ() const throw(INTERP_KERNEL::Exception); - void setAxisUnit(const std::string& unitName) throw(INTERP_KERNEL::Exception); - std::string getAxisUnit() const throw(INTERP_KERNEL::Exception); - double getMeasureOfAnyCell() const throw(INTERP_KERNEL::Exception); - MEDCouplingCMesh *convertToCartesian() const throw(INTERP_KERNEL::Exception); - void refineWithFactor(const std::vector& factors) throw(INTERP_KERNEL::Exception); - MEDCouplingIMesh *asSingleCell() const throw(INTERP_KERNEL::Exception); - MEDCouplingIMesh *buildWithGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingIMesh() - { - return MEDCouplingIMesh::New(); - } - static MEDCouplingIMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - static const char msg0[]="MEDCouplingIMesh::New : error on 'origin' parameter !"; - static const char msg1[]="MEDCouplingIMesh::New : error on 'dxyz' parameter !"; - const int *nodeStrctPtr(0); - const double *originPtr(0),*dxyzPtr(0); - int sw,sz,val0; - std::vector bb0; - nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); - // - double val,val2; - std::vector bb,bb2; - int sz1,sz2; - originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); - dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); - // - return MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); - } - - MEDCouplingIMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingIMesh_New__SWIG_1(meshName,spaceDim,nodeStrct,origin,dxyz); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingIMesh"); - } - - void setNodeStruct(PyObject *nodeStrct) throw(INTERP_KERNEL::Exception) - { - int sw,sz,val0; - std::vector bb0; - const int *nodeStrctPtr(convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0)); - self->setNodeStruct(nodeStrctPtr,nodeStrctPtr+sz); - } - - void setOrigin(PyObject *origin) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="MEDCouplingIMesh::setOrigin : invalid input 'origin' parameter ! integer, float, list/tuple of float, DataArrayDouble or DataArrayDoubleTuple supported !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw,nbTuples; - const double *originPtr(convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg,false,nbTuples)); - self->setOrigin(originPtr,originPtr+nbTuples); - } - - void setDXYZ(PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="MEDCouplingIMesh::setDXYZ : invalid input 'dxyz' parameter ! integer, float, list/tuple of float, DataArrayDouble or DataArrayDoubleTuple supported !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw,nbTuples; - const double *originPtr(convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val,bb,msg,false,nbTuples)); - self->setDXYZ(originPtr,originPtr+nbTuples); - } - - static void CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::CondenseFineToCoarse(coarseSt,fineDA,inp,facts,coarseDA); - } - - static void CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::CondenseFineToCoarseGhost(coarseSt,fineDA,inp,facts,coarseDA,ghostSize); - } - - static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::SpreadCoarseToFine(coarseDA,coarseSt,fineDA,inp,facts); - } - - static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, int ghostSize) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::SpreadCoarseToFineGhost(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); - } - - static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, int ghostSize) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::SpreadCoarseToFineGhostZone(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - } - }; - - //== MEDCouplingIMesh End - -} - -namespace ParaMEDMEM -{ - class MEDCouplingField : public ParaMEDMEM::RefCountObject, public ParaMEDMEM::TimeLabel - { - public: - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual bool areCompatibleForMerge(const MEDCouplingField *other) const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception); - virtual void copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception); - void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); - void setName(const char *name) throw(INTERP_KERNEL::Exception); - std::string getDescription() const throw(INTERP_KERNEL::Exception); - void setDescription(const char *desc) throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - TypeOfField getTypeOfField() const throw(INTERP_KERNEL::Exception); - NatureOfField getNature() const throw(INTERP_KERNEL::Exception); - virtual void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception); - DataArrayDouble *getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); - int getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception); - int getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception); - void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); - void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); - MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); - int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); - int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); - const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); - int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - void setDiscretization(MEDCouplingFieldDiscretization *newDisc); - %extend { - PyObject *getMesh() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingMesh *ret1=const_cast(self->getMesh()); - if(ret1) - ret1->incrRef(); - return convertMesh(ret1,SWIG_POINTER_OWN | 0 ); - } - - PyObject *getDiscretization() throw(INTERP_KERNEL::Exception) - { - MEDCouplingFieldDiscretization *ret=self->getDiscretization(); - if(ret) - ret->incrRef(); - return convertFieldDiscretization(ret,SWIG_POINTER_OWN | 0 ); - } - - PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) - { - std::set ret=self->getGaussLocalizationIdsOfOneType(type); - return convertIntArrToPyList3(ret); - } - - PyObject *isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,meshPrec,valsPrec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *buildSubMeshData(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingMesh *ret0=0; - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - ret0=self->buildSubMeshData(tmp,tmp+size,ret1); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - ret0=self->buildSubMeshData(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),ret1); - } - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - return res; - } - - PyObject *buildSubMeshDataRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - int bb,ee,ss; - MEDCouplingMesh *ret0=self->buildSubMeshDataRange(begin,end,step,bb,ee,ss,ret1); - PyObject *res=PyTuple_New(2); - PyTuple_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - if(ret1) - PyTuple_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - else - { - PyObject *res1=PySlice_New(PyInt_FromLong(bb),PyInt_FromLong(ee),PyInt_FromLong(ss)); - PyTuple_SetItem(res,1,res1); - } - return res; - } - - DataArrayInt *computeTupleIdsToSelectFromCellIds(PyObject *cellIds) const - { - int sw,sz(-1); - int v0; std::vector v1; - const int *cellIdsBg(convertObjToPossibleCpp1_Safe(cellIds,sw,sz,v0,v1)); - return self->computeTupleIdsToSelectFromCellIds(cellIdsBg,cellIdsBg+sz); - } - - void setGaussLocalizationOnCells(PyObject *li, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->setGaussLocalizationOnCells(tmp,((int *)tmp)+size,refCoo,gsCoo,wg); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->setGaussLocalizationOnCells(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),refCoo,gsCoo,wg); - } - } - - PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - self->getCellIdsHavingGaussLocalization(locId,tmp); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)tmp.size(),1); - std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - int getNumberOfTuplesExpectedRegardingCode(PyObject *code, PyObject *idsPerType) const throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - convertPyToNewIntArr4(code,1,3,inp0); - std::vector inp1; - convertFromPyObjVectorOfObj(idsPerType,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",inp1); - return self->getNumberOfTuplesExpectedRegardingCode(inp0,inp1); - } - } - }; - - class MEDCouplingFieldTemplate : public ParaMEDMEM::MEDCouplingField - { - public: - static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldTemplate *New(TypeOfField type); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingFieldTemplate::New(f); - } - - MEDCouplingFieldTemplate(TypeOfField type) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingFieldTemplate::New(type); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - } - }; - - class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField - { - public: - static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception); - void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); - void copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - std::string writeVTK(const std::string& fileName, bool isBinary=true) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *clone(bool recDeepCpy) const; - MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; - MEDCouplingFieldDouble *deepCpy() const; - MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *nodeToCellDiscretization() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *cellToNodeDiscretization() const throw(INTERP_KERNEL::Exception); - TypeOfTimeDiscretization getTimeDiscretization() const throw(INTERP_KERNEL::Exception); - double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - double getIJK(int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); - void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception); - void setArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); - void setEndArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); - void setTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); - void setStartTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); - void setEndTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); - int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); - int getNumberOfValues() const throw(INTERP_KERNEL::Exception); - void setTimeTolerance(double val) throw(INTERP_KERNEL::Exception); - double getTimeTolerance() const throw(INTERP_KERNEL::Exception); - void setIteration(int it) throw(INTERP_KERNEL::Exception); - void setEndIteration(int it) throw(INTERP_KERNEL::Exception); - void setOrder(int order) throw(INTERP_KERNEL::Exception); - void setEndOrder(int order) throw(INTERP_KERNEL::Exception); - void setTimeValue(double val) throw(INTERP_KERNEL::Exception); - void setEndTimeValue(double val) throw(INTERP_KERNEL::Exception); - void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); - void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); - bool mergeNodes(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); - bool mergeNodes2(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); - bool zipCoords(double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); - bool zipConnectivity(int compType,double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); - bool simplexize(int policy) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); - void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception); - void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception); - void fillFromAnalytic(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void fillFromAnalytic2(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc2(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc(int nbOfComp, double val) throw(INTERP_KERNEL::Exception); - void applyFunc(const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFuncFast32(const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFuncFast64(const std::string& func) throw(INTERP_KERNEL::Exception); - double accumulate(int compId) const throw(INTERP_KERNEL::Exception); - double getMaxValue() const throw(INTERP_KERNEL::Exception); - double getMinValue() const throw(INTERP_KERNEL::Exception); - double getAverageValue() const throw(INTERP_KERNEL::Exception); - double norm2() const throw(INTERP_KERNEL::Exception); - double normMax() const throw(INTERP_KERNEL::Exception); - //do not put a default value to isWAbs because confusion in python with overloaded getWeightedAverageValue method - double getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); - double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); - double normL1(int compId) const throw(INTERP_KERNEL::Exception); - double normL2(int compId) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *negate() const throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME) - { - return MEDCouplingFieldDouble::New(type,td); - } - - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME) - { - return MEDCouplingFieldDouble::New(ft,td); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - DataArrayDouble *getArray() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getArray(); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getArrays() const throw(INTERP_KERNEL::Exception) - { - std::vector arrs=self->getArrays(); - for(std::vector::iterator it=arrs.begin();it!=arrs.end();it++) - if(*it) - (*it)->incrRef(); - int sz=arrs.size(); - PyObject *ret=PyTuple_New(sz); - for(int i=0;i tmp; - convertFromPyObjVectorOfObj(ls,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); - int sz=tmp.size(); - std::vector arrs(sz); - for(int i=0;i(tmp[i]); - self->setArrays(arrs); - } - - DataArrayDouble *getEndArray() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getEndArray(); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getValueOn(PyObject *sl) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDouble::getValueOn : no underlying mesh !"); - int spaceDim=mesh->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingFieldDouble::getValueOn : "; - const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOn(spaceLoc,res); - return convertDblArrToPyList(res,sz); - } - - PyObject *getValueOnPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOnPos(i,j,k,res); - return convertDblArrToPyList(res,sz); - } - - DataArrayDouble *getValueOnMulti(PyObject *locs) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingMesh *mesh(self->getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap MEDCouplingFieldDouble::getValueOnMulti : lying on a null mesh !"); - // - int sw,nbPts; - double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector v3; - const double *inp=convertObjToPossibleCpp5_Safe2(locs,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDouble::getValueOnMulti", - mesh->getSpaceDimension(),true,nbPts); - return self->getValueOnMulti(inp,nbPts); - } - - PyObject *getValueOn(PyObject *sl, double time) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDouble::getValueOn : no underlying mesh !"); - int spaceDim=mesh->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingFieldDouble::getValueOn : "; - const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - // - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOn(spaceLoc,time,res); - return convertDblArrToPyList(res,sz); - } - - void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - if(self->getArray()!=0) - ParaMEDMEM_DataArrayDouble_setValues__SWIG_0(self->getArray(),li,nbOfTuples,nbOfComp); - else - { - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - ParaMEDMEM_DataArrayDouble_setValues__SWIG_0(arr,li,nbOfTuples,nbOfComp); - self->setArray(arr); - } - } - - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - PyObject *getStartTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getStartTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - PyObject *getEndTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getEndTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - PyObject *accumulate() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->accumulate(tmp); - return convertDblArrToPyList(tmp,sz); - } - PyObject *integral(bool isWAbs) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->integral(isWAbs,tmp); - return convertDblArrToPyList(tmp,sz); - } - PyObject *getWeightedAverageValue(bool isWAbs=true) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->getWeightedAverageValue(tmp,isWAbs); - return convertDblArrToPyList(tmp,sz); - } - PyObject *normL1() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL1(tmp); - return convertDblArrToPyList(tmp,sz); - } - PyObject *normL2() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL2(tmp); - return convertDblArrToPyList(tmp,sz); - } - void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberCells(tmp,check); - } - - void renumberCellsWithoutMesh(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberCellsWithoutMesh(tmp,check); - } - - void renumberNodes(PyObject *li, double eps=1e-15) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodes(tmp,eps); - } - - void renumberNodesWithoutMesh(PyObject *li, int newNbOfNodes, double eps=1e-15) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodesWithoutMesh(tmp,newNbOfNodes,eps); - } - - MEDCouplingFieldDouble *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : field lies on a null mesh !"); - int nbc=mesh->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - return self->buildSubPart(&singleVal,&singleVal+1); - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - return self->buildSubPart(&tmp,&tmp+1); - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - return self->buildSubPart(&multiVal[0],&multiVal[0]+multiVal.size()); - } - case 3: - { - return self->buildSubPartRange(slic.first,slic.second.first,slic.second.second); - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - return self->buildSubPart(daIntTyypp->begin(),daIntTyypp->end()); - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } - } - - MEDCouplingFieldDouble *__getitem__(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - const char msg[]="MEDCouplingFieldDouble::__getitem__ : invalid call Available API are : \n-myField[dataArrayInt]\n-myField[slice]\n-myField[pythonListOfCellIds]\n-myField[integer]\n-myField[dataArrayInt,1]\n-myField[slice,1]\n-myField[pythonListOfCellIds,1]\n-myField[integer,1]\n"; - if(PyTuple_Check(li)) - { - Py_ssize_t sz=PyTuple_Size(li); - if(sz!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *elt0=PyTuple_GetItem(li,0),*elt1=PyTuple_GetItem(li,1); - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!self->getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array set on field to deduce number of components !"); - try - { convertObjToPossibleCpp2(elt1,self->getArray()->getNumberOfComponents(),sw,singleVal,multiVal,slic,daIntTyypp); } - catch(INTERP_KERNEL::Exception& e) - { std::ostringstream oss; oss << "MEDCouplingFieldDouble::__getitem__ : invalid type in 2nd parameter (compo) !" << e.what(); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDCouplingAutoRefCountObjectPtr ret0=ParaMEDMEM_MEDCouplingFieldDouble_buildSubPart(self,elt0); - DataArrayDouble *ret0Arr=ret0->getArray(); - if(!ret0Arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array exists to apply restriction on component on it !"); - switch(sw) - { - case 1: - { - std::vector v2(1,singleVal); - MEDCouplingAutoRefCountObjectPtr aarr(ret0Arr->keepSelectedComponents(v2)); - ret0->setArray(aarr); - return ret0.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aarr(ret0Arr->keepSelectedComponents(multiVal)); - ret0->setArray(aarr); - return ret0.retn(); - } - case 3: - { - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(slic.first,slic.second.first,slic.second.second,"MEDCouplingFieldDouble::__getitem__ : invalid range in 2nd parameter (components) !"); - std::vector v2(nbOfComp); - for(int i=0;i aarr(ret0Arr->keepSelectedComponents(v2)); - ret0->setArray(aarr); - return ret0.retn(); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - - } - else - return ParaMEDMEM_MEDCouplingFieldDouble_buildSubPart(self,li); - } - - PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMaxValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMinValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - MEDCouplingFieldDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - return self->keepSelectedComponents(tmp); - } - - void setSelectedComponents(const MEDCouplingFieldDouble *f, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->setSelectedComponents(f,tmp); - } - - MEDCouplingFieldDouble *extractSlice3D(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - int spaceDim=3; - const char msg[]="Python wrap of MEDCouplingFieldDouble::extractSlice3D : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingFieldDouble::extractSlice3D : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - // - return self->extractSlice3D(orig,vect,eps); - } - - MEDCouplingFieldDouble *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(self,obj); - } - - MEDCouplingFieldDouble *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(self,obj); - } - - MEDCouplingFieldDouble *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__sub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__sub__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)-(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(1.,-val); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Substract(self->getArray(),a); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Substract(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Substract(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - MEDCouplingFieldDouble *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(self,obj); - } - - MEDCouplingFieldDouble *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(self,obj); - } - - MEDCouplingFieldDouble *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(self,obj); - } - - MEDCouplingFieldDouble *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__div__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__div__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)/(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble.__div__ : trying to divide by zero !"); - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(1./val,0); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Divide(self->getArray(),a); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Divide(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Divide(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - MEDCouplingFieldDouble *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(self,obj); - } - - MEDCouplingFieldDouble *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__pow__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__pow__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)^(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyPow(val); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Pow(self->getArray(),a); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Pow(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Pow(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - MEDCouplingFieldDouble *__neg__() const throw(INTERP_KERNEL::Exception) - { - return self->negate(); - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__iadd__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__iadd__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self+=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(1.,val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self+=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self+=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->addEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__isub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__isub__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self-=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(1.,-val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self-=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self-=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->substractEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__imul__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__imul__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self*=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(val,0); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self*=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self*=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->multiplyEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__idiv__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__idiv__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self/=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble.__idiv__ : trying to divide by zero !"); - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(1./val,0); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self/=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self/=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->divideEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__ipow__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__ipow__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self^=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyPow(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self^=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self^=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->powEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - static MEDCouplingFieldDouble *MergeFields(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - return MEDCouplingFieldDouble::MergeFields(tmp); - } - - static std::string WriteVTK(const char *fileName, PyObject *li, bool isBinary=true) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - return MEDCouplingFieldDouble::WriteVTK(fileName,tmp,isBinary); - } - - PyObject *getTinySerializationInformation() const throw(INTERP_KERNEL::Exception) - { - std::vector a0; - std::vector a1; - std::vector a2; - self->getTinySerializationDbleInformation(a0); - self->getTinySerializationIntInformation(a1); - self->getTinySerializationStrInformation(a2); - // - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); - int sz(a2.size()); - PyObject *ret2(PyList_New(sz)); - { - for(int i=0;i ret1; - self->serialize(ret0,ret1); - if(ret0) - ret0->incrRef(); - std::size_t sz(ret1.size()); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyObject *ret1Py(PyList_New(sz)); - for(std::size_t i=0;iincrRef(); - PyList_SetItem(ret1Py,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret1[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - } - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDCouplingFieldDouble.__new__ : the args in input is expected to be a tuple !"; - if(!PyTuple_Check(args)) - throw INTERP_KERNEL::Exception(MSG); - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - //// - PyObject *a(PyInt_FromLong(0)); - PyObject *uniqueElt(PyDict_GetItem(PyTuple_GetItem(args,1),a)); - Py_DECREF(a); - if(!uniqueElt) - throw INTERP_KERNEL::Exception(MSG); - if(!PyTuple_Check(uniqueElt) || PyTuple_Size(uniqueElt)!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *tmp2(PyObject_CallObject(initMeth,uniqueElt)); - Py_XDECREF(tmp2); - //// - Py_DECREF(initMeth); - } - return instance; - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - {// put an empty dict in input to say to __new__ to call __init__... - self->checkCoherency(); - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - { - PyObject *a(PyInt_FromLong(0)),*b(PyInt_FromLong(self->getTypeOfField())),*c(PyInt_FromLong(self->getTimeDiscretization())); - PyObject *d(PyTuple_New(2)); PyTuple_SetItem(d,0,b); PyTuple_SetItem(d,1,c); - PyDict_SetItem(ret0,a,d); - Py_DECREF(a); Py_DECREF(d); - } - PyTuple_SetItem(ret,0,ret0); - return ret; - } - - PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) - { - self->checkCoherency(); - PyObject *ret0(ParaMEDMEM_MEDCouplingFieldDouble_getTinySerializationInformation(self)); - PyObject *ret1(ParaMEDMEM_MEDCouplingFieldDouble_serialize(self)); - const MEDCouplingMesh *mesh(self->getMesh()); - if(mesh) - mesh->incrRef(); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,ret0); - PyTuple_SetItem(ret,1,ret1); - PyTuple_SetItem(ret,2,convertMesh(const_cast(mesh),SWIG_POINTER_OWN | 0 )); - return ret; - } - - void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDCouplingFieldDouble.__setstate__ : expected input is a tuple of size 3 !"; - if(!PyTuple_Check(inp)) - throw INTERP_KERNEL::Exception(MSG); - int sz(PyTuple_Size(inp)); - if(sz!=3) - throw INTERP_KERNEL::Exception(MSG); - // mesh - PyObject *elt2(PyTuple_GetItem(inp,2)); - void *argp=0; - int status(SWIG_ConvertPtr(elt2,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMesh,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - self->setMesh(reinterpret_cast< const MEDCouplingUMesh * >(argp)); - // - PyObject *elt0(PyTuple_GetItem(inp,0)); - PyObject *elt1(PyTuple_GetItem(inp,1)); - std::vector a0; - std::vector a1; - std::vector a2; - DataArrayInt *b0(0); - std::vectorb1; - { - if(!PyTuple_Check(elt0) && PyTuple_Size(elt0)!=3) - throw INTERP_KERNEL::Exception(MSG); - PyObject *a0py(PyTuple_GetItem(elt0,0)),*a1py(PyTuple_GetItem(elt0,1)),*a2py(PyTuple_GetItem(elt0,2)); - int tmp(-1); - fillArrayWithPyListDbl3(a0py,tmp,a0); - convertPyToNewIntArr3(a1py,a1); - fillStringVector(a2py,a2); - } - { - if(!PyTuple_Check(elt1) && PyTuple_Size(elt1)!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *b0py(PyTuple_GetItem(elt1,0)),*b1py(PyTuple_GetItem(elt1,1)); - void *argp(0); - int status(SWIG_ConvertPtr(b0py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - b0=reinterpret_cast(argp); - convertFromPyObjVectorOfObj(b1py,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",b1); - } - self->checkForUnserialization(a1,b0,b1); - // useless here to call resizeForUnserialization because arrays are well resized. - self->finishUnserialization(a1,a0,a2); - } - } - }; - - class MEDCouplingMultiFields : public RefCountObject, public TimeLabel - { - public: - int getNumberOfFields() const; - MEDCouplingMultiFields *deepCpy() const; - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - static MEDCouplingMultiFields *New(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingMultiFields::New(fs); - } - MEDCouplingMultiFields(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingMultiFields::New(fs); - } - PyObject *getFields() const - { - std::vector fields=self->getFields(); - int sz=fields.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(fields[i]),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, 0 )); - } - } - return res; - } - PyObject *getFieldAtPos(int id) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingFieldDouble *ret=self->getFieldAtPos(id); - if(ret) - { - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - return SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, 0 ); - } - PyObject *getMeshes() const throw(INTERP_KERNEL::Exception) - { - std::vector ms=self->getMeshes(); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,convertMesh(ms[i], SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 )); - } - } - return res; - } - PyObject *getDifferentMeshes() const throw(INTERP_KERNEL::Exception) - { - std::vector refs; - std::vector ms=self->getDifferentMeshes(refs); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,convertMesh(ms[i], SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 )); - } - } - // - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,res); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(refs)); - return ret; - } - PyObject *getArrays() const throw(INTERP_KERNEL::Exception) - { - std::vector ms=self->getArrays(); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 )); - } - } - return res; - } - PyObject *getDifferentArrays() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::vector > refs; - std::vector ms=self->getDifferentArrays(refs); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - PyObject *res2 = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 )); - } - PyList_SetItem(res2,i,convertIntArrToPyList2(refs[i])); - } - // - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,res); - PyTuple_SetItem(ret,1,res2); - return ret; - } - } - }; - - class MEDCouplingDefinitionTime - { - public: - MEDCouplingDefinitionTime(); - void assign(const MEDCouplingDefinitionTime& other); - bool isEqual(const MEDCouplingDefinitionTime& other) const; - double getTimeResolution() const; - std::vector getHotSpotsTime() const; - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->appendRepr(oss); - return oss.str(); - } - - PyObject *getIdsOnTimeRight(double tm) const throw(INTERP_KERNEL::Exception) - { - int meshId,arrId,arrIdInField,fieldId; - self->getIdsOnTimeRight(tm,meshId,arrId,arrIdInField,fieldId); - PyObject *res=PyList_New(4); - PyList_SetItem(res,0,PyInt_FromLong(meshId)); - PyList_SetItem(res,1,PyInt_FromLong(arrId)); - PyList_SetItem(res,2,PyInt_FromLong(arrIdInField)); - PyList_SetItem(res,3,PyInt_FromLong(fieldId)); - return res; - } - - PyObject *getIdsOnTimeLeft(double tm) const throw(INTERP_KERNEL::Exception) - { - int meshId,arrId,arrIdInField,fieldId; - self->getIdsOnTimeLeft(tm,meshId,arrId,arrIdInField,fieldId); - PyObject *res=PyList_New(4); - PyList_SetItem(res,0,PyInt_FromLong(meshId)); - PyList_SetItem(res,1,PyInt_FromLong(arrId)); - PyList_SetItem(res,2,PyInt_FromLong(arrIdInField)); - PyList_SetItem(res,3,PyInt_FromLong(fieldId)); - return res; - } - } - }; - - class MEDCouplingFieldOverTime : public MEDCouplingMultiFields - { - public: - double getTimeTolerance() const throw(INTERP_KERNEL::Exception); - MEDCouplingDefinitionTime getDefinitionTimeZone() const; - - %extend - { - MEDCouplingFieldOverTime(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingFieldOverTime::New(fs); - } - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - static MEDCouplingFieldOverTime *New(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingFieldOverTime::New(fs); - } - } - }; - - class MEDCouplingCartesianAMRMesh; - - class MEDCouplingCartesianAMRPatchGen : public RefCountObject - { - public: - int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); - int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingCartesianAMRMeshGen *getMesh() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *ret(const_cast(self->getMesh())); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDCouplingCartesianAMRPatch : public MEDCouplingCartesianAMRPatchGen - { - public: - int getNumberOfOverlapedCellsForFather() const throw(INTERP_KERNEL::Exception); - bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const throw(INTERP_KERNEL::Exception); - std::vector computeCellGridSt() const throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getBLTRRange() const throw(INTERP_KERNEL::Exception) - { - const std::vector< std::pair >& ret(self->getBLTRRange()); - return convertFromVectorPairInt(ret); - } - - PyObject *getBLTRRangeRelativeToGF() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > ret(self->getBLTRRangeRelativeToGF()); - return convertFromVectorPairInt(ret); - } - - void addPatch(PyObject *bottomLeftTopRight, const std::vector& factors) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(bottomLeftTopRight,inp); - self->addPatch(inp,factors); - } - - MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRMeshGen *mesh(self->getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatchGen.__getitem__ : no underlying mesh !"); - if(patchId==mesh->getNumberOfPatches()) - { - std::ostringstream oss; - oss << "Requesting for patchId " << patchId << " having only " << mesh->getNumberOfPatches() << " patches !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - MEDCouplingCartesianAMRPatch *ret(const_cast(mesh->getPatch(patchId))); - if(ret) - ret->incrRef(); - return ret; - } - - void __delitem__(int patchId) throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *mesh(const_cast(self->getMesh())); - if(!mesh) - throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatch.__delitem__ : no underlying mesh !"); - mesh->removePatch(patchId); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRMeshGen *mesh(self->getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatch.__len__ : no underlying mesh !"); - return mesh->getNumberOfPatches(); - } - } - }; - - class MEDCouplingCartesianAMRPatchGF : public MEDCouplingCartesianAMRPatchGen - { - }; - - class MEDCouplingCartesianAMRMeshGen : public RefCountObject, public TimeLabel - { - public: - int getAbsoluteLevel() const throw(INTERP_KERNEL::Exception); - int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const throw(INTERP_KERNEL::Exception); - std::vector getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const throw(INTERP_KERNEL::Exception); - int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - const std::vector& getFactors() const throw(INTERP_KERNEL::Exception); - void setFactors(const std::vector& newFactors) throw(INTERP_KERNEL::Exception); - int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsAtCurrentLevel() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); - bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const throw(INTERP_KERNEL::Exception); - virtual void detachFromFather() throw(INTERP_KERNEL::Exception); - // - int getNumberOfPatches() const throw(INTERP_KERNEL::Exception); - int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception); - std::vector getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const throw(INTERP_KERNEL::Exception); - void removeAllPatches() throw(INTERP_KERNEL::Exception); - void removePatch(int patchId) throw(INTERP_KERNEL::Exception); - void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors) throw(INTERP_KERNEL::Exception); - void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector& factors, double eps) throw(INTERP_KERNEL::Exception); - DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; - void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); - std::string buildPythonDumpOfThis() const throw(INTERP_KERNEL::Exception); - %extend - { - void addPatch(PyObject *bottomLeftTopRight, const std::vector& factors) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(bottomLeftTopRight,inp); - self->addPatch(inp,factors); - } - - PyObject *getPatches() const throw(INTERP_KERNEL::Exception) - { - std::vector< const MEDCouplingCartesianAMRPatch *> ps(self->getPatches()); - int sz(ps.size()); - PyObject *ret = PyList_New(sz); - for(int i=0;i(ps[i])); - if(elt) - elt->incrRef(); - PyList_SetItem(ret,i,convertCartesianAMRPatch(elt, SWIG_POINTER_OWN | 0 )); - } - return ret; - } - - // agy : don't know why typemap fails here ??? let it in the extend section - PyObject *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const throw(INTERP_KERNEL::Exception) - { - return convertCartesianAMRMesh(self->deepCpy(father), SWIG_POINTER_OWN | 0 ); - } - - MEDCouplingCartesianAMRPatch *getPatchAtPosition(const std::vector& pos) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRPatch *ret(self->getPatchAtPosition(pos)); - MEDCouplingCartesianAMRPatch *ret2(const_cast(ret)); - if(ret2) - ret2->incrRef(); - return ret2; - } - - MEDCouplingCartesianAMRMeshGen *getMeshAtPosition(const std::vector& pos) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRMeshGen *ret(self->getMeshAtPosition(pos)); - MEDCouplingCartesianAMRMeshGen *ret2(const_cast(ret)); - if(ret2) - ret2->incrRef(); - return ret2; - } - - virtual PyObject *positionRelativeToGodFather() const throw(INTERP_KERNEL::Exception) - { - std::vector out1; - std::vector< std::pair > out0(self->positionRelativeToGodFather(out1)); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,convertFromVectorPairInt(out0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(out1)); - return ret; - } - - virtual PyObject *retrieveGridsAt(int absoluteLev) const throw(INTERP_KERNEL::Exception) - { - std::vector ps(self->retrieveGridsAt(absoluteLev)); - int sz(ps.size()); - PyObject *ret = PyList_New(sz); - for(int i=0;i inp; - convertFromPyObjVectorOfObj(recurseArrs,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",inp); - return self->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,inp); - } - - virtual MEDCouplingCartesianAMRMeshGen *getFather() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *ret(const_cast(self->getFather())); - if(ret) - ret->incrRef(); - return ret; - } - - virtual MEDCouplingCartesianAMRMeshGen *getGodFather() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *ret(const_cast(self->getGodFather())); - if(ret) - ret->incrRef(); - return ret; - } - - MEDCouplingCartesianAMRPatch *getPatch(int patchId) const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRPatch *ret(const_cast(self->getPatch(patchId))); - if(ret) - ret->incrRef(); - return ret; - } - - MEDCouplingIMesh *getImageMesh() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingIMesh *ret(self->getImageMesh()); - if(ret) - ret->incrRef(); - return const_cast(ret); - } - - MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) - { - if(patchId==self->getNumberOfPatches()) - { - std::ostringstream oss; - oss << "Requesting for patchId " << patchId << " having only " << self->getNumberOfPatches() << " patches !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - MEDCouplingCartesianAMRPatch *ret(const_cast(self->getPatch(patchId))); - if(ret) - ret->incrRef(); - return ret; - } - - void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, PyObject *arrsOnPatches, bool isConservative=true) const throw(INTERP_KERNEL::Exception) - { - std::vector arrsOnPatches2; - convertFromPyObjVectorOfObj(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2); - self->fillCellFieldOnPatchGhostAdv(patchId,cellFieldOnThis,ghostLev,arrsOnPatches2,isConservative); - } - - void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, PyObject *arrsOnPatches) const - { - std::vector arrsOnPatches2; - convertFromPyObjVectorOfObj(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2); - self->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches2); - } - - void __delitem__(int patchId) throw(INTERP_KERNEL::Exception) - { - self->removePatch(patchId); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfPatches(); - } - } - }; - - class MEDCouplingCartesianAMRMeshSub : public MEDCouplingCartesianAMRMeshGen - { - }; - - class MEDCouplingCartesianAMRMesh : public MEDCouplingCartesianAMRMeshGen - { - public: - static MEDCouplingCartesianAMRMesh *New(MEDCouplingIMesh *mesh) throw(INTERP_KERNEL::Exception); - %extend - { - static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - static const char msg0[]="MEDCouplingCartesianAMRMesh::New : error on 'origin' parameter !"; - static const char msg1[]="MEDCouplingCartesianAMRMesh::New : error on 'dxyz' parameter !"; - const int *nodeStrctPtr(0); - const double *originPtr(0),*dxyzPtr(0); - int sw,sz,val0; - std::vector bb0; - nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); - // - double val,val2; - std::vector bb,bb2; - int sz1,sz2; - originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); - dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); - // - return MEDCouplingCartesianAMRMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); - } - - void createPatchesFromCriterionML(PyObject *bso, const DataArrayDouble *criterion, PyObject *factors, double eps) throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - convertFromPyObjVectorOfObj(bso,SWIGTYPE_p_INTERP_KERNEL__BoxSplittingOptions,"BoxSplittingOptions",inp0); - std::vector< std::vector > inp2; - convertPyToVectorOfVectorOfInt(factors,inp2); - self->createPatchesFromCriterionML(inp0,criterion,inp2,eps); - } - - MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingCartesianAMRMesh_New__SWIG_1(meshName,spaceDim,nodeStrct,origin,dxyz); - } - - MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingCartesianAMRMesh::New(mesh); - } - } - }; - - class MEDCouplingDataForGodFather : public RefCountObject - { - public: - virtual void synchronizeFineToCoarse() throw(INTERP_KERNEL::Exception); - virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeCoarseToFine() throw(INTERP_KERNEL::Exception); - virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZones() throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZonesAtASpecifiedLevel(int level) throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) throw(INTERP_KERNEL::Exception); - virtual void alloc() throw(INTERP_KERNEL::Exception); - virtual void dealloc() throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingCartesianAMRMesh *getMyGodFather() throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMesh *ret(self->getMyGodFather()); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel - { - public: - int getNumberOfLevels() const throw(INTERP_KERNEL::Exception); - MEDCouplingAMRAttribute *deepCpy() const throw(INTERP_KERNEL::Exception); - MEDCouplingAMRAttribute *deepCpyWithoutGodFather() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - bool changeGodFather(MEDCouplingCartesianAMRMesh *gf) throw(INTERP_KERNEL::Exception); - MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const throw(INTERP_KERNEL::Exception); - std::string writeVTHB(const std::string& fileName) const throw(INTERP_KERNEL::Exception); - %extend - { - static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > fieldNamesCpp0; - std::vector< std::pair > > fieldNamesCpp1; - MEDCouplingAMRAttribute *ret(0); - try - { - convertPyToVectorPairStringInt(fieldNames,fieldNamesCpp0); - ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0,ghostLev); - } - catch(INTERP_KERNEL::Exception&) - { - convertPyToVectorPairStringVecString(fieldNames,fieldNamesCpp1); - ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1,ghostLev); - } - return ret; - } - - MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames,ghostLev); - } - - DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception) - { - const DataArrayDouble *ret(self->getFieldOn(mesh,fieldName)); - DataArrayDouble *ret2(const_cast(ret)); - if(ret2) - ret2->incrRef(); - return ret2; - } - - void spillInfoOnComponents(PyObject *compNames) throw(INTERP_KERNEL::Exception) - { - std::vector< std::vector > compNamesCpp; - convertPyToVectorOfVectorOfString(compNames,compNamesCpp); - self->spillInfoOnComponents(compNamesCpp); - } - - void spillNatures(PyObject *nfs) throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - if(!fillIntVector(nfs,inp0)) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingAMRAttribute::spillNatures : vector of NatureOfField enum expected !"); - std::size_t sz(inp0.size()); - std::vector inp00(sz); - for(std::size_t i=0;ispillNatures(inp00); - } - - PyObject *retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception) - { - std::vector ret(self->retrieveFieldsOn(mesh)); - int sz((int)ret.size()); - PyObject *retPy(PyList_New(sz)); - for(int i=0;iisEqualIfNotWhy(other,eps,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - DataArrayDouble *getData() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret(self->getData()); - if(ret) - ret->incrRef(); - return ret; - } - - DenseMatrix *__add__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Add(self,other); - } - - DenseMatrix *__sub__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Substract(self,other); - } - - DenseMatrix *__mul__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Multiply(self,other); - } - - DenseMatrix *__mul__(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Multiply(self,other); - } - - PyObject *___iadd___(PyObject *trueSelf, const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - self->addEqual(other); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___isub___(PyObject *trueSelf, const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - self->substractEqual(other); - Py_XINCREF(trueSelf); - return trueSelf; - } -#ifdef WITH_NUMPY - PyObject *toNumPyMatrix() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! - { - PyObject *obj(ToNumPyArrayUnderground(self->getData(),NPY_DOUBLE,"DataArrayDouble",self->getNumberOfRows(),self->getNumberOfCols())); - return obj; - } -#endif - } - }; - - class PartDefinition : public RefCountObject, public TimeLabel - { - public: - static PartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); - static PartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *toDAI() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfElems() const throw(INTERP_KERNEL::Exception); - virtual std::string getRepr() const throw(INTERP_KERNEL::Exception); - virtual PartDefinition *composeWith(const PartDefinition *other) const throw(INTERP_KERNEL::Exception); - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual PartDefinition *tryToSimplify() const throw(INTERP_KERNEL::Exception); - %extend - { - virtual PartDefinition *__add__(const PartDefinition& other) const throw(INTERP_KERNEL::Exception) - { - return (*self)+other; - } - - virtual PyObject *isEqual(const PartDefinition *other) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0(self->isEqual(other,ret1)); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - virtual PyObject *deepCpy() const throw(INTERP_KERNEL::Exception) - { - return convertPartDefinition(self->deepCpy(),SWIG_POINTER_OWN | 0); - } - } - protected: - virtual ~PartDefinition(); - }; - - class DataArrayPartDefinition : public PartDefinition - { - public: - static DataArrayPartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayPartDefinition(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception) - { - return DataArrayPartDefinition::New(listOfIds); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->getRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "DataArrayPartDefinition C++ instance at " << self << "." << std::endl; - oss << self->getRepr(); - return oss.str(); - } - } - protected: - virtual ~DataArrayPartDefinition(); - }; - - class SlicePartDefinition : public PartDefinition - { - public: - static SlicePartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); - int getEffectiveStop() const throw(INTERP_KERNEL::Exception); - %extend - { - SlicePartDefinition(int start, int stop, int step) throw(INTERP_KERNEL::Exception) - { - return SlicePartDefinition::New(start,stop,step); - } - - PyObject *getSlice() const throw(INTERP_KERNEL::Exception) - { - int a,b,c; - self->getSlice(a,b,c); - return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(c)); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->getRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "SlicePartDefinition C++ instance at " << self << "." << std::endl; - oss << self->getRepr(); - return oss.str(); - } - } - protected: - virtual ~SlicePartDefinition(); - }; -} - -%pythoncode %{ -import os -__filename=os.environ.get('PYTHONSTARTUP') -if __filename and os.path.isfile(__filename): - execfile(__filename) - pass -%} diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i b/medtool/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i deleted file mode 100644 index eba6b204e..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i +++ /dev/null @@ -1,2529 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "InterpKernelAutoPtr.hxx" - -/*! - * This method is an extention of PySlice_GetIndices but less - * open than PySlice_GetIndicesEx that accepts too many situations. - */ -void GetIndicesOfSlice(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) -{ - int ret(PySlice_GetIndices(slice,length,start,stop,step)); - if(ret==0) - return ; - if(*step>0 && *start==*stop && length==*start) - return ; - throw INTERP_KERNEL::Exception(msgInCaseOfFailure); -} - -/*! - * This method allows to retrieve slice info from \a slice. - */ -void GetIndicesOfSliceExplicitely(PySliceObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) -{ - int ret(PySlice_GetIndices(slice,std::numeric_limits::max(),start,stop,step)); - if(ret==0) - { - if(*start!=std::numeric_limits::max() && *stop!=std::numeric_limits::max()) - return ; - std::ostringstream oss; - oss << msgInCaseOfFailure << " The input slice contains some unknowns that can't be determined in static method ! The input slice must be explicit here !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - throw INTERP_KERNEL::Exception(msgInCaseOfFailure); -} - -int InterpreteNegativeInt(int val, int nbelem) -{ - if(val<0) - { - int newVal(nbelem+val); - if(newVal<0) - { - std::ostringstream oss; oss << "interpreteNegativeInt : request for negative int=" << val << " but number of elems is equal to " << nbelem << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return newVal; - } - else - return val; -} - -#ifdef WITH_NUMPY -#include -#if NPY_API_VERSION <= 0x00000006 -# define MED_NUMPY_OWNDATA NPY_OWNDATA -#else -# define MED_NUMPY_OWNDATA NPY_ARRAY_OWNDATA -#endif - -// specific DataArray deallocator callback. This deallocator is used both in the constructor of DataArray and in the toNumPyArr -// method. This dellocator uses weakref to determine if the linked numArr is still alive or not. If alive the ownership is given to it. -// if no more alive the "standart" DataArray deallocator is called. -void numarrdeal(void *pt, void *wron) -{ - void **wronc=(void **)wron; - PyObject *weakRefOnOwner=reinterpret_cast(wronc[0]); - PyObject *obj=PyWeakref_GetObject(weakRefOnOwner); - if(obj!=Py_None) - { - Py_XINCREF(obj); - PyArrayObject *objC=reinterpret_cast(obj); - objC->flags|=MED_NUMPY_OWNDATA; - Py_XDECREF(weakRefOnOwner); - Py_XDECREF(obj); - } - else - { - typedef void (*MyDeallocator)(void *,void *); - MyDeallocator deall=(MyDeallocator)wronc[1]; - deall(pt,NULL); - Py_XDECREF(weakRefOnOwner); - } - delete [] wronc; -} - -template -struct PyCallBackDataArraySt { - PyObject_HEAD - MCData *_pt_mc; -}; - -typedef struct PyCallBackDataArraySt PyCallBackDataArrayInt; -typedef struct PyCallBackDataArraySt PyCallBackDataArrayDouble; - -extern "C" -{ - static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; } - - static PyObject *callbackmcdataarrayint___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) - { - PyCallBackDataArrayInt *self = (PyCallBackDataArrayInt *) ( type->tp_alloc(type, 0) ); - return (PyObject *)self; - } - - static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) - { - PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) ); - return (PyObject *)self; - } - - static void callbackmcdataarray_dealloc(PyObject *self) - { - Py_TYPE(self)->tp_free(self); - } - - // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed. - // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients. - static PyObject *callbackmcdataarrayint_call(PyCallBackDataArrayInt *self, PyObject *args, PyObject *kw) - { - if(self->_pt_mc) - { - ParaMEDMEM::MemArray& mma=self->_pt_mc->accessToMemArray(); - mma.destroy(); - } - Py_XINCREF(Py_None); - return Py_None; - } - - // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed. - // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients. - static PyObject *callbackmcdataarraydouble_call(PyCallBackDataArrayDouble *self, PyObject *args, PyObject *kw) - { - if(self->_pt_mc) - { - ParaMEDMEM::MemArray& mma=self->_pt_mc->accessToMemArray(); - mma.destroy(); - } - Py_XINCREF(Py_None); - return Py_None; - } -} - -PyTypeObject PyCallBackDataArrayInt_RefType = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "callbackmcdataarrayint", - sizeof(PyCallBackDataArrayInt), - 0, - callbackmcdataarray_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)callbackmcdataarrayint_call, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - callbackmcdataarray___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - callbackmcdataarrayint___new__, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ -}; - -PyTypeObject PyCallBackDataArrayDouble_RefType = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "callbackmcdataarraydouble", - sizeof(PyCallBackDataArrayDouble), - 0, - callbackmcdataarray_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)callbackmcdataarraydouble_call, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - callbackmcdataarray___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - callbackmcdataarraydouble___new__, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ -}; - -// this is the second type of specific deallocator, only valid for the constructor of DataArrays taking numpy array -// in input when an another DataArray is already client of this. -template -void numarrdeal2(void *pt, void *obj) -{ - typedef struct PyCallBackDataArraySt PyCallBackDataArray; - void **obj1=(void **)obj; - PyCallBackDataArray *cbdaic=reinterpret_cast(obj1[0]); - PyObject *weakRefOnOwner=reinterpret_cast(obj1[1]); - cbdaic->_pt_mc=0; - Py_XDECREF(weakRefOnOwner); - Py_XDECREF(cbdaic); - delete [] obj1; -} - -template -MCData *BuildNewInstance(PyObject *elt0, int npyObjectType, PyTypeObject *pytype, const char *msg) -{ - int ndim=PyArray_NDIM(elt0); - if(ndim!=1 && ndim!=2) - throw INTERP_KERNEL::Exception("Input numpy array should have dimension equal to 1 or 2 !"); - if(PyArray_DESCR(elt0)->type_num != npyObjectType) - { - std::ostringstream oss; oss << "Input numpy array has not the type " << msg << "!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - npy_intp sz0=PyArray_DIM(elt0,0); - npy_intp sz1=ndim==2?PyArray_DIM(elt0,1):1; - // - int itemSize=PyArray_ITEMSIZE(elt0); - if(itemSize!=sizeof(T)) - { - std::ostringstream oss; oss << "Input numpy array has not itemSize set to " << sizeof(T) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(itemSize*sz1!=PyArray_STRIDE(elt0,0)) - throw INTERP_KERNEL::Exception("Input numpy array has stride that mismatches the item size ! Data are not packed in the right way for DataArrays !"); - if(ndim==2) - if(itemSize!=PyArray_STRIDE(elt0,1)) - throw INTERP_KERNEL::Exception("Input numpy array has stride that mismatches the item size ! Data are not packed in the right way for DataArrays for component #1 !"); - const char *data=PyArray_BYTES(elt0); - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=MCData::New(); - if(PyArray_ISBEHAVED(elt0))//aligned and writeable and in machine byte-order - { - PyArrayObject *elt0C=reinterpret_cast(elt0); - PyArrayObject *eltOwning=(PyArray_FLAGS(elt0C) & MED_NUMPY_OWNDATA)?elt0C:NULL; - int mask=MED_NUMPY_OWNDATA; mask=~mask; - elt0C->flags&=mask; - PyObject *deepestObj=elt0; - PyObject *base=elt0C->base; - if(base) deepestObj=base; - bool isSpetialCase(false); - while(base) - { - if(PyArray_Check(base)) - { - PyArrayObject *baseC=reinterpret_cast(base); - eltOwning=(PyArray_FLAGS(baseC) & MED_NUMPY_OWNDATA)?baseC:eltOwning; - baseC->flags&=mask; - base=baseC->base; - if(base) deepestObj=base; - } - else - { - isSpetialCase=true; - break; - } - } - if(isSpetialCase) - {// this case is present for numpy arrayint coming from load of pickelized string. The owner of elt0 is not an array -> A copy is requested. - std::size_t nbOfElems(sz0*sz1); - T *dataCpy=(T*)malloc(sizeof(T)*nbOfElems); - std::copy(reinterpret_cast(data),reinterpret_cast(data)+nbOfElems,dataCpy); - ret->useArray(dataCpy,true,ParaMEDMEM::C_DEALLOC,sz0,sz1); - return ret.retn(); - } - typename ParaMEDMEM::MemArray& mma=ret->accessToMemArray(); - if(eltOwning==NULL) - { - PyCallBackDataArraySt *cb=PyObject_GC_New(PyCallBackDataArraySt,pytype); - cb->_pt_mc=ret; - ret->useArray(reinterpret_cast(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); - PyObject *ref=PyWeakref_NewRef(deepestObj,(PyObject *)cb); - void **objs=new void *[2]; objs[0]=cb; objs[1]=ref; - mma.setParameterForDeallocator(objs); - mma.setSpecificDeallocator(numarrdeal2); - //"Impossible to share this numpy array chunk of data, because already shared by an another non numpy array object (maybe an another DataArrayInt instance) ! Release it, or perform a copy on the input array !"); - } - else - { - ret->useArray(reinterpret_cast(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); - PyObject *ref=PyWeakref_NewRef(reinterpret_cast(eltOwning),NULL); - typename ParaMEDMEM::MemArray::Deallocator tmp(ParaMEDMEM::MemArray::CDeallocator); - void **tmp2 = reinterpret_cast(&tmp); // MSVC2010 does not support constructor() - void **objs=new void *[2]; objs[0]=ref; objs[1]=*tmp2; - mma.setParameterForDeallocator(objs); - mma.setSpecificDeallocator(numarrdeal); - } - } - else if(PyArray_ISBEHAVED_RO(elt0)) - ret->useArray(reinterpret_cast(data),false,ParaMEDMEM::CPP_DEALLOC,sz0,sz1); - return ret.retn(); -} - - -int NumpyArrSetBaseObjectExt(PyArrayObject *arr, PyObject *obj) -{ - if (obj == NULL) { - PyErr_SetString(PyExc_ValueError, - "Cannot set the NumPy array 'base' " - "dependency to NULL after initialization"); - return -1; - } - /* - * Allow the base to be set only once. Once the object which - * owns the data is set, it doesn't make sense to change it. - */ - if (PyArray_BASE(arr) != NULL) { - Py_DECREF(obj); - PyErr_SetString(PyExc_ValueError, - "Cannot set the NumPy array 'base' " - "dependency more than once"); - return -1; - } - - /* - * Don't allow infinite chains of views, always set the base - * to the first owner of the data. - * That is, either the first object which isn't an array, - * or the first object which owns its own data. - */ - - while (PyArray_Check(obj) && (PyObject *)arr != obj) { - PyArrayObject *obj_arr = (PyArrayObject *)obj; - PyObject *tmp; - - - /* If this array owns its own data, stop collapsing */ - if (PyArray_CHKFLAGS(obj_arr, MED_NUMPY_OWNDATA )) { - break; - } - - tmp = PyArray_BASE(obj_arr); - /* If there's no base, stop collapsing */ - if (tmp == NULL) { - break; - } - /* Stop the collapse new base when the would not be of the same - * type (i.e. different subclass). - */ - if (Py_TYPE(tmp) != Py_TYPE(arr)) { - break; - } - - - Py_INCREF(tmp); - Py_DECREF(obj); - obj = tmp; - } - - /* Disallow circular references */ - if ((PyObject *)arr == obj) { - Py_DECREF(obj); - PyErr_SetString(PyExc_ValueError, - "Cannot create a circular NumPy array 'base' dependency"); - return -1; - } - - arr->base = obj; - - return 0; -} - -template -PyObject *ToNumPyArrayUnderground(MCData *self, int npyObjectType, const char *MCDataStr, int nbTuples, int nbComp) -{ - if(!self->isAllocated()) - { - std::ostringstream oss; oss << MCDataStr << "::toNumPyArray : this is not allocated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ParaMEDMEM::MemArray& mem=self->accessToMemArray(); - if(nbComp==0) - { - std::ostringstream oss; oss << MCDataStr << "::toNumPyArray : number of components of this is 0 ! Should be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbDims=nbComp==1?1:2; - npy_intp dim[2]; - dim[0]=(npy_intp)nbTuples; dim[1]=nbComp; - const T *bg=self->getConstPointer(); - PyObject *ret(PyArray_SimpleNewFromData(nbDims,dim,npyObjectType,const_cast(bg))); - if(mem.isDeallocatorCalled()) - { - if(mem.getDeallocator()!=numarrdeal) - {// case for the first call of toNumPyArray - PyObject *ref(PyWeakref_NewRef(ret,NULL)); - typename ParaMEDMEM::MemArray::Deallocator tmp(mem.getDeallocator()); - void **tmp2 = reinterpret_cast(&tmp); // MSVC2010 does not support constructor() - void **objs=new void *[2]; objs[0]=reinterpret_cast(ref); objs[1]=*tmp2; - mem.setParameterForDeallocator(objs); - mem.setSpecificDeallocator(numarrdeal); - return ret; - } - else - {// case for the second and other call of toNumPyArray - void **objs=(void **)mem.getParameterForDeallocator(); - PyObject *weakRefOnOwner=(PyObject *)objs[0]; - PyObject *obj=PyWeakref_GetObject(weakRefOnOwner); - if(obj!=Py_None) - {//the previous numArray exists let numpy deals the numpy array each other by declaring the still alive instance as base - Py_XINCREF(obj); - NumpyArrSetBaseObjectExt((PyArrayObject*)ret,obj); - } - else - {//the previous numArray no more exists -> declare the newly created numpy array as the first one. - Py_XDECREF(weakRefOnOwner); - PyObject *ref=PyWeakref_NewRef(ret,NULL); - objs[0]=ref; - } - } - } - return ret; -} - -template -PyObject *ToNumPyArray(MCData *self, int npyObjectType, const char *MCDataStr) -{ - return ToNumPyArrayUnderground(self,npyObjectType,MCDataStr,self->getNumberOfTuples(),self->getNumberOfComponents()); -} - -SWIGINTERN PyObject *ParaMEDMEM_DataArrayInt_toNumPyArray(ParaMEDMEM::DataArrayInt *self); -SWIGINTERN PyObject *ParaMEDMEM_DataArrayDouble_toNumPyArray(ParaMEDMEM::DataArrayDouble *self); - -PyObject *ToCSRMatrix(const std::vector >& m, int nbCols) throw(INTERP_KERNEL::Exception) -{ - int nbRows((int)m.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr indPtr(ParaMEDMEM::DataArrayInt::New()),indices(ParaMEDMEM::DataArrayInt::New()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr data(ParaMEDMEM::DataArrayDouble::New()); - indPtr->alloc(nbRows+1,1); - int *intPtr_ptr(indPtr->getPointer()); intPtr_ptr[0]=0; intPtr_ptr++; - int sz2(0); - for(std::vector >::const_iterator it0=m.begin();it0!=m.end();it0++,intPtr_ptr++) - { - sz2+=(int)(*it0).size(); - *intPtr_ptr=sz2; - } - indices->alloc(sz2,1); data->alloc(sz2,1); - int *indices_ptr(indices->getPointer()); - double *data_ptr(data->getPointer()); - for(std::vector >::const_iterator it0=m.begin();it0!=m.end();it0++) - for(std::map::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++,indices_ptr++,data_ptr++) - { - *indices_ptr=(*it1).first; - *data_ptr=(*it1).second; - } - PyObject *a(ParaMEDMEM_DataArrayDouble_toNumPyArray(data)),*b(ParaMEDMEM_DataArrayInt_toNumPyArray(indices)),*c(ParaMEDMEM_DataArrayInt_toNumPyArray(indPtr)); - // - PyObject *args(PyTuple_New(1)),*args0(PyTuple_New(3)),*kw(PyDict_New()),*kw1(PyTuple_New(2)); - PyTuple_SetItem(args0,0,a); PyTuple_SetItem(args0,1,b); PyTuple_SetItem(args0,2,c); PyTuple_SetItem(args,0,args0); - PyTuple_SetItem(kw1,0,PyInt_FromLong(nbRows)); PyTuple_SetItem(kw1,1,PyInt_FromLong(nbCols)); - PyObject *tmp1(PyString_FromString("shape")); - PyDict_SetItem(kw,tmp1,kw1); Py_DECREF(tmp1); Py_DECREF(kw1); - PyObject* pdict=PyDict_New(); - PyDict_SetItemString(pdict, "__builtins__", PyEval_GetBuiltins()); - PyObject *tmp(PyRun_String("from scipy.sparse import csr_matrix", Py_single_input, pdict, pdict)); - if(!tmp) - throw INTERP_KERNEL::Exception("Problem during loading csr_matrix in scipy.sparse ! Is Scipy module available in present ?"); - PyObject *csrMatrixCls=PyDict_GetItemString(pdict,"csr_matrix"); - if(!csrMatrixCls) - throw INTERP_KERNEL::Exception("csr_matrix not found in scipy.sparse ! Is Scipy module available in present ?"); - PyObject *ret(PyObject_Call(csrMatrixCls,args,kw)); - Py_DECREF(pdict); Py_XDECREF(tmp); Py_DECREF(args); Py_DECREF(kw); - return ret; -} - -#endif - -static PyObject *convertDataArrayChar(ParaMEDMEM::DataArrayChar *dac, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!dac) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of DataArrayChar on downcast !"); - return ret; -} - -static PyObject *convertDataArray(ParaMEDMEM::DataArray *dac, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!dac) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of DataArray on downcast !"); - return ret; -} - -static PyObject *convertIntArrToPyList(const int *ptr, int size) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=PyList_New(size); - for(int i=0;i& v) throw(INTERP_KERNEL::Exception) -{ - int size=v.size(); - PyObject *ret=PyList_New(size); - for(int i=0;i& v) throw(INTERP_KERNEL::Exception) -{ - int size=v.size(); - PyObject *ret=PyList_New(size); - std::set::const_iterator it=v.begin(); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=PyList_New(arr.size()); - for(std::size_t i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="list must contain tuples of 2 integers only or tuple must contain tuples of 2 integers only !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - arr.resize(size); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorPairStringInt : list must contain tuples of 2 integers only or tuple must contain tuples of 1 string and 1 integer only !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - arr.resize(size); - for(int i=0;i& arr) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - arr.resize(size); - for(int i=0;i& arr) throw(INTERP_KERNEL::Exception) -{ - if(recurseLev<0) - throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : invalid list of integers level of recursion !"); - arr.clear(); - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - for(int i=0;i arr2; - convertPyToNewIntArr4(o,recurseLev-1,nbOfSubPart,arr2); - if(nbOfSubPart>=1 && nbOfSubPart!=(int)arr2.size()) - { - std::ostringstream oss; oss << "convertPyToNewIntArr4 : input list at lev " << recurseLev << " invalid nb of subpart elts expected " << nbOfSubPart << " having " << arr2.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - arr.insert(arr.end(),arr2.begin(),arr2.end()); - } - } - } - else if(PyTuple_Check(pyLi)) - { - int size=PyTuple_Size(pyLi); - for(int i=0;i arr2; - convertPyToNewIntArr4(o,recurseLev-1,nbOfSubPart,arr2); - if(nbOfSubPart>=1 && nbOfSubPart!=(int)arr2.size()) - { - std::ostringstream oss; oss << "convertPyToNewIntArr4 : input list at lev " << recurseLev << " invalid nb of subpart elts expected " << nbOfSubPart << " having " << arr2.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - arr.insert(arr.end(),arr2.begin(),arr2.end()); - } - } - } - else - throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : not a list nor a tuple recursively !"); -} - -static void checkFillArrayWithPyList(int size1, int size2, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) -{ - if(nbOfTuples==-1) - { - if(nbOfComp==-1) { nbOfTuples=size1; nbOfComp=size2; } - else { if(nbOfComp==size2) { nbOfTuples=size1; } else - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; - oss << " whereas nb of components expected is " << nbOfComp << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } } - } - else - { - if(nbOfComp!=-1) - { - if((nbOfTuples!=size1 || nbOfComp!=size2)) - { - if(size2!=1 || size1!=nbOfComp*nbOfTuples) - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; - oss << " whereas nb of tuples expected is " << nbOfTuples << " and number of components expected is " << nbOfComp << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - if(nbOfTuples==size1) - nbOfComp=size2; - else - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; - oss << " whereas nb of tuples expected is " << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -static void fillArrayWithPyListInt3(PyObject *pyLi, int& nbOfElt, std::vector& ret) -{ - static const char MSG[]="fillArrayWithPyListInt3 : It appears that the input list or tuple is composed by elts having different sizes !"; - if(PyInt_Check(pyLi)) - { - long val=PyInt_AS_LONG(pyLi); - if(nbOfElt==-1) - nbOfElt=1; - else - if(nbOfElt!=1) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(val); - } - else if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - int tmp=0; - for(int i=0;i fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) -{ - std::vector ret; - int size1=-1,size2=-1; - if(PyList_Check(pyLi)) - { - size1=PyList_Size(pyLi); - for(int i=0;i& vec) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - vec.resize(sz); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorOfVectorOfString : expecting list of list of strings !"; - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - arr.resize(sz); - for(int i=0;i& vec) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - vec.resize(sz); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorOfVectorOfInt : expecting list of list of strings !"; - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - arr.resize(sz); - for(int i=0;i > >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorPairStringVecString : expecting list of tuples containing each exactly 2 items : one string and one vector of string !"; - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - arr.resize(sz); - for(int i=0;i > item; - PyObject *o_0=PyTuple_GetItem(o,0); - if(!PyString_Check(o_0)) - throw INTERP_KERNEL::Exception(msg); - item.first=PyString_AsString(o_0); - PyObject *o_1=PyTuple_GetItem(o,1); - if(!fillStringVector(o_1,item.second)) - throw INTERP_KERNEL::Exception(msg); - arr[i]=item; - } - else - throw INTERP_KERNEL::Exception(msg); - } - } - else if(PyTuple_Check(pyLi)) - { - Py_ssize_t sz=PyTuple_Size(pyLi); - arr.resize(sz); - for(int i=0;i > item; - PyObject *o_0=PyTuple_GetItem(o,0); - if(!PyString_Check(o_0)) - throw INTERP_KERNEL::Exception(msg); - item.first=PyString_AsString(o_0); - PyObject *o_1=PyTuple_GetItem(o,1); - if(!fillStringVector(o_1,item.second)) - throw INTERP_KERNEL::Exception(msg); - arr[i]=item; - } - else - throw INTERP_KERNEL::Exception(msg); - } - } - else - throw INTERP_KERNEL::Exception(msg); -} - -static PyObject *convertDblArrToPyList(const double *ptr, int size) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=PyList_New(size); - for(int i=0;i& v) throw(INTERP_KERNEL::Exception) -{ - int size=v.size(); - PyObject *ret=PyList_New(size); - for(int i=0;i tmp=new char[nbOfComp+1]; tmp[nbOfComp]='\0'; - for(int i=0;i& ret) -{ - static const char MSG[]="fillArrayWithPyListDbl3 : It appears that the input list or tuple is composed by elts having different sizes !"; - if(PyFloat_Check(pyLi)) - { - if(nbOfElt==-1) - nbOfElt=1; - else - if(nbOfElt!=1) - throw INTERP_KERNEL::Exception(MSG); - double val=PyFloat_AS_DOUBLE(pyLi); - ret.push_back(val); - } - else if(PyInt_Check(pyLi)) - { - long val0=PyInt_AS_LONG(pyLi); - double val=val0; - if(nbOfElt==-1) - nbOfElt=1; - else - if(nbOfElt!=1) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(val); - } - else if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - int tmp=0; - for(int i=0;i fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) -{ - std::vector ret; - int size1=-1,size2=-1; - if(PyList_Check(pyLi)) - { - size1=PyList_Size(pyLi); - for(int i=0;i(pyLi,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh") -template -static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector& ret) -{ - void *argp=0; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i(argp); - ret[i]=arg; - } - } - else if(PyTuple_Check(pyLi)) - { - int size=PyTuple_Size(pyLi); - ret.resize(size); - for(int i=0;i(argp); - ret[i]=arg; - } - } - else if(SWIG_IsOK(SWIG_ConvertPtr(pyLi,&argp,ty,0|0))) - { - ret.resize(1); - T arg=reinterpret_cast< T >(argp); - ret[0]=arg; - } - else - throw INTERP_KERNEL::Exception("convertFromPyObjVectorOfObj : not a list nor a tuple"); -} - -/*! - * if python int -> cpp int sw=1 - * if python list[int] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayInt -> cpp DataArrayInt sw=3 - * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp1(PyObject *value, int& sw, int& iTyypp, std::vector& stdvecTyypp, ParaMEDMEM::DataArrayInt *& daIntTyypp, ParaMEDMEM::DataArrayIntTuple *&daIntTuple) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - sw=3; - return; - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(SWIG_IsOK(status)) - { - daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - sw=4; - return ; - } - throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple"); -} - -/*! - * if python double -> cpp double sw=1 - * if python int -> cpp double sw=1 - * if python list[double] -> cpp vector sw=2 - * if python list[int] -> cpp vector sw=2 - * if python tuple[double] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayDouble -> cpp DataArrayDouble sw=3 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp4(PyObject *value, int& sw, double& iTyypp, std::vector& stdvecTyypp, ParaMEDMEM::DataArrayDouble *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - iTyypp=PyFloat_AS_DOUBLE(value); - sw=1; - return; - } - if(PyInt_Check(value)) - { - iTyypp=(double)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - sw=3; -} - -/*! - * if python double -> cpp double sw=1 - * if python int -> cpp double sw=1 - * if python list[double] -> cpp vector sw=2 - * if python list[int] -> cpp vector sw=2 - * if python tuple[double] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp44(PyObject *value, int& sw, double& iTyypp, std::vector& stdvecTyypp, ParaMEDMEM::DataArrayDoubleTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - iTyypp=PyFloat_AS_DOUBLE(value); - sw=1; - return; - } - if(PyInt_Check(value)) - { - iTyypp=(double)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - sw=3; -} - -/*! - * if python int -> cpp int sw=1 - * if python list[int] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python slicp -> cpp pair sw=3 (begin,end,step) - * if python DataArrayInt -> cpp DataArrayInt sw=4 . The returned pointer cannot be the null pointer ! If null an exception is thrown. - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - const char *msg="5 types accepted : integer, tuple of integer, list of integer, slice, DataArrayInt, DataArrayIntTuple"; - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(value); - GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); - p.first=strt; - p.second.first=stp; - p.second.second=step; - sw=3; - return ; - } - void *argp; - int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - if(SWIG_IsOK(status)) - { - daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - if(!daIntTyypp) - { - std::ostringstream oss; oss << msg << " Instance in null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - sw=4; - return ; - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(SWIG_IsOK(status)) - { - ParaMEDMEM::DataArrayIntTuple *tmp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - if(!tmp) - { - std::ostringstream oss; oss << msg << " Instance in null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - stdvecTyypp.resize(tmp->getNumberOfCompo()); - std::copy(tmp->getConstPointer(),tmp->getConstPointer()+tmp->getNumberOfCompo(),stdvecTyypp.begin()); - sw=2; - return ; - } - throw INTERP_KERNEL::Exception(msg); -} - -/*! - * Idem than convertObjToPossibleCpp2 - */ -static void convertObjToPossibleCpp2WithNegIntInterp(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - convertObjToPossibleCpp2(value,nbelem,sw,iTyypp,stdvecTyypp,p,daIntTyypp); - if(sw==1) - { - iTyypp=InterpreteNegativeInt(iTyypp,nbelem); - } -} - -/*! - * if python int -> cpp int sw=1 - * if python tuple[int] -> cpp vector sw=2 - * if python list[int] -> cpp vector sw=2 - * if python slice -> cpp pair sw=3 - * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 . WARNING The returned pointer can be the null pointer ! - */ -static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayIntTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(value); - GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); - p.first=strt; - p.second.first=stp; - p.second.second=step; - sw=3; - return ; - } - void *argp; - int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception("4 types accepted : integer, tuple of integer, list of integer, slice, DataArrayIntTuple"); - daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - sw=4; -} - -/*! - * if python string with size one -> cpp char sw=1 - * if python string with size different from one -> cpp string sw=2 - * if python tuple[string] or list[string] -> vector sw=3 - * if python not null pointer of DataArrayChar -> cpp DataArrayChar sw=4 - * switch between (int,string,vector,DataArrayChar) - */ -static void convertObjToPossibleCpp6(PyObject *value, int& sw, char& cTyp, std::string& sType, std::vector& vsType, ParaMEDMEM::DataArrayChar *& dacType) throw(INTERP_KERNEL::Exception) -{ - const char *msg="4 types accepted : string, list or tuple of strings having same size, not null DataArrayChar instance."; - sw=-1; - if(PyString_Check(value)) - { - const char *pt=PyString_AsString(value); - Py_ssize_t sz=PyString_Size(value); - if(sz==1) - { - cTyp=pt[0]; - sw=1; - return; - } - else - { - sType=pt; - sw=2; - return; - } - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - vsType.resize(size); - for(int i=0;i(argp); - if(!dacType) - { - std::ostringstream oss; oss << msg << " Instance in null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - sw=4; - return ; - } - throw INTERP_KERNEL::Exception(msg); -} - -/*! - * if value int -> cpp it sw=1 - * if value list[int] -> vt sw=2 - * if value tuple[int] -> vt sw=2 - * if value slice -> pt sw=3 - * if value DataArrayInt -> dt sw=4 - * if value tuple [int,int] -> cpp it,ip sw=5 - * if value tuple [list[int],int] -> cpp vt,ip sw=6 - * if value tuple [tuple[int],int] -> cpp vt,ip sw=6 - * if value tuple [slice,int] -> cpp pt,ip sw=7 - * if value tuple [DaI,int] -> cpp dt,ip sw=8 - * if value tuple [int,list[int]] -> cpp it,vc sw=9 - * if value tuple [list[int],list[int]] -> cpp vt,vc sw=10 - * if value tuple [tuple[int],list[int]] -> cpp vt,vc sw=10 - * if value tuple [slice,list[int]] -> cpp pt,vc sw=11 - * if value tuple [DaI,list[int]] -> cpp dt,vc sw=12 - * if value tuple [int,tuple[int]] -> cpp it,vc sw=9 - * if value tuple [list[int],tuple[int]] -> cpp vt,vc sw=10 - * if value tuple [tuple[int],tuple[int]] -> cpp vt,vc sw=10 - * if value tuple [slice,tuple[int]] -> cpp pt,vc sw=11 - * if value tuple [DaI,tuple[int]] -> cpp dt,vc sw=12 - * if value tuple [int,slice] -> cpp it,pc sw=13 - * if value tuple [list[int],slice] -> cpp vt,pc sw=14 - * if value tuple [tuple[int],slice] -> cpp vt,pc sw=14 - * if value tuple [slice,slice] -> cpp pt,pc sw=15 - * if value tuple [DaI,slice] -> cpp dt,pc sw=16 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp3(PyObject *value, int nbTuple, int nbCompo, int& sw, int& it, int& ic, std::vector& vt, std::vector& vc, - std::pair >& pt, std::pair >& pc, - ParaMEDMEM::DataArrayInt *&dt, ParaMEDMEM::DataArrayInt *&dc) throw(INTERP_KERNEL::Exception) -{ - if(!PyTuple_Check(value)) - { - convertObjToPossibleCpp2WithNegIntInterp(value,nbTuple,sw,it,vt,pt,dt); - return ; - } - else - { - int sz=PyTuple_Size(value); - if(sz!=2) - throw INTERP_KERNEL::Exception("Unexpected nb of slice element : 1 or 2 expected !\n1st is for tuple selection, 2nd for component selection !"); - PyObject *ob0=PyTuple_GetItem(value,0); - int sw1,sw2; - convertObjToPossibleCpp2WithNegIntInterp(ob0,nbTuple,sw1,it,vt,pt,dt); - PyObject *ob1=PyTuple_GetItem(value,1); - convertObjToPossibleCpp2WithNegIntInterp(ob1,nbCompo,sw2,ic,vc,pc,dc); - sw=4*sw2+sw1; - } -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static void convertObjToPossibleCpp5(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector& f) -{ - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - return; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - f.resize(size); - for(int i=0;i(argp); - sw=2; - return ; - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - return ; - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static const double *convertObjToPossibleCpp5_Safe(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector& f, - const char *msg, int nbTuplesExpected, int nbCompExpected, bool throwIfNullPt) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - if(nbTuplesExpected*nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension one (single PyFloat) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return &val; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - if(nbTuplesExpected*nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension one (single PyInt) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return &val; - } - if(PyTuple_Check(value) || PyList_Check(value)) - { - try - { - int tmp1=nbTuplesExpected,tmp2=nbCompExpected; - std::vector ret=fillArrayWithPyListDbl2(value,tmp1,tmp2); - sw=4; - f=ret; - return &f[0]; - } - catch(INTERP_KERNEL::Exception& exc) { throw exc; } - } - void *argp; - int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); - if(SWIG_IsOK(status)) - { - d=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); - sw=2; - if(d) - { - if(d->getNumberOfTuples()==nbTuplesExpected) - { - if(d->getNumberOfComponents()==nbCompExpected) - { - return d->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input has " << d->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << msg << " input DataArrayDouble should have a number of tuples equal to " << nbTuplesExpected << " and there are " << d->getNumberOfTuples() << " tuples !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - return 0; - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - if(e->getNumberOfCompo()==nbCompExpected) - { - if(nbTuplesExpected==1) - return e->getConstPointer(); - else - { - std::ostringstream oss; oss << msg << "nb of tuples expected to be " << nbTuplesExpected << " , and input DataArrayDoubleTuple has always one tuple by contruction !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static const double *convertObjToPossibleCpp5_Safe2(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector& f, - const char *msg, int nbCompExpected, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - if(nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbCompExpected << " , and your data in input has dimension one (single PyFloat) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - nbTuples=1; - return &val; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - if(nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbCompExpected << " , and your data in input has dimension one (single PyInt) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - nbTuples=1; - return &val; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - f.resize(size); - for(int i=0;i(argp); - sw=2; - if(d) - { - if(d->getNumberOfComponents()==nbCompExpected) - { - nbTuples=d->getNumberOfTuples(); - return d->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be a multiple of " << nbCompExpected << " , and input has " << d->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - if(e) - { - if(e->getNumberOfCompo()==nbCompExpected) - { - nbTuples=1; - return e->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static const double *convertObjToPossibleCpp5_SingleCompo(PyObject *value, int& sw, double& val, std::vector& f, - const char *msg, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) -{ - ParaMEDMEM::DataArrayDouble *d=0; - ParaMEDMEM::DataArrayDoubleTuple *e=0; - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - nbTuples=1; - return &val; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - nbTuples=1; - return &val; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - f.resize(size); - for(int i=0;i(argp); - sw=2; - if(d) - { - if(d->getNumberOfComponents()==1) - { - nbTuples=d->getNumberOfTuples(); - return d->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be one, and input has " << d->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - if(e) - { - nbTuples=e->getNumberOfCompo(); - return e->getConstPointer(); - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if python int -> cpp int sw=1 - * if python list[int] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayInt -> cpp DataArrayInt sw=3 - * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 - * - * switch between (int,vector,DataArrayInt) - */ -static const int *convertObjToPossibleCpp1_Safe(PyObject *value, int& sw, int& sz, int& iTyypp, std::vector& stdvecTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; sz=1; - return &iTyypp; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - if(daIntTyypp) - { - sw=3; sz=daIntTyypp->getNbOfElems(); - return daIntTyypp->begin(); - } - else - { - sz=0; - return 0; - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(SWIG_IsOK(status)) - { - ParaMEDMEM::DataArrayIntTuple *daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - sw=4; sz=daIntTuple->getNumberOfCompo(); - return daIntTuple->getConstPointer(); - } - throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple"); -} - -static ParaMEDMEM::DataArray *CheckAndRetrieveDataArrayInstance(PyObject *obj, const char *msg) -{ - void *aBasePtrVS=0; - int status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArray,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,0|0); - std::ostringstream oss; oss << msg << " ! Accepted instances are DataArrayDouble, DataArrayInt, DataArrayAsciiChar, DataArrayByte !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } - return reinterpret_cast< ParaMEDMEM::DataArray * >(aBasePtrVS); -} diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/medtool/src/MEDCoupling_Swig/MEDCouplingDataForTest.py deleted file mode 100644 index f88aad244..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingDataForTest.py +++ /dev/null @@ -1,756 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDCoupling import * - -class MEDCouplingDataForTest: - def build2DTargetMesh_1(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DSourceMesh_1(cls): - sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] - sourceConn=[0,3,1,0,2,3] - sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2); - sourceMesh.allocateCells(2); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); - sourceMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(sourceCoords,4,2); - sourceMesh.setCoords(myCoords); - return sourceMesh; - - def build3DTargetMesh_1(cls): - targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. ]; - targetConn=[0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25]; - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(3); - targetMesh.allocateCells(12); - for i in xrange(8): - targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*i+8]); - pass - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,27,3); - targetMesh.setCoords(myCoords); - return targetMesh - - def build3DSourceMesh_1(self): - sourceCoords=[ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, - 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0] - sourceConn=[8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2] - sourceMesh=MEDCouplingUMesh.New(); - sourceMesh.setMeshDimension(3); - sourceMesh.allocateCells(12); - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[0:4]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[4:8]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[8:12]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[12:16]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[16:20]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[20:24]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[24:28]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[28:32]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[32:36]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[36:40]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[40:44]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[44:48]) - sourceMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(sourceCoords,9,3); - sourceMesh.setCoords(myCoords); - return sourceMesh; - - - def build3DSurfTargetMesh_1(self): - targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,3); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DExtrudedUMesh_1(self): - coords=[ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - - conn=[ - # 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - # 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - # 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - conn2=[7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3] - # - ret=MEDCouplingUMesh.New(); - ret.setMeshDimension(3); - ret.allocateCells(18); - # - ret.insertNextCell(NORM_HEXA8,8,conn[0:8]); - ret.insertNextCell(NORM_POLYHED,43,conn[8:51]); - ret.insertNextCell(NORM_HEXA8,8,conn[51:59]); - ret.insertNextCell(NORM_HEXA8,8,conn[59:67]); - ret.insertNextCell(NORM_POLYHED,43,conn[67:110]); - ret.insertNextCell(NORM_HEXA8,8,conn[110:118]); - # - ret.insertNextCell(NORM_HEXA8,8,conn[118:126]); - ret.insertNextCell(NORM_POLYHED,43,conn[126:169]); - ret.insertNextCell(NORM_HEXA8,8,conn[169:177]); - ret.insertNextCell(NORM_HEXA8,8,conn[177:185]); - ret.insertNextCell(NORM_POLYHED,43,conn[185:228]); - ret.insertNextCell(NORM_HEXA8,8,conn[228:236]); - # - ret.insertNextCell(NORM_HEXA8,8,conn[236:244]); - ret.insertNextCell(NORM_POLYHED,43,conn[244:287]); - ret.insertNextCell(NORM_HEXA8,8,conn[287:295]); - ret.insertNextCell(NORM_HEXA8,8,conn[295:303]); - ret.insertNextCell(NORM_POLYHED,43,conn[303:346]); - ret.insertNextCell(NORM_HEXA8,8,conn[346:354]); - # - ret.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,60,3); - ret.setCoords(myCoords); - # - mesh2D=MEDCouplingUMesh.New(); - mesh2D.setMeshDimension(2); - mesh2D.allocateCells(6); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[0:4]); - mesh2D.insertNextCell(NORM_POLYGON,6,conn2[4:10]); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[10:14]); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[14:18]); - mesh2D.insertNextCell(NORM_POLYGON,6,conn2[18:24]); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[24:28]); - mesh2D.finishInsertingCells(); - mesh2D.setCoords(myCoords); - return ret,mesh2D - - def buildCU1DMesh_U(self): - coords=[ 0.0, 0.3, 0.75, 1.0 ] - conn=[ 0,1, 1,2, 2,3 ] - mesh=MEDCouplingUMesh.New(); - mesh.setMeshDimension(1); - mesh.allocateCells(3); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]); - mesh.insertNextCell(NORM_SEG2,2,conn[2:4]); - mesh.insertNextCell(NORM_SEG2,2,conn[4:6]); - mesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,4,1); - mesh.setCoords(myCoords); - return mesh; - - def build2DTargetMeshMergeNode_1(self): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 ] - targetConn=[0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,18,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DTargetMeshMergeNode_1(self): - targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.] - targetConn=[0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(3); - targetMesh.allocateCells(12); - for i in xrange(8): - targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*(i+1)]); - pass - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,31,3); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DTargetMeshMerged_1(self): - targetCoords=[ - -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 - ] - targetConn=[ - 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, - 9,12,10,9,11,12 - ] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setName("merge"); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(10); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,13,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DTargetMesh_2(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 ] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(8); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[6:9]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[9:12]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[12:15]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[15:18]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build1DSourceMesh_2(cls): - ret=MEDCouplingUMesh.New("1DSourceMesh",1); - ret.allocateCells(4); - conn=[0,1,2,3,1,2,3,4] - for i in xrange(4): - ret.insertNextCell(NORM_SEG2,2,conn[2*i:2*i+2]); - pass - ret.finishInsertingCells(); - myCoords=DataArrayDouble.New([0.3,0.7,0.9,1.0,1.12],5,1); - ret.setCoords(myCoords); - return ret - - def build1DTargetMesh_3(cls): - ret=MEDCouplingUMesh.New("1DMesh_3",1); - ret.allocateCells(4); - conn=[0,1,2, 3,4, 6,5,7 ,9,8] - ret.insertNextCell(NORM_SEG3,3,conn[0:3]) - ret.insertNextCell(NORM_SEG2,2,conn[3:5]) - ret.insertNextCell(NORM_SEG3,3,conn[5:8]) - ret.insertNextCell(NORM_SEG2,2,conn[8:10]) - ret.finishInsertingCells(); - coords=[0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31] - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,10,1); - ret.setCoords(myCoords); - return ret; - - def build2DCurveTargetMesh_3(cls): - ret=MEDCouplingUMesh.New("2DCurveMesh_3",1); - ret.allocateCells(4); - conn=[0,1,2, 3,4, 6,5,7 ,9,8] - ret.insertNextCell(NORM_SEG3,3,conn[0:3]) - ret.insertNextCell(NORM_SEG2,2,conn[3:5]) - ret.insertNextCell(NORM_SEG3,3,conn[5:8]) - ret.insertNextCell(NORM_SEG2,2,conn[8:10]) - ret.finishInsertingCells(); - coords=[0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31] - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,10,2); - ret.setCoords(myCoords); - return ret; - - def build2DTargetMesh_3(cls): - ret=MEDCouplingUMesh.New("2DMesh_3",2); - ret.allocateCells(10); - conn=[0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6] - ret.insertNextCell(NORM_TRI3,3,conn[0:3]) - ret.insertNextCell(NORM_QUAD4,4,conn[3:7]) - ret.insertNextCell(NORM_POLYGON,5,conn[7:12]) - ret.insertNextCell(NORM_TRI6,6,conn[12:18]) - ret.insertNextCell(NORM_QUAD8,8,conn[18:26]) - ret.insertNextCell(NORM_TRI3,3,conn[26:29]) - ret.insertNextCell(NORM_QUAD4,4,conn[29:33]) - ret.insertNextCell(NORM_POLYGON,5,conn[33:38]) - ret.insertNextCell(NORM_TRI6,6,conn[38:44]) - ret.insertNextCell(NORM_QUAD8,8,conn[44:52]) - ret.finishInsertingCells(); - coords=[0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5] - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,11,2); - ret.setCoords(myCoords); - ret.checkCoherency(); - return ret; - - def build2DTargetMesh_4(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,10,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def buildMultiFields_1(cls): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.setName("m1"); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2.setName("m2"); - vals0=[-0.7,-1.,-2.,-3.,-4.]; - vals1=[0.,1.,2.,3.,4.,0.1,0.2,0.3,0.4]; - vals1_1=[170.,171.,172.,173.,174.,170.1,170.2,170.3,170.4]; - vals2=[5.,6.,7.,8.,9.]; - vals4=[15.,16.,17.,18.,19.]; - d0=DataArrayDouble.New(); - d0.setValues(vals0,5,1); - d1=DataArrayDouble.New(); - d1.setValues(vals1,9,1); - d1_1=DataArrayDouble.New(); - d1_1.setValues(vals1_1,9,1); - d2=DataArrayDouble.New(); - d2.setValues(vals2,5,1); - d4=DataArrayDouble.New(); - d4.setValues(vals4,5,1); - d0.setName("d0"); d1.setName("d1"); d1_1.setName("d1_1"); d2.setName("d2"); d4.setName("d4"); - d0.setInfoOnComponent(0,"c1"); - d1.setInfoOnComponent(0,"c6"); - d1_1.setInfoOnComponent(0,"c9"); - d2.setInfoOnComponent(0,"c5"); - d4.setInfoOnComponent(0,"c7"); - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f0.setMesh(m1); - f0.setArray(d0); - f0.setTime(0.2,5,6); - f0.setName("f0"); - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setMesh(m1); - f1.setArrays([d1,d1_1]); - f1.setStartTime(0.7,7,8); - f1.setEndTime(1.2,9,10); - f1.setName("f1"); - f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2.setMesh(m2); - f2.setArray(d2); - f2.setTime(1.2,11,12); - f2.setEndTime(1.5,13,14); - f2.setName("f2"); - f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f3.setMesh(m1); - f3.setArray(d2); - f3.setTime(1.7,15,16); - f3.setName("f3"); - f4=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f4.setMesh(m2); - f4.setArray(d4); - f4.setName("f4"); - ret=MEDCouplingMultiFields.New([f0,f1,f2,f3,f4]); - return ret; - - def buildMultiFields_2(cls): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.setName("m1"); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2.setName("m2"); - vals0=[-0.7,-1.,-2.,-3.,-4.]; - vals1=[0.,1.,2.,3.,4.]; - vals1_1=[170.,171.,172.,173.,174.]; - vals2=[5.,6.,7.,8.,9.]; - vals4=[15.,16.,17.,18.,19.]; - d0=DataArrayDouble.New(); - d0.setValues(vals0,5,1); - d1=DataArrayDouble.New(); - d1.setValues(vals1,5,1); - d1_1=DataArrayDouble.New(); - d1_1.setValues(vals1_1,5,1); - d2=DataArrayDouble.New(); - d2.setValues(vals2,5,1); - d4=DataArrayDouble.New(); - d4.setValues(vals4,5,1); - d0.setName("d0"); d1.setName("d1"); d1_1.setName("d1_1"); d2.setName("d2"); d4.setName("d4"); - d0.setInfoOnComponent(0,"c1"); - d1.setInfoOnComponent(0,"c6"); - d1_1.setInfoOnComponent(0,"c9"); - d2.setInfoOnComponent(0,"c5"); - d4.setInfoOnComponent(0,"c7"); - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f0.setMesh(m1); - f0.setArray(d0); - f0.setTime(0.2,5,6); - f0.setName("f0"); - f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f1.setMesh(m1); - f1.setArrays([d1,d1_1]); - f1.setStartTime(0.7,7,8); - f1.setEndTime(1.2,9,10); - f1.setName("f1"); - f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2.setMesh(m2); - f2.setArray(d2); - f2.setTime(1.2,11,12); - f2.setEndTime(1.5,13,14); - f2.setName("f2"); - f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f3.setMesh(m1); - f3.setArray(d2); - f3.setTime(1.7,15,16); - f3.setName("f3"); - f4=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f4.setMesh(m2); - f4.setArray(d4); - f4.setName("f4"); - return [f0,f1,f2,f3,f4] - - def build1DMultiTypes_1(self): - mesh=MEDCouplingUMesh.New("Multi1DMesh",1); - coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); - conn=[0,2, 0,2,1] - mesh.allocateCells(2); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) - mesh.insertNextCell(NORM_SEG3,3,conn[2:5]) - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def build2DMultiTypes_1(self): - mesh=MEDCouplingUMesh.New("Multi2DMesh",2); - coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); - conn=[3,4,5, 3,4,5,6,7,8, 0,9,10,11, 0,9,10,11,12,13,14,15] - mesh.allocateCells(4); - mesh.insertNextCell(NORM_TRI3,3,conn[0:3]) - mesh.insertNextCell(NORM_TRI6,6,conn[3:9]) - mesh.insertNextCell(NORM_QUAD4,4,conn[9:13]) - mesh.insertNextCell(NORM_QUAD8,8,conn[13:21]) - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def build3DMultiTypes_1(self): - mesh=MEDCouplingUMesh.New("Multi3DMesh",3); - coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); - conn=[0,16,17,18, - 0,16,17,18,19,20,21,22,23,24, - 0,11,10,9,25, - 0,11,10,9,25,15,14,13,12,26,27,28,29, - 0,30,31,32,33,34, - 0,30,31,32,33,34,35,36,37,38,39,40,41,42,43, - 0,9,10,11,44,45,46,47, - 0,9,10,11,44,45,46,47,12,13,14,15,48,49,50,51,52,53,54,55 ]; - mesh.allocateCells(8); - mesh.insertNextCell(NORM_TETRA4,4,conn[0:4]) - mesh.insertNextCell(NORM_TETRA10,10,conn[4:14]) - mesh.insertNextCell(NORM_PYRA5,5,conn[14:19]) - mesh.insertNextCell(NORM_PYRA13,13,conn[19:32]) - mesh.insertNextCell(NORM_PENTA6,6,conn[32:38]) - mesh.insertNextCell(NORM_PENTA15,15,conn[38:53]) - mesh.insertNextCell(NORM_HEXA8,8,conn[53:61]) - mesh.insertNextCell(NORM_HEXA20,20,conn[61:81]) - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def buildCoordsForMultiTypes_1(self): - coords=DataArrayDouble.New(); - data=[0.0,0.0,0.0, 0.5,0.5,0.5, 1.0,1.0,1.0, 1.0,1.0,0.0, 2.0,2.5,0.0, 6.0,1.5,0.0, 1.0,2.0,0.0, 4.5,2.5,0.0, 4.0,0.5,0.0, 0.0,4.0,0.0, 4.0,4.0,0.0, 4.0,0.0,0.0, 0.0,2.0,0.0, 2.0,4.0,0.0, 4.0,2.0,0.0, 2.0,0.0,0.0, 0.0,6.0,0.0, 3.0,3.0,0.0, 1.3,3.0,3.0, 0.0,3.0,0.0, 1.5,4.5,0.0, 1.5,1.5,0.0, 0.65,1.5,1.5, 0.65,4.5,1.5, 2.15,3.0,1.5, 2.0,2.0,2.0, 3.0,1.0,1.0, 3.0,3.0,1.0, 1.0,3.0,1.0, 1.0,1.0,1.0, 0.0,3.0,0.0, 2.0,0.0,0.0, 0.0,0.0,6.0, 0.0,3.0,6.0, 3.0,0.0,6.0, 0.0,1.5,0.0, 1.5,1.5,0.0, 1.5,0.0,0.0, 0.0,1.5,6.0, 1.5,1.5,6.0, 1.5,0.0,6.0, 0.0,0.0,3.0, 0.0,3.0,3.0, 3.0,0.0,3.0, 0.0,0.0,4.0, 0.0,4.0,4.0, 4.0,4.0,4.0, 4.0,0.0,4.0, 0.0,2.0,4.0, 2.0,4.0,4.0, 4.0,2.0,4.0, 2.0,0.0,4.0, 0.0,0.0,2.0, 0.0,4.0,2.0, 4.0,4.0,2.0, 4.0,0.0,2.0] - coords.setValues(data,56,3); - coords.setInfoOnComponent(0,"X (cm)"); - coords.setInfoOnComponent(1,"Y (cm)"); - coords.setInfoOnComponent(2,"Z (cm)"); - return coords - - def buildHexa8Mesh_1(self): - mesh=MEDCouplingUMesh.New("Hexa8Only",3); - coo=DataArrayDouble.New(); - coords=[0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0] - coo.setValues(coords,27,3); - conn=[3,12,13,4,0,9,10,1, - 4,13,14,5,1,10,11,2, - 6,15,16,7,3,12,13,4, - 7,16,17,8,4,13,14,5, - 12,21,22,13,9,18,19,10, - 13,22,23,14,10,19,20,11, - 15,24,25,16,12,21,22,13, - 16,25,26,17,13,22,23,14]; - mesh.allocateCells(8); - for i in xrange(8): - mesh.insertNextCell(NORM_HEXA8,8,conn[8*i:8*(i+1)]) - pass - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def buildPointe_1(self): - mesh=MEDCouplingUMesh.New("Pointe.med",3); - mesh2=MEDCouplingUMesh.New("Pointe.med",2); - coords=[0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 2.0, 1.0, -2.0, 0.0, 1.0, 0.0, -2.0, 1.0, 1.0, 1.0, 2.0, -1.0, 1.0, 2.0, -1.0, -1.0, 2.0, 1.0, -1.0, 2.0, 1.0, 1.0, 3.0, -1.0, 1.0, 3.0, -1.0, -1.0, 3.0, 1.0, -1.0, 3.0, 1.0, 1.0, 4.0, -1.0, 1.0, 4.0, -1.0, -1.0, 4.0, 1.0, -1.0, 4.0, 0.0, 0.0, 5.0] - conn=[0,1,2,5,0,1,3,2,0,1,4,3,0,1,5,4,1,6,3,2,1,7,4,3,1,8,5,4,1,9,2,5,1,6,2,9,1,7,3,6,1,8,4,7,1,9,5,8, 6,7,8,9,1,14,17,16,15,18, 10,11,12,13,6,7,8,9,14,15,16,17,10,11,12,13] - coo=DataArrayDouble.New(); - coo.setValues(coords,19,3); - mesh.setCoords(coo); - mesh2.setCoords(coo); - mesh.allocateCells(16); - for i in xrange(12): - mesh.insertNextCell(NORM_TETRA4,4,conn[4*i:4*i+4]) - pass - mesh.insertNextCell(NORM_PYRA5,5,conn[48:53]) - mesh.insertNextCell(NORM_PYRA5,5,conn[53:58]) - mesh.insertNextCell(NORM_HEXA8,8,conn[58:66]) - mesh.insertNextCell(NORM_HEXA8,8,conn[66:74]) - mesh.finishInsertingCells(); - #[1,34,29,23,41,32] - conn2=[0,5,1,14,18,17,8,7,4,9,5,2, 12,8,9,13,6,7,8,9] - mesh2.allocateCells(6); - for i in xrange(4): - mesh2.insertNextCell(NORM_TRI3,3,conn2[3*i:3*i+3]) - pass - mesh2.insertNextCell(NORM_QUAD4,4,conn2[12:16]) - mesh2.insertNextCell(NORM_QUAD4,4,conn2[16:20]) - mesh2.finishInsertingCells(); - return [mesh,mesh2] - - # 2D usecase1 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_1(self): - coo=DataArrayDouble([1.0,0.0,1.33333333333333,0.0,1.66666666666667,0.0,0.923879532511287,0.38268343236509006,1.23183937668172,0.510244576486786,1.53979922085214,0.6378057206084831,2.0,0.0,1.8477590650225701,0.7653668647301801,0.9428090415820631,0.9428090415820631,1.1785113019775801,1.1785113019775801,1.4142135623731,1.41421356237309,0.707106781186548,0.707106781186547,0.38268343236509006,0.923879532511287,0.510244576486786,1.23183937668172,0.6378057206084831,1.53979922085214,0.7653668647301801,1.8477590650225701,3.1550283219328204e-17,1.33333333333333,1.16009632455949e-17,1.66666666666667,-2.7620050344068196e-16,2.0,-1.3810025172034098e-16,1.0,-2.0,0.0,-1.53979922085214,0.6378057206084831,-1.66666666666667,0.0,-1.33333333333333,0.0,-0.923879532511287,0.38268343236509006,-1.8477590650225701,0.7653668647301801,-0.9428090415820631,0.9428090415820631,-1.23183937668172,0.510244576486786,-1.83333333333333,0.0,-1.6937791429373599,0.701586292669331,-1.5,0.0,-1.30771370720431,0.26012042935483803,-1.16666666666667,0.0,-1.0778594545965,0.44646400442593803,-1.38578268717091,0.9259503883660041,-1.38581929876693,0.574025148547635,-1.06066017177982,1.06066017177982,-0.8314696123025451,0.5555702330196021,-1.0,0.0,-1.1785113019775801,1.1785113019775801,-0.707106781186548,0.707106781186547,-1.63464213400538,0.325150536693547,-1.9615705608064598,0.390180644032256,-1.47117792060485,0.292635483024192,-0.9807852804032301,0.19509032201612803,-1.524360955888,1.0185454272026,-1.2963624321753402,1.2963624321753402,-1.10862614973673,0.740760310692803,-0.970047881019636,0.6481652718562021,-0.824957911384305,0.824957911384305,-1.4142135623731,1.41421356237309,-1.7981063474059198,0.357665590362902,-1.1442494938037702,0.227605375685483,-1.66293922460509,1.1111404660392,-1.24720441845382,0.833355349529403,-0.7653668647301801,1.8477590650225701,-0.6378057206084831,1.53979922085214,-0.510244576486786,1.23183937668172,-0.701586292669331,1.6937791429373599,-0.574025148547635,1.38581929876693,-0.44646400442593803,1.0778594545965,-0.38268343236509006,0.923879532511287,-0.9259503883660041,1.38578268717091,-0.740760310692803,1.10862614973673,-0.5555702330196021,0.8314696123025451,-0.325150536693547,1.63464213400538,-0.26012042935483803,1.30771370720431,-0.19509032201612803,0.9807852804032301,1.6805133673525298e-18,1.83333333333333,-2.4643915380595496e-16,1.5,-1.4799359654427099e-16,1.16666666666667,-1.1111404660392,1.66293922460509,-0.39018064403225705,1.9615705608064598],73,2) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) - m=MEDCouplingUMesh("MA1",2) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells() - conn=[[11,8,13],[11,13,12],[8,9,13],[9,14,13],[9,10,15],[9,15,14],[12,13,19],[13,16,19],[13,14,17],[13,17,16],[14,15,17],[15,18,17],[0,1,4,3],[1,2,5,4],[2,6,7,5],[3,4,8,11],[4,5,9,8],[5,7,10,9],[20,22,21,28,41,51],[21,25,20,29,42,51],[22,23,21,30,43,41],[23,27,21,31,35,43],[23,38,24,32,44,52],[24,27,23,33,31,52],[25,21,50,29,45,53],[21,39,50,34,46,45],[21,27,26,35,47,54],[26,39,21,36,34,54],[27,24,26,33,48,47],[24,40,26,37,49,48],[50,39,56,55,46,62,58,71],[39,26,57,56,36,63,59,62],[26,40,61,57,49,64,60,63],[55,56,17,18,58,65,68,72],[56,57,16,17,59,66,69,65],[57,61,19,16,60,67,70,66]] - for i in xrange(0,12): - m.insertNextCell(NORM_TRI3,conn[i]) - pass - for i in xrange(12,18): - m.insertNextCell(NORM_QUAD4,conn[i]) - pass - for i in xrange(18,30): - m.insertNextCell(NORM_TRI6,conn[i]) - pass - for i in xrange(30,36): - m.insertNextCell(NORM_QUAD8,conn[i]) - pass - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH1RB") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells(range(0,12),[0.,0.,1.,0.,0.,1.],[0.3333333333333333,0.3333333333333333],[0.5]) - fff.setGaussLocalizationOnCells(range(12,18),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) - fff.setGaussLocalizationOnCells(range(18,30),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells(range(30,36),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) - return MEDCouplingFieldTemplate(fff) - - # 2D usecase2 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_2(self): - coo=DataArrayDouble([1.0,0.0,1.24068268955165,0.15233667925643402,1.25,0.0,1.5,0.0,1.73695576537231,0.21327135095900804,1.75,0.0,2.0,0.0,0.9925461516413221,0.12186934340514702,1.212869657845,0.302402369499585,1.48881922746198,0.182804015107721,1.6980175209829897,0.423363317299419,1.9850923032826397,0.243738686810295,0.9702957262759959,0.241921895599668,1.1669755331215,0.447959936931625,1.4554435894139899,0.362882843399502,1.6337657463701,0.627143911704275,1.94059145255199,0.483843791199335,0.9335804264972021,0.35836794954530005,1.10368449107366,0.586839453482364,1.4003706397458,0.5375519243179501,1.5451582875031202,0.8215752348753091,1.8671608529944002,0.716735899090601,0.882947592858927,0.46947156278589103,1.02394005536124,0.716970545438808,1.32442138928839,0.704207344178836,1.43351607750574,1.00375876361433,1.76589518571785,0.9389431255717821,1.125,0.0,1.11661442059649,0.137103011330791,1.375,0.0,1.4972021976328,0.09157280930228531,1.625,0.0,1.61288749641715,0.198037683033365,1.875,0.0,1.9962695968437298,0.12209707906971401,1.0915826920605,0.272162132549626,1.36475095850682,0.167570347182078,1.47488236134593,0.27335328823822097,1.5767305551984903,0.39312308034946003,1.8610240343274802,0.228505018884652,1.96650981512791,0.364471050984295,1.05027797980935,0.403163943238463,1.3341566236295,0.332642606449543,1.43057542612234,0.45105869925641007,1.5170681930579497,0.5823479180111131,1.8193044867674901,0.45360355424937704,1.9074339014964499,0.601411599008546,0.993316041966293,0.528155508134127,1.28367308643365,0.492755930624788,1.36494190631481,0.6220398639843591,1.43478983839576,0.7628912895270731,1.7504632996822498,0.671939905397438,1.81992254175309,0.8293864853124782,0.921546049825116,0.645273490894927,1.21405294018102,0.6455233988306001,1.27896024653114,0.783747847073923,1.33112207196961,0.93206170907045,1.65552673661049,0.8802591802235451,1.70528032870818,1.0449971294319,0.8191520442889921,0.5735764363510459,1.22872806643349,0.8603646545265691,1.6383040885779798,1.14715287270209,1.24766849802733,0.0763106744185711,0.9981347984218671,0.0610485395348569,1.37243534783007,0.0839417418604282,1.74673589723827,0.106834944186,1.871502747041,0.114466011627857,1.22906863445494,0.227794406865184,0.9832549075639551,0.18223552549214703,1.3519754979004401,0.25057384755170303,1.7206960882369198,0.318912169611258,1.84360295168241,0.341691610297777,1.19214618843528,0.37588224938034104,0.953716950748227,0.300705799504273,1.31136080727881,0.413470474318376,1.6690046638094,0.526235149132478,1.7882192826529297,0.563823374070512,1.13745158859568,0.518366553320299,0.9099612708765431,0.4146932426562391,1.25119674745525,0.570203208652329,1.5924322240339497,0.725713174648418,1.7061773828935198,0.777549829980448,1.06580020544262,0.6531232058949361,0.8526401643540921,0.522498564715949,1.17238022598688,0.7184355264844301,1.12633406089736,0.7886675999826881,1.49212028761966,0.91437248825291,1.59870030816392,0.979684808842404,1.53591008304186,1.07545581815821,1.1229016482246,0.068679606976714,1.6219690474355302,0.0992038767441424,1.10616177100945,0.205014966178666,1.59778922479143,0.29613272892474,1.07293156959176,0.338294024442307,1.5497900449658701,0.488646924194444,1.02370642973611,0.466529897988269,1.47868706517438,0.673876519316388,0.9592201848983541,0.587810885305442,1.3855402670754,0.8490601676634171,0.743144825477394,0.669130606358858,0.9289310318467431,0.836413257948573,1.11471723821609,1.00369590953829,1.30050344458544,1.170978561128,0.656059028990507,0.7547095802227721,0.820073786238134,0.943386975278465,0.984088543485761,1.13206437033416,1.14810330073339,1.32074176538985,0.559192903470747,0.8290375725550421,0.6989911293384331,1.0362969656938,0.8387893552061201,1.24355635883256,0.978587581073807,1.45081575197132,0.453990499739547,0.8910065241883681,0.567488124674433,1.11375815523546,0.6809857496093201,1.3365097862825501,0.794483374544207,1.55926141732964,0.8360379286620679,0.7527719321537151,1.0218241350314199,0.92005458374343,1.20761034140077,1.08733723533314,1.39339654777011,1.25461988692286,0.7380664076143211,0.8490482777506181,0.902081164861948,1.03772567280631,1.06609592210957,1.226403067862,1.2301106793572,1.4150804629177,0.6290920164045901,0.932667269124422,0.7688902422722771,1.13992666226318,0.9086884681399641,1.34718605540194,1.04848669400765,1.5544454485407,0.51073931220699,1.00238233971191,0.624236937141877,1.22513397075901,0.737734562076764,1.4478856018061,0.85123218701165,1.6706372328531902,1.48628965095479,1.33826121271772,1.31211805798101,1.5094191604455398,1.11838580694149,1.6580751451100801,0.907980999479094,1.7820130483767398,0.978260196065517,0.778143295797024,1.17391223527862,0.9337719549564292,1.36956427449172,1.08940061411583,1.56521631370483,1.24502927327524,0.876136580374814,0.891563061442727,1.05136389644978,1.06987567373127,1.22659121252474,1.2481882860198201,1.4018185285997,1.42650089830836,0.7609517862609011,0.991691675364044,0.913142143513081,1.19003001043685,1.06533250076526,1.38836834550966,1.21752285801744,1.5867066805824699,0.6344229537008801,1.07703645055191,0.7613075444410561,1.29244374066229,0.8881921351812321,1.50785103077267,1.01507672592141,1.7232583208830499,0.498436336156558,1.1463250929814,0.5981236033878691,1.37559011157769,0.697810870619181,1.60485513017397,0.7974981378504931,1.8341201487702499,0.42752517915708604,1.17461577598239,0.513030214988503,1.4095389311788602,0.59853525081992,1.6444620863753399,0.6840402866513371,1.87938524157182,0.38477266124137705,1.05715419838415,0.470277697072795,1.29207735358062,0.5557827329042121,1.5270005087771,0.6412877687356291,1.76192366397358,0.34202014332566905,0.9396926207859091,0.782608156852414,0.6225146366376201,0.7009092642998511,0.713250449154182,0.608761429008721,0.7933533402912349,0.507538362960704,0.861629160441526,0.398749068925246,0.917060074385124,-2.0,0.0,-1.75,0.0,-1.5,0.0,-1.25,0.0,-1.9632543668953297,0.38161799075309005,-1.71784757103341,0.333915741908953,-1.4724407751715,0.286213493064817,-1.22703397930958,0.23851124422068104,-1.85436770913357,0.749213186831824,-1.62257174549188,0.655561538477846,-1.39077578185018,0.561909890123868,-1.15897981820848,0.46825824176988995,-1.6773411358908499,1.08927807003005,-1.4676734939044902,0.953118311276297,-1.25800585191814,0.816958552522541,-1.04833820993178,0.680798793768784,-1.4386796006773,1.38931674091799,-1.25884465059264,1.21565214830325,-1.07900970050798,1.0419875556885,-0.8991747504233141,0.868322963073747,-1.0,0.0,-0.981627183447664,0.19080899537654503,-0.9271838545667871,0.374606593415912,-0.838670567945424,0.544639035015027,-0.7193398003386511,0.694658370458997,-1.00375876361433,1.43351607750574,-0.8603646545265691,1.22872806643349,-0.716970545438808,1.02394005536124,-0.5735764363510459,0.8191520442889921,-1.14715287270209,1.6383040885779798,-0.8134732861516011,1.8270909152852002,-0.71178912538265,1.59870455087455,-0.6101049646137,1.3703181864639,-0.50842080384475,1.14193182205325,-0.4067366430758,0.9135454576426011,-0.44990210868773,1.9487401295704703,-0.39366434510176407,1.70514761337416,-0.337426581515798,1.4615550971778501,-0.281188817929831,1.21796258098154,-0.224951054343865,0.974370064785235,-0.06979899340500181,1.9987816540381902,-0.0610741192293767,1.74893394728342,-0.0523492450537515,1.49908624052864,-0.0436243708781263,1.24923853377387,-0.03489949670250091,0.9993908270190961,0.312868930080462,1.97537668119028,0.27376031382040406,1.72845459604149,0.23465169756034704,1.48153251089271,0.19554308130028902,1.23461042574392,0.156434465040231,0.9876883405951381],219,2) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) - m=MEDCouplingUMesh("MA2",2) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells(0) - conn=[[198,194,200],[198,200,199],[194,195,200],[195,201,200],[195,196,202],[195,202,201],[196,197,202],[197,203,202],[199,200,205],[199,205,204],[200,201,205],[201,206,205],[201,202,207],[201,207,206],[202,203,207],[203,208,207],[204,205,210],[204,210,209],[205,206,210],[206,211,210],[206,207,212],[206,212,211],[207,208,212],[208,213,212],[209,210,215],[209,215,214],[210,211,215],[211,216,215],[211,212,217],[211,217,216],[212,213,217],[213,218,217],[214,215,157],[214,157,158],[215,216,157],[216,156,157],[216,217,155],[216,155,156],[217,218,155],[218,163,155],[169,170,174,173],[170,171,175,174],[171,172,176,175],[172,189,190,176],[173,174,178,177],[174,175,179,178],[175,176,180,179],[176,190,191,180],[177,178,182,181],[178,179,183,182],[179,180,184,183],[180,191,192,184],[181,182,186,185],[182,183,187,186],[183,184,188,187],[184,192,193,188],[185,186,194,198],[186,187,195,194],[187,188,196,195],[188,193,197,196],[0,2,1,27,62,89],[1,7,0,28,63,89],[2,3,1,29,64,62],[3,9,1,30,36,64],[3,5,4,31,65,90],[4,9,3,32,30,90],[5,6,4,33,66,65],[6,11,4,34,39,66],[7,1,8,28,67,91],[8,12,7,35,68,91],[1,9,8,36,69,67],[9,14,8,37,42,69],[9,4,10,32,70,92],[10,14,9,38,37,92],[4,11,10,39,71,70],[11,16,10,40,45,71],[12,8,13,35,72,93],[13,17,12,41,73,93],[8,14,13,42,74,72],[14,19,13,43,48,74],[14,10,15,38,75,94],[15,19,14,44,43,94],[10,16,15,45,76,75],[16,21,15,46,51,76],[17,13,18,41,77,95],[18,22,17,47,78,95],[13,19,18,48,79,77],[19,24,18,49,54,79],[19,15,20,44,80,96],[20,24,19,50,49,96],[15,21,20,51,81,80],[21,26,20,52,57,81],[22,18,23,47,82,97],[23,59,22,53,83,97],[18,24,23,54,84,82],[24,60,23,55,85,84],[24,20,25,50,86,98],[25,60,24,56,55,98],[20,26,25,57,87,86],[26,61,25,58,88,87],[59,23,100,99,53,135,115,164],[23,60,101,100,85,136,116,135],[60,25,102,101,56,137,117,136],[25,61,131,102,88,138,118,137],[99,100,104,103,115,139,119,165],[100,101,105,104,116,140,120,139],[101,102,106,105,117,141,121,140],[102,131,132,106,118,142,122,141],[103,104,108,107,119,143,123,166],[104,105,109,108,120,144,124,143],[105,106,110,109,121,145,125,144],[106,132,133,110,122,146,126,145],[107,108,112,111,123,147,127,167],[108,109,113,112,124,148,128,147],[109,110,114,113,125,149,129,148],[110,133,134,114,126,150,130,149],[111,112,155,163,127,151,159,168],[112,113,156,155,128,152,160,151],[113,114,157,156,129,153,161,152],[114,134,158,157,130,154,162,153]] - for i in xrange(0,40): - m.insertNextCell(NORM_TRI3,conn[i]) - pass - for i in xrange(40,60): - m.insertNextCell(NORM_QUAD4,conn[i]) - pass - for i in xrange(60,100): - m.insertNextCell(NORM_TRI6,conn[i]) - pass - for i in xrange(100,120): - m.insertNextCell(NORM_QUAD8,conn[i]) - pass - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH2RB") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells(range(0,40),[0.,0.,1.,0.,0.,1.],[0.3333333333333333,0.3333333333333333],[0.5]) - fff.setGaussLocalizationOnCells(range(40,60),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) - fff.setGaussLocalizationOnCells(range(60,100),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells(range(100,120),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) - return MEDCouplingFieldTemplate(fff) - - # 3D usecase1 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_3(self): - coo=DataArrayDouble([0.,1.,0.,0.,2.,0.,0.,3.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,0.,1.,1.,0.,3.,1.,0.5,1.,1.,0.5,3.,1.,1.,1.,1.,1.,3.,1.,0.,0.,0.,0.,1.,0.,1.,0.,0.,1.,1.,0.,0.,0.,1.,0.,0.5,1.,0.,1.,1.,0.5,0.,1.,0.5,0.5,1.,0.5,1.,1.,1.,0.,1.,1.,0.5,1.,1.,1.,1.0],25,3) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]","Z [INCONNUE]"]) - m=MEDCouplingUMesh("MA1",3) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells(0) - conn=[[3,10,8,4],[19,22,23,20,14],[0,6,1,3,8,4],[4,8,10,5,9,11],[12,16,17,14,19,20],[14,20,23,15,21,24],[1,2,5,4,6,7,9,8],[12,13,15,14,17,18,21,20]] - m.insertNextCell(NORM_TETRA4,conn[0]) - m.insertNextCell(NORM_PYRA5,conn[1]) - for i in xrange(2,6): - m.insertNextCell(NORM_PENTA6,conn[i]) - pass - m.insertNextCell(NORM_HEXA8,conn[6]) - m.insertNextCell(NORM_HEXA8,conn[7]) - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH13") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells([0],[0.,1.,0.,0.,0.,0.,0.,0.,1.,1.,0.,0.],[0.25,0.25,0.25],[0.16666666666666666]) - fff.setGaussLocalizationOnCells([1],[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.],[0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416],[0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333]) - fff.setGaussLocalizationOnCells([2,3,4,5],[-1.,1.,0.,-1.,0.,0.,-1.,0.,1.,1.,1.,0.,1.,0.,0.,1.,0.,1.],[-0.577350269189626,0.5,0.5,-0.577350269189626,0.,0.5,-0.577350269189626,0.5,0.,0.577350269189626,0.5,0.5,0.577350269189626,0.,0.5,0.577350269189626,0.5,0.],[0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells([6,7],[-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) - return MEDCouplingFieldTemplate(fff) - - # 3D usecase2 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_4(self): - coo=DataArrayDouble([0.,2.,0.,0.,1.,0.,0.,0.,0.,1.,2.,0.,1.,1.,0.,1.,0.,0.,0.,2.,1.,0.,0.,1.,0.5, 2.,1.,0.5, 0.,1.,1.,2.,1.,1.,0.,1.,0.,3.,0.,0.,2.,0.,1.,3.,0.,1.,2.,0.,0.,3.,1.,0.,2.5, 1.,0.,2.,1.,0.5, 3.,1.,0.5, 2.5, 1.,0.5, 2.,1.,1.,3.,1.,1.,2.5, 1.,1.,2.,1.0],25,3) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]","Z [INCONNUE]"]) - m=MEDCouplingUMesh("MA2",3) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells(0) - conn=[[3,10,8,4],[19,22,23,20,14],[0,6,1,3,8,4],[4,8,10,5,9,11],[12,16,17,14,19,20],[14,20,23,15,21,24],[1,2,5,4,6,7,9,8],[12,13,15,14,17,18,21,20]] - m.insertNextCell(NORM_TETRA4,conn[0]) - m.insertNextCell(NORM_PYRA5,conn[1]) - for i in xrange(2,6): - m.insertNextCell(NORM_PENTA6,conn[i]) - pass - m.insertNextCell(NORM_HEXA8,conn[6]) - m.insertNextCell(NORM_HEXA8,conn[7]) - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH23") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells([0],[0.,1.,0.,0.,0.,0.,0.,0.,1.,1.,0.,0.],[0.25,0.25,0.25],[0.16666666666666666]) - fff.setGaussLocalizationOnCells([1],[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.],[0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416],[0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333]) - fff.setGaussLocalizationOnCells([2,3,4,5],[-1.,1.,0.,-1.,0.,0.,-1.,0.,1.,1.,1.,0.,1.,0.,0.,1.,0.,1.],[-0.577350269189626,0.5,0.5,-0.577350269189626,0.,0.5,-0.577350269189626,0.5,0.,0.577350269189626,0.5,0.5,0.577350269189626,0.,0.5,0.577350269189626,0.5,0.],[0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells([6,7],[-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) - return MEDCouplingFieldTemplate(fff) - - def buildCircle(self, center_X, center_Y, radius): - from cmath import rect - from math import pi - - c = [rect(radius, i*pi/4.0) for i in range(8)] - coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, - c[5].real,c[5].imag, c[1].real,c[1].imag] - connec = range(4) - baseMesh = MEDCouplingUMesh.New("circle", 2) - baseMesh.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - meshCoords += (center_X, center_Y) - baseMesh.setCoords(meshCoords) - - baseMesh.insertNextCell(NORM_QPOLYG, connec) - baseMesh.finishInsertingCells() - return baseMesh - - def buildCircle2(self, center_X, center_Y, radius): - from cmath import rect - from math import pi - - c = [rect(radius, i*pi/4.0) for i in range(8)] - coords = [] - for i in range(8): - coords.extend([c[i].real,c[i].imag]) - connec = [7,5,3,1, 6,4,2,0] - baseMesh = MEDCouplingUMesh.New("circle", 2) - baseMesh.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - meshCoords += (center_X, center_Y) - baseMesh.setCoords(meshCoords) - - baseMesh.insertNextCell(NORM_QPOLYG, connec) - baseMesh.finishInsertingCells() - return baseMesh - - build2DTargetMesh_1=classmethod(build2DTargetMesh_1) - build2DSourceMesh_1=classmethod(build2DSourceMesh_1) - build3DTargetMesh_1=classmethod(build3DTargetMesh_1) - build3DSourceMesh_1=classmethod(build3DSourceMesh_1) - build3DSurfTargetMesh_1=classmethod(build3DSurfTargetMesh_1) - build3DExtrudedUMesh_1=classmethod(build3DExtrudedUMesh_1) - buildCU1DMesh_U=classmethod(buildCU1DMesh_U) - build2DTargetMeshMergeNode_1=classmethod(build2DTargetMeshMergeNode_1) - build3DTargetMeshMergeNode_1=classmethod(build3DTargetMeshMergeNode_1) - build2DTargetMeshMerged_1=classmethod(build2DTargetMeshMerged_1) - build2DTargetMesh_2=classmethod(build2DTargetMesh_2) - build1DSourceMesh_2=classmethod(build1DSourceMesh_2) - build1DTargetMesh_3=classmethod(build1DTargetMesh_3) - build2DCurveTargetMesh_3=classmethod(build2DCurveTargetMesh_3) - build2DTargetMesh_3=classmethod(build2DTargetMesh_3) - build2DTargetMesh_4=classmethod(build2DTargetMesh_4) - buildMultiFields_1=classmethod(buildMultiFields_1) - buildMultiFields_2=classmethod(buildMultiFields_2) - build1DMultiTypes_1=classmethod(build1DMultiTypes_1) - build2DMultiTypes_1=classmethod(build2DMultiTypes_1) - build3DMultiTypes_1=classmethod(build3DMultiTypes_1) - buildCoordsForMultiTypes_1=classmethod(buildCoordsForMultiTypes_1) - buildHexa8Mesh_1=classmethod(buildHexa8Mesh_1) - buildPointe_1=classmethod(buildPointe_1) - buildFieldOnGauss_1=classmethod(buildFieldOnGauss_1) - buildFieldOnGauss_2=classmethod(buildFieldOnGauss_2) - buildFieldOnGauss_3=classmethod(buildFieldOnGauss_3) - buildFieldOnGauss_4=classmethod(buildFieldOnGauss_4) - buildCircle=classmethod(buildCircle) - buildCircle2=classmethod(buildCircle2) - pass - - - diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py b/medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py deleted file mode 100644 index 86ee5d767..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py +++ /dev/null @@ -1,2345 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDCoupling import * -import unittest -from math import pi, sqrt - -class MEDCouplingBasicsTest(unittest.TestCase): - - def testExample_MEDCouplingFieldDouble_WriteVTK(self): - #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1] - # mesh - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) # mesh becomes a 2D one - - # 3 fields (lying on the same mesh!) - field1 = mesh.getMeasureField( True ) - field2 = mesh.buildOrthogonalField() - field3 = mesh.fillFromAnalytic( ON_CELLS, 2, "IVec * x + JVec * y" ) - field2.setName( "Normal" ) # name is necessary! - field3.setName( "Barycenter" ) # name is necessary! - - # WriteVTK - fileName = "testExample_MEDCouplingFieldDouble_WriteVTK" - fs = [ field1, field2, field3 ] # field series - writtenFileName=MEDCouplingFieldDouble.WriteVTK( fileName, fs ) - print "The file name with correct extension is : %s"%(writtenFileName) - #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1] - import os - os.remove( writtenFileName ) - - return - - def testExample_MEDCouplingFieldDouble_MaxFields(self): - #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1] - vals1 = [0.,2., 4.,6.] # for field 1 - vals2 = [2.,0., 6.,4.] # for field 2 - valsMax = [2.,2., 6.,6.] # expected max field - valsMin = [0.,0., 4.,4.] # expected min field - - # field 1 - valsArr1=DataArrayDouble(vals1,2,2) # 2 tuples per 2 components - field1 = MEDCouplingFieldDouble( ON_NODES ) - field1.setArray( valsArr1 ) - - # field 2 - valsArr2=DataArrayDouble(vals2,2,2) # 2 tuples per 2 components - field2 = MEDCouplingFieldDouble( ON_NODES ) - field2.setArray( valsArr2 ) - - # max field - fieldMax = MEDCouplingFieldDouble.MaxFields( field1, field2 ) - self.assertTrue( fieldMax.getArray().getValues() == valsMax ) - - # min field - fieldMin = MEDCouplingFieldDouble.MinFields( field1, field2 ) - self.assertTrue( fieldMin.getArray().getValues() == valsMin ) - #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1] - - def testExample_MEDCouplingFieldDouble_MergeFields(self): - #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1] - # mesh 1 - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh1=MEDCouplingCMesh() - mesh1.setCoords(coordsArr) - # field 1 - field1 = mesh1.fillFromAnalytic( ON_CELLS, 1, "x") - - # mesh 2 and field 2 - field2 = field1.cloneWithMesh( True ) - vec = [5.] - field2.getMesh().translate(vec) # translate mesh2 - field2.applyFunc("x + 5") # "translate" field2 - - # concatenate field1 and field2 - field3 = MEDCouplingFieldDouble.MergeFields( field1, field2 ) - field4 = MEDCouplingFieldDouble.MergeFields( [ field1, field2] ) - #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1] - return - - def testExample_MEDCouplingFieldDouble_substractInPlaceDM(self): - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - coords1=[0.,1.,2.,3.] - coords2=[2.,1.,0.,3.] #0 <==> #2 - # mesh 1 - mesh1=MEDCouplingUMesh() - coordsArr=DataArrayDouble(coords1, 4, 1) - mesh1.setCoords(coordsArr) - mesh1.setMeshDimension(0) - mesh1.allocateCells(0) - mesh1.finishInsertingCells() - # mesh 2 - mesh2=mesh1.deepCpy() - mesh2.getCoords().setValues(coords2, 4, 1) - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - field1 = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field1 values == coords1 - field2 = mesh2.fillFromAnalytic(ON_NODES,1,"x") # field2 values == coords2 - levOfCheck = 10 # nodes can be permuted - field1.substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] - field2.applyFunc( 1, 0.0 ) # all field2 values == 0.0 - self.assertTrue( field1.isEqual( field2, 1e-13, 1e-13 )) # field1 == field2 == 0.0 - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] - return - - def testExample_MEDCouplingFieldDouble_changeUnderlyingMesh(self): - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - coords1=[0.,1.,2.,3.] - coords2=[2.,1.,0.,3.] #0 <==> #2 - # mesh 1 - mesh1=MEDCouplingUMesh() - coordsArr=DataArrayDouble(coords1, 4, 1) - mesh1.setCoords(coordsArr) - mesh1.setMeshDimension(0) - mesh1.allocateCells(0) - mesh1.finishInsertingCells() - # mesh 2 - mesh2=mesh1.deepCpy() - mesh2.getCoords().setValues(coords2, 4, 1) - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] - field = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field values == coords1 - levOfCheck = 10 # nodes can be permuted - field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap - self.assertTrue( field.getArray().getValues() == coords2 ) - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - v = [1.,2., 3.,4.] - array = DataArrayDouble( v, 2, 2 ) # 2 tuples per 2 components - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - func = "IVec * v + JVec * w*w + 10" - field.applyFunc( 2, func ) - self.assertTrue( field.getNumberOfComponents() == 2 ) # 2 components remains - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] - v2 = field.getArray().getValues() - self.assertAlmostEqual( v2[0], 10 + v[0], 13 ) # "10 + IVec * v" - self.assertAlmostEqual( v2[1], 10 + v[1]*v[1], 13 ) # "10 + JVec * v*v" - self.assertAlmostEqual( v2[2], 10 + v[2], 13 ) # "10 + IVec * v" - self.assertAlmostEqual( v2[3], 10 + v[3]*v[3], 13 ) # "10 + JVec * v*v" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc3(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1] - # create a 2D vector field - values = [1.,1., 2.,1.] - array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - # transform the field to a 3D vector field - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - varNames=["a","b"] # names used to refer to X and Y components - field.applyFunc3( 3, varNames, func ) # require 3 components - self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2] - vec1 = field.getArray().getTuple(1) # vector #1 - a,b = values[2], values[3] # initial components of the vector #1 - self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc2(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1] - # create a 2D vector field - values = [1.,1., 2.,1.] - array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components - array.setInfoOnComponent(0,"a") # name used to refer to X component within a function - array.setInfoOnComponent(1,"b") # name used to refer to Y component within a function - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - # transform the field to a 3D vector field - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.applyFunc2( 3, func ) # require 3 components - self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2] - vec1 = field.getArray().getTuple(1) # vector #1 - a,b = values[2], values[3] # initial components of the vector #1 - self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1] - # create a 2D vector field - values = [1.,1., 2.,1.] - array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - # transform the field to a 3D vector field - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.applyFunc( 3, func ) # require 3 components - self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2] - vec1 = field.getArray().getTuple(1) # vector #1 - a,b = values[2], values[3] # initial components of the vector #1 - self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc_val(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - field.fillFromAnalytic(2,"IVec * x + JVec * y") # 2 components - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2] - newValue = 7. - field.applyFunc( 3, newValue ) # 3 components are required - self.assertTrue( field.getIJ(1,0) == newValue ) # a value is as expected - self.assertTrue( field.getNumberOfComponents() == 3 ) - self.assertTrue( field.getNumberOfTuples() == mesh.getNumberOfCells() ) - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2] - return - - def testExample_MEDCouplingFieldDouble_fillFromAnalytic3(self): - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - varNames=["a","b"] # names used to refer to X and Y coord components - field.fillFromAnalytic3(3,varNames,func) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] - return - - def testExample_MEDCouplingFieldDouble_fillFromAnalytic2(self): - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - coords = [0.,2.,4.] - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function - y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.fillFromAnalytic2(3,func) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] - return - - def testExample_MEDCouplingFieldDouble_fillFromAnalytic(self): - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - coords = [0.,2.,4.] - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.fillFromAnalytic(3,func) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] - return - - def testExample_MEDCouplingFieldDouble_getValueOn_time(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2] - field = MEDCouplingFieldDouble( ON_CELLS, LINEAR_TIME ) - field.setMesh( mesh ) - field.fillFromAnalytic(1,"10") # all values == 10. - field.setEndArray( field.getArray() + field.getArray() ) # all values == 20. - time1, time2 = 1.1, 22. - field.setStartTime( time1, 0, 0 ) - field.setEndTime ( time2, 0, 0 ) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2] - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3] - pos = [ 1., 1. ] # we are in 2D space - value = field.getValueOn( pos, 0.5*( time1 + time2 )) - self.assertTrue( value[0] == 0.5*( 10. + 20.)) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3] - return - - def testExample_MEDCouplingFieldDouble_getValueOnMulti(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2] - bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters - valArray = field.getValueOnMulti( bc ) - self.assertTrue( valArray.isEqual( field.getArray(), 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2] - return - - def testExample_MEDCouplingFieldDouble_getValueOn(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2] - bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters - vals = [] # array to collect values returned by getValueOn() - for i,tupl in enumerate( bc ): - vals.extend( field.getValueOn( tupl ) ) - self.assertTrue( vals == field.getArray().getValues() ) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2] - return - - def testExample_MEDCouplingFieldDouble_getValueOnPos(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2] - val11 = field.getValueOnPos( 1,1,-1) - bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters - self.assertTrue( val11[0] == bc[3,0] + bc[3,1] ) - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2] - return - - def testExample_MEDCouplingFieldDouble_renumberNodes(self): - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - mesh=mesh.buildUnstructured() - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1] - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2] - field = mesh.fillFromAnalytic(ON_NODES,2,"IVec*x+JVec*y") - values = field.getArray() - nodeCoords = mesh.getCoords() - self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2] - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3] - renumber = [8, 7, 6, 5, 4, 3, 2, 1, 0] - field.renumberNodes(renumber,False) - mesh2 = field.getMesh() # field now refers to another mesh - values = field.getArray() - nodeCoords = mesh2.getCoords() - self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3] - return - - - def testExample_MEDCouplingFieldDouble_renumberCells(self): - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - mesh=mesh.buildUnstructured() - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1] - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2] - field = mesh.fillFromAnalytic(ON_CELLS,2,"IVec*x+JVec*y") - values = field.getArray() - bc = mesh.getBarycenterAndOwner() - self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2] - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3] - renumber = [ 3, 2, 1, 0 ] - field.renumberCells(renumber,False) - mesh2 = field.getMesh() # field now refers to another mesh - values = field.getArray() - bc = mesh2.getBarycenterAndOwner() - self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3] - return - - def testExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(self): - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field1 = mesh.fillFromAnalytic(ON_NODES,1,"x+y") - self.assertTrue( field1.getTimeDiscretization() == ONE_TIME ) - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] - field2 = field1.buildNewTimeReprFromThis(NO_TIME,False) - self.assertTrue( field2.getTimeDiscretization() == NO_TIME ) - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] - return - - def testExample_MEDCouplingMesh_fillFromAnalytic3(self): - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - varNames=["a","b"] # names used to refer to X and Y coord components - field=mesh.fillFromAnalytic3(ON_CELLS,3,varNames,func) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] - return - - def testExample_MEDCouplingMesh_fillFromAnalytic2(self): - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function - y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field=mesh.fillFromAnalytic2(ON_CELLS,3,func) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] - return - - def testExample_MEDCouplingMesh_fillFromAnalytic(self): - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field=mesh.fillFromAnalytic(ON_CELLS,3,func) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] - return - - def testExample_MEDCouplingCMesh_getCoordsAt(self): - #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] - coords = [1.,2.,4.] - x=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoordsAt(0,x) - x2=mesh.getCoordsAt(0) - assert coords == x2.getValues() - #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] - return - - def testExample_MEDCouplingUMesh_areCellsIncludedIn(self): - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - mesh1=MEDCouplingUMesh() - mesh1.setMeshDimension(2) - mesh1.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh1.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh1.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh1.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh1.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh1.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh1.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh1.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - cells2 = [ 4,2,0 ] - mesh2 = mesh1.buildPartOfMySelf(cells2, True ) # even cells selected - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - compType = 0 # the strongest policy - isOk, corr2to1 = mesh1.areCellsIncludedIn( mesh2, compType ) - assert isOk # a larger mesh1 includes a smaller mesh2 - assert corr2to1.getValues() == cells2 - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - isOk, corr1to2 = mesh2.areCellsIncludedIn( mesh1, compType ) - assert not isOk # the smaller mesh2 does NOT include the larger mesh1 - assert corr1to2.getValues() == [2, 3, 1, 4, 0] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - - def testExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(self): - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - # 2D coordinates of 5 base nodes - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2] - coordsArr=DataArrayDouble(coords,5,2) - # coordinates of 5 top nodes - coordsArr2 = coordsArr.deepCpy() - # 3D coordinates of base + top nodes - coordsArr = coordsArr.changeNbOfComponents( 3, 0 ) - coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 ) - coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2]) - # mesh - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - mesh.setMeshDimension(3) - mesh.allocateCells(2) - # connectivity of reversed HEXA8 and PENTA6 - conn=[0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9] - mesh.insertNextCell(NORM_HEXA8, 8,conn[0:0+8]) - mesh.insertNextCell(NORM_PENTA6,6,conn[8:8+6]) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] - fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells() - assert len( fixedCells ) == 2 # 2 cells fixed - fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells() - assert len( fixedCells ) == 0 # no bad cells - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] - return - - def testExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(self): - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - # 2D coordinates of 5 base nodes - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2] - coordsArr=DataArrayDouble(coords,5,2) - # coordinates of 5 top nodes - coordsArr2 = coordsArr.deepCpy() - # 3D coordinates of base + top nodes - coordsArr = coordsArr.changeNbOfComponents( 3, 0 ) - coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 ) - coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2]) - # mesh - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - mesh.setMeshDimension(3) - mesh.allocateCells(2) - # connectivity of a HEXA8 + a reversed PENTA6 - conn=[0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9] - mesh.insertNextCell(NORM_POLYHED, 8,conn[0:0+8]) # "extruded" polyhedron - mesh.insertNextCell(NORM_POLYHED,6,conn[8:8+6]) - mesh.finishInsertingCells() - # fix connectivity of NORM_POLYHED's - mesh.convertExtrudedPolyhedra() - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] - badCells = mesh.arePolyhedronsNotCorrectlyOriented() - assert len( badCells ) == 1 # one polyhedron is KO - # fix invalid rolyherdons - mesh.orientCorrectlyPolyhedrons() - # re-check the orientation - badCells = mesh.arePolyhedronsNotCorrectlyOriented() - assert len( badCells ) == 0 # connectivity is OK - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] - return - - def testExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(self): - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - mesh.changeSpaceDimension(3) - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] - vec = [0.,0.,-1.] - badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False ) - assert len( badCellIds ) == 1 # one cell is reversed - # fix orientation - mesh.orientCorrectly2DCells( vec, False ) - # re-check orientation - badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False ) - assert len( badCellIds ) == 0 # the orientation is OK - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] - return - - def testExample_MEDCouplingUMesh_getCellsContainingPoints(self): - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2] - pos = [ 10., 10, # point out of the mesh - 0.3, 0.3, # point located somewhere inside the mesh - coords[2], coords[3]] # point at the node #1 - eps = 1e-4 # ball radius - cells,cellsIndex=mesh.getCellsContainingPoints( pos, 3, eps ) - assert cells.getValues() == [4, 0, 1] - assert cellsIndex.getValues() == [0, 0, 1, 3] - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2] - return - - - def testExample_MEDCouplingUMesh_getCellsContainingPoint(self): - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2] - pos4 = coords[ 4*2 : ] # coordinates of the node #4 - eps = 1e-4 # ball radius - pos = [ pos4[0]+eps, pos4[1]-eps ] # ball center - cellIds=mesh.getCellsContainingPoint( pos, eps ) - assert len( cellIds ) == mesh.getNumberOfCells() - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2] - return - - - def testExample_MEDCouplingUMesh_buildPartOrthogonalField(self): - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] - part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted - vecField=mesh.buildPartOrthogonalField( part ) - vecArr = vecField.getArray() - assert len( vecArr ) == len( part ) - assert vecArr.getNumberOfComponents() == 3 - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] - return - - def testExample_MEDCouplingUMesh_getPartMeasureField(self): - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1] - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2] - isAbs = True - part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted - areaArr=mesh.getPartMeasureField( isAbs, part ) - assert areaArr[0] > 0 # orientation ignored - areaArr=mesh.getPartMeasureField( not isAbs, part ) - assert areaArr[0] < 0 # orientation considered - assert len( areaArr ) == len( part ) - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2] - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3] - part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted - baryCenters = mesh.getPartBarycenterAndOwner( part ) - assert len( baryCenters ) == len( part ) - assert baryCenters.getNumberOfComponents() == mesh.getSpaceDimension() - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3] - return - - def testExample_MEDCouplingUMesh_getCellsInBoundingBox(self): - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - coords=[0.,0., 0.,1., 1.,1] - coordsArr=DataArrayDouble(coords,3,2) - mesh.setCoords(coordsArr) - mesh.allocateCells(1) - conn=[0,1,2] - mesh.insertNextCell(NORM_TRI3,3,conn) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] - bbox = [1., 1., 1.001,1.001] # xMin, xMax, yMin, yMax - cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.0 ) - assert cellsInBox.getValues() == [] - cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.1 ) - assert cellsInBox.getValues() == [0] - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] - - - def testExample_MEDCouplingUMesh_renumberNodesInConn(self): - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(1) - conn=[4,3,2,1] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1] - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2] - old2newIds = [-1,3,2,1,0] - mesh.renumberNodesInConn( old2newIds ) - nodes0 = mesh.getNodeIdsOfCell( 0 ) - assert nodes0 == [0,1,2,3] - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2] - return - - - def testExample_MEDCouplingUMesh_renumberNodes(self): - #! [PySnippet_MEDCouplingUMesh_renumberNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3] - coordsArr=DataArrayDouble(coords,4,2) - mesh.setCoords(coordsArr) - mesh.allocateCells(0) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_renumberNodes_1] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_2] - mesh.renumberNodes([ 2,1,0,-1 ], 3) - coordsArr = mesh.getCoords() # get a shorten array - assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,-0.3] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_2] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_3] - coordsArr.setValues(coords,4,2) # restore old nodes - mesh.renumberNodes2([ 2,1,0,2 ], 3) - coordsArr = mesh.getCoords() # get a shorten array - assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,0.0] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_3] - return - - def testExample_MEDCouplingUMesh_findBoundaryNodes(self): - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1] - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2] - nodeIdsArr=mesh.findBoundaryNodes() - assert nodeIdsArr.getNumberOfTuples() == mesh.getNumberOfNodes() - 1 - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2] - return - - def testExample_MEDCouplingUMesh_buildBoundaryMesh(self): - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2] - mesh1=mesh.buildBoundaryMesh(True) - mesh2=mesh.buildBoundaryMesh(False) - assert coordsArr.isEqual( mesh1.getCoords(), 1e-13 ) # same nodes - assert not coordsArr.isEqual( mesh2.getCoords(), 1e-13 ) # different nodes - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2] - return - - def testExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(self): - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] - nodeIds = mesh.getNodeIdsOfCell( 0 ) - allNodes = True - mesh1 = mesh.buildFacePartOfMySelfNode( nodeIds, allNodes ) - assert mesh1.getNumberOfCells() == 4 # 4 segments bounding QUAD4 #0 only - mesh2 = mesh.buildFacePartOfMySelfNode( nodeIds, not allNodes ) - assert mesh2.getNumberOfCells() > 4 # more segments added - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] - return - - - def testExample_MEDCouplingUMesh_buildPartOfMySelfNode(self): - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] - nodeIds = mesh.getNodeIdsOfCell( 0 ) - allNodes = True - mesh1 = mesh.buildPartOfMySelfNode( nodeIds, allNodes ) - mesh2 = mesh.buildPartOfMySelfNode( nodeIds, not allNodes ) - assert mesh1.getNumberOfCells() == 1 # cell #0 is found only - assert mesh2.getNumberOfCells() == mesh.getNumberOfCells() # all cells are found - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] - return - - - def testExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(self): - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - nodeIds = mesh.getNodeIdsOfCell( 0 ) - allNodes = True - cellIdsArr1 = mesh.getCellIdsLyingOnNodes( nodeIds, allNodes ) - cellIdsArr2 = mesh.getCellIdsLyingOnNodes( nodeIds, not allNodes ) - assert cellIdsArr1.getNumberOfTuples() == 1 # cell #0 is found only - assert cellIdsArr2.getNumberOfTuples() == mesh.getNumberOfCells() # all cells are found - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - return - - - def testExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(self): - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - cellIds = [1,2] - nodeIds = mesh.getNodeIdsOfCell( cellIds[0] ) - nodeIds += mesh.getNodeIdsOfCell( cellIds[1] ) - cellIdsArr = mesh.getCellIdsFullyIncludedInNodeIds( nodeIds ) - assert cellIdsArr.getValues() == cellIds - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - return - - - def testExample_MEDCouplingUMesh_buildPartOfMySelf(self): - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - cellIds=[1,2] - mesh2=mesh.buildPartOfMySelf(cellIds, True) - mesh3=mesh.buildPartOfMySelf(cellIds, False) - coordsArr2 = mesh2.getCoords() - assert coordsArr.isEqual( coordsArr2, 1e-13 ) # same nodes - coordsArr3 = mesh3.getCoords() - assert not coordsArr.isEqual( coordsArr3, 1e-13 ) # different nodes - assert mesh2.getNodeIdsOfCell(0) == mesh.getNodeIdsOfCell( cellIds[0]) # cell #1 was copied - assert mesh2.getNodeIdsOfCell(1) == mesh.getNodeIdsOfCell( cellIds[1]) # cell #2 was copied - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - return - - def testExample_MEDCouplingUMesh_mergeNodes(self): - #! [PySnippet_MEDCouplingUMesh_mergeNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.finishInsertingCells() - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 ~~ 0 - 1.1,0.0, # 3 - 1.1,0.0, # 4 == 3 - 0.3,-0.303]# 5 ~~ 0 - coordsArr=DataArrayDouble(coords,6,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_mergeNodes_1] - #! [PySnippet_MEDCouplingUMesh_mergeNodes_2] - arr,areNodesMerged,newNbOfNodes=mesh.mergeNodes(0.004) - assert arr.getValues() == [0, 1, 0, 2, 2, 0] - assert areNodesMerged - assert newNbOfNodes == 3 - #! [PySnippet_MEDCouplingUMesh_mergeNodes_2] - #! [PySnippet_MEDCouplingUMesh_mergeNodes_3] - baryCoords2 = coords[2*2:] # initial coordinates of node #2 - coordsArr = mesh.getCoords() # retrieve a new shorten coord array - self.assertNotAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 differs from that of baryCoords2 - # restore coordinates - coordsArr = DataArrayDouble(coords,6,2) - mesh.setCoords(coordsArr) - # call mergeNodes2() - mesh.mergeNodes2(0.004) - coordsArr = mesh.getCoords() # retrieve a new shorten coord array - self.assertAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 equals to that of baryCoords2 - #! [PySnippet_MEDCouplingUMesh_mergeNodes_3] - return - - def testExample_MEDCouplingUMesh_zipConnectivityTraducer(self): - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 2 == 1 - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 3 == 0 - mesh.insertNextCell(NORM_QUAD4,4,conn[2:4]+conn[0:2]) # 4 ~~ 0 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - oldNbCells = mesh.getNumberOfCells() - arr = mesh.zipConnectivityTraducer(0) - assert mesh.getNumberOfCells() == oldNbCells-2 - assert arr.getValues() == [0, 1, 1, 0, 2] - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - return - - def testExample_MEDCouplingUMesh_zipCoordsTraducer(self): - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - cellIds=[1,2] - mesh2=mesh.buildPartOfMySelf(cellIds,True) - arr=mesh2.zipCoordsTraducer() - assert mesh2.getNumberOfNodes() == 4 # nb of nodes decreased - assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] # -1 for unused nodes - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - return - - def testExample_MEDCouplingUMesh_getNodeIdsInUse(self): - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - cellIds=[1,2] - mesh2=mesh.buildPartOfMySelf(cellIds,True) - arr,newNbOfNodes=mesh2.getNodeIdsInUse() - assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - arr2=arr.invertArrayO2N2N2O(newNbOfNodes) - assert arr2.getValues() == [1,2,4,5] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - return - - def testExample_MEDCouplingUMesh_convertToPolyTypes(self): - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1] - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2] - cells=[1,3] - mesh.convertToPolyTypes(cells) - assert mesh.getTypeOfCell(0) == NORM_QUAD4 - assert mesh.getTypeOfCell(1) == NORM_POLYGON, mesh.getTypeOfCell(1) - assert mesh.getTypeOfCell(2) == NORM_TRI3 - assert mesh.getTypeOfCell(3) == NORM_POLYGON - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2] - return - - def testExample_MEDCouplingUMesh_buildDescendingConnectivity2(self): - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2() - assert desc.getValues() == [1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10] - assert descIndx.getValues() == [0,4,7,10,14,18] - assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] - assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - assert mesh2.getNodeIdsOfCell( 3-1 ) == [4, 1] # cell #3 in FORTRAN mode - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - return - - def testExample_MEDCouplingUMesh_buildDescendingConnectivity(self): - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity() - assert desc.getValues() == [0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9] - assert descIndx.getValues() == [0,4,7,10,14,18] - assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] - assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - return - - def testExample_MEDCouplingUMesh_getReverseNodalConnectivity(self): - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - revNodal,revNodalIndx=mesh.getReverseNodalConnectivity() - assert revNodal.getValues() == [0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4] - assert revNodalIndx.getValues() == [0,1,3,5,7,12,14,15,17,18] - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - return - - def testExample_MEDCouplingUMesh_checkDeepEquivalWith(self): - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - # mesh 1 - mesh1=MEDCouplingUMesh() - mesh1.setMeshDimension(2) - coords=[0.0,0.0, #0 - 1.0,0.0, #1 - 1.0,1.0, #2 - 0.0,1.0] #3 - coordsArr=DataArrayDouble(coords,4,2) - mesh1.setCoords(coordsArr) - mesh1.allocateCells(2) - mesh1.insertNextCell(NORM_TRI3,3,[0,1,2]) #0 - mesh1.insertNextCell(NORM_TRI3,3,[1,2,3]) #1 - mesh1.finishInsertingCells() - # mesh 2 - mesh2=MEDCouplingUMesh() - mesh2.setMeshDimension(2) - coords=[0.0,1.0, #0 = #3 - 0.0,0.0, #1 = #0 - 1.0,0.0, #2 = #1 - 1.0,1.001] #3 ~ #2 - coordsArr2=DataArrayDouble(coords,4,2) - mesh2.setCoords(coordsArr2) - mesh2.allocateCells(2) - mesh2.insertNextCell(NORM_TRI3,3,[2,3,0]) #0 = #1 - mesh2.insertNextCell(NORM_TRI3,3,[3,1,2]) #1 ~ #0 - mesh2.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - cellCompPol = 1 # "permuted same orientation" - policy of medium severity - cOld2New, nOld2New = mesh1.checkDeepEquivalWith( mesh2, cellCompPol, 0.002 ) - assert nOld2New.getValues() == [3, 0, 1, 2] - assert cOld2New.getValues() == [1, 0] - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - self.assertRaises( InterpKernelException, mesh1.checkDeepEquivalOnSameNodesWith, mesh2, cellCompPol, 0.002) - mesh2.setCoords(coordsArr) # make meshes share the same coordinates array - mesh2.allocateCells(2) - mesh2.insertNextCell(NORM_TRI3,3,[1,2,3]) #0 = #1 - mesh2.insertNextCell(NORM_TRI3,3,[1,0,2]) #1 ~ #0 - mesh2.finishInsertingCells() - cellCompPol = 2 # the weakest policy - mesh1.checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0 ) - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - return - - def testExample_MEDCouplingPointSet_scale(self): - #! [PySnippet_MEDCouplingPointSet_scale_1] - coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes - coordsArr=DataArrayDouble(coords,4,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - initCoords = coordsArr.deepCpy() - #! [PySnippet_MEDCouplingPointSet_scale_1] - #! [PySnippet_MEDCouplingPointSet_scale_2] - center = [0.,0.] - factor = 2. - mesh.scale(center,factor) - #! [PySnippet_MEDCouplingPointSet_scale_2] - #! [PySnippet_MEDCouplingPointSet_scale_3] - coords2 = mesh.getCoords() - assert coords2.isEqualWithoutConsideringStr( initCoords, 1.0 ) - assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 ) - #! [PySnippet_MEDCouplingPointSet_scale_3] - return - - def testExample_MEDCouplingPointSet_translate(self): - #! [PySnippet_MEDCouplingPointSet_translate_1] - coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes - coordsArr=DataArrayDouble(coords,4,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - initCoords = coordsArr.deepCpy() - #! [PySnippet_MEDCouplingPointSet_translate_1] - #! [PySnippet_MEDCouplingPointSet_translate_2] - vector = [1.,1.] - mesh.translate(vector) - #! [PySnippet_MEDCouplingPointSet_translate_2] - #! [PySnippet_MEDCouplingPointSet_translate_3] - coords2 = mesh.getCoords() - assert coords2.isEqualWithoutConsideringStr( initCoords, 1 ) - assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 ) - #! [PySnippet_MEDCouplingPointSet_translate_3] - return - - def testExample_MEDCouplingPointSet_rotate(self): - #! [PySnippet_MEDCouplingPointSet_rotate_1] - coords=[0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1] # 2D coordinates of 4 nodes - coordsArr=DataArrayDouble(coords,4,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_rotate_1] - #! [PySnippet_MEDCouplingPointSet_rotate_2] - center = [0.,0.] - mesh.rotate(center,-pi/2) - #! [PySnippet_MEDCouplingPointSet_rotate_2] - #! [PySnippet_MEDCouplingPointSet_rotate_3] - mesh.changeSpaceDimension(3) - center = [0.,0.,0.] - vector = [0.,0.,1.] - mesh.rotate(center,vector,pi/2) - #! [PySnippet_MEDCouplingPointSet_rotate_3] - #! [PySnippet_MEDCouplingPointSet_rotate_4] - mesh.changeSpaceDimension(2) - coords2 = mesh.getCoords() - for i,c in enumerate( coords ): - self.assertAlmostEqual( c, coords2.getIJ(0,i), 13 ) - #! [PySnippet_MEDCouplingPointSet_rotate_4] - return - - def testExample_MEDCouplingPointSet_getBoundingBox(self): - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1] - cc=[0.0, 0.1, 0.2, # 3D coordinates of 2 nodes - 2.0, 2.1, 2.2] - coordsArr=DataArrayDouble(cc,2,3) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1] - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2] - bbox=mesh.getBoundingBox() - assert bbox == [( cc[0], cc[3] ), # NOTE: list of 3 tuples is retirned! - ( cc[1], cc[4] ), - ( cc[2], cc[5] )] - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2] - - def testExample_MEDCouplingPointSet_getNodeIdsNearPoint(self): - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - # 2D coordinates of 5 nodes - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 - 1.1,0.0, # 3 - 0.3,-0.30299999999999]# 4 - coordsArr=DataArrayDouble(coords,5,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] - point=[0.3, -0.3] # point close to nodes #0, #2 and #4 - ids=mesh.getNodeIdsNearPoint(point,0.003) - assert ids.getValues() == [0,2,4] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] - return - - def testExample_MEDCouplingPointSet_getNodeIdsNearPoints(self): - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - # 2D coordinates of 7 nodes - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 - 1.1,0.0, # 3 - 1.1,0.0, # 4 - 1.1,0.002, # 5 - 0.3,-0.303]# 6 - coordsArr=DataArrayDouble(coords,7,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] - points=[0.2,-0.301, # ~ node #1 - 0.0, 0.0, - 1.1, 0.002] # ~ nodes #3, #4 and #5 - ids,idsIndex=mesh.getNodeIdsNearPoints(points,3,0.003) - assert ids.getValues() == [1, 3, 4, 5] - assert idsIndex.getValues() == [0, 1, 1, 4] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] - return - - def testExample_MEDCouplingPointSet_findCommonNodes(self): - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1] - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 - 1.1,0.0, # 3 - 1.1,0.0, # 4 - 0.3,-0.303]# 5 - coordsArr=DataArrayDouble(coords,6,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1] - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2] - comm,commI=mesh.findCommonNodes(1e-13) - assert comm.getValues() == [3,4] - comm,commI=mesh.findCommonNodes(0.004) - assert comm.getValues() == [0,2,5,3,4] - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2] - return - - def testExample_MEDCouplingPointSet_getCoordinatesOfNode(self): - #! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3] - coordsArr=DataArrayDouble(coords,3,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) -#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] -#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] - nodeCoords=mesh.getCoordinatesOfNode(1) - self.assertAlmostEqual(0.2, nodeCoords[0],13) - self.assertAlmostEqual(-0.3,nodeCoords[1],13) -#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] - return - - def testExample_DataArrayInt_getTuple(self): -#! [Snippet_DataArrayInt_getTuple_1] - dv=DataArrayInt() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) - assert dv.getTuple( 1 ) == [9,10] -#! [Snippet_DataArrayInt_getTuple_1] -#! [Snippet_DataArrayInt_getTuple_2] - for tpl in dv: - print tpl -#! [Snippet_DataArrayInt_getTuple_2] - return - - def testExample_DataArrayInt_buildPermutationArr(self): -#! [PySnippet_DataArrayInt_buildPermutationArr_1] - a=DataArrayInt() - a.setValues([4,5,6,7,8],5,1) - b=DataArrayInt() - b.setValues([5,4,8,6,7],5,1) - c=a.buildPermutationArr(b) -#! [PySnippet_DataArrayInt_buildPermutationArr_1] - self.assertEqual([1,0,4,2,3],c.getValues()) - return - - def testExample_DataArrayInt_invertArrayO2N2N2O(self): -#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] - arr1=[2,0,4,1,5,3] - da=DataArrayInt() - da.setValues(arr1,6,1) - da2=da.invertArrayO2N2N2O(6) - expected1=[1,3,0,5,2,4] - for i in xrange(6): - self.assertEqual(expected1[i],da2.getIJ(i,0)) - pass -#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] - return - - def testExample_DataArrayInt_invertArrayN2O2O2N(self): -#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] - arr1=[2,0,4,1,5,3] - da=DataArrayInt() - da.setValues(arr1,6,1) - da2=da.invertArrayN2O2O2N(7) - expected1=[1,3,0,5,2,4,-1] - for i in xrange(6): - self.assertEqual(expected1[i],da2.getIJ(i,0)) - pass -#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] - return - - - def testExample_DataArrayDouble_getIdsInRange(self): -#! [PySnippet_DataArrayDouble_getIdsInRange_1] - da=DataArrayDouble() - da.alloc( 10, 1 ) - da[ :, :] = range(10) - da2 = da.getIdsInRange( 2.5, 6 ) -#! [PySnippet_DataArrayDouble_getIdsInRange_1] - return - - def testExample_DataArrayDouble_setPartOfValues2(self): -#! [Snippet_DataArrayDouble_setPartOfValues2_1] - da=DataArrayDouble() - da.alloc( 4, 7 ) - # - dv=DataArrayDouble() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayDouble_setPartOfValues2_1] -#! [Snippet_DataArrayDouble_setPartOfValues2_2] - da.fillWithZero() - da[ [0,1,2], [1,3] ] = dv -#! [Snippet_DataArrayDouble_setPartOfValues2_2] -#! [Snippet_DataArrayDouble_setPartOfValues2_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ [0,2,3], [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayDouble_setPartOfValues2_3] - return - - def testExample_DataArrayInt_setPartOfValues2(self): -#! [Snippet_DataArrayInt_setPartOfValues2_1] - da=DataArrayInt() - da.alloc( 4, 7 ) - # - dv=DataArrayInt() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayInt_setPartOfValues2_1] -#! [Snippet_DataArrayInt_setPartOfValues2_2] - da.fillWithZero() - da[ [0,1,2], [1,3] ] = dv -#! [Snippet_DataArrayInt_setPartOfValues2_2] -#! [Snippet_DataArrayInt_setPartOfValues2_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ [0,2,3], [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayInt_setPartOfValues2_3] - return - - def testExample_DataArrayDouble_setPartOfValues3(self): -#! [Snippet_DataArrayDouble_setPartOfValues3_1] - da=DataArrayDouble() - da.alloc( 4, 7 ) - # - dv=DataArrayDouble() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayDouble_setPartOfValues3_1] -#! [Snippet_DataArrayDouble_setPartOfValues3_2] - da.fillWithZero() - da[ 0:3, [1,3] ] = dv -#! [Snippet_DataArrayDouble_setPartOfValues3_2] -#! [Snippet_DataArrayDouble_setPartOfValues3_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ 0:4:2, [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayDouble_setPartOfValues3_3] - return - - def testExample_DataArrayInt_setPartOfValues3(self): -#! [Snippet_DataArrayInt_setPartOfValues3_1] - da=DataArrayInt() - da.alloc( 4, 7 ) - # - dv=DataArrayInt() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayInt_setPartOfValues3_1] -#! [Snippet_DataArrayInt_setPartOfValues3_2] - da.fillWithZero() - da[ 0:3, [1,3] ] = dv -#! [Snippet_DataArrayInt_setPartOfValues3_2] -#! [Snippet_DataArrayInt_setPartOfValues3_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ 0:4:2, [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayInt_setPartOfValues3_3] - return - - def testExample_DataArrayDouble_setPartOfValues1(self): -#! [Snippet_DataArrayDouble_setPartOfValues1_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - da.setInfoOnComponents( ["v1","v2","v3","v4"]) - # - dv=DataArrayDouble() - dv.alloc( 4, 1 ) - dv.iota(7) - dv.rearrange( 2 ) - dv.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayDouble_setPartOfValues1_1] -#! [Snippet_DataArrayDouble_setPartOfValues1_2] - da.fillWithZero() - da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) -#! [Snippet_DataArrayDouble_setPartOfValues1_2] -#! [Snippet_DataArrayDouble_setPartOfValues1_3] - da.fillWithZero() - da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) -#! [Snippet_DataArrayDouble_setPartOfValues1_3] -#! [Snippet_DataArrayDouble_setPartOfValues1_4] - da.fillWithZero() - da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) -#! [Snippet_DataArrayDouble_setPartOfValues1_4] -#! [Snippet_DataArrayDouble_setPartOfValues1_5] - da.fillWithZero() - da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) -#! [Snippet_DataArrayDouble_setPartOfValues1_5] -#! [Snippet_DataArrayDouble_setPartOfValues1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2, 1e-20 )) -#! [Snippet_DataArrayDouble_setPartOfValues1_6] - return - - def testExample_DataArrayInt_setPartOfValues1(self): -#! [Snippet_DataArrayInt_setPartOfValues1_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - da.setInfoOnComponents( ["v1","v2","v3","v4"]) - # - dv=DataArrayInt() - dv.alloc( 4, 1 ) - dv.iota(7) - dv.rearrange( 2 ) - dv.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayInt_setPartOfValues1_1] -#! [Snippet_DataArrayInt_setPartOfValues1_2] - da.fillWithZero() - da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) -#! [Snippet_DataArrayInt_setPartOfValues1_2] -#! [Snippet_DataArrayInt_setPartOfValues1_3] - da.fillWithZero() - da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) -#! [Snippet_DataArrayInt_setPartOfValues1_3] -#! [Snippet_DataArrayInt_setPartOfValues1_4] - da.fillWithZero() - da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) -#! [Snippet_DataArrayInt_setPartOfValues1_4] -#! [Snippet_DataArrayInt_setPartOfValues1_5] - da.fillWithZero() - da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) -#! [Snippet_DataArrayInt_setPartOfValues1_5] -#! [Snippet_DataArrayInt_setPartOfValues1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2 )) -#! [Snippet_DataArrayInt_setPartOfValues1_6] - return - - def testExample_DataArrayDouble_setPartOfValuesSimple1(self): -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2, 1e-20 )) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] - return - - def testExample_DataArrayInt_setPartOfValuesSimple1(self): -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2 )) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] - return - - def testExample_DataArrayDouble_setPartOfValuesSimple2(self): -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] - da.fillWithZero() - da[[1,2], [1,2]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] - da.fillWithZero() - da[[0,1,2,3], [1]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] - da.fillWithZero() - da[[1], [0,1,2,3]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] - da.fillWithZero() - da[[0,2], [1,3]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] - return - - def testExample_DataArrayInt_setPartOfValuesSimple2(self): -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] - da.fillWithZero() - da[[1,2], [1,2]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] - da.fillWithZero() - da[[0,1,2,3], [1]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] - da.fillWithZero() - da[[1], [0,1,2,3]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] - da.fillWithZero() - da[[0,2], [1,3]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] - return - - def testExample_DataArrayDouble_setPartOfValuesSimple3(self): -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] - da.fillWithZero() - da[[1,2], 1:3] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] - da.fillWithZero() - da[[0,1,2,3], 1:2] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] - da.fillWithZero() - da[[1], 0:4] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] - da.fillWithZero() - da[[0,2], 1:4:2] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] - return - - def testExample_DataArrayInt_setPartOfValuesSimple3(self): -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] - da.fillWithZero() - da[[1,2], 1:3] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] - da.fillWithZero() - da[[0,1,2,3], 1:2] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] - da.fillWithZero() - da[[1], 0:4] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] - da.fillWithZero() - da[[0,2], 1:4:2] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] - return - - def testExample_DataArrayDouble_setSelectedComponents(self): -#! [Snippet_DataArrayDouble_setSelectedComponents1] - array1=[1.,2., 3.,4., 5.,6.] - da=DataArrayDouble(array1,3,2) - da.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayDouble_setSelectedComponents1] -#! [Snippet_DataArrayDouble_setSelectedComponents2] - dv=DataArrayDouble() - dv.alloc( 4, 4 ) - dv.fillWithZero() - dv.setInfoOnComponents( ["v1","v2","v3","v4"]) - dv2 = dv.deepCpy() - dv.setSelectedComponents( da, [1,0] ) -#! [Snippet_DataArrayDouble_setSelectedComponents2] -#! [Snippet_DataArrayDouble_setSelectedComponents3] - dv2[:3,[1,0]] = da - self.assertTrue( dv.isEqualWithoutConsideringStr( dv2, 1e-20 )) -#! [Snippet_DataArrayDouble_setSelectedComponents3] - return - - def testExample_DataArrayInt_setSelectedComponents(self): -#! [Snippet_DataArrayInt_setSelectedComponents1] - da=DataArrayInt() - array1=[1,2, 3,4, 5,6] - da.setValues(array1,3,2) - da.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayInt_setSelectedComponents1] -#! [Snippet_DataArrayInt_setSelectedComponents2] - dv=DataArrayInt() - dv.alloc( 4, 4 ) - dv.fillWithZero() - dv.setInfoOnComponents( ["v1","v2","v3","v4"]) - dv2 = dv.deepCpy() - dv.setSelectedComponents( da, [1,0] ) -#! [Snippet_DataArrayInt_setSelectedComponents2] -#! [Snippet_DataArrayInt_setSelectedComponents3] - dv2[:3,[1,0]] = da - self.assertTrue( dv.isEqualWithoutConsideringStr( dv2 )) -#! [Snippet_DataArrayInt_setSelectedComponents3] - return - - def testExample_DataArrayDouble_getDifferentValues(self): -#! [Snippet_DataArrayDouble_getDifferentValues1] - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da=DataArrayDouble(array1,6,1) - # - dv=da.getDifferentValues(2e-1) - expected2=[2.301,1.3,0.8] - self.assertEqual(3,dv.getNbOfElems()) - for i in xrange(3): - self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14) - pass -#! [Snippet_DataArrayDouble_getDifferentValues1] - return - - def testExample_DataArrayDouble_findCommonTuples1(self): -#! [PySnippet_DataArrayDouble_findCommonTuples1] - array2=[2.3,2.3, 1.2,1.2, 1.3,1.3, 2.3,2.3, 2.301,2.301, 0.8,0.8] - da=DataArrayDouble(array2,6,2) -#! [PySnippet_DataArrayDouble_findCommonTuples1] -#! [PySnippet_DataArrayDouble_findCommonTuples2] - c,cI=da.findCommonTuples(1.01e-1) - expected3=[0,3,4,1,2] - expected4=[0,3,5] - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) -#! [PySnippet_DataArrayDouble_findCommonTuples2] - return - - def testExampleDataArrayDoubleMeldWith(self): -#! [PySnippet_DataArrayDouble_Meld1_1] - da1=DataArrayDouble() - da1.alloc(7,2) - da2=DataArrayDouble() - da2.alloc(7,1) - # - da1.fillWithValue(7.) - da2.iota(0.) - da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec") - # - da1.setInfoOnComponent(0,"c0da1") - da1.setInfoOnComponent(1,"c1da1") - da3.setInfoOnComponent(0,"c0da3") - da3.setInfoOnComponent(1,"c1da3") - da3.setInfoOnComponent(2,"c2da3") - # - da1C=da1.deepCpy() - da1.meldWith(da3) -#! [PySnippet_DataArrayDouble_Meld1_1] - - def testExampleDataArrayIntMeldWith(self): -#! [PySnippet_DataArrayInt_Meld1_1] - da1=DataArrayInt() - da1.alloc(7,2) - da2=DataArrayInt() - da2.alloc(7,1) - # - da1.fillWithValue(7) - da2.iota(0) - # - da1.setInfoOnComponent(0,"c0da1") - da1.setInfoOnComponent(1,"c1da1") - da2.setInfoOnComponent(0,"c0da2") - # - da1.meldWith(da2) -#! [PySnippet_DataArrayInt_Meld1_1] - - def testExampleDataArrayDoubleKeepSelectedComponents1(self): -#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] - arr1=[1.,2.,3.,4., # tuple 0 - 11.,12.,13.,14., # tuple 1 - 21.,22.,23.,24., # ... - 31.,32.,33.,34., - 41.,42.,43.,44.] - a1=DataArrayDouble(arr1,5,4) - a1.setInfoOnComponent(0,"a") - a1.setInfoOnComponent(1,"b") - a1.setInfoOnComponent(2,"c") - a1.setInfoOnComponent(3,"d") -#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] -#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] - arr2V=[1,2,1,2,0,0] - a2=a1.keepSelectedComponents(arr2V) -#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] - return - - def testExampleDataArrayIntKeepSelectedComponents1(self): -#! [SnippeDataArrayIntKeepSelectedComponents1_1] - arr1=[1,2,3,4, # tuple 0 - 11,12,13,14, # tuple 1 - 21,22,23,24, # - 31,32,33,34, - 41,42,43,44] - a1=DataArrayInt() - a1.setValues(arr1,5,4) - a1.setInfoOnComponent(0,"a") - a1.setInfoOnComponent(1,"b") - a1.setInfoOnComponent(2,"c") - a1.setInfoOnComponent(3,"d") -#! [SnippeDataArrayIntKeepSelectedComponents1_1] -#! [SnippeDataArrayIntKeepSelectedComponents1_2] - arr2V=[1,2,1,2,0,0] - a2=a1.keepSelectedComponents(arr2V) -#! [SnippeDataArrayIntKeepSelectedComponents1_2] -#! [SnippeDataArrayIntKeepSelectedComponents1_3] - a3=a1[:,arr2V ] -#! [SnippeDataArrayIntKeepSelectedComponents1_3] - return - - def testExampleFieldDoubleBuildSubPart1(self): - from MEDCouplingDataForTest import MEDCouplingDataForTest -#! [PySnippetFieldDoubleBuildSubPart1_1] - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1() - f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f1.setTime(2.3,5,6) - f1.setMesh(mesh1) - arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] - array=DataArrayDouble(arr1,mesh1.getNumberOfCells(),2) - f1.setArray(array) -# ! [PySnippetFieldDoubleBuildSubPart1_1] -# ! [PySnippetFieldDoubleBuildSubPart1_2] - part1=[2,1,4] - f2=f1.buildSubPart(part1) -# ! [PySnippetFieldDoubleBuildSubPart1_2] - f2.zipCoords() - self.assertEqual(3,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - expected1=[5.,105.,4.,104.,7.,107.] - for i in xrange(6): - self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12) - pass - self.assertEqual(3,f2.getMesh().getNumberOfCells()) - self.assertEqual(6,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(13,m2C.getMeshLength()) - expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] - self.assertEqual(expected3,list(m2C.getNodalConnectivity().getValues())) - expected4=[0,4,8,13] - self.assertEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())) - # Test with field on nodes. -# ! [PySnippetFieldDoubleBuildSubPart1_3] - f1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) - f1.setTime(2.3,5,6) - f1.setMesh(mesh1) - arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] - array=DataArrayDouble(arr2,mesh1.getNumberOfNodes(),2) - f1.setArray(array) -# ! [PySnippetFieldDoubleBuildSubPart1_3] -# ! [PySnippetFieldDoubleBuildSubPart1_4] - part2=[1,2] - f2=f1.buildSubPart(part2) -# ! [PySnippetFieldDoubleBuildSubPart1_4] - self.assertEqual(4,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - expected5=[4.,104.,5.,105.,7.,107.,8.,108.] - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12) - pass - self.assertEqual(2,f2.getMesh().getNumberOfCells()) - self.assertEqual(4,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(8,m2C.getMeshLength()) - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - self.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:]) - self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4]) - self.assertEqual(expected4[:3],[int(i) for i in m2C.getNodalConnectivityIndex()]) - #idem previous because nodes of cell#4 are not fully present in part3 - part3=[1,2] - arrr=DataArrayInt() - arrr.setValues(part3,2,1) - f2=f1.buildSubPart(arrr) - self.assertEqual(4,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12) - pass - self.assertEqual(2,f2.getMesh().getNumberOfCells()) - self.assertEqual(4,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(8,m2C.getMeshLength()) - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - self.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:8]) - self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4]) - self.assertEqual(expected4[:3],m2C.getNodalConnectivityIndex().getValues()) - part4=[1,2,4] - f2=f1.buildSubPart(part4) - self.assertEqual(6,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] - for i in xrange(12): - self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12) - pass - self.assertEqual(3,f2.getMesh().getNumberOfCells()) - self.assertEqual(6,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(13,m2C.getMeshLength()) - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - self.assertEqual(expected3[0:4],m2C.getNodalConnectivity().getValues()[4:8]) - self.assertEqual(expected3[4:8],m2C.getNodalConnectivity().getValues()[0:4]) - self.assertEqual(expected3[8:13],m2C.getNodalConnectivity().getValues()[8:13]) - self.assertEqual(expected4,m2C.getNodalConnectivityIndex().getValues()) - # previous line equivalent to - self.assertEqual(expected4,[int(i) for i in m2C.getNodalConnectivityIndex()]) - return - - def testExampleUMeshStdBuild1(self): -# ! [PySnippetUMeshStdBuild1_1] - coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] - nodalConnPerCell=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] -# ! [PySnippetUMeshStdBuild1_1] -# ! [PySnippetUMeshStdBuild1_2] - mesh=MEDCouplingUMesh("My2DMesh",2) -# ! [PySnippetUMeshStdBuild1_2] -# ! [PySnippetUMeshStdBuild1_3] - mesh.allocateCells(5)#You can put more than 5 if you want but not less. - mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[:4]) - mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[4:7]) - mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[7:10]) - mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[10:14]) - mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[14:]) - mesh.finishInsertingCells() -# ! [PySnippetUMeshStdBuild1_3] -# ! [PySnippetUMeshStdBuild1_4] - coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. -# ! [PySnippetUMeshStdBuild1_4] -# ! [PySnippetUMeshStdBuild1_5] -# ! [PySnippetUMeshStdBuild1_5] - mesh.checkCoherency() - return - - def testExampleCMeshStdBuild1(self): -# ! [PySnippetCMeshStdBuild1_1] - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] # 9 values along X - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] # 7 values along Y - arrX=DataArrayDouble(XCoords) - arrX.setInfoOnComponent(0,"X [m]") - arrY=DataArrayDouble(YCoords) - arrY.setInfoOnComponent(0,"Y [m]") -# ! [PySnippetCMeshStdBuild1_1] -# ! [PySnippetCMeshStdBuild1_2] - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetCMeshStdBuild1_2] -# ! [PySnippetCMeshStdBuild1_3] - self.assertEqual(8*6,mesh.getNumberOfCells()) - self.assertEqual(9*7,mesh.getNumberOfNodes()) - self.assertEqual(2,mesh.getSpaceDimension()) - self.assertEqual(2,mesh.getMeshDimension()) -# ! [PySnippetCMeshStdBuild1_3] - mesh=MEDCouplingCMesh("My2D_CMesh") -# ! [PySnippetCMeshStdBuild1_2bis] - mesh.setCoordsAt(0,arrX) - mesh.setCoordsAt(1,arrY) -# ! [PySnippetCMeshStdBuild1_2bis] - self.assertEqual(8*6,mesh.getNumberOfCells()) - self.assertEqual(9*7,mesh.getNumberOfNodes()) - self.assertEqual(2,mesh.getSpaceDimension()) - self.assertEqual(2,mesh.getMeshDimension()) -# ! [PySnippetCMeshStdBuild1_4] -# ! [PySnippetCMeshStdBuild1_4] - return - - def testExampleUMeshAdvBuild1(self): -# ! [PySnippetUMeshAdvBuild1_1] - coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] - nodalConnPerCell=[4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4] - nodalConnPerCellIndex=[0,5,9,13,18,23] -# ! [PySnippetUMeshAdvBuild1_1] -# ! [PySnippetUMeshAdvBuild1_2] - mesh=MEDCouplingUMesh("My2DMesh",2) -# ! [PySnippetUMeshAdvBuild1_2] -# ! [PySnippetUMeshAdvBuild1_3] - nodalConn=DataArrayInt(nodalConnPerCell,23,1) - nodalConnI=DataArrayInt(nodalConnPerCellIndex,6,1) - mesh.setConnectivity(nodalConn,nodalConnI,True) -# ! [PySnippetUMeshAdvBuild1_3] -# ! [PySnippetUMeshAdvBuild1_4] - coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. -# ! [PySnippetUMeshAdvBuild1_4] -# ! [PySnippetUMeshAdvBuild1_5] -# ! [PySnippetUMeshAdvBuild1_5] - mesh.checkCoherency() - return - - def testExampleDataArrayBuild1(self): -# ! [PySnippetDataArrayBuild1_0] - dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] -# ! [PySnippetDataArrayBuild1_0] -# ! [PySnippetDataArrayBuild1_1] - arrayDouble=DataArrayDouble() - arrayDouble.setValues(dataDouble,5,3)# 5 tuples containing each 3 components -# ! [PySnippetDataArrayBuild1_1] -# ! [PySnippetDataArrayBuild1_1bis] - arrayDouble=DataArrayDouble(dataDouble,5,3) -# ! [PySnippetDataArrayBuild1_1bis] -# ! [PySnippetDataArrayBuild1_2] - dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24] -# ! [PySnippetDataArrayBuild1_2] -# ! [PySnippetDataArrayBuild1_3] - arrayInt=DataArrayInt() - arrayInt.setValues(dataInt,5,3)# 5 tuples containing each 3 components -# ! [PySnippetDataArrayBuild1_3] -# ! [PySnippetDataArrayBuild1_3bis] - arrayInt=DataArrayInt(dataInt,5,3) -# ! [PySnippetDataArrayBuild1_3bis] - return - - def testExampleFieldDoubleBuild1(self): - XCoords=[-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.07,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild1_1] - fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) - fieldOnCells.setName("MyTensorFieldOnCellNoTime") - fieldOnCells.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnCells.getMesh().getNumberOfCells(),9) # Implicitely fieldOnCells will be a 9 components field. - array.fillWithValue(7.) - fieldOnCells.setArray(array) - # fieldOnCells is now usable - # ... -# ! [PySnippetFieldDoubleBuild1_1] -# ! [PySnippetFieldDoubleBuild1_2] - f1=mesh.fillFromAnalytic(ON_CELLS,1,"x*x+y*y*3+2.*x") # f1 is scalar - f2=mesh.fillFromAnalytic(ON_CELLS,1,"cos(x+y/x)") # f2 is scalar too - f2bis=mesh.fillFromAnalytic(ON_CELLS,2,"x*x*IVec+3*y*JVec") # f2bis is a vectors field - f3=f1+f2 # f3 scalar - f4=f3/f2 # f4 scalar - f2bis.applyFunc(1,"sqrt(x*x+y*y)") # f2bis becomes scalar - f5=f2bis*f4 # f5 scalar - pos1=[0.48,0.38] - res=f4.getValueOn(pos1) # f4 is scalar so the returned value is of size 1. - # ... -# ! [PySnippetFieldDoubleBuild1_2] -# ! [PySnippetFieldDoubleBuild1_3] -# ! [PySnippetFieldDoubleBuild1_3] - return - - def testExampleFieldDoubleBuild2(self): - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild2_1] - fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,NO_TIME) - fieldOnNodes.setName("MyScalarFieldOnNodeNoTime") - fieldOnNodes.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),1) # Implicitely fieldOnNodes will be a 1 component field. - array.fillWithValue(7.) - fieldOnNodes.setArray(array) - # fieldOnNodes is now usable - # ... -# ! [PySnippetFieldDoubleBuild2_1] - return - - def testExampleFieldDoubleBuild3(self): - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild3_1] - fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - fieldOnCells.setName("MyTensorFieldOnCellNoTime") - fieldOnCells.setTimeUnit("ms") # Time unit is ms. - fieldOnCells.setTime(4.22,2,-1) # Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1 - fieldOnCells.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnCells.getMesh().getNumberOfCells(),2) # Implicitely fieldOnCells will be a 2 components field. - array.fillWithValue(7.) - fieldOnCells.setArray(array) - # fieldOnCells is now usable - # ... -# ! [PySnippetFieldDoubleBuild3_1] - return - - def testExampleFieldDoubleBuild4(self): - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild4_1] - fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,CONST_ON_TIME_INTERVAL) - fieldOnNodes.setName("MyVecFieldOnNodeWithConstTime") - fieldOnNodes.setTimeUnit("ms") # Time unit is ms. - fieldOnNodes.setStartTime(4.22,2,-1) - fieldOnNodes.setEndTime(6.44,4,-1)# fieldOnNodes is defined in interval [4.22 ms,6.44 ms] - fieldOnNodes.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),3) # Implicitely fieldOnNodes will be a 3 components field. - array.fillWithValue(7.) - fieldOnNodes.setArray(array) - # fieldOnNodes is now usable - # ... -# ! [PySnippetFieldDoubleBuild4_1] - return - - def testExampleDataArrayApplyFunc1(self): -# ! [PySnippetDataArrayApplyFunc1_1] - d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2) - self.assertRaises(InterpKernelException,d.applyFunc,"x*y") -# ! [PySnippetDataArrayApplyFunc1_1] -# ! [PySnippetDataArrayApplyFunc1_2] - d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2) - d1=d.applyFunc("smth*smth") - self.assertTrue(d1.isEqual(DataArrayDouble([1.,4.,121.,144.,441.,484.,961.,1681.],4,2),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_2] -# ! [PySnippetDataArrayApplyFunc1_3] - d2=d.applyFunc(2,"smth1*IVec+2*smth2*JVec") - self.assertTrue(d2.isEqual(DataArrayDouble([1.,4.,11.,24.,21.,44.,31.,82.],4,2),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_3] -# ! [PySnippetDataArrayApplyFunc1_4] - dd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3) -# ! [PySnippetDataArrayApplyFunc1_4] -# ! [PySnippetDataArrayApplyFunc1_5] - dd1=dd.applyFunc(1,"f+sqrt(g)+h") - self.assertTrue(dd1.isEqual(DataArrayDouble([6.,36.,66.,96.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_5] -# ! [PySnippetDataArrayApplyFunc1_6] - dd2=dd.applyFunc(1,"a+0.*b+c") - self.assertTrue(dd2.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_6] -# ! [PySnippetDataArrayApplyFunc1_7] - ddd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3) - ddd.setInfoOnComponents(["Y [m]","AA [m/s]","GG [MW]"]) -# ! [PySnippetDataArrayApplyFunc1_7] -# ! [PySnippetDataArrayApplyFunc1_8] - ddd1=ddd.applyFunc2(1,"Y+GG") - self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_8] -# ! [PySnippetDataArrayApplyFunc1_9] - ddd1=ddd.applyFunc3(1,["X","Y","Z"],"X+Z") - self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_9] - return - - pass - -unittest.main() diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i b/medtool/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i deleted file mode 100644 index bf4732b14..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::New; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::deepCpy; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clone; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePartRange; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getOffsetArr; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getLocalizationOfDiscValues; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getMeasureField; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getValueOnMulti; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::computeTupleIdsToSelectFromCellIds; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec; - -namespace ParaMEDMEM -{ - class MEDCouplingFieldDiscretization : public RefCountObject, public TimeLabel - { - public: - static MEDCouplingFieldDiscretization *New(TypeOfField type) throw(INTERP_KERNEL::Exception); - double getPrecision() const throw(INTERP_KERNEL::Exception); - void setPrecision(double val) throw(INTERP_KERNEL::Exception); - static TypeOfField GetTypeOfFieldFromStringRepr(const std::string& repr) throw(INTERP_KERNEL::Exception); - virtual TypeOfField getEnum() const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDiscretization *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDiscretization *clone() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); - virtual std::string getStringRepr() const throw(INTERP_KERNEL::Exception); - virtual const char *getRepr() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); - virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); - virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const throw(INTERP_KERNEL::Exception); - virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); - virtual void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); - virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); - virtual int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); - virtual int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); - virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - %extend - { - virtual MEDCouplingFieldDiscretization *clonePart(PyObject *li) - { - int sz=0,sw=-1,val1=-1; - std::vector val2; - const int *inp=convertObjToPossibleCpp1_Safe(li,sw,sz,val1,val2); - return self->clonePart(inp,inp+sz); - } - - virtual PyObject *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - int bb,ee,ss; - MEDCouplingMesh *ret0=self->buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,bb,ee,ss,ret1); - PyObject *res=PyTuple_New(2); - PyTuple_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - if(ret1) - PyTuple_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - else - { - PyObject *res1=PySlice_New(PyInt_FromLong(bb),PyInt_FromLong(ee),PyInt_FromLong(ss)); - PyTuple_SetItem(res,1,res1); - } - return res; - } - - virtual int getNumberOfTuplesExpectedRegardingCode(PyObject *code, PyObject *idsPerType) const throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - convertPyToNewIntArr4(code,1,3,inp0); - std::vector inp1; - convertFromPyObjVectorOfObj(idsPerType,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",inp1); - return self->getNumberOfTuplesExpectedRegardingCode(inp0,inp1); - } - - virtual PyObject *computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, PyObject *tupleIds) const throw(INTERP_KERNEL::Exception) - { - std::vector vVal; int iVal=-1; - int sz=-1,sw=0; - const int *tupleIdsBg=convertObjToPossibleCpp1_Safe(tupleIds,sw,sz,iVal,vVal); - if(sw==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::computeMeshRestrictionFromTupleIds : none parameter in input !"); - DataArrayInt *ret0=0,*ret1=0; - self->computeMeshRestrictionFromTupleIds(mesh,tupleIdsBg,tupleIdsBg+sz,ret0,ret1); - PyObject *pyRet=PyTuple_New(2); - PyTuple_SetItem(pyRet,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(pyRet,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return pyRet; - } - - virtual PyObject *normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::normL1 : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL1(mesh,arr,tmp); - return convertDblArrToPyList(tmp,sz); - } - - virtual PyObject *normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::normL2 : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL2(mesh,arr,tmp); - return convertDblArrToPyList(tmp,sz); - } - - virtual PyObject *integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::integral : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->integral(mesh,arr,isWAbs,tmp); - return convertDblArrToPyList(tmp,sz); - } - - virtual PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - self->getCellIdsHavingGaussLocalization(locId,tmp); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)tmp.size(),1); - std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, PyObject *li, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->setGaussLocalizationOnCells(m,tmp,((int *)tmp)+size,refCoo,gsCoo,wg); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->setGaussLocalizationOnCells(m,da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),refCoo,gsCoo,wg); - } - } - - virtual PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) - { - std::set ret=self->getGaussLocalizationIdsOfOneType(type); - return convertIntArrToPyList3(ret); - } - - virtual PyObject *getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, PyObject *sl) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDiscretization::getValueOn : no underlying mesh !"); - int spaceDim=mesh->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingFieldDiscretization::getValueOn : "; - const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - INTERP_KERNEL::AutoPtr res(new double[spaceDim]); - self->getValueOn(arr,mesh,spaceLoc,res); - return convertDblArrToPyList(res,spaceDim); - } - - virtual PyObject *getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::getValueOnPos : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOnPos(arr,mesh,i,j,k,res); - return convertDblArrToPyList(res,sz); - } - - virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, PyObject *loc) const throw(INTERP_KERNEL::Exception) - { - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap MEDCouplingFieldDiscretization::getValueOnMulti : null input mesh !"); - // - int sw,nbPts; - double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector v3; - const double *inp=convertObjToPossibleCpp5_Safe2(loc,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDouble::getValueOnMulti", - mesh->getSpaceDimension(),true,nbPts); - return self->getValueOnMulti(arr,mesh,inp,nbPts); - } - - virtual void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *ids(convertObjToPossibleCpp1_Safe(li,sw,sz,v0,v1)); - self->renumberCells(ids,check); - } - - virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, PyObject *arrays, - PyObject *old2New, bool check) throw(INTERP_KERNEL::Exception) - { - std::vector input1; - convertFromPyObjVectorOfObj(arrays,SWIGTYPE_p_ParaMEDMEM__DataArray,"DataArray",input1); - // - int sw,sz(-1); - int v0; std::vector v1; - const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); - // - self->renumberArraysForCell(mesh,input1,old2NewBg,check); - } - - virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, PyObject *cellIds) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *cellIdsBg(convertObjToPossibleCpp1_Safe(cellIds,sw,sz,v0,v1)); - return self->computeTupleIdsToSelectFromCellIds(mesh,cellIdsBg,cellIdsBg+sz); - } - - virtual PyObject *buildSubMeshData(const MEDCouplingMesh *mesh, PyObject *ids) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *idsBg(convertObjToPossibleCpp1_Safe(ids,sw,sz,v0,v1)); - DataArrayInt *di(0); - MEDCouplingMesh *ret0=self->buildSubMeshData(mesh,idsBg,idsBg+sz,di); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(di),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - virtual void renumberValuesOnNodes(double epsOnVals, PyObject *old2New, int newNbOfNodes, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); - self->renumberValuesOnNodes(epsOnVals,old2NewBg,newNbOfNodes,arr); - } - - virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, PyObject *old2New, int newSz, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); - self->renumberValuesOnCells(epsOnVals,mesh,old2NewBg,newSz,arr); - } - - virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, PyObject *new2old, int newSz, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *new2oldBg(convertObjToPossibleCpp1_Safe(new2old,sw,sz,v0,v1)); - self->renumberValuesOnCellsR(mesh,new2oldBg,newSz,arr); - } - } - }; - - class MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization - { - }; - - class MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization - { - }; - - class MEDCouplingFieldDiscretizationP1 : public MEDCouplingFieldDiscretizationOnNodes - { - }; - - class MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization - { - public: - void setArrayOfDiscIds(const DataArrayInt *adids) throw(INTERP_KERNEL::Exception); - void checkNoOrphanCells() const throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getArrayOfDiscIds() const - { - DataArrayInt *ret=const_cast(self->getArrayOfDiscIds()); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *splitIntoSingleGaussDicrPerCellType() const throw(INTERP_KERNEL::Exception) - { - std::vector ret1; - std::vector ret0=self->splitIntoSingleGaussDicrPerCellType(ret1); - std::size_t sz=ret0.size(); - PyObject *pyRet=PyTuple_New(2); - PyObject *pyRet0=PyList_New((int)sz); - PyObject *pyRet1=PyList_New((int)sz); - for(std::size_t i=0;icomputeVectorOfCoefficients(mesh,arr,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - - PyObject *computeInverseMatrix(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - int ret1(-1),ret2(-1); - DataArrayDouble *ret0=self->computeInverseMatrix(mesh,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); - return ret; - } - - PyObject *computeMatrix(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - int ret1(-1),ret2(-1); - DataArrayDouble *ret0=self->computeMatrix(mesh,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); - return ret; - } - - PyObject *computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, PyObject *locs) const throw(INTERP_KERNEL::Exception) - { - if(!mesh) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts : input mesh is empty !"); - int sw,nbPts; - double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector v3; - const double *inp=convertObjToPossibleCpp5_Safe2(locs,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts", - mesh->getSpaceDimension(),true,nbPts); - // - int ret1(-1); - DataArrayDouble *ret0=self->computeEvaluationMatrixOnGivenPts(mesh,inp,nbPts,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - - void operateOnDenseMatrix(int spaceDimension, DataArrayDouble *myMatrix) const throw(INTERP_KERNEL::Exception) - { - if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); - self->operateOnDenseMatrix(spaceDimension,myMatrix->getNumberOfTuples(),myMatrix->getPointer()); - } - - PyObject *performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int ret1(-1); - DataArrayDouble *ret0(self->performDrift(matr,arr,ret1)); - PyObject *res(PyTuple_New(2)); - PyTuple_SetItem(res,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0)); - PyTuple_SetItem(res,1,PyInt_FromLong(ret1)); - return res; - } - - static PyObject *PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) - { - int ret1(-1); - DataArrayDouble *ret0(MEDCouplingFieldDiscretizationKriging::PerformDriftRect(matr,arr,ret1)); - PyObject *res(PyTuple_New(2)); - PyTuple_SetItem(res,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0)); - PyTuple_SetItem(res,1,PyInt_FromLong(ret1)); - return res; - } - - static void OperateOnDenseMatrixH3(DataArrayDouble *myMatrix) throw(INTERP_KERNEL::Exception) - { - if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3 : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); - MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3(myMatrix->getNumberOfTuples(),myMatrix->getPointer()); - } - - static void OperateOnDenseMatrixH2Ln(DataArrayDouble *myMatrix) throw(INTERP_KERNEL::Exception) - { - if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); - MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln(myMatrix->getNumberOfTuples(),myMatrix->getPointer()); - } - } - }; -} diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingFinalize.i b/medtool/src/MEDCoupling_Swig/MEDCouplingFinalize.i deleted file mode 100644 index 393dec9c8..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingFinalize.i +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%pythoncode %{ -InterpKernelException.__reduce__=INTERPKERNELExceptionReduce -DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) -DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd -DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub -DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul -DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv -DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow - -DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) -DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd -DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub -DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul -DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv -DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod -DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow - -MEDCouplingFieldDouble.__iadd__=ParaMEDMEMMEDCouplingFieldDoubleIadd -MEDCouplingFieldDouble.__isub__=ParaMEDMEMMEDCouplingFieldDoubleIsub -MEDCouplingFieldDouble.__imul__=ParaMEDMEMMEDCouplingFieldDoubleImul -MEDCouplingFieldDouble.__idiv__=ParaMEDMEMMEDCouplingFieldDoubleIdiv -MEDCouplingFieldDouble.__ipow__=ParaMEDMEMMEDCouplingFieldDoubleIpow - -DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd -DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub -DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul -DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv - -DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd -DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub -DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul -DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv -DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod - -DenseMatrix.__iadd__=ParaMEDMEMDenseMatrixIadd -DenseMatrix.__isub__=ParaMEDMEMDenseMatrixIsub - -MEDCouplingUMesh.__new__=classmethod(ParaMEDMEMMEDCouplingUMeshnew) -MEDCoupling1DGTUMesh.__new__=classmethod(ParaMEDMEMMEDCoupling1DGTUMeshnew) -MEDCoupling1SGTUMesh.__new__=classmethod(ParaMEDMEMMEDCoupling1SGTUMeshnew) -MEDCouplingCurveLinearMesh.__new__=classmethod(ParaMEDMEMMEDCouplingCurveLinearMeshnew) -MEDCouplingCMesh.__new__=classmethod(ParaMEDMEMMEDCouplingCMeshnew) -MEDCouplingIMesh.__new__=classmethod(ParaMEDMEMMEDCouplingIMeshnew) -MEDCouplingExtrudedMesh.__new__=classmethod(ParaMEDMEMMEDCouplingExtrudedMeshnew) -MEDCouplingFieldDouble.__new__=classmethod(ParaMEDMEMMEDCouplingFieldDoublenew) - -del INTERPKERNELExceptionReduce -del ParaMEDMEMDataArrayDoublenew -del ParaMEDMEMDataArrayDoubleIadd -del ParaMEDMEMDataArrayDoubleIsub -del ParaMEDMEMDataArrayDoubleImul -del ParaMEDMEMDataArrayDoubleIdiv -del ParaMEDMEMMEDCouplingFieldDoubleIadd -del ParaMEDMEMMEDCouplingFieldDoubleIsub -del ParaMEDMEMMEDCouplingFieldDoubleImul -del ParaMEDMEMMEDCouplingFieldDoubleIdiv -del ParaMEDMEMMEDCouplingFieldDoubleIpow -del ParaMEDMEMDataArrayIntnew -del ParaMEDMEMDataArrayIntIadd -del ParaMEDMEMDataArrayIntIsub -del ParaMEDMEMDataArrayIntImul -del ParaMEDMEMDataArrayIntIdiv -del ParaMEDMEMDataArrayIntImod -del ParaMEDMEMDataArrayDoubleTupleIadd -del ParaMEDMEMDataArrayDoubleTupleIsub -del ParaMEDMEMDataArrayDoubleTupleImul -del ParaMEDMEMDataArrayDoubleTupleIdiv -del ParaMEDMEMDataArrayIntTupleIadd -del ParaMEDMEMDataArrayIntTupleIsub -del ParaMEDMEMDataArrayIntTupleImul -del ParaMEDMEMDataArrayIntTupleIdiv -del ParaMEDMEMDataArrayIntTupleImod -del ParaMEDMEMDenseMatrixIadd -del ParaMEDMEMDenseMatrixIsub -del ParaMEDMEMMEDCouplingUMeshnew -del ParaMEDMEMMEDCoupling1DGTUMeshnew -del ParaMEDMEMMEDCoupling1SGTUMeshnew -del ParaMEDMEMMEDCouplingCurveLinearMeshnew -del ParaMEDMEMMEDCouplingCMeshnew -del ParaMEDMEMMEDCouplingIMeshnew -del ParaMEDMEMMEDCouplingExtrudedMeshnew -del ParaMEDMEMMEDCouplingFieldDoublenew -%} diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/medtool/src/MEDCoupling_Swig/MEDCouplingMemArray.i deleted file mode 100644 index 3e4010867..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ /dev/null @@ -1,6160 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -//////////////////// -%typemap(out) ParaMEDMEM::DataArray* -{ - $result=convertDataArray($1,$owner); -} - -%typemap(out) DataArray* -{ - $result=convertDataArray($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::DataArrayChar* -{ - $result=convertDataArrayChar($1,$owner); -} - -%typemap(out) DataArrayChar* -{ - $result=convertDataArrayChar($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -%newobject ParaMEDMEM::DataArray::deepCpy; -%newobject ParaMEDMEM::DataArray::selectByTupleRanges; -%newobject ParaMEDMEM::DataArray::selectByTupleId; -%newobject ParaMEDMEM::DataArray::selectByTupleIdSafe; -%newobject ParaMEDMEM::DataArray::selectByTupleId2; -%newobject ParaMEDMEM::DataArray::Aggregate; -%newobject ParaMEDMEM::DataArrayInt::New; -%newobject ParaMEDMEM::DataArrayInt::__iter__; -%newobject ParaMEDMEM::DataArrayInt::convertToDblArr; -%newobject ParaMEDMEM::DataArrayInt::performCpy; -%newobject ParaMEDMEM::DataArrayInt::substr; -%newobject ParaMEDMEM::DataArrayInt::changeNbOfComponents; -%newobject ParaMEDMEM::DataArrayInt::accumulatePerChunck; -%newobject ParaMEDMEM::DataArrayInt::checkAndPreparePermutation; -%newobject ParaMEDMEM::DataArrayInt::transformWithIndArrR; -%newobject ParaMEDMEM::DataArrayInt::renumber; -%newobject ParaMEDMEM::DataArrayInt::renumberR; -%newobject ParaMEDMEM::DataArrayInt::renumberAndReduce; -%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O; -%newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N; -%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2OBis; -%newobject ParaMEDMEM::DataArrayInt::getIdsEqual; -%newobject ParaMEDMEM::DataArrayInt::getIdsNotEqual; -%newobject ParaMEDMEM::DataArrayInt::getIdsEqualList; -%newobject ParaMEDMEM::DataArrayInt::getIdsNotEqualList; -%newobject ParaMEDMEM::DataArrayInt::getIdsEqualTuple; -%newobject ParaMEDMEM::DataArrayInt::sumPerTuple; -%newobject ParaMEDMEM::DataArrayInt::negate; -%newobject ParaMEDMEM::DataArrayInt::computeAbs; -%newobject ParaMEDMEM::DataArrayInt::getIdsInRange; -%newobject ParaMEDMEM::DataArrayInt::getIdsNotInRange; -%newobject ParaMEDMEM::DataArrayInt::getIdsStrictlyNegative; -%newobject ParaMEDMEM::DataArrayInt::Aggregate; -%newobject ParaMEDMEM::DataArrayInt::AggregateIndexes; -%newobject ParaMEDMEM::DataArrayInt::Meld; -%newobject ParaMEDMEM::DataArrayInt::Add; -%newobject ParaMEDMEM::DataArrayInt::Substract; -%newobject ParaMEDMEM::DataArrayInt::Multiply; -%newobject ParaMEDMEM::DataArrayInt::Divide; -%newobject ParaMEDMEM::DataArrayInt::Pow; -%newobject ParaMEDMEM::DataArrayInt::BuildUnion; -%newobject ParaMEDMEM::DataArrayInt::BuildIntersection; -%newobject ParaMEDMEM::DataArrayInt::Range; -%newobject ParaMEDMEM::DataArrayInt::fromNoInterlace; -%newobject ParaMEDMEM::DataArrayInt::toNoInterlace; -%newobject ParaMEDMEM::DataArrayInt::buildComplement; -%newobject ParaMEDMEM::DataArrayInt::buildUnion; -%newobject ParaMEDMEM::DataArrayInt::buildSubstraction; -%newobject ParaMEDMEM::DataArrayInt::buildSubstractionOptimized; -%newobject ParaMEDMEM::DataArrayInt::buildIntersection; -%newobject ParaMEDMEM::DataArrayInt::buildUnique; -%newobject ParaMEDMEM::DataArrayInt::buildUniqueNotSorted; -%newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex; -%newobject ParaMEDMEM::DataArrayInt::buildExplicitArrByRanges; -%newobject ParaMEDMEM::DataArrayInt::buildExplicitArrOfSliceOnScaledArr; -%newobject ParaMEDMEM::DataArrayInt::findRangeIdForEachTuple; -%newobject ParaMEDMEM::DataArrayInt::findIdInRangeForEachTuple; -%newobject ParaMEDMEM::DataArrayInt::duplicateEachTupleNTimes; -%newobject ParaMEDMEM::DataArrayInt::buildPermutationArr; -%newobject ParaMEDMEM::DataArrayInt::buildPermArrPerLevel; -%newobject ParaMEDMEM::DataArrayInt::getDifferentValues; -%newobject ParaMEDMEM::DataArrayInt::FindPermutationFromFirstToSecond; -%newobject ParaMEDMEM::DataArrayInt::CheckAndPreparePermutation; -%newobject ParaMEDMEM::DataArrayInt::__neg__; -%newobject ParaMEDMEM::DataArrayInt::__add__; -%newobject ParaMEDMEM::DataArrayInt::__radd__; -%newobject ParaMEDMEM::DataArrayInt::__sub__; -%newobject ParaMEDMEM::DataArrayInt::__rsub__; -%newobject ParaMEDMEM::DataArrayInt::__mul__; -%newobject ParaMEDMEM::DataArrayInt::__rmul__; -%newobject ParaMEDMEM::DataArrayInt::__div__; -%newobject ParaMEDMEM::DataArrayInt::__rdiv__; -%newobject ParaMEDMEM::DataArrayInt::__mod__; -%newobject ParaMEDMEM::DataArrayInt::__rmod__; -%newobject ParaMEDMEM::DataArrayInt::__pow__; -%newobject ParaMEDMEM::DataArrayInt::__rpow__; -%newobject ParaMEDMEM::DataArrayIntTuple::buildDAInt; -%newobject ParaMEDMEM::DataArrayChar::convertToIntArr; -%newobject ParaMEDMEM::DataArrayChar::renumber; -%newobject ParaMEDMEM::DataArrayChar::renumberR; -%newobject ParaMEDMEM::DataArrayChar::renumberAndReduce; -%newobject ParaMEDMEM::DataArrayChar::changeNbOfComponents; -%newobject ParaMEDMEM::DataArrayChar::getIdsEqual; -%newobject ParaMEDMEM::DataArrayChar::getIdsNotEqual; -%newobject ParaMEDMEM::DataArrayChar::Aggregate; -%newobject ParaMEDMEM::DataArrayChar::Meld; -%newobject ParaMEDMEM::DataArrayByte::New; -%newobject ParaMEDMEM::DataArrayByte::__iter__; -%newobject ParaMEDMEM::DataArrayByte::performCpy; -%newobject ParaMEDMEM::DataArrayByteTuple::buildDAByte; -%newobject ParaMEDMEM::DataArrayChar::substr; -%newobject ParaMEDMEM::DataArrayAsciiChar::New; -%newobject ParaMEDMEM::DataArrayAsciiChar::__iter__; -%newobject ParaMEDMEM::DataArrayAsciiChar::performCpy; -%newobject ParaMEDMEM::DataArrayAsciiCharTuple::buildDAAsciiChar; -%newobject ParaMEDMEM::DataArrayDouble::New; -%newobject ParaMEDMEM::DataArrayDouble::__iter__; -%newobject ParaMEDMEM::DataArrayDouble::convertToIntArr; -%newobject ParaMEDMEM::DataArrayDouble::performCpy; -%newobject ParaMEDMEM::DataArrayDouble::Aggregate; -%newobject ParaMEDMEM::DataArrayDouble::Meld; -%newobject ParaMEDMEM::DataArrayDouble::Dot; -%newobject ParaMEDMEM::DataArrayDouble::CrossProduct; -%newobject ParaMEDMEM::DataArrayDouble::Add; -%newobject ParaMEDMEM::DataArrayDouble::Substract; -%newobject ParaMEDMEM::DataArrayDouble::Multiply; -%newobject ParaMEDMEM::DataArrayDouble::Divide; -%newobject ParaMEDMEM::DataArrayDouble::Pow; -%newobject ParaMEDMEM::DataArrayDouble::substr; -%newobject ParaMEDMEM::DataArrayDouble::changeNbOfComponents; -%newobject ParaMEDMEM::DataArrayDouble::accumulatePerChunck; -%newobject ParaMEDMEM::DataArrayDouble::getIdsInRange; -%newobject ParaMEDMEM::DataArrayDouble::getIdsNotInRange; -%newobject ParaMEDMEM::DataArrayDouble::negate; -%newobject ParaMEDMEM::DataArrayDouble::computeAbs; -%newobject ParaMEDMEM::DataArrayDouble::applyFunc; -%newobject ParaMEDMEM::DataArrayDouble::applyFunc2; -%newobject ParaMEDMEM::DataArrayDouble::applyFunc3; -%newobject ParaMEDMEM::DataArrayDouble::doublyContractedProduct; -%newobject ParaMEDMEM::DataArrayDouble::determinant; -%newobject ParaMEDMEM::DataArrayDouble::eigenValues; -%newobject ParaMEDMEM::DataArrayDouble::eigenVectors; -%newobject ParaMEDMEM::DataArrayDouble::inverse; -%newobject ParaMEDMEM::DataArrayDouble::trace; -%newobject ParaMEDMEM::DataArrayDouble::deviator; -%newobject ParaMEDMEM::DataArrayDouble::magnitude; -%newobject ParaMEDMEM::DataArrayDouble::maxPerTuple; -%newobject ParaMEDMEM::DataArrayDouble::sumPerTuple; -%newobject ParaMEDMEM::DataArrayDouble::computeBBoxPerTuple; -%newobject ParaMEDMEM::DataArrayDouble::buildEuclidianDistanceDenseMatrix; -%newobject ParaMEDMEM::DataArrayDouble::buildEuclidianDistanceDenseMatrixWith; -%newobject ParaMEDMEM::DataArrayDouble::renumber; -%newobject ParaMEDMEM::DataArrayDouble::renumberR; -%newobject ParaMEDMEM::DataArrayDouble::renumberAndReduce; -%newobject ParaMEDMEM::DataArrayDouble::fromNoInterlace; -%newobject ParaMEDMEM::DataArrayDouble::toNoInterlace; -%newobject ParaMEDMEM::DataArrayDouble::fromPolarToCart; -%newobject ParaMEDMEM::DataArrayDouble::fromCylToCart; -%newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart; -%newobject ParaMEDMEM::DataArrayDouble::getDifferentValues; -%newobject ParaMEDMEM::DataArrayDouble::findClosestTupleId; -%newobject ParaMEDMEM::DataArrayDouble::computeNbOfInteractionsWith; -%newobject ParaMEDMEM::DataArrayDouble::duplicateEachTupleNTimes; -%newobject ParaMEDMEM::DataArrayDouble::__neg__; -%newobject ParaMEDMEM::DataArrayDouble::__radd__; -%newobject ParaMEDMEM::DataArrayDouble::__rsub__; -%newobject ParaMEDMEM::DataArrayDouble::__rmul__; -%newobject ParaMEDMEM::DataArrayDouble::__rdiv__; -%newobject ParaMEDMEM::DataArrayDouble::__pow__; -%newobject ParaMEDMEM::DataArrayDouble::__rpow__; -%newobject ParaMEDMEM::DataArrayDoubleTuple::buildDADouble; - -%feature("unref") DataArray "$this->decrRef();" -%feature("unref") DataArrayDouble "$this->decrRef();" -%feature("unref") DataArrayInt "$this->decrRef();" -%feature("unref") DataArrayChar "$this->decrRef();" -%feature("unref") DataArrayAsciiChar "$this->decrRef();" -%feature("unref") DataArrayByte "$this->decrRef();" - -namespace ParaMEDMEM -{ - class DataArray : public RefCountObject, public TimeLabel - { - public: - void setName(const std::string& name); - void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); - void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); - void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception); - bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception); - bool areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception); - std::string cppRepr(const std::string& varName) const throw(INTERP_KERNEL::Exception); - std::string getName() const; - void setInfoOnComponents(const std::vector& info) throw(INTERP_KERNEL::Exception); - void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); - std::vector getVarsOnComponent() const throw(INTERP_KERNEL::Exception); - std::vector getUnitsOnComponent() const throw(INTERP_KERNEL::Exception); - std::string getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception); - std::string getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception); - std::string getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception); - void setInfoOnComponent(int i, const std::string& info) throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const; - virtual void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception); - virtual void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); - virtual bool isAllocated() const throw(INTERP_KERNEL::Exception); - virtual void checkAllocated() const throw(INTERP_KERNEL::Exception); - virtual void desallocate() throw(INTERP_KERNEL::Exception); - virtual int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); - virtual std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception); - virtual std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception); - virtual DataArray *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual DataArray *selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception); - virtual void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception); - void checkNbOfTuples(int nbOfTuples, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfComps(int nbOfCompo, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const throw(INTERP_KERNEL::Exception); - static int GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg) throw(INTERP_KERNEL::Exception); - static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg) throw(INTERP_KERNEL::Exception); - static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception); - static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); - static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); - static std::string BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) throw(INTERP_KERNEL::Exception); - void updateTime() const; - %extend - { - PyObject *getInfoOnComponents() const throw(INTERP_KERNEL::Exception) - { - const std::vector& comps=self->getInfoOnComponents(); - PyObject *ret=PyList_New((int)comps.size()); - for(int i=0;i<(int)comps.size();i++) - PyList_SetItem(ret,i,PyString_FromString(comps[i].c_str())); - return ret; - } - - void copyPartOfStringInfoFrom(const DataArray& other, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->copyPartOfStringInfoFrom(other,tmp); - } - - void copyPartOfStringInfoFrom2(PyObject *li, const DataArray& other) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->copyPartOfStringInfoFrom2(tmp,other); - } - - virtual void renumberInPlace(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlace(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlace(da2->getConstPointer()); - } - } - - virtual void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlaceR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlaceR(da2->getConstPointer()); - } - } - - //tuplesSelec in PyObject * because DataArrayInt is not already existing ! - virtual void setContigPartOfSelectedValues(int tupleIdStart, PyObject *aBase, PyObject *tuplesSelec) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="DataArray::setContigPartOfSelectedValues2 : 4th parameter \"tuplesSelec\" should be of type DataArrayInt"; - DataArray *a=CheckAndRetrieveDataArrayInstance(aBase,"DataArray::setContigPartOfSelectedValues2 : 3rd parameter \"aBase\" should be of type DataArray"); - DataArray *tuplesSelecPtr=CheckAndRetrieveDataArrayInstance(tuplesSelec,msg); - DataArrayInt *tuplesSelecPtr2=0; - if(tuplesSelecPtr) - { - tuplesSelecPtr2=dynamic_cast(tuplesSelecPtr); - if(!tuplesSelecPtr2) - throw INTERP_KERNEL::Exception(msg); - } - self->setContigPartOfSelectedValues(tupleIdStart,a,tuplesSelecPtr2); - } - - virtual void setContigPartOfSelectedValues2(int tupleIdStart, PyObject *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) - { - DataArray *a=CheckAndRetrieveDataArrayInstance(aBase,"DataArray::setContigPartOfSelectedValues2 : 2nd parameter \"aBase\" should be of type DataArray"); - self->setContigPartOfSelectedValues2(tupleIdStart,a,bg,end2,step); - } - - virtual DataArray *selectByTupleRanges(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - std::vector > ranges; - convertPyToVectorPairInt(li,ranges); - return self->selectByTupleRanges(ranges); - } - - virtual DataArray *selectByTupleId(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->selectByTupleId(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->selectByTupleId(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - virtual DataArray *selectByTupleIdSafe(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->selectByTupleIdSafe(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->selectByTupleIdSafe(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - virtual PyObject *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - DataArray *ret=self->keepSelectedComponents(tmp); - return convertDataArray(ret,SWIG_POINTER_OWN | 0 ); - } - - static PyObject *GetSlice(PyObject *slic, int sliceId, int nbOfSlices) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::GetSlice (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetSlice (wrap) : the input slice is invalid !"); - int a,b; - DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); - return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); - } - - PyObject *getSlice(PyObject *slic, int sliceId, int nbOfSlices) const throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::getSlice (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getSlice (wrap) : the input slice is invalid !"); - int a,b; - DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); - return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); - } - - static int GetNumberOfItemGivenBES(PyObject *slic) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBES (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); - } - - static int GetNumberOfItemGivenBESRelative(PyObject *slic) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); - } - - static DataArray *Aggregate(PyObject *arrs) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(arrs,SWIGTYPE_p_ParaMEDMEM__DataArray,"DataArray",tmp); - return DataArray::Aggregate(tmp); - } - - int getNumberOfItemGivenBES(PyObject *slic) const throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBES (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); - } - - int getNumberOfItemGivenBESRelative(PyObject *slic) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); - } - - PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) - { - PyObject *ret(PyTuple_New(2)); - std::string a0(self->getName()); - const std::vector &a1(self->getInfoOnComponents()); - PyTuple_SetItem(ret,0,PyString_FromString(a0.c_str())); - // - int sz(a1.size()); - PyObject *ret1(PyList_New(sz)); - for(int i=0;i a1cpp; - if(!fillStringVector(a1,a1cpp)) - throw INTERP_KERNEL::Exception(MSG); - self->setName(PyString_AsString(a0)); - self->setInfoOnComponents(a1cpp); - } - } - }; - - class DataArrayInt; - class DataArrayDoubleIterator; - - class DataArrayDouble : public DataArray - { - public: - static DataArrayDouble *New(); - double doubleValue() const throw(INTERP_KERNEL::Exception); - bool empty() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - void cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception); - void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); - void pushBackSilent(double val) throw(INTERP_KERNEL::Exception); - double popBackSilent() throw(INTERP_KERNEL::Exception); - void pack() const throw(INTERP_KERNEL::Exception); - void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); - void fillWithZero() throw(INTERP_KERNEL::Exception); - void fillWithValue(double val) throw(INTERP_KERNEL::Exception); - void iota(double init=0.) throw(INTERP_KERNEL::Exception); - bool isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception); - void sort(bool asc=true) throw(INTERP_KERNEL::Exception); - void reverse() throw(INTERP_KERNEL::Exception); - void checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); - bool isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); - std::string repr() const throw(INTERP_KERNEL::Exception); - std::string reprZip() const throw(INTERP_KERNEL::Exception); - std::string reprNotTooLong() const throw(INTERP_KERNEL::Exception); - bool isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); - bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); - DataArrayInt *convertToIntArr() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromNoInterlace() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *toNoInterlace() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); - void transpose() throw(INTERP_KERNEL::Exception); - DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); - void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception); - void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); - void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); - void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); - double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - double front() const throw(INTERP_KERNEL::Exception); - double back() const throw(INTERP_KERNEL::Exception); - double getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - void setIJ(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); - void setIJSilent(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); - double *getPointer() throw(INTERP_KERNEL::Exception); - void checkNoNullValues() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const throw(INTERP_KERNEL::Exception); - void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); - double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - double getMaxValueInArray() const throw(INTERP_KERNEL::Exception); - double getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - double getMinValueInArray() const throw(INTERP_KERNEL::Exception); - int count(double value, double eps) const throw(INTERP_KERNEL::Exception); - double getAverageValue() const throw(INTERP_KERNEL::Exception); - double norm2() const throw(INTERP_KERNEL::Exception); - double normMax() const throw(INTERP_KERNEL::Exception); - double normMin() const throw(INTERP_KERNEL::Exception); - double accumulate(int compId) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromPolarToCart() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromCylToCart() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromSpherToCart() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *determinant() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *eigenValues() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *inverse() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *trace() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *deviator() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *magnitude() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *sumPerTuple() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); - void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - void abs() throw(INTERP_KERNEL::Exception); - DataArrayDouble *computeAbs() const throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); - void applyInv(double numerator) throw(INTERP_KERNEL::Exception); - void applyPow(double val) throw(INTERP_KERNEL::Exception); - void applyRPow(double val) throw(INTERP_KERNEL::Exception); - DataArrayDouble *negate() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - void applyFuncOnThis(const std::string& func, bool isSafe=true) throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - void applyFuncFast32(const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFuncFast64(const std::string& func) throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsNotInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayDouble() throw(INTERP_KERNEL::Exception) - { - return DataArrayDouble::New(); - } - - static DataArrayDouble *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) - { - const char *msgBase="ParaMEDMEM::DataArrayDouble::New : Available API are : \n-DataArrayDouble.New()\n-DataArrayDouble.New([1.,3.,4.])\n-DataArrayDouble.New([1.,3.,4.],3)\n-DataArrayDouble.New([1.,3.,4.,5.],2,2)\n-DataArrayDouble.New([1.,3.,4.,5.,7,8.],3,2)\n-DataArrayDouble.New([(1.,3.),(4.,5.),(7,8.)])\n-DataArrayDouble.New(5)\n-DataArrayDouble.New(5,2)"; - std::string msg(msgBase); -#ifdef WITH_NUMPY - msg+="\n-DataArrayDouble.New(numpy array with dtype=float64)"; -#endif - msg+=" !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); - if(elt2) - { - if(PyInt_Check(elt2)) - {//DataArrayDouble.New([1.,3.,4.,5.],2,2) - int nbOfCompo=PyInt_AS_LONG(elt2); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayDouble.New([1.,3.,4.],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {// DataArrayDouble.New([1.,3.,4.]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListDbl2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!elt2) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayDouble.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayDouble.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } -#ifdef WITH_NUMPY - else if(PyArray_Check(elt0) && nbOfTuples==NULL && elt2==NULL) - {//DataArrayDouble.New(numpyArray) - return BuildNewInstance(elt0,NPY_DOUBLE,&PyCallBackDataArrayDouble_RefType,"FLOAT64"); - } -#endif - else - throw INTERP_KERNEL::Exception(msg.c_str()); - throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy - } - - DataArrayDouble(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,nbOfTuples,elt2); - } - - void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) - { - double val; - std::vector bb; - int sw,nbTuples=-1; - const char msg[]="Python wrap of DataArrayDouble::pushBackValsSilent : "; - const double *tmp=convertObjToPossibleCpp5_SingleCompo(li,sw,val,bb,msg,true,nbTuples); - self->pushBackValsSilent(tmp,tmp+nbTuples); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->reprNotTooLong(); - } - - double __float__() const throw(INTERP_KERNEL::Exception) - { - return self->doubleValue(); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - if(self->isAllocated()) - { - return self->getNumberOfTuples(); - } - else - { - throw INTERP_KERNEL::Exception("DataArrayDouble::__len__ : Instance is NOT allocated !"); - } - } - - DataArrayDoubleIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayDouble::setValues : Available API are : \n-DataArrayDouble.setValues([1.,3.,4.])\n-DataArrayDouble.setValues([1.,3.,4.],3)\n-DataArrayDouble.setValues([1.,3.,4.,5.],2,2)\n-DataArrayDouble.setValues([(1.,1.7),(3.,3.7),(4.,4.7)])\n !"; - if(PyList_Check(li) || PyTuple_Check(li)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayDouble.setValues([1.,3.,4.,5.],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive number of components !"); - std::vector tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,nbOfCompo); - self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayDouble.setValues([1.,3.,4.],3) - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,tmpp1); - self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {// DataArrayDouble.setValues([1.,3.,4.]) - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListDbl2(li,tmpp1,tmpp2); - self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - PyObject *getValues() const throw(INTERP_KERNEL::Exception) - { - const double *vals=self->getConstPointer(); - return convertDblArrToPyList(vals,self->getNbOfElems()); - } - -#ifdef WITH_NUMPY - PyObject *toNumPyArray() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! - { - return ToNumPyArray(self,NPY_DOUBLE,"DataArrayDouble"); - } -#endif - - PyObject *isEqualIfNotWhy(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,prec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *getValuesAsTuple() const throw(INTERP_KERNEL::Exception) - { - const double *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertDblArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - DataArrayDouble *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(da2->getConstPointer()); - } - } - - DataArrayDouble *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(da2->getConstPointer()); - } - } - - DataArrayDouble *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(tmp,newNbOfTuple); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); - } - } - - PyObject *minimalDistanceTo(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception) - { - int thisTupleId,otherTupleId; - double r0=self->minimalDistanceTo(other,thisTupleId,otherTupleId); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(thisTupleId)); - PyTuple_SetItem(ret,2,PyInt_FromLong(otherTupleId)); - return ret; - } - - PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - double r1=self->getMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMaxValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - double r1=self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMinValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getMinMaxPerComponent() const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[2*nbOfCompo]; - self->getMinMaxPerComponent(tmp); - PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,nbOfCompo); - return ret; - } - - PyObject *accumulate() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->accumulate(tmp); - return convertDblArrToPyList(tmp,sz); - } - - DataArrayDouble *accumulatePerChunck(PyObject *indexArr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz,val; - std::vector val2; - const int *bg=convertObjToPossibleCpp1_Safe(indexArr,sw,sz,val,val2); - return self->accumulatePerChunck(bg,bg+sz); - } - - PyObject *findCommonTuples(double prec, int limitNodeId=-1) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *comm, *commIndex; - self->findCommonTuples(prec,limitNodeId,comm,commIndex); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - PyObject *distanceToTuple(PyObject *tuple) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int tupleId=-1,nbOfCompo=self->getNumberOfComponents(); - const double *pt=convertObjToPossibleCpp5_Safe(tuple,sw,val,a,aa,bb,"Python wrap of DataArrayDouble::distanceToTuple",1,nbOfCompo,true); - // - double ret0=self->distanceToTuple(pt,pt+nbOfCompo,tupleId); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tupleId)); - return ret; - } - - void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->setSelectedComponents(a,tmp); - } - - PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->getTuple(tupleId,tmp); - return convertDblArrToPyList(tmp,sz); - } - - static DataArrayDouble *Aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); - return DataArrayDouble::Aggregate(tmp); - } - - static DataArrayDouble *Meld(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); - return DataArrayDouble::Meld(tmp); - } - - PyObject *computeTupleIdsNearTuples(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int nbComp=self->getNumberOfComponents(),nbTuples=-1; - const char msg[]="Python wrap of DataArrayDouble::computeTupleIdsNearTuples : "; - const double *pos=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,msg,nbComp,true,nbTuples); - MEDCouplingAutoRefCountObjectPtr inpu=DataArrayDouble::New(); inpu->useArray(pos,false,CPP_DEALLOC,nbTuples,nbComp); - DataArrayInt *c=0,*cI=0; - self->computeTupleIdsNearTuples(inpu,eps,c,cI); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *areIncludedInMe(const DataArrayDouble *other, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - bool ret0=self->areIncludedInMe(other,prec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in DataArrayDouble::__getitem__ !"; - const char msg2[]="DataArrayDouble::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - self->checkAllocated(); - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - int sw; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr ret; - switch(sw) - { - case 1: - if(nbOfComponents==1) - return PyFloat_FromDouble(self->getIJSafe(it1,0)); - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&it1,&it1+1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 2: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size())),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 3: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 4: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems())),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 5: - return PyFloat_FromDouble(self->getIJSafe(it1,ic1)); - case 6: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 7: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 8: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 9: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 10: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 11: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 12: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 13: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 14: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 15: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 16: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - self->checkAllocated(); - const char msg[]="Unexpected situation in DataArrayDouble::__setitem__ !"; - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int sw1,sw2; - double i1; - std::vector v1; - DataArrayDouble *d1=0; - convertObjToPossibleCpp4(value,sw1,i1,v1,d1); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr tmp; - switch(sw2) - { - case 1: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 2: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 3: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 4: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 5: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 6: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 7: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 8: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 9: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 10: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 11: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues4(d1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 12: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 13: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 14: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 15: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 16: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - return self; - } - - DataArrayDouble *__neg__() const throw(INTERP_KERNEL::Exception) - { - return self->negate(); - } - - PyObject *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in DataArrayDouble.__add__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1.,val); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __radd__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1.,val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Add(self,aaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Add(self,aaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __iadd__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyLin(1.,val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->addEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->addEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->addEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __sub__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1.,-val); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rsub__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(-1.,val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Substract(aaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Substract(aaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __isub__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyLin(1,-val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->substractEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->substractEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->substractEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __mul__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0.); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rmul__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0.); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Multiply(self,aaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Multiply(self,aaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __imul__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyLin(val,0.); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->multiplyEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->multiplyEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->multiplyEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __div__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("DataArrayDouble::__div__ : trying to divide by zero !"); - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1/val,0.); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rdiv__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyInv(val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Divide(aaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Divide(aaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __idiv__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("DataArrayDouble::__div__ : trying to divide by zero !"); - self->applyLin(1./val,0.); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->divideEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->divideEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->divideEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __pow__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyPow(val); - return ret.retn(); - } - case 2: - { - return DataArrayDouble::Pow(self,a); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Pow(self,aaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Pow(self,aaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rpow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rpow__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyRPow(val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Pow(aaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Pow(aaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __ipow__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyPow(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->powEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->powEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->powEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *computeTupleIdsNearTuples(const DataArrayDouble *other, double eps) - { - DataArrayInt *c=0,*cI=0; - // - self->computeTupleIdsNearTuples(other,eps,c,cI); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *maxPerTupleWithCompoId() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->maxPerTupleWithCompoId(ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="DataArrayDouble.__new__ : the args in input is expected to be a tuple !"; - if(!PyTuple_Check(args)) - throw INTERP_KERNEL::Exception(MSG); - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - int sz(PyTuple_Size(args)); - - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *zeNumpyRepr(0); - PyObject *tmp1(PyInt_FromLong(0)); - zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed - Py_DECREF(tmp1); - PyObject *tmp3(PyTuple_New(1)); - PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr); - PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); - Py_XDECREF(tmp2); - Py_DECREF(tmp3); - } - Py_DECREF(initMeth); - return instance; - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - { -#ifdef WITH_NUMPY - if(!self->isAllocated()) - throw INTERP_KERNEL::Exception("PyWrap of DataArrayDouble.__getnewargs__ : self is not allocated !"); - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyObject *numpyArryObj(ParaMEDMEM_DataArrayDouble_toNumPyArray(self)); - {// create a dict to discriminite in __new__ if __init__ should be called. Not beautiful but not idea ... - PyObject *tmp1(PyInt_FromLong(0)); - PyDict_SetItem(ret0,tmp1,numpyArryObj); Py_DECREF(tmp1); Py_DECREF(numpyArryObj); - PyTuple_SetItem(ret,0,ret0); - } - return ret; -#else - throw INTERP_KERNEL::Exception("PyWrap of DataArrayDouble.__getnewargs__ : not implemented because numpy is not active in your configuration ! No serialization/unserialization available without numpy !"); -#endif - } - } - }; - - class DataArrayDoubleTuple; - - class DataArrayDoubleIterator - { - public: - DataArrayDoubleIterator(DataArrayDouble *da); - ~DataArrayDoubleIterator(); - %extend - { - PyObject *next() - { - DataArrayDoubleTuple *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,SWIG_POINTER_OWN|0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class DataArrayDoubleTuple - { - public: - int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - double __float__() const throw(INTERP_KERNEL::Exception) - { - return self->doubleValue(); - } - - DataArrayDouble *buildDADouble() throw(INTERP_KERNEL::Exception) - { - return self->buildDADouble(1,self->getNumberOfCompo()); - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____iadd___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____isub___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____imul___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____idiv___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *__len__() throw(INTERP_KERNEL::Exception) - { - return PyInt_FromLong(self->getNumberOfCompo()); - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg2[]="DataArrayDoubleTuple::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - const double *pt=self->getConstPointer(); - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - if(singleVal>=0) - return PyFloat_FromDouble(pt[singleVal]); - else - { - if(nbc+singleVal>0) - return PyFloat_FromDouble(pt[nbc+singleVal]); - else - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - PyObject *t=PyTuple_New(multiVal.size()); - for(int j=0;j<(int)multiVal.size();j++) - { - int cid=multiVal[j]; - if(cid>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id #" << cid << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - PyTuple_SetItem(t,j,PyFloat_FromDouble(pt[cid])); - } - return t; - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - PyObject *t=PyTuple_New(sz); - for(int j=0;j multiValV; - ParaMEDMEM::DataArrayDoubleTuple *daIntTyyppV=0; - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp44(value,sw1,singleValV,multiValV,daIntTyyppV); - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - double *pt=self->getPointer(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); - switch(sw2) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(sw1) - { - case 1: - { - pt[singleVal]=singleValV; - return self; - } - case 2: - { - if(multiValV.size()!=1) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[singleVal]=multiValV[0]; - return self; - } - case 3: - { - pt[singleVal]=daIntTyyppV->getConstPointer()[0]; - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 2: - { - switch(sw1) - { - case 1: - { - for(std::vector::const_iterator it=multiVal.begin();it!=multiVal.end();it++) - { - if(*it>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[*it]=singleValV; - } - return self; - } - case 2: - { - if(multiVal.size()!=multiValV.size()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i<(int)multiVal.size();i++) - { - int pos=multiVal[i]; - if(pos>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[multiVal[i]]=multiValV[i]; - } - return self; - } - case 3: - { - const double *ptV=daIntTyyppV->getConstPointer(); - if(nbc>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::copy(ptV,ptV+nbc,pt); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - switch(sw1) - { - case 1: - { - for(int j=0;jgetConstPointer(); - if(sz>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int j=0;j& tupl) const throw(INTERP_KERNEL::Exception); - int locateValue(int value) const throw(INTERP_KERNEL::Exception); - int locateValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); - int search(const std::vector& vals) const throw(INTERP_KERNEL::Exception); - bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); - bool presenceOfValue(int value) const throw(INTERP_KERNEL::Exception); - bool presenceOfValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); - int count(int value) const throw(INTERP_KERNEL::Exception); - int accumulate(int compId) const throw(INTERP_KERNEL::Exception); - int getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - int getMaxValueInArray() const throw(INTERP_KERNEL::Exception); - int getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - int getMinValueInArray() const throw(INTERP_KERNEL::Exception); - void abs() throw(INTERP_KERNEL::Exception); - DataArrayInt *computeAbs() const throw(INTERP_KERNEL::Exception); - void applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception); - void applyLin(int a, int b) throw(INTERP_KERNEL::Exception); - void applyInv(int numerator) throw(INTERP_KERNEL::Exception); - DataArrayInt *negate() const throw(INTERP_KERNEL::Exception); - void applyDivideBy(int val) throw(INTERP_KERNEL::Exception); - void applyModulus(int val) throw(INTERP_KERNEL::Exception); - void applyRModulus(int val) throw(INTERP_KERNEL::Exception); - void applyPow(int val) throw(INTERP_KERNEL::Exception); - void applyRPow(int val) throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsNotInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsStrictlyNegative() const throw(INTERP_KERNEL::Exception); - bool checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); - static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) throw(INTERP_KERNEL::Exception); - static DataArrayInt *BuildUnion(const std::vector& arr) throw(INTERP_KERNEL::Exception); - static DataArrayInt *BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception); - static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception); - DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUniqueNotSorted() const throw(INTERP_KERNEL::Exception); - DataArrayInt *deltaShiftIndex() const throw(INTERP_KERNEL::Exception); - void computeOffsets() throw(INTERP_KERNEL::Exception); - void computeOffsets2() throw(INTERP_KERNEL::Exception); - DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); - void sortEachPairToMakeALinkedList() throw(INTERP_KERNEL::Exception); - DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getDifferentValues() const throw(INTERP_KERNEL::Exception); - static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - public: - static DataArrayInt *Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayInt() throw(INTERP_KERNEL::Exception) - { - return DataArrayInt::New(); - } - - static DataArrayInt *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msgBase="ParaMEDMEM::DataArrayInt::New : Available API are : \n-DataArrayInt.New()\n-DataArrayInt.New([1,3,4])\n-DataArrayInt.New([1,3,4],3)\n-DataArrayInt.New([1,3,4,5],2,2)\n-DataArrayInt.New([1,3,4,5,7,8],3,2)\n-DataArrayInt.New([(1,3),(4,5),(7,8)])\n-DataArrayInt.New(5)\n-DataArrayInt.New(5,2)"; - std::string msg(msgBase); -#ifdef WITH_NUMPY - msg+="\n-DataArrayInt.New(numpy array with dtype=int32)"; -#endif - msg+=" !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayInt.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayInt.New([1,3,4],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {// DataArrayInt.New([1,3,4]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!nbOfComp) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayInt.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayInt.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } -#ifdef WITH_NUMPY - else if(PyArray_Check(elt0) && nbOfTuples==NULL && nbOfComp==NULL) - {//DataArrayInt.New(numpyArray) - return BuildNewInstance(elt0,NPY_INT32,&PyCallBackDataArrayInt_RefType,"INT32"); - } -#endif - else - throw INTERP_KERNEL::Exception(msg.c_str()); - throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy - } - - DataArrayInt(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,nbOfTuples,nbOfComp); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->reprNotTooLong(); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - if(self->isAllocated()) - { - return self->getNumberOfTuples(); - } - else - { - throw INTERP_KERNEL::Exception("DataArrayInt::__len__ : Instance is NOT allocated !"); - } - } - - int __int__() const throw(INTERP_KERNEL::Exception) - { - return self->intValue(); - } - - DataArrayIntIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - PyObject *accumulate() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - self->accumulate(tmp); - return convertIntArrToPyList(tmp,sz); - } - - DataArrayInt *accumulatePerChunck(PyObject *indexArr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz,val; - std::vector val2; - const int *bg=convertObjToPossibleCpp1_Safe(indexArr,sw,sz,val,val2); - return self->accumulatePerChunck(bg,bg+sz); - } - - DataArrayInt *getIdsEqualTuple(PyObject *inputTuple) const throw(INTERP_KERNEL::Exception) - { - int sw,sz,val; - std::vector val2; - const int *bg(convertObjToPossibleCpp1_Safe(inputTuple,sw,sz,val,val2)); - return self->getIdsEqualTuple(bg,bg+sz); - } - - PyObject *splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > slcs(self->splitInBalancedSlices(nbOfSlices)); - PyObject *ret=PyList_New(slcs.size()); - for(std::size_t i=0;i(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice is invalid !"); - if(strt==std::numeric_limits::max() || stp==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice contains some unknowns that can't be determined in static method ! Call DataArray::getSlice (non static) instead !"); - return self->buildExplicitArrOfSliceOnScaledArr(strt,stp,step); - } - - PyObject *getMinMaxValues() const throw(INTERP_KERNEL::Exception) - { - int a,b; - self->getMinMaxValues(a,b); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(a)); - PyTuple_SetItem(ret,1,PyInt_FromLong(b)); - return ret; - } - - static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, PyObject *arr, PyObject *arrI) throw(INTERP_KERNEL::Exception) - { - int newNbOfTuples=-1; - int szArr,szArrI,sw,iTypppArr,iTypppArrI; - std::vector stdvecTyyppArr,stdvecTyyppArrI; - const int *arrPtr=convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr); - const int *arrIPtr=convertObjToPossibleCpp1_Safe(arrI,sw,szArrI,iTypppArrI,stdvecTyyppArrI); - DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arrPtr,arrIPtr,arrIPtr+szArrI,newNbOfTuples); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples)); - return ret; - } - - static DataArrayInt *CheckAndPreparePermutation(PyObject *arr) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *arrPtr(convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr)); - int *pt(ParaMEDMEM::DataArrayInt::CheckAndPreparePermutation(arrPtr,arrPtr+szArr)); - ret->useArray(pt,true,ParaMEDMEM::C_DEALLOC,szArr,1); - return ret.retn(); - } - - void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayInt::setValues : Available API are : \n-DataArrayInt.setValues([1,3,4])\n-DataArrayInt.setValues([1,3,4],3)\n-DataArrayInt.setValues([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n !"; - if(PyList_Check(li) || PyTuple_Check(li)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples<0) - throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayInt.setValues([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive number of components !"); - std::vector tmp=fillArrayWithPyListInt2(li,nbOfTuples1,nbOfCompo); - self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayInt.setValues([1,3,4],3) - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(li,nbOfTuples1,tmpp1); - self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {// DataArrayInt.setValues([1,3,4]) - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(li,tmpp1,tmpp2); - self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - PyObject *getValues() const throw(INTERP_KERNEL::Exception) - { - const int *vals=self->getConstPointer(); - return convertIntArrToPyList(vals,self->getNbOfElems()); - } - -#ifdef WITH_NUMPY - PyObject *toNumPyArray() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! - { - return ToNumPyArray(self,NPY_INT32,"DataArrayInt"); - } -#endif - - PyObject *isEqualIfNotWhy(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *getValuesAsTuple() const throw(INTERP_KERNEL::Exception) - { - const int *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertIntArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - static PyObject *MakePartition(PyObject *gps, int newNb) throw(INTERP_KERNEL::Exception) - { - std::vector groups; - std::vector< std::vector > fidsOfGroups; - convertFromPyObjVectorOfObj(gps,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",groups); - ParaMEDMEM::DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::MakePartition(groups,newNb,fidsOfGroups); - PyObject *ret = PyList_New(2); - PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - int sz=fidsOfGroups.size(); - PyObject *ret1 = PyList_New(sz); - for(int i=0;i tmp=convertPyToNewIntArr2(li,&size); - self->transformWithIndArr(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - self->transformWithIndArr(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - DataArrayInt *getIdsEqualList(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->getIdsEqualList(&singleVal,&singleVal+1); - case 2: - return self->getIdsEqualList(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->getIdsEqualList(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - DataArrayInt *getIdsNotEqualList(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->getIdsNotEqualList(&singleVal,&singleVal+1); - case 2: - return self->getIdsNotEqualList(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->getIdsNotEqualList(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - PyObject *splitByValueRange(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret0=0,*ret1=0,*ret2=0; - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->splitByValueRange(tmp,(int *)tmp+size,ret0,ret1,ret2); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - self->splitByValueRange(da2->getConstPointer(),da2->getConstPointer()+size,ret0,ret1,ret2); - } - PyObject *ret = PyList_New(3); - PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *transformWithIndArrR(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->transformWithIndArrR(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - return self->transformWithIndArrR(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - DataArrayInt *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(tmp,newNbOfTuple); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); - } - } - - DataArrayInt *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(da2->getConstPointer()); - } - } - - DataArrayInt *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(da2->getConstPointer()); - } - } - - void setSelectedComponents(const DataArrayInt *a, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->setSelectedComponents(a,tmp); - } - - PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - self->getTuple(tupleId,tmp); - return convertIntArrToPyList(tmp,sz); - } - - PyObject *changeSurjectiveFormat(int targetNb) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arr=0; - DataArrayInt *arrI=0; - self->changeSurjectiveFormat(targetNb,arr,arrI); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj((void*)arr,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - PyList_SetItem(res,1,SWIG_NewPointerObj((void*)arrI,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - return res; - } - - static DataArrayInt *Meld(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::Meld(tmp); - } - - static DataArrayInt *Aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::Aggregate(tmp); - } - - static DataArrayInt *AggregateIndexes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::AggregateIndexes(tmp); - } - - static DataArrayInt *BuildUnion(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::BuildUnion(tmp); - } - - static DataArrayInt *BuildIntersection(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::BuildIntersection(tmp); - } - - PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - int r1=self->getMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - int r1=self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->locateValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::index : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - { - std::vector arr; - convertPyToNewIntArr3(obj,arr); - return self->locateTuple(arr); - } - } - } - - bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 0: - return false; - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->presenceOfValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - { - std::vector arr; - convertPyToNewIntArr3(obj,arr); - return self->presenceOfTuple(arr); - } - } - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in DataArrayInt::__getitem__ !"; - const char msg2[]="DataArrayInt::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - self->checkAllocated(); - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - int sw; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr ret; - switch(sw) - { - case 1: - { - if(nbOfComponents==1) - return PyInt_FromLong(self->getIJSafe(it1,0)); - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&it1,&it1+1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 2: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size())),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - case 3: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - case 4: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems())),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - case 5: - return PyInt_FromLong(self->getIJSafe(it1,ic1)); - case 6: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 7: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 8: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 9: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 10: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 11: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 12: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 13: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 14: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 15: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 16: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - self->checkAllocated(); - const char msg[]="Unexpected situation in __setitem__ !"; - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int sw1,sw2; - int i1; - std::vector v1; - DataArrayInt *d1=0; - DataArrayIntTuple *dd1=0; - convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr tmp; - switch(sw2) - { - case 1: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 2: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 3: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 4: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 5: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 6: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 7: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 8: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 9: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 10: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 11: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues4(d1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 12: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 13: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 14: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 15: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 16: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - return self; - } - - DataArrayInt *__neg__() const throw(INTERP_KERNEL::Exception) - { - return self->negate(); - } - - DataArrayInt *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __add__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1,val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Add(self,aaaa); - } - case 3: - { - return DataArrayInt::Add(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Add(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __radd__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1,val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Add(self,aaaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Add(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __iadd__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyLin(1,val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->addEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->addEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->addEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __sub__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1,-val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Substract(self,aaaa); - } - case 3: - { - return DataArrayInt::Substract(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Substract(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rsub__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(-1,val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Substract(aaaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Substract(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __isub__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyLin(1,-val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->substractEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->substractEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->substractEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __mul__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Multiply(self,aaaa); - } - case 3: - { - return DataArrayInt::Multiply(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Multiply(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rmul__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Multiply(self,aaaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Multiply(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __imul__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyLin(val,0); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->multiplyEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->multiplyEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->multiplyEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __div__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyDivideBy(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Divide(self,aaaa); - } - case 3: - { - return DataArrayInt::Divide(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Divide(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rdiv__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyInv(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Divide(aaaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Divide(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __idiv__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyDivideBy(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->divideEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->divideEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->divideEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__mod__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __mod__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyModulus(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Modulus(self,aaaa); - } - case 3: - { - return DataArrayInt::Modulus(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Modulus(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rmod__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rmod__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyRModulus(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Modulus(aaaa,self); - } - case 3: - { - return DataArrayInt::Modulus(a,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Modulus(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___imod___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __imod__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyModulus(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->modulusEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->modulusEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __pow__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyPow(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Pow(self,aaaa); - } - case 3: - { - return DataArrayInt::Pow(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Pow(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rpow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rpow__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyRPow(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Pow(aaaa,self); - } - case 3: - { - return DataArrayInt::Pow(a,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Pow(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __ipow__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyPow(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->powEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->powEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->pushBackValsSilent(tmp,tmp+szArr); - } - - PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception) - { - std::vector ret1; - std::vector ret0=self->partitionByDifferentValues(ret1); - std::size_t sz=ret0.size(); - PyObject *pyRet=PyTuple_New(2); - PyObject *pyRet0=PyList_New((int)sz); - PyObject *pyRet1=PyList_New((int)sz); - for(std::size_t i=0;isearchRangesInListOfIds(listOfIds,ret0,ret1); - PyObject *pyRet=PyTuple_New(2); - PyTuple_SetItem(pyRet,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(pyRet,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return pyRet; - } - - PyObject *isRange() const throw(INTERP_KERNEL::Exception) - { - int a(0),b(0),c(0); - bool ret(self->isRange(a,b,c)); - PyObject *pyRet=PyTuple_New(2); - PyObject *ret0Py=ret?Py_True:Py_False,*ret1Py(0); - Py_XINCREF(ret0Py); - PyTuple_SetItem(pyRet,0,ret0Py); - if(ret) - ret1Py=PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(c)); - else - { - ret1Py=Py_None; - Py_XINCREF(ret1Py); - } - PyTuple_SetItem(pyRet,1,ret1Py); - return pyRet; - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="DataArrayInt.__new__ : the args in input is expected to be a tuple !"; - if(!PyTuple_Check(args)) - throw INTERP_KERNEL::Exception(MSG); - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - int sz(PyTuple_Size(args)); - - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *zeNumpyRepr(0); - PyObject *tmp1(PyInt_FromLong(0)); - zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed - Py_DECREF(tmp1); - PyObject *tmp3(PyTuple_New(1)); - PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr); - PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); - Py_XDECREF(tmp2); - Py_DECREF(tmp3); - } - Py_DECREF(initMeth); - return instance; - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - { -#ifdef WITH_NUMPY - if(!self->isAllocated()) - throw INTERP_KERNEL::Exception("PyWrap of DataArrayInt.__getnewargs__ : self is not allocated !"); - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyObject *numpyArryObj(ParaMEDMEM_DataArrayInt_toNumPyArray(self)); - {// create a dict to discriminite in __new__ if __init__ should be called. Not beautiful but not idea ... - PyObject *tmp1(PyInt_FromLong(0)); - PyDict_SetItem(ret0,tmp1,numpyArryObj); Py_DECREF(tmp1); Py_DECREF(numpyArryObj); - PyTuple_SetItem(ret,0,ret0); - } - return ret; -#else - throw INTERP_KERNEL::Exception("PyWrap of DataArrayInt.__getnewargs__ : not implemented because numpy is not active in your configuration ! No serialization/unserialization available without numpy !"); -#endif - } - } - }; - - class DataArrayIntTuple; - - class DataArrayIntIterator - { - public: - DataArrayIntIterator(DataArrayInt *da); - ~DataArrayIntIterator(); - %extend - { - PyObject *next() - { - DataArrayIntTuple *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,SWIG_POINTER_OWN | 0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class DataArrayIntTuple - { - public: - int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - int __int__() const throw(INTERP_KERNEL::Exception) - { - return self->intValue(); - } - - DataArrayInt *buildDAInt() throw(INTERP_KERNEL::Exception) - { - return self->buildDAInt(1,self->getNumberOfCompo()); - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____iadd___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____isub___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____imul___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____idiv___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___imod___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____imod___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *__len__() throw(INTERP_KERNEL::Exception) - { - return PyInt_FromLong(self->getNumberOfCompo()); - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg2[]="DataArrayIntTuple::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - const int *pt=self->getConstPointer(); - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - if(singleVal>=0) - return PyInt_FromLong(pt[singleVal]); - else - { - if(nbc+singleVal>0) - return PyInt_FromLong(pt[nbc+singleVal]); - else - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - PyObject *t=PyTuple_New(multiVal.size()); - for(int j=0;j<(int)multiVal.size();j++) - { - int cid=multiVal[j]; - if(cid>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id #" << cid << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - PyTuple_SetItem(t,j,PyInt_FromLong(pt[cid])); - } - return t; - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - PyObject *t=PyTuple_New(sz); - for(int j=0;j multiValV; - std::pair > slicV; - ParaMEDMEM::DataArrayIntTuple *daIntTyyppV=0; - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp22(value,nbc,sw1,singleValV,multiValV,slicV,daIntTyyppV); - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int *pt=self->getPointer(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); - switch(sw2) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(sw1) - { - case 1: - { - pt[singleVal]=singleValV; - return self; - } - case 2: - { - if(multiValV.size()!=1) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[singleVal]=multiValV[0]; - return self; - } - case 4: - { - pt[singleVal]=daIntTyyppV->getConstPointer()[0]; - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 2: - { - switch(sw1) - { - case 1: - { - for(std::vector::const_iterator it=multiVal.begin();it!=multiVal.end();it++) - { - if(*it>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[*it]=singleValV; - } - return self; - } - case 2: - { - if(multiVal.size()!=multiValV.size()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i<(int)multiVal.size();i++) - { - int pos=multiVal[i]; - if(pos>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[multiVal[i]]=multiValV[i]; - } - return self; - } - case 4: - { - const int *ptV=daIntTyyppV->getConstPointer(); - if(nbc>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::copy(ptV,ptV+nbc,pt); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - switch(sw1) - { - case 1: - { - for(int j=0;jgetConstPointer(); - if(sz>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int j=0;j& tupl) const throw(INTERP_KERNEL::Exception); - bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); - char getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - char getMaxValueInArray() const throw(INTERP_KERNEL::Exception); - char getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - char getMinValueInArray() const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(char vmin, char vmax) const throw(INTERP_KERNEL::Exception); - static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); - static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); - %extend - { - int __len__() const throw(INTERP_KERNEL::Exception) - { - if(self->isAllocated()) - { - return self->getNumberOfTuples(); - } - else - { - throw INTERP_KERNEL::Exception("DataArrayChar::__len__ : Instance is NOT allocated !"); - } - } - - PyObject *isEqualIfNotWhy(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - DataArrayChar *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(da2->getConstPointer()); - } - } - - DataArrayChar *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(da2->getConstPointer()); - } - } - - DataArrayChar *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(tmp,newNbOfTuple); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); - } - } - - static DataArrayChar *Aggregate(PyObject *dachs) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(dachs,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,"DataArrayChar",tmp); - return DataArrayChar::Aggregate(tmp); - } - - static DataArrayChar *Meld(PyObject *dachs) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(dachs,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,"DataArrayChar",tmp); - return DataArrayChar::Meld(tmp); - } - } - }; - - class DataArrayByteIterator; - - class DataArrayByte : public DataArrayChar - { - public: - static DataArrayByte *New(); - DataArrayByteIterator *iterator() throw(INTERP_KERNEL::Exception); - DataArrayByte *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - char byteValue() const throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayByte() throw(INTERP_KERNEL::Exception) - { - return DataArrayByte::New(); - } - - static DataArrayByte *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayByte::New : Available API are : \n-DataArrayByte.New()\n--DataArrayByte.New([1,3,4])\n-DataArrayByte.New([1,3,4],3)\n-DataArrayByte.New([1,3,4,5],2,2)\n-DataArrayByte.New(5)\n-DataArrayByte.New(5,2) !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayByte.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayByte.New([1,3,4],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {// DataArrayByte.New([1,3,4]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!nbOfComp) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayByte.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayByte.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - DataArrayByte(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayByte_New__SWIG_1(elt0,nbOfTuples,nbOfComp); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - int __int__() const throw(INTERP_KERNEL::Exception) - { - return (int) self->byteValue(); - } - - DataArrayByteIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - return (int)self->getIJ(tupleId,compoId); - } - - int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - return (int)self->getIJSafe(tupleId,compoId); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - PyObject *toStrList() const throw(INTERP_KERNEL::Exception) - { - const char *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertCharArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - bool presenceOfTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(tupl,sw,sz,ival,ivval); - std::vector vals(sz); - std::copy(pt,pt+sz,vals.begin()); - return self->presenceOfTuple(vals); - } - - bool presenceOfValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(vals,sw,sz,ival,ivval); - std::vector vals2(sz); - std::copy(pt,pt+sz,vals2.begin()); - return self->presenceOfValue(vals2); - } - - int locateValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(vals,sw,sz,ival,ivval); - std::vector vals2(sz); - std::copy(pt,pt+sz,vals2.begin()); - return self->locateValue(vals2); - } - - int locateTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(tupl,sw,sz,ival,ivval); - std::vector vals(sz); - std::copy(pt,pt+sz,vals.begin()); - return self->locateTuple(vals); - } - - int search(PyObject *strOrListOfInt) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(strOrListOfInt,sw,sz,ival,ivval); - std::vector vals(sz); - std::copy(pt,pt+sz,vals.begin()); - return self->search(vals); - } - - PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new char[sz]; - self->getTuple(tupleId,tmp); - PyObject *ret=PyTuple_New(sz); - for(int i=0;igetMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - int r1=(int)self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->locateValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayByte::index : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayByte_locateTuple(self,obj); - } - } - - bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 0: - return false; - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->presenceOfValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayByte::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayByte_presenceOfTuple(self,obj); - } - } - - DataArrayByte *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - self->checkAllocated(); - const char msg[]="Unexpected situation in __setitem__ !"; - int nbOfTuples(self->getNumberOfTuples()),nbOfComponents(self->getNumberOfComponents()); - int sw1,sw2; - int i1; - std::vector v1; - DataArrayInt *d1=0; - DataArrayIntTuple *dd1=0; - convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr tmp; - switch(sw2) - { - case 1: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 2: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 3: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 4: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 5: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 6: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 7: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 8: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 9: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 10: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 11: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 12: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 13: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 14: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 15: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 16: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - return self; - } - } - }; - - class DataArrayByteTuple; - - class DataArrayByteIterator - { - public: - DataArrayByteIterator(DataArrayByte *da); - ~DataArrayByteIterator(); - }; - - class DataArrayByteTuple - { - public: - std::string repr() const throw(INTERP_KERNEL::Exception); - DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - char __int__() const throw(INTERP_KERNEL::Exception) - { - return self->byteValue(); - } - - DataArrayByte *buildDAByte() throw(INTERP_KERNEL::Exception) - { - return self->buildDAByte(1,self->getNumberOfCompo()); - } - } - }; - - class DataArrayAsciiCharIterator; - - class DataArrayAsciiChar : public DataArrayChar - { - public: - static DataArrayAsciiChar *New(); - DataArrayAsciiCharIterator *iterator() throw(INTERP_KERNEL::Exception); - DataArrayAsciiChar *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - char asciiCharValue() const throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayAsciiChar() throw(INTERP_KERNEL::Exception) - { - return DataArrayAsciiChar::New(); - } - - static DataArrayAsciiChar *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayAsciiChar::New : Available API are : \n-DataArrayAsciiChar.New()\n-DataArrayAsciiChar.New([1,3,4])\n-DataArrayAsciiChar.New([\"abc\",\"de\",\"fghi\"])\n-DataArrayAsciiChar.New([\"abc\",\"de\",\"fghi\"],\"t\")\n-DataArrayAsciiChar.New([1,3,4],3)\n-DataArrayAsciiChar.New([1,3,4,5],2,2)\n-DataArrayAsciiChar.New(5)\n-DataArrayAsciiChar.New(5,2) !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayAsciiChar.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayAsciiChar.New([1,3,4],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyString_Check(nbOfTuples)) - { - if(PyString_Size(nbOfTuples)!=1) - throw INTERP_KERNEL::Exception(msg); - //DataArrayAsciiChar.New(["abc","de","fghi"],"t") - std::vector tmp; - if(fillStringVector(elt0,tmp)) - return DataArrayAsciiChar::New(tmp,PyString_AsString(nbOfTuples)[0]); - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - { - std::vector tmmp; - if(fillStringVector(elt0,tmmp)) - //DataArrayAsciiChar.New(["abc","de","fghi"]) - return DataArrayAsciiChar::New(tmmp,' '); - else - { - // DataArrayAsciiChar.New([1,3,4]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!nbOfComp) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayAsciiChar.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayAsciiChar.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - DataArrayAsciiChar(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayAsciiChar_New__SWIG_1(elt0,nbOfTuples,nbOfComp); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - DataArrayAsciiCharIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - std::string getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - char tmp[2]; tmp[1]='\0'; - tmp[0]=self->getIJ(tupleId,compoId); - return std::string(tmp); - } - - std::string getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - char tmp[2]; tmp[1]='\0'; - tmp[0]=self->getIJSafe(tupleId,compoId); - return std::string(tmp); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - PyObject *toStrList() const throw(INTERP_KERNEL::Exception) - { - const char *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertCharArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - bool presenceOfTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(tupl)) - { - Py_ssize_t sz=PyString_Size(tupl); - std::vector vals(sz); - std::copy(PyString_AsString(tupl),PyString_AsString(tupl)+sz,vals.begin()); - return self->presenceOfTuple(vals); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::presenceOfTuple : only strings in input supported !"); - } - - bool presenceOfValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(vals)) - { - Py_ssize_t sz=PyString_Size(vals); - std::vector vals2(sz); - std::copy(PyString_AsString(vals),PyString_AsString(vals)+sz,vals2.begin()); - return self->presenceOfValue(vals2); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::presenceOfValue : only strings in input supported !"); - } - - int locateValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(vals)) - { - Py_ssize_t sz=PyString_Size(vals); - std::vector vals2(sz); - std::copy(PyString_AsString(vals),PyString_AsString(vals)+sz,vals2.begin()); - return self->locateValue(vals2); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::locateValue : only strings in input supported !"); - } - - int locateTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(tupl)) - { - Py_ssize_t sz=PyString_Size(tupl); - std::vector vals(sz); - std::copy(PyString_AsString(tupl),PyString_AsString(tupl)+sz,vals.begin()); - return self->locateTuple(vals); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::locateTuple : only strings in input supported !"); - } - - int search(PyObject *strOrListOfInt) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(strOrListOfInt)) - { - Py_ssize_t sz=PyString_Size(strOrListOfInt); - std::vector vals(sz); - std::copy(PyString_AsString(strOrListOfInt),PyString_AsString(strOrListOfInt)+sz,vals.begin()); - return self->search(vals); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::search : only strings in input supported !"); - } - - PyObject *getTuple(int tupleId) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new char[sz+1]; tmp[sz]='\0'; - self->getTuple(tupleId,tmp); - return PyString_FromString(tmp); - } - - PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - char tmp2[2]; tmp2[1]='\0'; - tmp2[0]=self->getMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyString_FromString(tmp2)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - char tmp2[2]; tmp2[1]='\0'; - tmp2[0]=self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyString_FromString(tmp2)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 1: - { - if(PyString_Check(obj)) - { - Py_ssize_t sz=PyString_Size(obj); - char *pt=PyString_AsString(obj); - if(sz==1) - return self->locateValue(pt[0]); - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::index : 'this' contains one component and trying to find a string with size different from 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::index : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayAsciiChar_locateTuple(self,obj); - } - } - - bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 0: - return false; - case 1: - { - if(PyString_Check(obj)) - { - Py_ssize_t sz=PyString_Size(obj); - char *pt=PyString_AsString(obj); - if(sz==1) - return self->presenceOfValue(pt[0]); - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__contains__ : 'this' contains one component and trying to find a string with size different from 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayAsciiChar_presenceOfTuple(self,obj); - } - } - - PyObject *__getitem__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int sw,iTypppArr; - std::vector stdvecTyyppArr; - std::pair > sTyyppArr; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2WithNegIntInterp(obj,self->getNumberOfTuples(),sw,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); - switch(sw) - { - case 1: - return ParaMEDMEM_DataArrayAsciiChar_getTuple(self,iTypppArr); - case 2: - return convertDataArrayChar(self->selectByTupleIdSafe(&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size()), SWIG_POINTER_OWN | 0 ); - case 3: - return convertDataArrayChar(self->selectByTupleId2(sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second), SWIG_POINTER_OWN | 0 ); - case 4: - return convertDataArrayChar(self->selectByTupleIdSafe(daIntTyypp->begin(),daIntTyypp->end()), SWIG_POINTER_OWN | 0 ); - default: - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__getitem__ : supporting int, list of int, tuple of int, DataArrayInt and slice in input !"); - } - } - - DataArrayAsciiChar *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="DataArrayAsciiChar::__setitem__ : supporting int, list of int, tuple of int, DataArrayInt and slice in input, and 4 types accepted in value : string, list or tuple of strings having same size, not null DataArrayChar instance."; - int sw1,iTypppArr; - std::vector stdvecTyyppArr; - std::pair > sTyyppArr; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbOfCompo=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbOfTuples,sw1,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); - int sw2; - char vc; std::string sc; std::vector vsc; DataArrayChar *dacc=0; - convertObjToPossibleCpp6(value,sw2,vc,sc,vsc,dacc); - switch(sw1) - { - case 1: - {//obj int - switch(sw2) - {//value char - case 1: - { - self->setPartOfValuesSimple3(vc,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues3(tmp,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues3(tmp,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues3(dacc,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 2: - {//obj list-tuple[int] - switch(sw2) - { - {//value char - case 1: - { - self->setPartOfValuesSimple3(vc,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues3(tmp,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues3(tmp,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues3(dacc,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - case 3: - {//slice - switch(sw2) - { - {//value char - case 1: - { - self->setPartOfValuesSimple1(vc,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues1(tmp,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues1(tmp,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues1(dacc,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - case 4: - {//DataArrayInt - switch(sw2) - { - {//value char - case 1: - { - self->setPartOfValuesSimple3(vc,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues3(tmp,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues3(tmp,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues3(dacc,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - }; - - class DataArrayAsciiCharTuple; - - class DataArrayAsciiCharIterator - { - public: - DataArrayAsciiCharIterator(DataArrayAsciiChar *da); - ~DataArrayAsciiCharIterator(); - %extend - { - PyObject *next() - { - DataArrayAsciiCharTuple *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiCharTuple,SWIG_POINTER_OWN | 0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class DataArrayAsciiCharTuple - { - public: - int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); - DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - DataArrayAsciiChar *buildDAAsciiChar() throw(INTERP_KERNEL::Exception) - { - return self->buildDAAsciiChar(1,self->getNumberOfCompo()); - } - } - }; -} diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py b/medtool/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py deleted file mode 100644 index e5d7943bf..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py +++ /dev/null @@ -1,672 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDCoupling import * - -if MEDCouplingHasNumPyBindings(): - from numpy import * - pass - -from platform import architecture -from sys import getrefcount - -import os,gc,weakref,unittest - -class MEDCouplingNumPyTest(unittest.TestCase): - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test1(self): - sz=20 - a=array(0,dtype=int32) - a.resize(sz) - a[:]=4 - self.assertEqual(getrefcount(a),2) - a=a.cumsum(dtype=int32) - a=array(a,dtype=int64) ; a=array(a,dtype=int32) - self.assertEqual(getrefcount(a),2) - d=DataArrayInt(a) - d[:]=2 - # - e=DataArrayInt(sz) ; e.fillWithValue(2) - self.assertTrue(d.isEqual(e)) - # - a[:]=4 ; e.fillWithValue(4) - self.assertTrue(d.isEqual(e)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test2(self): - sz=20 - a=array(0,dtype=int32) - a.resize(sz,2) - self.assertEqual(getrefcount(a),2) - b=a.reshape(2*sz) - self.assertEqual(getrefcount(a),3) - self.assertEqual(getrefcount(b),2) - b[:]=5 - d=DataArrayInt(b) - # - e=DataArrayInt(sz*2) ; e.fillWithValue(5) - self.assertTrue(d.isEqual(e)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test3(self): - sz=10 - a=array(0,dtype=int32) - a.resize(sz,2) - b=a.reshape(2*sz) - c=a.reshape(2,sz) - b[:]=6 - b[7:17]=7 - d=DataArrayInt(b) - self.assertTrue(d.isEqual(DataArrayInt([6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6]))) - # - a=zeros((10,2),dtype=int32) - b=a.T - c=b.view() - a.shape=20 - a[3:]=10. - d=DataArrayInt(a) - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]))) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test4(self): - a=zeros(20,dtype=int32) - b = a[::-1] - self.assertRaises(InterpKernelException,DataArrayInt.New,b) # b is not contiguous in memory - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test5(self): - a=arange(20,dtype=int32) - self.assertEqual(weakref.getweakrefcount(a),0) - d=DataArrayInt(a) - self.assertEqual(weakref.getweakrefcount(a),1) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(d.isIdentity()) - self.assertEqual(len(d),20) - a[:]=2 # modifying a and d because a and d share the same chunk of data - self.assertTrue(d.isUniform(2)) - del d # d is destroyed, a retrieves its ownership of its initial chunk of data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - a[:]=4 # a can be used has usual - self.assertTrue(DataArrayInt(a).isUniform(4)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test6(self): - a=arange(20,dtype=int32) - d=DataArrayInt(a) # d owns data of a - e=DataArrayInt(a) # a not owned -> e only an access to chunk of a - self.assertTrue(d.isIdentity()) - self.assertTrue(e.isIdentity()) - a[:]=6 - self.assertTrue(d.isUniform(6)) - self.assertTrue(e.isUniform(6)) - del a # a destroyed -> d no change because owned and e array is has no more data set - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isUniform(6)) - self.assertTrue(not e.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test7(self): - a=array(0,dtype=int32) ; a.resize(10,2) - b=a.reshape(20) - c=a.reshape(2,10) - d=DataArrayInt(b) # d owns data of a - e=DataArrayInt(b) # a not owned -> e only an access to chunk of a - f=DataArrayInt(b) # a not owned -> e only an access to chunk of a - del d # d removed -> a ownes again data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(e.isUniform(0)) - e[:]=6 - self.assertTrue(e.isUniform(6)) - self.assertTrue(f.isUniform(6)) - self.assertEqual(b.tolist(),[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]) - self.assertEqual(a.tolist(),[[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6]]) - b[:]=arange(20) - del b # no impact on e and f because a is the base of a. - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isIdentity()) - self.assertTrue(e.isIdentity()) - del a # a destroyed, but as c has its base set to a, a exists -> e and f not allocated - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isIdentity()) - self.assertTrue(e.isIdentity()) - del c # c killed -> a killed -> e and d are put into not allocated state - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(not e.isAllocated()) - self.assertTrue(not f.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test8(self): - a=arange(20,dtype=int32) - self.assertTrue(a.flags["OWNDATA"]) - d=DataArrayInt(a) # d owns data of a - self.assertTrue(not a.flags["OWNDATA"]) - d.pushBackSilent(20)# d pushBack so release of chunk of data -> a becomes owner of its data again - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]))) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test9(self): - sz=20 - a=array(0,dtype=float64) - a.resize(sz) - a[:]=4 - self.assertEqual(getrefcount(a),2) - a=a.cumsum(dtype=float64) - self.assertEqual(getrefcount(a),2) - d=DataArrayDouble(a) - d[:]=2 - # - e=DataArrayDouble(sz) ; e.fillWithValue(2) - self.assertTrue(d.isEqual(e,1e-14)) - # - a[:]=4 ; e.fillWithValue(4) - self.assertTrue(d.isEqual(e,1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test10(self): - sz=20 - a=array(0,dtype=float64) - a.resize(sz,2) - self.assertEqual(getrefcount(a),2) - b=a.reshape(2*sz) - self.assertEqual(getrefcount(a),3) - self.assertEqual(getrefcount(b),2) - b[:]=5 - d=DataArrayDouble(b) - # - e=DataArrayDouble(sz*2) ; e.fillWithValue(5) - self.assertTrue(d.isEqual(e,1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test11(self): - sz=10 - a=array(0,dtype=float64) - a.resize(sz,2) - b=a.reshape(2*sz) - c=a.reshape(2,sz) - b[:]=6 - b[7:17]=7 - d=DataArrayDouble(b) - self.assertTrue(d.isEqual(DataArrayDouble([6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6]),1e-14)) - # - a=zeros((10,2),dtype=float64) - b=a.T - c=b.view() - a.shape=20 - a[3:]=10. - d=DataArrayDouble(a) - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]),1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test12(self): - a=zeros(20,dtype=float64) - b = a[::-1] - self.assertRaises(InterpKernelException,DataArrayDouble.New,b) # b is not contiguous in memory - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test13(self): - a=arange(20,dtype=float64) - self.assertEqual(weakref.getweakrefcount(a),0) - d=DataArrayDouble(a) - self.assertEqual(weakref.getweakrefcount(a),1) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertEqual(len(d),20) - a[:]=2 # modifying a and d because a and d share the same chunk of data - self.assertTrue(d.isUniform(2,1e-14)) - del d # d is destroyed, a retrieves its ownership of its initial chunk of data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - a[:]=4 # a can be used has usual - self.assertTrue(DataArrayDouble(a).isUniform(4,1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test14(self): - a=arange(20,dtype=float64) - d=DataArrayDouble(a) # d owns data of a - e=DataArrayDouble(a) # a not owned -> e only an access to chunk of a - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - a[:]=6 - self.assertTrue(d.isUniform(6,1e-14)) - self.assertTrue(e.isUniform(6,1e-14)) - del a # a destroyed -> d no change because owned and e array is has no more data set - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isUniform(6,1e-14)) - self.assertTrue(not e.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test15(self): - a=array(0,dtype=float64) ; a.resize(10,2) - b=a.reshape(20) - c=a.reshape(2,10) - d=DataArrayDouble(b) # d owns data of a - e=DataArrayDouble(b) # a not owned -> e only an access to chunk of a - f=DataArrayDouble(b) # a not owned -> e only an access to chunk of a - del d # d removed -> a ownes again data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(e.isUniform(0,1e-14)) - e[:]=6 - self.assertTrue(e.isUniform(6,1e-14)) - self.assertTrue(f.isUniform(6,1e-14)) - self.assertEqual(b.tolist(),[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]) - self.assertEqual(a.tolist(),[[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6]]) - b[:]=arange(20) - del b # no impact on e and f because a is the base of a. - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - del a # a destroyed, but as c has its base set to a, a exists -> e and f not allocated - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - del c # c killed -> a killed -> e and d are put into not allocated state - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(not e.isAllocated()) - self.assertTrue(not f.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test16(self): - a=arange(20,dtype=float64) - self.assertTrue(a.flags["OWNDATA"]) - d=DataArrayDouble(a) # d owns data of a - self.assertTrue(not a.flags["OWNDATA"]) - d.pushBackSilent(20)# d pushBack so release of chunk of data -> a becomes owner of its data again - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]),1e-14)) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test17(self): - d=DataArrayInt.Range(0,20,1) - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=100 - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]))) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]))) - # - d.rearrange(2) - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=200 - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2))) - self.assertEqual(a.tolist(),[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[200,200],[200,200]]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2))) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test18(self): - d=DataArrayInt.Range(0,20,1) - d=d.convertToDblArr() - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=100 - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]),1e-14)) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]),1e-14)) - # - d.rearrange(2) - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=200 - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2),1e-14)) - self.assertEqual(a.tolist(),[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[200,200],[200,200]]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2),1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test19(self): - sz=20 - a=array(0,dtype=int32) - a.resize(sz/2,2) - a[:]=4 - self.assertEqual(getrefcount(a),2) - d=DataArrayInt(a) - self.assertEqual(10,d.getNumberOfTuples()) - self.assertEqual(2,d.getNumberOfComponents()) - self.assertEqual(sz,d.getNbOfElems()) - self.assertTrue(d.isEqual(DataArrayInt([(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4)]))) - a[:]=7 - self.assertTrue(d.isEqual(DataArrayInt([(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7)]))) - # - b=a.reshape((2,5,2)) - self.assertRaises(InterpKernelException,DataArrayInt.New,b) # b has not dimension in [0,1] ! - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test20(self): - sz=20 - a=array(0,dtype=float64) - a.resize(sz/2,2) - a[:]=4 - self.assertEqual(getrefcount(a),2) - d=DataArrayDouble(a) - self.assertEqual(10,d.getNumberOfTuples()) - self.assertEqual(2,d.getNumberOfComponents()) - self.assertEqual(sz,d.getNbOfElems()) - self.assertTrue(d.isEqual(DataArrayDouble([(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.)]),1e-14)) - a[:]=7 - self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.)]),1e-14)) - # - b=a.reshape((2,5,2)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,b) # b has not dimension in [0,1] ! - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test21(self): - #tests that only DataArray*(npArray) contructor is available - a=array(0,dtype=int32) - a.resize(20) - DataArrayInt(a) - self.assertRaises(InterpKernelException,DataArrayInt.New,a,20) - self.assertRaises(InterpKernelException,DataArrayInt.New,a,20,1) - a=array(0,dtype=float64) - a.resize(20) - DataArrayDouble(a) - self.assertRaises(InterpKernelException,DataArrayDouble.New,a,20) - self.assertRaises(InterpKernelException,DataArrayDouble.New,a,20,1) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test22(self): - d=DataArrayDouble(10) - d.iota() - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - # - d=DataArrayInt(10) - d.iota() - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test23(self): - d=DataArrayDouble(10) - d.iota() - a=d.toNumPyArray() - b=d.toNumPyArray() - c=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(c.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(c.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - # - d=DataArrayInt(10) - d.iota() - a=d.toNumPyArray() - b=d.toNumPyArray() - c=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(c.tolist(),[0,1,2,3,4,5,6,7,8,9]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(c.tolist(),[0,1,2,3,4,5,6,7,8,9]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test24(self): - d=DataArrayDouble(10) - d.iota() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - del a - gc.collect() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - b=d.toNumPyArray() - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(b.base is a) - del a - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - del d - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - # - d=DataArrayInt(10) - d.iota() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - del a - gc.collect() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - b=d.toNumPyArray() - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(b.base is a) - del a - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - del d - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test25(self): - a=arange(10,dtype=int32) - b=DataArrayInt(a) - c=DataArrayInt(a) - d=DataArrayInt(a) - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) - self.assertTrue(d.isIdentity()) ; self.assertEqual(len(d),10) - c.pushBackSilent(10) # c and a,b are dissociated - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) - self.assertTrue(d.isIdentity()) ; self.assertEqual(len(d),10) - del a - gc.collect() - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) - self.assertTrue(not d.isAllocated()) - del b - gc.collect() - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) - # - a=arange(10,dtype=int32) - b=DataArrayInt(a) - c=DataArrayInt(a) - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) - b.pushBackSilent(10) # c and a,b are dissociated - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),11) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) - del a - gc.collect() - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),11) - self.assertTrue(not c.isAllocated()) - del b - gc.collect() - self.assertTrue(not c.isAllocated()) - # - a=float64(arange(5,dtype=int32)) - b=DataArrayDouble(a) - c=DataArrayDouble(a) - d=DataArrayDouble(a) - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - c.pushBackSilent(10.) # c and a,b are dissociated - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - del a - gc.collect() - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(not d.isAllocated()) - del b - gc.collect() - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - # - a=float64(arange(5,dtype=int32)) - b=DataArrayDouble(a) - c=DataArrayDouble(a) - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - b.pushBackSilent(10.) # c and a,b are dissociated - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - del a - gc.collect() - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(not c.isAllocated()) - del b - gc.collect() - self.assertTrue(not c.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test26(self): - d=DataArrayInt(15) ; d.iota() - d.rearrange(3) - a=d.toNumPyArray() - self.assertEqual(a.ndim,2) - self.assertEqual(a.size,15) - self.assertEqual(a.shape,(5,3)) - self.assertEqual(a.strides,(12,4)) - self.assertEqual(a.nbytes,60) - self.assertEqual(a.itemsize,4) - self.assertEqual(a.tolist(),[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13,14]]) - # - d2=d.convertToDblArr() - a2=d2.toNumPyArray() - self.assertEqual(a2.ndim,2) - self.assertEqual(a2.size,15) - self.assertEqual(a2.shape,(5,3)) - self.assertEqual(a2.strides,(24,8)) - self.assertEqual(a2.nbytes,120) - self.assertEqual(a2.itemsize,8) - self.assertEqual(a2.tolist(),[[0.,1.,2.],[3.,4.,5.],[6.,7.,8.],[9.,10.,11.],[12.,13.,14.]]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test27(self): - m0=DenseMatrix(DataArrayDouble([2,3,4,5,1,6]),2,3) - m0np=m0.toNumPyMatrix() - self.assertEqual(m0np.shape,(2,3)) - self.assertEqual(m0np.tolist(),[[2.0,3.0,4.0],[5.0,1.0,6.0]]) - pass - - def setUp(self): - pass - pass - -#gc.set_debug(gc.DEBUG_LEAK) -unittest.main() diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingPickleTest.py b/medtool/src/MEDCoupling_Swig/MEDCouplingPickleTest.py deleted file mode 100644 index 677b11082..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingPickleTest.py +++ /dev/null @@ -1,300 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDCoupling import * -from MEDCouplingDataForTest import MEDCouplingDataForTest - -if MEDCouplingHasNumPyBindings(): - from numpy import * - pass - -from platform import architecture -from sys import getrefcount - -import os,gc,weakref,cPickle,unittest - -class MEDCouplingPickleTest(unittest.TestCase): - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test1(self): - """ Test of a simple DataArrayDouble.""" - x=DataArrayDouble(10,1) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"]) - x.setName("toto") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x,1e-16)) - # Bigger to check that the behavior is OK for large strings. - x=DataArrayDouble(1200) ; x.iota() ; x.setInfoOnComponents(["aa"]) - x.setName("titi") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test2(self): - """ Test of a simple DataArrayInt.""" - x=DataArrayInt(10) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"]) - x.setName("toto") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x)) - # Bigger to check that the behavior is OK for large strings. - x=DataArrayInt(1200) ; x.iota() ; x.setInfoOnComponents(["aa"]) - x.setName("titi") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test3(self): - """ Test of a MEDCouplingUMesh pickeling.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m.setName("mesh") - m.getCoords().setInfoOnComponents(["aa","bbb","ddddd"]) - m.checkCoherency() - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test4(self): - """ Idem test3 except that here serialization/deserialization is done explicitely.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m.setName("mesh") - m.getCoords().setInfoOnComponents(["aa","bbb","ddddd"]) - m.checkCoherency() - # - a0,a1,a2=m.getTinySerializationInformation() - b0,b1=m.serialize() - m2=MEDCouplingUMesh() - m2.unserialization(a0,a1,b0,b1,a2); - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test5(self): - """ Test of a MEDCouplingCMesh pickeling.""" - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - arrZ=DataArrayDouble(7) ; arrZ.iota() ; arrZ.setInfoOnComponents(["cccc"]) - # - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - m.setName("mesh") - m.checkCoherency() - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - self.assertTrue(m2.getCoordsAt(0).isEqual(arrX,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test6(self): - """ Test of a MEDCoupling1SGTUMesh pickeling.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.build1SGTUnstructured() - self.assertTrue(isinstance(m,MEDCoupling1SGTUMesh)) - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test7(self): - """ Test of a MEDCoupling1DGTUMesh pickeling.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.convertAllToPoly() - m=MEDCoupling1DGTUMesh(m) - self.assertTrue(isinstance(m,MEDCoupling1DGTUMesh)) - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test8(self): - """ Test of a MEDCouplingExtrudedMesh pickeling.""" - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - arrZ=DataArrayDouble(7) ; arrZ.iota() ; arrZ.setInfoOnComponents(["cccc"]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - mesh3D=m.buildUnstructured() ; del m - # - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - mesh2D=m.buildUnstructured() ; del m - # - mesh2D.setCoords(mesh3D.getCoords()) - mesh=MEDCouplingExtrudedMesh(mesh3D,mesh2D,0) ; del mesh3D,mesh2D - self.assertTrue(isinstance(mesh,MEDCouplingExtrudedMesh)) - st=cPickle.dumps(mesh,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(mesh,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test9(self): - """ Test of a MEDCouplingCurveLinearMesh pickeling.""" - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - m=m.buildUnstructured() - # - mesh=MEDCouplingCurveLinearMesh() ; mesh.setCoords(m.getCoords()) ; del m - mesh.setNodeGridStructure([10,5]) - st=cPickle.dumps(mesh,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(mesh,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test10(self): - """ Test of a MEDCouplingIMesh pickeling.""" - m=MEDCouplingIMesh("mesh",3,DataArrayInt([3,1,4]),DataArrayDouble([1.5,2.5,3.5]),DataArrayDouble((0.5,1.,0.25))) ; m.setAxisUnit("km") - m.checkCoherency() - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - self.assertEqual(m2.getName(),m.getName()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test11(self): - """ Test of MEDCouplingFieldDouble lying on MEDCouplingCMesh pickeling. """ - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - f=m.getMeasureField(True) - f.setName("aname") - a=f.getArray() - b=a[:] ; b.iota(7000.) - f.setArray(DataArrayDouble.Meld(a,b)) - f.getArray().setInfoOnComponents(["u1","vv2"]) - f.checkCoherency(); - # - st=cPickle.dumps(f,cPickle.HIGHEST_PROTOCOL) - f2=cPickle.loads(st) - self.assertTrue(f2.isEqual(f,1e-16,1e-16)) - self.assertTrue(f2.getMesh().isEqual(f.getMesh(),1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test12(self): - """ Test of MEDCouplingFieldDouble on Gauss Points lying on MEDCouplingUMesh pickeling.""" - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1 - _gsCoo1=gsCoo1 - _wg1=wg1 - # - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - self.assertEqual(0,f.getNbOfGaussLocalization()); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) - self.assertEqual(1,f.getNbOfGaussLocalization()); - refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo2=refCoo2 - _gsCoo1=_gsCoo1[0:4] - _wg1=_wg1[0:2] - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - array=DataArrayDouble.New(); - ptr=18*2*[None] - for i in xrange(18*2): - ptr[i]=float(i+1) - array.setValues(ptr,18,2); - ptr=array.getPointer(); - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - f.checkCoherency(); - self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); - self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); - # - f.clearGaussLocalizations(); - self.assertEqual(0,f.getNbOfGaussLocalization()); - self.assertRaises(InterpKernelException,f.checkCoherency); - ids1=[0,1,3,4] - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(0,f.getNbOfGaussLocalization()); - ids2=[0,4] - f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(1,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneCell,1); - ids3=[1,2] - f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- cell 3 has no localization - ids4=[3] - _gsCoo2=_gsCoo1; - _wg2=_wg1; - _gsCoo2[0]=0.8888777776666; - _wg2[0]=0.1234567892377; - f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); - self.assertEqual(3,f.getNbOfGaussLocalization()); - tmpIds=f.getCellIdsHavingGaussLocalization(0); - self.assertEqual(ids2,list(tmpIds.getValues())); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. - array2=f.getArray().substr(0,10); - f.setArray(array2); - f.checkCoherency(); - #### - st=cPickle.dumps(f,cPickle.HIGHEST_PROTOCOL) - f2=cPickle.loads(st) - self.assertTrue(f2.isEqual(f,1e-16,1e-16)) - self.assertTrue(f2.getMesh().isEqual(f.getMesh(),1e-16)) - pass - - def test13(self): - eStr="This is an exception." - e=InterpKernelException(eStr) - self.assertEqual(e.what(),eStr) - st=cPickle.dumps(e,cPickle.HIGHEST_PROTOCOL) - e2=cPickle.loads(st) - self.assertTrue(e is not e2) - self.assertTrue(isinstance(e2,InterpKernelException)) - self.assertEqual(e2.what(),eStr) - pass - - def setUp(self): - pass - pass - -if __name__=="__main__": - unittest.main() diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i b/medtool/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i deleted file mode 100644 index 48003ef55..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -namespace INTERP_KERNEL -{ - class Exception - { - public: - Exception(const char* what); - ~Exception() throw (); - const char *what() const throw (); - %extend - { - std::string __str__() const - { - return std::string(self->what()); - } - } - }; -} - -namespace ParaMEDMEM -{ - class TimeLabel - { - public: - void declareAsNew() const; - virtual void updateTime() const; - unsigned int getTimeOfThis() const; - protected: - ~TimeLabel(); - }; -} - -namespace ParaMEDMEM -{ - typedef enum - { - C_DEALLOC = 2, - CPP_DEALLOC = 3 - } DeallocType; - - const char *MEDCouplingVersionStr(); - int MEDCouplingVersion(); - int MEDCouplingSizeOfVoidStar(); - bool MEDCouplingByteOrder(); - const char *MEDCouplingByteOrderStr(); - - class BigMemoryObject - { - public: - std::size_t getHeapMemorySize() const throw(INTERP_KERNEL::Exception); - std::string getHeapMemorySizeStr() const throw(INTERP_KERNEL::Exception); - bool isObjectInTheProgeny(const BigMemoryObject *obj) const throw(INTERP_KERNEL::Exception); - virtual std::size_t getHeapMemorySizeWithoutChildren() const throw(INTERP_KERNEL::Exception); - virtual ~BigMemoryObject(); - %extend - { - virtual PyObject *getDirectChildren() const throw(INTERP_KERNEL::Exception) - { - std::vector c(self->getDirectChildren()); - PyObject *ret(PyList_New(c.size())); - for(std::size_t i=0;i c(self->getAllTheProgeny()); - PyObject *ret(PyList_New(c.size())); - for(std::size_t i=0;i cppObjs; - convertFromPyObjVectorOfObj(objs,SWIGTYPE_p_ParaMEDMEM__BigMemoryObject,"BigMemoryObject",cppObjs); - return BigMemoryObject::GetHeapMemorySizeOfObjs(cppObjs); - } - } - }; - - class RefCountObjectOnly - { - public: - bool decrRef() const; - void incrRef() const; - int getRCValue() const; - protected: - ~RefCountObjectOnly(); - }; - - class RefCountObject : public RefCountObjectOnly, public BigMemoryObject - { - protected: - ~RefCountObject(); - }; -} - -%inline -{ - PyObject *MEDCouplingVersionMajMinRel() - { - int tmp0=0,tmp1=0,tmp2=0; - MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - bool MEDCouplingHasNumPyBindings() - { -#ifdef WITH_NUMPY - return true; -#else - return false; -#endif - } - - bool MEDCouplingHasSciPyBindings() - { -#ifdef WITH_SCIPY - return true; -#else - return false; -#endif - } - - std::string MEDCouplingCompletionScript() throw(INTERP_KERNEL::Exception) - { - static const char script[]="import rlcompleter,readline\nreadline.parse_and_bind('tab:complete')"; - std::ostringstream oss; oss << "MEDCouplingCompletionScript : error when trying to activate completion ! readline not present ?\nScript is :\n" << script; - if(PyRun_SimpleString(script)!=0) - throw INTERP_KERNEL::Exception(oss.str().c_str()); - return std::string(script); - } -} - -%pythoncode %{ -def INTERPKERNELExceptionReduceFunct(a,b): - ret=InterpKernelException.__new__(a) - ret.__init__(*b) - return ret -def INTERPKERNELExceptionReduce(self): - return INTERPKERNELExceptionReduceFunct,(InterpKernelException,(self.what(),)) -%} diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingRemapper.i b/medtool/src/MEDCoupling_Swig/MEDCouplingRemapper.i deleted file mode 100644 index 135958b88..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingRemapper.i +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%module MEDCouplingRemapper - -#define MEDCOUPLING_EXPORT -#define INTERPKERNEL_EXPORT -#define MEDCOUPLINGREMAPPER_EXPORT - -%{ -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingField.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingRemapper.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; -%} - -%newobject ParaMEDMEM::MEDCouplingRemapper::transferField; -%newobject ParaMEDMEM::MEDCouplingRemapper::reverseTransferField; - -%include "MEDCouplingCommon.i" -%include "InterpolationOptions.hxx" - -namespace ParaMEDMEM -{ - typedef enum - { - IK_ONLY_PREFERED = 0, - NOT_IK_ONLY_PREFERED = 1, - IK_ONLY_FORCED = 2, - NOT_IK_ONLY_FORCED =3 - } InterpolationMatrixPolicy; - - class MEDCouplingRemapper : public TimeLabel, public INTERP_KERNEL::InterpolationOptions - { - private: - void updateTime() const; - public: - MEDCouplingRemapper(); - ~MEDCouplingRemapper(); - int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method) throw(INTERP_KERNEL::Exception); - int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception); - void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - void partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField) throw(INTERP_KERNEL::Exception); - void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - bool setOptionInt(const std::string& key, int value) throw(INTERP_KERNEL::Exception); - bool setOptionDouble(const std::string& key, double value) throw(INTERP_KERNEL::Exception); - bool setOptionString(const std::string& key, const std::string& value) throw(INTERP_KERNEL::Exception); - int getInterpolationMatrixPolicy() const throw(INTERP_KERNEL::Exception); - void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception); - // - int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception); - int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); - double getMaxValueInCrudeMatrix() const throw(INTERP_KERNEL::Exception); - int getNumberOfColsOfMatrix() const throw(INTERP_KERNEL::Exception); - static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2) throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getCrudeMatrix() const throw(INTERP_KERNEL::Exception) - { - const std::vector >& m=self->getCrudeMatrix(); - std::size_t sz=m.size(); - PyObject *ret=PyList_New(sz); - for(std::size_t i=0;i& row=m[i]; - PyObject *ret0=PyDict_New(); - for(std::map::const_iterator it=row.begin();it!=row.end();it++) - PyDict_SetItem(ret0,PyInt_FromLong((*it).first),PyFloat_FromDouble((*it).second)); - PyList_SetItem(ret,i,ret0); - } - return ret; - } -#if defined(WITH_NUMPY) && defined(WITH_SCIPY) - PyObject *getCrudeCSRMatrix() const throw(INTERP_KERNEL::Exception) - { - return ToCSRMatrix(self->getCrudeMatrix(),self->getNumberOfColsOfMatrix()); - } -#endif - } - }; -} - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____imod___(self, self, *args) -def ParaMEDMEMDenseMatrixIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DenseMatrix____iadd___(self, self, *args) -def ParaMEDMEMDenseMatrixIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DenseMatrix____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCoupling1DGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCoupling1SGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingCurveLinearMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingCMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingIMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingExtrudedMesh____new___(cls,args) -%} - -%include "MEDCouplingFinalize.i" diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/medtool/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py deleted file mode 100644 index ba5ba6428..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py +++ /dev/null @@ -1,907 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDCouplingDataForTest import MEDCouplingDataForTest -from MEDCouplingRemapper import * -from math import * -import unittest - -class MEDCouplingBasicsTest(unittest.TestCase): - def testRemapper1(self): - sourceMesh=self.build2DSourceMesh_1(); - targetMesh=self.build2DTargetMesh_1(); - remapper=MEDCouplingRemapper() - remapper.setPrecision(1e-12); - remapper.setIntersectionType(Triangulation); - self.failUnless(remapper.prepare(sourceMesh,targetMesh,"P0P0")==1); - srcField=MEDCouplingFieldDouble.New(ON_CELLS); - srcField.setNature(ConservativeVolumic); - srcField.setMesh(sourceMesh); - array=DataArrayDouble.New(); - ptr=sourceMesh.getNumberOfCells()*[None] - for i in xrange(sourceMesh.getNumberOfCells()): - ptr[i]=float(i+7) - pass - array.setValues(ptr,sourceMesh.getNumberOfCells(),1); - srcField.setArray(array); - srcField.setName("abc") ; srcField.setDescription("def") - srcField.setTime(7.7,9,10) - trgfield=remapper.transferField(srcField,4.57); - self.assertEqual("abc",trgfield.getName()) - self.assertEqual("def",trgfield.getDescription()) - a,b,c=trgfield.getTime() - self.assertAlmostEqual(7.7,a,14) - self.assertEqual(b,9) - self.assertEqual(c,10) - values=trgfield.getArray().getValues(); - valuesExpected=[7.5 ,7. ,7.,8.,7.5]; - for i in xrange(targetMesh.getNumberOfCells()): - self.failUnless(abs(values[i]-valuesExpected[i])<1e-12); - pass - self.failUnless(1==trgfield.getArray().getNumberOfComponents()); - pass - - def testPrepareEx1(self): - sourceMesh=self.build2DSourceMesh_1(); - targetMesh=self.build2DTargetMesh_3(); - # - remapper=MEDCouplingRemapper(); - remapper.setPrecision(1e-12); - remapper.setIntersectionType(Triangulation); - srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); - trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); - srcFt.setMesh(sourceMesh); - trgFt.setMesh(targetMesh); - self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); - srcField=MEDCouplingFieldDouble.New(ON_CELLS); - srcField.setNature(ConservativeVolumic); - srcField.setMesh(sourceMesh); - array=DataArrayDouble.New(); - ptr=sourceMesh.getNumberOfCells()*[None] - for i in xrange(sourceMesh.getNumberOfCells()): - ptr[i]=float(i+7); - pass - array.setValues(ptr,sourceMesh.getNumberOfCells(),1); - srcField.setArray(array); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield.getArray().getValues(); - valuesExpected=[7.75, 7.0625, 4.220173,8.0] - self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); - self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); - for i0 in xrange(4): - self.assertAlmostEqual(valuesExpected[i0],values[i0],12); - pass - pass - - def testPartialTransfer1(self): - sourceMesh=self.build2DSourceMesh_1(); - targetMesh=self.build2DTargetMesh_3(); - # - remapper=MEDCouplingRemapper(); - remapper.setPrecision(1e-12); - remapper.setIntersectionType(Triangulation); - srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); - trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); - srcFt.setMesh(sourceMesh); - trgFt.setMesh(targetMesh); - self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); - srcField=MEDCouplingFieldDouble.New(ON_CELLS); - srcField.setNature(ConservativeVolumic); - srcField.setMesh(sourceMesh); - array=DataArrayDouble.New(); - ptr=sourceMesh.getNumberOfCells()*[None] - for i in xrange(sourceMesh.getNumberOfCells()): - ptr[i]=float(i+7); - pass - array.setValues(ptr,sourceMesh.getNumberOfCells(),1); - srcField.setArray(array); - trgfield=MEDCouplingFieldDouble.New(ON_CELLS); - trgfield.setNature(ConservativeVolumic); - trgfield.setMesh(targetMesh); - array=DataArrayDouble.New(); - ptr=targetMesh.getNumberOfCells()*[None] - for i in xrange(targetMesh.getNumberOfCells()): - ptr[i]=4.220173; - pass - array.setValues(ptr,targetMesh.getNumberOfCells(),1); - trgfield.setArray(array); - remapper.partialTransfer(srcField,trgfield); - values=trgfield.getArray().getValues(); - valuesExpected=[7.75, 7.0625, 4.220173,8.0] - self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); - self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); - for i0 in xrange(4): - self.assertAlmostEqual(valuesExpected[i0],values[i0],12); - pass - pass - - def testPrepareUC(self): - # 1D - coords=DataArrayDouble([0.,0.5,0.7]) - src=MEDCouplingUMesh("",1) ; src.setCoords(coords) - src.allocateCells(2) ; src.insertNextCell(NORM_SEG2,[0,1]) ; src.insertNextCell(NORM_SEG2,[1,2]) ; src.finishInsertingCells() - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - trg.setCoordsAt(0,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected1=[-7.,4.,36.,-7.,-7.] - self.assertEqual(5,trgField.getArray().getNumberOfTuples()) - self.assertEqual(5,len(expected1)) - for i,val in enumerate(expected1): - self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); - pass - # 2D - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2) - src=MEDCouplingUMesh("",2) ; src.setCoords(coords) - src.allocateCells(2) ; src.insertNextCell(NORM_TRI3,[0,1,2]) ; src.insertNextCell(NORM_TRI3,[3,4,0]) ; src.finishInsertingCells() - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected2=[-7.,-7.,7.35,0.15,-7.,-7.,2.8,14.85,5.25,-7.,-7.,2.,2.5,-7.,-7.,-7.,1.2,3.,0.9,-7.,-7.,-7.,-7.,-7.,-7.] - self.assertEqual(25,trgField.getArray().getNumberOfTuples()) - self.assertEqual(25,len(expected2)) - for i,val in enumerate(expected2): - self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); - pass - # 3D - coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3) - src=MEDCouplingUMesh("",3) ; src.setCoords(coords) - src.allocateCells(2) ; src.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; src.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; src.finishInsertingCells() - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr2) - src.checkCoherency2(1e-10) - trg.checkCoherency() - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected3=[-7.,-7.,2.925,0.015,-7.,-7.,0.9392,8.595,2.265,-7.,-7.,1.1008,1.1192,-7.,-7.,-7.,0.6392,1.6408,0.2808,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,0.81,-7.,-7.,-7.,0.1208,11.55,0.96,-7.,-7.,1.1752,0.6592,-7.,-7.,-7.,0.8512,1.7744,0.0192,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,1.92,-7.,-7.,-7.,0.12578571428571422,0.007314285714285673,-7.,-7.,-7.,0.3189253968253971,0.1879746031746033,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.] - self.assertEqual(100,trgField.getArray().getNumberOfTuples()) - self.assertEqual(100,len(expected3)) - for i,val in enumerate(expected3): - self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); - pass - pass - - def testPrepareCU(self): - # 1D - coords=DataArrayDouble([0.,0.5,0.7]) - trg=MEDCouplingUMesh("",1) ; trg.setCoords(coords) - trg.allocateCells(2) ; trg.insertNextCell(NORM_SEG2,[0,1]) ; trg.insertNextCell(NORM_SEG2,[1,2]) ; trg.finishInsertingCells() - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrTrg) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected1=[44.,16.] - self.assertEqual(2.,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected1)) - for i,val in enumerate(expected1): - self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); - pass - # 2D - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2) - trg=MEDCouplingUMesh("",2) ; trg.setCoords(coords) - trg.allocateCells(2) ; trg.insertNextCell(NORM_TRI3,[0,1,2]) ; trg.insertNextCell(NORM_TRI3,[3,4,0]) ; trg.finishInsertingCells() - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected2=[441.3050624589086,68.69529914529915] - self.assertEqual(2,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected2)) - for i,val in enumerate(expected2): - self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); - pass - # 3D - coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3) - trg=MEDCouplingUMesh("",3) ; trg.setCoords(coords) - trg.allocateCells(2) ; trg.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; trg.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; trg.finishInsertingCells() - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr2) - trg.checkCoherency2(1e-10) - src.checkCoherency() - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(100) ; arrSrc.iota(7.7) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected3=[39.635196634558845,12.13422356758468] - self.assertEqual(2,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected3)) - for i,val in enumerate(expected3): - self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); - pass - pass - - def testPrepareCC(self): - # 1D - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) - trg.setCoordsAt(0,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrTrg) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected1=[10.,25.] - self.assertEqual(2.,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected1)) - for i,val in enumerate(expected1): - self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); - pass - # 2D - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected2=[10.,25.,91.66666666666666,90.27777777777777] - self.assertEqual(4,trgField.getArray().getNumberOfTuples()) - self.assertEqual(4,len(expected2)) - for i,val in enumerate(expected2): - self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); - pass - # 3D - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr) - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(125) ; arrSrc.iota(7.7) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) ; fieldSrc.checkCoherency() - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected3=[7.7, 7.249999999999999, 10.583333333333332, 9.513888888888886, 27.25, 23.40277777777777, 26.180555555555546, 22.39583333333333] - self.assertEqual(8,trgField.getArray().getNumberOfTuples()) - self.assertEqual(8,len(expected3)) - for i,val in enumerate(expected3): - self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); - pass - pass - - # Bug when source mesh is not homogeneously oriented in source mesh - def testNonRegressionNonHomegenousOrriented3DCells(self): - csrc=DataArrayDouble([-0.15240000188350677,0,0,-0.1086929515004158,0,0,-0.15240000188350677,0.018142856657505035,0,-0.13054648041725159,0.0090714283287525177,0.019050000235438347,-0.13054648041725159,0.0090714283287525177,0],5,3) - src1=MEDCouplingUMesh("src",3) ; src1.allocateCells(0) ; src1.insertNextCell(NORM_TETRA4,[0,1,4,3]) ; src1.insertNextCell(NORM_TETRA4,[2,0,4,3]) - src2=MEDCouplingUMesh("src",3) ; src2.allocateCells(0) ; src2.insertNextCell(NORM_TETRA4,[0,4,1,3]) ; src2.insertNextCell(NORM_TETRA4,[2,0,4,3]) - src1.setCoords(csrc) ; src2.setCoords(csrc) - ctrg=DataArrayDouble([-0.15240000188350677,-0.038100000470876694,0,0.32379999756813049,-0.038100000470876694,0,-0.15240000188350677,0.076200000941753387,0,0.32379999756813049,0.076200000941753387,0,-0.15240000188350677,-0.038100000470876694,0.076200000941753387,0.32379999756813049,-0.038100000470876694,0.076200000941753387,-0.15240000188350677,0.076200000941753387,0.076200000941753387,0.32379999756813049,0.076200000941753387,0.076200000941753387],8,3) - trg=MEDCouplingUMesh("trg",3) ; trg.allocateCells(0) ; trg.insertNextCell(NORM_HEXA8,[0,1,3,2,4,5,7,6]) - trg.setCoords(ctrg) - rem1=MEDCouplingRemapper() ; rem1.setSplittingPolicy(PLANAR_FACE_5) ; rem1.prepare(src1,trg,"P0P0") - rem2=MEDCouplingRemapper() ; rem2.setSplittingPolicy(PLANAR_FACE_5) ; rem2.prepare(src1,trg,"P0P0") - mat1=rem1.getCrudeMatrix() ; mat2=rem2.getCrudeMatrix() - self.assertEqual(1,len(mat1)) ; self.assertEqual(1,len(mat2)) - self.assertEqual(mat1[0].keys(),mat2[0].keys()) ; self.assertEqual([0,1],mat1[0].keys()) - self.assertAlmostEqual(1.25884108122e-06,mat1[0][0],16) ; self.assertAlmostEqual(1.25884108122e-06,mat2[0][0],16) - self.assertAlmostEqual(1.25884086663e-06,mat1[0][1],16) ; self.assertAlmostEqual(1.25884086663e-06,mat2[0][1],16) - # - d=DataArrayDouble([13.45,27.67],2,1) - f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f1.setMesh(src1) ; f1.setArray(d) ; f1.setNature(RevIntegral) - f2=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f2.setMesh(src2) ; f2.setArray(d) ; f2.setNature(RevIntegral) - f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) - expected1=DataArrayDouble([0.012480539537637884]) - self.assertTrue(f11.getArray().isEqual(expected1,1e-15)) - self.assertTrue(f22.getArray().isEqual(expected1,1e-15)) - # - f1.setNature(Integral) ; f2.setNature(Integral) - f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) - # - expected2=DataArrayDouble([41.12]) - self.assertTrue(f11.getArray().isEqual(expected2,1e-13)) - self.assertTrue(f22.getArray().isEqual(expected2,1e-13)) - pass - - def testCellToNodeReverse3D(self): - c=DataArrayDouble([0.,1.,2.5]) - cc=MEDCouplingCMesh() - cc.setCoords(c,c,c) - um=cc.buildUnstructured() - f=um.getMeasureField(ON_CELLS) - # - n2o=um.simplexize(PLANAR_FACE_5) - f.setArray(f.getArray()[n2o]) - f.checkCoherency() - f.setNature(ConservativeVolumic) - f.setTime(5.6,7,8) - f.setName("toto") ; f.setDescription("aDescription") - p=MEDCouplingRemapper() - p.setIntersectionType(Barycentric) - p.prepare(um,um,"P1P0") - fNode=p.reverseTransferField(f,1e300) - self.assertEqual("toto",fNode.getName()) - self.assertEqual("aDescription",fNode.getDescription()) - a,b,c=fNode.getTime() - self.assertAlmostEqual(5.6,a,14) - self.assertEqual(7,b) ; self.assertEqual(8,c) - # - integExpected=34.328125 - self.assertAlmostEqual(fNode.integral(False)[0],integExpected,14) - self.assertAlmostEqual(f.integral(False)[0],integExpected,14) - pass - - def testGauss2Gauss2DValidated(self): - srcFt=MEDCouplingDataForTest.buildFieldOnGauss_1() - trgFt=MEDCouplingDataForTest.buildFieldOnGauss_2() - src=MEDCouplingFieldDouble(srcFt) - self.assertEqual(srcFt.getMesh().getHiddenCppPointer(),src.getMesh().getHiddenCppPointer()) - self.assertEqual(srcFt.getDiscretization().getHiddenCppPointer(),src.getDiscretization().getHiddenCppPointer()) - #values given by ASTER usecase - src.setArray(DataArrayDouble([1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) - src.getArray().setInfoOnComponents(["DOMA"]) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - rem.prepareEx(srcFt,trgFt) - trg=rem.transferField(src,1e300) - self.assertEqual(trg.getMesh().getHiddenCppPointer(),trgFt.getMesh().getHiddenCppPointer()) - self.assertEqual(trg.getDiscretization().getHiddenCppPointer(),trgFt.getDiscretization().getHiddenCppPointer()) - #values given after interpolation in ASTER - arrExpected=DataArrayDouble([1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.]) ; arrExpected.setInfoOnComponents(["DOMA"]) - self.assertTrue(trg.getArray().isEqual(arrExpected,1e-12)) - # - # second part of the test : reverse source and target - # - rem.prepareEx(trgFt,srcFt)# sorry trgFt is in the place of source and srcFt in the place of target it is not a bug - trg=MEDCouplingFieldDouble(trgFt) - #values given after interpolation in ASTER - trg.setArray(DataArrayDouble([1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) - trg.getArray().setInfoOnComponents(["DOMA"]) - src=rem.transferField(trg,1e300) - #values given after interpolation in ASTER - arrExpected2=DataArrayDouble([1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1., 1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,1.,0.,1.,1.,1.,1.,0.,0.,0.,0.,1.,0.,0.,0.,1.,1.,1.,0.,1.,1.,1.,1.,1.,1.,0.,0.,1.,1.,0.,1.,1.,1.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,1.,1.,0.,1.,1.,1.,1.,1.]) ; arrExpected2.setInfoOnComponents(["DOMA"]) - # modification of values in ASTER due to modification of algorithm - # target PG 82 in target cell 32(C)/36 PG 1(C)/9 is in source cell 58(C)/120 source Gauss point 113 (1(C)/4). Values must be 1. and not 0. - arrExpected2.setIJ(82,0,1.) - self.assertTrue(src.getArray().isEqual(arrExpected2,1e-12)) - pass - - def testGauss2Gauss3DValidated(self): - srcFt=MEDCouplingDataForTest.buildFieldOnGauss_3() - trgFt=MEDCouplingDataForTest.buildFieldOnGauss_4() - src=MEDCouplingFieldDouble(srcFt) - self.assertEqual(srcFt.getMesh().getHiddenCppPointer(),src.getMesh().getHiddenCppPointer()) - self.assertEqual(srcFt.getDiscretization().getHiddenCppPointer(),src.getDiscretization().getHiddenCppPointer()) - #values given by ASTER usecase - src.setArray(DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,0.,0.])) - src.getArray().setInfoOnComponents(["DOMA"]) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - rem.prepareEx(srcFt,trgFt) - trg=rem.transferField(src,1e300) - self.assertEqual(trg.getMesh().getHiddenCppPointer(),trgFt.getMesh().getHiddenCppPointer()) - self.assertEqual(trg.getDiscretization().getHiddenCppPointer(),trgFt.getDiscretization().getHiddenCppPointer()) - #values given after interpolation in ASTER - arrExpected=DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,0.,1.,1.,1.,0.,1.]) ; arrExpected.setInfoOnComponents(["DOMA"]) - self.assertTrue(trg.getArray().isEqual(arrExpected,1e-12)) - # - # second part of the test : reverse source and target - # - rem.prepareEx(trgFt,srcFt)# sorry trgFt is in the place of source and srcFt in the place of target it is not a bug - trg=MEDCouplingFieldDouble(trgFt) - #values given after interpolation in ASTER - trg.setArray(DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) - trg.getArray().setInfoOnComponents(["DOMA"]) - src=rem.transferField(trg,1e300) - #values given after interpolation in ASTER - arrExpected2=DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,1.,0.,1.,1.,1.,0.,1.,1.,1.,1.,0.,1.,1.,1.,0.,1.]) ; arrExpected2.setInfoOnComponents(["DOMA"]) - self.assertTrue(src.getArray().isEqual(arrExpected2,1e-12)) - pass - - def testSwig2MixOfUMesh(self): - arr0=DataArrayDouble([0,1,1.5]) ; arr1=DataArrayDouble([0,1]) - sc=MEDCouplingCMesh() ; sc.setCoords(arr0,arr1,arr1) - tc=sc.deepCpy() ; tc.translate([0.4,0.3,0.3]) - # umesh-umesh - # 90 (umesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCouplingUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 91 (umesh-1dgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - self.assertTrue(isinstance(s,MEDCouplingUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 165 (1sgtumesh-umesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.buildUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCouplingUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 181 (1dgtumesh-umesh - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.buildUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - self.assertTrue(isinstance(t,MEDCouplingUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 170 (1sgtumesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 171 (1sgtumesh-1dgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 186 (1dgtumesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 187 (1dgtumesh-1dgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # (umesh-cmesh) - # 167 (1sgtumesh-cmesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.deepCpy() - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCouplingCMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 183 (1dgtumesh-cmesh) - #rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - #s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.deepCpy() - #self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - #self.assertTrue(isinstance(t,MEDCouplingCMesh)) - #rem.prepare(s,t,"P0P0") - #mat=rem.getCrudeMatrix() - #self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - #self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - #del s,t - # (cmesh-umesh) - # 122 (cmesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.deepCpy() ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCouplingCMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 123 (cmesh-1dgtumesh) - #rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - #s=sc.deepCpy() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - #self.assertTrue(isinstance(s,MEDCouplingCMesh)) - #self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - #rem.prepare(s,t,"P0P0") - #mat=rem.getCrudeMatrix() - #self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - #self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - #del s,t - pass - - def testSwig2BarycentricP1P13D_1(self): - sCoo=DataArrayDouble([0.313,0.00218,6.90489,0.313,0.10692667,6.90489,0.313,0.10692667,6.96790167,0.313,0.00218,6.9773125,0.313,0.21167333,6.90489,0.313,0.21167333,6.95849083,0.313,0.31642,6.90489,0.313,0.31642,6.94908,0.313,0.09383333,7.04891667,0.313,0.00218,7.049735,0.313,0.18548667,7.04809833,0.313,0.27714,7.04728,0.313,0.05782667,7.133205,0.313,0.00218,7.1221575,0.313,0.11347333,7.1442525,0.313,0.16912,7.1553,0.313,0.02509333,7.19458,0.313,0.00218,7.19458,0.313,0.04800667,7.19458,0.313,0.07092,7.19458,0.31005609,0.00218,6.90460005,0.31005609,0.10692667,6.90460005,0.29776312,0.10692667,6.96640097,0.29592716,0.00218,6.97563097,0.31005609,0.21167333,6.90460005,0.29959908,0.21167333,6.95717096,0.31005609,0.31642,6.90460005,0.30143505,0.31642,6.94794095,0.28195788,0.09383333,7.04585928,0.28179823,0.00218,7.04666189,0.28211753,0.18548667,7.04505668,0.28227718,0.27714,7.04425407,0.26551404,0.05782667,7.12852804,0.2676693,0.00218,7.11769282,0.26335878,0.11347333,7.13936327,0.26120352,0.16912,7.15019849,0.25354037,0.02509333,7.18872374,0.25354037,0.00218,7.18872374,0.25354037,0.04800667,7.18872374,0.25354037,0.07092,7.18872374,0.30722531,0.00218,6.90374134,0.30722531,0.10692667,6.90374134,0.28311179,0.10692667,6.96195653,0.27951042,0.00218,6.97065101,0.30722531,0.21167333,6.90374134,0.28671316,0.21167333,6.95326205,0.30722531,0.31642,6.90374134,0.29031453,0.31642,6.94456758,0.25210869,0.09383333,7.03680463,0.25179553,0.00218,7.03756067,0.25242185,0.18548667,7.03604859,0.25273501,0.27714,7.03529255,0.21985294,0.05782667,7.1146769,0.22408063,0.00218,7.10447034,0.21562524,0.11347333,7.12488346,0.21139755,0.16912,7.13509002,0.19636574,0.02509333,7.17138,0.19636574,0.00218,7.17138,0.19636574,0.04800667,7.17138,0.19636574,0.07092,7.17138,0.30461645,0.00218,6.90234688,0.30461645,0.10692667,6.90234688,0.26960904,0.10692667,6.95473916,0.26438066,0.00218,6.96256398,0.30461645,0.21167333,6.90234688,0.27483742,0.21167333,6.94691434,0.30461645,0.31642,6.90234688,0.2800658,0.31642,6.93908952,0.22459952,0.09383333,7.02210067,0.22414487,0.00218,7.02278109,0.22505416,0.18548667,7.02142025,0.2255088,0.27714,7.02073983,0.17777143,0.05782667,7.09218386,0.18390909,0.00218,7.0829982,0.17163377,0.11347333,7.10136952,0.1654961,0.16912,7.11055518,0.1436733,0.02509333,7.14321531,0.1436733,0.00218,7.14321531,0.1436733,0.04800667,7.14321531,0.1436733,0.07092,7.14321531,0.30232976,0.00218,6.90047024,0.30232976,0.10692667,6.90047024,0.25777378,0.10692667,6.94502622,0.25111932,0.00218,6.95168068,0.30232976,0.21167333,6.90047024,0.26442825,0.21167333,6.93837175,0.30232976,0.31642,6.90047024,0.27108271,0.31642,6.93171729,0.20048753,0.09383333,7.00231247,0.19990888,0.00218,7.00289112,0.20106618,0.18548667,7.00173382,0.20164482,0.27714,7.00115518,0.14088667,0.05782667,7.06191333,0.14869844,0.00218,7.05410156,0.13307491,0.11347333,7.06972509,0.12526315,0.16912,7.07753685,0.097488,0.02509333,7.105312,0.097488,0.00218,7.105312,0.097488,0.04800667,7.105312,0.097488,0.07092,7.105312,0.30045312,0.00218,6.89818355,0.30045312,0.10692667,6.89818355,0.24806084,0.10692667,6.93319096,0.24023602,0.00218,6.93841934,0.30045312,0.21167333,6.89818355,0.25588566,0.21167333,6.92796258,0.30045312,0.31642,6.89818355,0.26371048,0.31642,6.9227342,0.18069933,0.09383333,6.97820048,0.18001891,0.00218,6.97865513,0.18137975,0.18548667,6.97774584,0.18206017,0.27714,6.9772912,0.11061614,0.05782667,7.02502857,0.1198018,0.00218,7.01889091,0.10143048,0.11347333,7.03116623,0.09224482,0.16912,7.0373039,0.05958469,0.02509333,7.0591267,0.05958469,0.00218,7.0591267,0.05958469,0.04800667,7.0591267,0.05958469,0.07092,7.0591267,0.29905866,0.00218,6.89557469,0.29905866,0.10692667,6.89557469,0.24084347,0.10692667,6.91968821,0.23214899,0.00218,6.92328958,0.29905866,0.21167333,6.89557469,0.24953795,0.21167333,6.91608684,0.29905866,0.31642,6.89557469,0.25823242,0.31642,6.91248547,0.16599537,0.09383333,6.95069131,0.16523933,0.00218,6.95100447,0.16675141,0.18548667,6.95037815,0.16750745,0.27714,6.95006499,0.0881231,0.05782667,6.98294706,0.09832966,0.00218,6.97871937,0.07791654,0.11347333,6.98717476,0.06770998,0.16912,6.99140245,0.03142,0.02509333,7.00643426,0.03142,0.00218,7.00643426,0.03142,0.04800667,7.00643426,0.03142,0.07092,7.00643426,0.29819995,0.00218,6.89274391,0.29819995,0.10692667,6.89274391,0.23639903,0.10692667,6.90503688,0.22716903,0.00218,6.90687284,0.29819995,0.21167333,6.89274391,0.24562904,0.21167333,6.90320092,0.29819995,0.31642,6.89274391,0.25485905,0.31642,6.90136495,0.15694072,0.09383333,6.92084212,0.15613811,0.00218,6.92100177,0.15774332,0.18548667,6.92068247,0.15854593,0.27714,6.92052282,0.07427196,0.05782667,6.93728596,0.08510718,0.00218,6.9351307,0.06343673,0.11347333,6.93944122,0.05260151,0.16912,6.94159648,0.01407626,0.02509333,6.94925963,0.01407626,0.00218,6.94925963,0.01407626,0.04800667,6.94925963,0.01407626,0.07092,6.94925963,0.29792818,0.00218,6.89054043,0.29792818,0.10692667,6.89054043,0.23499241,0.10692667,6.89363227,0.22559291,0.00218,6.89409403,0.29792818,0.21167333,6.89054043,0.24439191,0.21167333,6.8931705,0.29792818,0.31642,6.89054043,0.25379141,0.31642,6.89270873,0.154075,0.09383333,6.89760748,0.15325765,0.00218,6.89764764,0.15489234,0.18548667,6.89756733,0.15570969,0.27714,6.89752718,0.06988819,0.05782667,6.90174332,0.08092238,0.00218,6.90120124,0.058854,0.11347333,6.90228539,0.04781981,0.16912,6.90282747,0.00858712,0.02509333,6.90475485,0.00858712,0.00218,6.90475485,0.00858712,0.04800667,6.90475485,0.00858712,0.07092,6.90475485,0.29791,0.00218,6.820902,0.29791,0.10692667,6.820902,0.23489833,0.10692667,6.820902,0.2254875,0.00218,6.820902,0.29791,0.21167333,6.820902,0.24430917,0.21167333,6.820902,0.29791,0.31642,6.820902,0.25372,0.31642,6.820902,0.15388333,0.09383333,6.820902,0.153065,0.00218,6.820902,0.15470167,0.18548667,6.820902,0.15552,0.27714,6.820902,0.069595,0.05782667,6.820902,0.0806425,0.00218,6.820902,0.0585475,0.11347333,6.820902,0.0475,0.16912,6.820902,0.00822,0.02509333,6.820902,0.00822,0.00218,6.820902,0.00822,0.04800667,6.820902,0.00822,0.07092,6.820902],200,3) - sConn=DataArrayInt([0,1,2,3,20,21,22,23,1,4,5,2,21,24,25,22,4,6,7,5,24,26,27,25,3,2,8,9,23,22,28,29,2,5,10,8,22,25,30,28,5,7,11,10,25,27,31,30,9,8,12,13,29,28,32,33,8,10,14,12,28,30,34,32,10,11,15,14,30,31,35,34,13,12,16,17,33,32,36,37,12,14,18,16,32,34,38,36,14,15,19,18,34,35,39,38,20,21,22,23,40,41,42,43,21,24,25,22,41,44,45,42,24,26,27,25,44,46,47,45,23,22,28,29,43,42,48,49,22,25,30,28,42,45,50,48,25,27,31,30,45,47,51,50,29,28,32,33,49,48,52,53,28,30,34,32,48,50,54,52,30,31,35,34,50,51,55,54,33,32,36,37,53,52,56,57,32,34,38,36,52,54,58,56,34,35,39,38,54,55,59,58,40,41,42,43,60,61,62,63,41,44,45,42,61,64,65,62,44,46,47,45,64,66,67,65,43,42,48,49,63,62,68,69,42,45,50,48,62,65,70,68,45,47,51,50,65,67,71,70,49,48,52,53,69,68,72,73,48,50,54,52,68,70,74,72,50,51,55,54,70,71,75,74,53,52,56,57,73,72,76,77,52,54,58,56,72,74,78,76,54,55,59,58,74,75,79,78,60,61,62,63,80,81,82,83,61,64,65,62,81,84,85,82,64,66,67,65,84,86,87,85,63,62,68,69,83,82,88,89,62,65,70,68,82,85,90,88,65,67,71,70,85,87,91,90,69,68,72,73,89,88,92,93,68,70,74,72,88,90,94,92,70,71,75,74,90,91,95,94,73,72,76,77,93,92,96,97,72,74,78,76,92,94,98,96,74,75,79,78,94,95,99,98,80,81,82,83,100,101,102,103,81,84,85,82,101,104,105,102,84,86,87,85,104,106,107,105,83,82,88,89,103,102,108,109,82,85,90,88,102,105,110,108,85,87,91,90,105,107,111,110,89,88,92,93,109,108,112,113,88,90,94,92,108,110,114,112,90,91,95,94,110,111,115,114,93,92,96,97,113,112,116,117,92,94,98,96,112,114,118,116,94,95,99,98,114,115,119,118,100,101,102,103,120,121,122,123,101,104,105,102,121,124,125,122,104,106,107,105,124,126,127,125,103,102,108,109,123,122,128,129,102,105,110,108,122,125,130,128,105,107,111,110,125,127,131,130,109,108,112,113,129,128,132,133,108,110,114,112,128,130,134,132,110,111,115,114,130,131,135,134,113,112,116,117,133,132,136,137,112,114,118,116,132,134,138,136,114,115,119,118,134,135,139,138,120,121,122,123,140,141,142,143,121,124,125,122,141,144,145,142,124,126,127,125,144,146,147,145,123,122,128,129,143,142,148,149,122,125,130,128,142,145,150,148,125,127,131,130,145,147,151,150,129,128,132,133,149,148,152,153,128,130,134,132,148,150,154,152,130,131,135,134,150,151,155,154,133,132,136,137,153,152,156,157,132,134,138,136,152,154,158,156,134,135,139,138,154,155,159,158,140,141,142,143,160,161,162,163,141,144,145,142,161,164,165,162,144,146,147,145,164,166,167,165,143,142,148,149,163,162,168,169,142,145,150,148,162,165,170,168,145,147,151,150,165,167,171,170,149,148,152,153,169,168,172,173,148,150,154,152,168,170,174,172,150,151,155,154,170,171,175,174,153,152,156,157,173,172,176,177,152,154,158,156,172,174,178,176,154,155,159,158,174,175,179,178,160,161,162,163,180,181,182,183,161,164,165,162,181,184,185,182,164,166,167,165,184,186,187,185,163,162,168,169,183,182,188,189,162,165,170,168,182,185,190,188,165,167,171,170,185,187,191,190,169,168,172,173,189,188,192,193,168,170,174,172,188,190,194,192,170,171,175,174,190,191,195,194,173,172,176,177,193,192,196,197,172,174,178,176,192,194,198,196,174,175,179,178,194,195,199,198]) - s=MEDCoupling1SGTUMesh("target",NORM_HEXA8) ; s.setCoords(sCoo) - s.setNodalConnectivity(sConn) - # - tCoo=DataArrayDouble([0.328,0.012,6.8598,0.328,0.168320184237353,6.8598,0.328,0.324640368474706,6.8598,0.328,0.0,6.8598,0.298,0.012,6.8598,0.1565,0.012,6.8598,0.180205346493166,0.144794653506834,6.8598,0.298,0.168320184237353,6.8598,0.0,0.012,6.8598,0.0916755774886107,0.233324422511389,6.8598,0.298,0.324640368474706,6.8598,0.298,0.0,6.8598,0.1565,0.0,6.8598,0.0,0.0,6.8598,0.328,0.012,7.2298,0.328,0.168320184237353,7.2298,0.328,0.324640368474706,7.2298,0.328,0.0,7.2298,0.298,0.012,7.2298,0.1565,0.012,7.2298,0.180205346493166,0.144794653506834,7.2298,0.298,0.168320184237353,7.2298,0.0,0.012,7.2298,0.0916755774886107,0.233324422511389,7.2298,0.298,0.324640368474706,7.2298,0.298,0.0,7.2298,0.1565,0.0,7.2298,0.0,0.0,7.2298],28,3) - tConn=DataArrayInt([4,5,6,7,18,19,20,21,5,8,9,6,19,22,23,20,6,9,10,7,20,23,24,21,11,12,5,4,25,26,19,18,12,13,8,5,26,27,22,19,3,11,4,0,17,25,18,14,0,4,7,1,14,18,21,15,1,7,10,2,15,21,24,16]) - t=MEDCoupling1SGTUMesh("target",NORM_HEXA8) ; t.setCoords(tCoo) - t.setNodalConnectivity(tConn) - # - s.simplexize(PLANAR_FACE_5) - aRemapper=MEDCouplingRemapper() - aRemapper.setPrecision(1e-12) - aRemapper.setIntersectionType(Barycentric) - self.assertEqual(aRemapper.prepare(s,t,'P1P1'),1) - m=aRemapper.getCrudeMatrix() - self.assertEqual(len(m),28) - for i in xrange(28): - if i not in [5,6]: - self.assertEqual(len(m[i]),0) - pass - pass - self.assertEqual(len(m[5]),4) - self.assertEqual(len(m[6]),4) - self.assertAlmostEqual(0.10714286103952797,m[5][168],12) - self.assertAlmostEqual(0.35691534416938014,m[5][169],12) - self.assertAlmostEqual(0.04492099619713096,m[5][163],12) - self.assertAlmostEqual(0.49102079859396097,m[5][189],12) - self.assertAlmostEqual(0.14039089397104254,m[6][185],12) - self.assertAlmostEqual(0.16362822318261033,m[6][162],12) - self.assertAlmostEqual(0.3438363717836785 ,m[6][188],12) - self.assertAlmostEqual(0.3521445110626687 ,m[6][170],12) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def testGetCrudeCSRMatrix1(self): - """ testing CSR matrix output using numpy/scipy. - """ - from scipy.sparse import spdiags #diags - import scipy - from numpy import array - arr=DataArrayDouble(3) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - src=m.buildUnstructured() - trg=src.deepCpy() ; trg=trg[[0,1,3]] - trg.getCoords()[:]*=0.5 ; trg.getCoords()[:]+=[0.3,0.25] - # Let's interpolate. - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - # Internal crude sparse matrix computed. Let's manipulate it using CSR matrix in scipy. - for i in xrange(10): - m=rem.getCrudeCSRMatrix() - pass - m2=rem.getCrudeCSRMatrix() - diff=m-m2 - self.assertTrue(isinstance(m,scipy.sparse.csr.csr_matrix)) - self.assertEqual(m.getnnz(),7) - self.assertAlmostEqual(m[0,0],0.25,12) - self.assertAlmostEqual(m[1,0],0.1,12) - self.assertAlmostEqual(m[1,1],0.15,12) - self.assertAlmostEqual(m[2,0],0.05,12) - self.assertAlmostEqual(m[2,1],0.075,12) - self.assertAlmostEqual(m[2,2],0.05,12) - self.assertAlmostEqual(m[2,3],0.075,12) - self.assertEqual(diff.getnnz(),0) - # IntegralGlobConstraint (division by sum of cols) - colSum=m.sum(axis=0) - # version 0.12.0 # m_0=m*diags(array(1/colSum),[0]) - m_0=m*spdiags(array(1/colSum),[0],colSum.shape[1],colSum.shape[1]) - del colSum - self.assertAlmostEqual(m_0[0,0],0.625,12) - self.assertAlmostEqual(m_0[1,0],0.25,12) - self.assertAlmostEqual(m_0[1,1],0.6666666666666667,12) - self.assertAlmostEqual(m_0[2,0],0.125,12) - self.assertAlmostEqual(m_0[2,1],0.3333333333333333,12) - self.assertAlmostEqual(m_0[2,2],1.,12) - self.assertAlmostEqual(m_0[2,3],1.,12) - self.assertEqual(m_0.getnnz(),7) - # ConservativeVolumic (division by sum of rows) - rowSum=m.sum(axis=1) - # version 0.12.0 # m_1=diags(array(1/rowSum.transpose()),[0])*m - m_1=spdiags(array(1/rowSum.transpose()),[0],rowSum.shape[0],rowSum.shape[0])*m - del rowSum - self.assertAlmostEqual(m_1[0,0],1.,12) - self.assertAlmostEqual(m_1[1,0],0.4,12) - self.assertAlmostEqual(m_1[1,1],0.6,12) - self.assertAlmostEqual(m_1[2,0],0.2,12) - self.assertAlmostEqual(m_1[2,1],0.3,12) - self.assertAlmostEqual(m_1[2,2],0.2,12) - self.assertAlmostEqual(m_1[2,3],0.3,12) - self.assertEqual(m_1.getnnz(),7) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def testP0P1Bary_1(self): - a=MEDCouplingUMesh("a",2) - a.allocateCells() - conna=[0,1,3,2,1,4,5,3,4,6,7,5,6,8,9,7,8,10,11,9,10,12,13,11,12,14,15,13,14,16,17,15,16,18,19,17,18,20,21,19,20,22,23,21,22,24,25,23,24,26,27,25] - a.setCoords(DataArrayDouble([1.54,0,-0.01,1.54,0.02,-0.01,1.54,0,0.01,1.54,0.02,0.01,1.54,0.04,-0.01,1.54,0.04,0.01,1.54,0.06,-0.01,1.54,0.06,0.01,1.54,0.08,-0.01,1.54,0.08,0.01,1.54,0.1,-0.01,1.54,0.1,0.01,1.54,0.12,-0.01,1.54,0.12,0.01,1.54,0.14,-0.01,1.54,0.14,0.01,1.54,0.16,-0.01,1.54,0.16,0.01,1.54,0.18,-0.01,1.54,0.18,0.01,1.54,0.2,-0.01,1.54,0.2,0.01,1.54,0.22,-0.01,1.54,0.22,0.01,1.54,0.24,-0.01,1.54,0.24,0.01,1.54,0.26,-0.01,1.54,0.26,0.01],28,3)) - for i in xrange(13): - a.insertNextCell(NORM_QUAD4,conna[4*i:4*(i+1)]) - pass - a.finishInsertingCells() ; a.simplexize(0) - # - connb=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,0,2,39,3,5,40,6,8,41,9,11,42,12,14,43,15,17,44,18,20,45,21,23,46,24,26,47,27,29,48,30,32,49,33,35,50,36,38,51,52,2,39,53,5,40,54,8,41,55,11,42,56,14,43,57,17,44,58,20,45,59,23,46,60,26,47,61,29,48,62,32,49,63,35,50,64,38,51,52,2,65,53,5,66,54,8,67,55,11,68,56,14,69,57,17,70,58,20,71,59,23,72,60,26,73,61,29,74,62,32,75,63,35,76,64,38,77,53,2,65,54,5,66,55,8,67,56,11,68,57,14,69,58,17,70,59,20,71,60,23,72,61,26,73,62,29,74,63,32,75,64,35,76,78,38,77,53,2,40,54,5,41,55,8,42,56,11,43,57,14,44,58,17,45,59,20,46,60,23,47,61,26,48,62,29,49,63,32,50,64,35,51,78,38,79,3,2,40,6,5,41,9,8,42,12,11,43,15,14,44,18,17,45,21,20,46,24,23,47,27,26,48,30,29,49,33,32,50,36,35,51,80,38,79,3,2,1,6,5,4,9,8,7,12,11,10,15,14,13,18,17,16,21,20,19,24,23,22,27,26,25,30,29,28,33,32,31,36,35,34,80,38,37] - b=MEDCouplingUMesh("b",2) - b.allocateCells() - for i in xrange(104): - b.insertNextCell(NORM_TRI3,connb[3*i:3*(i+1)]) - pass - b.setCoords(DataArrayDouble([1.54,0,-0.01,1.54,0.01,-0.01,1.54,0.01,0,1.54,0.02,-0.01,1.54,0.03,-0.01,1.54,0.03,0,1.54,0.04,-0.01,1.54,0.05,-0.01,1.54,0.05,0,1.54,0.06,-0.01,1.54,0.07,-0.01,1.54,0.07,0,1.54,0.08,-0.01,1.54,0.09,-0.01,1.54,0.09,0,1.54,0.1,-0.01,1.54,0.11,-0.01,1.54,0.11,0,1.54,0.12,-0.01,1.54,0.13,-0.01,1.54,0.13,0,1.54,0.14,-0.01,1.54,0.15,-0.01,1.54,0.15,0,1.54,0.16,-0.01,1.54,0.17,-0.01,1.54,0.17,0,1.54,0.18,-0.01,1.54,0.19,-0.01,1.54,0.19,0,1.54,0.2,-0.01,1.54,0.21,-0.01,1.54,0.21,0,1.54,0.22,-0.01,1.54,0.23,-0.01,1.54,0.23,0,1.54,0.24,-0.01,1.54,0.25,-0.01,1.54,0.25,0,1.54,0,0,1.54,0.02,0,1.54,0.04,0,1.54,0.06,0,1.54,0.08,0,1.54,0.1,0,1.54,0.12,0,1.54,0.14,0,1.54,0.16,0,1.54,0.18,0,1.54,0.2,0,1.54,0.22,0,1.54,0.24,0,1.54,0,0.01,1.54,0.02,0.01,1.54,0.04,0.01,1.54,0.06,0.01,1.54,0.08,0.01,1.54,0.1,0.01,1.54,0.12,0.01,1.54,0.14,0.01,1.54,0.16,0.01,1.54,0.18,0.01,1.54,0.2,0.01,1.54,0.22,0.01,1.54,0.24,0.01,1.54,0.01,0.01,1.54,0.03,0.01,1.54,0.05,0.01,1.54,0.07,0.01,1.54,0.09,0.01,1.54,0.11,0.01,1.54,0.13,0.01,1.54,0.15,0.01,1.54,0.17,0.01,1.54,0.19,0.01,1.54,0.21,0.01,1.54,0.23,0.01,1.54,0.25,0.01,1.54,0.26,0.01,1.54,0.26,0,1.54,0.26,-0.01],81,3)) - # - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Barycentric) - rem.prepare(a,b,"P1P0") - m0=rem.getCrudeCSRMatrix() - self.assertEqual(m0.nnz,312) - # - ids=4*[None] ; vs=4*[None] - ids[0]=DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,158,161,164,167,170,173,176,179,182,185,188,191,194,197,200,203,206,209,212,215,218,221,224,227,230,233]) ; vs[0]=10./3. - ids[1]=DataArrayInt([1,2,4,5,7,8,10,11,13,14,16,17,19,20,22,23,25,26,28,29,31,32,34,35,37,38,40,41,43,44,46,47,49,50,52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,76,77,80,83,86,89,92,95,98,101,104,107,110,113,116,117,120,123,126,129,132,135,138,141,144,147,150,153,156,157,159,160,162,163,165,166,168,169,171,172,174,175,177,178,180,181,183,184,186,187,189,190,192,193,195,196,198,199,201,202,204,205,207,208,210,211,213,214,216,217,219,220,222,223,225,226,228,229,231,232,234,237,240,243,246,249,252,255,258,261,264,267,270,275,278,281,284,287,290,293,296,299,302,305,308,311]) ; vs[1]=5./6. - ids[2]=DataArrayInt([78,81,84,87,90,93,96,99,102,105,108,111,114,119,122,125,128,131,134,137,140,143,146,149,152,155,236,239,242,245,248,251,254,257,260,263,266,269,272,273,276,279,282,285,288,291,294,297,300,303,306,309]) ; vs[2]=5./3. - ids[3]=DataArrayInt([79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,235,238,241,244,247,250,253,256,259,262,265,268,271,274,277,280,283,286,289,292,295,298,301,304,307,310]) ; vs[3]=2.5 - vals=DataArrayDouble(312,1) - for idd,v in zip(ids,vs): - vals[idd]=v - pass - vals*=1e-5 - eps0=DataArrayDouble(m0.data)-vals ; eps0.abs() - self.assertTrue(eps0.getIdsInRange(1e-17,1e300).empty()) - self.assertTrue(DataArrayInt(m0.indices).isEqual(DataArrayInt([0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27]))) - self.assertTrue(DataArrayInt(m0.indptr).isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,303,306,309,312]))) - # - rem2=MEDCouplingRemapper() ; rem2.setIntersectionType(Barycentric) - rem2.prepare(b,a,"P0P1") - m1=rem2.getCrudeCSRMatrix() - self.assertEqual(m1.nnz,312) - # - m1=rem2.getCrudeCSRMatrix() - m1t=m1.transpose() - delta=m0-m1t - self.assertTrue(DataArrayDouble(delta.data).isUniform(0.,1e-17)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def testNonConformWithRemapper_1(self): - coo=DataArrayDouble([-0.396700000780411,-0.134843245350081,-0.0361311386958691,-0.407550009429364,-0.13484324535008,-0.0361311386958923,-0.396700000780411,-0.132191446077668,-0.0448729493559049,-0.407550009429364,-0.132191446077666,-0.0448729493559254,-0.396700000780411,-0.128973582738749,-0.0534226071577727,-0.407550009429364,-0.128973582738747,-0.0534226071577904,-0.396700000780411,-0.128348829636458,-0.0346583696473619,-0.407550009429364,-0.128348829636457,-0.0346583696473822,-0.396700000780411,-0.125874740261886,-0.0430683597970123,-0.407550009429364,-0.125874740261885,-0.0430683597970302,-0.396700000780411,-0.122905344829122,-0.051310216195766,-0.407550009429364,-0.12290534482912,-0.0513102161957814],12,3) - conn=DataArrayInt([2,9,3,11,2,3,5,11,2,8,9,11,2,10,8,11,2,5,4,11,2,4,10,11,3,0,1,6,3,1,7,6,3,2,0,6,3,8,2,6,3,7,9,6,3,9,8,6]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) - m.setNodalConnectivity(conn) - m.setCoords(coo) - # m is ready - m1,d,di,rd,rdi=m.buildUnstructured().buildDescendingConnectivity() - rdi2=rdi.deltaShiftIndex() - cellIds=rdi2.getIdsEqual(1) - skinAndNonConformCells=m1[cellIds] - skinAndNonConformCells.zipCoords() # at this point skinAndNonConformCells contains non conform cells and skin cells. Now trying to split them in two parts. - # - rem=MEDCouplingRemapper() - rem.setMaxDistance3DSurfIntersect(1e-12) - rem.setMinDotBtwPlane3DSurfIntersect(0.99)# this line is important it is to tell to remapper to select only cells with very close orientation - rem.prepare(skinAndNonConformCells,skinAndNonConformCells,"P0P0") - mat=rem.getCrudeCSRMatrix() - indptr=DataArrayInt(mat.indptr) - indptr2=indptr.deltaShiftIndex() - cellIdsOfNonConformCells=indptr2.getIdsNotEqual(1) - cellIdsOfSkin=indptr2.getIdsEqual(1) - self.assertTrue(cellIdsOfSkin.isEqual(DataArrayInt([1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,23]))) - self.assertTrue(cellIdsOfNonConformCells.isEqual(DataArrayInt([0,4,18,22]))) - pass - - def test3D1DOnP1P0_1(self): - """ This test focused on P1P0 interpolation with a source with meshDim=1 spaceDim=3 and a target with meshDim=3. - This test has revealed a bug in remapper. A reverse matrix is computed so a reverse method should be given in input. - """ - target=MEDCouplingCMesh() - arrX=DataArrayDouble([0,1]) ; arrY=DataArrayDouble([0,1]) ; arrZ=DataArrayDouble(11) ; arrZ.iota() - target.setCoords(arrX,arrY,arrZ) - target=target.buildUnstructured() ; target.setName("TargetSecondaire") - # - sourceCoo=DataArrayDouble([(0.5,0.5,0.1),(0.5,0.5,1.2),(0.5,0.5,1.6),(0.5,0.5,1.8),(0.5,0.5,2.43),(0.5,0.5,2.55),(0.5,0.5,4.1),(0.5,0.5,4.4),(0.5,0.5,4.9),(0.5,0.5,5.1),(0.5,0.5,7.6),(0.5,0.5,7.7),(0.5,0.5,8.2),(0.5,0.5,8.4),(0.5,0.5,8.6),(0.5,0.5,8.8),(0.5,0.5,9.2),(0.5,0.5,9.6),(0.5,0.5,11.5)]) - source=MEDCoupling1SGTUMesh("SourcePrimaire",NORM_SEG2) - source.setCoords(sourceCoo) - source.allocateCells() - for i in xrange(len(sourceCoo)-1): - source.insertNextCell([i,i+1]) - pass - source=source.buildUnstructured() - fsource=MEDCouplingFieldDouble(ON_NODES) ; fsource.setName("field") - fsource.setMesh(source) - arr=DataArrayDouble(len(sourceCoo)) ; arr.iota(0.7) ; arr*=arr - fsource.setArray(arr) - fsource.setNature(ConservativeVolumic) - # - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - rem.prepare(source,target,"P1P0") - f2Test=rem.transferField(fsource,-27) - self.assertEqual(f2Test.getName(),fsource.getName()) - self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),target.getHiddenCppPointer()) - expArr=DataArrayDouble([0.49,7.956666666666667,27.29,-27,59.95666666666667,94.09,-27,125.69,202.89,296.09]) - self.assertTrue(f2Test.getArray().isEqual(expArr,1e-12)) - f2Test=rem.reverseTransferField(f2Test,-36) - self.assertEqual(f2Test.getName(),fsource.getName()) - self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),source.getHiddenCppPointer()) - expArr2=DataArrayDouble([0.49,7.956666666666667,7.956666666666667,7.956666666666667,27.29,27.29,59.95666666666667,59.95666666666667,59.95666666666667,94.09,125.69,125.69,202.89,202.89,202.89,202.89,296.09,296.09,-36.]) - self.assertTrue(f2Test.getArray().isEqual(expArr2,1e-12)) - pass - - def testRemapperAMR1(self): - """ This test is the origin of the ref values for MEDCouplingBasicsTest.testAMR2""" - coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 - fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 - MEDCouplingIMesh.CondenseFineToCoarse([5,7],fine,[(1,4),(2,4)],[4,4],coarse) - # - m=MEDCouplingCartesianAMRMesh("mesh",2,[6,8],[0.,0.],[1.,1.]) - trgMesh=m.buildUnstructured() - m.addPatch([(1,4),(2,4)],[4,4]) - srcMesh=m[0].getMesh().buildUnstructured() - srcField=MEDCouplingFieldDouble(ON_CELLS) - fine2=DataArrayDouble(3*2*4*4) ; fine2.iota(0) ; srcField.setArray(fine2) - srcField.setMesh(srcMesh) ; srcField.setNature(Integral) - # - trgField=MEDCouplingFieldDouble(ON_CELLS) - coarse2=DataArrayDouble(35) ; coarse2.iota(0) ; trgField.setArray(coarse2) - trgField.setMesh(trgMesh) ; trgField.setNature(Integral) - # - rem=MEDCouplingRemapper() - rem.prepare(srcMesh,trgMesh,"P0P0") - rem.partialTransfer(srcField,trgField) - # - self.assertTrue(coarse.isEqual(trgField.getArray(),1e-12)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def test1DPointLocator1(self): - """This test focuses on PointLocator for P1P1 in 1D and 2DCurve.""" - from numpy import array - from scipy.sparse import diags,csr_matrix,identity - ## basic case 1D - arrS=DataArrayInt.Range(0,11,1).convertToDblArr() - arrT=DataArrayDouble([0.1,1.7,5.5,9.6]) - mS=MEDCouplingCMesh() ; mS.setCoords(arrS) - mT=MEDCouplingCMesh() ; mT.setCoords(arrT) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS.buildUnstructured(),mT.buildUnstructured(),"P1P1"),1) - m=rem.getCrudeCSRMatrix() - rowSum=m.sum(axis=1) - m=diags(array(1/rowSum.transpose()),[0])*m - # expected matrix - row=array([0,0,1,1,2,2,3,3]) - col=array([0,1,1,2,5,6,9,10]) - data=array([0.9,0.1,0.3,0.7,0.5,0.5,0.4,0.6]) - mExp0=csr_matrix((data,(row,col)),shape=(4,11)) - # compute diff and check - diff=abs(m-mExp0) - self.assertAlmostEqual(diff.max(),0.,14) - ## full specific case 1D where target=source - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS.buildUnstructured(),mS.buildUnstructured(),"P1P1"),1) - m=rem.getCrudeCSRMatrix() - rowSum=m.sum(axis=1) - m=diags(array(1/rowSum.transpose()),[0])*m - # expected matrix - mExp1=identity(11) - diff=abs(m-mExp1) - self.assertAlmostEqual(diff.max(),0.,14) - ## case where some points in target are not in source - arrT=DataArrayDouble([-0.2,0.1,1.7,5.5,10.3]) - mT=MEDCouplingCMesh() ; mT.setCoords(arrT) - mT=mT.buildUnstructured() - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS.buildUnstructured(),mT,"P1P1"),1) - m=rem.getCrudeCSRMatrix() - row=array([1,1,2,2,3,3]) - col=array([0,1,1,2,5,6]) - data=array([0.9,0.1,0.3,0.7,0.5,0.5]) - mExp2=csr_matrix((data,(row,col)),shape=(5,11)) - diff=abs(m-mExp2) - self.assertAlmostEqual(diff.max(),0.,14) - ## basic case 2D Curve - arrS=DataArrayInt.Range(0,11,1).convertToDblArr() - arrT=DataArrayDouble([0.1,1.7,5.5,9.6]) - mS=MEDCouplingCMesh() ; mS.setCoords(arrS) - mT=MEDCouplingCMesh() ; mT.setCoords(arrT) - mS=mS.buildUnstructured() ; mS.changeSpaceDimension(2) - mT=mT.buildUnstructured() ; mT.changeSpaceDimension(2) - mS.rotate([-1.,-1.],1.2) - mT.rotate([-1.,-1.],1.2) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS,mT,"P1P1"),1) - m=rem.getCrudeCSRMatrix() - rowSum=m.sum(axis=1) - m=diags(array(1/rowSum.transpose()),[0])*m - diff=abs(m-mExp0) - self.assertAlmostEqual(diff.max(),0.,14) - pass - - def build2DSourceMesh_1(self): - sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] - sourceConn=[0,3,1,0,2,3] - sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2) - sourceMesh.allocateCells(2); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); - sourceMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(sourceCoords,4,2); - sourceMesh.setCoords(myCoords); - return sourceMesh; - - def build2DTargetMesh_1(self): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DTargetMesh_3(self): - targetCoords=[-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, -0.6,1.1, -0.1,1.1] - targetConn=[0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(4); - for i in xrange(4): - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[4*i:4*(i+1)]) - pass - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,10,2); - targetMesh.setCoords(myCoords); - return targetMesh; - pass - - def setUp(self): - pass - pass - -unittest.main() diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i b/medtool/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i deleted file mode 100644 index 411033e59..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -namespace ParaMEDMEM -{ - class MEDCouplingTimeDiscretization : public TimeLabel, public BigMemoryObject - { - public: - static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type) throw(INTERP_KERNEL::Exception); - void setTimeUnit(const char *unit); - const char *getTimeUnit() const; - virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception); - virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const throw(INTERP_KERNEL::Exception); - virtual std::string getStringRepr() const throw(INTERP_KERNEL::Exception); - virtual TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception); - virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - void setTimeTolerance(double val); - double getTimeTolerance() const; - virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); - virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); - virtual void setArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception); - virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception); - virtual void setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception); - DataArrayDouble *getArray() throw(INTERP_KERNEL::Exception); - const DataArrayDouble *getArray() const throw(INTERP_KERNEL::Exception); - virtual const DataArrayDouble *getEndArray() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getEndArray() throw(INTERP_KERNEL::Exception); - virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); - virtual void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception); - virtual void getArrays(std::vector& arrays) const throw(INTERP_KERNEL::Exception); - virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - double getTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); - virtual double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); - virtual double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); - void setTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); - void setIteration(int it) throw(INTERP_KERNEL::Exception); - void setOrder(int order) throw(INTERP_KERNEL::Exception); - void setTimeValue(double val) throw(INTERP_KERNEL::Exception); - virtual void setStartIteration(int it) throw(INTERP_KERNEL::Exception); - virtual void setEndIteration(int it) throw(INTERP_KERNEL::Exception); - virtual void setStartOrder(int order) throw(INTERP_KERNEL::Exception); - virtual void setEndOrder(int order) throw(INTERP_KERNEL::Exception); - virtual void setStartTimeValue(double time) throw(INTERP_KERNEL::Exception); - virtual void setEndTimeValue(double time) throw(INTERP_KERNEL::Exception); - virtual void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); - virtual void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); - virtual void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); - virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); - // - virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *determinant() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *eigenValues() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *eigenVectors() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *inverse() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *trace() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *deviator() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *magnitude() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *negate() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *maxPerTuple() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); - virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); - virtual void changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception); - virtual void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value) throw(INTERP_KERNEL::Exception); - virtual void setOrCreateUniformValueOnAllComponents(int nbOfTuple, double value) throw(INTERP_KERNEL::Exception); - virtual void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); - virtual void applyFunc(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); - virtual void applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); - virtual void applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); - virtual void applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception); - virtual void applyFunc(const char *func) throw(INTERP_KERNEL::Exception); - virtual void applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception); - virtual void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception); - virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); - virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); - virtual void fillFromAnalytic2(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); - virtual void fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception); - // - virtual ~MEDCouplingTimeDiscretization(); - }; - - class MEDCouplingNoTimeLabel : public MEDCouplingTimeDiscretization - { - public: - MEDCouplingNoTimeLabel(); - MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; - static const char REPR[]; - }; - - class MEDCouplingWithTimeStep : public MEDCouplingTimeDiscretization - { - public: - MEDCouplingWithTimeStep(); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; - static const char REPR[]; - }; - - class MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization - { - protected: - MEDCouplingConstOnTimeInterval(); - MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; - static const char REPR[]; - }; - - class MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization - { - }; - - class MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps - { - public: - MEDCouplingLinearTime(); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; - static const char REPR[]; - }; -} - -#endif diff --git a/medtool/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/medtool/src/MEDCoupling_Swig/MEDCouplingTypemaps.i deleted file mode 100644 index 94bed84df..000000000 --- a/medtool/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDCouplingDataArrayTypemaps.i" - -static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!mesh) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingIMesh,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of mesh on downcast !"); - return ret; -} - -static PyObject *convertFieldDiscretization(ParaMEDMEM::MEDCouplingFieldDiscretization *fd, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!fd) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationP0,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationP1,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationGauss,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationGaussNE,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationKriging,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of field discretization on downcast !"); - return ret; -} - -static PyObject* convertMultiFields(ParaMEDMEM::MEDCouplingMultiFields *mfs, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!mfs) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(mfs)) - ret=SWIG_NewPointerObj((void*)mfs,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldOverTime,owner); - else - ret=SWIG_NewPointerObj((void*)mfs,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMultiFields,owner); - return ret; -} - -static PyObject *convertPartDefinition(ParaMEDMEM::PartDefinition *pd, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!pd) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(pd)) - ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__DataArrayPartDefinition,owner); - else - ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__SlicePartDefinition,owner); - return ret; -} - -static PyObject *convertCartesianAMRMesh(ParaMEDMEM::MEDCouplingCartesianAMRMeshGen *mesh, int owner) throw(INTERP_KERNEL::Exception) -{ - if(!mesh) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(mesh)) - { - return SWIG_NewPointerObj(reinterpret_cast(mesh),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRMeshSub,owner); - } - if(dynamic_cast(mesh)) - { - return SWIG_NewPointerObj(reinterpret_cast(mesh),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRMesh,owner); - } - throw INTERP_KERNEL::Exception("convertCartesianAMRMesh wrap : unrecognized type of cartesian AMR mesh !"); -} - -static PyObject *convertDataForGodFather(ParaMEDMEM::MEDCouplingDataForGodFather *data, int owner) throw(INTERP_KERNEL::Exception) -{ - if(!data) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(data)) - { - return SWIG_NewPointerObj(reinterpret_cast(data),SWIGTYPE_p_ParaMEDMEM__MEDCouplingAMRAttribute,owner); - } - throw INTERP_KERNEL::Exception("convertDataForGodFather wrap : unrecognized data type for AMR !"); -} - -static PyObject *convertCartesianAMRPatch(ParaMEDMEM::MEDCouplingCartesianAMRPatchGen *patch, int owner) throw(INTERP_KERNEL::Exception) -{ - if(!patch) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(patch)) - { - return SWIG_NewPointerObj(reinterpret_cast(patch),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRPatchGF,owner); - } - if(dynamic_cast(patch)) - { - return SWIG_NewPointerObj(reinterpret_cast(patch),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRPatch,owner); - } - throw INTERP_KERNEL::Exception("convertCartesianAMRPatch wrap : unrecognized type of cartesian AMR patch !"); -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__add__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__add__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)+(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(1.,val); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),a); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - return ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(self,obj); -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__rsub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__rsub__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*other)-(*self); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(-1.,val); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Substract(a,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Substract(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Substract(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__mul__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__mul__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)*(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(val,0.); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),a); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - return ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(self,obj); -} - -ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__rdiv__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__div__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*other)/(*self); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyInv(val); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Divide(a,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Divide(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Divide(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -static PyObject *NewMethWrapCallInitOnlyIfEmptyDictInInput(PyObject *cls, PyObject *args, const char *clsName) -{ - if(!PyTuple_Check(args)) - { - std::ostringstream oss; oss << clsName << ".__new__ : the args in input is expected to be a tuple !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==0 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - PyObject *tmp3(PyTuple_New(0)); - PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); - Py_XDECREF(tmp2); - Py_DECREF(tmp3); - Py_DECREF(initMeth); - } - return instance; -} diff --git a/medtool/src/MEDLoader/CMakeLists.txt b/medtool/src/MEDLoader/CMakeLists.txt deleted file mode 100644 index 3c4e10bfd..000000000 --- a/medtool/src/MEDLoader/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${XDR_DEFINITIONS}) - -IF(MEDCOUPLING_MED_ENABLE_PYTHON) - ADD_SUBDIRECTORY(Swig) -ENDIF(MEDCOUPLING_MED_ENABLE_PYTHON) - -IF(MEDCOUPLING_BUILD_TESTS) - ADD_SUBDIRECTORY(Test) -ENDIF(MEDCOUPLING_BUILD_TESTS) - -SET(MEDLOADER_XDR_INCLUDE_DIRS) -SET(MEDLOADER_XDR_LIBRARIES) - -IF(WIN32) - IF(MEDCOUPLING_MED_MEDLOADER_USE_XDR) - ADD_DEFINITIONS(-DNOMINMAX) - SET(MEDLOADER_XDR_INCLUDE_DIRS ${XDR_INCLUDE_DIRS}) - SET(MEDLOADER_XDR_LIBRARIES ${XDR_LIBRARIES}) - ENDIF(MEDCOUPLING_MED_MEDLOADER_USE_XDR) -ELSE(WIN32) - SET(MEDLOADER_XDR_INCLUDE_DIRS ${XDR_INCLUDE_DIRS}) -ENDIF(WIN32) - -INCLUDE_DIRECTORIES( - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MEDLOADER_XDR_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SET(medloader_SOURCES - MEDLoader.cxx - MEDLoaderBase.cxx - MEDFileUtilities.cxx - MEDFileMesh.cxx - MEDFileMeshElt.cxx - MEDFileBasis.cxx - MEDFileMeshLL.cxx - MEDFileField.cxx - MEDFileJoint.cxx - MEDFileEquivalence.cxx - MEDFileParameter.cxx - MEDFileData.cxx - MEDFileFieldOverView.cxx - MEDFileMeshReadSelector.cxx - SauvMedConvertor.cxx - SauvReader.cxx - SauvWriter.cxx - ) - -ADD_LIBRARY(medloader SHARED ${medloader_SOURCES}) -SET_TARGET_PROPERTIES(medloader PROPERTIES COMPILE_FLAGS "") -TARGET_LINK_LIBRARIES(medloader medcoupling ${MEDFILE_C_LIBRARIES} ${HDF5_LIBRARIES} ${MEDLOADER_XDR_LIBRARIES}) -INSTALL(TARGETS medloader EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -FILE(GLOB medloader_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") -INSTALL(FILES ${medloader_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -# To allow usage as SWIG dependencies: -SET(medloader_HEADERS_HXX PARENT_SCOPE) diff --git a/medtool/src/MEDLoader/MEDFileBasis.cxx b/medtool/src/MEDLoader/MEDFileBasis.cxx deleted file mode 100644 index 8e61dfb0e..000000000 --- a/medtool/src/MEDLoader/MEDFileBasis.cxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileBasis.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDFileString::MEDFileString(int maxLgth):_max_lgth(maxLgth),_content(new char[maxLgth+1]) -{ - std::fill(_content,_content+maxLgth+1,'\0'); -} - -MEDFileString::~MEDFileString() -{ - delete [] _content; -} - -void MEDFileString::set(const char *s) -{ - if((int)strlen(s)>_max_lgth) - throw INTERP_KERNEL::Exception("Name is too long to be stored in MEDfile !"); - std::fill(_content,_content+_max_lgth+1,'\0'); - strcpy(_content,s); -} - -std::string MEDFileString::getRepr() const -{ - return std::string(_content); -} - diff --git a/medtool/src/MEDLoader/MEDFileBasis.hxx b/medtool/src/MEDLoader/MEDFileBasis.hxx deleted file mode 100644 index 41f402787..000000000 --- a/medtool/src/MEDLoader/MEDFileBasis.hxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEBASIS_HXX__ -#define __MEDFILEBASIS_HXX__ - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDFileString - { - public: - MEDFileString(int maxLgth); - ~MEDFileString(); - void set(const char *s); - char *getPointer() { return _content; } - const char *getReprForWrite() const { return _content; } - std::string getRepr() const; - private: - int _max_lgth; - char *_content; - }; - - - class MEDFileMultiString - { - public: - MEDFileMultiString(int nbOfCompo, int maxLgthPerCompo); - ~MEDFileMultiString(); - void set(int compoId, const char *s); - const char *getReprForWrite() const; - std::vector getRepr() const; - std::string getReprPerComp(int compId) const; - private: - int _nb_of_comp; - int _max_lgth_per_comp; - char *_content; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileData.cxx b/medtool/src/MEDLoader/MEDFileData.cxx deleted file mode 100644 index ca2b84aa3..000000000 --- a/medtool/src/MEDLoader/MEDFileData.cxx +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileData.hxx" - -using namespace ParaMEDMEM; - -MEDFileData *MEDFileData::New(const std::string& fileName) -{ - return new MEDFileData(fileName); -} - -MEDFileData *MEDFileData::New() -{ - return new MEDFileData; -} - -MEDFileData *MEDFileData::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr fields; - if((const MEDFileFields *)_fields) - fields=_fields->deepCpy(); - MEDCouplingAutoRefCountObjectPtr meshes; - if((const MEDFileMeshes *)_meshes) - meshes=_meshes->deepCpy(); - MEDCouplingAutoRefCountObjectPtr params; - if((const MEDFileParameters *)_params) - params=_params->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret(MEDFileData::New()); - ret->_fields=fields; ret->_meshes=meshes; ret->_params=params; - return ret.retn(); -} - -std::size_t MEDFileData::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileData::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDFileFields *)_fields); - ret.push_back((const MEDFileMeshes *)_meshes); - ret.push_back((const MEDFileParameters *)_params); - return ret; - -} - -/** Return a borrowed reference (caller is not responsible for object destruction) */ -MEDFileFields *MEDFileData::getFields() const -{ - return const_cast(static_cast(_fields)); -} - -/** Return a borrowed reference (caller is not responsible for object destruction) */ -MEDFileMeshes *MEDFileData::getMeshes() const -{ - return const_cast(static_cast(_meshes)); -} - -/** Return a borrowed reference (caller is not responsible for object destruction) */ -MEDFileParameters *MEDFileData::getParams() const -{ - return const_cast(static_cast(_params)); -} - -void MEDFileData::setFields(MEDFileFields *fields) -{ - if(fields) - fields->incrRef(); - _fields=fields; -} - -void MEDFileData::setMeshes(MEDFileMeshes *meshes) -{ - if(meshes) - meshes->incrRef(); - _meshes=meshes; -} - -void MEDFileData::setParams(MEDFileParameters *params) -{ - if(params) - params->incrRef(); - _params=params; -} - -int MEDFileData::getNumberOfFields() const -{ - const MEDFileFields *f=_fields; - if(!f) - throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfFields : no fields set !"); - return f->getNumberOfFields(); -} - -int MEDFileData::getNumberOfMeshes() const -{ - const MEDFileMeshes *m=_meshes; - if(!m) - throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfMeshes : no meshes set !"); - return m->getNumberOfMeshes(); -} - -int MEDFileData::getNumberOfParams() const -{ - const MEDFileParameters *p=_params; - if(!p) - throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfParams : no params set !"); - return p->getNumberOfParams(); -} - -std::string MEDFileData::simpleRepr() const -{ - std::ostringstream oss; - oss << "(***************)\n(* MEDFileData *)\n(***************)\n\nFields part :\n*************\n\n"; - const MEDFileFields *tmp=_fields; - if(tmp) - { - tmp->simpleRepr(0,oss); - oss << std::endl; - } - else - oss << "No fields set !!!\n\n"; - oss << "Meshes part :\n*************\n\n"; - const MEDFileMeshes *tmp2=_meshes; - if(tmp2) - { - tmp2->simpleReprWithoutHeader(oss); - } - else - oss << "No meshes set !!!\n\n"; - oss << "Params part :\n*************\n\n"; - const MEDFileParameters *tmp3=_params; - if(tmp3) - { - tmp3->simpleReprWithoutHeader(oss); - } - else - oss << "No params set !!!\n"; - return oss.str(); -} - -bool MEDFileData::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - MEDFileFields *fields=_fields; - if(fields) - ret=fields->changeMeshNames(modifTab) || ret; - MEDFileMeshes *meshes=_meshes; - if(meshes) - ret=meshes->changeNames(modifTab) || ret; - return ret; -} - -bool MEDFileData::changeMeshName(const std::string& oldMeshName, const std::string& newMeshName) -{ - std::string oldName(oldMeshName); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - return changeMeshNames(v); -} - -/*! - * This method performs unpolyzation in meshes in \a this and if it leads to a modification to one or more than one meshes in \a this - * the fields are automatically renumbered (for those impacted, that is to say here fields on cells and fields on gauss points on impacted fields) - * - * \return If true is returned it means that some meshes in \a this has been modified and eventually fields have been renumbered. - * \n If false \a this remains unchanged. - */ -bool MEDFileData::unPolyzeMeshes() -{ - MEDFileMeshes *ms=_meshes; - if(!ms) - return false; - std::vector< MEDFileMesh * > meshesImpacted; - std::vector< DataArrayInt * > renumParamsOfMeshImpacted;//same size as meshesImpacted - std::vector< std::vector > oldCodeOfMeshImpacted,newCodeOfMeshImpacted;//same size as meshesImpacted - std::vector > memSaverIfThrow;//same size as meshesImpacted - for(int i=0;igetNumberOfMeshes();i++) - { - MEDFileMesh *m=ms->getMeshAtPos(i); - if(m) - { - std::vector oldCode,newCode; - DataArrayInt *o2nRenumCell=0; - bool modif=m->unPolyze(oldCode,newCode,o2nRenumCell); - if(!modif) - continue; - renumParamsOfMeshImpacted.push_back(o2nRenumCell); memSaverIfThrow.push_back(o2nRenumCell); - oldCodeOfMeshImpacted.push_back(oldCode); - newCodeOfMeshImpacted.push_back(newCode); - meshesImpacted.push_back(m); - } - } - if(!meshesImpacted.empty()) - { - MEDFileFields *fs=_fields; - if(fs) - for(std::size_t i=0;irenumberEntitiesLyingOnMesh(meshesImpacted[i]->getName(),oldCodeOfMeshImpacted[i],newCodeOfMeshImpacted[i],renumParamsOfMeshImpacted[i]); - } - return !meshesImpacted.empty(); -} - -MEDFileData::MEDFileData() -{ -} - -MEDFileData::MEDFileData(const std::string& fileName) -try -{ - _fields=MEDFileFields::New(fileName); - _meshes=MEDFileMeshes::New(fileName); - _params=MEDFileParameters::New(fileName); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileData::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - const MEDFileMeshes *ms=_meshes; - if(ms) - ms->write(fid); - const MEDFileFields *fs=_fields; - if(fs) - fs->writeLL(fid); - const MEDFileParameters *ps=_params; - if(ps) - ps->writeLL(fid); -} diff --git a/medtool/src/MEDLoader/MEDFileData.hxx b/medtool/src/MEDLoader/MEDFileData.hxx deleted file mode 100644 index ce7a2ea36..000000000 --- a/medtool/src/MEDLoader/MEDFileData.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEDATA_HXX__ -#define __MEDFILEDATA_HXX__ - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDFileParameter.hxx" -#include "MEDFileField.hxx" -#include "MEDFileMesh.hxx" - -namespace ParaMEDMEM -{ - /*! - * User class. - */ - class MEDFileData : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileData *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileData *New(); - MEDLOADER_EXPORT MEDFileData *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileFields *getFields() const; - MEDLOADER_EXPORT MEDFileMeshes *getMeshes() const; - MEDLOADER_EXPORT MEDFileParameters *getParams() const; - MEDLOADER_EXPORT void setFields(MEDFileFields *fields); - MEDLOADER_EXPORT void setMeshes(MEDFileMeshes *meshes); - MEDLOADER_EXPORT void setParams(MEDFileParameters *params); - MEDLOADER_EXPORT int getNumberOfFields() const; - MEDLOADER_EXPORT int getNumberOfMeshes() const; - MEDLOADER_EXPORT int getNumberOfParams() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - // - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName); - MEDLOADER_EXPORT bool unPolyzeMeshes(); - // - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - private: - MEDFileData(); - MEDFileData(const std::string& fileName); - private: - MEDCouplingAutoRefCountObjectPtr _fields; - MEDCouplingAutoRefCountObjectPtr _meshes; - MEDCouplingAutoRefCountObjectPtr _params; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileEquivalence.cxx b/medtool/src/MEDLoader/MEDFileEquivalence.cxx deleted file mode 100644 index 5f9ff6de4..000000000 --- a/medtool/src/MEDLoader/MEDFileEquivalence.cxx +++ /dev/null @@ -1,769 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#include "MEDFileEquivalence.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDCouplingMemArray.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileMesh.hxx" -#include "InterpKernelAutoPtr.hxx" - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmai3[34]; -extern med_geometry_type typmainoeud[1]; - -using namespace ParaMEDMEM; - -MEDFileEquivalencePair *MEDFileEquivalencePair::Load(MEDFileEquivalences *father, med_idt fid, const std::string& name, const std::string &desc) -{ - if(!father) - throw INTERP_KERNEL::Exception("MEDFileEquivalencePair::Load : father is NULL ! Should not !"); - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileEquivalencePair(father,name,desc)); - ret->load(fid); - return ret.retn(); -} - -void MEDFileEquivalencePair::write(med_idt fid) const -{ - std::string meshName(getFather()->getMeshName()); - INTERP_KERNEL::AutoPtr meshName2(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr name(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr desc(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE)); - MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,meshName2,getFather()->getMesh()->getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,name,getFather()->getMesh()->getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(_description.c_str(),MED_COMMENT_SIZE,desc,getFather()->getMesh()->getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDequivalenceCr,(fid,meshName2,name,desc)); - const MEDFileEquivalenceCell *cell(_cell); - if(cell) - cell->write(fid); - const MEDFileEquivalenceNode *node(_node); - if(node) - node->write(fid); -} - -const MEDFileMesh *MEDFileEquivalencePair::getMesh() const -{ - return getFather()->getMesh(); -} - -MEDFileMesh *MEDFileEquivalencePair::getMesh() -{ - return getFather()->getMesh(); -} - -MEDFileEquivalencePair *MEDFileEquivalencePair::deepCpy(MEDFileEquivalences *father) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileEquivalencePair(father,_name,_description)); - const MEDFileEquivalenceCell *cell(_cell); - if(cell) - ret->_cell=cell->deepCpy(const_cast(this)); - const MEDFileEquivalenceNode *node(_node); - if(node) - ret->_node=node->deepCpy(const_cast(this)); - return ret.retn(); -} - -bool MEDFileEquivalencePair::isEqual(const MEDFileEquivalencePair *other, std::string& what) const -{ - if(_name!=other->_name) - { - std::ostringstream oss; oss << "Names differs : " << _name << " != " << other->_name << " !"; - what=oss.str(); - return false; - } - if(_description!=other->_description) - { - std::ostringstream oss; oss << "Description differs : " << _description << " != " << other->_description << " !"; - what=oss.str(); - return false; - } - const MEDFileEquivalenceCell *c1(_cell),*c2(other->_cell); - if((c1 && !c2) || (!c1 && c2)) - { - std::ostringstream oss; oss << "Cell def of Equiv " << _name << " are defined for this and not for other (or reversely) !"; - what=oss.str(); - return false; - } - if(c1 && c2) - if(!c1->isEqual(c2,what)) - return false; - const MEDFileEquivalenceNode *n1(_node),*n2(other->_node); - if((n1 && !n2) || (!n1 && n2)) - { - std::ostringstream oss; oss << "Node def of Equiv " << _name << " are defined for this and not for other (or reversely) !"; - what=oss.str(); - return false; - } - if(n1 && n2) - if(!n1->isEqual(n2,what)) - return false; - return true; -} - -void MEDFileEquivalencePair::getRepr(std::ostream& oss) const -{ - const MEDFileEquivalenceNode *node(_node); - const MEDFileEquivalenceCell *cell(_cell); - oss << std::endl << " name of equivalence : " << _name << std::endl; - oss << " description of equivalence : " << _description << std::endl; - oss << " Node : "; - if(!node) - oss << "None" << std::endl; - else - node->getRepr(oss); - oss << " Cell : "; - if(!cell) - oss << "None" << std::endl; - else - cell->getRepr(oss); -} - -MEDFileEquivalencePair *MEDFileEquivalencePair::New(MEDFileEquivalences *father, const std::string& name) -{ - return new MEDFileEquivalencePair(father,name,std::string()); -} - -std::vector MEDFileEquivalencePair::getDirectChildrenWithNull() const -{ - std::vector ret(2); - ret[0]=_cell; ret[1]=_node; - return ret; -} - -void MEDFileEquivalencePair::setArray(int meshDimRelToMaxExt, DataArrayInt *da) -{ - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileEquivalencePair::setArray : meshDimRelToMaxExt must be in [1,0,-1,-2,-3] at most !"); - if(meshDimRelToMaxExt==1) - { - MEDFileEquivalenceNode *node(_node); - if(!node) - { - _node=new MEDFileEquivalenceNode(this,0); - node=_node; - } - node->setArray(da); - } - else - { - MEDFileEquivalenceCell *cell(_cell); - if(!cell) - { - _cell=new MEDFileEquivalenceCell(this); - cell=_cell; - } - cell->setArray(meshDimRelToMaxExt,da); - } -} - -/*! - * The returned pointer is a borrowed pointer. - */ -MEDFileEquivalenceCell *MEDFileEquivalencePair::initCell() -{ - _cell=new MEDFileEquivalenceCell(this); - return _cell; -} - -/*! - * The returned pointer is a borrowed pointer. - */ -MEDFileEquivalenceNode *MEDFileEquivalencePair::initNode() -{ - _node=new MEDFileEquivalenceNode(this,0); - return _node; -} - -std::size_t MEDFileEquivalencePair::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -void MEDFileEquivalencePair::load(med_idt fid) -{ - std::string meshName(_father->getMeshName()); - int dt,it; - _father->getDtIt(dt,it); - med_int ncor; - MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceSize,(fid,meshName.c_str(),_name.c_str(),dt,it,MED_NODE,MED_NONE,&ncor)); - if(ncor>0) - { - MEDCouplingAutoRefCountObjectPtr da(DataArrayInt::New()); - da->alloc(ncor*2); - MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceRd,(fid,meshName.c_str(),_name.c_str(),dt,it,MED_NODE,MED_NONE,da->getPointer())); - da->applyLin(1,-1); - da->rearrange(2); - MEDCouplingAutoRefCountObjectPtr node(new MEDFileEquivalenceNode(this,da)); - _node=node; - } - _cell=MEDFileEquivalenceCell::Load(fid,this); -} - -std::vector MEDFileEquivalences::getDirectChildrenWithNull() const -{ - std::size_t sz(_equ.size()); - std::vector ret(sz); - for(std::size_t i=0;igetIteration(); it=_owner->getOrder(); -} - -std::string MEDFileEquivalences::getMeshName() const -{ - return _owner->getName(); -} - -void MEDFileEquivalences::pushEquivalence(MEDFileEquivalencePair *elt) -{ - MEDCouplingAutoRefCountObjectPtr elta(elt); - if(elt) - elt->incrRef(); - _equ.push_back(elta); -} - -MEDFileEquivalencePair *MEDFileEquivalences::getEquivalence(int i) -{ - int sz(size()); - if(i<0 || i>=sz) - { - std::ostringstream oss; oss << "MEDFileEquivalences::getEquivalence : invalid id ! Must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _equ[i]; -} - -MEDFileEquivalencePair *MEDFileEquivalences::getEquivalenceWithName(const std::string& name) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_equ.begin();it!=_equ.end();it++) - { - MEDFileEquivalencePair *elt(*it); - if(elt) - { - if(elt->getName()==name) - return elt; - } - } - std::ostringstream oss; oss << "MEDFileEquivalences::getEquivalenceWithName : no equivalence with name \"" << name << "\" ! Must be in [ "; - std::vector eqs(getEquivalenceNames()); - std::copy(eqs.begin(),eqs.end(),std::ostream_iterator(oss,", ")); - oss << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileEquivalences::size() const -{ - return _equ.size(); -} - -std::vector MEDFileEquivalences::getEquivalenceNames() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_equ.begin();it!=_equ.end();it++) - { - const MEDFileEquivalencePair *elt(*it); - if(elt) - { - ret.push_back(elt->getName()); - } - } - return ret; -} - -MEDFileEquivalencePair *MEDFileEquivalences::appendEmptyEquivalenceWithName(const std::string& name) -{ - MEDCouplingAutoRefCountObjectPtr elt(MEDFileEquivalencePair::New(this,name)); - _equ.push_back(elt); - return elt; -} - -MEDFileEquivalences *MEDFileEquivalences::deepCpy(MEDFileMesh *owner) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileEquivalences(owner)); - ret->deepCpyFrom(*this); - return ret.retn(); -} - -bool MEDFileEquivalences::isEqual(const MEDFileEquivalences *other, std::string& what) const -{ - std::size_t sz(_equ.size()); - if(sz!=other->_equ.size()) - { - what="Equivalences differs : not same number !"; - return false; - } - for(std::size_t i=0;i_equ[i]); - if(!thisp && !otherp) - continue; - if(thisp && otherp) - { - if(!thisp->isEqual(otherp,what)) - { - std::ostringstream oss; oss << "At Eq #" << i << " there is a difference !"; - what=oss.str()+what; - return false; - } - } - else - { - std::ostringstream oss; oss << "At Eq #" << i << " defined in this not is other (or reversely) !"; - what=oss.str()+what; - return false; - } - } -} - -void MEDFileEquivalences::getRepr(std::ostream& oss) const -{ - std::size_t ii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_equ.begin();it!=_equ.end();it++,ii++) - { - const MEDFileEquivalencePair *elt(*it); - oss << "Equivalence #" << ii << " : " ; - if(elt) - elt->getRepr(oss); - else - oss << "None" << std::endl; - } -} - -void MEDFileEquivalences::killEquivalenceWithName(const std::string& name) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it(_equ.begin()); - for(;it!=_equ.end();it++) - { - const MEDFileEquivalencePair *elt(*it); - if(elt && elt->getName()==name) - break; - } - if(it==_equ.end()) - { - std::ostringstream oss; oss << "MEDFileEquivalences::killEquivalenceWithName : Equivalence with name \"" << name << "\" not found !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _equ.erase(it); -} - -void MEDFileEquivalences::killEquivalenceAt(int i) -{ - int sz(size()); - if(i<0 || i>=sz) - { - std::ostringstream oss; oss << "MEDFileEquivalences::killEquivalenceAt : Id must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it(_equ.begin()); - for(int j=0;j >::const_iterator it=_equ.begin();it!=_equ.end();it++) - { - const MEDFileEquivalencePair *elt(*it); - if(elt) - elt->write(fid); - } -} - -int MEDFileEquivalences::PresenceOfEquivalences(med_idt fid, const std::string& meshName) -{ - med_int nequ(MEDnEquivalence(fid,meshName.c_str())); - return nequ; -} - -MEDFileEquivalences *MEDFileEquivalences::Load(med_idt fid, int nbOfEq, MEDFileMesh *owner) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileEquivalences(owner)); - if(!owner) - throw INTERP_KERNEL::Exception("MEDFileEquivalences::Load : owner is NULL !"); - std::string meshName(owner->getName()); - for(int i=0;i equ(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr desc(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE)); - int nstep,nocstpncor; - MEDFILESAFECALLERRD0(MEDequivalenceInfo,(fid,meshName.c_str(),i+1,equ,desc,&nstep,&nocstpncor)); - std::string eqName(MEDLoaderBase::buildStringFromFortran(equ,MED_NAME_SIZE)),eqDescName(MEDLoaderBase::buildStringFromFortran(desc,MED_COMMENT_SIZE)); - MEDCouplingAutoRefCountObjectPtr eqv(MEDFileEquivalencePair::Load(ret,fid,eqName,eqDescName)); - ret->pushEquivalence(eqv); - } - return ret.retn(); -} - -void MEDFileEquivalences::CheckDataArray(const DataArrayInt *data) -{ - if(!data) - return; - data->checkAllocated(); - if(data->getNumberOfComponents()!=2) - { - std::ostringstream oss; oss << "MEDFileEquivalences::CheckDataArray : Input DataArray must have 2 components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDFileEquivalences::deepCpyFrom(const MEDFileEquivalences& other) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._equ.begin();it!=other._equ.end();it++) - { - const MEDFileEquivalencePair *elt(*it); - MEDCouplingAutoRefCountObjectPtr eltCpy; - if(elt) - { - eltCpy=elt->deepCpy(this); - } - _equ.push_back(eltCpy); - } -} - -MEDFileEquivalenceBase::MEDFileEquivalenceBase(MEDFileEquivalencePair *father):_father(father) -{ -} - -MEDFileEquivalenceData::MEDFileEquivalenceData(MEDFileEquivalencePair *owner, DataArrayInt *data):MEDFileEquivalenceBase(owner),_data(data) -{ - if(data) - data->incrRef(); -} - -void MEDFileEquivalenceData::setArray(DataArrayInt *data) -{ - MEDFileEquivalences::CheckDataArray(data); - _data=data; - if(data) - data->incrRef(); -} - -std::vector MEDFileEquivalenceData::getDirectChildrenWithNull() const -{ - std::vector ret(1); - ret[0]=_data; - return ret; -} - -bool MEDFileEquivalenceData::isEqual(const MEDFileEquivalenceData *other, std::string& what) const -{ - const DataArrayInt *d1(_data),*d2(other->_data); - if((!d1 && d2) || (d1 && !d2)) - { - what="Data array is defined in this not in other (or reversely) !"; - return false; - } - if(d1 && d2) - { - if(!d1->isEqualIfNotWhy(*d2,what)) - return false; - } - return true; -} - -void MEDFileEquivalenceData::writeLL(med_idt fid, med_entity_type medtype, med_geometry_type medgt) const -{ - - const DataArrayInt *da(getArray()); - if(!da) - return ; - MEDFileEquivalences::CheckDataArray(da); - const MEDFileMesh *mesh(getFather()->getMesh()); - int dt,it; - mesh->getTime(dt,it); - std::string meshName(mesh->getName()); - std::string equName(getFather()->getName()); - INTERP_KERNEL::AutoPtr meshName2(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr name(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,meshName2,getFather()->getMesh()->getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(equName.c_str(),MED_NAME_SIZE,name,getFather()->getMesh()->getTooLongStrPolicy()); - MEDCouplingAutoRefCountObjectPtr da2(da->deepCpy()); da2->rearrange(1); da2->applyLin(1,1); da2->rearrange(2); - MEDFILESAFECALLERWR0(MEDequivalenceCorrespondenceWr,(fid,meshName2,name,dt,it,medtype,medgt,da2->getNumberOfTuples(),da2->begin())); -} - -std::size_t MEDFileEquivalenceCellType::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDFileEquivalenceCellType); -} - -MEDFileEquivalenceCellType *MEDFileEquivalenceCellType::deepCpy(MEDFileEquivalencePair *owner) const -{ - MEDCouplingAutoRefCountObjectPtr da; - if(getArray()) - da=getArray()->deepCpy(); - return new MEDFileEquivalenceCellType(owner,_type,da); -} - -bool MEDFileEquivalenceCellType::isEqual(const MEDFileEquivalenceCellType *other, std::string& what) const -{ - if(_type!=other->_type) - { - what="Geo types differs !"; - return false; - } - return MEDFileEquivalenceData::isEqual(other,what); -} - -void MEDFileEquivalenceCellType::getRepr(std::ostream& oss) const -{ - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(_type)); - const DataArrayInt *da(getArray()); - oss << cm.getRepr() << ":"; - if(da) - oss << da->getNumberOfTuples() << " tuples"; - else - oss << "no dataarray"; - oss << ","; -} - -void MEDFileEquivalenceCellType::write(med_idt fid) const -{ - writeLL(fid,MED_CELL,typmai3[_type]); -} - -std::vector MEDFileEquivalenceCell::getDirectChildrenWithNull() const -{ - std::size_t sz(_types.size()); - std::vector ret(sz); - for(std::size_t i=0;i ret(new MEDFileEquivalenceCell(owner)); - ret->load(fid); - if(ret->size()>0) - return ret.retn(); - else - return 0; -} - -void MEDFileEquivalenceCell::write(med_idt fid) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_types.begin();it!=_types.end();it++) - { - const MEDFileEquivalenceCellType *ct(*it); - if(ct) - ct->write(fid); - } -} - -MEDFileEquivalenceCell *MEDFileEquivalenceCell::deepCpy(MEDFileEquivalencePair *owner) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileEquivalenceCell(owner)); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_types.begin();it!=_types.end();it++) - { - const MEDFileEquivalenceCellType *elt(*it); - MEDCouplingAutoRefCountObjectPtr eltCpy; - if(elt) - eltCpy=elt->deepCpy(owner); - ret->_types.push_back(eltCpy); - } - return ret.retn(); -} - -bool MEDFileEquivalenceCell::isEqual(const MEDFileEquivalenceCell *other, std::string& what) const -{ - std::size_t sz(_types.size()); - if(sz!=other->_types.size()) - { - std::ostringstream oss; oss << "Nb of geo types differs : " << sz << " != " << other->_types.size(); - what=oss.str(); - return false; - } - for(std::size_t i=0;i_types[i]); - if((ct1 && !ct2) || (!ct1 && ct2)) - { - std::ostringstream oss; oss << "At gt #" << i << " this is defined not other (or reversely !)"; - what=oss.str(); - return false; - } - if(ct1 && ct2) - { - if(!ct1->isEqual(ct2,what)) - { - std::ostringstream oss; oss << "At gt #" << i << " of Eq " << getFather()->getName() << " it differs !"; - what=oss.str()+what; - return false; - } - } - } - return true; -} - -void MEDFileEquivalenceCell::getRepr(std::ostream& oss) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_types.begin();it!=_types.end();it++) - { - const MEDFileEquivalenceCellType *elt(*it); - if(elt) - elt->getRepr(oss); - } -} - -DataArrayInt *MEDFileEquivalenceCell::getArray(INTERP_KERNEL::NormalizedCellType type) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_types.begin();it!=_types.end();it++) - { - MEDFileEquivalenceCellType *elt(*it); - if(elt && elt->getType()==type) - return elt->getArray(); - } - std::ostringstream oss; oss << "MEDFileEquivalenceCell::getArray : In Equivalence \"" << getFather()->getName() << "\" the geotype " << type << " is not available !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void MEDFileEquivalenceCell::setArray(int meshDimRelToMax, DataArrayInt *da) -{ - if(!da) - return ; - MEDFileEquivalences::CheckDataArray(da); - MEDFileMesh *mm(getMesh()); - int totalNbOfCells(mm->getNumberOfCellsAtLevel(meshDimRelToMax)); - // - MEDCouplingAutoRefCountObjectPtr tmp(da->deepCpy()); tmp->rearrange(1); - int maxv,minv; - tmp->getMinMaxValues(minv,maxv); - if((minv<0 || minv>=totalNbOfCells) || (maxv<0 || maxv>=totalNbOfCells)) - { - std::ostringstream oss; oss << "MEDFileEquivalenceCell::setArray : Input 2 component DataArray has incorrect values ! all values must be in [0," << totalNbOfCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector gts(mm->getGeoTypesAtLevel(meshDimRelToMax)); - int startId(0),endId; - std::vector compS(1,0); - for(std::vector::const_iterator it=gts.begin();it!=gts.end();it++) - { - endId=startId+mm->getNumberOfCellsWithType(*it); - MEDCouplingAutoRefCountObjectPtr da0(da->keepSelectedComponents(compS)); - MEDCouplingAutoRefCountObjectPtr ids(da0->getIdsInRange(startId,endId)); - MEDCouplingAutoRefCountObjectPtr da1(da->selectByTupleIdSafe(ids->begin(),ids->end())); - da1->applyLin(1,-startId); - setArrayForType(*it,da1); - startId=endId; - } -} - -void MEDFileEquivalenceCell::setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_types.begin();it!=_types.end();it++) - { - MEDFileEquivalenceCellType *elt(*it); - if(elt && elt->getType()==type) - { - elt->setArray(da); - return ; - } - } - MEDCouplingAutoRefCountObjectPtr newElt(new MEDFileEquivalenceCellType(getFather(),type,da)); - _types.push_back(newElt); -} - -std::vector MEDFileEquivalenceCell::getTypes() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_types.begin();it!=_types.end();it++) - { - const MEDFileEquivalenceCellType *elt(*it); - if(elt) - ret.push_back(elt->getType()); - } - return ret; -} - -void MEDFileEquivalenceCell::load(med_idt fid) -{ - std::string meshName(getFather()->getFather()->getMeshName()),name(getName()); - int dt,it; - getFather()->getFather()->getDtIt(dt,it); - for(int i=0;i0) - { - MEDCouplingAutoRefCountObjectPtr da(DataArrayInt::New()); - da->alloc(ncor*2); - MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceRd,(fid,meshName.c_str(),name.c_str(),dt,it,MED_CELL,typmai[i],da->getPointer())); - da->applyLin(1,-1); - da->rearrange(2); - MEDCouplingAutoRefCountObjectPtr ct(new MEDFileEquivalenceCellType(getFather(),typmai2[i],da)); - _types.push_back(ct); - } - } -} - -std::size_t MEDFileEquivalenceNode::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDFileEquivalenceNode); -} - -void MEDFileEquivalenceNode::write(med_idt fid) const -{ - writeLL(fid,MED_NODE,MED_NONE); -} - -MEDFileEquivalenceNode *MEDFileEquivalenceNode::deepCpy(MEDFileEquivalencePair *owner) const -{ - MEDCouplingAutoRefCountObjectPtr da; - if(getArray()) - da=getArray()->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileEquivalenceNode(owner,da)); - return ret.retn(); -} - -bool MEDFileEquivalenceNode::isEqual(const MEDFileEquivalenceNode *other, std::string& what) const -{ - return MEDFileEquivalenceData::isEqual(other,what); -} - -void MEDFileEquivalenceNode::getRepr(std::ostream& oss) const -{ - const DataArrayInt *da(getArray()); - if(!da) - oss << " No dataarray defined !" << std::endl; - else - oss << da->getNumberOfTuples() << " tuples in node equivalence." << std::endl; -} diff --git a/medtool/src/MEDLoader/MEDFileEquivalence.hxx b/medtool/src/MEDLoader/MEDFileEquivalence.hxx deleted file mode 100644 index bcf14904b..000000000 --- a/medtool/src/MEDLoader/MEDFileEquivalence.hxx +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __MEDFILEEQUIVALENCE_HXX__ -#define __MEDFILEEQUIVALENCE_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDFileEquivalenceCell; - class MEDFileEquivalenceNode; - class MEDFileEquivalences; - class MEDFileMesh; - - class MEDFileEquivalencePair : public RefCountObject - { - public: - static MEDFileEquivalencePair *Load(MEDFileEquivalences *father, med_idt fid, const std::string& name, const std::string &desc); - void write(med_idt fid) const; - const MEDFileEquivalences *getFather() const { return _father; } - MEDFileEquivalences *getFather() { return _father; } - const MEDFileMesh *getMesh() const; - MEDFileMesh *getMesh(); - MEDFileEquivalencePair *deepCpy(MEDFileEquivalences *father) const; - bool isEqual(const MEDFileEquivalencePair *other, std::string& what) const; - void getRepr(std::ostream& oss) const; - static MEDFileEquivalencePair *New(MEDFileEquivalences *father, const std::string& name); - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - public: - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _description; } - MEDLOADER_EXPORT void setDescription(const std::string& descr) { _description=descr; } - MEDLOADER_EXPORT MEDFileEquivalenceCell *initCell(); - MEDLOADER_EXPORT MEDFileEquivalenceNode *initNode(); - MEDLOADER_EXPORT MEDFileEquivalenceCell *getCell() { return _cell; } - MEDLOADER_EXPORT MEDFileEquivalenceNode *getNode() { return _node; } - MEDLOADER_EXPORT void setArray(int meshDimRelToMaxExt, DataArrayInt *da); - private: - MEDFileEquivalencePair(MEDFileEquivalences *father, const std::string& name, const std::string& desc):_father(father),_name(name),_description(desc) { } - void load(med_idt fid); - private: - MEDFileEquivalences *_father; - std::string _name; - std::string _description; - MEDCouplingAutoRefCountObjectPtr _cell; - MEDCouplingAutoRefCountObjectPtr _node; - }; - - class MEDFileEquivalences : public RefCountObject - { - public: - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT const MEDFileMesh *getMesh() const { return _owner; } - MEDLOADER_EXPORT MEDFileMesh *getMesh() { return _owner; } - void getDtIt(int &dt, int &it) const; - std::string getMeshName() const; - void pushEquivalence(MEDFileEquivalencePair *elt); - static MEDFileEquivalences *New(MEDFileMesh *owner) { return new MEDFileEquivalences(owner); } - MEDFileEquivalences *deepCpy(MEDFileMesh *owner) const; - bool isEqual(const MEDFileEquivalences *other, std::string& what) const; - void getRepr(std::ostream& oss) const; - public: - MEDLOADER_EXPORT MEDFileEquivalencePair *getEquivalence(int i); - MEDLOADER_EXPORT MEDFileEquivalencePair *getEquivalenceWithName(const std::string& name); - MEDLOADER_EXPORT int size() const; - MEDLOADER_EXPORT std::vector getEquivalenceNames() const; - MEDLOADER_EXPORT MEDFileEquivalencePair *appendEmptyEquivalenceWithName(const std::string& name); - MEDLOADER_EXPORT void killEquivalenceWithName(const std::string& name); - MEDLOADER_EXPORT void killEquivalenceAt(int i); - MEDLOADER_EXPORT void clear(); - public: - void write(med_idt fid) const; - static int PresenceOfEquivalences(med_idt fid, const std::string& meshName); - static MEDFileEquivalences *Load(med_idt fid, int nbOfEq, MEDFileMesh *owner); - static void CheckDataArray(const DataArrayInt *data); - private: - MEDFileEquivalences(MEDFileMesh *owner):_owner(owner) { } - void deepCpyFrom(const MEDFileEquivalences& other); - private: - MEDFileMesh *_owner; - std::vector< MEDCouplingAutoRefCountObjectPtr > _equ; - }; - - class MEDFileEquivalenceBase : public RefCountObject - { - protected: - MEDFileEquivalenceBase(MEDFileEquivalencePair *father); - const MEDFileEquivalencePair *getFather() const { return _father; } - MEDFileEquivalencePair *getFather() { return _father; } - const MEDFileMesh *getMesh() const { return getFather()->getMesh(); } - MEDFileMesh *getMesh() { return getFather()->getMesh(); } - protected: - ~MEDFileEquivalenceBase() { } - private: - MEDFileEquivalencePair *_father; - }; - - class MEDFileEquivalenceData : public MEDFileEquivalenceBase - { - public: - MEDFileEquivalenceData(MEDFileEquivalencePair *owner, DataArrayInt *data); - MEDLOADER_EXPORT void setArray(DataArrayInt *data); - MEDLOADER_EXPORT const DataArrayInt *getArray() const { return _data; } - MEDLOADER_EXPORT DataArrayInt *getArray() { return _data; } - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - bool isEqual(const MEDFileEquivalenceData *other, std::string& what) const; - protected: - void writeLL(med_idt fid, med_entity_type medtype, med_geometry_type medgt) const; - protected: - ~MEDFileEquivalenceData() { } - protected: - MEDCouplingAutoRefCountObjectPtr _data; - }; - - class MEDFileEquivalenceCellType : public MEDFileEquivalenceData - { - public: - MEDFileEquivalenceCellType(MEDFileEquivalencePair *owner, INTERP_KERNEL::NormalizedCellType type, DataArrayInt *data):MEDFileEquivalenceData(owner,data),_type(type) { } - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - INTERP_KERNEL::NormalizedCellType getType() const { return _type; } - MEDFileEquivalenceCellType *deepCpy(MEDFileEquivalencePair *owner) const; - bool isEqual(const MEDFileEquivalenceCellType *other, std::string& what) const; - void getRepr(std::ostream& oss) const; - public: - void write(med_idt fid) const; - private: - ~MEDFileEquivalenceCellType() { } - private: - INTERP_KERNEL::NormalizedCellType _type; - }; - - class MEDFileEquivalenceCell : public MEDFileEquivalenceBase - { - public: - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - static MEDFileEquivalenceCell *Load(med_idt fid, MEDFileEquivalencePair *owner); - void write(med_idt fid) const; - MEDFileEquivalenceCell *deepCpy(MEDFileEquivalencePair *owner) const; - bool isEqual(const MEDFileEquivalenceCell *other, std::string& what) const; - void getRepr(std::ostream& oss) const; - public: - MEDLOADER_EXPORT void clear() { _types.clear(); } - MEDLOADER_EXPORT std::size_t size() const { return _types.size(); } - MEDLOADER_EXPORT DataArrayInt *getArray(INTERP_KERNEL::NormalizedCellType type); - MEDLOADER_EXPORT void setArray(int meshDimRelToMax, DataArrayInt *da); - MEDLOADER_EXPORT void setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da); - MEDLOADER_EXPORT std::vector getTypes() const; - public: - MEDFileEquivalenceCell(MEDFileEquivalencePair *owner):MEDFileEquivalenceBase(owner) { } - private: - ~MEDFileEquivalenceCell() { } - private: - void load(med_idt fid); - std::string getName() const { return getFather()->getName(); } - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _types; - }; - - class MEDFileEquivalenceNode : public MEDFileEquivalenceData - { - public: - MEDFileEquivalenceNode(MEDFileEquivalencePair *owner, DataArrayInt *data):MEDFileEquivalenceData(owner,data) { } - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - void write(med_idt fid) const; - MEDFileEquivalenceNode *deepCpy(MEDFileEquivalencePair *owner) const; - bool isEqual(const MEDFileEquivalenceNode *other, std::string& what) const; - void getRepr(std::ostream& oss) const; - private: - ~MEDFileEquivalenceNode() { } - }; -} - -#endif - diff --git a/medtool/src/MEDLoader/MEDFileField.cxx b/medtool/src/MEDLoader/MEDFileField.cxx deleted file mode 100644 index 932e70028..000000000 --- a/medtool/src/MEDLoader/MEDFileField.cxx +++ /dev/null @@ -1,10491 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileField.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileFieldOverView.hxx" - -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" - -#include "InterpKernelAutoPtr.hxx" -#include "CellModel.hxx" - -#include -#include - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmainoeud[1]; -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -const char MEDFileField1TSWithoutSDA::TYPE_STR[]="FLOAT64"; -const char MEDFileIntField1TSWithoutSDA::TYPE_STR[]="INT32"; - -MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, const std::string& locName) -{ - return new MEDFileFieldLoc(fid,locName); -} - -MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, int id) -{ - return new MEDFileFieldLoc(fid,id); -} - -MEDFileFieldLoc *MEDFileFieldLoc::New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) -{ - return new MEDFileFieldLoc(locName,geoType,refCoo,gsCoo,w); -} - -MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, const std::string& locName):_name(locName) -{ - med_geometry_type geotype; - med_geometry_type sectiongeotype; - int nsectionmeshcell; - INTERP_KERNEL::AutoPtr geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDlocalizationInfoByName(fid,locName.c_str(),&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); - _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - _nb_node_per_cell=cm.getNumberOfNodes(); - _ref_coo.resize(_dim*_nb_node_per_cell); - _gs_coo.resize(_dim*_nb_gauss_pt); - _w.resize(_nb_gauss_pt); - MEDlocalizationRd(fid,locName.c_str(),MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); -} - -MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id) -{ - med_geometry_type geotype; - med_geometry_type sectiongeotype; - int nsectionmeshcell; - INTERP_KERNEL::AutoPtr locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDlocalizationInfo(fid,id+1,locName,&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); - _name=locName; - _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - _nb_node_per_cell=cm.getNumberOfNodes(); - _ref_coo.resize(_dim*_nb_node_per_cell); - _gs_coo.resize(_dim*_nb_gauss_pt); - _w.resize(_nb_gauss_pt); - MEDlocalizationRd(fid,locName,MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); -} - -MEDFileFieldLoc::MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, - const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w):_name(locName),_geo_type(geoType),_ref_coo(refCoo),_gs_coo(gsCoo), - _w(w) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - _dim=cm.getDimension(); - _nb_node_per_cell=cm.getNumberOfNodes(); - _nb_gauss_pt=_w.size(); -} - -MEDFileFieldLoc *MEDFileFieldLoc::deepCpy() const -{ - return new MEDFileFieldLoc(*this); -} - -std::size_t MEDFileFieldLoc::getHeapMemorySizeWithoutChildren() const -{ - return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity(); -} - -std::vector MEDFileFieldLoc::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const -{ - static const char OFF7[]="\n "; - oss << "\"" << _name << "\"" << OFF7; - oss << "GeoType=" << INTERP_KERNEL::CellModel::GetCellModel(_geo_type).getRepr() << OFF7; - oss << "Dimension=" << _dim << OFF7; - oss << "Number of Gauss points=" << _nb_gauss_pt << OFF7; - oss << "Number of nodes per cell=" << _nb_node_per_cell << OFF7; - oss << "RefCoords="; std::copy(_ref_coo.begin(),_ref_coo.end(),std::ostream_iterator(oss," ")); oss << OFF7; - oss << "Weights="; std::copy(_w.begin(),_w.end(),std::ostream_iterator(oss," ")); oss << OFF7; - oss << "GaussPtsCoords="; std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator(oss," ")); oss << std::endl; -} - -void MEDFileFieldLoc::setName(const std::string& name) -{ - _name=name; -} - -bool MEDFileFieldLoc::isEqual(const MEDFileFieldLoc& other, double eps) const -{ - if(_name!=other._name) - return false; - if(_dim!=other._dim) - return false; - if(_nb_gauss_pt!=other._nb_gauss_pt) - return false; - if(_nb_node_per_cell!=other._nb_node_per_cell) - return false; - if(_geo_type!=other._geo_type) - return false; - if(!MEDCouplingGaussLocalization::AreAlmostEqual(_ref_coo,other._ref_coo,eps)) - return false; - if(!MEDCouplingGaussLocalization::AreAlmostEqual(_gs_coo,other._gs_coo,eps)) - return false; - if(!MEDCouplingGaussLocalization::AreAlmostEqual(_w,other._w,eps)) - return false; - - return true; -} - -void MEDFileFieldLoc::writeLL(med_idt fid) const -{ - MEDlocalizationWr(fid,_name.c_str(),typmai3[(int)_geo_type],_dim,&_ref_coo[0],MED_FULL_INTERLACE,_nb_gauss_pt,&_gs_coo[0],&_w[0],MED_NO_INTERPOLATION,MED_NO_MESH_SUPPORT); -} - -std::string MEDFileFieldLoc::repr() const -{ - std::ostringstream oss; oss.precision(15); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - oss << "Localization \"" << _name << "\" :\n" << " - Geometric Type : " << cm.getRepr(); - oss << "\n - Dimension : " << _dim << "\n - Number of gauss points : "; - oss << _nb_gauss_pt << "\n - Number of nodes in cell : " << _nb_node_per_cell; - oss << "\n - Ref coords are : "; - int sz=_ref_coo.size(); - if(sz%_dim==0) - { - int nbOfTuples=sz/_dim; - for(int i=0;i(oss," ")); - oss << "\n - Gauss coords in reference element : "; - sz=_gs_coo.size(); - if(sz%_dim==0) - { - int nbOfTuples=sz/_dim; - for(int i=0;i(oss," ")); - oss << "\n - Weights of Gauss coords are : "; std::copy(_w.begin(),_w.end(),std::ostream_iterator(oss," ")); - return oss.str(); -} - -void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - _type=field->getTypeOfField(); - _start=start; - switch(_type) - { - case ON_CELLS: - { - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,offset,offset+nbOfCells,1); - _end=_start+nbOfCells; - _nval=nbOfCells; - break; - } - case ON_GAUSS_NE: - { - MEDCouplingAutoRefCountObjectPtr arr=field->getDiscretization()->getOffsetArr(field->getMesh()); - const int *arrPtr=arr->getConstPointer(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,arrPtr[offset],arrPtr[offset+nbOfCells],1); - _end=_start+(arrPtr[offset+nbOfCells]-arrPtr[offset]); - _nval=nbOfCells; - break; - } - case ON_GAUSS_PT: - { - const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); - const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id); - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); - if(!disc2) - throw INTERP_KERNEL::Exception("assignFieldNoProfile : invalid call to this method ! Internal Error !"); - const DataArrayInt *dai=disc2->getArrayOfDiscIds(); - MEDCouplingAutoRefCountObjectPtr dai2=disc2->getOffsetArr(field->getMesh()); - const int *dai2Ptr=dai2->getConstPointer(); - int nbi=gsLoc.getWeights().size(); - MEDCouplingAutoRefCountObjectPtr da2=dai->selectByTupleId2(offset,offset+nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr da3=da2->getIdsEqual(_loc_id); - const int *da3Ptr=da3->getConstPointer(); - if(da3->getNumberOfTuples()!=nbOfCells) - {//profile : for gauss even in NoProfile !!! - std::ostringstream oss; oss << "Pfl_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; - _profile=oss.str(); - da3->setName(_profile.c_str()); - glob.appendProfile(da3); - } - MEDCouplingAutoRefCountObjectPtr da4=DataArrayInt::New(); - _nval=da3->getNbOfElems(); - da4->alloc(_nval*nbi,1); - int *da4Ptr=da4->getPointer(); - for(int i=0;i<_nval;i++) - { - int ref=dai2Ptr[offset+da3Ptr[i]]; - for(int j=0;jsetContigPartOfSelectedValues(_start,arrr,da4); - _end=_start+_nval*nbi; - glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile : not implemented yet for such discretization type of field !"); - } - start=_end; -} - -/*! - * Leaf method of field with profile assignement. This method is the most general one. No optimization is done here. - * \param [in] pflName input containing name of profile if any. 0 if no profile (except for GAUSS_PT where a no profile can hide a profile when splitted by loc_id). - * \param [in] multiTypePfl is the end user profile specified in high level API - * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type. - * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl. - * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. - * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. - */ -void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - _profile.clear(); - _type=field->getTypeOfField(); - std::string pflName(multiTypePfl->getName()); - std::ostringstream oss; oss << pflName; - if(_type!=ON_NODES) - { - if(!isPflAlone) - { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" << cm.getRepr(); } - } - else - { oss << "_NODE"; } - if(locIds) - { - if(pflName.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : existing profile with empty name !"); - if(_type!=ON_GAUSS_PT) - { - locIds->setName(oss.str().c_str()); - glob.appendProfile(locIds); - _profile=oss.str(); - } - } - _start=start; - switch(_type) - { - case ON_NODES: - { - _nval=idsInPfl->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,arrr->getNumberOfTuples(),1); - _end=_start+_nval; - break; - } - case ON_CELLS: - { - _nval=idsInPfl->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,idsInPfl); - _end=_start+_nval; - break; - } - case ON_GAUSS_NE: - { - MEDCouplingAutoRefCountObjectPtr arr=field->getDiscretization()->getOffsetArr(mesh); - MEDCouplingAutoRefCountObjectPtr arr2=arr->deltaShiftIndex(); - MEDCouplingAutoRefCountObjectPtr arr3=arr2->selectByTupleId(multiTypePfl->begin(),multiTypePfl->end()); - arr3->computeOffsets2(); - MEDCouplingAutoRefCountObjectPtr tmp=idsInPfl->buildExplicitArrByRanges(arr3); - int trueNval=tmp->getNumberOfTuples(); - _nval=idsInPfl->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); - _end=_start+trueNval; - break; - } - case ON_GAUSS_PT: - { - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(field->getDiscretization()); - if(!disc2) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); - const DataArrayInt *da1=disc2->getArrayOfDiscIds(); - const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id); - MEDCouplingAutoRefCountObjectPtr da2=da1->selectByTupleId(idsInPfl->begin(),idsInPfl->end()); - MEDCouplingAutoRefCountObjectPtr da3=da2->getIdsEqual(_loc_id); - MEDCouplingAutoRefCountObjectPtr da4=idsInPfl->selectByTupleId(da3->begin(),da3->end()); - // - MEDCouplingAutoRefCountObjectPtr mesh2=mesh->buildPart(multiTypePfl->begin(),multiTypePfl->end()); - MEDCouplingAutoRefCountObjectPtr arr=disc2->getOffsetArr(mesh2); - // - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); - int trueNval=0; - for(const int *pt=da4->begin();pt!=da4->end();pt++) - trueNval+=arr->getIJ(*pt+1,0)-arr->getIJ(*pt,0); - tmp->alloc(trueNval,1); - int *tmpPtr=tmp->getPointer(); - for(const int *pt=da4->begin();pt!=da4->end();pt++) - for(int j=arr->getIJ(*pt,0);jgetIJ(*pt+1,0);j++) - *tmpPtr++=j; - // - _nval=da4->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); - _end=_start+trueNval; - oss << "_loc_" << _loc_id; - if(locIds) - { - MEDCouplingAutoRefCountObjectPtr da5=locIds->selectByTupleId(da3->begin(),da3->end()); - da5->setName(oss.str().c_str()); - glob.appendProfile(da5); - _profile=oss.str(); - } - else - { - if(da3->getNumberOfTuples()!=nbOfEltsInWholeMesh || !da3->isIdentity()) - { - da3->setName(oss.str().c_str()); - glob.appendProfile(da3); - _profile=oss.str(); - } - } - std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; - _localization=oss2.str(); - glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for such discretization type of field !"); - } - start=_end; -} - -void MEDFileFieldPerMeshPerTypePerDisc::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob) -{ - _start=start; - _nval=arrr->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,_nval,1); - _end=_start+_nval; - start=_end; -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd) -{ - return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,profileIt,pd); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId) -{ - return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,locId,std::string()); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const MEDFileFieldPerMeshPerTypePerDisc& other) -{ - return new MEDFileFieldPerMeshPerTypePerDisc(other); -} - -std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySizeWithoutChildren() const -{ - return _profile.capacity()+_localization.capacity()+sizeof(MEDFileFieldPerMeshPerTypePerDisc); -} - -std::vector MEDFileFieldPerMeshPerTypePerDisc::getDirectChildrenWithNull() const -{ - std::vector ret(1); - ret[0]=(const PartDefinition*)_pd; - return ret; -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerTypePerDisc(*this); - ret->_father=father; - return ret.retn(); -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt, const PartDefinition *pd) -try:_type(atype),_father(fath),_profile_it(profileIt),_pd(const_cast(pd)) -{ - if(pd) - pd->incrRef(); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId, const std::string& dummy):_type(type),_father(fath),_loc_id(locId) -{ -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other):RefCountObject(other),_type(other._type),_father(0),_start(other._start),_end(other._end),_nval(other._nval),_profile(other._profile),_localization(other._localization),_loc_id(other._loc_id),_profile_it(other._profile_it),_pd(other._pd),_tmp_work1(other._tmp_work1) -{ -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc():_type(ON_CELLS),_father(0),_start(-std::numeric_limits::max()),_end(-std::numeric_limits::max()), - _nval(-std::numeric_limits::max()),_loc_id(-std::numeric_limits::max()) -{ -} - -void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr) -{ - const PartDefinition *pd(_pd); - if(!pd) - { - INTERP_KERNEL::AutoPtr locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - int nbi,tmp1; - med_int nbValsInFile(MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi)); - if(_end-_start!=nbValsInFile*nbi) - { - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : The number of tuples to read is " << nbValsInFile << "*" << nbi << " (nb integration points) ! But in data structure it values " << _end-_start << " is expected !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERRD0(MEDfieldValueWithProfileRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,MED_COMPACT_PFLMODE,_profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,startFeedingPtr)); - } - else - { - if(!_profile.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : not implemented !"); - INTERP_KERNEL::AutoPtr pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - int profilesize,nbi; - int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); - const SlicePartDefinition *spd(dynamic_cast(pd)); - if(spd) - { - int start,stop,step; - spd->getSlice(start,stop,step); - int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(start,stop,step,"MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile")); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/start+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,startFeedingPtr)); - MEDfilterClose(&filter); - return ; - } - const DataArrayPartDefinition *dpd(dynamic_cast(pd)); - if(dpd) - { - dpd->checkCoherency(); - MEDCouplingAutoRefCountObjectPtr myIds(dpd->toDAI()); - int a(myIds->getMinValueInArray()),b(myIds->getMaxValueInArray()); - myIds->applyLin(1,-a); - int nbOfEltsToLoad(b-a+1); - med_filter filter=MED_FILTER_INIT; - {//TODO : manage int32 ! - MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); - tmp->alloc(nbOfEltsToLoad,nbOfCompo); - MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/a+1,/*stride*/1,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,reinterpret_cast(tmp->getPointer()))); - MEDCouplingAutoRefCountObjectPtr feeder(DataArrayDouble::New()); - feeder->useExternalArrayWithRWAccess(reinterpret_cast(startFeedingPtr),_nval,nbOfCompo); - feeder->setContigPartOfSelectedValues(0,tmp,myIds); - } - MEDfilterClose(&filter); - } - else - throw INTERP_KERNEL::Exception("Not implemented yet for not slices!"); - } -} - -const MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerTypePerDisc::getFather() const -{ - return _father; -} - -void MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) -{ - INTERP_KERNEL::AutoPtr locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - std::string fieldName(nasc.getName()),meshName(getMeshName()); - int iteration(getIteration()),order(getOrder()); - TypeOfField type(getType()); - INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); - int profilesize,nbi; - med_geometry_type mgeoti; - med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); - int zeNVal(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); - _profile=MEDLoaderBase::buildStringFromFortran(pflname,MED_NAME_SIZE); - _localization=MEDLoaderBase::buildStringFromFortran(locname,MED_NAME_SIZE); - const PartDefinition *pd(_pd); - if(!pd) - { - _nval=zeNVal; - } - else - { - if(!_profile.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : profiles are not managed yet with part of def !"); - _nval=pd->getNumberOfElems(); - } - _start=start; - _end=start+_nval*nbi; - start=_end; - if(type==ON_CELLS && !_localization.empty()) - { - if(_localization!="MED_GAUSS_ELNO")//For compatibily with MED2.3 - setType(ON_GAUSS_PT); - else - { - setType(ON_GAUSS_NE); - _localization.clear(); - } - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - std::string fieldName(nasc.getName()),meshName(getMeshName()); - int iteration(getIteration()),order(getOrder()); - TypeOfField type(getType()); - INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); - med_geometry_type mgeoti; - med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); - if(_start>_end) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : internal error in range !"); - if(_start==_end) - return ; - DataArray *arr(getOrCreateAndGetArray());//arr is not null due to the spec of getOrCreateAndGetArray - if(_start<0 || _start>=arr->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(_end<0 || _end>arr->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCompo(arr->getNumberOfComponents()); - DataArrayDouble *arrD(dynamic_cast(arr)); - if(arrD) - { - double *startFeeding(arrD->getPointer()+_start*nbOfCompo); - goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast(startFeeding)); - return ; - } - DataArrayInt *arrI(dynamic_cast(arr)); - if(arrI) - { - int *startFeeding(arrI->getPointer()+_start*nbOfCompo); - goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast(startFeeding)); - return ; - } - throw INTERP_KERNEL::Exception("Error on array reading ! Unrecognized type of field ! Should be in FLOAT64 or INT32 !"); -} - -/*! - * Set a \c this->_start **and** \c this->_end keeping the same delta between the two. - */ -void MEDFileFieldPerMeshPerTypePerDisc::setNewStart(int newValueOfStart) -{ - int delta=_end-_start; - _start=newValueOfStart; - _end=_start+delta; -} - -int MEDFileFieldPerMeshPerTypePerDisc::getIteration() const -{ - return _father->getIteration(); -} - -int MEDFileFieldPerMeshPerTypePerDisc::getOrder() const -{ - return _father->getOrder(); -} - -double MEDFileFieldPerMeshPerTypePerDisc::getTime() const -{ - return _father->getTime(); -} - -std::string MEDFileFieldPerMeshPerTypePerDisc::getMeshName() const -{ - return _father->getMeshName(); -} - -void MEDFileFieldPerMeshPerTypePerDisc::simpleRepr(int bkOffset, std::ostream& oss, int id) const -{ - const char startLine[]=" ## "; - std::string startLine2(bkOffset,' '); - startLine2+=startLine; - MEDCouplingFieldDiscretization *tmp=MEDCouplingFieldDiscretization::New(_type); - oss << startLine2 << "Localization #" << id << "." << std::endl; - oss << startLine2 << " Type=" << tmp->getRepr() << "." << std::endl; - delete tmp; - oss << startLine2 << " This type discretization lies on profile : \"" << _profile << "\" and on the following localization : \"" << _localization << "\"." << std::endl; - oss << startLine2 << " This type discretization has " << _end-_start << " tuples (start=" << _start << ", end=" << _end << ")." << std::endl; - oss << startLine2 << " This type discretization has " << (_end-_start)/_nval << " integration points." << std::endl; -} - -TypeOfField MEDFileFieldPerMeshPerTypePerDisc::getType() const -{ - return _type; -} - -void MEDFileFieldPerMeshPerTypePerDisc::fillTypesOfFieldAvailable(std::set& types) const -{ - types.insert(_type); -} - -void MEDFileFieldPerMeshPerTypePerDisc::setType(TypeOfField newType) -{ - _type=newType; -} - -INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerTypePerDisc::getGeoType() const -{ - return _father->getGeoType(); -} - -int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfComponents() const -{ - return _father->getNumberOfComponents(); -} - -int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const -{ - return _end-_start; -} - -DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() -{ - return _father->getOrCreateAndGetArray(); -} - -const DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() const -{ - const MEDFileFieldPerMeshPerType *fath=_father; - return fath->getOrCreateAndGetArray(); -} - -const std::vector& MEDFileFieldPerMeshPerTypePerDisc::getInfo() const -{ - return _father->getInfo(); -} - -std::string MEDFileFieldPerMeshPerTypePerDisc::getProfile() const -{ - return _profile; -} - -void MEDFileFieldPerMeshPerTypePerDisc::setProfile(const std::string& newPflName) -{ - _profile=newPflName; -} - -std::string MEDFileFieldPerMeshPerTypePerDisc::getLocalization() const -{ - return _localization; -} - -void MEDFileFieldPerMeshPerTypePerDisc::setLocalization(const std::string& newLocName) -{ - _localization=newLocName; -} - -void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),_profile)!=(*it2).first.end()) - { - _profile=(*it2).second; - return; - } - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),_localization)!=(*it2).first.end()) - { - _localization=(*it2).second; - return; - } - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const -{ - if(type!=_type) - return ; - dads.push_back(std::pair(_start,_end)); - geoTypes.push_back(getGeoType()); - if(_profile.empty()) - pfls.push_back(0); - else - { - pfls.push_back(glob->getProfile(_profile.c_str())); - } - if(_localization.empty()) - locs.push_back(-1); - else - { - locs.push_back(glob->getLocalizationId(_localization.c_str())); - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::fillValues(int discId, int& startEntryId, std::vector< std::pair,std::pair > >& entries) const -{ - entries[startEntryId]=std::pair ,std::pair >(std::pair(getGeoType(),discId),std::pair(_start,_end)); - startEntryId++; -} - -void MEDFileFieldPerMeshPerTypePerDisc::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const -{ - TypeOfField type=getType(); - INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); - med_geometry_type mgeoti; - med_entity_type menti=MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti); - const DataArray *arr=getOrCreateAndGetArray(); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : no array set !"); - const DataArrayDouble *arrD=dynamic_cast(arr); - const DataArrayInt *arrI=dynamic_cast(arr); - const unsigned char *locToWrite=0; - if(arrD) - locToWrite=reinterpret_cast(arrD->getConstPointer()+_start*arr->getNumberOfComponents()); - else if(arrI) - locToWrite=reinterpret_cast(arrI->getConstPointer()+_start*arr->getNumberOfComponents()); - else - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : not recognized type of values ! Supported are FLOAT64 and INT32 !"); - MEDFILESAFECALLERWR0(MEDfieldValueWithProfileWr,(fid,nasc.getName().c_str(),getIteration(),getOrder(),getTime(),menti,mgeoti, - MED_COMPACT_PFLMODE,_profile.c_str(),_localization.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,_nval, - locToWrite)); -} - -void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pair& dad, std::string& pfl, std::string& loc) const -{ - type=_type; - pfl=_profile; - loc=_localization; - dad.first=_start; dad.second=_end; -} - -/*! - * \param [in] codeOfMesh is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset). - * This code corresponds to the distribution of types in the corresponding mesh. - * \param [out] ptToFill memory zone where the output will be stored. - * \return the size of data pushed into output param \a ptToFill - */ -int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std::vector& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const -{ - _loc_id=offset; - std::ostringstream oss; - std::size_t nbOfType=codeOfMesh.size()/3; - int found=-1; - for(std::size_t i=0;igetNumberOfTuples()!=_nval) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); - oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : for geometric type " << cm.getRepr() << ", field is defined on profile \"" << _profile << "\" and size of profile is "; - oss << _nval; - oss << pfl->getNumberOfTuples() << " whereas the number of ids is set to " << _nval << " for this geometric type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int offset2=codeOfMesh[3*found+2]; - for(const int *pflId=pfl->begin();pflId!=pfl->end();pflId++) - { - if(*pflId > MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries) -{ - int id=0; - std::map,int> m; - std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > ret; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++) - if(m.find(std::pair((*it)->getLocalization(),(*it)->getType()))==m.end()) - m[std::pair((*it)->getLocalization(),(*it)->getType())]=id++; - ret.resize(id); - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++) - ret[m[std::pair((*it)->getLocalization(),(*it)->getType())]].push_back(*it); - return ret; -} - -/*! - * - \c this->_loc_id mutable attribute is used for elt id in mesh offsets. - * - * \param [in] offset the offset id used to take into account that \a result is not compulsary empty in input - * \param [in] entriesOnSameDisc some entries **on same localization** if not the result can be invalid. The _start and _end on them are relative to \a arr parameter. - * \param [in] explicitIdsInMesh ids in mesh of the considered chunk. - * \param [in] newCode one of the input parameter to explicit the new geo type dispatch (in classical format same than those asked by MEDFileFields::renumberEntitiesLyingOnMesh) - * \param [in,out] glob if necessary by the method, new profiles can be added to it - * \param [in,out] arr after the call of this method \a arr is renumbered to be compliant with added entries to \a result. - * \param [out] result All new entries will be appended on it. - * \return false if the configuration of renumbering leads to an unnecessary resplit of input \a entriesOnSameDisc. If not true is returned (the most general case !) - */ -bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - const DataArrayInt *explicitIdsInMesh, - const std::vector& newCode, - MEDFileFieldGlobsReal& glob, DataArrayDouble *arr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& result) -{ - if(entriesOnSameDisc.empty()) - return false; - TypeOfField type=entriesOnSameDisc[0]->getType(); - int szEntities=0,szTuples=0; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++) - { szEntities+=(*it)->_nval; szTuples+=(*it)->_end-(*it)->_start; } - int nbi=szTuples/szEntities; - if(szTuples%szEntities!=0) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks : internal error the splitting into same dicretization failed !"); - MEDCouplingAutoRefCountObjectPtr renumTuples=DataArrayInt::New(); renumTuples->alloc(szTuples,1); - MEDCouplingAutoRefCountObjectPtr ranges=MEDCouplingUMesh::ComputeRangesFromTypeDistribution(newCode); - std::vector< MEDCouplingAutoRefCountObjectPtr > newGeoTypesPerChunk(entriesOnSameDisc.size()); - std::vector< const DataArrayInt * > newGeoTypesPerChunk2(entriesOnSameDisc.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > newGeoTypesPerChunk_bis(entriesOnSameDisc.size()); - std::vector< const DataArrayInt * > newGeoTypesPerChunk3(entriesOnSameDisc.size()); - MEDCouplingAutoRefCountObjectPtr newGeoTypesPerChunk4=DataArrayInt::New(); newGeoTypesPerChunk4->alloc(szEntities,nbi); - int id=0; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++,id++) - { - int startOfEltIdOfChunk=(*it)->_start; - MEDCouplingAutoRefCountObjectPtr newEltIds=explicitIdsInMesh->substr(startOfEltIdOfChunk,startOfEltIdOfChunk+(*it)->_nval); - MEDCouplingAutoRefCountObjectPtr rangeIdsForChunk=newEltIds->findRangeIdForEachTuple(ranges); - MEDCouplingAutoRefCountObjectPtr idsInRrangeForChunk=newEltIds->findIdInRangeForEachTuple(ranges); - // - MEDCouplingAutoRefCountObjectPtr tmp=rangeIdsForChunk->duplicateEachTupleNTimes(nbi); rangeIdsForChunk->rearrange(nbi); - newGeoTypesPerChunk4->setPartOfValues1(tmp,(*it)->_tmp_work1-offset,(*it)->_tmp_work1+(*it)->_nval*nbi-offset,1,0,nbi,1); - // - newGeoTypesPerChunk[id]=rangeIdsForChunk; newGeoTypesPerChunk2[id]=rangeIdsForChunk; - newGeoTypesPerChunk_bis[id]=idsInRrangeForChunk; newGeoTypesPerChunk3[id]=idsInRrangeForChunk; - } - MEDCouplingAutoRefCountObjectPtr newGeoTypesEltIdsAllGather=DataArrayInt::Aggregate(newGeoTypesPerChunk2); newGeoTypesPerChunk.clear(); newGeoTypesPerChunk2.clear(); - MEDCouplingAutoRefCountObjectPtr newGeoTypesEltIdsAllGather2=DataArrayInt::Aggregate(newGeoTypesPerChunk3); newGeoTypesPerChunk_bis.clear(); newGeoTypesPerChunk3.clear(); - MEDCouplingAutoRefCountObjectPtr diffVals=newGeoTypesEltIdsAllGather->getDifferentValues(); - MEDCouplingAutoRefCountObjectPtr renumEltIds=newGeoTypesEltIdsAllGather->buildPermArrPerLevel(); - // - MEDCouplingAutoRefCountObjectPtr renumTupleIds=newGeoTypesPerChunk4->buildPermArrPerLevel(); - // - MEDCouplingAutoRefCountObjectPtr arrPart=arr->substr(offset,offset+szTuples); - arrPart->renumberInPlace(renumTupleIds->begin()); - arr->setPartOfValues1(arrPart,offset,offset+szTuples,1,0,arrPart->getNumberOfComponents(),1); - bool ret=false; - const int *idIt=diffVals->begin(); - std::list li(entriesOnSameDisc.begin(),entriesOnSameDisc.end()); - int offset2=0; - for(int i=0;igetNumberOfTuples();i++,idIt++) - { - MEDCouplingAutoRefCountObjectPtr ids=newGeoTypesEltIdsAllGather->getIdsEqual(*idIt); - MEDCouplingAutoRefCountObjectPtr subIds=newGeoTypesEltIdsAllGather2->selectByTupleId(ids->begin(),ids->end()); - int nbEntityElts=subIds->getNumberOfTuples(); - bool ret2; - MEDCouplingAutoRefCountObjectPtr eltToAdd=MEDFileFieldPerMeshPerTypePerDisc:: - NewObjectOnSameDiscThanPool(type,(INTERP_KERNEL::NormalizedCellType)newCode[3*(*idIt)],subIds,!subIds->isIdentity() || nbEntityElts!=newCode[3*(*idIt)+1],nbi, - offset+offset2, - li,glob,ret2); - ret=ret || ret2; - result.push_back(eltToAdd); - offset2+=nbEntityElts*nbi; - } - ret=ret || li.empty(); - return ret; -} - -/*! - * \param [in] typeF type of field of new chunk - * \param [in] geoType the geometric type of the chunk - * \param [in] idsOfMeshElt the entity ids of mesh (cells or nodes) of the new chunk. - * \param [in] isPfl specifies if a profile is requested regarding size of \a idsOfMeshElt and the number of such entities regarding underlying mesh. - * \param [in] nbi number of integration points - * \param [in] offset The offset in the **global array of data**. - * \param [in,out] entriesOnSameDisc the pool **on the same discretization** inside which it will be attempted to find an existing entry corresponding exactly - * to the new chunk to create. - * \param [in,out] glob the global shared info that will be requested for existing profiles or to append a new profile if needed. - * \param [out] notInExisting If false the return newly allocated entry is not coming from \a entriesOnSameDisc. If true the output comes from copy of \a entriesOnSameDisc - * and corresponding entry erased from \a entriesOnSameDisc. - * \return a newly allocated chunk - */ -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, - bool isPfl, int nbi, int offset, - std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - MEDFileFieldGlobsReal& glob, - bool ¬InExisting) -{ - int nbMeshEntities=idsOfMeshElt->getNumberOfTuples(); - std::list< const MEDFileFieldPerMeshPerTypePerDisc *>::iterator it=entriesOnSameDisc.begin(); - for(;it!=entriesOnSameDisc.end();it++) - { - if(((INTERP_KERNEL::NormalizedCellType)(*it)->_loc_id)==geoType && (*it)->_nval==nbMeshEntities) - { - if(!isPfl) - { - if((*it)->_profile.empty()) - break; - else - if(!(*it)->_profile.empty()) - { - const DataArrayInt *pfl=glob.getProfile((*it)->_profile.c_str()); - if(pfl->isEqualWithoutConsideringStr(*idsOfMeshElt)) - break; - } - } - } - } - if(it==entriesOnSameDisc.end()) - { - notInExisting=true; - MEDFileFieldPerMeshPerTypePerDisc *ret=new MEDFileFieldPerMeshPerTypePerDisc; - ret->_type=typeF; - ret->_loc_id=(int)geoType; - ret->_nval=nbMeshEntities; - ret->_start=offset; - ret->_end=ret->_start+ret->_nval*nbi; - if(isPfl) - { - idsOfMeshElt->setName(glob.createNewNameOfPfl().c_str()); - glob.appendProfile(idsOfMeshElt); - ret->_profile=idsOfMeshElt->getName(); - } - //tony treatment of localization - return ret; - } - else - { - notInExisting=false; - MEDFileFieldPerMeshPerTypePerDisc *ret=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)); - ret->_loc_id=(int)geoType; - ret->setNewStart(offset); - entriesOnSameDisc.erase(it); - return ret; - } - -} - -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd) -{ - return new MEDFileFieldPerMeshPerType(fid,fath,type,geoType,nasc,pd); -} - -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) -{ - return new MEDFileFieldPerMeshPerType(fath,geoType); -} - -std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySizeWithoutChildren() const -{ - return _field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileFieldPerMeshPerType::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - ret.push_back((const MEDFileFieldPerMeshPerTypePerDisc *)*it); - return ret; -} - -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerType(*this); - ret->_father=father; - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) - { - if((const MEDFileFieldPerMeshPerTypePerDisc *)*it) - ret->_field_pm_pt_pd[i]=(*it)->deepCpy((MEDFileFieldPerMeshPerType *)ret); - } - return ret.retn(); -} - -void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - std::vector pos=addNewEntryIfNecessary(field,offset,nbOfCells); - for(std::vector::const_iterator it=pos.begin();it!=pos.end();it++) - _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); -} - -/*! - * This method is the most general one. No optimization is done here. - * \param [in] multiTypePfl is the end user profile specified in high level API - * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type. - * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl. - * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. - * \param [in] nbOfEltsInWholeMesh nb of elts of type \a this->_geo_type in \b WHOLE mesh - * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. - */ -void MEDFileFieldPerMeshPerType::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - std::vector pos=addNewEntryIfNecessary(field,idsInPfl); - for(std::vector::const_iterator it=pos.begin();it!=pos.end();it++) - _field_pm_pt_pd[*it]->assignFieldProfile(isPflAlone,start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,arr,mesh,glob,nasc); -} - -void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) -{ - _field_pm_pt_pd.resize(1); - _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); - _field_pm_pt_pd[0]->assignNodeFieldNoProfile(start,field,arr,glob); -} - -void MEDFileFieldPerMeshPerType::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - MEDCouplingAutoRefCountObjectPtr pfl2=pfl->deepCpy(); - if(!arr || !arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::assignNodeFieldProfile : input array is null, or not allocated !"); - _field_pm_pt_pd.resize(1); - _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); - _field_pm_pt_pd[0]->assignFieldProfile(true,start,pfl,pfl2,pfl2,-1,field,arr,0,glob,nasc);//mesh is not requested so 0 is send. -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) -{ - TypeOfField type=field->getTypeOfField(); - if(type!=ON_GAUSS_PT) - { - int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0); - int sz=_field_pm_pt_pd.size(); - bool found=false; - for(int j=0;jgetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - } - std::vector ret(1,(int)sz); - return ret; - } - else - { - std::vector ret2=addNewEntryIfNecessaryGauss(field,offset,nbOfCells); - int sz2=ret2.size(); - std::vector ret3(sz2); - int k=0; - for(int i=0;igetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=j; - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=sz; - } - } - return ret3; - } -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) -{ - const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); - if(!disc2) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); - const DataArrayInt *da=disc2->getArrayOfDiscIds(); - if(!da) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss (no profile) : no localization ids per cell array available ! The input Gauss node field is maybe invalid !"); - MEDCouplingAutoRefCountObjectPtr da2=da->selectByTupleId2(offset,offset+nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr retTmp=da2->getDifferentValues(); - if(retTmp->presenceOfValue(-1)) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); - std::vector ret(retTmp->begin(),retTmp->end()); - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) -{ - TypeOfField type=field->getTypeOfField(); - if(type!=ON_GAUSS_PT) - { - int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0); - int sz=_field_pm_pt_pd.size(); - bool found=false; - for(int j=0;jgetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - } - std::vector ret(1,0); - return ret; - } - else - { - std::vector ret2=addNewEntryIfNecessaryGauss(field,subCells); - int sz2=ret2.size(); - std::vector ret3(sz2); - int k=0; - for(int i=0;igetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=j; - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=sz; - } - } - return ret3; - } -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) -{ - const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); - if(!disc2) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); - const DataArrayInt *da=disc2->getArrayOfDiscIds(); - if(!da) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : no localization ids per cell array available ! The input Gauss node field is maybe invalid !"); - MEDCouplingAutoRefCountObjectPtr da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr retTmp=da2->getDifferentValues(); - if(retTmp->presenceOfValue(-1)) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); - std::vector ret(retTmp->begin(),retTmp->end()); - return ret; -} - -const MEDFileFieldPerMesh *MEDFileFieldPerMeshPerType::getFather() const -{ - return _father; -} - -void MEDFileFieldPerMeshPerType::getDimension(int& dim) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - int curDim=(int)cm.getDimension(); - dim=std::max(dim,curDim); -} - -void MEDFileFieldPerMeshPerType::fillTypesOfFieldAvailable(std::set& types) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - (*it)->fillTypesOfFieldAvailable(types); - } -} - -void MEDFileFieldPerMeshPerType::fillFieldSplitedByType(std::vector< std::pair >& dads, std::vector& types, std::vector& pfls, std::vector& locs) const -{ - int sz=_field_pm_pt_pd.size(); - dads.resize(sz); types.resize(sz); pfls.resize(sz); locs.resize(sz); - for(int i=0;igetCoarseData(types[i],dads[i],pfls[i],locs[i]); - } -} - -int MEDFileFieldPerMeshPerType::getIteration() const -{ - return _father->getIteration(); -} - -int MEDFileFieldPerMeshPerType::getOrder() const -{ - return _father->getOrder(); -} - -double MEDFileFieldPerMeshPerType::getTime() const -{ - return _father->getTime(); -} - -std::string MEDFileFieldPerMeshPerType::getMeshName() const -{ - return _father->getMeshName(); -} - -void MEDFileFieldPerMeshPerType::simpleRepr(int bkOffset, std::ostream& oss, int id) const -{ - const char startLine[]=" ## "; - std::string startLine2(bkOffset,' '); - std::string startLine3(startLine2); - startLine3+=startLine; - if(_geo_type!=INTERP_KERNEL::NORM_ERROR) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - oss << startLine3 << "Entry geometry type #" << id << " is lying on geometry types " << cm.getRepr() << "." << std::endl; - } - else - oss << startLine3 << "Entry geometry type #" << id << " is lying on NODES." << std::endl; - oss << startLine3 << "Entry is defined on " << _field_pm_pt_pd.size() << " localizations." << std::endl; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) - { - const MEDFileFieldPerMeshPerTypePerDisc *cur=(*it); - if(cur) - cur->simpleRepr(bkOffset,oss,i); - else - { - oss << startLine2 << " ## " << "Localization #" << i << " is empty !" << std::endl; - } - } -} - -void MEDFileFieldPerMeshPerType::getSizes(int& globalSz, int& nbOfEntries) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - globalSz+=(*it)->getNumberOfTuples(); - } - nbOfEntries+=(int)_field_pm_pt_pd.size(); -} - -INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerType::getGeoType() const -{ - return _geo_type; -} - - -int MEDFileFieldPerMeshPerType::getNumberOfComponents() const -{ - return _father->getNumberOfComponents(); -} - -bool MEDFileFieldPerMeshPerType::presenceOfMultiDiscPerGeoType() const -{ - std::size_t nb(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - const MEDFileFieldPerMeshPerTypePerDisc *fmtd(*it); - if(fmtd) - nb++; - } - return nb>1; -} - -DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() -{ - return _father->getOrCreateAndGetArray(); -} - -const DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() const -{ - const MEDFileFieldPerMesh *fath=_father; - return fath->getOrCreateAndGetArray(); -} - -const std::vector& MEDFileFieldPerMeshPerType::getInfo() const -{ - return _father->getInfo(); -} - -std::vector MEDFileFieldPerMeshPerType::getPflsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getProfile(); - if(!tmp.empty()) - if(ret2.find(tmp)==ret2.end()) - { - ret.push_back(tmp); - ret2.insert(tmp); - } - } - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::getLocsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getLocalization(); - if(!tmp.empty() && tmp!=MED_GAUSS_ELNO) - if(ret2.find(tmp)==ret2.end()) - { - ret.push_back(tmp); - ret2.insert(tmp); - } - } - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::getPflsReallyUsedMulti() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getProfile(); - if(!tmp.empty()) - ret.push_back(tmp); - } - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::getLocsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getLocalization(); - if(!tmp.empty() && tmp!=MED_GAUSS_ELNO) - ret.push_back(tmp); - } - return ret; -} - -void MEDFileFieldPerMeshPerType::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - (*it1)->changePflsRefsNamesGen(mapOfModif); -} - -void MEDFileFieldPerMeshPerType::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - (*it1)->changeLocsRefsNamesGen(mapOfModif); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) -{ - if(_field_pm_pt_pd.empty()) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no localizations for geotype \"" << cm.getRepr() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(locId>=0 && locId<(int)_field_pm_pt_pd.size()) - return _field_pm_pt_pd[locId]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no such locId available (" << locId; - oss2 << ") for geometric type \"" << cm.getRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - return static_cast(0); -} - -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) const -{ - if(_field_pm_pt_pd.empty()) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no localizations for geotype \"" << cm.getRepr() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(locId>=0 && locId<(int)_field_pm_pt_pd.size()) - return _field_pm_pt_pd[locId]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no such locId available (" << locId; - oss2 << ") for geometric type \"" << cm.getRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - return static_cast(0); -} - -void MEDFileFieldPerMeshPerType::getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const -{ - if(_geo_type!=INTERP_KERNEL::NORM_ERROR) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - if(meshDim!=(int)cm.getDimension()) - return ; - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->getFieldAtLevel(type,glob,dads,pfls,locs,geoTypes); -} - -void MEDFileFieldPerMeshPerType::fillValues(int& startEntryId, std::vector< std::pair,std::pair > >& entries) const -{ - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) - { - (*it)->fillValues(i,startEntryId,entries); - } -} - -void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) -{ - _field_pm_pt_pd=leaves; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->setFather(this); -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - * \return bool - false if the type of field \a tof is not contained in \a this. - */ -bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) -{ - bool ret(false); - std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - if((*it)->getType()==tof) - { - newPmPtPd.push_back(*it); - std::pair bgEnd; bgEnd.first=(*it)->getStart(); bgEnd.second=(*it)->getEnd(); - (*it)->setNewStart(globalNum); - globalNum=(*it)->getEnd(); - its.push_back(bgEnd); - ret=true; - } - if(ret) - _field_pm_pt_pd=newPmPtPd; - return ret; -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - * \return bool - false if the type of field \a tof is not contained in \a this. - */ -bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) -{ - if(_field_pm_pt_pd.size()<=idOfDisc) - return false; - MEDCouplingAutoRefCountObjectPtr elt(_field_pm_pt_pd[idOfDisc]); - std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd(1,elt); - std::pair bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd(); - elt->setNewStart(globalNum); - globalNum=elt->getEnd(); - its.push_back(bgEnd); - _field_pm_pt_pd=newPmPtPd; - return true; -} - -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType) -{ -} - -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd):_father(fath),_geo_type(geoType) -{ - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_geometry_type mgeoti; - med_entity_type menti(ConvertIntoMEDFileType(type,geoType,mgeoti)); - int nbProfiles(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),menti,mgeoti,pflName,locName)); - _field_pm_pt_pd.resize(nbProfiles); - for(int i=0;i >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); -} - -void MEDFileFieldPerMeshPerType::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->loadBigArray(fid,nasc); -} - -void MEDFileFieldPerMeshPerType::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - (*it)->copyOptionsFrom(*this); - (*it)->writeLL(fid,nasc); - } -} - -med_entity_type MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType) -{ - switch(ikType) - { - case ON_CELLS: - medfGeoType=typmai3[(int)ikGeoType]; - return MED_CELL; - case ON_NODES: - medfGeoType=MED_NONE; - return MED_NODE; - case ON_GAUSS_NE: - medfGeoType=typmai3[(int)ikGeoType]; - return MED_NODE_ELEMENT; - case ON_GAUSS_PT: - medfGeoType=typmai3[(int)ikGeoType]; - return MED_CELL; - default: - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType : unexpected entity type ! internal error"); - } - return MED_UNDEF_ENTITY_TYPE; -} - -MEDFileFieldPerMesh *MEDFileFieldPerMesh::NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities) -{ - return new MEDFileFieldPerMesh(fid,fath,meshCsit,meshIteration,meshOrder,nasc,mm,entities); -} - -MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh) -{ - return new MEDFileFieldPerMesh(fath,mesh); -} - -std::size_t MEDFileFieldPerMesh::getHeapMemorySizeWithoutChildren() const -{ - return _mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >); -} - -std::vector MEDFileFieldPerMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - ret.push_back((const MEDFileFieldPerMeshPerType *)*it); - return ret; -} - -MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const -{ - MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this); - ret->_father=father; - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) - { - if((const MEDFileFieldPerMeshPerType *)*it) - ret->_field_pm_pt[i]=(*it)->deepCpy((MEDFileFieldPerMesh *)(ret)); - } - return ret.retn(); -} - -void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) const -{ - std::string startLine(bkOffset,' '); - oss << startLine << "## Field part (" << id << ") lying on mesh \"" << _mesh_name << "\", Mesh iteration=" << _mesh_iteration << ". Mesh order=" << _mesh_order << "." << std::endl; - oss << startLine << "## Field is defined on " << _field_pm_pt.size() << " types." << std::endl; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) - { - const MEDFileFieldPerMeshPerType *cur=*it; - if(cur) - cur->simpleRepr(bkOffset,oss,i); - else - { - oss << startLine << " ## Entry geometry type #" << i << " is empty !" << std::endl; - } - } -} - -void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh) -{ - _mesh_name=mesh->getName(); - mesh->getTime(_mesh_iteration,_mesh_order); -} - -void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - int nbOfTypes=code.size()/3; - int offset=0; - for(int i=0;iassignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); - offset+=nbOfCells; - } -} - -/*! - * This method is the most general one. No optimization is done here. - * \param [in] multiTypePfl is the end user profile specified in high level API - * \param [in] code is the code of \a mesh[multiTypePfl] mesh. It is of size of number of different geometric types into \a mesh[multiTypePfl]. - * \param [in] code2 is the code of the \b WHOLE mesh on the same level. So all types in \a code are in \a code2. - * \param [in] idsInPflPerType is the selection into the \a multiTypePfl whole profile that corresponds to the given geometric type. This vector is always 3 times smaller than \a code. - * \param [in] idsPerType is a vector containing the profiles needed to be created for MED file format. \b WARNING these processed MED file profiles can be subdivided again in case of Gauss points. - * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. - */ -void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - int nbOfTypes(code.size()/3); - for(int i=0;iassignFieldProfile(nbOfTypes==1,start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,arr,mesh,glob,nasc); - } -} - -void MEDFileFieldPerMesh::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) -{ - int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); - _field_pm_pt[pos]->assignNodeFieldNoProfile(start,field,arr,glob); -} - -void MEDFileFieldPerMesh::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); - _field_pm_pt[pos]->assignNodeFieldProfile(start,pfl,field,arr,glob,nasc); -} - -void MEDFileFieldPerMesh::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); -} - -void MEDFileFieldPerMesh::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->loadBigArraysRecursively(fid,nasc); -} - -void MEDFileFieldPerMesh::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const -{ - int nbOfTypes=_field_pm_pt.size(); - for(int i=0;icopyOptionsFrom(*this); - _field_pm_pt[i]->writeLL(fid,nasc); - } -} - -void MEDFileFieldPerMesh::getDimension(int& dim) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->getDimension(dim); -} - -void MEDFileFieldPerMesh::fillTypesOfFieldAvailable(std::set& types) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->fillTypesOfFieldAvailable(types); -} - -std::vector< std::vector< std::pair > > MEDFileFieldPerMesh::getFieldSplitedByType(std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector > & locs) const -{ - int sz=_field_pm_pt.size(); - std::vector< std::vector > > ret(sz); - types.resize(sz); typesF.resize(sz); pfls.resize(sz); locs.resize(sz); - for(int i=0;igetGeoType(); - _field_pm_pt[i]->fillFieldSplitedByType(ret[i],typesF[i],pfls[i],locs[i]); - } - return ret; -} - -double MEDFileFieldPerMesh::getTime() const -{ - int tmp1,tmp2; - return _father->getTime(tmp1,tmp2); -} - -int MEDFileFieldPerMesh::getIteration() const -{ - return _father->getIteration(); -} - -int MEDFileFieldPerMesh::getOrder() const -{ - return _father->getOrder(); -} - -int MEDFileFieldPerMesh::getNumberOfComponents() const -{ - return _father->getNumberOfComponents(); -} - -bool MEDFileFieldPerMesh::presenceOfMultiDiscPerGeoType() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - const MEDFileFieldPerMeshPerType *fpmt(*it); - if(!fpmt) - continue; - if(fpmt->presenceOfMultiDiscPerGeoType()) - return true; - } - return false; -} - -DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); - return _father->getOrCreateAndGetArray(); -} - -const DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() const -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); - return _father->getOrCreateAndGetArray(); -} - -const std::vector& MEDFileFieldPerMesh::getInfo() const -{ - return _father->getInfo(); -} - -/*! - * type,geoTypes,dads,pfls,locs are input parameters. They should have the same size. - * Before the call of this method 'geoTypes','dads','pfls','locs' must be reorganized so that types in geoTypes are contiguous and ordered following typmai2 array. - * It returns 2 output vectors : - * - 'code' of size 3*sz where sz is the number of different values into 'geoTypes' - * - 'notNullPfls' contains sz2 values that are extracted from 'pfls' in which null profiles have been removed. - * 'code' and 'notNullPfls' are in MEDCouplingUMesh::checkTypeConsistencyAndContig format. - */ -void MEDFileFieldPerMesh::SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& pfls, const std::vector& locs, std::vector& code, std::vector& notNullPfls) -{ - int notNullPflsSz=0; - int nbOfArrs=geoTypes.size(); - for(int i=0;i geoTypes3(geoTypes.begin(),geoTypes.end()); - int nbOfDiffGeoTypes=geoTypes3.size(); - code.resize(3*nbOfDiffGeoTypes); - notNullPfls.resize(notNullPflsSz); - notNullPflsSz=0; - int j=0; - for(int i=0;i notNullTmp; - if(pfls[j]) - notNullTmp.push_back(pfls[j]); - j++; - for(;j > tmpDads(dads.begin()+startZone,dads.begin()+j); - std::vector tmpPfls(pfls.begin()+startZone,pfls.begin()+j); - std::vector tmpLocs(locs.begin()+startZone,locs.begin()+j); - code[3*i]=(int)refType; - std::vector refType2(1,refType); - code[3*i+1]=ComputeNbOfElems(glob,type,refType2,tmpDads,tmpLocs); - if(notNullTmp.empty()) - code[3*i+2]=-1; - else - { - notNullPfls[notNullPflsSz]=DataArrayInt::Aggregate(notNullTmp); - code[3*i+2]=notNullPflsSz++; - } - } -} - -/*! - * 'dads' 'geoTypes' and 'locs' are input parameters that should have same size sz. sz should be >=1. - */ -int MEDFileFieldPerMesh::ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs) -{ - int sz=dads.size(); - int ret=0; - for(int i=0;igetNbOfGaussPtPerCell(locs[i]); - ret+=(dads[i].second-dads[i].first)/nbOfGaussPtPerCell; - } - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getPflsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getPflsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getLocsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getLocsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) - { - if((*it).first==_mesh_name) - { - _mesh_name=(*it).second; - return true; - } - } - return false; -} - -bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) -{ - if(_mesh_name!=meshName) - return false; - std::set typesToKeep; - for(std::size_t i=0;i,std::pair > > entries; - std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKept; - std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> otherEntries; - getUndergroundDataArrayExt(entries); - DataArray *arr0=getOrCreateAndGetArray();//tony - if(!arr0) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values of field is null !"); - DataArrayDouble *arr=dynamic_cast(arr0);//tony - if(!arr0) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values is double ! Not managed for the moment !"); - int sz=0; - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArrayDouble storing values of field is null !"); - for(std::vector< std::pair,std::pair > >::const_iterator it=entries.begin();it!=entries.end();it++) - { - if(typesToKeep.find((*it).first.first)!=typesToKeep.end()) - { - entriesKept.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second)); - sz+=(*it).second.second-(*it).second.first; - } - else - otherEntries.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second)); - } - MEDCouplingAutoRefCountObjectPtr renumDefrag=DataArrayInt::New(); renumDefrag->alloc(arr->getNumberOfTuples(),1); renumDefrag->fillWithZero(); - //////////////////// - MEDCouplingAutoRefCountObjectPtr explicitIdsOldInMesh=DataArrayInt::New(); explicitIdsOldInMesh->alloc(sz,1);//sz is a majorant of the real size. A realloc will be done after - int *workI2=explicitIdsOldInMesh->getPointer(); - int sz1=0,sz2=0,sid=1; - std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptML=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKept); - // std::vector tupleIdOfStartOfNewChuncksV(entriesKeptML.size()); - for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator itL1=entriesKeptML.begin();itL1!=entriesKeptML.end();itL1++,sid++) - { - // tupleIdOfStartOfNewChuncksV[sid-1]=sz2; - MEDCouplingAutoRefCountObjectPtr explicitIdsOldInArr=DataArrayInt::New(); explicitIdsOldInArr->alloc(sz,1); - int *workI=explicitIdsOldInArr->getPointer(); - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*itL1).begin();itL2!=(*itL1).end();itL2++) - { - int delta1=(*itL2)->fillTupleIds(workI); workI+=delta1; sz1+=delta1; - (*itL2)->setLocId(sz2); - (*itL2)->_tmp_work1=(*itL2)->getStart(); - int delta2=(*itL2)->fillEltIdsFromCode(sz2,oldCode,glob,workI2); workI2+=delta2; sz2+=delta2; - } - renumDefrag->setPartOfValuesSimple3(sid,explicitIdsOldInArr->begin(),explicitIdsOldInArr->end(),0,1,1); - } - explicitIdsOldInMesh->reAlloc(sz2); - int tupleIdOfStartOfNewChuncks=arr->getNumberOfTuples()-sz2; - //////////////////// - MEDCouplingAutoRefCountObjectPtr permArrDefrag=renumDefrag->buildPermArrPerLevel(); renumDefrag=0; - // perform redispatching of non concerned MEDFileFieldPerMeshPerTypePerDisc - std::vector< MEDCouplingAutoRefCountObjectPtr > otherEntriesNew; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=otherEntries.begin();it!=otherEntries.end();it++) - { - otherEntriesNew.push_back(MEDFileFieldPerMeshPerTypePerDisc::New(*(*it))); - otherEntriesNew.back()->setNewStart(permArrDefrag->getIJ((*it)->getStart(),0)); - otherEntriesNew.back()->setLocId((*it)->getGeoType()); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > entriesKeptNew; - std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKeptNew2; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesKept.begin();it!=entriesKept.end();it++) - { - MEDCouplingAutoRefCountObjectPtr elt=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)); - int newStart=elt->getLocId(); - elt->setLocId((*it)->getGeoType()); - elt->setNewStart(newStart); - elt->_tmp_work1=permArrDefrag->getIJ(elt->_tmp_work1,0); - entriesKeptNew.push_back(elt); - entriesKeptNew2.push_back(elt); - } - MEDCouplingAutoRefCountObjectPtr arr2=arr->renumber(permArrDefrag->getConstPointer()); - // perform redispatching of concerned MEDFileFieldPerMeshPerTypePerDisc -> values are in arr2 - MEDCouplingAutoRefCountObjectPtr explicitIdsNewInMesh=renumO2N->selectByTupleId(explicitIdsOldInMesh->begin(),explicitIdsOldInMesh->end()); - std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptPerDisc=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKeptNew2); - bool ret=false; - for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it4=entriesKeptPerDisc.begin();it4!=entriesKeptPerDisc.end();it4++) - { - sid=0; - /*for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*it4).begin();itL2!=(*it4).end();itL2++) - { - MEDFileFieldPerMeshPerTypePerDisc *curNC=const_cast(*itL2); - curNC->setNewStart(permArrDefrag->getIJ((*itL2)->getStart(),0)-tupleIdOfStartOfNewChuncks+tupleIdOfStartOfNewChuncksV[sid]); - }*/ - ret=MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(tupleIdOfStartOfNewChuncks,*it4,explicitIdsNewInMesh,newCode, - glob,arr2,otherEntriesNew) || ret; - } - if(!ret) - return false; - // Assign new dispatching - assignNewLeaves(otherEntriesNew); - arr->cpyFrom(*arr2); - return true; -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - */ -void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector< std::pair > its2; - if((*it)->keepOnlySpatialDiscretization(tof,globalNum,its2)) - { - ret.push_back(*it); - its.insert(its.end(),its2.begin(),its2.end()); - } - } - _field_pm_pt=ret; -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - */ -void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector< std::pair > its2; - if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2)) - { - ret.push_back(*it); - its.insert(its.end(),its2.begin(),its2.end()); - } - } - _field_pm_pt=ret; -} - -void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) -{ - std::map > > types; - for( std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >::const_iterator it=leaves.begin();it!=leaves.end();it++) - types[(INTERP_KERNEL::NormalizedCellType)(*it)->getLocId()].push_back(*it); - // - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > fieldPmPt(types.size()); - std::map > >::const_iterator it1=types.begin(); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it2=fieldPmPt.begin(); - for(;it1!=types.end();it1++,it2++) - { - MEDCouplingAutoRefCountObjectPtr elt=MEDFileFieldPerMeshPerType::New(this,(INTERP_KERNEL::NormalizedCellType)((*it1).second[0]->getLocId())); - elt->setLeaves((*it1).second); - *it2=elt; - } - _field_pm_pt=fieldPmPt; -} - -void MEDFileFieldPerMesh::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->changePflsRefsNamesGen(mapOfModif); -} - -void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->changeLocsRefsNamesGen(mapOfModif); -} - -/*! - * \param [in] mesh is the whole mesh - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - if(_field_pm_pt.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); - // - std::vector< std::pair > dads; - std::vector pfls; - std::vector notNullPflsPerGeoType; - std::vector locs,code; - std::vector geoTypes; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes); - // Sort by types - SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); - if(code.empty()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector< MEDCouplingAutoRefCountObjectPtr > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - if(type!=ON_NODES) - { - DataArrayInt *arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); - if(!arr) - return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); - else - { - MEDCouplingAutoRefCountObjectPtr arr2(arr); - return finishField2(type,glob,dads,locs,geoTypes,mesh,arr,isPfl,arrOut,nasc); - } - } - else - { - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !"); - int nb=code[1]; - if(code[2]==-1) - { - if(nb!=mesh->getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes(); - oss << " nodes in mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); - } - else - return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl,arrOut,nasc); - } -} - -DataArray *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const -{ - if(_field_pm_pt.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); - // - std::vector > dads; - std::vector pfls; - std::vector notNullPflsPerGeoType; - std::vector locs,code; - std::vector geoTypes; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes); - // Sort by types - SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); - if(code.empty()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - if(type!=ON_NODES) - { - MEDCouplingAutoRefCountObjectPtr arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); - return finishField4(dads,arr,mesh->getNumberOfCells(),pfl); - } - else - { - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !"); - int nb=code[1]; - if(code[2]==-1) - { - if(nb!=mesh->getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes(); - oss << " nodes in mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return finishField4(dads,code[2]==-1?0:notNullPflsPerGeoType3[0],mesh->getNumberOfNodes(),pfl); - } - // - return 0; -} - -void MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - int globalSz=0; - int nbOfEntries=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - (*it)->getSizes(globalSz,nbOfEntries); - } - entries.resize(nbOfEntries); - nbOfEntries=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - (*it)->fillValues(nbOfEntries,entries); - } -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - if((*it)->getGeoType()==typ) - return (*it)->getLeafGivenLocId(locId); - } - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl; - oss << "Possiblities are : "; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType()); - oss << "\"" << cm2.getRepr() << "\", "; - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - if((*it)->getGeoType()==typ) - return (*it)->getLeafGivenLocId(locId); - } - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl; - oss << "Possiblities are : "; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType()); - oss << "\"" << cm2.getRepr() << "\", "; - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type) -{ - int i=0; - int pos=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,type)); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it2=_field_pm_pt.begin(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) - { - INTERP_KERNEL::NormalizedCellType curType=(*it)->getGeoType(); - if(type==curType) - return i; - else - { - int pos2=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,curType)); - if(pos>pos2) - it2=it+1; - } - } - int ret=std::distance(_field_pm_pt.begin(),it2); - _field_pm_pt.insert(it2,MEDFileFieldPerMeshPerType::New(this,type)); - return ret; -} - -/*! - * 'dads' and 'locs' input parameters have the same number of elements - * \param [in] mesh is \b NOT the global mesh, but the possibly reduced mesh. \a mesh parameter will be directly aggregated in the returned field - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - isPfl=false; - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(type,ONE_TIME); - ret->setMesh(mesh); ret->setName(nasc.getName().c_str()); ret->setTime(getTime(),getIteration(),getOrder()); ret->setTimeUnit(nasc.getDtUnit().c_str()); - MEDCouplingAutoRefCountObjectPtr da=getOrCreateAndGetArray()->selectByTupleRanges(dads); - const std::vector& infos=getInfo(); - da->setInfoOnComponents(infos); - da->setName(""); - if(type==ON_GAUSS_PT) - { - int offset=0; - int nbOfArrs=dads.size(); - for(int i=0;i > dads2(1,dads[i]); const std::vector locs2(1,locs[i]); - const std::vector geoTypes2(1,INTERP_KERNEL::NORM_ERROR); - int nbOfElems=ComputeNbOfElems(glob,type,geoTypes2,dads2,locs2); - MEDCouplingAutoRefCountObjectPtr di=DataArrayInt::New(); - di->alloc(nbOfElems,1); - di->iota(offset); - const MEDFileFieldLoc& fl=glob->getLocalizationFromId(locs[i]); - ret->setGaussLocalizationOnCells(di->getConstPointer(),di->getConstPointer()+nbOfElems,fl.getRefCoords(),fl.getGaussCoords(),fl.getGaussWeights()); - offset+=nbOfElems; - } - } - arrOut=da; - return ret.retn(); -} - -/*! - * This method is an extension of MEDFileFieldPerMesh::finishField method. It deals with profiles. This method should be called when type is different from ON_NODES. - * 'dads', 'locs' and 'geoTypes' input parameters have the same number of elements. - * No check of this is performed. 'da' array contains an array in old2New style to be applyied to mesh to obtain the right support. - * The order of cells in the returned field is those imposed by the profile. - * \param [in] mesh is the global mesh. - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector >& dads, const std::vector& locs, - const std::vector& geoTypes, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - if(da->isIdentity()) - { - int nbOfTuples=da->getNumberOfTuples(); - if(nbOfTuples==mesh->getNumberOfCells()) - return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); - } - MEDCouplingAutoRefCountObjectPtr m2=mesh->buildPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - m2->setName(mesh->getName().c_str()); - MEDCouplingAutoRefCountObjectPtr ret=finishField(type,glob,dads,locs,m2,isPfl,arrOut,nasc); - isPfl=true; - return ret.retn(); -} - -/*! - * This method is the complement of MEDFileFieldPerMesh::finishField2 method except that this method works for node profiles. - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob, - const std::vector >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - if(da->isIdentity()) - { - int nbOfTuples=da->getNumberOfTuples(); - if(nbOfTuples==mesh->getNumberOfNodes())//No problem for NORM_ERROR because it is in context of node - return finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); - } - // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1. - const MEDCouplingUMesh *meshu=dynamic_cast(mesh); - if(meshu) - { - if(meshu->getNodalConnectivity()==0) - { - MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_CELLS,glob,dads,locs,mesh,isPfl,arrOut,nasc); - int nb=da->getNbOfElems(); - const int *ptr=da->getConstPointer(); - MEDCouplingUMesh *meshuc=const_cast(meshu); - meshuc->allocateCells(nb); - for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_POINT1,1,ptr+i); - meshuc->finishInsertingCells(); - ret->setMesh(meshuc); - const MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); - if(!disc) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::finishFieldNode2 : internal error, no discretization on field !"); - disc->checkCoherencyBetween(meshuc,arrOut); - return ret.retn(); - } - } - // - MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); - isPfl=true; - DataArrayInt *arr2=0; - MEDCouplingAutoRefCountObjectPtr cellIds=mesh->getCellIdsFullyIncludedInNodeIds(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - MEDCouplingAutoRefCountObjectPtr mesh2=mesh->buildPartAndReduceNodes(cellIds->getConstPointer(),cellIds->getConstPointer()+cellIds->getNbOfElems(),arr2); - MEDCouplingAutoRefCountObjectPtr arr3(arr2); - int nnodes=mesh2->getNumberOfNodes(); - if(nnodes==(int)da->getNbOfElems()) - { - MEDCouplingAutoRefCountObjectPtr da3=da->transformWithIndArrR(arr2->begin(),arr2->end()); - arrOut->renumberInPlace(da3->getConstPointer()); - mesh2->setName(mesh->getName().c_str()); - ret->setMesh(mesh2); - return ret.retn(); - } - else - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishFieldNode2 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!"; - oss << "So it is impossible to return a well definied MEDCouplingFieldDouble instance on specified mesh on a specified meshDim !" << std::endl; - oss << "To retrieve correctly such a field you have 3 possibilities :" << std::endl; - oss << " - use an another meshDim compatible with the field on nodes (MED file does not have such information)" << std::endl; - oss << " - use an another a meshDimRelToMax equal to 1 -> it will return a mesh with artificial cell POINT1 containing the profile !" << std::endl; - oss << " - if definitely the node profile has no link with mesh connectivity use MEDFileField1TS::getFieldWithProfile or MEDFileFieldMultiTS::getFieldWithProfile methods instead !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return 0; -} - -/*! - * This method is the most light method of field retrieving. - */ -DataArray *MEDFileFieldPerMesh::finishField4(const std::vector >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const -{ - if(!pflIn) - { - pflOut=DataArrayInt::New(); - pflOut->alloc(nbOfElems,1); - pflOut->iota(0); - } - else - { - pflOut=const_cast(pflIn); - pflOut->incrRef(); - } - MEDCouplingAutoRefCountObjectPtr safePfl(pflOut); - MEDCouplingAutoRefCountObjectPtr da=getOrCreateAndGetArray()->selectByTupleRanges(dads); - const std::vector& infos=getInfo(); - int nbOfComp=infos.size(); - for(int i=0;isetInfoOnComponent(i,infos[i].c_str()); - safePfl->incrRef(); - return da.retn(); -} - - -/// @cond INTERNAL - -class MFFPMIter -{ -public: - static MFFPMIter *NewCell(const std::vector< std::pair > *entities); - static bool IsPresenceOfNode(const std::vector< std::pair > *entities); - virtual ~MFFPMIter() { } - virtual void begin() = 0; - virtual bool finished() const = 0; - virtual void next() = 0; - virtual int current() const = 0; -}; - -class MFFPMIterSimple : public MFFPMIter -{ -public: - MFFPMIterSimple():_pos(0) { } - void begin() { _pos=0; } - bool finished() const { return _pos>=MED_N_CELL_FIXED_GEO; } - void next() { _pos++; } - int current() const { return _pos; } -private: - int _pos; -}; - -class MFFPMIter2 : public MFFPMIter -{ -public: - MFFPMIter2(const std::vector& cts); - void begin() { _it=_ids.begin(); } - bool finished() const { return _it==_ids.end(); } - void next() { _it++; } - int current() const { return *_it; } -private: - std::vector _ids; - std::vector::const_iterator _it; -}; - -MFFPMIter *MFFPMIter::NewCell(const std::vector< std::pair > *entities) -{ - if(!entities) - return new MFFPMIterSimple; - else - { - std::vector tmp; - for(std::vector< std::pair >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) - { - if((*it).first==ON_CELLS || (*it).first==ON_GAUSS_NE || (*it).first==ON_GAUSS_PT) - tmp.push_back((*it).second); - } - return new MFFPMIter2(tmp); - } -} - -bool MFFPMIter::IsPresenceOfNode(const std::vector< std::pair > *entities) -{ - if(!entities) - return true; - else - { - for(std::vector< std::pair >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) - if((*it).first==ON_NODES) - return true; - return false; - } -} - -MFFPMIter2::MFFPMIter2(const std::vector& cts) -{ - std::size_t sz(cts.size()); - _ids.resize(sz); - for(std::size_t i=0;i > *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder), - _father(fath) -{ - INTERP_KERNEL::AutoPtr meshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr pflName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr locName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - const MEDFileUMesh *mmu(dynamic_cast(mm)); - INTERP_KERNEL::AutoCppPtr iter0(MFFPMIter::NewCell(entities)); - for(iter0->begin();!iter0->finished();iter0->next()) - { - int nbProfile (MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_CELL ,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); - std::string name0(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); - int nbProfile2(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); - std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); - if(nbProfile>0 || nbProfile2>0) - { - const PartDefinition *pd(0); - if(mmu) - pd=mmu->getPartDefAtLevel(mmu->getRelativeLevOnGeoType(typmai2[iter0->current()]),typmai2[iter0->current()]); - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pd)); - if(nbProfile>0) - _mesh_name=name0; - else - _mesh_name=name1; - } - } - if(MFFPMIter::IsPresenceOfNode(entities)) - { - int nbProfile(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,meshCsit+1,meshName,pflName,locName)); - if(nbProfile>0) - { - const PartDefinition *pd(0); - if(mmu) - pd=mmu->getPartDefAtLevel(1,INTERP_KERNEL::NORM_ERROR); - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR,nasc,pd)); - _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); - } - } -} - -MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh):_father(fath) -{ - copyTinyInfoFrom(mesh); -} - -void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int id, const std::string& pflName) -{ - if(id>=(int)_pfls.size()) - _pfls.resize(id+1); - _pfls[id]=DataArrayInt::New(); - int lgth(MEDprofileSizeByName(fid,pflName.c_str())); - _pfls[id]->setName(pflName); - _pfls[id]->alloc(lgth,1); - MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName.c_str(),_pfls[id]->getPointer())); - _pfls[id]->applyLin(1,-1,0);//Converting into C format -} - -void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int i) -{ - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - int sz; - MEDFILESAFECALLERRD0(MEDprofileInfo,(fid,i+1,pflName,&sz)); - std::string pflCpp=MEDLoaderBase::buildStringFromFortran(pflName,MED_NAME_SIZE); - if(i>=(int)_pfls.size()) - _pfls.resize(i+1); - _pfls[i]=DataArrayInt::New(); - _pfls[i]->alloc(sz,1); - _pfls[i]->setName(pflCpp.c_str()); - MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName,_pfls[i]->getPointer())); - _pfls[i]->applyLin(1,-1,0);//Converting into C format -} - -void MEDFileFieldGlobs::writeGlobals(med_idt fid, const MEDFileWritable& opt) const -{ - int nbOfPfls=_pfls.size(); - for(int i=0;i cpy=_pfls[i]->deepCpy(); - cpy->applyLin(1,1,0); - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(_pfls[i]->getName().c_str(),MED_NAME_SIZE,pflName,opt.getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDprofileWr,(fid,pflName,_pfls[i]->getNumberOfTuples(),cpy->getConstPointer())); - } - // - int nbOfLocs=_locs.size(); - for(int i=0;iwriteLL(fid); -} - -void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) -{ - std::vector pfls=getPfls(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._pfls.begin();it!=other._pfls.end();it++) - { - std::vector::iterator it2=std::find(pfls.begin(),pfls.end(),(*it)->getName()); - if(it2==pfls.end()) - { - _pfls.push_back(*it); - } - else - { - int id=std::distance(pfls.begin(),it2); - if(!(*it)->isEqual(*_pfls[id])) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendGlobs : Profile \"" << (*it)->getName() << "\" already exists and is different from those expecting to be append !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - std::vector locs=getLocs(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._locs.begin();it!=other._locs.end();it++) - { - std::vector::iterator it2=std::find(locs.begin(),locs.end(),(*it)->getName()); - if(it2==locs.end()) - { - _locs.push_back(*it); - } - else - { - int id=std::distance(locs.begin(),it2); - if(!(*it)->isEqual(*_locs[id],eps)) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendGlobs : Localization \"" << (*it)->getName() << "\" already exists and is different from those expecting to be append !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -void MEDFileFieldGlobs::checkGlobsPflsPartCoherency(const std::vector& pflsUsed) const -{ - for(std::vector::const_iterator it=pflsUsed.begin();it!=pflsUsed.end();it++) - getProfile((*it).c_str()); -} - -void MEDFileFieldGlobs::checkGlobsLocsPartCoherency(const std::vector& locsUsed) const -{ - for(std::vector::const_iterator it=locsUsed.begin();it!=locsUsed.end();it++) - getLocalization((*it).c_str()); -} - -void MEDFileFieldGlobs::loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real) -{ - std::vector profiles=real.getPflsReallyUsed(); - int sz=profiles.size(); - _pfls.resize(sz); - for(int i=0;i locs=real.getLocsReallyUsed(); - sz=locs.size(); - _locs.resize(sz); - for(int i=0;i)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileFieldGlobs::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< DataArrayInt > >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) - ret.push_back((const DataArrayInt *)*it); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) - ret.push_back((const MEDFileFieldLoc *)*it); - return ret; -} - -MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldGlobs(*this); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) - { - if((const DataArrayInt *)*it) - ret->_pfls[i]=(*it)->deepCpy(); - } - i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) - { - if((const MEDFileFieldLoc*)*it) - ret->_locs[i]=(*it)->deepCpy(); - } - return ret.retn(); -} - -/*! - * \throw if a profile in \a pfls in not in \a this. - * \throw if a localization in \a locs in not in \a this. - * \sa MEDFileFieldGlobs::deepCpyPart - */ -MEDFileFieldGlobs *MEDFileFieldGlobs::shallowCpyPart(const std::vector& pfls, const std::vector& locs) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldGlobs::New(); - for(std::vector::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) - { - DataArrayInt *pfl=const_cast(getProfile((*it1).c_str())); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! pfl null !"); - pfl->incrRef(); - MEDCouplingAutoRefCountObjectPtr pfl2(pfl); - ret->_pfls.push_back(pfl2); - } - for(std::vector::const_iterator it2=locs.begin();it2!=locs.end();it2++) - { - MEDFileFieldLoc *loc=const_cast(&getLocalization((*it2).c_str())); - if(!loc) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! loc null !"); - loc->incrRef(); - MEDCouplingAutoRefCountObjectPtr loc2(loc); - ret->_locs.push_back(loc2); - } - ret->setFileName(getFileName()); - return ret.retn(); -} - -/*! - * \throw if a profile in \a pfls in not in \a this. - * \throw if a localization in \a locs in not in \a this. - * \sa MEDFileFieldGlobs::shallowCpyPart - */ -MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpyPart(const std::vector& pfls, const std::vector& locs) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldGlobs::New(); - for(std::vector::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) - { - DataArrayInt *pfl=const_cast(getProfile((*it1).c_str())); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! pfl null !"); - ret->_pfls.push_back(pfl->deepCpy()); - } - for(std::vector::const_iterator it2=locs.begin();it2!=locs.end();it2++) - { - MEDFileFieldLoc *loc=const_cast(&getLocalization((*it2).c_str())); - if(!loc) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! loc null !"); - ret->_locs.push_back(loc->deepCpy()); - } - ret->setFileName(getFileName()); - return ret.retn(); -} - -MEDFileFieldGlobs::MEDFileFieldGlobs(const std::string& fname):_file_name(fname) -{ -} - -MEDFileFieldGlobs::MEDFileFieldGlobs() -{ -} - -MEDFileFieldGlobs::~MEDFileFieldGlobs() -{ -} - -void MEDFileFieldGlobs::simpleRepr(std::ostream& oss) const -{ - oss << "Profiles :\n"; - std::size_t n=_pfls.size(); - for(std::size_t i=0;igetName() << "\"\n"; - else - oss << "EMPTY !\n"; - } - n=_locs.size(); - oss << "Localizations :\n"; - for(std::size_t i=0;isimpleRepr(oss); - else - oss<< "EMPTY !\n"; - } -} - -void MEDFileFieldGlobs::setFileName(const std::string& fileName) -{ - _file_name=fileName; -} - -void MEDFileFieldGlobs::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_pfls.begin();it!=_pfls.end();it++) - { - DataArrayInt *elt(*it); - if(elt) - { - std::string name(elt->getName()); - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),name)!=(*it2).first.end()) - { - elt->setName((*it2).second.c_str()); - return; - } - } - } - } -} - -void MEDFileFieldGlobs::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_locs.begin();it!=_locs.end();it++) - { - MEDFileFieldLoc *elt(*it); - if(elt) - { - std::string name(elt->getName()); - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),name)!=(*it2).first.end()) - { - elt->setName((*it2).second.c_str()); - return; - } - } - } - } -} - -int MEDFileFieldGlobs::getNbOfGaussPtPerCell(int locId) const -{ - if(locId<0 || locId>=(int)_locs.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getNbOfGaussPtPerCell : Invalid localization id !"); - return _locs[locId]->getNbOfGaussPtPerCell(); -} - -const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) const -{ - return getLocalizationFromId(getLocalizationId(locName)); -} - -const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) const -{ - if(locId<0 || locId>=(int)_locs.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); - return *_locs[locId]; -} - -/// @cond INTERNAL -namespace ParaMEDMEMImpl -{ - class LocFinder - { - public: - LocFinder(const std::string& loc):_loc(loc) { } - bool operator() (const MEDCouplingAutoRefCountObjectPtr& loc) { return loc->isName(_loc); } - private: - const std::string &_loc; - }; - - class PflFinder - { - public: - PflFinder(const std::string& pfl):_pfl(pfl) { } - bool operator() (const MEDCouplingAutoRefCountObjectPtr& pfl) { return _pfl==pfl->getName(); } - private: - const std::string& _pfl; - }; -} -/// @endcond - -int MEDFileFieldGlobs::getLocalizationId(const std::string& loc) const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_locs.begin(),_locs.end(),ParaMEDMEMImpl::LocFinder(loc)); - if(it==_locs.end()) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::getLocalisationId : no such localisation name : \"" << loc << "\" Possible localizations are : "; - for(it=_locs.begin();it!=_locs.end();it++) - oss << "\"" << (*it)->getName() << "\", "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return std::distance(_locs.begin(),it); -} - -/*! - * The returned value is never null. - */ -const DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) const -{ - std::string pflNameCpp(pflName); - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); - if(it==_pfls.end()) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; - for(it=_pfls.begin();it!=_pfls.end();it++) - oss << "\"" << (*it)->getName() << "\", "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return *it; -} - -const DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) const -{ - if(pflId<0 || pflId>=(int)_pfls.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); - return _pfls[pflId]; -} - -MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) -{ - if(locId<0 || locId>=(int)_locs.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); - return *_locs[locId]; -} - -MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) -{ - return getLocalizationFromId(getLocalizationId(locName)); -} - -/*! - * The returned value is never null. - */ -DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) -{ - std::string pflNameCpp(pflName); - std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); - if(it==_pfls.end()) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; - for(it=_pfls.begin();it!=_pfls.end();it++) - oss << "\"" << (*it)->getName() << "\", "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return *it; -} - -DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) -{ - if(pflId<0 || pflId>=(int)_pfls.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); - return _pfls[pflId]; -} - -void MEDFileFieldGlobs::killProfileIds(const std::vector& pflIds) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newPfls; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) - { - if(std::find(pflIds.begin(),pflIds.end(),i)==pflIds.end()) - newPfls.push_back(*it); - } - _pfls=newPfls; -} - -void MEDFileFieldGlobs::killLocalizationIds(const std::vector& locIds) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newLocs; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) - { - if(std::find(locIds.begin(),locIds.end(),i)==locIds.end()) - newLocs.push_back(*it); - } - _locs=newLocs; -} - -std::vector MEDFileFieldGlobs::getPfls() const -{ - int sz=_pfls.size(); - std::vector ret(sz); - for(int i=0;igetName(); - return ret; -} - -std::vector MEDFileFieldGlobs::getLocs() const -{ - int sz=_locs.size(); - std::vector ret(sz); - for(int i=0;igetName(); - return ret; -} - -bool MEDFileFieldGlobs::existsPfl(const std::string& pflName) const -{ - std::vector v=getPfls(); - std::string s(pflName); - return std::find(v.begin(),v.end(),s)!=v.end(); -} - -bool MEDFileFieldGlobs::existsLoc(const std::string& locName) const -{ - std::vector v=getLocs(); - std::string s(locName); - return std::find(v.begin(),v.end(),s)!=v.end(); -} - -std::vector< std::vector > MEDFileFieldGlobs::whichAreEqualProfiles() const -{ - std::map > m; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) - { - const DataArrayInt *tmp=(*it); - if(tmp) - { - m[tmp->getHashCode()].push_back(i); - } - } - std::vector< std::vector > ret; - for(std::map >::const_iterator it2=m.begin();it2!=m.end();it2++) - { - if((*it2).second.size()>1) - { - std::vector ret0; - bool equalityOrNot=false; - for(std::vector::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++) - { - std::vector::const_iterator it4=it3; it4++; - for(;it4!=(*it2).second.end();it4++) - { - if(_pfls[*it3]->isEqualWithoutConsideringStr(*_pfls[*it4])) - { - if(!equalityOrNot) - ret0.push_back(*it3); - ret0.push_back(*it4); - equalityOrNot=true; - } - } - } - if(!ret0.empty()) - ret.push_back(ret0); - } - } - return ret; -} - -std::vector< std::vector > MEDFileFieldGlobs::whichAreEqualLocs(double eps) const -{ - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::whichAreEqualLocs : no implemented yet ! Sorry !"); -} - -void MEDFileFieldGlobs::appendProfile(DataArrayInt *pfl) -{ - std::string name(pfl->getName()); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::appendProfile : unsupported profiles with no name !"); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) - if(name==(*it)->getName()) - { - if(!pfl->isEqual(*(*it))) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendProfile : profile \"" << name << "\" already exists and is different from existing !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - pfl->incrRef(); - _pfls.push_back(pfl); -} - -void MEDFileFieldGlobs::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) -{ - std::string name(locName); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::appendLoc : unsupported localizations with no name !"); - MEDCouplingAutoRefCountObjectPtr obj=MEDFileFieldLoc::New(locName,geoType,refCoo,gsCoo,w); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) - if((*it)->isName(locName)) - { - if(!(*it)->isEqual(*obj,1e-12)) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendLoc : localization \"" << name << "\" already exists and is different from existing !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - _locs.push_back(obj); -} - -std::string MEDFileFieldGlobs::createNewNameOfPfl() const -{ - std::vector names=getPfls(); - return CreateNewNameNotIn("NewPfl_",names); -} - -std::string MEDFileFieldGlobs::createNewNameOfLoc() const -{ - std::vector names=getLocs(); - return CreateNewNameNotIn("NewLoc_",names); -} - -std::string MEDFileFieldGlobs::CreateNewNameNotIn(const std::string& prefix, const std::vector& namesToAvoid) -{ - for(std::size_t sz=0;sz<100000;sz++) - { - std::ostringstream tryName; - tryName << prefix << sz; - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tryName.str())==namesToAvoid.end()) - return tryName.str(); - } - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::CreateNewNameNotIn : impossible to create an additional profile limit of 100000 profiles reached !"); -} - -/*! - * Creates a MEDFileFieldGlobsReal on a given file name. Nothing is read here. - * \param [in] fname - the file name. - */ -MEDFileFieldGlobsReal::MEDFileFieldGlobsReal(const std::string& fname):_globals(MEDFileFieldGlobs::New(fname)) -{ -} - -/*! - * Creates an empty MEDFileFieldGlobsReal. - */ -MEDFileFieldGlobsReal::MEDFileFieldGlobsReal():_globals(MEDFileFieldGlobs::New()) -{ -} - -std::size_t MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileFieldGlobsReal::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDFileFieldGlobs *)_globals); - return ret; -} - -/*! - * Returns a string describing profiles and Gauss points held in \a this. - * \return std::string - the description string. - */ -void MEDFileFieldGlobsReal::simpleReprGlobs(std::ostream& oss) const -{ - const MEDFileFieldGlobs *glob=_globals; - std::ostringstream oss2; oss2 << glob; - std::string stars(oss2.str().length(),'*'); - oss << "Globals information on fields (at " << oss2.str() << "):" << "\n************************************" << stars << "\n\n"; - if(glob) - glob->simpleRepr(oss); - else - oss << "NO GLOBAL INFORMATION !\n"; -} - -void MEDFileFieldGlobsReal::resetContent() -{ - _globals=MEDFileFieldGlobs::New(); -} - -MEDFileFieldGlobsReal::~MEDFileFieldGlobsReal() -{ -} - -/*! - * Copies references to profiles and Gauss points from another MEDFileFieldGlobsReal. - * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. - */ -void MEDFileFieldGlobsReal::shallowCpyGlobs(const MEDFileFieldGlobsReal& other) -{ - _globals=other._globals; -} - -/*! - * Copies references to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. - * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. - */ -void MEDFileFieldGlobsReal::shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) -{ - const MEDFileFieldGlobs *otherg(other._globals); - if(!otherg) - return ; - _globals=otherg->shallowCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); -} - -/*! - * Copies deeply to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. - * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. - */ -void MEDFileFieldGlobsReal::deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) -{ - const MEDFileFieldGlobs *otherg(other._globals); - if(!otherg) - return ; - _globals=otherg->deepCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); -} - -void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other) -{ - _globals=other._globals; - if((const MEDFileFieldGlobs *)_globals) - _globals=other._globals->deepCpy(); -} - -/*! - * Adds profiles and Gauss points held by another MEDFileFieldGlobsReal to \a this one. - * \param [in] other - the MEDFileFieldGlobsReal to copy data from. - * \param [in] eps - a precision used to compare Gauss points with same name held by - * \a this and \a other MEDFileFieldGlobsReal. - * \throw If \a this and \a other hold profiles with equal names but different ids. - * \throw If \a this and \a other hold different Gauss points with equal names. - */ -void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) -{ - const MEDFileFieldGlobs *thisGlobals(_globals),*otherGlobals(other._globals); - if(thisGlobals==otherGlobals) - return ; - if(!thisGlobals) - { - _globals=other._globals; - return ; - } - _globals->appendGlobs(*other._globals,eps); -} - -void MEDFileFieldGlobsReal::checkGlobsCoherency() const -{ - checkGlobsPflsPartCoherency(); - checkGlobsLocsPartCoherency(); -} - -void MEDFileFieldGlobsReal::checkGlobsPflsPartCoherency() const -{ - contentNotNull()->checkGlobsPflsPartCoherency(getPflsReallyUsed()); -} - -void MEDFileFieldGlobsReal::checkGlobsLocsPartCoherency() const -{ - contentNotNull()->checkGlobsLocsPartCoherency(getLocsReallyUsed()); -} - -void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id, const std::string& pflName) -{ - contentNotNull()->loadProfileInFile(fid,id,pflName); -} - -void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id) -{ - contentNotNull()->loadProfileInFile(fid,id); -} - -void MEDFileFieldGlobsReal::loadGlobals(med_idt fid) -{ - contentNotNull()->loadGlobals(fid,*this); -} - -void MEDFileFieldGlobsReal::loadAllGlobals(med_idt fid) -{ - contentNotNull()->loadAllGlobals(fid); -} - -void MEDFileFieldGlobsReal::writeGlobals(med_idt fid, const MEDFileWritable& opt) const -{ - contentNotNull()->writeGlobals(fid,opt); -} - -/*! - * Returns names of all profiles. To get only used profiles call getPflsReallyUsed() - * or getPflsReallyUsedMulti(). - * \return std::vector - a sequence of names of all profiles. - */ -std::vector MEDFileFieldGlobsReal::getPfls() const -{ - return contentNotNull()->getPfls(); -} - -/*! - * Returns names of all localizations. To get only used localizations call getLocsReallyUsed() - * or getLocsReallyUsedMulti(). - * \return std::vector - a sequence of names of all localizations. - */ -std::vector MEDFileFieldGlobsReal::getLocs() const -{ - return contentNotNull()->getLocs(); -} - -/*! - * Checks if the profile with a given name exists. - * \param [in] pflName - the profile name of interest. - * \return bool - \c true if the profile named \a pflName exists. - */ -bool MEDFileFieldGlobsReal::existsPfl(const std::string& pflName) const -{ - return contentNotNull()->existsPfl(pflName); -} - -/*! - * Checks if the localization with a given name exists. - * \param [in] locName - the localization name of interest. - * \return bool - \c true if the localization named \a locName exists. - */ -bool MEDFileFieldGlobsReal::existsLoc(const std::string& locName) const -{ - return contentNotNull()->existsLoc(locName); -} - -std::string MEDFileFieldGlobsReal::createNewNameOfPfl() const -{ - return contentNotNull()->createNewNameOfPfl(); -} - -std::string MEDFileFieldGlobsReal::createNewNameOfLoc() const -{ - return contentNotNull()->createNewNameOfLoc(); -} - -/*! - * Sets the name of a MED file. - * \param [inout] fileName - the file name. - */ -void MEDFileFieldGlobsReal::setFileName(const std::string& fileName) -{ - contentNotNull()->setFileName(fileName); -} - -/*! - * Finds equal profiles. Two profiles are considered equal if they contain the same ids - * in the same order. - * \return std::vector< std::vector > - a sequence of groups of equal profiles. - * Each item of this sequence is a vector containing ids of equal profiles. - */ -std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualProfiles() const -{ - return contentNotNull()->whichAreEqualProfiles(); -} - -/*! - * Finds equal localizations. - * \param [in] eps - a precision used to compare real values of the localizations. - * \return std::vector< std::vector > - a sequence of groups of equal localizations. - * Each item of this sequence is a vector containing ids of equal localizations. - */ -std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualLocs(double eps) const -{ - return contentNotNull()->whichAreEqualLocs(eps); -} - -/*! - * Renames the profiles. References to profiles (a reference is a profile name) are not changed. - * \param [in] mapOfModif - a sequence describing required renaming. Each element of - * this sequence is a pair whose - * - the first item is a vector of profile names to replace by the second item, - * - the second item is a profile name to replace every profile name of the first item. - */ -void MEDFileFieldGlobsReal::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNull()->changePflsNamesInStruct(mapOfModif); -} - -/*! - * Renames the localizations. References to localizations (a reference is a localization name) are not changed. - * \param [in] mapOfModif - a sequence describing required renaming. Each element of - * this sequence is a pair whose - * - the first item is a vector of localization names to replace by the second item, - * - the second item is a localization name to replace every localization name of the first item. - */ -void MEDFileFieldGlobsReal::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNull()->changeLocsNamesInStruct(mapOfModif); -} - -/*! - * Replaces references to some profiles (a reference is a profile name) by references - * to other profiles and, contrary to changePflsRefsNamesGen(), renames the profiles - * them-selves accordingly.
- * This method is a generalization of changePflName(). - * \param [in] mapOfModif - a sequence describing required replacements. Each element of - * this sequence is a pair whose - * - the first item is a vector of profile names to replace by the second item, - * - the second item is a profile name to replace every profile of the first item. - * \sa changePflsRefsNamesGen() - * \sa changePflName() - */ -void MEDFileFieldGlobsReal::changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif) -{ - changePflsRefsNamesGen(mapOfModif); - changePflsNamesInStruct(mapOfModif); -} - -/*! - * Replaces references to some localizations (a reference is a localization name) by references - * to other localizations and, contrary to changeLocsRefsNamesGen(), renames the localizations - * them-selves accordingly.
- * This method is a generalization of changeLocName(). - * \param [in] mapOfModif - a sequence describing required replacements. Each element of - * this sequence is a pair whose - * - the first item is a vector of localization names to replace by the second item, - * - the second item is a localization name to replace every localization of the first item. - * \sa changeLocsRefsNamesGen() - * \sa changeLocName() - */ -void MEDFileFieldGlobsReal::changeLocsNames(const std::vector< std::pair, std::string > >& mapOfModif) -{ - changeLocsRefsNamesGen(mapOfModif); - changeLocsNamesInStruct(mapOfModif); -} - -/*! - * Renames the profile having a given name and updates references to this profile. - * \param [in] oldName - the name of the profile to rename. - * \param [in] newName - a new name of the profile. - * \sa changePflsNames(). - */ -void MEDFileFieldGlobsReal::changePflName(const std::string& oldName, const std::string& newName) -{ - std::vector< std::pair, std::string > > mapOfModif(1); - std::pair, std::string > p(std::vector(1,std::string(oldName)),std::string(newName)); - mapOfModif[0]=p; - changePflsNames(mapOfModif); -} - -/*! - * Renames the localization having a given name and updates references to this localization. - * \param [in] oldName - the name of the localization to rename. - * \param [in] newName - a new name of the localization. - * \sa changeLocsNames(). - */ -void MEDFileFieldGlobsReal::changeLocName(const std::string& oldName, const std::string& newName) -{ - std::vector< std::pair, std::string > > mapOfModif(1); - std::pair, std::string > p(std::vector(1,std::string(oldName)),std::string(newName)); - mapOfModif[0]=p; - changeLocsNames(mapOfModif); -} - -/*! - * Removes duplicated profiles. Returns a map used to update references to removed - * profiles via changePflsRefsNamesGen(). - * Equal profiles are found using whichAreEqualProfiles(). - * \return std::vector< std::pair, std::string > > - - * a sequence describing the performed replacements of profiles. Each element of - * this sequence is a pair whose - * - the first item is a vector of profile names replaced by the second item, - * - the second item is a profile name replacing every profile of the first item. - */ -std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipPflsNames() -{ - std::vector< std::vector > pseudoRet=whichAreEqualProfiles(); - std::vector< std::pair, std::string > > ret(pseudoRet.size()); - int i=0; - for(std::vector< std::vector >::const_iterator it=pseudoRet.begin();it!=pseudoRet.end();it++,i++) - { - std::vector< std::string > tmp((*it).size()); - int j=0; - for(std::vector::const_iterator it2=(*it).begin();it2!=(*it).end();it2++,j++) - tmp[j]=std::string(getProfileFromId(*it2)->getName()); - std::pair, std::string > p(tmp,tmp.front()); - ret[i]=p; - std::vector tmp2((*it).begin()+1,(*it).end()); - killProfileIds(tmp2); - } - changePflsRefsNamesGen(ret); - return ret; -} - -/*! - * Removes duplicated localizations. Returns a map used to update references to removed - * localizations via changeLocsRefsNamesGen(). - * Equal localizations are found using whichAreEqualLocs(). - * \param [in] eps - a precision used to compare real values of the localizations. - * \return std::vector< std::pair, std::string > > - - * a sequence describing the performed replacements of localizations. Each element of - * this sequence is a pair whose - * - the first item is a vector of localization names replaced by the second item, - * - the second item is a localization name replacing every localization of the first item. - */ -std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipLocsNames(double eps) -{ - std::vector< std::vector > pseudoRet=whichAreEqualLocs(eps); - std::vector< std::pair, std::string > > ret(pseudoRet.size()); - int i=0; - for(std::vector< std::vector >::const_iterator it=pseudoRet.begin();it!=pseudoRet.end();it++,i++) - { - std::vector< std::string > tmp((*it).size()); - int j=0; - for(std::vector::const_iterator it2=(*it).begin();it2!=(*it).end();it2++,j++) - tmp[j]=std::string(getLocalizationFromId(*it2).getName()); - std::pair, std::string > p(tmp,tmp.front()); - ret[i]=p; - std::vector tmp2((*it).begin()+1,(*it).end()); - killLocalizationIds(tmp2); - } - changeLocsRefsNamesGen(ret); - return ret; -} - -/*! - * Returns number of Gauss points per cell in a given localization. - * \param [in] locId - an id of the localization of interest. - * \return int - the number of the Gauss points per cell. - */ -int MEDFileFieldGlobsReal::getNbOfGaussPtPerCell(int locId) const -{ - return contentNotNull()->getNbOfGaussPtPerCell(locId); -} - -/*! - * Returns an id of a localization by its name. - * \param [in] loc - the localization name of interest. - * \return int - the id of the localization. - * \throw If there is no a localization named \a loc. - */ -int MEDFileFieldGlobsReal::getLocalizationId(const std::string& loc) const -{ - return contentNotNull()->getLocalizationId(loc); -} - -/*! - * Returns the name of the MED file. - * \return const std::string& - the MED file name. - */ -std::string MEDFileFieldGlobsReal::getFileName() const -{ - return contentNotNull()->getFileName(); -} - -/*! - * Returns a localization object by its name. - * \param [in] locName - the name of the localization of interest. - * \return const MEDFileFieldLoc& - the localization object having the name \a locName. - * \throw If there is no a localization named \a locName. - */ -const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) const -{ - return contentNotNull()->getLocalization(locName); -} - -/*! - * Returns a localization object by its id. - * \param [in] locId - the id of the localization of interest. - * \return const MEDFileFieldLoc& - the localization object having the id \a locId. - * \throw If there is no a localization with id \a locId. - */ -const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) const -{ - return contentNotNull()->getLocalizationFromId(locId); -} - -/*! - * Returns a profile array by its name. - * \param [in] pflName - the name of the profile of interest. - * \return const DataArrayInt * - the profile array having the name \a pflName. - * \throw If there is no a profile named \a pflName. - */ -const DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) const -{ - return contentNotNull()->getProfile(pflName); -} - -/*! - * Returns a profile array by its id. - * \param [in] pflId - the id of the profile of interest. - * \return const DataArrayInt * - the profile array having the id \a pflId. - * \throw If there is no a profile with id \a pflId. - */ -const DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) const -{ - return contentNotNull()->getProfileFromId(pflId); -} - -/*! - * Returns a localization object, apt for modification, by its id. - * \param [in] locId - the id of the localization of interest. - * \return MEDFileFieldLoc& - a non-const reference to the localization object - * having the id \a locId. - * \throw If there is no a localization with id \a locId. - */ -MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) -{ - return contentNotNull()->getLocalizationFromId(locId); -} - -/*! - * Returns a localization object, apt for modification, by its name. - * \param [in] locName - the name of the localization of interest. - * \return MEDFileFieldLoc& - a non-const reference to the localization object - * having the name \a locName. - * \throw If there is no a localization named \a locName. - */ -MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) -{ - return contentNotNull()->getLocalization(locName); -} - -/*! - * Returns a profile array, apt for modification, by its name. - * \param [in] pflName - the name of the profile of interest. - * \return DataArrayInt * - a non-const pointer to the profile array having the name \a pflName. - * \throw If there is no a profile named \a pflName. - */ -DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) -{ - return contentNotNull()->getProfile(pflName); -} - -/*! - * Returns a profile array, apt for modification, by its id. - * \param [in] pflId - the id of the profile of interest. - * \return DataArrayInt * - a non-const pointer to the profile array having the id \a pflId. - * \throw If there is no a profile with id \a pflId. - */ -DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) -{ - return contentNotNull()->getProfileFromId(pflId); -} - -/*! - * Removes profiles given by their ids. No data is updated to track this removal. - * \param [in] pflIds - a sequence of ids of the profiles to remove. - */ -void MEDFileFieldGlobsReal::killProfileIds(const std::vector& pflIds) -{ - contentNotNull()->killProfileIds(pflIds); -} - -/*! - * Removes localizations given by their ids. No data is updated to track this removal. - * \param [in] locIds - a sequence of ids of the localizations to remove. - */ -void MEDFileFieldGlobsReal::killLocalizationIds(const std::vector& locIds) -{ - contentNotNull()->killLocalizationIds(locIds); -} - -/*! - * Stores a profile array. - * \param [in] pfl - the profile array to store. - * \throw If the name of \a pfl is empty. - * \throw If a profile with the same name as that of \a pfl already exists but contains - * different ids. - */ -void MEDFileFieldGlobsReal::appendProfile(DataArrayInt *pfl) -{ - contentNotNull()->appendProfile(pfl); -} - -/*! - * Adds a new localization of Gauss points. - * \param [in] locName - the name of the new localization. - * \param [in] geoType - a geometrical type of the reference cell. - * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector - * must be \c nbOfNodesPerCell * \c dimOfType. - * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector - * must be _wg_.size() * \c dimOfType. - * \param [in] w - the weights of Gauss points. - * \throw If \a locName is empty. - * \throw If a localization with the name \a locName already exists but is - * different form the new one. - */ -void MEDFileFieldGlobsReal::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) -{ - contentNotNull()->appendLoc(locName,geoType,refCoo,gsCoo,w); -} - -MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() -{ - MEDFileFieldGlobs *g(_globals); - if(!g) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in not const !"); - return g; -} - -const MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() const -{ - const MEDFileFieldGlobs *g(_globals); - if(!g) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in const !"); - return g; -} - -//= MEDFileFieldNameScope - -MEDFileFieldNameScope::MEDFileFieldNameScope() -{ -} - -MEDFileFieldNameScope::MEDFileFieldNameScope(const std::string& fieldName):_name(fieldName) -{ -} - -/*! - * Returns the name of \a this field. - * \return std::string - a string containing the field name. - */ -std::string MEDFileFieldNameScope::getName() const -{ - return _name; -} - -/*! - * Sets name of \a this field - * \param [in] name - the new field name. - */ -void MEDFileFieldNameScope::setName(const std::string& fieldName) -{ - _name=fieldName; -} - -std::string MEDFileFieldNameScope::getDtUnit() const -{ - return _dt_unit; -} - -void MEDFileFieldNameScope::setDtUnit(const std::string& dtUnit) -{ - _dt_unit=dtUnit; -} - -void MEDFileFieldNameScope::copyNameScope(const MEDFileFieldNameScope& other) -{ - _name=other._name; - _dt_unit=other._dt_unit; -} - -//= MEDFileAnyTypeField1TSWithoutSDA - -void MEDFileAnyTypeField1TSWithoutSDA::deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other) -{ - _field_per_mesh.resize(other._field_per_mesh.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=other._field_per_mesh.begin();it!=other._field_per_mesh.end();it++,i++) - { - if((const MEDFileFieldPerMesh *)*it) - _field_per_mesh[i]=(*it)->deepCpy(this); - } -} - -/*! - * Prints a string describing \a this field into a stream. This string is outputted - * by \c print Python command. - * \param [in] bkOffset - number of white spaces printed at the beginning of each line. - * \param [in,out] oss - the out stream. - * \param [in] f1tsId - the field index within a MED file. If \a f1tsId < 0, the tiny - * info id printed, else, not. - */ -void MEDFileAnyTypeField1TSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const -{ - std::string startOfLine(bkOffset,' '); - oss << startOfLine << "Field "; - if(bkOffset==0) - oss << "[Type=" << getTypeStr() << "] with name \"" << getName() << "\" "; - oss << "on one time Step "; - if(f1tsId>=0) - oss << "(" << f1tsId << ") "; - oss << "on iteration=" << _iteration << " order=" << _order << "." << std::endl; - oss << startOfLine << "Time attached is : " << _dt << " [" << _dt_unit << "]." << std::endl; - const DataArray *arr=getUndergroundDataArray(); - if(arr) - { - const std::vector &comps=arr->getInfoOnComponents(); - if(f1tsId<0) - { - oss << startOfLine << "Field has " << comps.size() << " components with the following infos :" << std::endl; - for(std::vector::const_iterator it=comps.begin();it!=comps.end();it++) - oss << startOfLine << " - \"" << (*it) << "\"" << std::endl; - } - if(arr->isAllocated()) - { - oss << startOfLine << "Whole field contains " << arr->getNumberOfTuples() << " tuples." << std::endl; - } - else - oss << startOfLine << "The array of the current field has not allocated yet !" << std::endl; - } - else - { - oss << startOfLine << "Field infos are empty ! Not defined yet !" << std::endl; - } - oss << startOfLine << "----------------------" << std::endl; - if(!_field_per_mesh.empty()) - { - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it2=_field_per_mesh.begin();it2!=_field_per_mesh.end();it2++,i++) - { - const MEDFileFieldPerMesh *cur=(*it2); - if(cur) - cur->simpleRepr(bkOffset,oss,i); - else - oss << startOfLine << "Field per mesh #" << i << " is not defined !" << std::endl; - } - } - else - { - oss << startOfLine << "Field is not defined on any meshes !" << std::endl; - } - oss << startOfLine << "----------------------" << std::endl; -} - -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitComponents() const -{ - const DataArray *arr(getUndergroundDataArray()); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitComponents : no array defined !"); - int nbOfCompo=arr->getNumberOfComponents(); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfCompo); - for(int i=0;i v(1,i); - MEDCouplingAutoRefCountObjectPtr arr2=arr->keepSelectedComponents(v); - ret[i]->setArray(arr2); - } - return ret; -} - -MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order):MEDFileFieldNameScope(fieldName),_iteration(iteration),_order(order),_csit(csit),_nb_of_tuples_to_be_allocated(-2) -{ -} - -MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA():_iteration(-1),_order(-1),_dt(0.),_csit(-1),_nb_of_tuples_to_be_allocated(-1) -{ -} - -/*! - * Returns the maximal dimension of supporting elements. Returns -2 if \a this is - * empty. Returns -1 if this in on nodes. - * \return int - the dimension of \a this. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getDimension() const -{ - int ret=-2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->getDimension(ret); - return ret; -} - -/*! - * Returns the mesh name. - * \return std::string - a string holding the mesh name. - * \throw If \c _field_per_mesh.empty() - */ -std::string MEDFileAnyTypeField1TSWithoutSDA::getMeshName() const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshName : No field set !"); - return _field_per_mesh[0]->getMeshName(); -} - -void MEDFileAnyTypeField1TSWithoutSDA::setMeshName(const std::string& newMeshName) -{ - std::string oldName(getMeshName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeMeshNames(v); -} - -bool MEDFileAnyTypeField1TSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - MEDFileFieldPerMesh *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; -} - -/*! - * Returns the number of iteration of the state of underlying mesh. - * \return int - the iteration number. - * \throw If \c _field_per_mesh.empty() - */ -int MEDFileAnyTypeField1TSWithoutSDA::getMeshIteration() const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshIteration : No field set !"); - return _field_per_mesh[0]->getMeshIteration(); -} - -/*! - * Returns the order number of iteration of the state of underlying mesh. - * \return int - the order number. - * \throw If \c _field_per_mesh.empty() - */ -int MEDFileAnyTypeField1TSWithoutSDA::getMeshOrder() const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshOrder : No field set !"); - return _field_per_mesh[0]->getMeshOrder(); -} - -/*! - * Checks if \a this field is tagged by a given iteration number and a given - * iteration order number. - * \param [in] iteration - the iteration number of interest. - * \param [in] order - the iteration order number of interest. - * \return bool - \c true if \a this->getIteration() == \a iteration && - * \a this->getOrder() == \a order. - */ -bool MEDFileAnyTypeField1TSWithoutSDA::isDealingTS(int iteration, int order) const -{ - return iteration==_iteration && order==_order; -} - -/*! - * Returns number of iteration and order number of iteration when - * \a this field has been calculated. - * \return std::pair - a pair of the iteration number and the iteration - * order number. - */ -std::pair MEDFileAnyTypeField1TSWithoutSDA::getDtIt() const -{ - std::pair p; - fillIteration(p); - return p; -} - -/*! - * Returns number of iteration and order number of iteration when - * \a this field has been calculated. - * \param [in,out] p - a pair returning the iteration number and the iteration - * order number. - */ -void MEDFileAnyTypeField1TSWithoutSDA::fillIteration(std::pair& p) const -{ - p.first=_iteration; - p.second=_order; -} - -/*! - * Returns all types of spatial discretization of \a this field. - * \param [in,out] types - a sequence of types of \a this field. - */ -void MEDFileAnyTypeField1TSWithoutSDA::fillTypesOfFieldAvailable(std::vector& types) const -{ - std::set types2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - (*it)->fillTypesOfFieldAvailable(types2); - } - std::back_insert_iterator< std::vector > bi(types); - std::copy(types2.begin(),types2.end(),bi); -} - -/*! - * Returns all types of spatial discretization of \a this field. - * \return std::vector - a sequence of types of spatial discretization - * of \a this field. - */ -std::vector MEDFileAnyTypeField1TSWithoutSDA::getTypesOfFieldAvailable() const -{ - std::vector ret; - fillTypesOfFieldAvailable(ret); - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsedMulti2() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsedMulti2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDFileAnyTypeField1TSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->changePflsRefsNamesGen(mapOfModif); -} - -void MEDFileAnyTypeField1TSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->changeLocsRefsNamesGen(mapOfModif); -} - -/*! - * Returns all attributes of parts of \a this field lying on a given mesh. - * Each part differs from other ones by a type of supporting mesh entity. The _i_-th - * item of every of returned sequences refers to the _i_-th part of \a this field. - * Thus all sequences returned by this method are of the same length equal to number - * of different types of supporting entities.
- * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" - * for example. Hence, some of the returned sequences contains nested sequences, and an item - * of a nested sequence corresponds to a type of spatial discretization.
- * This method allows for iteration over MEDFile DataStructure without any overhead. - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] types - a sequence of types of underlying mesh entities. A type per - * a field part is returned. - * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. - * This sequence is of the same length as \a types. - * \param [in,out] pfls - a sequence returning a profile name per each type of spatial - * discretization. A profile name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \param [in,out] locs - a sequence returning a localization name per each type of spatial - * discretization. A localization name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \return std::vector< std::vector< std::pair > > - a sequence holding a range - * of ids of tuples within the data array, per each type of spatial - * discretization within one mesh entity type. - * Length of this and of nested sequences is the same as that of \a typesF. - * \throw If no field is lying on \a mname. - */ -std::vector< std::vector< std::pair > > MEDFileAnyTypeField1TSWithoutSDA::getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - int meshId=0; - if(!mname.empty()) - meshId=getMeshIdFromMeshName(mname); - else - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); - return _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); -} - -/*! - * Returns dimensions of mesh elements \a this field lies on. The returned value is a - * maximal absolute dimension and values returned via the out parameter \a levs are - * dimensions relative to the maximal absolute dimension.
- * This method is designed for MEDFileField1TS instances that have a discretization - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". - * Only these 3 discretizations will be taken into account here. If \a this is - * \ref ParaMEDMEM::ON_NODES "ON_NODES", -1 is returned and \a levs are empty.
- * This method is useful to make the link between the dimension of the underlying mesh - * and the levels of \a this, because it is possible that the highest dimension of \a this - * field is not equal to the dimension of the underlying mesh. - * - * Let's consider the following case: - * - mesh \a m1 has a meshDimension 3 and has non empty levels [0,-1,-2] with elements - * TETRA4, HEXA8, TRI3 and SEG2. - * - field \a f1 lies on \a m1 and is defined on 3D and 1D elements TETRA4 and SEG2. - * - field \a f2 lies on \a m1 and is defined on 2D and 1D elements TRI3 and SEG2. - * - * In this case \a f1->getNonEmptyLevels() returns (3,[0,-2]) and \a - * f2->getNonEmptyLevels() returns (2,[0,-1]).
- * The returned values can be used for example to retrieve a MEDCouplingFieldDouble lying - * on elements of a certain relative level by calling getFieldAtLevel(). \a meshDimRelToMax - * parameter of getFieldAtLevel() is computed basing on the returned values as this: - * meshDimRelToMax = absDim - meshDim + relativeLev . - * For example
- * to retrieve the highest level of - * \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+0 ); // absDim - meshDim + relativeLev
- * to retrieve the lowest level of \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+(-2) );
- * to retrieve the highest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+0 );
- * to retrieve the lowest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+(-1) ). - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] levs - a sequence returning the dimensions relative to the maximal - * absolute one. They are in decreasing order. This sequence is cleared before - * filling it in. - * \return int - the maximal absolute dimension of elements \a this fields lies on. - * \throw If no field is lying on \a mname. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getNonEmptyLevels(const std::string& mname, std::vector& levs) const -{ - levs.clear(); - int meshId=getMeshIdFromMeshName(mname); - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls, locs; - _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); - if(types.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getNonEmptyLevels : 'this' is empty !"); - std::set st(types.begin(),types.end()); - if(st.size()==1 && (*st.begin())==INTERP_KERNEL::NORM_ERROR) - return -1; - st.erase(INTERP_KERNEL::NORM_ERROR); - std::set ret1; - for(std::set::const_iterator it=st.begin();it!=st.end();it++) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*it); - ret1.insert((int)cm.getDimension()); - } - int ret=*std::max_element(ret1.begin(),ret1.end()); - std::copy(ret1.rbegin(),ret1.rend(),std::back_insert_iterator >(levs)); - std::transform(levs.begin(),levs.end(),levs.begin(),std::bind2nd(std::plus(),-ret)); - return ret; -} - -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - */ -MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) -{ - int mid=getMeshIdFromMeshName(mName); - return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); -} - -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - */ -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const -{ - int mid=getMeshIdFromMeshName(mName); - return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); -} - -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getMeshIdFromMeshName(const std::string& mName) const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No field set !"); - if(mName.empty()) - return 0; - std::string mName2(mName); - int ret=0; - std::vector msg; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,ret++) - if(mName2==(*it)->getMeshName()) - return ret; - else - msg.push_back((*it)->getMeshName()); - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No such mesh \"" << mName2 << "\" as underlying mesh of field \"" << getName() << "\" !\n"; - oss << "Possible meshes are : "; - for(std::vector::const_iterator it2=msg.begin();it2!=msg.end();it2++) - oss << "\"" << (*it2) << "\" "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary : input mesh is NULL !"); - std::string tmp(mesh->getName()); - if(tmp.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::addNewEntryIfNecessary : empty mesh name ! unsupported by MED file !"); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin(); - int i=0; - for(;it!=_field_per_mesh.end();it++,i++) - { - if((*it)->getMeshName()==tmp) - return i; - } - int sz=_field_per_mesh.size(); - _field_per_mesh.resize(sz+1); - _field_per_mesh[sz]=MEDFileFieldPerMesh::New(this,mesh); - return sz; -} - -bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - MEDFileFieldPerMesh *fpm(*it); - if(fpm) - ret=fpm->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; - } - return ret; -} - -/*! - * This method splits \a this into several sub-parts so that each sub parts have exactly one spatial discretization. This method implements the minimal - * splitting that leads to single spatial discretization of this. - * - * \sa splitMultiDiscrPerGeoTypes - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const -{ - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls,locs; - std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); - std::set allEnt; - for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++) - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - allEnt.insert(*it2); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(allEnt.size()); - std::set::const_iterator it3(allEnt.begin()); - for(std::size_t i=0;i > its; - ret[i]=shallowCpy(); - int newLgth(ret[i]->keepOnlySpatialDiscretization(*it3,its)); - ret[i]->updateData(newLgth,its); - } - return ret; -} - -/*! - * This method performs a sub splitting as splitDiscretizations does but finer. This is the finest spliting level that can be done. - * This method implements the minimal splitting so that each returned elements are mono Gauss discretization per geometric type. - * - * \sa splitDiscretizations - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes() const -{ - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls,locs; - std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); - std::set allEnt; - std::size_t nbOfMDPGT(0),ii(0); - for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++,ii++) - { - nbOfMDPGT=std::max(nbOfMDPGT,locs[ii].size()); - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - allEnt.insert(*it2); - } - if(allEnt.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !"); - if(nbOfMDPGT==0) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); - if(nbOfMDPGT==1) - { - std::vector< MEDCouplingAutoRefCountObjectPtr > ret0(1); - ret0[0]=const_cast(this); this->incrRef(); - return ret0; - } - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfMDPGT); - for(std::size_t i=0;i > its; - ret[i]=shallowCpy(); - int newLgth(ret[i]->keepOnlyGaussDiscretization(i,its)); - ret[i]->updateData(newLgth,its); - } - return ret; -} - -int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its) -{ - int globalCounter(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->keepOnlySpatialDiscretization(tof,globalCounter,its); - return globalCounter; -} - -int MEDFileAnyTypeField1TSWithoutSDA::keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its) -{ - int globalCounter(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->keepOnlyGaussDiscretization(idOfDisc,globalCounter,its); - return globalCounter; -} - -void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair >& oldStartStops) -{ - if(_nb_of_tuples_to_be_allocated>=0) - { - _nb_of_tuples_to_be_allocated=newLgth; - const DataArray *oldArr(getUndergroundDataArray()); - if(oldArr) - { - MEDCouplingAutoRefCountObjectPtr newArr(createNewEmptyDataArrayInstance()); - newArr->setInfoAndChangeNbOfCompo(oldArr->getInfoOnComponents()); - setArray(newArr); - _nb_of_tuples_to_be_allocated=newLgth;//force the _nb_of_tuples_to_be_allocated because setArray has been used specialy - } - return ; - } - if(_nb_of_tuples_to_be_allocated==-1) - return ; - if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) - { - const DataArray *oldArr(getUndergroundDataArray()); - if(!oldArr || !oldArr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 1 !"); - MEDCouplingAutoRefCountObjectPtr newArr(createNewEmptyDataArrayInstance()); - newArr->alloc(newLgth,getNumberOfComponents()); - if(oldArr) - newArr->copyStringInfoFrom(*oldArr); - int pos=0; - for(std::vector< std::pair >::const_iterator it=oldStartStops.begin();it!=oldStartStops.end();it++) - { - if((*it).second<(*it).first) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : the range in the leaves was invalid !"); - newArr->setContigPartOfSelectedValues2(pos,oldArr,(*it).first,(*it).second,1); - pos+=(*it).second-(*it).first; - } - setArray(newArr); - return ; - } - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 2 !"); -} - -void MEDFileAnyTypeField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : empty field !"); - if(_field_per_mesh.size()>1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : In MED3.0 mode in writting mode only ONE underlying mesh supported !"); - _field_per_mesh[0]->copyOptionsFrom(opts); - _field_per_mesh[0]->writeLL(fid,nasc); -} - -/*! - * This methods returns true is the allocation has been needed leading to a modification of state in \a this->_nb_of_tuples_to_be_allocated. - * If false is returned the memory allocation is not required. - */ -bool MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile() -{ - if(_nb_of_tuples_to_be_allocated>=0) - { - getOrCreateAndGetArray()->alloc(_nb_of_tuples_to_be_allocated,getNumberOfComponents()); - _nb_of_tuples_to_be_allocated=-2; - return true; - } - if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) - return false; - if(_nb_of_tuples_to_be_allocated==-1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : trying to read from a file an empty instance ! Need to prepare the structure before !"); - if(_nb_of_tuples_to_be_allocated<-3) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - med_int numdt,numit; - med_float dt; - med_int nmesh; - med_bool localMesh; - med_int meshnumdt,meshnumit; - INTERP_KERNEL::AutoPtr meshName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&_dt)); - MEDFILESAFECALLERRD0(MEDfield23ComputingStepMeshInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&dt,&nmesh,meshName,&localMesh,&meshnumdt,&meshnumit)); - if(_iteration!=numdt || _order!=numit) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively : unexpected exception internal error !"); - _field_per_mesh.resize(nmesh); - // - MEDFileMesh *mm(0); - if(ms) - { - std::string meshNameCpp(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); - mm=ms->getMeshWithName(meshNameCpp); - } - // - for(int i=0;iloadOnlyStructureOfDataRecursively(fid,_nb_of_tuples_to_be_allocated,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - allocIfNecessaryTheArrayToReceiveDataFromFile(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->loadBigArraysRecursively(fid,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - if(allocIfNecessaryTheArrayToReceiveDataFromFile()) - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->loadBigArraysRecursively(fid,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - loadOnlyStructureOfDataRecursively(fid,nasc,ms,entities); - loadBigArraysRecursively(fid,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::unloadArrays() -{ - DataArray *thisArr(getUndergroundDataArray()); - if(thisArr && thisArr->isAllocated()) - { - _nb_of_tuples_to_be_allocated=thisArr->getNumberOfTuples(); - thisArr->desallocate(); - } -} - -std::size_t MEDFileAnyTypeField1TSWithoutSDA::getHeapMemorySizeWithoutChildren() const -{ - return _dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >); -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getDirectChildrenWithNull() const -{ - std::vector ret; - if(getUndergroundDataArray()) - ret.push_back(getUndergroundDataArray()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - ret.push_back((const MEDFileFieldPerMesh *)*it); - return ret; -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * \param [in] field - the field to add to \a this. The array of field \a field is ignored - * \param [in] arr - the array of values. - * \param [in,out] glob - the global data where profiles and localization present in - * \a field, if any, are added. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileAnyTypeField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - const MEDCouplingMesh *mesh=field->getMesh(); - // - TypeOfField type=field->getTypeOfField(); - std::vector dummy; - int start=copyTinyInfoFrom(field,arr); - int pos=addNewEntryIfNecessary(mesh); - if(type!=ON_NODES) - { - std::vector code=MEDFileField1TSWithoutSDA::CheckSBTMesh(mesh); - _field_per_mesh[pos]->assignFieldNoProfileNoRenum(start,code,field,arr,glob,nasc); - } - else - _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,arr,glob); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. Specified entities of a given dimension - * of a given mesh are used as the support of the given field (a real support is not used). - * Elements of the given mesh must be sorted suitable for writing to MED file. - * Order of underlying mesh entities of the given field specified by \a profile parameter - * is not prescribed; this method permutes field values to have them sorted by element - * type as required for writing to MED file. A new profile is added only if no equal - * profile is missing. - * \param [in] field - the field to add to \a this. The field double values are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on. - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \param [in,out] glob - the global data where profiles and localization present in - * \a field, if any, are added. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input field is null !"); - if(!arrOfVals || !arrOfVals->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input array is null or not allocated !"); - TypeOfField type=field->getTypeOfField(); - std::vector idsInPflPerType; - std::vector idsPerType; - std::vector code,code2; - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax); - if(type!=ON_NODES) - { - m->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); - std::vector< MEDCouplingAutoRefCountObjectPtr > idsInPflPerType2(idsInPflPerType.size()); std::copy(idsInPflPerType.begin(),idsInPflPerType.end(),idsInPflPerType2.begin()); - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerType2(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType2.begin()); - std::vector idsPerType3(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType3.begin()); - // start of check - MEDCouplingAutoRefCountObjectPtr field2=field->clone(false); - int nbOfTuplesExp=field2->getNumberOfTuplesExpectedRegardingCode(code,idsPerType3); - if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : The array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // end of check - int start=copyTinyInfoFrom(field,arrOfVals); - code2=m->getDistributionOfTypes(); - // - int pos=addNewEntryIfNecessary(m); - _field_per_mesh[pos]->assignFieldProfile(start,profile,code,code2,idsInPflPerType,idsPerType,field,arrOfVals,m,glob,nasc); - } - else - { - if(!profile || !profile->isAllocated() || profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input profile is null, not allocated or with number of components != 1 !"); - std::vector v(3); v[0]=-1; v[1]=profile->getNumberOfTuples(); v[2]=0; - std::vector idsPerType3(1); idsPerType3[0]=profile; - int nbOfTuplesExp=field->getNumberOfTuplesExpectedRegardingCode(v,idsPerType3); - if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : For node field, the array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int start=copyTinyInfoFrom(field,arrOfVals); - int pos=addNewEntryIfNecessary(m); - _field_per_mesh[pos]->assignNodeFieldProfile(start,profile,field,arrOfVals,glob,nasc); - } -} - -/*! - * \param [in] newNbOfTuples - The new nb of tuples to be allocated. - */ -void MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile(int newNbOfTuples) -{ - if(_nb_of_tuples_to_be_allocated>=0) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile : the object is expected to be appended to a data coming from a file but not loaded ! Load before appending data !"); - DataArray *arr(getOrCreateAndGetArray()); - arr->alloc(newNbOfTuples,arr->getNumberOfComponents()); - _nb_of_tuples_to_be_allocated=-3; -} - -/*! - * Copies tiny info and allocates \a this->_arr instance of DataArrayDouble to - * append data of a given MEDCouplingFieldDouble. So that the size of \a this->_arr becomes - * larger by the size of \a field. Returns an id of the first not filled - * tuple of \a this->_arr. - * \param [in] field - the field to copy the info on components and the name from. - * \return int - the id of first not initialized tuple of \a this->_arr. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - */ -int MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom : input field is NULL !"); - std::string name(field->getName()); - setName(name.c_str()); - setDtUnit(field->getTimeUnit()); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : no array set !"); - if(!arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : array is not allocated !"); - _dt=field->getTime(_iteration,_order); - getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(arr->getInfoOnComponents()); - if(!getOrCreateAndGetArray()->isAllocated()) - { - allocNotFromFile(arr->getNumberOfTuples()); - return 0; - } - else - { - int oldNbOfTuples=getOrCreateAndGetArray()->getNumberOfTuples(); - int newNbOfTuples=oldNbOfTuples+arr->getNumberOfTuples(); - getOrCreateAndGetArray()->reAlloc(newNbOfTuples); - _nb_of_tuples_to_be_allocated=-3; - return oldNbOfTuples; - } -} - -/*! - * Returns number of components in \a this field - * \return int - the number of components. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getNumberOfComponents() const -{ - return getOrCreateAndGetArray()->getNumberOfComponents(); -} - -/*! - * Change info on components in \a this. - * \throw If size of \a infos is not equal to the number of components already in \a this. - */ -void MEDFileAnyTypeField1TSWithoutSDA::setInfo(const std::vector& infos) -{ - DataArray *arr=getOrCreateAndGetArray(); - arr->setInfoOnComponents(infos);//will throw an exception if number of components mimatches -} - -/*! - * Returns info on components of \a this field. - * \return const std::vector& - a sequence of strings each being an - * information on _i_-th component. - */ -const std::vector& MEDFileAnyTypeField1TSWithoutSDA::getInfo() const -{ - const DataArray *arr=getOrCreateAndGetArray(); - return arr->getInfoOnComponents(); -} - -/*! - * Returns a mutable info on components of \a this field. - * \return std::vector& - a sequence of strings each being an - * information on _i_-th component. - */ -std::vector& MEDFileAnyTypeField1TSWithoutSDA::getInfo() -{ - DataArray *arr=getOrCreateAndGetArray(); - return arr->getInfoOnComponents(); -} - -bool MEDFileAnyTypeField1TSWithoutSDA::presenceOfMultiDiscPerGeoType() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - const MEDFileFieldPerMesh *fpm(*it); - if(!fpm) - continue; - if(fpm->presenceOfMultiDiscPerGeoType()) - return true; - } - return false; -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given support. - * \param [in] type - a spatial discretization of the new field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mName - a name of the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on the mesh \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr mm; - if(mName.empty()) - mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); - else - mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); - return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given support. - * \param [in] type - a spatial discretization of the new field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \param [in] mesh - the supporting mesh. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If no field of \a this is lying on \a mesh. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax,false); - const DataArrayInt *d=mesh->getNumberFieldAtLevel(meshDimRelToMax); - const DataArrayInt *e=mesh->getNumberFieldAtLevel(1); - if(meshDimRelToMax==1) - (static_cast((MEDCouplingMesh *)m))->setMeshDimension(0); - return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,renumPol,glob,m,d,e,arrOut,nasc); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on the top level cells of a - * given mesh. - * \param [in] type - a spatial discretization of the new field. - * \param [in] mName - a name of the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities in the mesh. - * \throw If no field values of the given \a type are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr mm; - if(mName.empty()) - mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); - else - mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); - int absDim=getDimension(); - int meshDimRelToMax=absDim-mm->getMeshDimension(); - return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given support. - * \param [in] type - a spatial discretization of the new field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \param [in] mesh - the supporting mesh. - * \param [in] cellRenum - the cell numbers array used for permutation of the result - * field according to \a renumPol. - * \param [in] nodeRenum - the node numbers array used for permutation of the result - * field according to \a renumPol. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - static const char msg1[]="MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : request for a renumbered field following mesh numbering whereas it is a profile field !"; - int meshId=getMeshIdFromMeshName(mesh->getName()); - bool isPfl=false; - MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevel(type,glob,mesh,isPfl,arrOut,nasc); - switch(renumPol) - { - case 0: - { - //no need to test _field_per_mesh.empty() because geMeshName has already done it - return ret.retn(); - } - case 3: - case 1: - { - if(isPfl) - throw INTERP_KERNEL::Exception(msg1); - //no need to test _field_per_mesh.empty() because geMeshName has already done it - if(cellRenum) - { - if((int)cellRenum->getNbOfElems()!=mesh->getNumberOfCells()) - { - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; - oss << "\"" << getName() << "\" has partial renumbering (some geotype has no renumber) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); - if(!disc) throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel : internal error, no discretization on field !"); - std::vector arrOut2(1,arrOut); - // 2 following lines replace ret->renumberCells(cellRenum->getConstPointer()) if not DataArrayDouble - disc->renumberArraysForCell(ret->getMesh(),arrOut2,cellRenum->getConstPointer(),true); - (const_cast(ret->getMesh()))->renumberCells(cellRenum->getConstPointer(),true); - } - if(renumPol==1) - return ret.retn(); - } - case 2: - { - //no need to test _field_per_mesh.empty() because geMeshName has already done it - if(isPfl) - throw INTERP_KERNEL::Exception(msg1); - if(nodeRenum) - { - if((int)nodeRenum->getNbOfElems()!=mesh->getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; - oss << "\"" << nasc.getName() << "\" not defined on all nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr nodeRenumSafe=nodeRenum->checkAndPreparePermutation(); - if(!dynamic_cast((DataArray *)arrOut)) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : node renumbering not implemented for not double DataArrays !"); - ret->renumberNodes(nodeRenumSafe->getConstPointer()); - } - return ret.retn(); - } - default: - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : unsupported renum policy ! Dealing with policy 0 1 2 and 3 !"); - } -} - -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] glob - the global data storing profiles and localization. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type are available. - */ -DataArray *MEDFileAnyTypeField1TSWithoutSDA::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax); - int meshId=getMeshIdFromMeshName(mesh->getName().c_str()); - MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevelWithPfl(type,m,pfl,glob,nasc); - ret->setName(nasc.getName().c_str()); - return ret.retn(); -} - -//= MEDFileField1TSWithoutSDA - -/*! - * Throws if a given value is not a valid (non-extended) relative dimension. - * \param [in] meshDimRelToMax - the relative dimension value. - * \throw If \a meshDimRelToMax > 0. - */ -void MEDFileField1TSWithoutSDA::CheckMeshDimRel(int meshDimRelToMax) -{ - if(meshDimRelToMax>0) - throw INTERP_KERNEL::Exception("CheckMeshDimRel : This is a meshDimRel not a meshDimRelExt ! So value should be <=0 !"); -} - -/*! - * Checks if elements of a given mesh are in the order suitable for writing - * to the MED file. If this is not so, an exception is thrown. In a case of success, returns a - * vector describing types of elements and their number. - * \param [in] mesh - the mesh to check. - * \return std::vector - a vector holding for each element type (1) item of - * INTERP_KERNEL::NormalizedCellType, (2) number of elements, (3) -1. - * These values are in full-interlace mode. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - */ -std::vector MEDFileField1TSWithoutSDA::CheckSBTMesh(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : input mesh is NULL !"); - std::set geoTypes=mesh->getAllGeoTypes(); - int nbOfTypes=geoTypes.size(); - std::vector code(3*nbOfTypes); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayInt::New(); - arr1->alloc(nbOfTypes,1); - int *arrPtr=arr1->getPointer(); - std::set::const_iterator it=geoTypes.begin(); - for(int i=0;i arr2=arr1->checkAndPreparePermutation(); - const int *arrPtr2=arr2->getConstPointer(); - int i=0; - for(it=geoTypes.begin();it!=geoTypes.end();it++,i++) - { - int pos=arrPtr2[i]; - int nbCells=mesh->getNumberOfCellsWithType(*it); - code[3*pos]=(int)(*it); - code[3*pos+1]=nbCells; - code[3*pos+2]=-1;//no profiles - } - std::vector idsPerType;//no profiles - DataArrayInt *da=mesh->checkTypeConsistencyAndContig(code,idsPerType); - if(da) - { - da->decrRef(); - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : underlying mesh is not sorted by type as MED file expects !"); - } - return code; -} - -MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos) -{ - return new MEDFileField1TSWithoutSDA(fieldName,csit,iteration,order,infos); -} - -/*! - * Returns all attributes and values of parts of \a this field lying on a given mesh. - * Each part differs from other ones by a type of supporting mesh entity. The _i_-th - * item of every of returned sequences refers to the _i_-th part of \a this field. - * Thus all sequences returned by this method are of the same length equal to number - * of different types of supporting entities.
- * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" - * for example. Hence, some of the returned sequences contains nested sequences, and an item - * of a nested sequence corresponds to a type of spatial discretization.
- * This method allows for iteration over MEDFile DataStructure with a reduced overhead. - * The overhead is due to selecting values into new instances of DataArrayDouble. - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] types - a sequence of types of underlying mesh entities. A type per - * a field part is returned. - * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. - * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" for example. - * This sequence is of the same length as \a types. - * \param [in,out] pfls - a sequence returning a profile name per each type of spatial - * discretization. A profile name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \param [in,out] locs - a sequence returning a localization name per each type of spatial - * discretization. A localization name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \return std::vector< std::vector > - a sequence holding arrays of values - * per each type of spatial discretization within one mesh entity type. - * The caller is to delete each DataArrayDouble using decrRef() as it is no more needed. - * Length of this and of nested sequences is the same as that of \a typesF. - * \throw If no field is lying on \a mname. - */ -std::vector< std::vector > MEDFileField1TSWithoutSDA::getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - int meshId=0; - if(!mname.empty()) - meshId=getMeshIdFromMeshName(mname); - else - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); - std::vector< std::vector< std::pair > > ret0=_field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); - int nbOfRet=ret0.size(); - std::vector< std::vector > ret(nbOfRet); - for(int i=0;i >& p=ret0[i]; - int nbOfRet1=p.size(); - ret[i].resize(nbOfRet1); - for(int j=0;jselectByTupleId2(p[j].first,p[j].second,1); - ret[i][j]=tmp; - } - } - return ret; -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayDouble * - the pointer to the field values array. - */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDouble() const -{ - const DataArrayDouble *ret=_arr; - if(ret) - return const_cast(ret); - else - return 0; -} - -const char *MEDFileField1TSWithoutSDA::getTypeStr() const -{ - return TYPE_STR; -} - -MEDFileIntField1TSWithoutSDA *MEDFileField1TSWithoutSDA::convertToInt() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TSWithoutSDA); - ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); - ret->deepCpyLeavesFrom(*this); - const DataArrayDouble *arr(_arr); - if(arr) - { - MEDCouplingAutoRefCountObjectPtr arr2(arr->convertToIntArr()); - ret->setArray(arr2); - } - return ret.retn(); -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayDouble * - the pointer to the field values array. - */ -DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArray() const -{ - return getUndergroundDataArrayDouble(); -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayDouble. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayDouble * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDoubleExt(std::vector< std::pair,std::pair > >& entries) const -{ - if(_field_per_mesh.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); - if(_field_per_mesh[0]==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); - _field_per_mesh[0]->getUndergroundDataArrayExt(entries); - return getUndergroundDataArrayDouble(); -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayDouble. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayDouble * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - return getUndergroundDataArrayDoubleExt(entries); -} - -MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) -{ - DataArrayDouble *arr(getOrCreateAndGetArrayDouble()); - arr->setInfoAndChangeNbOfCompo(infos); -} - -MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() -{ -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TSWithoutSDA(*this)); - ret->deepCpyLeavesFrom(*this); - return ret.retn(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=static_cast(shallowCpy()); - if((const DataArrayDouble *)_arr) - ret->_arr=_arr->deepCpy(); - return ret.retn(); -} - -void MEDFileField1TSWithoutSDA::setArray(DataArray *arr) -{ - if(!arr) - { - _nb_of_tuples_to_be_allocated=-1; - _arr=0; - return ; - } - DataArrayDouble *arrC=dynamic_cast(arr); - if(!arrC) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayDouble !"); - else - _nb_of_tuples_to_be_allocated=-3; - arrC->incrRef(); - _arr=arrC; -} - -DataArray *MEDFileField1TSWithoutSDA::createNewEmptyDataArrayInstance() const -{ - return DataArrayDouble::New(); -} - -DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() -{ - DataArrayDouble *ret=_arr; - if(ret) - return ret; - _arr=DataArrayDouble::New(); - return _arr; -} - -DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() -{ - return getOrCreateAndGetArrayDouble(); -} - -const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() const -{ - const DataArrayDouble *ret=_arr; - if(ret) - return ret; - DataArrayDouble *ret2=DataArrayDouble::New(); - const_cast(this)->_arr=DataArrayDouble::New(); - return ret2; -} - -const DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const -{ - return getOrCreateAndGetArrayDouble(); -} - -//= MEDFileIntField1TSWithoutSDA - -MEDFileIntField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos) -{ - return new MEDFileIntField1TSWithoutSDA(fieldName,csit,iteration,order,infos); -} - -MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() -{ -} - -MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, - const std::vector& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) -{ - DataArrayInt *arr(getOrCreateAndGetArrayInt()); - arr->setInfoAndChangeNbOfCompo(infos); -} - -const char *MEDFileIntField1TSWithoutSDA::getTypeStr() const -{ - return TYPE_STR; -} - -MEDFileField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::convertToDouble() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TSWithoutSDA); - ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); - ret->deepCpyLeavesFrom(*this); - const DataArrayInt *arr(_arr); - if(arr) - { - MEDCouplingAutoRefCountObjectPtr arr2(arr->convertToDblArr()); - ret->setArray(arr2); - } - return ret.retn(); -} - -/*! - * Returns a pointer to the underground DataArrayInt instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayInt * - the pointer to the field values array. - */ -DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArray() const -{ - return getUndergroundDataArrayInt(); -} - -/*! - * Returns a pointer to the underground DataArrayInt instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayInt * - the pointer to the field values array. - */ -DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayInt() const -{ - const DataArrayInt *ret=_arr; - if(ret) - return const_cast(ret); - else - return 0; -} - -/*! - * Returns a pointer to the underground DataArrayInt instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayInt. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayInt * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - return getUndergroundDataArrayIntExt(entries); -} - -/*! - * Returns a pointer to the underground DataArrayInt instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayInt. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayInt * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayIntExt(std::vector< std::pair,std::pair > >& entries) const -{ - if(_field_per_mesh.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); - if(_field_per_mesh[0]==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); - _field_per_mesh[0]->getUndergroundDataArrayExt(entries); - return getUndergroundDataArrayInt(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TSWithoutSDA(*this)); - ret->deepCpyLeavesFrom(*this); - return ret.retn(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=static_cast(shallowCpy()); - if((const DataArrayInt *)_arr) - ret->_arr=_arr->deepCpy(); - return ret.retn(); -} - -void MEDFileIntField1TSWithoutSDA::setArray(DataArray *arr) -{ - if(!arr) - { - _nb_of_tuples_to_be_allocated=-1; - _arr=0; - return ; - } - DataArrayInt *arrC=dynamic_cast(arr); - if(!arrC) - throw INTERP_KERNEL::Exception("MEDFileIntField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayInt !"); - else - _nb_of_tuples_to_be_allocated=-3; - arrC->incrRef(); - _arr=arrC; -} - -DataArray *MEDFileIntField1TSWithoutSDA::createNewEmptyDataArrayInstance() const -{ - return DataArrayInt::New(); -} - -DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() -{ - DataArrayInt *ret=_arr; - if(ret) - return ret; - _arr=DataArrayInt::New(); - return _arr; -} - -DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() -{ - return getOrCreateAndGetArrayInt(); -} - -const DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() const -{ - const DataArrayInt *ret=_arr; - if(ret) - return ret; - DataArrayInt *ret2=DataArrayInt::New(); - const_cast(this)->_arr=DataArrayInt::New(); - return ret2; -} - -const DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() const -{ - return getOrCreateAndGetArrayInt(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS() -{ -} - -//= MEDFileAnyTypeField1TS - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - // - std::vector infos; - std::string dtunit,fieldName; - LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=MEDFileField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - case MED_INT32: - { - ret=MEDFileIntField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - // - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); - ret->setTime(numdt,numit,dt); - ret->_csit=1; - if(loadAll) - ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - else - ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - return ret.retn(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - std::vector infos; - std::string dtunit; - int iii=-1; - int nbSteps=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - case MED_INT32: - { - ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - // - if(nbSteps<1) - { - std::ostringstream oss; oss << "MEDFileField1TS(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); - ret->setTime(numdt,numit,dt); - ret->_csit=1; - if(loadAll) - ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - else - ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - return ret.retn(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName) -{ - if(!c) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntField1TS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,fieldName,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,fieldName,iteration,order,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - std::vector infos; - std::string dtunit; - int iii=-1; - int nbOfStep2=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector()); - break; - } - case MED_INT32: - { - ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector()); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName,iteration,order) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - // - bool found=false; - std::vector< std::pair > dtits(nbOfStep2); - for(int i=0;i_csit=i+1; - } - else - dtits[i]=std::pair(numdt,numit); - } - if(!found) - { - std::ostringstream oss; oss << "No such iteration (" << iteration << "," << order << ") in existing field '" << fieldName << "' in file '" << fileName << "' ! Available iterations are : "; - for(std::vector< std::pair >::const_iterator iter=dtits.begin();iter!=dtits.end();iter++) - oss << "(" << (*iter).first << "," << (*iter).second << "), "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(loadAll) - ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - else - ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - return ret.retn(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName.c_str(),fieldName.c_str(),iteration,order,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent) -{ - if(!shallowCopyOfContent) - { - const MEDFileAnyTypeField1TSWithoutSDA *otherPtr(&other); - otherPtr->incrRef(); - _content=const_cast(otherPtr); - } - else - { - _content=other.shallowCpy(); - } -} - -int MEDFileAnyTypeField1TS::LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector& infos, std::string& dtunitOut) -{ - if(checkFieldId) - { - int nbFields=MEDnField(fid); - if(fieldIdCFormat>=nbFields) - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::LocateField2(fileName) : in file \'" << fileName << "\' number of fields is " << nbFields << " ! Trying to request for id " << fieldIdCFormat << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - int ncomp(MEDfieldnComponent(fid,fieldIdCFormat+1)); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,fieldIdCFormat+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep)); - fieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE); - dtunitOut=MEDLoaderBase::buildStringFromFortran(dtunit,MED_LNAME_SIZE); - infos.clear(); infos.resize(ncomp); - for(int j=0;j& infos, std::string& dtunitOut) -{ - int nbFields=MEDnField(fid); - bool found=false; - std::vector fns(nbFields); - int nbOfStep2=-1; - for(int i=0;i::const_iterator it=fns.begin();it!=fns.end();it++) - oss << "\"" << *it << "\" "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return nbOfStep2; -} - -/*! - * This method as MEDFileField1TSW::setLocNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure - * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. - * This method changes the attribute (here it's profile name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). - * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile - * to keep a valid instance. - * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. - * If \b newPflName profile name does not already exist the profile with old name will be renamed with name \b newPflName. - * If \b newPflName already exists and that \b forceRenameOnGlob is false (the default) an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newPflName. - * - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - * \param [in] newLocName is the new localization name. - * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newPflName already exists. If true, the renaming is done without check. It can lead to major bug. - * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newPflName - */ -void MEDFileAnyTypeField1TS::setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob) -{ - MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); - std::string oldPflName=disc->getProfile(); - std::vector vv=getPflsReallyUsedMulti(); - int nbOfOcc=std::count(vv.begin(),vv.end(),oldPflName); - if(forceRenameOnGlob || (!existsPfl(newPflName) && nbOfOcc==1)) - { - disc->setProfile(newPflName); - DataArrayInt *pfl=getProfile(oldPflName.c_str()); - pfl->setName(newPflName); - } - else - { - std::ostringstream oss; oss << "MEDFileField1TS::setProfileNameOnLeaf : Profile \"" << newPflName << "\" already exists or referenced more than one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method as MEDFileField1TSW::setProfileNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure - * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. - * This method changes the attribute (here it's localization name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). - * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile - * to keep a valid instance. - * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. - * This method is an extension of MEDFileField1TSWithoutSDA::setProfileNameOnLeafExt method because it performs a modification of global info. - * If \b newLocName profile name does not already exist the localization with old name will be renamed with name \b newLocName. - * If \b newLocName already exists an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newLocName. - * - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - * \param [in] newLocName is the new localization name. - * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newLocName already exists. If true, the renaming is done without check. It can lead to major bug. - * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newLocName - */ -void MEDFileAnyTypeField1TS::setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob) -{ - MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); - std::string oldLocName=disc->getLocalization(); - std::vector vv=getLocsReallyUsedMulti(); - int nbOfOcc=std::count(vv.begin(),vv.end(),oldLocName); - if(forceRenameOnGlob || (!existsLoc(newLocName) && nbOfOcc==1)) - { - disc->setLocalization(newLocName); - MEDFileFieldLoc& loc=getLocalization(oldLocName.c_str()); - loc.setName(newLocName); - } - else - { - std::ostringstream oss; oss << "MEDFileField1TS::setLocNameOnLeaf : Localization \"" << newLocName << "\" already exists or referenced more than one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() -{ - MEDFileAnyTypeField1TSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : content is expected to be not null !"); - return ret; -} - -const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : const content is expected to be not null !"); - return ret; -} - -/*! - * Writes \a this field into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the field name is not set. - * \throw If no field data is set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileAnyTypeField1TS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid); -} - -/*! - * This method alloc the arrays and load potentially huge arrays contained in this field. - * This method should be called when a MEDFileAnyTypeField1TS::New constructor has been with false as the last parameter. - * This method can be also called to refresh or reinit values from a file. - * - * \throw If the fileName is not set or points to a non readable MED file. - * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary - */ -void MEDFileAnyTypeField1TS::loadArrays() -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::loadArrays : the structure does not come from a file !"); - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); -} - -/*! - * This method behaves as MEDFileAnyTypeField1TS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. - * But once data loaded once, this method does nothing. Contrary to MEDFileAnyTypeField1TS::loadArrays and MEDFileAnyTypeField1TS::unloadArrays - * this method does not throw if \a this does not come from file read. - * - * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::unloadArrays - */ -void MEDFileAnyTypeField1TS::loadArraysIfNecessary() -{ - if(!getFileName().empty()) - { - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); - } -} - -/*! - * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. - * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss instead. - * - * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary, MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss - */ -void MEDFileAnyTypeField1TS::unloadArrays() -{ - contentNotNullBase()->unloadArrays(); -} - -/*! - * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. - * This method is the symetrical method of MEDFileAnyTypeField1TS::loadArraysIfNecessary. - * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. - * - * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary - */ -void MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss() -{ - if(!getFileName().empty()) - contentNotNullBase()->unloadArrays(); -} - -void MEDFileAnyTypeField1TS::writeLL(med_idt fid) const -{ - int nbComp=getNumberOfComponents(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;iwriteLL(fid,*this,*contentNotNullBase()); -} - -std::size_t MEDFileAnyTypeField1TS::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileAnyTypeField1TS::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); - ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)_content); - return ret; -} - -/*! - * Returns a string describing \a this field. This string is outputted - * by \c print Python command. - */ -std::string MEDFileAnyTypeField1TS::simpleRepr() const -{ - std::ostringstream oss; - contentNotNullBase()->simpleRepr(0,oss,-1); - simpleReprGlobs(oss); - return oss.str(); -} - -/*! - * This method returns all profiles whose name is non empty used. - * \b WARNING If profile is used several times it will be reported \b only \b once. - * To get non empty name profiles as time as they appear in \b this call MEDFileField1TS::getPflsReallyUsedMulti instead. - */ -std::vector MEDFileAnyTypeField1TS::getPflsReallyUsed() const -{ - return contentNotNullBase()->getPflsReallyUsed2(); -} - -/*! - * This method returns all localizations whose name is non empty used. - * \b WARNING If localization is used several times it will be reported \b only \b once. - */ -std::vector MEDFileAnyTypeField1TS::getLocsReallyUsed() const -{ - return contentNotNullBase()->getLocsReallyUsed2(); -} - -/*! - * This method returns all profiles whose name is non empty used. - * \b WARNING contrary to MEDFileField1TS::getPflsReallyUsed, if profile is used several times it will be reported as time as it appears. - */ -std::vector MEDFileAnyTypeField1TS::getPflsReallyUsedMulti() const -{ - return contentNotNullBase()->getPflsReallyUsedMulti2(); -} - -/*! - * This method returns all localizations whose name is non empty used. - * \b WARNING contrary to MEDFileField1TS::getLocsReallyUsed if localization is used several times it will be reported as time as it appears. - */ -std::vector MEDFileAnyTypeField1TS::getLocsReallyUsedMulti() const -{ - return contentNotNullBase()->getLocsReallyUsedMulti2(); -} - -void MEDFileAnyTypeField1TS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileAnyTypeField1TS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); -} - -int MEDFileAnyTypeField1TS::getDimension() const -{ - return contentNotNullBase()->getDimension(); -} - -int MEDFileAnyTypeField1TS::getIteration() const -{ - return contentNotNullBase()->getIteration(); -} - -int MEDFileAnyTypeField1TS::getOrder() const -{ - return contentNotNullBase()->getOrder(); -} - -double MEDFileAnyTypeField1TS::getTime(int& iteration, int& order) const -{ - return contentNotNullBase()->getTime(iteration,order); -} - -void MEDFileAnyTypeField1TS::setTime(int iteration, int order, double val) -{ - contentNotNullBase()->setTime(iteration,order,val); -} - -std::string MEDFileAnyTypeField1TS::getName() const -{ - return contentNotNullBase()->getName(); -} - -void MEDFileAnyTypeField1TS::setName(const std::string& name) -{ - contentNotNullBase()->setName(name); -} - -void MEDFileAnyTypeField1TS::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const -{ - contentNotNullBase()->simpleRepr(bkOffset,oss,f1tsId); -} - -std::string MEDFileAnyTypeField1TS::getDtUnit() const -{ - return contentNotNullBase()->getDtUnit(); -} - -void MEDFileAnyTypeField1TS::setDtUnit(const std::string& dtUnit) -{ - contentNotNullBase()->setDtUnit(dtUnit); -} - -std::string MEDFileAnyTypeField1TS::getMeshName() const -{ - return contentNotNullBase()->getMeshName(); -} - -void MEDFileAnyTypeField1TS::setMeshName(const std::string& newMeshName) -{ - contentNotNullBase()->setMeshName(newMeshName); -} - -bool MEDFileAnyTypeField1TS::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - return contentNotNullBase()->changeMeshNames(modifTab); -} - -int MEDFileAnyTypeField1TS::getMeshIteration() const -{ - return contentNotNullBase()->getMeshIteration(); -} - -int MEDFileAnyTypeField1TS::getMeshOrder() const -{ - return contentNotNullBase()->getMeshOrder(); -} - -int MEDFileAnyTypeField1TS::getNumberOfComponents() const -{ - return contentNotNullBase()->getNumberOfComponents(); -} - -bool MEDFileAnyTypeField1TS::isDealingTS(int iteration, int order) const -{ - return contentNotNullBase()->isDealingTS(iteration,order); -} - -std::pair MEDFileAnyTypeField1TS::getDtIt() const -{ - return contentNotNullBase()->getDtIt(); -} - -void MEDFileAnyTypeField1TS::fillIteration(std::pair& p) const -{ - contentNotNullBase()->fillIteration(p); -} - -void MEDFileAnyTypeField1TS::fillTypesOfFieldAvailable(std::vector& types) const -{ - contentNotNullBase()->fillTypesOfFieldAvailable(types); -} - -void MEDFileAnyTypeField1TS::setInfo(const std::vector& infos) -{ - contentNotNullBase()->setInfo(infos); -} - -const std::vector& MEDFileAnyTypeField1TS::getInfo() const -{ - return contentNotNullBase()->getInfo(); -} -std::vector& MEDFileAnyTypeField1TS::getInfo() -{ - return contentNotNullBase()->getInfo(); -} - -bool MEDFileAnyTypeField1TS::presenceOfMultiDiscPerGeoType() const -{ - return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) -{ - return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); -} - -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const -{ - return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); -} - -int MEDFileAnyTypeField1TS::getNonEmptyLevels(const std::string& mname, std::vector& levs) const -{ - return contentNotNullBase()->getNonEmptyLevels(mname,levs); -} - -std::vector MEDFileAnyTypeField1TS::getTypesOfFieldAvailable() const -{ - return contentNotNullBase()->getTypesOfFieldAvailable(); -} - -std::vector< std::vector > > MEDFileAnyTypeField1TS::getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNullBase()->getFieldSplitedByType(mname,types,typesF,pfls,locs); -} - -/*! - * This method returns as MEDFileAnyTypeField1TS new instances as number of components in \a this. - * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. - * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitComponents() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitComponents : no content in this ! Unable to split components !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitComponents(); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeField1TS new instances as number of spatial discretizations in \a this. - * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitDiscretizations : no content in this ! Unable to split discretization !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeField1TS new instances as number of maximal number of discretization in \a this. - * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretization !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - if((const MEDFileAnyTypeField1TSWithoutSDA *)_content) - ret->_content=_content->deepCpy(); - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -int MEDFileAnyTypeField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) -{ - return contentNotNullBase()->copyTinyInfoFrom(field,arr); -} - -//= MEDFileField1TS - -/*! - * Returns a new instance of MEDFileField1TS holding data of the first time step of - * the first field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileField1TS holding data of the first time step of - * a given field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,fieldName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileField1TS holding data of a given time step of - * a given field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - * \throw If the required time step is missing from the file. - */ -MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,fieldName,iteration,order,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileField1TS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * Returns a new instance of MEDFileField1TS holding either a shallow copy - * of a given MEDFileField1TSWithoutSDA ( \a other ) or \a other itself. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS(other,shallowCopyOfContent); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new empty instance of MEDFileField1TS. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileField1TS *MEDFileField1TS::New() -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS; - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileIntField1TS * - a new object that is the result of the conversion of \a this to int32 field. - */ -MEDFileIntField1TS *MEDFileField1TS::convertToInt(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(content) - { - const MEDFileField1TSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileField1TS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToInt()); - ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileIntField1TSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileIntField1TS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -const MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is null !"); - const MEDFileField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() -{ - MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is null !"); - MEDFileField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -void MEDFileField1TS::SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr& arr) -{ - if(!f) - throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : input field is NULL !"); - if(!((DataArray*)arr)) - throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : no array !"); - DataArrayDouble *arrOutC=dynamic_cast((DataArray*)arr); - if(!arrOutC) - throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); - f->setArray(arrOutC); -} - -DataArrayDouble *MEDFileField1TS::ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr& arr) -{ - if(!((DataArray*)arr)) - throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : no array !"); - DataArrayDouble *arrOutC=dynamic_cast((DataArray*)arr); - if(!arrOutC) - throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); - arrOutC->incrRef(); - return arrOutC; -} - -MEDFileField1TS::MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) -try:MEDFileAnyTypeField1TS(other,shallowCopyOfContent) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileField1TS::MEDFileField1TS() -{ - _content=new MEDFileField1TSWithoutSDA; -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * mesh entities of a given dimension of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * the top level cells of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the given \a type. - * \throw If no field values lying on the top level support. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If the mesh is empty. - * \throw If no field values of the given \a type are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * This method is called "Old" because in MED3 norm a field has only one meshName - * attached, so this method is for readers of MED2 files. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] mName - a name of the supporting mesh. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If \a this field has not been constructed via file reading. - * \throw If no field of \a this is lying on the mesh named \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -DataArrayDouble *MEDFileField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); - return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If the data array is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) -{ - setFileName(""); - contentNotNull()->setFieldNoProfileSBT(field,field->getArray(),*this,*contentNotNull()); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense - * can be an aggregation of several MEDCouplingFieldDouble instances. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The mesh support of field is ignored. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - setFileName(""); - contentNotNull()->setFieldProfile(field,field->getArray(),mesh,meshDimRelToMax,profile,*this,*contentNotNull()); -} - -MEDFileAnyTypeField1TS *MEDFileField1TS::shallowCpy() const -{ - return new MEDFileField1TS(*this); -} - -DataArrayDouble *MEDFileField1TS::getUndergroundDataArray() const -{ - return contentNotNull()->getUndergroundDataArrayDouble(); -} - -DataArrayDouble *MEDFileField1TS::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - return contentNotNull()->getUndergroundDataArrayDoubleExt(entries); -} - -std::vector< std::vector > MEDFileField1TS::getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNull()->getFieldSplitedByType2(mname,types,typesF,pfls,locs); -} - -//= MEDFileIntField1TS - -MEDFileIntField1TS *MEDFileIntField1TS::New() -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntField1TS; - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,fieldName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,fieldName,iteration,order,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntField1TS(other,shallowCopyOfContent); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS::MEDFileIntField1TS() -{ - _content=new MEDFileIntField1TSWithoutSDA; -} - -MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileIntField1TS::MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeField1TS(other,shallowCopyOfContent) -{ -} - -MEDFileAnyTypeField1TS *MEDFileIntField1TS::shallowCpy() const -{ - return new MEDFileIntField1TS(*this); -} - -/*! - * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileField1TS * - a new object that is the result of the conversion of \a this to float64 field. - */ -MEDFileField1TS *MEDFileIntField1TS::convertToDouble(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(content) - { - const MEDFileIntField1TSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToDouble()); - ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileField1TSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileField1TS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The field double values are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If the data array is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileIntField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) -{ - setFileName(""); - contentNotNull()->setFieldNoProfileSBT(field,arrOfVals,*this,*contentNotNull()); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense - * can be an aggregation of several MEDCouplingFieldDouble instances. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileIntField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - setFileName(""); - contentNotNull()->setFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this,*contentNotNull()); -} - -const MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is null !"); - const MEDFileIntField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut2; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut2,*contentNotNull()); - DataArrayInt *arrOutC=dynamic_cast((DataArray *)arrOut2); - if(!arrOutC) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevelOld : mismatch between dataArrays type and MEDFileIntField1TS ! Expected int32 !"); - arrOut=arrOutC; - arrOut->incrRef(); // arrOut2 dies at the end of the func - return ret.retn(); -} - -DataArrayInt *MEDFileIntField1TS::ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr& arr) -{ - if(!((DataArray *)arr)) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is NULL !"); - DataArrayInt *arrC=dynamic_cast((DataArray *)arr); - if(!arrC) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is not of type INT32 !"); - arrC->incrRef(); - return arrC; -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * the top level cells of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the given \a type. - * \throw If no field values lying on the top level support. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] mesh - the supporting mesh. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If the mesh is empty. - * \throw If no field values of the given \a type are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * This method is called "Old" because in MED3 norm a field has only one meshName - * attached, so this method is for readers of MED2 files. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] mName - a name of the supporting mesh. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If \a this field has not been constructed via file reading. - * \throw If no field of \a this is lying on the mesh named \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return DataArrayInt * - a new instance of DataArrayInt holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -DataArrayInt *MEDFileIntField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - MEDCouplingAutoRefCountObjectPtr arr=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); - return MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); -} - -MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() -{ - MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is null !"); - MEDFileIntField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -DataArrayInt *MEDFileIntField1TS::getUndergroundDataArray() const -{ - return contentNotNull()->getUndergroundDataArrayInt(); -} - -//= MEDFileAnyTypeFieldMultiTSWithoutSDA - -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA() -{ -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileFieldNameScope(fieldName) -{ -} - -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - med_field_type typcha; - std::string dtunitOut; - int nbOfStep=MEDFileAnyTypeField1TS::LocateField2(fid,"",fieldId,false,_name,typcha,_infos,dtunitOut); - setDtUnit(dtunitOut.c_str()); - loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,typcha,loadAll,ms,entities); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileFieldNameScope(fieldName),_infos(infos) -{ - setDtUnit(dtunit.c_str()); - loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,fieldTyp,loadAll,ms,entities); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -std::size_t MEDFileAnyTypeFieldMultiTSWithoutSDA::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); - for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) - ret+=(*it).capacity(); - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)*it); - return ret; -} - -/*! - * If one of the id in [ \a startIds , \a endIds ) points to a null element, there is not throw. Simply, this empty element is added as if it were not - * NULL. - */ -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds(const int *startIds, const int *endIds) const -{ - MEDCouplingAutoRefCountObjectPtr ret=createNew(); - ret->setInfo(_infos); - int sz=(int)_time_steps.size(); - for(const int *id=startIds;id!=endIds;id++) - { - if(*id>=0 && *id tse2; - if(tse) - { - tse->incrRef(); - tse2=(const_cast(tse)); - } - ret->pushBackTimeStep(tse2); - } - else - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << std::distance(startIds,id) << " value is " << *id; - oss << " ! Should be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(ret->getNumberOfTS()>0) - ret->synchronizeNameScope(); - ret->copyNameScope(*this); - return ret.retn(); -} - -/*! - * If one of the id in the input range points to a null element, there is not throw. Simply, this empty element is added as if it were not - * NULL. - */ -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2(int bg, int end, int step) const -{ - static const char msg[]="MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2"; - int nbOfEntriesToKeep=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); - MEDCouplingAutoRefCountObjectPtr ret=createNew(); - ret->setInfo(_infos); - int sz=(int)_time_steps.size(); - int j=bg; - for(int i=0;i=0 && j tse2; - if(tse) - { - tse->incrRef(); - tse2=(const_cast(tse)); - } - ret->pushBackTimeStep(tse2); - } - else - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << i << " value is " << j; - oss << " ! Should be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(ret->getNumberOfTS()>0) - ret->synchronizeNameScope(); - ret->copyNameScope(*this); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - int id=0; - MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(0,1); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) - { - const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(!cur) - continue; - std::pair p(cur->getIteration(),cur->getOrder()); - if(std::find(timeSteps.begin(),timeSteps.end(),p)!=timeSteps.end()) - ids->pushBackSilent(id); - } - return buildFromTimeStepIds(ids->begin(),ids->end()); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - int id=0; - MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(0,1); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) - { - const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(!cur) - continue; - std::pair p(cur->getIteration(),cur->getOrder()); - if(std::find(timeSteps.begin(),timeSteps.end(),p)==timeSteps.end()) - ids->pushBackSilent(id); - } - return buildFromTimeStepIds(ids->begin(),ids->end()); -} - -bool MEDFileAnyTypeFieldMultiTSWithoutSDA::presenceOfMultiDiscPerGeoType() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(!cur) - continue; - if(cur->presenceOfMultiDiscPerGeoType()) - return true; - } - return false; -} - -const std::vector& MEDFileAnyTypeFieldMultiTSWithoutSDA::getInfo() const -{ - return _infos; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::setInfo(const std::vector& info) -{ - _infos=info; -} - -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepPos(int iteration, int order) const -{ - int ret=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileAnyTypeField1TSWithoutSDA *pt(*it); - if(pt->isDealingTS(iteration,order)) - return ret; - } - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepPos : Muli timestep field on time (" << iteration << "," << order << ") does not exist ! Available (iteration,order) are :\n"; - std::vector< std::pair > vp=getIterations(); - for(std::vector< std::pair >::const_iterator it2=vp.begin();it2!=vp.end();it2++) - oss << "(" << (*it2).first << "," << (*it2).second << ") "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -const MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) const -{ - return *_time_steps[getTimeStepPos(iteration,order)]; -} - -MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) -{ - return *_time_steps[getTimeStepPos(iteration,order)]; -} - -std::string MEDFileAnyTypeFieldMultiTSWithoutSDA::getMeshName() const -{ - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getMeshName : not time steps !"); - return _time_steps[0]->getMeshName(); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::setMeshName(const std::string& newMeshName) -{ - std::string oldName(getMeshName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeMeshNames(v); -} - -bool MEDFileAnyTypeFieldMultiTSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; -} - -/*! - * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArray - */ -DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArray(int iteration, int order) const -{ - return getTimeStepEntry(iteration,order).getUndergroundDataArray(); -} - -/*! - * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt - */ -DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const -{ - return getTimeStepEntry(iteration,order).getUndergroundDataArrayExt(entries); -} - -bool MEDFileAnyTypeFieldMultiTSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *f1ts(*it); - if(f1ts) - ret=f1ts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const -{ - std::string startLine(bkOffset,' '); - oss << startLine << "Field multi time steps [Type=" << getTypeStr() << "]"; - if(fmtsId>=0) - oss << " (" << fmtsId << ")"; - oss << " has the following name: \"" << _name << "\"." << std::endl; - oss << startLine << "Field multi time steps has " << _infos.size() << " components with the following infos :" << std::endl; - for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) - { - oss << startLine << " - \"" << *it << "\"" << std::endl; - } - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - std::string chapter(17,'0'+i); - oss << startLine << chapter << std::endl; - const MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); - if(cur) - cur->simpleRepr(bkOffset+2,oss,i); - else - oss << startLine << " Field on one time step #" << i << " is not defined !" << std::endl; - oss << startLine << chapter << std::endl; - } -} - -std::vector< std::pair > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeSteps(std::vector& ret1) const -{ - std::size_t sz=_time_steps.size(); - std::vector< std::pair > ret(sz); - ret1.resize(sz); - for(std::size_t i=0;igetTime(ret[i].first,ret[i].second); - } - else - { - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeSteps : At rank #" << i << " time step is not defined. Invoke eraseEmptyTS method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr& tse) -{ - MEDFileAnyTypeField1TSWithoutSDA *tse2(tse); - if(!tse2) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input content object is null !"); - checkCoherencyOfType(tse2); - if(_time_steps.empty()) - { - setName(tse2->getName().c_str()); - setInfo(tse2->getInfo()); - } - checkThatComponentsMatch(tse2->getInfo()); - _time_steps.push_back(tse); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope() -{ - std::size_t nbOfCompo=_infos.size(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); - if(cur) - { - if((cur->getInfo()).size()!=nbOfCompo) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope : Mismatch in the number of components of parts ! Should be " << nbOfCompo; - oss << " ! but the field at iteration=" << cur->getIteration() << " order=" << cur->getOrder() << " has " << (cur->getInfo()).size() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - cur->copyNameScope(*this); - } - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - _time_steps.resize(nbPdt); - for(int i=0;i > ts; - med_int numdt=0,numo=0; - med_int meshIt=0,meshOrder=0; - med_float dt=0.0; - MEDFILESAFECALLERRD0(MEDfieldComputingStepMeshInfo,(fid,_name.c_str(),i+1,&numdt,&numo,&dt,&meshIt,&meshOrder)); - switch(fieldTyp) - { - case MED_FLOAT64: - { - _time_steps[i]=MEDFileField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); - break; - } - case MED_INT32: - { - _time_steps[i]=MEDFileIntField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively : managed field type are : FLOAT64, INT32 !"); - } - if(loadAll) - _time_steps[i]->loadStructureAndBigArraysRecursively(fid,*this,ms,entities); - else - _time_steps[i]->loadOnlyStructureOfDataRecursively(fid,*this,ms,entities); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts) const -{ - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::writeLL : no time steps set !"); - checkThatNbOfCompoOfTSMatchThis(); - std::vector infos(getInfo()); - int nbComp=infos.size(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;iwriteLL(fid,opts,*this); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursively(fid,nasc); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursivelyIfNecessary(fid,nasc); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::unloadArrays() -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - elt->unloadArrays(); - } -} - -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNumberOfTS() const -{ - return _time_steps.size(); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseEmptyTS() -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - const MEDFileAnyTypeField1TSWithoutSDA *tmp=(*it); - if(tmp) - newTS.push_back(*it); - } - _time_steps=newTS; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseTimeStepIds(const int *startIds, const int *endIds) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; - int maxId=(int)_time_steps.size(); - int ii=0; - std::set idsToDel; - for(const int *id=startIds;id!=endIds;id++,ii++) - { - if(*id>=0 && *id b(sz,true); - int j=bg; - for(int i=0;i > newTS; - for(std::size_t i=0;i >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); - if(tmp) - { - int it2,ord; - tmp->getTime(it2,ord); - if(it2==iteration && order==ord) - return ret; - else - oss << "(" << it2 << "," << ord << "), "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getPosGivenTime(double time, double eps) const -{ - int ret=0; - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosGivenTime : No such time step " << time << "! \nPossibilities are : "; - oss.precision(15); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); - if(tmp) - { - int it2,ord; - double ti=tmp->getTime(it2,ord); - if(fabs(time-ti) > MEDFileAnyTypeFieldMultiTSWithoutSDA::getIterations() const -{ - int lgth=_time_steps.size(); - std::vector< std::pair > ret(lgth); - for(int i=0;ifillIteration(ret[i]); - return ret; -} - -/*! - * This method has 3 inputs 'iteration' 'order' 'mname'. 'mname' can be null if the user is the general case where there is only one meshName lying on 'this' - * This method returns two things. - * - The absolute dimension of 'this' in first parameter. - * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative - * to the first output parameter. The values in 'levs' will be returned in decreasing order. - * - * This method is designed for MEDFileFieldMultiTS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. - * Only these 3 discretizations will be taken into account here. - * - * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. - * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this - * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. - * - * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. - * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. - * - * Let's consider the typical following case : - * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels - * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 - * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example - * TETRA4 and SEG2 - * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 - * - * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) - * - * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev - * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev - * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev - * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev - */ -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const -{ - return getTimeStepEntry(iteration,order).getNonEmptyLevels(mname,levs); -} - -const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) const -{ - if(pos<0 || pos>=(int)_time_steps.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; - if(item==0) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; - oss << "\nTry to use following method eraseEmptyTS !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return item; -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) -{ - if(pos<0 || pos>=(int)_time_steps.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; - if(item==0) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; - oss << "\nTry to use following method eraseEmptyTS !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return item; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsedMulti2() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsedMulti2() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - (*it)->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - (*it)->changeLocsRefsNamesGen2(mapOfModif); -} - -std::vector< std::vector > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTypesOfFieldAvailable() const -{ - int lgth=_time_steps.size(); - std::vector< std::vector > ret(lgth); - for(int i=0;ifillTypesOfFieldAvailable(ret[i]); - return ret; -} - -/*! - * entry point for users that want to iterate into MEDFile DataStructure without any overhead. - */ -std::vector< std::vector< std::pair > > MEDFileAnyTypeFieldMultiTSWithoutSDA::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return getTimeStepEntry(iteration,order).getFieldSplitedByType(mname,types,typesF,pfls,locs); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - if((const MEDFileAnyTypeField1TSWithoutSDA *)*it) - ret->_time_steps[i]=(*it)->deepCpy(); - } - return ret.retn(); -} - -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents() const -{ - std::size_t sz(_infos.size()),sz2(_time_steps.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(sz); - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ts(sz2); - for(std::size_t i=0;i_infos.resize(1); ret[i]->_infos[0]=_infos[i]; - } - for(std::size_t i=0;i > ret1=_time_steps[i]->splitComponents(); - if(ret1.size()!=sz) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents : At rank #" << i << " number of components is " << ret1.size() << " whereas it should be for all time steps " << sz << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ts[i]=ret1; - } - for(std::size_t i=0;i_time_steps[j]=ts[j][i]; - return ret; -} - -/*! - * This method splits into discretization each time steps in \a this. - * ** WARNING ** the returned instances are not compulsary defined on the same time steps series ! - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations() const -{ - std::size_t sz(_time_steps.size()); - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); - for(std::size_t i=0;isplitDiscretizations(); - } - // - std::vector< MEDCouplingAutoRefCountObjectPtr > ret; - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ret2; - std::vector< TypeOfField > types; - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - { - std::vector ts=(*it1)->getTypesOfFieldAvailable(); - if(ts.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations : it appears that the splitting of MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations has returned invalid result !"); - std::vector< TypeOfField >::iterator it2=std::find(types.begin(),types.end(),ts[0]); - if(it2==types.end()) - types.push_back(ts[0]); - } - ret.resize(types.size()); ret2.resize(types.size()); - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - { - TypeOfField typ=(*it1)->getTypesOfFieldAvailable()[0]; - std::size_t pos=std::distance(types.begin(),std::find(types.begin(),types.end(),typ)); - ret2[pos].push_back(*it1); - } - for(std::size_t i=0;i elt(createNew()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=ret2[i].begin();it1!=ret2[i].end();it1++) - elt->pushBackTimeStep(*it1);//also updates infos in elt - ret[i]=elt; - elt->MEDFileFieldNameScope::operator=(*this); - } - return ret; -} - -/*! - * Contrary to splitDiscretizations method this method makes the hypothesis that the times series are **NOT** impacted by the splitting of multi discretization. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes() const -{ - std::size_t sz(_time_steps.size()); - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); - std::size_t szOut(std::numeric_limits::max()); - for(std::size_t i=0;isplitMultiDiscrPerGeoTypes(); - if(szOut==std::numeric_limits::max()) - szOut=items[i].size(); - else - if(items[i].size()!=szOut) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : The splitting per discretization is expected to be same among time steps !"); - } - if(szOut==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(szOut); - for(std::size_t i=0;i elt(createNew()); - for(std::size_t j=0;jpushBackTimeStep(items[j][i]); - ret[i]=elt; - elt->MEDFileFieldNameScope::operator=(*this); - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) -{ - _name=field->getName(); - if(_name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : no array set !"); - _infos=arr->getInfoOnComponents(); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const -{ - static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : invalid "; - if(_name!=field->getName()) - { - std::ostringstream oss; oss << MSG << "name ! should be \"" << _name; - oss << "\" and it is set in input field to \"" << field->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : no array set !"); - checkThatComponentsMatch(arr->getInfoOnComponents()); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatComponentsMatch(const std::vector& compos) const -{ - static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkThatComponentsMatch : "; - if(getInfo().size()!=compos.size()) - { - std::ostringstream oss; oss << MSG << "mismatch of number of components between this (" << getInfo().size() << ") and "; - oss << " number of components of element to append (" << compos.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(_infos!=compos) - { - std::ostringstream oss; oss << MSG << "components have same size but are different ! should be \""; - std::copy(_infos.begin(),_infos.end(),std::ostream_iterator(oss,", ")); - oss << " But compo in input fields are : "; - std::copy(compos.begin(),compos.end(),std::ostream_iterator(oss,", ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis() const -{ - std::size_t sz=_infos.size(); - int j=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,j++) - { - const MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - if(elt->getInfo().size()!=sz) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis : At pos #" << j << " the number of components is equal to "; - oss << elt->getInfo().size() << " whereas it is expected to be equal to " << sz << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); - if(!_time_steps.empty()) - checkCoherencyOfTinyInfo(field,arr); - MEDFileAnyTypeField1TSWithoutSDA *objC=createNew1TSWithoutSDAEmptyInstance(); - MEDCouplingAutoRefCountObjectPtr obj(objC); - objC->setFieldNoProfileSBT(field,arr,glob,*this); - copyTinyInfoFrom(field,arr); - _time_steps.push_back(obj); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); - if(!_time_steps.empty()) - checkCoherencyOfTinyInfo(field,arr); - MEDFileField1TSWithoutSDA *objC=new MEDFileField1TSWithoutSDA; - MEDCouplingAutoRefCountObjectPtr obj(objC); - objC->setFieldProfile(field,arr,mesh,meshDimRelToMax,profile,glob,*this); - copyTinyInfoFrom(field,arr); - _time_steps.push_back(obj); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration(int i, MEDCouplingAutoRefCountObjectPtr ts) -{ - int sz=(int)_time_steps.size(); - if(i<0 || i>=sz) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element at place #" << i << " should be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileAnyTypeField1TSWithoutSDA *tsPtr(ts); - if(tsPtr) - { - if(tsPtr->getNumberOfComponents()!=(int)_infos.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element with " << tsPtr->getNumberOfComponents() << " components ! Should be " << _infos.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - _time_steps[i]=ts; -} - -//= MEDFileFieldMultiTSWithoutSDA - -MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - return new MEDFileFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); -} - -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA() -{ -} - -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) -{ -} - -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const -{ - return new MEDFileField1TSWithoutSDA; -} - -void MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileField1TSWithoutSDA *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); -} - -const char *MEDFileFieldMultiTSWithoutSDA::getTypeStr() const -{ - return MEDFileField1TSWithoutSDA::TYPE_STR; -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::shallowCpy() const -{ - return new MEDFileFieldMultiTSWithoutSDA(*this); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew() const -{ - return new MEDFileFieldMultiTSWithoutSDA; -} - -/*! - * entry point for users that want to iterate into MEDFile DataStructure with a reduced overhead because output arrays are extracted (created) specially - * for the call of this method. That's why the DataArrayDouble instance in returned vector of vector should be dealed by the caller. - */ -std::vector< std::vector > MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2 : mismatch of type of field expecting FLOAT64 !"); - return myF1TSC->getFieldSplitedByType2(mname,types,typesF,pfls,locs); -} - -MEDFileIntFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::convertToInt() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntFieldMultiTSWithoutSDA); - ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); - if(eltToConv) - { - const MEDFileField1TSWithoutSDA *eltToConvC=dynamic_cast(eltToConv); - if(!eltToConvC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type FLOAT64 !"); - MEDCouplingAutoRefCountObjectPtr elt=eltToConvC->convertToInt(); - ret->setIteration(i,elt); - } - } - return ret.retn(); -} - -//= MEDFileAnyTypeFieldMultiTS - -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS() -{ -} - -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - med_field_type typcha; - std::vector infos; - std::string dtunit; - int i=-1; - MEDFileAnyTypeField1TS::LocateField(fid,fileName,fieldName,i,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=new MEDFileFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); - break; - } - case MED_INT32: - { - ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - // - std::vector infos; - std::string dtunit,fieldName; - MEDFileAnyTypeField1TS::LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=new MEDFileFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); - break; - } - case MED_INT32: - { - ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName) -{ - if(!c) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldMultiTS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntFieldMultiTS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); -} - -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms,entities); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -//= MEDFileIntFieldMultiTSWithoutSDA - -MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - return new MEDFileIntFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); -} - -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA() -{ -} - -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) -{ -} - -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const -{ - return new MEDFileIntField1TSWithoutSDA; -} - -void MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileIntField1TSWithoutSDA *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a INT32 type !"); -} - -const char *MEDFileIntFieldMultiTSWithoutSDA::getTypeStr() const -{ - return MEDFileIntField1TSWithoutSDA::TYPE_STR; -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::shallowCpy() const -{ - return new MEDFileIntFieldMultiTSWithoutSDA(*this); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew() const -{ - return new MEDFileIntFieldMultiTSWithoutSDA; -} - -MEDFileFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::convertToDouble() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileFieldMultiTSWithoutSDA); - ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); - if(eltToConv) - { - const MEDFileIntField1TSWithoutSDA *eltToConvC=dynamic_cast(eltToConv); - if(!eltToConvC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type INT32 !"); - MEDCouplingAutoRefCountObjectPtr elt=eltToConvC->convertToDouble(); - ret->setIteration(i,elt); - } - } - return ret.retn(); -} - -//= MEDFileAnyTypeFieldMultiTS - -/*! - * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of the first field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of a given field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c(BuildContentFrom(fid,fileName,fieldName,loadAll,0,0)); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) -{ - if(!shallowCopyOfContent) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *otherPtr(&other); - otherPtr->incrRef(); - _content=const_cast(otherPtr); - } - else - { - _content=other.shallowCpy(); - } -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() -{ - MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : content is expected to be not null !"); - return ret; -} - -const MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : const content is expected to be not null !"); - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTS::getPflsReallyUsed() const -{ - return contentNotNullBase()->getPflsReallyUsed2(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getLocsReallyUsed() const -{ - return contentNotNullBase()->getLocsReallyUsed2(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getPflsReallyUsedMulti() const -{ - return contentNotNullBase()->getPflsReallyUsedMulti2(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getLocsReallyUsedMulti() const -{ - return contentNotNullBase()->getLocsReallyUsedMulti2(); -} - -void MEDFileAnyTypeFieldMultiTS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileAnyTypeFieldMultiTS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); -} - -int MEDFileAnyTypeFieldMultiTS::getNumberOfTS() const -{ - return contentNotNullBase()->getNumberOfTS(); -} - -void MEDFileAnyTypeFieldMultiTS::eraseEmptyTS() -{ - contentNotNullBase()->eraseEmptyTS(); -} - -void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) -{ - contentNotNullBase()->eraseTimeStepIds(startIds,endIds); -} - -void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds2(int bg, int end, int step) -{ - contentNotNullBase()->eraseTimeStepIds2(bg,end,step); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPart(const int *startIds, const int *endIds) const -{ - MEDCouplingAutoRefCountObjectPtr c=contentNotNullBase()->buildFromTimeStepIds(startIds,endIds); - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - ret->_content=c; - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPartSlice(int bg, int end, int step) const -{ - MEDCouplingAutoRefCountObjectPtr c=contentNotNullBase()->buildFromTimeStepIds2(bg,end,step); - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - ret->_content=c; - return ret.retn(); -} - -std::vector< std::pair > MEDFileAnyTypeFieldMultiTS::getIterations() const -{ - return contentNotNullBase()->getIterations(); -} - -void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(const std::vector& f1ts) -{ - for(std::vector::const_iterator it=f1ts.begin();it!=f1ts.end();it++) - pushBackTimeStep(*it); -} - -void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts) -{ - if(!fmts) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps : Input fmts is NULL !"); - int nbOfTS(fmts->getNumberOfTS()); - for(int i=0;i elt(fmts->getTimeStepAtPos(i)); - pushBackTimeStep(elt); - } -} - -void MEDFileAnyTypeFieldMultiTS::pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input pointer is NULL !"); - checkCoherencyOfType(f1ts); - f1ts->incrRef(); - MEDCouplingAutoRefCountObjectPtr f1tsSafe(f1ts); - MEDFileAnyTypeField1TSWithoutSDA *c=f1ts->contentNotNullBase(); - c->incrRef(); - MEDCouplingAutoRefCountObjectPtr cSafe(c); - if(!((MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content)) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : no content in this !"); - _content->pushBackTimeStep(cSafe); - appendGlobs(*f1ts,1e-12); -} - -void MEDFileAnyTypeFieldMultiTS::synchronizeNameScope() -{ - contentNotNullBase()->synchronizeNameScope(); -} - -int MEDFileAnyTypeFieldMultiTS::getPosOfTimeStep(int iteration, int order) const -{ - return contentNotNullBase()->getPosOfTimeStep(iteration,order); -} - -int MEDFileAnyTypeFieldMultiTS::getPosGivenTime(double time, double eps) const -{ - return contentNotNullBase()->getPosGivenTime(time,eps); -} - -int MEDFileAnyTypeFieldMultiTS::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const -{ - return contentNotNullBase()->getNonEmptyLevels(iteration,order,mname,levs); -} - -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::getTypesOfFieldAvailable() const -{ - return contentNotNullBase()->getTypesOfFieldAvailable(); -} - -std::vector< std::vector< std::pair > > MEDFileAnyTypeFieldMultiTS::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNullBase()->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); -} - -std::string MEDFileAnyTypeFieldMultiTS::getName() const -{ - return contentNotNullBase()->getName(); -} - -void MEDFileAnyTypeFieldMultiTS::setName(const std::string& name) -{ - contentNotNullBase()->setName(name); -} - -std::string MEDFileAnyTypeFieldMultiTS::getDtUnit() const -{ - return contentNotNullBase()->getDtUnit(); -} - -void MEDFileAnyTypeFieldMultiTS::setDtUnit(const std::string& dtUnit) -{ - contentNotNullBase()->setDtUnit(dtUnit); -} - -void MEDFileAnyTypeFieldMultiTS::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const -{ - contentNotNullBase()->simpleRepr(bkOffset,oss,fmtsId); -} - -std::vector< std::pair > MEDFileAnyTypeFieldMultiTS::getTimeSteps(std::vector& ret1) const -{ - return contentNotNullBase()->getTimeSteps(ret1); -} - -std::string MEDFileAnyTypeFieldMultiTS::getMeshName() const -{ - return contentNotNullBase()->getMeshName(); -} - -void MEDFileAnyTypeFieldMultiTS::setMeshName(const std::string& newMeshName) -{ - contentNotNullBase()->setMeshName(newMeshName); -} - -bool MEDFileAnyTypeFieldMultiTS::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - return contentNotNullBase()->changeMeshNames(modifTab); -} - -const std::vector& MEDFileAnyTypeFieldMultiTS::getInfo() const -{ - return contentNotNullBase()->getInfo(); -} - -bool MEDFileAnyTypeFieldMultiTS::presenceOfMultiDiscPerGeoType() const -{ - return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); -} - -void MEDFileAnyTypeFieldMultiTS::setInfo(const std::vector& info) -{ - return contentNotNullBase()->setInfo(info); -} - -int MEDFileAnyTypeFieldMultiTS::getNumberOfComponents() const -{ - const std::vector ret=getInfo(); - return (int)ret.size(); -} - -void MEDFileAnyTypeFieldMultiTS::writeLL(med_idt fid) const -{ - writeGlobals(fid,*this); - contentNotNullBase()->writeLL(fid,*this); -} - -/*! - * Writes \a this field into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the field name is not set. - * \throw If no field data is set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileAnyTypeFieldMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid); -} - -/*! - * This method alloc the arrays and load potentially huge arrays contained in this field. - * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. - * This method can be also called to refresh or reinit values from a file. - * - * \throw If the fileName is not set or points to a non readable MED file. - */ -void MEDFileAnyTypeFieldMultiTS::loadArrays() -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::loadArrays : the structure does not come from a file !"); - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); -} - -/*! - * This method behaves as MEDFileAnyTypeFieldMultiTS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. - * But once data loaded once, this method does nothing. - * - * \throw If the fileName is not set or points to a non readable MED file. - * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::unloadArrays - */ -void MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary() -{ - if(!getFileName().empty()) - { - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); - } -} - -/*! - * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. - * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss instead. - * - * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary, MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss - */ -void MEDFileAnyTypeFieldMultiTS::unloadArrays() -{ - contentNotNullBase()->unloadArrays(); -} - -/*! - * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. - * This method is the symetrical method of MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary. - * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. - * - * \sa MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary - */ -void MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss() -{ - if(!getFileName().empty()) - contentNotNullBase()->unloadArrays(); -} - -std::string MEDFileAnyTypeFieldMultiTS::simpleRepr() const -{ - std::ostringstream oss; - contentNotNullBase()->simpleRepr(0,oss,-1); - simpleReprGlobs(oss); - return oss.str(); -} - -std::size_t MEDFileAnyTypeFieldMultiTS::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); - ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content); - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of components in \a this. - * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. - * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitComponents() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitComponents : no content in this ! Unable to split components !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitComponents(); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of discretizations over time steps in \a this. - * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitDiscretizations : no content in this ! Unable to split discretizations !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of sub-discretizations over time steps in \a this. - * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretizations !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - if((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content) - ret->_content=_content->deepCpy(); - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -MEDCouplingAutoRefCountObjectPtr MEDFileAnyTypeFieldMultiTS::getContent() -{ - return _content; -} - -/*! - * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \return MEDFileField1TS * or MEDFileIntField1TS *- a new instance of MEDFileField1TS or MEDFileIntField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If there is no required time step in \a this field. - */ -MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStep(int iteration, int order) const -{ - int pos=getPosOfTimeStep(iteration,order); - return getTimeStepAtPos(pos); -} - -/*! - * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. - * \param [in] time - the time of the time step of interest. - * \param [in] eps - a precision used to compare time values. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If there is no required time step in \a this field. - */ -MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime(double time, double eps) const -{ - int pos=getPosGivenTime(time,eps); - return getTimeStepAtPos(pos); -} - -/*! - * This method groups not null items in \a vectFMTS per time step series. Two time series are considered equal if the list of their pair of integers iteration,order are equal. - * The float64 value of time attached to the pair of integers are not considered here. - * WARNING the returned pointers are not incremented. The caller is \b not responsible to deallocate them ! This method only reorganizes entries in \a vectFMTS. - * - * \param [in] vectFMTS - vector of not null fields defined on a same global data pointer. - * \throw If there is a null pointer in \a vectFMTS. - */ -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(const std::vector& vectFMTS) -{ - static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries : presence of null instance in input vector !"; - std::vector< std::vector > ret; - std::list lstFMTS(vectFMTS.begin(),vectFMTS.end()); - while(!lstFMTS.empty()) - { - std::list::iterator it(lstFMTS.begin()); - MEDFileAnyTypeFieldMultiTS *curIt(*it); - if(!curIt) - throw INTERP_KERNEL::Exception(msg); - std::vector< std::pair > refIts=curIt->getIterations(); - std::vector elt; - elt.push_back(curIt); it=lstFMTS.erase(it); - while(it!=lstFMTS.end()) - { - curIt=*it; - if(!curIt) - throw INTERP_KERNEL::Exception(msg); - std::vector< std::pair > curIts=curIt->getIterations(); - if(refIts==curIts) - { elt.push_back(curIt); it=lstFMTS.erase(it); } - else - it++; - } - ret.push_back(elt); - } - return ret; -} - -/*! - * This method splits the input list \a vectFMTS considering the aspect of the geometrical support over time. - * All returned instances in a subvector can be safely loaded, rendered along time - * All items must be defined on the same time step ids ( see MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries method ). - * Each item in \a vectFMTS is expected to have one and exactly one spatial discretization along time. - * All items in \a vectFMTS must lie on the mesh (located by meshname and time step) and compatible with the input mesh \a mesh (having the same name than those in items). - * All items in \a vectFMTS whose spatial discretization is not ON_NODES will appear once. - * For items in \a vectFMTS that are ON_NODES it is possible to appear several times (more than once or once) in the returned vector. - * - * \param [in] vectFMTS - list of multi times step part all defined each on a same spatial discretization along time and pointing to a mesh whose name is equal to \c mesh->getName(). - * \param [in] mesh - the mesh shared by all items in \a vectFMTS across time. - * \param [out] fsc - A vector having same size than returned vector. It specifies the support comporator of the corresponding vector of MEDFileAnyTypeFieldMultiTS in returned vector of vector. - * \return - A vector of vector of objects that contains the same pointers (objects) than thoose in \a vectFMTS except that there are organized differently. So pointers included in returned vector of vector should \b not been dealt by the caller. - * - * \throw If an element in \a vectFMTS has not only one spatial discretization set. - * \throw If an element in \a vectFMTS change of spatial discretization along time. - * \throw If an element in \a vectFMTS lies on a mesh with meshname different from those in \a mesh. - * \thorw If some elements in \a vectFMTS do not have the same times steps. - * \throw If mesh is null. - * \throw If an element in \a vectFMTS is null. - * \sa MEDFileAnyTypeFieldMultiTS::AreOnSameSupportAcrossTime - */ -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& fsc) -{ - static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : presence of a null instance in the input vector !"; - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : input mesh is null !"); - std::vector< std::vector > ret; - if(vectFMTS.empty()) - return ret; - std::vector::const_iterator it(vectFMTS.begin()); - MEDFileAnyTypeFieldMultiTS *frstElt(*it); - if(!frstElt) - throw INTERP_KERNEL::Exception(msg); - std::size_t i=0; - std::vector vectFMTSNotNodes; - std::vector vectFMTSNodes; - for(;it!=vectFMTS.end();it++,i++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception(msg); - TypeOfField tof0,tof1; - if(CheckSupportAcrossTime(frstElt,*it,mesh,tof0,tof1)>0) - { - if(tof1!=ON_NODES) - vectFMTSNotNodes.push_back(*it); - else - vectFMTSNodes.push_back(*it); - } - else - vectFMTSNotNodes.push_back(*it); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > cmps; - std::vector< std::vector > retCell=SplitPerCommonSupportNotNodesAlg(vectFMTSNotNodes,mesh,cmps); - ret=retCell; - for(std::vector::const_iterator it2=vectFMTSNodes.begin();it2!=vectFMTSNodes.end();it2++) - { - i=0; - bool isFetched(false); - for(std::vector< std::vector >::const_iterator it0=retCell.begin();it0!=retCell.end();it0++,i++) - { - if((*it0).empty()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : internal error !"); - if(cmps[i]->isCompatibleWithNodesDiscr(*it2)) - { ret[i].push_back(*it2); isFetched=true; } - } - if(!isFetched) - { - std::vector tmp(1,*it2); - MEDCouplingAutoRefCountObjectPtr tmp2(MEDFileMeshStruct::New(mesh)); - ret.push_back(tmp); retCell.push_back(tmp); cmps.push_back(MEDFileFastCellSupportComparator::New(tmp2,*it2)); - } - } - fsc=cmps; - return ret; -} - -/*! - * WARNING no check here. The caller must be sure that all items in vectFMTS are coherent each other in time steps, only one same spatial discretization and not ON_NODES. - * \param [out] cmps - same size than the returned vector. - */ -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupportNotNodesAlg(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& cmps) -{ - std::vector< std::vector > ret; - std::list lstFMTS(vectFMTS.begin(),vectFMTS.end()); - while(!lstFMTS.empty()) - { - std::list::iterator it(lstFMTS.begin()); - MEDFileAnyTypeFieldMultiTS *ref(*it); - std::vector elt; - elt.push_back(ref); it=lstFMTS.erase(it); - MEDCouplingAutoRefCountObjectPtr mst(MEDFileMeshStruct::New(mesh)); - MEDCouplingAutoRefCountObjectPtr cmp(MEDFileFastCellSupportComparator::New(mst,ref)); - while(it!=lstFMTS.end()) - { - MEDFileAnyTypeFieldMultiTS *curIt(*it); - if(cmp->isEqual(curIt)) - { elt.push_back(curIt); it=lstFMTS.erase(it); } - else - it++; - } - ret.push_back(elt); cmps.push_back(cmp); - } - return ret; -} - -/*! - * This method scan the two main structs along time of \a f0 and \a f1 to see if there are all lying on the same mesh along time than those in \a mesh. - * \a f0 and \a f1 must be defined each only on a same spatial discretization even if this can be different each other. - * - * \throw If \a f0 or \a f1 has not only one spatial discretization set. - * \throw If \a f0 or \a f1 change of spatial discretization along time. - * \throw If \a f0 or \a f1 on a mesh with meshname different from those in \a mesh. - * \thorw If \a f0 and \a f1 do not have the same times steps. - * \throw If mesh is null. - * \throw If \a f0 or \a f1 is null. - * \sa MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport - */ -int MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : input mesh is null !"); - if(!f0 || !f1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : presence of null instance in fields over time !"); - if(f0->getMeshName()!=mesh->getName()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh \""<< f0->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f1->getMeshName()!=mesh->getName()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh \""<< f1->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nts=f0->getNumberOfTS(); - if(nts!=f1->getNumberOfTS()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : number of time steps are not the same !"); - if(nts==0) - return nts; - for(int i=0;i f0cur=f0->getTimeStepAtPos(i); - MEDCouplingAutoRefCountObjectPtr f1cur=f1->getTimeStepAtPos(i); - std::vector tofs0(f0cur->getTypesOfFieldAvailable()),tofs1(f1cur->getTypesOfFieldAvailable()); - if(tofs0.size()!=1 || tofs1.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : All time steps must be defined on only one spatial discretization !"); - if(i!=0) - { - if(tof0!=tofs0[0] || tof1!=tofs1[0]) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : Across times steps MEDFileAnyTypeFieldMultiTS instances have to keep the same unique spatial discretization !"); - } - else - { tof0=tofs0[0]; tof1=tofs1[0]; } - if(f0cur->getMeshIteration()!=mesh->getIteration() || f0cur->getMeshOrder()!=mesh->getOrder()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh time step (" << f0cur->getMeshIteration() << ","<< f0cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f1cur->getMeshIteration()!=mesh->getIteration() || f1cur->getMeshOrder()!=mesh->getOrder()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh time step (" << f1cur->getMeshIteration() << ","<< f1cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f0cur->getIteration()!=f1cur->getIteration() || f0cur->getOrder()!=f1cur->getOrder()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : all the time steps must be the same ! it is not the case (" << f0cur->getIteration() << "," << f0cur->getOrder() << ")!=(" << f1cur->getIteration() << "," << f1cur->getOrder() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return nts; -} - -MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator() -{ - return new MEDFileAnyTypeFieldMultiTSIterator(this); -} - -//= MEDFileFieldMultiTS - -/*! - * Returns a new empty instance of MEDFileFieldMultiTS. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New() -{ - return new MEDFileFieldMultiTS; -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS holding data of the first field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(fileName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS holding data of a given field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * Returns a new instance of MEDFileFieldMultiTS holding either a shallow copy - * of a given MEDFileFieldMultiTSWithoutSDA ( \a other ) or \a other itself. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) -{ - return new MEDFileFieldMultiTS(other,shallowCopyOfContent); -} - -MEDFileFieldMultiTS *MEDFileFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0,&entities)); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFieldMultiTS::shallowCpy() const -{ - return new MEDFileFieldMultiTS(*this); -} - -void MEDFileFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileField1TS *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); -} - -/*! - * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileIntFieldMultiTS * - a new object that is the result of the conversion of \a this to int32 field. - */ -MEDFileIntFieldMultiTS *MEDFileFieldMultiTS::convertToInt(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(content) - { - const MEDFileFieldMultiTSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToInt()); - ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileIntFieldMultiTSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileIntFieldMultiTS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Returns a new MEDFileField1TS holding data of a given time step of \a this field. - * \param [in] pos - a time step id. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a pos is not a valid time step id. - */ -MEDFileAnyTypeField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const -{ - const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); - if(!item) - { - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSWithoutSDA *itemC=dynamic_cast(item); - if(itemC) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(*itemC,false); - ret->shallowCpyGlobs(*this); - return ret.retn(); - } - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not FLOAT64 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * mesh entities of a given dimension of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting FLOAT64 !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * the top level cells of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtTopLevel : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a - * given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * This method has a close behaviour than MEDFileFieldMultiTS::getFieldAtLevel. - * This method is called 'old' because the user should give the mesh name he wants to use for it's field. - * This method is useful for MED2 file format when field on different mesh was autorized. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevelOld : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type, of a given time step, - * lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] glob - the global data storing profiles and localization. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -DataArrayDouble *MEDFileFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldWithProfile : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); - return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); -} - -const MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is null !"); - const MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() -{ - MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is null !"); - MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of - * the given field is checked if its elements are sorted suitable for writing to MED file - * ("STB" stands for "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If existing time steps have different name or number of components than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) -{ - const DataArrayDouble *arr=0; - if(field) - arr=field->getArray(); - contentNotNull()->appendFieldNoProfileSBT(field,arr,*this); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The mesh support of field is ignored. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - const DataArrayDouble *arr=0; - if(field) - arr=field->getArray(); - contentNotNull()->appendFieldProfile(field,arr,mesh,meshDimRelToMax,profile,*this); -} - -MEDFileFieldMultiTS::MEDFileFieldMultiTS() -{ - _content=new MEDFileFieldMultiTSWithoutSDA; -} - -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) -{ -} - -std::vector< std::vector > MEDFileFieldMultiTS::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNull()->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); -} - -DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArray(int iteration, int order) const -{ - return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); -} - -DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const -{ - return static_cast(contentNotNull()->getUndergroundDataArrayExt(iteration,order,entries)); -} - -//= MEDFileAnyTypeFieldMultiTSIterator - -MEDFileAnyTypeFieldMultiTSIterator::MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts):_fmts(fmts),_iter_id(0),_nb_iter(0) -{ - if(fmts) - { - fmts->incrRef(); - _nb_iter=fmts->getNumberOfTS(); - } -} - -MEDFileAnyTypeFieldMultiTSIterator::~MEDFileAnyTypeFieldMultiTSIterator() -{ -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTSIterator::nextt() -{ - if(_iter_id<_nb_iter) - { - MEDFileAnyTypeFieldMultiTS *fmts(_fmts); - if(fmts) - return fmts->getTimeStepAtPos(_iter_id++); - else - return 0; - } - else - return 0; -} - -//= MEDFileIntFieldMultiTS - -/*! - * Returns a new empty instance of MEDFileFieldMultiTS. - * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New() -{ - return new MEDFileIntFieldMultiTS; -} - -/*! - * Returns a new instance of MEDFileIntFieldMultiTS holding data of the first field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileIntFieldMultiTS holding data of a given field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileIntFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * Returns a new instance of MEDFileIntFieldMultiTS holding either a shallow copy - * of a given MEDFileIntFieldMultiTSWithoutSDA ( \a other ) or \a other itself. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileIntField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) -{ - return new MEDFileIntFieldMultiTS(other,shallowCopyOfContent); -} - -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0,&entities); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileFieldMultiTS * - a new object that is the result of the conversion of \a this to float64 field. - */ -MEDFileFieldMultiTS *MEDFileIntFieldMultiTS::convertToDouble(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(content) - { - const MEDFileIntFieldMultiTSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToDouble()); - ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileFieldMultiTSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileFieldMultiTS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileIntFieldMultiTS::shallowCpy() const -{ - return new MEDFileIntFieldMultiTS(*this); -} - -void MEDFileIntFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileIntField1TS *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : the input field1TS is not a INT32 type !"); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * mesh entities of a given dimension of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting INT32 !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * the top level cells of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtTopLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a - * given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] mesh - the supporting mesh. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldIntMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * This method has a close behaviour than MEDFileIntFieldMultiTS::getFieldAtLevel. - * This method is called 'old' because the user should give the mesh name he wants to use for it's field. - * This method is useful for MED2 file format when field on different mesh was autorized. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type, of a given time step, - * lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] glob - the global data storing profiles and localization. - * \return DataArrayInt * - a new instance of DataArrayInt holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -DataArrayInt *MEDFileIntFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldWithProfile : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); - return MEDFileIntField1TS::ReturnSafelyDataArrayInt(ret); -} - -/*! - * Returns a new MEDFileIntField1TS holding data of a given time step of \a this field. - * \param [in] pos - a time step id. - * \return MEDFileIntField1TS * - a new instance of MEDFileIntField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a pos is not a valid time step id. - */ -MEDFileAnyTypeField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const -{ - const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); - if(!item) - { - std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileIntField1TSWithoutSDA *itemC=dynamic_cast(item); - if(itemC) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntField1TS::New(*itemC,false); - ret->shallowCpyGlobs(*this); - return ret.retn(); - } - std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not INT32 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of - * the given field is checked if its elements are sorted suitable for writing to MED file - * ("STB" stands for "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If existing time steps have different name or number of components than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileIntFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) -{ - contentNotNull()->appendFieldNoProfileSBT(field,arrOfVals,*this); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileIntFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - contentNotNull()->appendFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this); -} - -const MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is null !"); - const MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() -{ - MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is null !"); - MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS() -{ - _content=new MEDFileIntFieldMultiTSWithoutSDA; -} - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) -{ -} - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -DataArrayInt *MEDFileIntFieldMultiTS::getUndergroundDataArray(int iteration, int order) const -{ - return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); -} - -//= MEDFileFields - -MEDFileFields *MEDFileFields::New() -{ - return new MEDFileFields; -} - -MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll) -{ - return new MEDFileFields(fileName,loadAll,0,0); -} - -MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -{ - return new MEDFileFields(fileName,loadAll,ms,0); -} - -MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair >& entities, bool loadAll) -{ - return new MEDFileFields(fileName,loadAll,0,&entities); -} - -std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren()); - ret+=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; -} - -std::vector MEDFileFields::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it); - return ret; -} - -MEDFileFields *MEDFileFields::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) - ret->_fields[i]=(*it)->deepCpy(); - } - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -MEDFileFields *MEDFileFields::shallowCpy() const -{ - return new MEDFileFields(*this); -} - -/*! - * This method scans for all fields in \a this which time steps ids are common. Time step are discriminated by the pair of integer (iteration,order) whatever - * the double time value. If all returned time steps are \b exactly those for all fields in \a this output parameter \a areThereSomeForgottenTS will be set to false. - * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned. - * - * \param [out] areThereSomeForgottenTS - indicates to the caller if there is some time steps in \a this that are not present for all fields in \a this. - * \return the sorted list of time steps (specified with a pair of integer iteration first and order second) present for all fields in \a this. - * - * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps - */ -std::vector< std::pair > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const -{ - std::set< std::pair > s; - bool firstShot=true; - areThereSomeForgottenTS=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) - continue; - std::vector< std::pair > v=(*it)->getIterations(); - std::set< std::pair > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end())); - if(firstShot) - { s=s1; firstShot=false; } - else - { - std::set< std::pair > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end())); - if(s!=s2) - areThereSomeForgottenTS=true; - s=s2; - } - } - std::vector< std::pair > ret; - std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair > >(ret)); - return ret; -} - -int MEDFileFields::getNumberOfFields() const -{ - return _fields.size(); -} - -std::vector MEDFileFields::getFieldsNames() const -{ - std::vector ret(_fields.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it); - if(f) - { - ret[i]=f->getName(); - } - else - { - std::ostringstream oss; oss << "MEDFileFields::getFieldsNames : At rank #" << i << " field is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -std::vector MEDFileFields::getMeshesNames() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); - if(cur) - ret.push_back(cur->getMeshName()); - } - return ret; -} - -std::string MEDFileFields::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*****************)\n(* MEDFileFields *)\n(*****************)\n\n"; - simpleRepr(0,oss); - return oss.str(); -} - -void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const -{ - int nbOfFields=getNumberOfFields(); - std::string startLine(bkOffset,' '); - oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(cur) - { - oss << startLine << " - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl; - } - else - { - oss << startLine << " - not defined !" << std::endl; - } - } - i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - std::string chapter(17,'0'+i); - oss << startLine << chapter << std::endl; - if(cur) - { - cur->simpleRepr(bkOffset+2,oss,i); - } - else - { - oss << startLine << " - not defined !" << std::endl; - } - oss << startLine << chapter << std::endl; - } - simpleReprGlobs(oss); -} - -MEDFileFields::MEDFileFields() -{ -} - -MEDFileFields::MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - int nbFields(MEDnField(fid)); - _fields.resize(nbFields); - med_field_type typcha; - for(int i=0;i infos; - std::string fieldName,dtunit; - int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,fileName,i,false,fieldName,typcha,infos,dtunit)); - switch(typcha) - { - case MED_FLOAT64: - { - _fields[i]=MEDFileFieldMultiTSWithoutSDA::New(fid,fieldName.c_str(),typcha,infos,nbOfStep,dtunit,loadAll,ms,entities); - break; - } - case MED_INT32: - { - _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName.c_str(),typcha,infos,nbOfStep,dtunit,loadAll,ms,entities); - break; - } - default: - { - std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << fileName << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - loadAllGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileFields::writeLL(med_idt fid) const -{ - int i=0; - writeGlobals(fid,*this); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it; - if(!elt) - { - std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - elt->writeLL(fid,*this); - } -} - -void MEDFileFields::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),medmod)); - writeLL(fid); -} - -/*! - * This method alloc the arrays and load potentially huge arrays contained in this field. - * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. - * This method can be also called to refresh or reinit values from a file. - * - * \throw If the fileName is not set or points to a non readable MED file. - */ -void MEDFileFields::loadArrays() -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !"); - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursively(fid,*elt); - } -} - -/*! - * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays. - * But once data loaded once, this method does nothing. - * - * \throw If the fileName is not set or points to a non readable MED file. - * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays - */ -void MEDFileFields::loadArraysIfNecessary() -{ - if(!getFileName().empty()) - { - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursivelyIfNecessary(fid,*elt); - } - } -} - -/*! - * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. - * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead. - * - * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss - */ -void MEDFileFields::unloadArrays() -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - elt->unloadArrays(); - } -} - -/*! - * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. - * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary. - * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. - * - * \sa MEDFileFields::loadArraysIfNecessary - */ -void MEDFileFields::unloadArraysWithoutDataLoss() -{ - if(!getFileName().empty()) - unloadArrays(); -} - -std::vector MEDFileFields::getPflsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFields::getLocsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFields::getPflsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileFields::getLocsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) - (*it)->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) - (*it)->changeLocsRefsNamesGen2(mapOfModif); -} - -void MEDFileFields::resize(int newSize) -{ - _fields.resize(newSize); -} - -void MEDFileFields::pushFields(const std::vector& fields) -{ - for(std::vector::const_iterator it=fields.begin();it!=fields.end();it++) - pushField(*it); -} - -void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !"); - _fields.push_back(field->getContent()); - appendGlobs(*field,1e-12); -} - -void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !"); - if(i>=(int)_fields.size()) - _fields.resize(i+1); - _fields[i]=field->getContent(); - appendGlobs(*field,1e-12); -} - -void MEDFileFields::destroyFieldAtPos(int i) -{ - destroyFieldsAtPos(&i,&i+1); -} - -void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds) -{ - std::vector b(_fields.size(),true); - for(const int *i=startIds;i!=endIds;i++) - { - if(*i<0 || *i>=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - b[*i]=false; - } - std::vector< MEDCouplingAutoRefCountObjectPtr > fields(std::count(b.begin(),b.end(),true)); - std::size_t j=0; - for(std::size_t i=0;i<_fields.size();i++) - if(b[i]) - fields[j++]=_fields[i]; - _fields=fields; -} - -void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step) -{ - static const char msg[]="MEDFileFields::destroyFieldsAtPos2"; - int nbOfEntriesToKill=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); - std::vector b(_fields.size(),true); - int k=bg; - for(int i=0;i=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - b[k]=false; - } - std::vector< MEDCouplingAutoRefCountObjectPtr > fields(std::count(b.begin(),b.end(),true)); - std::size_t j=0; - for(std::size_t i=0;i<_fields.size();i++) - if(b[i]) - fields[j++]=_fields[i]; - _fields=fields; -} - -bool MEDFileFields::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; -} - -/*! - * \param [in] meshName the name of the mesh that will be renumbered. - * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset). - * This code corresponds to the distribution of types in the corresponding mesh. - * \param [in] newCode idem to param \a oldCode except that here the new distribution is given. - * \param [in] renumO2N the old to new renumber array. - * \return If true a renumbering has been performed. The structure in \a this has been modified. If false, nothing has been done: it is typically the case if \a meshName is not refered by any - * field in \a this. - */ -bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it); - if(fmts) - { - ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret; - } - } - return ret; -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const -{ - if(i<0 || i>=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i]; - if(!fmts) - return 0; - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileFieldMultiTSWithoutSDA *fmtsC=dynamic_cast(fmts); - const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2=dynamic_cast(fmts); - if(fmtsC) - ret=MEDFileFieldMultiTS::New(*fmtsC,false); - else if(fmtsC2) - ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false); - else - { - std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor integer (INT32) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ). - * This method is accessible in python using __getitem__ with a list in input. - * \return a new object that the caller should deal with. - */ -MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - std::size_t sz=std::distance(startIds,endIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > fields(sz); - int j=0; - for(const int *i=startIds;i!=endIds;i++,j++) - { - if(*i<0 || *i>=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - fields[j]=_fields[*i]; - } - ret->_fields=fields; - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const -{ - return getFieldAtPos(getPosFromFieldName(fieldName)); -} - -/*! - * This method removes, if any, fields in \a this having no time steps. - * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this. - * - * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const. - */ -bool MEDFileFields::removeFieldsWithoutAnyTimeStep() -{ - std::vector > newFields; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - { - if(elt->getNumberOfTS()>0) - newFields.push_back(*it); - } - } - if(_fields.size()==newFields.size()) - return false; - _fields=newFields; - return true; -} - -/*! - * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName. - * This method can be seen as a filter applied on \a this, that returns an object containing - * reduced the list of fields compared to those in \a this. The returned object is a new object but the object on which it lies are only - * shallow copied from \a this. - * - * \param [in] meshName - the name of the mesh on w - * \return a new object that the caller should deal with. - */ -MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(!cur) - continue; - if(cur->getMeshName()==meshName) - { - cur->incrRef(); - MEDCouplingAutoRefCountObjectPtr cur2(const_cast(cur)); - ret->_fields.push_back(cur2); - } - } - ret->shallowCpyOnlyUsedGlobs(*this); - return ret.retn(); -} - -/*! - * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps. - * Input time steps are specified using a pair of integer (iteration, order). - * This method can be seen as a filter applied on \a this, that returns an object containing the same number of fields than those in \a this, - * but for each multitimestep only the time steps in \a timeSteps are kept. - * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations. - * - * The returned object points to shallow copy of elements in \a this. - * - * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order) - * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps. - * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps - */ -MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(!cur) - continue; - MEDCouplingAutoRefCountObjectPtr elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps); - ret->_fields.push_back(elt); - } - ret->shallowCpyOnlyUsedGlobs(*this); - return ret.retn(); -} - -/*! - * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps - */ -MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(!cur) - continue; - MEDCouplingAutoRefCountObjectPtr elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps); - if(elt->getNumberOfTS()!=0) - ret->_fields.push_back(elt); - } - ret->shallowCpyOnlyUsedGlobs(*this); - return ret.retn(); -} - -MEDFileFieldsIterator *MEDFileFields::iterator() -{ - return new MEDFileFieldsIterator(this); -} - -int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const -{ - std::string tmp(fieldName); - std::vector poss; - for(std::size_t i=0;i<_fields.size();i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=_fields[i]; - if(f) - { - std::string fname(f->getName()); - if(tmp==fname) - return i; - else - poss.push_back(fname); - } - } - std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : "; - std::copy(poss.begin(),poss.end(),std::ostream_iterator(oss,", ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0) -{ - if(fs) - { - fs->incrRef(); - _nb_iter=fs->getNumberOfFields(); - } -} - -MEDFileFieldsIterator::~MEDFileFieldsIterator() -{ -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt() -{ - if(_iter_id<_nb_iter) - { - MEDFileFields *fs(_fs); - if(fs) - return fs->getFieldAtPos(_iter_id++); - else - return 0; - } - else - return 0; -} diff --git a/medtool/src/MEDLoader/MEDFileField.hxx b/medtool/src/MEDLoader/MEDFileField.hxx deleted file mode 100644 index bf0e31351..000000000 --- a/medtool/src/MEDLoader/MEDFileField.hxx +++ /dev/null @@ -1,1171 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEFIELD_HXX__ -#define __MEDFILEFIELD_HXX__ - -#include "MEDLoaderDefines.hxx" - -#include "MEDFileFieldOverView.hxx" -#include "MEDFileUtilities.hxx" - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingMemArray.hxx" - -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -#include -#include -#include -#include - -#include "med.h" - -namespace ParaMEDMEM -{ - class MEDFileFieldGlobs; - class MEDCouplingMesh; - class MEDCouplingFieldDouble; - class MEDFileMesh; - - class MEDFileFieldLoc : public RefCountObject - { - public: - MEDLOADER_EXPORT void simpleRepr(std::ostream& oss) const; - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void setName(const std::string& name); - static MEDFileFieldLoc *New(med_idt fid, const std::string& locName); - static MEDFileFieldLoc *New(med_idt fid, int id); - static MEDFileFieldLoc *New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldLoc *deepCpy() const; - MEDLOADER_EXPORT int getNbOfGaussPtPerCell() const { return _nb_gauss_pt; } - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT std::string repr() const; - MEDLOADER_EXPORT bool isName(const std::string& name) const { return _name==name; } - MEDLOADER_EXPORT int getDimension() const { return _dim; } - MEDLOADER_EXPORT int getNumberOfGaussPoints() const { return _nb_gauss_pt; } - MEDLOADER_EXPORT int getNumberOfPointsInCells() const { return _nb_node_per_cell; } - MEDLOADER_EXPORT const std::vector& getRefCoords() const { return _ref_coo; } - MEDLOADER_EXPORT const std::vector& getGaussCoords() const { return _gs_coo; } - MEDLOADER_EXPORT const std::vector& getGaussWeights() const { return _w; } - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getGeoType() const { return _geo_type; } - MEDLOADER_EXPORT bool isEqual(const MEDFileFieldLoc& other, double eps) const; - private: - MEDFileFieldLoc(med_idt fid, const std::string& locName); - MEDFileFieldLoc(med_idt fid, int id); - MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - private: - int _dim; - int _nb_gauss_pt; - int _nb_node_per_cell; - std::string _name; - INTERP_KERNEL::NormalizedCellType _geo_type; - std::vector _ref_coo; - std::vector _gs_coo; - std::vector _w; - }; - - /// @cond INTERNAL - class MEDFileAnyTypeField1TSWithoutSDA; - class MEDFileFieldPerMeshPerType; - class MEDFileField1TSWithoutSDA; - class MEDFileFieldNameScope; - class MEDFileFieldGlobsReal; - class MEDFileFieldPerMesh; - class PartDefinition; - - class MEDFileFieldPerMeshPerTypePerDisc : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileFieldPerMeshPerTypePerDisc *NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); - static MEDFileFieldPerMeshPerTypePerDisc *New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId); - static MEDFileFieldPerMeshPerTypePerDisc *New(const MEDFileFieldPerMeshPerTypePerDisc& other); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldPerMeshPerTypePerDisc *deepCpy(MEDFileFieldPerMeshPerType *father) const; - void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob); - void getCoarseData(TypeOfField& type, std::pair& dad, std::string& pfl, std::string& loc) const; - void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; - const MEDFileFieldPerMeshPerType *getFather() const; - void loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc); - void loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc); - void setNewStart(int newValueOfStart); - int getIteration() const; - int getOrder() const; - double getTime() const; - std::string getMeshName() const; - TypeOfField getType() const; - void simpleRepr(int bkOffset, std::ostream& oss, int id) const; - void fillTypesOfFieldAvailable(std::set& types) const; - void setType(TypeOfField newType); - INTERP_KERNEL::NormalizedCellType getGeoType() const; - int getNumberOfComponents() const; - int getNumberOfTuples() const; - int getStart() const { return _start; } - int getEnd() const { return _end; } - DataArray *getOrCreateAndGetArray(); - const DataArray *getOrCreateAndGetArray() const; - const std::vector& getInfo() const; - std::string getProfile() const; - void setProfile(const std::string& newPflName); - std::string getLocalization() const; - void setLocalization(const std::string& newLocName); - int getLocId() const { return _loc_id; } - void setLocId(int newId) const { _loc_id=newId; } - void setFather(MEDFileFieldPerMeshPerType *newFather) { _father=newFather; } - void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, - std::vector& geoTypes) const; - void fillValues(int discId, int& startEntryId, std::vector< std::pair,std::pair > >& entries) const; - int fillEltIdsFromCode(int offset, const std::vector& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const; - int fillTupleIds(int *ptToFill) const; - static int ConvertType(TypeOfField type, int locId); - static std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries); - static bool RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - const DataArrayInt *explicitIdsInMesh, const std::vector& newCode, - MEDFileFieldGlobsReal& glob, DataArrayDouble *arr, std::vector< MEDCouplingAutoRefCountObjectPtr >& result); - static MEDFileFieldPerMeshPerTypePerDisc *NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, - bool isPfl, int nbi, int offset, std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - MEDFileFieldGlobsReal& glob, bool ¬InExisting); - private: - MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); - MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const std::string& dummy); - MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other); - MEDFileFieldPerMeshPerTypePerDisc(); - private: - void goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr); - private: - TypeOfField _type; - MEDFileFieldPerMeshPerType *_father; - int _start; - int _end; - //! _nval is different than end-start in case of ON_GAUSS_PT and ON_GAUSS_NE ! (_nval=(_end-_start)/nbi) - int _nval; - std::string _profile; - std::string _localization; - //! only on assignement -3 : ON_NODES, -2 : ON_CELLS, -1 : ON_GAUSS_NE, 0..* : ON_GAUSS_PT - mutable int _loc_id; - mutable int _profile_it; - MEDCouplingAutoRefCountObjectPtr _pd; - public: - mutable int _tmp_work1; - }; - - class MEDFileFieldPerMeshPerType : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileFieldPerMeshPerType *New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); - static MEDFileFieldPerMeshPerType *NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldPerMeshPerType *deepCpy(MEDFileFieldPerMesh *father) const; - void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); - void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - const MEDFileFieldPerMesh *getFather() const; - void loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc); - void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; - void getDimension(int& dim) const; - void fillTypesOfFieldAvailable(std::set& types) const; - void fillFieldSplitedByType(std::vector< std::pair >& dads, std::vector& types, std::vector& pfls, std::vector& locs) const; - int getIteration() const; - int getOrder() const; - double getTime() const; - std::string getMeshName() const; - void simpleRepr(int bkOffset, std::ostream& oss, int id) const; - void getSizes(int& globalSz, int& nbOfEntries) const; - INTERP_KERNEL::NormalizedCellType getGeoType() const; - int getNumberOfComponents() const; - bool presenceOfMultiDiscPerGeoType() const; - DataArray *getOrCreateAndGetArray(); - const DataArray *getOrCreateAndGetArray() const; - const std::vector& getInfo() const; - std::vector getPflsReallyUsed() const; - std::vector getLocsReallyUsed() const; - std::vector getPflsReallyUsedMulti() const; - std::vector getLocsReallyUsedMulti() const; - void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId); - const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId) const; - void getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const; - void fillValues(int& startEntryId, std::vector< std::pair,std::pair > >& entries) const; - void setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); - bool keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its); - bool keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its); - static med_entity_type ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType); - private: - std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); - std::vector addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); - std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); - std::vector addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); - MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); - MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); - private: - MEDFileFieldPerMesh *_father; - std::vector< MEDCouplingAutoRefCountObjectPtr > _field_pm_pt_pd; - INTERP_KERNEL::NormalizedCellType _geo_type; - }; - - class MEDFileMesh; - - class MEDFileFieldPerMesh : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileFieldPerMesh *New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); - static MEDFileFieldPerMesh *NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldPerMesh *deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const; - void simpleRepr(int bkOffset,std::ostream& oss, int id) const; - void copyTinyInfoFrom(const MEDCouplingMesh *mesh); - void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignFieldNoProfileNoRenum(int& start, const std::vector& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); - void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc); - void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; - void fillTypesOfFieldAvailable(std::set& types) const; - std::vector< std::vector< std::pair > > getFieldSplitedByType(std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - void getDimension(int& dim) const; - double getTime() const; - int getIteration() const; - int getOrder() const; - int getMeshIteration() const { return _mesh_iteration; } - int getMeshOrder() const { return _mesh_order; } - std::string getMeshName() const { return _mesh_name; } - int getNumberOfComponents() const; - bool presenceOfMultiDiscPerGeoType() const; - DataArray *getOrCreateAndGetArray(); - const DataArray *getOrCreateAndGetArray() const; - const std::vector& getInfo() const; - std::vector getPflsReallyUsed() const; - std::vector getLocsReallyUsed() const; - std::vector getPflsReallyUsedMulti() const; - std::vector getLocsReallyUsedMulti() const; - bool changeMeshNames(const std::vector< std::pair >& modifTab); - bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); - void keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its); - void keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its); - void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - DataArray *getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const; - void getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId); - const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const; - private: - int addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type); - MEDCouplingFieldDouble *finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDCouplingFieldDouble *finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const std::vector& geoTypes, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDCouplingFieldDouble *finishFieldNode2(const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - DataArray *finishField4(const std::vector< std::pair >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const; - void assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); - static void SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, - const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& pfls, const std::vector& locs, - std::vector& code, std::vector& notNullPfls); - static int ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs); - MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities); - MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); - private: - std::string _mesh_name; - int _mesh_iteration; - int _mesh_order; - MEDFileAnyTypeField1TSWithoutSDA *_father; - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > _field_pm_pt; - }; - - class MEDFileFieldGlobsReal; - - class MEDFileFieldGlobs : public RefCountObject - { - public: - static MEDFileFieldGlobs *New(const std::string& fname); - static MEDFileFieldGlobs *New(); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldGlobs *deepCpy() const; - MEDFileFieldGlobs *shallowCpyPart(const std::vector& pfls, const std::vector& locs) const; - MEDFileFieldGlobs *deepCpyPart(const std::vector& pfls, const std::vector& locs) const; - void simpleRepr(std::ostream& oss) const; - void appendGlobs(const MEDFileFieldGlobs& other, double eps); - void checkGlobsPflsPartCoherency(const std::vector& pflsUsed) const; - void checkGlobsLocsPartCoherency(const std::vector& locsUsed) const; - void loadProfileInFile(med_idt fid, int id, const std::string& pflName); - void loadProfileInFile(med_idt fid, int id); - void loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real); - void loadAllGlobals(med_idt fid); - void writeGlobals(med_idt fid, const MEDFileWritable& opt) const; - std::vector getPfls() const; - std::vector getLocs() const; - bool existsPfl(const std::string& pflName) const; - bool existsLoc(const std::string& locName) const; - std::string createNewNameOfPfl() const; - std::string createNewNameOfLoc() const; - std::vector< std::vector > whichAreEqualProfiles() const; - std::vector< std::vector > whichAreEqualLocs(double eps) const; - void setFileName(const std::string& fileName); - void changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - int getNbOfGaussPtPerCell(int locId) const; - int getLocalizationId(const std::string& loc) const; - std::string getFileName() const { return _file_name; } - const MEDFileFieldLoc& getLocalizationFromId(int locId) const; - const MEDFileFieldLoc& getLocalization(const std::string& locName) const; - const DataArrayInt *getProfileFromId(int pflId) const; - const DataArrayInt *getProfile(const std::string& pflName) const; - MEDFileFieldLoc& getLocalizationFromId(int locId); - MEDFileFieldLoc& getLocalization(const std::string& locName); - DataArrayInt *getProfile(const std::string& pflName); - DataArrayInt *getProfileFromId(int pflId); - void killProfileIds(const std::vector& pflIds); - void killLocalizationIds(const std::vector& locIds); - // - void appendProfile(DataArrayInt *pfl); - void appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - // - static std::string CreateNewNameNotIn(const std::string& prefix, const std::vector& namesToAvoid); - protected: - MEDFileFieldGlobs(const std::string& fname); - MEDFileFieldGlobs(); - ~MEDFileFieldGlobs(); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _pfls; - std::vector< MEDCouplingAutoRefCountObjectPtr > _locs; - std::string _file_name; - }; - - /// @endcond INTERNAL - - class MEDFileFieldGlobsReal - { - public: - MEDLOADER_EXPORT MEDFileFieldGlobsReal(const std::string& fname); - MEDLOADER_EXPORT MEDFileFieldGlobsReal(); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT void simpleReprGlobs(std::ostream& oss) const; - MEDLOADER_EXPORT void resetContent(); - MEDLOADER_EXPORT void shallowCpyGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void deepCpyGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void appendGlobs(const MEDFileFieldGlobsReal& other, double eps); - MEDLOADER_EXPORT void checkGlobsCoherency() const; - MEDLOADER_EXPORT void checkGlobsPflsPartCoherency() const; - MEDLOADER_EXPORT void checkGlobsLocsPartCoherency() const; - MEDLOADER_EXPORT virtual std::vector getPflsReallyUsed() const = 0; - MEDLOADER_EXPORT virtual std::vector getLocsReallyUsed() const = 0; - MEDLOADER_EXPORT virtual std::vector getPflsReallyUsedMulti() const = 0; - MEDLOADER_EXPORT virtual std::vector getLocsReallyUsedMulti() const = 0; - MEDLOADER_EXPORT virtual void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) = 0; - MEDLOADER_EXPORT virtual void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) = 0; - MEDLOADER_EXPORT virtual ~MEDFileFieldGlobsReal(); - // - MEDLOADER_EXPORT void loadProfileInFile(med_idt fid, int id, const std::string& pflName); - MEDLOADER_EXPORT void loadProfileInFile(med_idt fid, int id); - MEDLOADER_EXPORT void loadGlobals(med_idt fid); - MEDLOADER_EXPORT void loadAllGlobals(med_idt fid); - MEDLOADER_EXPORT void writeGlobals(med_idt fid, const MEDFileWritable& opt) const; - MEDLOADER_EXPORT std::vector getPfls() const; - MEDLOADER_EXPORT std::vector getLocs() const; - MEDLOADER_EXPORT bool existsPfl(const std::string& pflName) const; - MEDLOADER_EXPORT bool existsLoc(const std::string& locName) const; - MEDLOADER_EXPORT std::string createNewNameOfPfl() const; - MEDLOADER_EXPORT std::string createNewNameOfLoc() const; - MEDLOADER_EXPORT std::vector< std::vector > whichAreEqualProfiles() const; - MEDLOADER_EXPORT std::vector< std::vector > whichAreEqualLocs(double eps) const; - MEDLOADER_EXPORT void setFileName(const std::string& fileName); - MEDLOADER_EXPORT void changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsNames(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changePflName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT void changeLocName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT std::vector< std::pair, std::string > > zipPflsNames(); - MEDLOADER_EXPORT std::vector< std::pair, std::string > > zipLocsNames(double eps); - MEDLOADER_EXPORT int getNbOfGaussPtPerCell(int locId) const; - MEDLOADER_EXPORT int getLocalizationId(const std::string& loc) const; - MEDLOADER_EXPORT std::string getFileName() const; - MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalizationFromId(int locId) const; - MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalization(const std::string& locName) const; - MEDLOADER_EXPORT MEDFileFieldLoc& getLocalizationFromId(int locId); - MEDLOADER_EXPORT MEDFileFieldLoc& getLocalization(const std::string& locName); - MEDLOADER_EXPORT const DataArrayInt *getProfile(const std::string& pflName) const; - MEDLOADER_EXPORT const DataArrayInt *getProfileFromId(int pflId) const; - MEDLOADER_EXPORT DataArrayInt *getProfile(const std::string& pflName); - MEDLOADER_EXPORT DataArrayInt *getProfileFromId(int pflId); - MEDLOADER_EXPORT void killProfileIds(const std::vector& pflIds); - MEDLOADER_EXPORT void killLocalizationIds(const std::vector& locIds); - // - MEDLOADER_EXPORT void appendProfile(DataArrayInt *pfl); - MEDLOADER_EXPORT void appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - protected: - MEDFileFieldGlobs *contentNotNull(); - const MEDFileFieldGlobs *contentNotNull() const; - protected: - MEDCouplingAutoRefCountObjectPtr< MEDFileFieldGlobs > _globals; - }; - - class MEDFileFieldNameScope - { - public: - MEDLOADER_EXPORT MEDFileFieldNameScope(); - MEDLOADER_EXPORT MEDFileFieldNameScope(const std::string& fieldName); - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& fieldName); - MEDLOADER_EXPORT std::string getDtUnit() const; - MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); - MEDLOADER_EXPORT void copyNameScope(const MEDFileFieldNameScope& other); - protected: - std::string _name; - std::string _dt_unit; - }; - - class MEDFileMeshes; - - /*! - * SDA is for Shared Data Arrays such as profiles. - */ - class MEDFileAnyTypeField1TSWithoutSDA : public RefCountObject, public MEDFileFieldNameScope - { - public: - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA(); - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order); - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT double getTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _dt; } - MEDLOADER_EXPORT void setTime(int iteration, int order, double val) { _dt=val; _iteration=iteration; _order=order; } - MEDLOADER_EXPORT int getDimension() const; - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT int getMeshIteration() const; - MEDLOADER_EXPORT int getMeshOrder() const; - MEDLOADER_EXPORT bool isDealingTS(int iteration, int order) const; - MEDLOADER_EXPORT std::pair getDtIt() const; - MEDLOADER_EXPORT void fillIteration(std::pair& p) const; - MEDLOADER_EXPORT void fillTypesOfFieldAvailable(std::vector& types) const; - MEDLOADER_EXPORT std::vector getTypesOfFieldAvailable() const; - // - MEDLOADER_EXPORT std::vector getPflsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti2() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - // - MEDLOADER_EXPORT int getNonEmptyLevels(const std::string& mname, std::vector& levs) const; - MEDLOADER_EXPORT std::vector< std::vector > > getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - // - MEDLOADER_EXPORT MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId); - MEDLOADER_EXPORT const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const; - MEDLOADER_EXPORT void deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other); - public: - MEDLOADER_EXPORT int getNumberOfComponents() const; - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT std::vector& getInfo(); - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT void setInfo(const std::vector& infos); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); - MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT virtual void simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitComponents() const; - MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; - MEDLOADER_EXPORT virtual DataArray *getUndergroundDataArray() const = 0; - MEDLOADER_EXPORT virtual DataArray *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const = 0; - MEDLOADER_EXPORT virtual void setArray(DataArray *arr) = 0; - MEDLOADER_EXPORT virtual DataArray *createNewEmptyDataArrayInstance() const = 0; - MEDLOADER_EXPORT virtual DataArray *getOrCreateAndGetArray() = 0; - MEDLOADER_EXPORT virtual const DataArray *getOrCreateAndGetArray() const = 0; - public: - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - DataArray *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const; - public: - MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT int keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its); - MEDLOADER_EXPORT int keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its); - public: - MEDLOADER_EXPORT void allocNotFromFile(int newNbOfTuples); - MEDLOADER_EXPORT bool allocIfNecessaryTheArrayToReceiveDataFromFile(); - MEDLOADER_EXPORT void loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const; - protected: - int getMeshIdFromMeshName(const std::string& mName) const; - int addNewEntryIfNecessary(const MEDCouplingMesh *mesh); - void updateData(int newLgth, const std::vector< std::pair >& oldStartStops); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > > _field_per_mesh; - int _iteration; - int _order; - double _dt; - public: - //! only useable on reading - mutable int _csit; - // -3 means allocated and build from scratch - // -2 means allocated and read from a file - // -1 means not allocated and build from scratch - // >=0 means not allocated and read from a file - mutable int _nb_of_tuples_to_be_allocated; - }; - - class MEDFileIntField1TSWithoutSDA; - - /*! - * SDA is for Shared Data Arrays such as profiles. - */ - class MEDFileField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA - { - public: - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayDouble() const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayDoubleExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT static void CheckMeshDimRel(int meshDimRelToMax); - MEDLOADER_EXPORT static std::vector CheckSBTMesh(const MEDCouplingMesh *mesh); - MEDLOADER_EXPORT static MEDFileField1TSWithoutSDA *New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - public: - MEDLOADER_EXPORT MEDFileField1TSWithoutSDA(); - MEDLOADER_EXPORT MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const; - MEDLOADER_EXPORT void setArray(DataArray *arr); - MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const; - MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray(); - MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const; - MEDLOADER_EXPORT DataArrayDouble *getOrCreateAndGetArrayDouble(); - MEDLOADER_EXPORT const DataArrayDouble *getOrCreateAndGetArrayDouble() const; - MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA *convertToInt() const; - protected: - MEDCouplingAutoRefCountObjectPtr< DataArrayDouble > _arr; - public: - static const char TYPE_STR[]; - }; - - /*! - * SDA is for Shared Data Arrays such as profiles. - */ - class MEDFileIntField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA - { - public: - MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA(); - MEDLOADER_EXPORT static MEDFileIntField1TSWithoutSDA *New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT void setArray(DataArray *arr); - MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const; - MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray(); - MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const; - MEDLOADER_EXPORT DataArrayInt *getOrCreateAndGetArrayInt(); - MEDLOADER_EXPORT const DataArrayInt *getOrCreateAndGetArrayInt() const; - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayInt() const; - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayIntExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT MEDFileField1TSWithoutSDA *convertToDouble() const; - protected: - MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - protected: - MEDCouplingAutoRefCountObjectPtr< DataArrayInt > _arr; - public: - MEDLOADER_EXPORT static const char TYPE_STR[]; - }; - - /*! - * User class. - */ - class MEDFileAnyTypeField1TS : public RefCountObject, public MEDFileWritable, public MEDFileFieldGlobsReal - { - protected: - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - // direct forwarding to MEDFileAnyTypeField1TSWithoutSDA instance _content - public: - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); - MEDLOADER_EXPORT int getDimension() const; - MEDLOADER_EXPORT int getIteration() const; - MEDLOADER_EXPORT int getOrder() const; - MEDLOADER_EXPORT double getTime(int& iteration, int& order) const; - MEDLOADER_EXPORT void setTime(int iteration, int order, double val); - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& name); - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const; - MEDLOADER_EXPORT std::string getDtUnit() const; - MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT int getMeshIteration() const; - MEDLOADER_EXPORT int getMeshOrder() const; - MEDLOADER_EXPORT int getNumberOfComponents() const; - MEDLOADER_EXPORT bool isDealingTS(int iteration, int order) const; - MEDLOADER_EXPORT std::pair getDtIt() const; - MEDLOADER_EXPORT void fillIteration(std::pair& p) const; - MEDLOADER_EXPORT void fillTypesOfFieldAvailable(std::vector& types) const; - MEDLOADER_EXPORT void setInfo(const std::vector& infos); - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT std::vector& getInfo(); - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT std::vector getTypesOfFieldAvailable() const; - MEDLOADER_EXPORT std::vector< std::vector > > getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId); - MEDLOADER_EXPORT const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const; - MEDLOADER_EXPORT int getNonEmptyLevels(const std::string& mname, std::vector& levs) const; - public: - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void loadArrays(); - MEDLOADER_EXPORT void loadArraysIfNecessary(); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *deepCpy() const; - MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *shallowCpy() const = 0; - public: - //! underground method see MEDFileField1TSWithoutSDA::setProfileNameOnLeaf - MEDLOADER_EXPORT void setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false); - //! underground method see MEDFileField1TSWithoutSDA::setLocNameOnLeaf - MEDLOADER_EXPORT void setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - public: - MEDLOADER_EXPORT static int LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector& infos, std::string& dtunitOut); - MEDLOADER_EXPORT static int LocateField(med_idt fid, const std::string& fileName, const std::string& fieldName, int& posCFormat, med_field_type& typcha, std::vector& infos, std::string& dtunitOut); - public: - MEDLOADER_EXPORT virtual med_field_type getMEDFileFieldType() const = 0; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *contentNotNullBase(); - MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA *contentNotNullBase() const; - protected: - MEDCouplingAutoRefCountObjectPtr _content; - }; - - class MEDFileIntField1TS; - - /*! - * User class. - */ - class MEDFileField1TS : public MEDFileAnyTypeField1TS - { - public: - MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileField1TS *New(); - MEDLOADER_EXPORT MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayDouble *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field); - MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - // direct forwarding to MEDFileField1TSWithoutSDA instance _content - public: - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *shallowCpy() const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray() const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - public: - MEDLOADER_EXPORT static void SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr& arr); - MEDLOADER_EXPORT static DataArrayDouble *ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr& arr); - private: - med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } - const MEDFileField1TSWithoutSDA *contentNotNull() const; - MEDFileField1TSWithoutSDA *contentNotNull(); - private: - ~MEDFileField1TS() { } - MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDFileField1TS(); - }; - - class MEDFileIntField1TS : public MEDFileAnyTypeField1TS - { - public: - MEDLOADER_EXPORT static MEDFileIntField1TS *New(); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT MEDFileField1TS *convertToDouble(bool isDeepCpyGlobs=true) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *shallowCpy() const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayInt *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals); - MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray() const; - public: - MEDLOADER_EXPORT static DataArrayInt *ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr& arr); - private: - med_field_type getMEDFileFieldType() const { return MED_INT32; } - const MEDFileIntField1TSWithoutSDA *contentNotNull() const; - MEDFileIntField1TSWithoutSDA *contentNotNull(); - private: - ~MEDFileIntField1TS() { } - MEDFileIntField1TS(); - MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent); - }; - - class MEDFileAnyTypeFieldMultiTSWithoutSDA : public RefCountObject, public MEDFileFieldNameScope - { - protected: - MEDFileAnyTypeFieldMultiTSWithoutSDA(); - MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName); - MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - public: - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *deepCpy() const; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitComponents() const; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const = 0; - MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const = 0; - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT void setInfo(const std::vector& info); - MEDLOADER_EXPORT int getTimeStepPos(int iteration, int order) const; - MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA& getTimeStepEntry(int iteration, int order) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA& getTimeStepEntry(int iteration, int order); - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT void eraseEmptyTS(); - MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); - MEDLOADER_EXPORT void eraseTimeStepIds2(int bg, int end, int step); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *buildFromTimeStepIds(const int *startIds, const int *endIds) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *buildFromTimeStepIds2(int bg, int end, int step) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; - MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; - MEDLOADER_EXPORT void pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr& tse); - MEDLOADER_EXPORT void synchronizeNameScope(); - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const; - MEDLOADER_EXPORT int getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const; - MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT std::vector< std::vector< std::pair > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT std::vector< std::vector > getTypesOfFieldAvailable() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArray(int iteration, int order) const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT void loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& opts) const; - MEDLOADER_EXPORT void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void unloadArrays(); - public: - MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA *getTimeStepAtPos2(int pos) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *getTimeStepAtPos2(int pos); - MEDLOADER_EXPORT std::vector getPflsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti2() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void setIteration(int i, MEDCouplingAutoRefCountObjectPtr ts); - protected: - virtual med_field_type getMEDFileFieldType() const = 0; - void copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); - void checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const; - void checkThatComponentsMatch(const std::vector& compos) const; - void checkThatNbOfCompoOfTSMatchThis() const; - protected: - std::vector _infos; - std::vector< MEDCouplingAutoRefCountObjectPtr > _time_steps; - }; - - class MEDFileIntFieldMultiTSWithoutSDA; - - class MEDFileFieldMultiTSWithoutSDA : public MEDFileAnyTypeFieldMultiTSWithoutSDA - { - public: - MEDLOADER_EXPORT static MEDFileFieldMultiTSWithoutSDA *New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const; - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA *convertToInt() const; - protected: - MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName); - MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } - MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const; - void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const; - public: - MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA(); - }; - - class MEDFileIntFieldMultiTSWithoutSDA : public MEDFileAnyTypeFieldMultiTSWithoutSDA - { - public: - MEDLOADER_EXPORT static MEDFileIntFieldMultiTSWithoutSDA *New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const; - MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA *convertToDouble() const; - protected: - MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName); - MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - med_field_type getMEDFileFieldType() const { return MED_INT32; } - MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const; - void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const; - public: - MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA(); - }; - - class MEDFileAnyTypeFieldMultiTSIterator; - class MEDFileFastCellSupportComparator; - /*! - * User class. - */ - class MEDFileAnyTypeFieldMultiTS : public RefCountObject, public MEDFileWritable, public MEDFileFieldGlobsReal - { - protected: - MEDFileAnyTypeFieldMultiTS(); - MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities=0); - MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - static MEDFileAnyTypeFieldMultiTS *BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName); - static MEDFileAnyTypeFieldMultiTSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - static MEDFileAnyTypeFieldMultiTSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - public: - MEDLOADER_EXPORT static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT void loadArrays(); - MEDLOADER_EXPORT void loadArraysIfNecessary(); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *deepCpy() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitComponents() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitDiscretizations() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const = 0; - // - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const = 0; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT static std::vector< std::vector > SplitIntoCommonTimeSeries(const std::vector& vectFMTS); - MEDLOADER_EXPORT static std::vector< std::vector > SplitPerCommonSupport(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& fsc); - MEDLOADER_EXPORT static int CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1); - public:// direct forwarding to MEDFileField1TSWithoutSDA instance _content - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& name); - MEDLOADER_EXPORT std::string getDtUnit() const; - MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const; - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT void eraseEmptyTS(); - MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); - MEDLOADER_EXPORT void eraseTimeStepIds2(int bg, int end, int step); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *buildSubPart(const int *startIds, const int *endIds) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *buildSubPartSlice(int bg, int end, int step) const; - MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; - MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; - MEDLOADER_EXPORT void pushBackTimeSteps(const std::vector& f1ts); - MEDLOADER_EXPORT void pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts); - MEDLOADER_EXPORT void pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts); - MEDLOADER_EXPORT void synchronizeNameScope(); - MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSIterator *iterator(); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT void setInfo(const std::vector& info); - MEDLOADER_EXPORT int getNumberOfComponents() const; - MEDLOADER_EXPORT int getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const; - MEDLOADER_EXPORT std::vector< std::vector > getTypesOfFieldAvailable() const; - MEDLOADER_EXPORT std::vector< std::vector< std::pair > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT MEDCouplingAutoRefCountObjectPtr getContent(); - public: - MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - protected: - MEDFileAnyTypeFieldMultiTSWithoutSDA *contentNotNullBase(); - const MEDFileAnyTypeFieldMultiTSWithoutSDA *contentNotNullBase() const; - private: - static std::vector< std::vector > SplitPerCommonSupportNotNodesAlg(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& cmps); - protected: - MEDCouplingAutoRefCountObjectPtr _content; - }; - - class MEDFileIntFieldMultiTS; - - /*! - * User class. - */ - class MEDFileFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll=true); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; - MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; - MEDLOADER_EXPORT MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const; - // - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayDouble *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field); - MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray(int iteration, int order) const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const; - private: - const MEDFileFieldMultiTSWithoutSDA *contentNotNull() const; - MEDFileFieldMultiTSWithoutSDA *contentNotNull(); - private: - ~MEDFileFieldMultiTS() { } - MEDFileFieldMultiTS(); - MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities=0); - }; - - /*! - * User class. - */ - class MEDFileIntFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll=true); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; - MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; - MEDLOADER_EXPORT MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayInt *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals); - MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - // - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray(int iteration, int order) const; - private: - const MEDFileIntFieldMultiTSWithoutSDA *contentNotNull() const; - MEDFileIntFieldMultiTSWithoutSDA *contentNotNull(); - private: - ~MEDFileIntFieldMultiTS() { } - MEDFileIntFieldMultiTS(); - MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities=0); - }; - - class MEDFileAnyTypeFieldMultiTSIterator - { - public: - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts); - MEDLOADER_EXPORT ~MEDFileAnyTypeFieldMultiTSIterator(); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *nextt(); - private: - MEDCouplingAutoRefCountObjectPtr _fmts; - int _iter_id; - int _nb_iter; - }; - - class MEDFileFieldsIterator; - - /*! - * Use class. - */ - class MEDFileFields : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileFields *New(); - MEDLOADER_EXPORT static MEDFileFields *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileFields *LoadPartOf(const std::string& fileName, bool loadAll=true, const MEDFileMeshes *ms=0); - MEDLOADER_EXPORT static MEDFileFields *LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair >& entities, bool loadAll=true); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileFields *deepCpy() const; - MEDLOADER_EXPORT MEDFileFields *shallowCpy() const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT void loadArrays(); - MEDLOADER_EXPORT void loadArraysIfNecessary(); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); - MEDLOADER_EXPORT int getNumberOfFields() const; - MEDLOADER_EXPORT std::vector< std::pair > getCommonIterations(bool& areThereSomeForgottenTS) const; - MEDLOADER_EXPORT std::vector getFieldsNames() const; - MEDLOADER_EXPORT std::vector getMeshesNames() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss) const; - // - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushField(MEDFileAnyTypeFieldMultiTS *field); - MEDLOADER_EXPORT void pushFields(const std::vector& fields); - MEDLOADER_EXPORT void setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field); - MEDLOADER_EXPORT int getPosFromFieldName(const std::string& fieldName) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const; - MEDLOADER_EXPORT MEDFileFields *buildSubPart(const int *startIds, const int *endIds) const; - MEDLOADER_EXPORT bool removeFieldsWithoutAnyTimeStep(); - MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const; - MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT MEDFileFieldsIterator *iterator(); - MEDLOADER_EXPORT void destroyFieldAtPos(int i); - MEDLOADER_EXPORT void destroyFieldsAtPos(const int *startIds, const int *endIds); - MEDLOADER_EXPORT void destroyFieldsAtPos2(int bg, int end, int step); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N); - public: - MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - private: - ~MEDFileFields() { } - MEDFileFields(); - MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _fields; - }; - - class MEDFileFieldsIterator - { - public: - MEDLOADER_EXPORT MEDFileFieldsIterator(MEDFileFields *fs); - MEDLOADER_EXPORT ~MEDFileFieldsIterator(); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *nextt(); - private: - MEDCouplingAutoRefCountObjectPtr _fs; - int _iter_id; - int _nb_iter; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileFieldOverView.cxx b/medtool/src/MEDLoader/MEDFileFieldOverView.cxx deleted file mode 100644 index 4f0367cb2..000000000 --- a/medtool/src/MEDLoader/MEDFileFieldOverView.cxx +++ /dev/null @@ -1,2427 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileFieldOverView.hxx" -#include "MEDFileField.hxx" -#include "MEDFileMesh.hxx" - -#include "MEDCouplingFieldDiscretization.hxx" -#include "CellModel.hxx" - -using namespace ParaMEDMEM; - -const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= -{1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; - -const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26}; - -const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; - -MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) -{ - return new MEDFileMeshStruct(mesh); -} - -std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(0); - for(std::vector< std::vector >::const_iterator it0=_geo_types_distrib.begin();it0!=_geo_types_distrib.end();it0++) - ret+=(*it0).capacity()*sizeof(int); - ret+=_geo_types_distrib.capacity()*sizeof(std::vector); - return ret; -} - -std::vector MEDFileMeshStruct::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) -{ - std::vector levs(mesh->getNonEmptyLevels()); - _name=mesh->getName(); - _nb_nodes=mesh->getNumberOfNodes(); - if(!levs.empty()) - { - _geo_types_distrib.resize(-(*std::min_element(levs.begin(),levs.end()))+1); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); - } -} - -int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const -{ - int j=0; - for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--) - { - std::size_t sz=(*it1).size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : internal error in code !"); - std::size_t nbGeo=sz/3; - for(std::size_t i=0;i >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) - { - std::size_t sz=(*it1).size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfElemsOfGeoType : internal error in code !"); - std::size_t nbGeo=sz/3; - for(std::size_t i=0;i >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) - { - std::size_t sz=(*it1).size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::doesManageGeoType : internal error in code !"); - std::size_t nbGeo=sz/3; - for(std::size_t i=0;ihasImplicitPart()) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : by default no implicit geo type can be appended !"); - static const char MSG[]="MEDFileMeshStruct::appendIfImplicitType : the distribution does not looks like structured standard !"; - if(_geo_types_distrib.size()!=1) - throw INTERP_KERNEL::Exception(MSG); - std::size_t sz(_geo_types_distrib[0].size()); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : internal error in code !"); - std::size_t nbGeo(sz/3); - if(nbGeo!=1) - throw INTERP_KERNEL::Exception(MSG); - std::vector arr(3); arr[0]=(int)t; arr[1]=_mesh->buildImplicitPartIfAny(t); arr[2]=-1; - _geo_types_distrib.push_back(arr); -} - - -int MEDFileMeshStruct::getNumberOfLevs() const -{ - return (int)_geo_types_distrib.size(); -} - -int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const -{ - int pos(-relativeLev); - if(pos<0 || pos>=(int)_geo_types_distrib.size()) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !"); - std::size_t sz=_geo_types_distrib[pos].size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : internal error in code !"); - return (int)(sz/3); -} - -//= - -std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDMeshMultiLev::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& levs) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !"); - const MEDFileUMesh *um(dynamic_cast(m)); - if(um) - return MEDUMeshMultiLev::New(um,levs); - const MEDFileCMesh *cm(dynamic_cast(m)); - if(cm) - return MEDCMeshMultiLev::New(cm,levs); - const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); - if(clm) - return MEDCurveLinearMeshMultiLev::New(clm,levs); - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); -} - -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !"); - const MEDFileUMesh *um(dynamic_cast(m)); - if(um) - return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities); - const MEDFileCMesh *cm(dynamic_cast(m)); - if(cm) - return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities); - const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); - if(clm) - return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities); - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); -} - -MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode) -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,m->getNonEmptyLevels())); - ret->selectPartOfNodes(pflOnNode); - return ret.retn(); -} - -void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) -{ - if(nr) - nr->incrRef(); - _node_reduction=const_cast(nr); -} - -void MEDMeshMultiLev::setCellReduction(const DataArrayInt *cr) -{ - if(_pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::setCellReduction : can be used only for single geo type mesh !"); - _pfls[0]=const_cast(cr); - if(cr) - cr->incrRef(); -} - -bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const -{ - if(fst.getType()==ON_NODES) - { - if(fst.getNumberOfItems()!=1) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !"); - const MEDFileField1TSStructItem2& p(fst[0]); - std::string pflName(p.getPflName()); - const DataArrayInt *nr(_node_reduction); - if(pflName.empty() && !nr) - return true; - if(!pflName.empty() && !nr) - return false; - if(pflName==nr->getName()) - return true; - return false; - } - else - { - std::size_t sz(fst.getNumberOfItems()); - if(sz!=_geo_types.size()) - return false; - int strt(0); - for(std::size_t i=0;i ret(const_cast(vals)); ret->incrRef(); - if(isFastlyTheSameStruct(fst,globs)) - return ret.retn(); - else - return constructDataArray(fst,globs,vals); -} - -/*! - * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const -{ - const DataArrayInt *fids(_cell_fam_ids); - if(!fids) - { famIds=0; isWithoutCopy=true; return ; } - std::size_t sz(_geo_types.size()); - bool presenceOfPfls(false); - for(std::size_t i=0;i(fids); famIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); return ; } - //bad luck the slowest part - isWithoutCopy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); - std::vector< const DataArrayInt *> ret(sz); - int start(0); - for(std::size_t i=0;i tmp(fids->selectByTupleId2(start,start+lgth,1)); - retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); - } - else - { - retSafe[i]=fids->selectByTupleId2(start,start+lgth,1); - } - ret[i]=retSafe[i]; - start+=lgth; - } - famIds=DataArrayInt::Aggregate(ret); -} - -/*! - * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const -{ - const DataArrayInt *nids(_cell_num_ids); - if(!nids) - { numIds=0; isWithoutCopy=true; return ; } - std::size_t sz(_geo_types.size()); - bool presenceOfPfls(false); - for(std::size_t i=0;i(nids); numIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); return ; } - //bad luck the slowest part - isWithoutCopy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); - std::vector< const DataArrayInt *> ret(sz); - int start(0); - for(std::size_t i=0;i tmp(nids->selectByTupleId2(start,start+lgth,1)); - retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); - } - else - { - retSafe[i]=nids->selectByTupleId2(start,start+lgth,1); - } - ret[i]=retSafe[i]; - start+=lgth; - } - numIds=DataArrayInt::Aggregate(ret); -} - -/*! - * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const -{ - const DataArrayInt *fids(_node_fam_ids); - if(!fids) - { famIds=0; isWithoutCopy=true; return ; } - const DataArrayInt *nr(_node_reduction); - if(nr) - { - isWithoutCopy=false; - famIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); - } - else - { - famIds=const_cast(fids); famIds->incrRef(); - isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); - } -} - -/*! - * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const -{ - const DataArrayInt *fids(_node_num_ids); - if(!fids) - { numIds=0; isWithoutCopy=true; return ; } - const DataArrayInt *nr(_node_reduction); - if(nr) - { - isWithoutCopy=false; - numIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); - } - else - { - numIds=const_cast(fids); numIds->incrRef(); - isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); - } -} - -std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes() const -{ - return _geo_types; -} - -void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds) -{ - _cell_fam_ids=famIds; - if(famIds) - famIds->incrRef(); -} - -void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds) -{ - _cell_num_ids=numIds; - if(numIds) - numIds->incrRef(); -} - -void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds) -{ - _node_fam_ids=famIds; - if(famIds) - famIds->incrRef(); -} - -void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds) -{ - _node_num_ids=numIds; - if(numIds) - numIds->incrRef(); -} - -std::string MEDMeshMultiLev::getPflNameOfId(int id) const -{ - std::size_t sz(_pfls.size()); - if(id<0 || id>=(int)sz) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); - const DataArrayInt *pfl(_pfls[id]); - if(!pfl) - return std::string(""); - return pfl->getName(); -} - -/*! - * Returns the number of cells having geometric type \a t. - * The profiles are **NOT** taken into account here. - */ -int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const -{ - std::size_t sz(_nb_entities.size()); - for(std::size_t i=0;ideepCpy(); - if(pflName.empty() && nr) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); - if(!pflName.empty() && nr) - { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(nr->deepCpy()); - p1->sort(true); p2->sort(true); - if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : it appears that a profile on nodes does not cover the cells correctly !"); - p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); - ret->renumberInPlace(p1->begin()); - return ret.retn(); - } - if(!pflName.empty() && !nr) - { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); - p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=getNumberOfNodes()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); - ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !"); - } - else - { - std::size_t sz(fst.getNumberOfItems()); - std::set s(_geo_types.begin(),_geo_types.end()); - if(s.size()!=_geo_types.size()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); - std::vector< const DataArray *> arr(s.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrSafe(s.size()); - int iii(0); - int nc(vals->getNumberOfComponents()); - std::vector compInfo(vals->getInfoOnComponents()); - for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it=_geo_types.begin();it!=_geo_types.end();it++,iii++) - { - const DataArrayInt *thisP(_pfls[iii]); - std::vector ps; - for(std::size_t i=0;igetNbOfIntegrationPts(globs)); - const DataArrayInt *otherP(ps[0]->getPfl(globs)); - const std::pair& strtStop(ps[0]->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - if(!thisP && !otherP) - { - arrSafe[iii]=ret; arr[iii]=ret; - continue; - } - if(thisP && otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo()))); - MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); - p2->transformWithIndArr(p1->begin(),p1->end()); - //p1=p2->getIdsNotEqual(-1); - //p1=p2->selectByTupleIdSafe(p1->begin(),p1->end()); - ret->rearrange(nbi*nc); ret=ret->selectByTupleIdSafe(p2->begin(),p2->end()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[iii]=ret; arr[iii]=ret; - continue; - } - if(!thisP && otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); - p1->sort(true); - p1->checkAllIdsInRange(0,getNumberOfCells(ps[0]->getGeo())); - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1); - ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[iii]=ret; arr[iii]=ret; - continue; - } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); - } - else - { - std::vector< const DataArrayInt * >otherPS(ps.size()); - std::vector< const DataArray * > arr2(ps.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arr2Safe(ps.size()); - std::vector< const DataArrayInt * > nbis(ps.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > nbisSafe(ps.size()); - int jj(0); - for(std::vector::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) - { - int nbi((*it2)->getNbOfIntegrationPts(globs)); - const DataArrayInt *otherPfl((*it2)->getPfl(globs)); - const std::pair& strtStop((*it2)->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - if(!otherPfl) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); - arr2[jj]=ret2; arr2Safe[jj]=ret2; otherPS[jj]=otherPfl; - nbisSafe[jj]=DataArrayInt::New(); nbisSafe[jj]->alloc(otherPfl->getNumberOfTuples(),1); nbisSafe[jj]->fillWithValue(nbi); - nbis[jj]=nbisSafe[jj]; - } - MEDCouplingAutoRefCountObjectPtr arr3(DataArray::Aggregate(arr2)); - MEDCouplingAutoRefCountObjectPtr otherP(DataArrayInt::Aggregate(otherPS)); - MEDCouplingAutoRefCountObjectPtr zenbis(DataArrayInt::Aggregate(nbis)); - MEDCouplingAutoRefCountObjectPtr otherPN(otherP->invertArrayN2O2O2N(getNumberOfCells(*it))); - MEDCouplingAutoRefCountObjectPtr p1; - if(thisP) - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); - else - p1=otherP->deepCpy(); - MEDCouplingAutoRefCountObjectPtr zenbisN(zenbis->renumber(p1->begin())); - zenbisN->computeOffsets2(); - jj=0; - for(std::vector::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) - { - //int nbi((*it2)->getNbOfIntegrationPts(globs)); - const DataArrayInt *otherPfl((*it2)->getPfl(globs)); - const std::pair& strtStop((*it2)->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - // - MEDCouplingAutoRefCountObjectPtr p2(otherPfl->deepCpy()); - p2->transformWithIndArr(otherPN->begin(),otherPN->end()); - p2->transformWithIndArr(p1->begin(),p1->end()); - MEDCouplingAutoRefCountObjectPtr idsN(p2->buildExplicitArrByRanges(zenbisN)); - arr3->setPartOfValuesBase3(ret2,idsN->begin(),idsN->end(),0,nc,1); - } - arrSafe[iii]=arr3; arr[iii]=arr3; - continue; - } - } - return DataArray::Aggregate(arr); - } -} - -/*! - * This method is called to add NORM_POINT1 cells in \a this so that orphan nodes in \a verticesToAdd will be fetched. - */ -void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) -{ - int nbOfVertices(verticesToAdd->getNumberOfTuples()); - std::size_t sz(_pfls.size()); - _pfls.resize(sz+1); - _geo_types.resize(sz+1,INTERP_KERNEL::NORM_POINT1); - _nb_entities.resize(sz+1,nbOfVertices); - _node_reduction=nr; nr->incrRef(); - _nb_nodes+=nbOfVertices; - const DataArrayInt *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids); - if(cf) - { - MEDCouplingAutoRefCountObjectPtr tmp; - std::vector a(2); - a[0]=cf; - if(nf) - tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); - else - { - tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); - } - a[1]=tmp; - _cell_fam_ids=DataArrayInt::Aggregate(a); - } - if(cn) - { - MEDCouplingAutoRefCountObjectPtr tmp; - std::vector a(2); - a[0]=cn; - if(nn) - tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); - else - { - tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); - } - a[1]=tmp; - _cell_num_ids=DataArrayInt::Aggregate(a); - } -} - -MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0) -{ -} - -MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes) -{ - std::size_t sz(_geo_types.size()); - if(sz!=pfls.size() || sz!=nbEntities.size()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !"); - _pfls.resize(sz); - for(std::size_t i=0;iincrRef(); - _pfls[i]=const_cast(pfls[i]); - } -} - -MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_mesh(other._mesh),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_num_ids(other._cell_num_ids),_node_fam_ids(other._node_fam_ids),_node_num_ids(other._node_num_ids) -{ -} - -//= - -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& levs) -{ - return new MEDUMeshMultiLev(m,levs); -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs):MEDMeshMultiLev(m) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); - std::vector v; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - std::vector vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it)); - v.insert(v.end(),vTmp.begin(),vTmp.end()); - } - std::size_t sz(v.size()); - if(v.empty()) - { - _coords=m->getCoords(); _coords->incrRef(); - } - _parts.resize(sz); - _pfls.resize(sz); - _geo_types.resize(sz); - _nb_entities.resize(sz); - for(std::size_t i=0;iincrRef(); - else - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); - _parts[i]=obj; - _geo_types[i]=obj->getCellModelEnum(); - _nb_entities[i]=obj->getNumberOfCells(); - } - // ids fields management - bool cellFamIdsNoCpy(levs.size()==1); - if(cellFamIdsNoCpy) - { - const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0])); - if(tmp) - { - tmp->incrRef(); - _cell_fam_ids=(const_cast(tmp)); - } - } - else - { - std::vector tmps(levs.size()); - bool f(true); - for(std::size_t i=0;igetFamilyFieldAtLevel(levs[i]); - if(!tmps[i]) - f=false; - } - if(f && !tmps.empty()) - _cell_fam_ids=DataArrayInt::Aggregate(tmps); - } - bool cellNumIdsNoCpy(levs.size()==1); - if(cellNumIdsNoCpy) - { - const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0])); - if(tmp) - { - tmp->incrRef(); - _cell_num_ids=(const_cast(tmp)); - } - } - else - { - std::vector tmps(levs.size()); - bool n(true); - for(std::size_t i=0;igetNumberFieldAtLevel(levs[i]); - if(!tmps[i]) - n=false; - } - if(n && !tmps.empty()) - _cell_num_ids=DataArrayInt::Aggregate(tmps); - } - // node part - { - const DataArrayInt *tmp(m->getFamilyFieldAtLevel(1)); - if(tmp) - { - tmp->incrRef(); - _node_fam_ids=(const_cast(tmp)); - } - } - { - const DataArrayInt *tmp(m->getNumberFieldAtLevel(1)); - if(tmp) - { - tmp->incrRef(); - _node_num_ids=(const_cast(tmp)); - } - } -} - -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) -{ - std::size_t sz(gts.size()); - if(sz<1) - throw INTERP_KERNEL::Exception("constructor of MEDUMeshMultiLev : number of different geo type must be >= 1 !"); - unsigned dim(INTERP_KERNEL::CellModel::GetCellModel(gts[0]).getDimension()); - _parts.resize(sz); - bool isSameDim(true),isNoPfl(true); - for(std::size_t i=0;igetDirectUndergroundSingleGeoTypeMesh(gts[i])); - if(INTERP_KERNEL::CellModel::GetCellModel(gts[i]).getDimension()!=dim) - isSameDim=false; - if(pfls[i]) - isNoPfl=false; - if(elt) - elt->incrRef(); - _parts[i]=elt; - } - // ids fields management - int lev((int)dim-m->getMeshDimension()); - if(isSameDim && isNoPfl && m->getGeoTypesAtLevel(lev)==gts)//optimized part - { - const DataArrayInt *famIds(m->getFamilyFieldAtLevel(lev)); - if(famIds) - { _cell_fam_ids=const_cast(famIds); famIds->incrRef(); } - const DataArrayInt *numIds(m->getNumberFieldAtLevel(lev)); - if(numIds) - { _cell_num_ids=const_cast(numIds); numIds->incrRef(); } - famIds=m->getFamilyFieldAtLevel(1); - if(famIds) - { _node_fam_ids=const_cast(famIds); famIds->incrRef(); } - numIds=m->getNumberFieldAtLevel(1); - if(numIds) - { _node_num_ids=const_cast(numIds); numIds->incrRef(); } - return ; - } - // - std::vector< MEDCouplingAutoRefCountObjectPtr > famIdsSafe(sz); - std::vector famIds(sz); - bool f(true); - for(std::size_t i=0;iextractFamilyFieldOnGeoType(gts[i]); - famIds[i]=famIdsSafe[i]; - if(!famIds[i]) - f=false; - } - if(f) - _cell_fam_ids=DataArrayInt::Aggregate(famIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > numIdsSafe(sz); - std::vector numIds(sz); - bool n(true); - for(std::size_t i=0;iextractNumberFieldOnGeoType(gts[i]); - numIds[i]=numIdsSafe[i]; - if(!numIds[i]) - n=false; - } - if(n) - _cell_num_ids=DataArrayInt::Aggregate(numIds); - // node ids management - const DataArrayInt *nodeFamIds(m->getFamilyFieldAtLevel(1)); - if(nodeFamIds) - { _node_fam_ids=const_cast(nodeFamIds); nodeFamIds->incrRef(); } - const DataArrayInt *nodeNumIds(m->getNumberFieldAtLevel(1)); - if(nodeNumIds) - { _node_num_ids=const_cast(nodeNumIds); nodeNumIds->incrRef(); } -} - -void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) -{ - if(!pflNodes || !pflNodes->isAllocated()) - return ; - std::size_t sz(_parts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > a(sz); - std::vector< const DataArrayInt *> aa(sz); - for(std::size_t i=0;i m(_parts[i]); - if(pfl) - m=dynamic_cast(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - DataArrayInt *cellIds=0; - m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; - MEDCouplingAutoRefCountObjectPtr o2n(m2->getNodeIdsInUse(tmp)); - a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i]; - if(pfl) - _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - else - _pfls[i]=cellIdsSafe; - } - if(!aa.empty()) - _node_reduction=DataArrayInt::Aggregate(aa);//general case - else - _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh. - _node_reduction->sort(true); - _node_reduction=_node_reduction->buildUnique(); - if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples()) - return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts - if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !"); - // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts... - MEDCouplingAutoRefCountObjectPtr pflNodes2(pflNodes->deepCpy()); - pflNodes2->sort(true); - MEDCouplingAutoRefCountObjectPtr diff(pflNodes2->buildSubstractionOptimized(_node_reduction)); - appendVertices(diff,pflNodes2); -} - -MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const -{ - return new MEDUMeshMultiLev(*this); -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts),_coords(other._coords) -{ -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part):MEDMeshMultiLev(other) -{ - _parts.resize(1); - _parts[0]=part; - _geo_types.resize(1); _geo_types[0]=part->getCellModelEnum(); - _nb_entities.resize(1); _nb_entities[0]=part->getNumberOfCells(); - _pfls.resize(1); _pfls[0]=0; -} - -/*! - * To be called only once ! Because due to some optimizations (sometimes aggressive) the internal state can be changed... - * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer. - * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance. - */ -bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const -{ - const DataArrayDouble *tmp(0); - if(_parts.empty()) - tmp=_coords; - else - tmp=_parts[0]->getCoords(); - if(!tmp) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); - MEDCouplingAutoRefCountObjectPtr a(const_cast(tmp)); tmp->incrRef(); - int szBCE(0),szD(0),szF(0); - bool isPolyh(false); - int iii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) - { - const MEDCoupling1GTUMesh *cur(*it); - if(!cur) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !"); - // - const DataArrayInt *pfl(_pfls[iii]); - MEDCouplingAutoRefCountObjectPtr cur2; - if(!pfl) - { cur2=const_cast(cur); cur2->incrRef(); } - else - { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } - // - int curNbCells(cur->getNumberOfCells()); - szBCE+=curNbCells; - if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - szD+=cur->getNodalConnectivity()->getNumberOfTuples()+curNbCells; - else - { - isPolyh=true; - MEDCouplingAutoRefCountObjectPtr tmp2(cur->computeEffectiveNbOfNodesPerCell()); - szD+=tmp2->accumulate(0)+curNbCells; - szF+=2*curNbCells+cur->getNodalConnectivity()->getNumberOfTuples(); - } - } - MEDCouplingAutoRefCountObjectPtr b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer()); - MEDCouplingAutoRefCountObjectPtr d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer()); - MEDCouplingAutoRefCountObjectPtr e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0); - if(isPolyh) - { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } - int k(0); - iii=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) - { - const MEDCoupling1GTUMesh *cur(*it); - // - const DataArrayInt *pfl(_pfls[iii]); - MEDCouplingAutoRefCountObjectPtr cur2; - if(!pfl) - { cur2=const_cast(cur); cur2->incrRef(); } - else - { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } - // - int curNbCells(cur->getNumberOfCells()); - int gt((int)cur->getCellModelEnum()); - if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); - unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]); - if(gtvtk==255) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !"); - std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; - const MEDCoupling1SGTUMesh *scur(dynamic_cast(cur)); - const MEDCoupling1DGTUMesh *dcur(dynamic_cast(cur)); - const int *connPtr(cur->getNodalConnectivity()->begin()); - if(!scur && !dcur) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); - if(scur) - { - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) - { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetNodalConnectivityIndex()->begin()); - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1); - *dPtr++=(int)s.size(); - dPtr=std::copy(s.begin(),s.end(),dPtr); - *cPtr++=k; k+=(int)s.size()+1; - } - } - if(isPolyh) - { - connIPtr=dcur->getNodalConnectivityIndex()->begin(); - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } - else - { - int kk(0); - for(int i=0;igetNumberOfComponents()!=3) - a=a->changeNbOfComponents(3,0.); - coords=a.retn(); types=b.retn(); cellLocations=c.retn(); cells=d.retn(); - if(!isPolyh) - { faceLocations=0; faces=0; } - else - { faceLocations=e.retn(); faces=f.retn(); } - return _mesh->isObjectInTheProgeny(coords); -} - -void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const -{ - const DataArrayInt *nr(_node_reduction); - if(!nr) - return ; - if(nodalConnVTK->empty() && !polyhedNodalConnVTK) - { - coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); - return ; - } - int sz(coords->getNumberOfTuples()); - std::vector b(sz,false); - const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); - while(work!=endW) - { - int nb(*work++); - for(int i=0;i=0 && *workbegin(); endW=polyhedNodalConnVTK->end(); - while(work!=endW) - { - int nb(*work++); - for(int i=0;i=0 && *workgetNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); - // Go renumbering ! - MEDCouplingAutoRefCountObjectPtr o2n(DataArrayInt::New()); o2n->alloc(sz,1); - int *o2nPtr(o2n->getPointer()); - int newId(0); - for(int i=0;ibegin()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples())); - MEDCouplingAutoRefCountObjectPtr perm(DataArrayInt::FindPermutationFromFirstToSecond(n2o,nr)); - const int *permPtr(perm->begin()); - int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples()); - while(work2!=endW2) - { - int nb(*work2++); - for(int i=0;igetPointer(); endW2=polyhedNodalConnVTK->getPointer()+polyhedNodalConnVTK->getNumberOfTuples(); - while(work2!=endW2) - { - int nb(*work2++); - for(int i=0;iselectByTupleIdSafe(nr->begin(),nr->end())); -} - - -void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) -{ - int nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1 - MEDMeshMultiLev::appendVertices(verticesToAdd,nr); - MEDCouplingAutoRefCountObjectPtr elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1)); - elt->allocateCells(nbOfCells); - for(int i=0;igetIJ(i,0)); - elt->insertNextCell(&pt,&pt+1); - } - if(_parts.empty()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::appendVertices : parts are empty !"); - elt->setCoords(_parts[0]->getCoords()); - MEDCouplingAutoRefCountObjectPtr elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef(); - _parts.push_back(elt2); -} - -//= - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev):MEDMeshMultiLev(m),_is_internal(true) -{ - initStdFieldOfIntegers(m); -} - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true) -{ - initStdFieldOfIntegers(m); -} - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true),_face_fam_ids(other._face_fam_ids),_face_num_ids(other._face_num_ids) -{ -} - -void MEDStructuredMeshMultiLev::initStdFieldOfIntegers(const MEDFileStructuredMesh *m) -{ - // ids fields management - const DataArrayInt *tmp(0); - tmp=m->getFamilyFieldAtLevel(0); - if(tmp) - { - tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(0); - if(tmp) - { - tmp->incrRef(); - _cell_num_ids=const_cast(tmp); - } - // - tmp=0; - tmp=m->getFamilyFieldAtLevel(1); - if(tmp) - { - tmp->incrRef(); - _node_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(1); - if(tmp) - { - tmp->incrRef(); - _node_num_ids=const_cast(tmp); - } - // faces (if any) - tmp=m->getFamilyFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _face_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _face_num_ids=const_cast(tmp); - } -} - -void MEDStructuredMeshMultiLev::moveFaceToCell() const -{ - const_cast(this)->_cell_fam_ids=_face_fam_ids; const_cast(this)->_face_fam_ids=0; - const_cast(this)->_cell_num_ids=_face_num_ids; const_cast(this)->_face_num_ids=0; -} - -bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const -{ - ret=0; - if(_geo_types.empty()) - return false; - if(_geo_types.size()!=1) - throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase only one geo types supported at most supported for the moment !"); - INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(_mesh->getMeshDimension())); - if(_geo_types[0]==gt) - return false; - MEDCoupling1GTUMesh *facesIfPresent((static_cast(_mesh))->getImplicitFaceMesh()); - if(!facesIfPresent) - return false; - const DataArrayInt *pfl(0),*nr(_node_reduction); - if(!_pfls.empty()) - pfl=_pfls[0]; - MEDCouplingAutoRefCountObjectPtr facesIfPresent2(facesIfPresent); facesIfPresent->incrRef(); - moveFaceToCell(); - MEDCouplingAutoRefCountObjectPtr ret2(new MEDUMeshMultiLev(*this,facesIfPresent2)); - if(pfl) - ret2->setCellReduction(pfl); - if(nr) - throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for node reduction on implicit unstructured mesh."); - ret=ret2.retn(); - return true; -} - -void MEDStructuredMeshMultiLev::dealWithImplicitUnstructuredMesh(const MEDFileMesh *m) -{ - const DataArrayInt *tmp(0); - tmp=m->getFamilyFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _cell_num_ids=const_cast(tmp); - } -} - -void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) -{ - if(!pflNodes || !pflNodes->isAllocated()) - return ; - std::vector ngs(getNodeGridStructure()); - MEDCouplingAutoRefCountObjectPtr conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); - MEDCouplingAutoRefCountObjectPtr m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size()))); - m->setNodalConnectivity(conn); - const DataArrayInt *pfl(_pfls[0]); - if(pfl) - { - m=dynamic_cast(m->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - } - DataArrayInt *cellIds=0; - m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; - _node_reduction=m2->getNodeIdsInUse(tmp); - if(pfl) - _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - else - _pfls[0]=cellIdsSafe; -} - -//= - -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) -{ - return new MEDCMeshMultiLev(m,levs); -} - -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); -} - -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs):MEDStructuredMeshMultiLev(m,levs) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : null input pointer !"); - if(levs.size()!=1 || levs[0]!=0) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : levels supported is 0 only !"); - int sdim(m->getSpaceDimension()); - _coords.resize(sdim); - for(int i=0;i(m->getMesh()->getCoordsAt(i))); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); - elt->incrRef(); - _coords[i]=elt; - } -} - -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !"); - if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - int mdim(m->getMeshDimension()); - INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim)); - if(gt==gts[0]) - { - _coords.resize(mdim); - for(int i=0;i(m->getMesh()->getCoordsAt(i))); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); - _coords[i]=elt; _coords[i]->incrRef(); - } - } - else - dealWithImplicitUnstructuredMesh(m); -} - -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords) -{ -} - -std::vector MEDCMeshMultiLev::getNodeGridStructure() const -{ - std::vector ret(_coords.size()); - for(std::size_t i=0;i<_coords.size();i++) - ret[i]=_coords[i]->getNumberOfTuples(); - return ret; -} - -MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const -{ - MEDMeshMultiLev *retSpecific(0); - if(prepareForImplicitUnstructuredMeshCase(retSpecific)) - return retSpecific; - const DataArrayInt *pfl(0),*nr(_node_reduction); - if(!_pfls.empty()) - pfl=_pfls[0]; - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); - cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); - if(pfl) - { - std::vector< std::pair > cellParts; - MEDCouplingAutoRefCountObjectPtr ret2; - if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); - ret->_is_internal=false; - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret->_nb_entities[0]=pfl->getNumberOfTuples(); - ret->_pfls[0]=0; - std::vector< MEDCouplingAutoRefCountObjectPtr > coords(_coords.size()); - for(std::size_t i=0;i<_coords.size();i++) - coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); - ret->_coords=coords; - ret2=(MEDCMeshMultiLev *)ret; ret2->incrRef(); - } - else - { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCMesh::New()); - for(std::size_t i=0;isetCoordsAt(i,_coords[i]); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); - if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); - } - const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); - if(famIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setFamilyIdsOnCells(tmp); - } - if(numIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setNumberIdsOnCells(tmp); - } - return ret2.retn(); - - } - else - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); - } -} - -/*! - * \a param [out] isInternal if true the returned pointers are those in main data structure. If false those pointers have been built espacially for that method. - */ -std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays(bool& isInternal) const -{ - isInternal=_is_internal; - std::size_t sz(_coords.size()); - std::vector< DataArrayDouble * > ret(sz); - for(std::size_t i=0;i((const DataArrayDouble *)_coords[i]); - ret[i]->incrRef(); - } - return ret; -} - -//= - -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& levs) -{ - return new MEDCurveLinearMeshMultiLev(m,levs); -} - -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); -} - -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs):MEDStructuredMeshMultiLev(m,levs) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); - if(levs.size()!=1 || levs[0]!=0) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !"); - DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); - coords->incrRef(); - _coords=coords; - _structure=m->getMesh()->getNodeGridStructure(); -} - -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !"); - if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - if(gt==gts[0]) - { - DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); - coords->incrRef(); - _coords=coords; - _structure=m->getMesh()->getNodeGridStructure(); - } - else - dealWithImplicitUnstructuredMesh(m); -} - -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) -{ -} - -std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const -{ - return _structure; -} - -MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const -{ - MEDMeshMultiLev *retSpecific(0); - if(prepareForImplicitUnstructuredMeshCase(retSpecific)) - return retSpecific; - const DataArrayInt *pfl(0),*nr(_node_reduction); - if(!_pfls.empty()) - pfl=_pfls[0]; - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); - cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); - if(pfl) - { - std::vector< std::pair > cellParts,nodeParts; - MEDCouplingAutoRefCountObjectPtr ret2; - if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) - { - nodeParts=cellParts; - std::vector st(ngs.size()); - for(std::size_t i=0;i p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); - ret->_is_internal=false; - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret->_nb_entities[0]=pfl->getNumberOfTuples(); - ret->_pfls[0]=0; - ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); - ret->_structure=st; - ret2=(MEDCurveLinearMeshMultiLev *)ret; ret2->incrRef(); - } - else - { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCurveLinearMesh::New()); - m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size()); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); - if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); - } - const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); - if(famIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setFamilyIdsOnCells(tmp); - } - if(numIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setNumberIdsOnCells(tmp); - } - return ret2.retn(); - } - else - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); - } -} - -void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const -{ - isInternal=_is_internal; - nodeStrct=_structure; - const DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev::buildVTUArrays : null pointer on coordinates !"); - coords=const_cast(coo); coords->incrRef(); -} - -//= - -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() -{ -} - -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1) -{ - _pfl->setName(c.c_str()); -} - -void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - if(!mst->doesManageGeoType(_geo_type)) - { - MEDFileMeshStruct *mstUnConstCasted(const_cast(mst)); - mstUnConstCasted->appendIfImplicitType(_geo_type); - } - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - checkInRange(nbOfEnt,1,globs); -} - -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); -} - -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - if(!globs) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !"); - if(_loc.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !"); - const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str()); - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); -} - -int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const -{ - if(_loc.empty()) - { - if(getPflName().empty()) - return (_start_end.second-_start_end.first)/_nb_of_entity; - else - return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); - } - else - { - const MEDFileFieldLoc& loc(globs->getLocalization(_loc.c_str())); - return loc.getNumberOfGaussPoints(); - } -} - -std::string MEDFileField1TSStructItem2::getPflName() const -{ - return _pfl->getName(); -} - -const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const -{ - if(!_pfl->isAllocated()) - { - if(_pfl->getName().empty()) - return 0; - else - return globs->getProfile(_pfl->getName().c_str()); - } - else - return _pfl; -} - -/*! - * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. - * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES - */ -void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) -{ - _nb_of_entity=nbOfEntity; - if(_pfl->getName().empty()) - { - if(nbOfEntity!=(_start_end.second-_start_end.first)/nip) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of field !"); - return ; - } - else - { - if(!globs) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !"); - const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str()); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !"); - pfl->checkAllIdsInRange(0,nbOfEntity); - } -} - -bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const -{ - if(startExp!=_start_end.first) - return false; - if(gt!=_geo_type) - return false; - if(getPflName()!=pflName) - return false; - startExp=_start_end.second; - return true; -} - -bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const -{ - //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare. - //idem for _loc. It is not an effective attribute for support comparison. - return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); -} - -bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const -{ - if(_geo_type!=other._geo_type) - return false; - if(_nb_of_entity!=other._nb_of_entity) - return false; - if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty())) - return false; - if(_pfl->getName().empty() && other._pfl->getName().empty()) - return true; - const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); - return pfl1->isEqualWithoutConsideringStr(*pfl2); -} - -bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const -{ - return isCellSupportEqual(other,globs); -} - -/*! - * \a objs must be non empty. \a objs should contain items having same geometric type. - */ -MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs) -{ - if(objs.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !"); - if(objs.size()==1) - return MEDFileField1TSStructItem2(*objs[0]); - INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type); - int nbEntityRef(objs[0]->_nb_of_entity); - std::size_t sz(objs.size()); - std::vector arrs(sz); - for(std::size_t i=0;i_geo_type) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !"); - if(nbEntityRef!=obj->_nb_of_entity) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !"); - if(obj->_pfl->getName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !"); - arrs[i]=globs->getProfile(obj->_pfl->getName().c_str()); - } - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::Aggregate(arrs)); - arr->sort(); - int oldNbTuples(arr->getNumberOfTuples()); - arr=arr->buildUnique(); - if(oldNbTuples!=arr->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !"); - if(arr->isIdentity() && oldNbTuples==nbEntityRef) - { - std::pair p(0,nbEntityRef); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - return ret; - } - else - { - arr->setName(NEWLY_CREATED_PFL_NAME); - std::pair p(0,oldNbTuples); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - ret._pfl=arr; - return ret; - } -} - -std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_loc.capacity()); - return ret; -} - -std::vector MEDFileField1TSStructItem2::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const DataArrayInt *)_pfl); - return ret; -} - -//= - -MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b) -{ -} - -void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - switch(_type) - { - case ON_NODES: - { - int nbOfEnt=mst->getNumberOfNodes(); - if(_items.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !"); - _items[0].checkInRange(nbOfEnt,1,globs); - break ; - } - case ON_CELLS: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForCells(mst,globs); - break; - } - case ON_GAUSS_NE: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForGaussNE(mst,globs); - break; - } - case ON_GAUSS_PT: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForGaussPT(mst,globs); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); - } -} - -bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const -{ - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i]==other._items[i])) - return false; - return true; -} - -bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const -{ - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isCellSupportEqual(other._items[i],globs))) - return false; - return true; -} - -bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const -{ - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isNodeSupportEqual(other._items[i],globs))) - return false; - return true; -} - -bool MEDFileField1TSStructItem::isEntityCell() const -{ - if(_type==ON_NODES) - return false; - else - return true; -} - -class CmpGeo -{ -public: - CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { } - bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > & v) const { return _geo_type==v.first; } -private: - INTERP_KERNEL::NormalizedCellType _geo_type; -}; - -MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const -{ - if(!isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !"); - std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > > m; - std::size_t i=0; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) - { - std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo()))); - if(it0==m.end()) - m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector >((*it).getGeo(),std::vector(1,i))); - else - (*it0).second.push_back(i); - } - if(m.size()==_items.size()) - { - MEDFileField1TSStructItem ret(*this); - ret._type=ON_CELLS; - return ret; - } - std::size_t sz(m.size()); - std::vector< MEDFileField1TSStructItem2 > items(sz); - for(i=0;i& ids=m[i].second; - std::vectorobjs(ids.size()); - for(std::size_t j=0;jgetNumberOfNodes()); - if(otherNodeIt.getPflName().empty()) - {//on all nodes - if(!ret0) - return false; - std::vector nodesFetched(nbOfNodes,false); - meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); - if(std::find(nodesFetched.begin(),nodesFetched.end(),false)==nodesFetched.end()) - return theFirstLevFull==0; - else - return false; - } - else - { - const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str()); - MEDCouplingAutoRefCountObjectPtr cpyPfl(pfl->deepCpy()); - cpyPfl->sort(); - if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes) - {//on all nodes also ! - if(!ret0) - return false; - return theFirstLevFull==0; - } - std::vector nodesFetched(nbOfNodes,false); - meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); - return cpyPfl->isFittingWith(nodesFetched); - } -} - -bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const -{ - if(_type!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !"); - if(_items.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !"); - int nbOfLevs(meshSt->getNumberOfLevs()); - if(nbOfLevs==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); - std::vector levs(nbOfLevs); - theFirstLevFull=1; - std::set gts; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - { - if(!(*it).getPflName().empty()) - return false; - INTERP_KERNEL::NormalizedCellType gt((*it).getGeo()); - if(gts.find(gt)!=gts.end()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !"); - gts.insert(gt); - int pos(meshSt->getLevelOfGeoType((*it).getGeo())); - levs[-pos]++; - } - for(int i=0;igetNumberOfGeoTypesInLev(-i)==levs[i]) - { theFirstLevFull=-i; return true; } - return false; -} - -const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const -{ - if(i>=_items.size()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); - return _items[i]; -} - -std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_items.size()*sizeof(MEDFileField1TSStructItem2)); - return ret; -} - -std::vector MEDFileField1TSStructItem::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - ret.push_back(&(*it)); - return ret; -} - -MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const -{ - std::size_t sz(_items.size()); - std::vector a0(sz); - std::vector a1(sz); - std::vector a2(sz); - std::size_t i(0); - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) - { - a0[i]=(*it).getGeo(); - a1[i]=(*it).getPfl(globs); - a2[i]=mst->getNumberOfElemsOfGeoType((*it).getGeo()); - } - return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); -} - -std::vector MEDFileField1TSStructItem::getGeoTypes(const MEDFileMesh *m) const -{ - std::vector ret; - if(_type==ON_NODES) - { - if(!_items.empty() && _items[0].getPflName().empty()) - { - if(m) - return m->getAllGeoTypes(); - else - return ret; - } - else - return ret; - } - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - { - INTERP_KERNEL::NormalizedCellType elt((*it).getGeo()); - std::vector::iterator it2(std::find(ret.begin(),ret.end(),elt)); - if(it2==ret.end()) - ret.push_back(elt); - } - return ret; -} - -MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) -{ - std::vector< MEDFileField1TSStructItem2 > anItems; - // - std::vector< std::vector > pfls,locs; - std::vector< std::vector > typesF; - std::vector geoTypes; - std::vector< std::vector > > strtEnds=ref->getFieldSplitedByType(std::string(),geoTypes,typesF,pfls,locs); - std::size_t nbOfGeoTypes(geoTypes.size()); - if(nbOfGeoTypes==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); - if(typesF[0].empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 bis !"); - TypeOfField atype(typesF[0][0]); - for(std::size_t i=0;i::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - { - if((*it)==b) - return true; - } - return false; -} - -/*! - * Not const because \a other structure will be added to the \c _already_checked attribute in case of success. - */ -bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !"); - MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); - if(!_already_checked[0].isEntityCell() || !b.isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !"); - MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other)); - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) - { - MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); - ret=this1.isCellSupportEqual(other1,other); - if(ret) - _already_checked.push_back(this1); - } - else - ret=_already_checked[found].isCellSupportEqual(other1,other); - if(ret) - _already_checked.push_back(b); - return ret; -} - -/*! - * \param [in] other - a field with only one spatial discretization : ON_NODES. - */ -bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); - MEDFileField1TSStructItem other1(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); - if(_already_checked[0].isEntityCell()) - { - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) - { - MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); - ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other); - if(ret) - _already_checked.push_back(this1); - } - else - ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other); - if(ret) - _already_checked.push_back(other1); - return ret; - } - else - return _already_checked[0].isNodeSupportEqual(other1,other); -} - -std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_already_checked.capacity()*sizeof(MEDFileField1TSStructItem)); - return ret; -} - -std::vector MEDFileField1TSStruct::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - ret.push_back(&(*it)); - return ret; -} - -MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::buildFromScratchDataSetSupport : No outline structure in this !"); - int pos0(-1),pos1(-1); - if(presenceOfCellDiscr(pos0)) - { - MEDCouplingAutoRefCountObjectPtr ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); - if(presenceOfPartialNodeDiscr(pos1)) - ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); - return ret.retn(); - } - else - { - if(!presenceOfPartialNodeDiscr(pos1)) - {//we have only all nodes, no cell definition info -> all existing levels !; - return MEDMeshMultiLev::New(mst->getTheMesh(),mst->getTheMesh()->getNonEmptyLevels()); - } - else - return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); - } -} - -bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const -{ - int b0,b1; - bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); - int d0,d1; - bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); - if(a0!=c0 || a1!=c1) - return false; - if(a0) - if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs)) - return false; - if(a1) - if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs)) - return false; - return true; -} - -std::vector MEDFileField1TSStruct::getGeoTypes(const MEDFileMesh *m) const -{ - std::vector ret; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - { - std::vector ret2((*it).getGeoTypes(m)); - for(std::vector::const_iterator it2=ret2.begin();it2!=ret2.end();it2++) - { - if(*it2==INTERP_KERNEL::NORM_ERROR) - continue; - std::vector::iterator it3(std::find(ret.begin(),ret.end(),*it2)); - if(it3==ret.end()) - ret.push_back(*it2); - } - } - return ret; -} - -/*! - * Returns true if presence in \a this of discretization ON_CELLS, ON_GAUSS_PT, ON_GAUSS_NE. - * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less splitted subparts. - */ -bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const -{ - std::size_t refSz(std::numeric_limits::max()); - bool ret(false); - int i(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - { - if((*it).getType()!=ON_NODES) - { - ret=true; - std::size_t sz((*it).getNumberOfItems()); - if(refSz>sz) - { pos=i; refSz=sz; } - } - } - if(refSz==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !"); - return ret; -} - -/*! - * Returns true if presence in \a this of discretization ON_NODES. - * If true is returned the pos of the first element containing the single subpart. - */ -bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const -{ - int i(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - { - if((*it).getType()==ON_NODES) - { - std::size_t sz((*it).getNumberOfItems()); - if(sz==1) - { - if(!(*it)[0].getPflName().empty()) - { pos=i; return true; } - } - else - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfPartialNodeDiscr : an element in this on entity NODE is split into several parts !"); - } - } - return false; -} - -//= - -MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) -{ - return new MEDFileFastCellSupportComparator(m,ref); -} - -MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !"); - _mesh_comp=const_cast(m); _mesh_comp->incrRef(); - int nbPts=ref->getNumberOfTS(); - _f1ts_cmps.resize(nbPts); - for(int i=0;i elt=ref->getTimeStepAtPos(i); - try - { - _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); - _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream oss; oss << "Problem in field with name \"" << ref->getName() << "\"" << std::endl; - oss << "More Details : " << e.what(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; -} - -std::vector MEDFileFastCellSupportComparator::getDirectChildrenWithNull() const -{ - std::vector ret; - const MEDFileMeshStruct *mst(_mesh_comp); - if(mst) - ret.push_back(mst); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) - ret.push_back((const MEDFileField1TSStruct *)*it); - return ret; -} - -bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) -{ - int nbPts=other->getNumberOfTS(); - if(nbPts!=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) - if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) - return false; - } - return true; -} - -bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) -{ - int nbPts=other->getNumberOfTS(); - if(nbPts!=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp)) - return false; - } - return true; -} - -MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const -{ - if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); - if(!obj) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); -} - -bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const -{ - if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); - const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); - return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); -} - -int MEDFileFastCellSupportComparator::getNumberOfTS() const -{ - return _f1ts_cmps.size(); -} - -std::vector MEDFileFastCellSupportComparator::getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const -{ - if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *elt(_f1ts_cmps[timeStepId]); - if(!elt) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " points to a NULL pointer !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return elt->getGeoTypes(m); -} diff --git a/medtool/src/MEDLoader/MEDFileFieldOverView.hxx b/medtool/src/MEDLoader/MEDFileFieldOverView.hxx deleted file mode 100644 index 25384f4bd..000000000 --- a/medtool/src/MEDLoader/MEDFileFieldOverView.hxx +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEFIELDOVERVIEW_HXX__ -#define __MEDFILEFIELDOVERVIEW_HXX__ - -#include "MEDLoaderDefines.hxx" - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCoupling1GTUMesh.hxx" - -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class MEDCouplingMesh; - class MEDFileMesh; - class MEDFileUMesh; - class MEDFileCMesh; - class MEDFileStructuredMesh; - class MEDFileCurveLinearMesh; - class MEDFileFieldGlobs; - class MEDFileFieldGlobsReal; - class MEDFileAnyTypeField1TS; - class MEDFileAnyTypeFieldMultiTS; - - class MEDFileMeshStruct : public RefCountObject - { - public: - MEDLOADER_EXPORT static MEDFileMeshStruct *New(const MEDFileMesh *mesh); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - const MEDFileMesh *getTheMesh() const { return _mesh; } - int getNumberOfNodes() const { return _nb_nodes; } - bool doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const; - int getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const; - int getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const; - int getNumberOfLevs() const; - int getNumberOfGeoTypesInLev(int relativeLev) const; - // non const methods - void appendIfImplicitType(INTERP_KERNEL::NormalizedCellType t); - private: - MEDFileMeshStruct(const MEDFileMesh *mesh); - private: - const MEDFileMesh *_mesh; - std::string _name; - int _nb_nodes; - std::vector< std::vector > _geo_types_distrib; - }; - - class MEDFileField1TSStructItem; - - class MEDMeshMultiLev : public RefCountObject - { - public: - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - public: - static MEDMeshMultiLev *New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - static MEDMeshMultiLev *New(const MEDFileMesh *m, const std::vector& levs); - static MEDMeshMultiLev *NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode); - void setNodeReduction(const DataArrayInt *nr); - void setCellReduction(const DataArrayInt *cr); - bool isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const; - MEDLOADER_EXPORT void retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT void retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT void retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT void retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT std::vector< INTERP_KERNEL::NormalizedCellType > getGeoTypes() const; - void setFamilyIdsOnCells(DataArrayInt *famIds); - void setNumberIdsOnCells(DataArrayInt *numIds); - void setFamilyIdsOnNodes(DataArrayInt *famIds); - void setNumberIdsOnNodes(DataArrayInt *numIds); - virtual void selectPartOfNodes(const DataArrayInt *pflNodes) = 0; - virtual MEDMeshMultiLev *prepare() const = 0; - int getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const; - int getNumberOfNodes() const; - protected: - std::string getPflNameOfId(int id) const; - DataArray *constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const; - virtual void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr); - protected: - MEDMeshMultiLev(const MEDFileMesh *mesh); - MEDMeshMultiLev(const MEDMeshMultiLev& other); - MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - protected: - const MEDFileMesh *_mesh; - std::vector< MEDCouplingAutoRefCountObjectPtr > _pfls; - std::vector< INTERP_KERNEL::NormalizedCellType > _geo_types; - std::vector _nb_entities; - MEDCouplingAutoRefCountObjectPtr _node_reduction; - int _nb_nodes; - // - MEDCouplingAutoRefCountObjectPtr _cell_fam_ids; - MEDCouplingAutoRefCountObjectPtr _cell_num_ids; - MEDCouplingAutoRefCountObjectPtr _node_fam_ids; - MEDCouplingAutoRefCountObjectPtr _node_num_ids; - public: - MEDLOADER_EXPORT static const int PARAMEDMEM_2_VTKTYPE_LGTH=34; - MEDLOADER_EXPORT static const unsigned char PARAMEDMEM_2_VTKTYPE[PARAMEDMEM_2_VTKTYPE_LGTH]; - MEDLOADER_EXPORT static const unsigned char HEXA27_PERM_ARRAY[27]; - }; - - class MEDStructuredMeshMultiLev; - - class MEDUMeshMultiLev : public MEDMeshMultiLev - { - public: - static MEDUMeshMultiLev *New(const MEDFileUMesh *m, const std::vector& levs); - static MEDUMeshMultiLev *New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - void selectPartOfNodes(const DataArrayInt *pflNodes); - MEDMeshMultiLev *prepare() const; - MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part); - MEDLOADER_EXPORT bool buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const; - protected: - void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr); - private: - void reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const; - private: - MEDUMeshMultiLev(const MEDUMeshMultiLev& other); - MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs); - MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _parts; - //! this attribute is used only for mesh with no cells but having coordinates. For classical umeshes those pointer is equal to pointer of coordinates of instances in this->_parts. - MEDCouplingAutoRefCountObjectPtr _coords; - }; - - class MEDStructuredMeshMultiLev : public MEDMeshMultiLev - { - public: - void selectPartOfNodes(const DataArrayInt *pflNodes); - virtual std::vector getNodeGridStructure() const = 0; - protected: - MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other); - MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev); - MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - void dealWithImplicitUnstructuredMesh(const MEDFileMesh *m); - protected: - void moveFaceToCell() const; - bool prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const; - private: - void initStdFieldOfIntegers(const MEDFileStructuredMesh *m); - protected: - bool _is_internal; - MEDCouplingAutoRefCountObjectPtr _face_fam_ids; - MEDCouplingAutoRefCountObjectPtr _face_num_ids; - }; - - class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev - { - public: - static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector& levs); - static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - std::vector getNodeGridStructure() const; - MEDMeshMultiLev *prepare() const; - MEDLOADER_EXPORT std::vector< DataArrayDouble * > buildVTUArrays(bool& isInternal) const; - private: - MEDCMeshMultiLev(const MEDCMeshMultiLev& other); - MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs); - MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _coords; - }; - - class MEDCurveLinearMeshMultiLev : public MEDStructuredMeshMultiLev - { - public: - static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector& levs); - static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls , const std::vector& nbEntities); - std::vector getNodeGridStructure() const; - MEDMeshMultiLev *prepare() const; - MEDLOADER_EXPORT void buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const; - private: - MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other); - MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs); - MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - private: - MEDCouplingAutoRefCountObjectPtr _coords; - std::vector _structure; - }; - - class MEDFileField1TSStructItem2 : public BigMemoryObject - { - public: - MEDFileField1TSStructItem2(); - MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& pfl, const std::string& loc); - void checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - void checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - void checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - // - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - // - const DataArrayInt *getPfl(const MEDFileFieldGlobsReal *globs) const; - INTERP_KERNEL::NormalizedCellType getGeo() const { return _geo_type; } - int getNbEntity() const { return _nb_of_entity; } - const std::pair& getStartStop() const { return _start_end; } - std::string getPflName() const; - int getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const; - //! warning this method also set _nb_of_entity attribute ! - void checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs); - bool isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const; - bool operator==(const MEDFileField1TSStructItem2& other) const; - bool isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const; - bool isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const; - static MEDFileField1TSStructItem2 BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs); - public: - static const char NEWLY_CREATED_PFL_NAME[]; - private: - INTERP_KERNEL::NormalizedCellType _geo_type; - std::pair _start_end; - MEDCouplingAutoRefCountObjectPtr _pfl; - std::string _loc; - int _nb_of_entity; - }; - - class MEDFileField1TSStructItem : public BigMemoryObject - { - public: - MEDFileField1TSStructItem():_computed(false),_type(ON_CELLS) { } - MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b); - void checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - bool operator==(const MEDFileField1TSStructItem& other) const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - bool isEntityCell() const; - bool isComputed() const { return _computed; } - TypeOfField getType() const { return _type; } - std::size_t getNumberOfItems() const { return _items.size(); } - const MEDFileField1TSStructItem2& operator[](std::size_t i) const; - // - bool isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const; - bool isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const; - MEDFileField1TSStructItem simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const; - bool isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const; - bool isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const; - std::vector getGeoTypes(const MEDFileMesh *m) const; - MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt); - private: - bool _computed; - TypeOfField _type; - std::vector< MEDFileField1TSStructItem2 > _items; - }; - - class MEDFileField1TSStruct : public RefCountObject - { - public: - static MEDFileField1TSStruct *New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); - void checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - bool isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const; - bool isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt); - bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt); - MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const; - bool isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const; - std::vector getGeoTypes(const MEDFileMesh *m) const; - private: - MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); - bool presenceOfCellDiscr(int& pos) const; - bool presenceOfPartialNodeDiscr(int& pos) const; - private: - std::vector _already_checked; - }; - - class MEDFileFastCellSupportComparator : public RefCountObject - { - public: - MEDLOADER_EXPORT static MEDFileFastCellSupportComparator *New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref); - MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT bool isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT std::vector getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const; - bool isEqual(const MEDFileAnyTypeFieldMultiTS *other); - bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - private: - MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref); - private: - MEDCouplingAutoRefCountObjectPtr _mesh_comp; - std::vector< MEDCouplingAutoRefCountObjectPtr > _f1ts_cmps; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileJoint.cxx b/medtool/src/MEDLoader/MEDFileJoint.cxx deleted file mode 100644 index 2db32825a..000000000 --- a/medtool/src/MEDLoader/MEDFileJoint.cxx +++ /dev/null @@ -1,839 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDFileJoint.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileSafeCaller.txx" - -#include "CellModel.hxx" -#include "InterpKernelAutoPtr.hxx" - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -std::size_t MEDFileJointCorrespondence::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileJointCorrespondence::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileJointCorrespondence::MEDFileJointCorrespondence(): - _is_nodal( true ), - _loc_geo_type( INTERP_KERNEL::NORM_ERROR ), - _rem_geo_type( INTERP_KERNEL::NORM_ERROR ) -{ -} - -/*! - * Constructor. - * \param [in] correspondence - correspondence. - * \param [in] is_nodal - is the correspondence of cells or nodes. - * \param [in] loc_geo_type - the local geometry type of correspondence. - * \param [in] rem_geo_type - the remote geometry type of correspondence. - */ -MEDFileJointCorrespondence::MEDFileJointCorrespondence(DataArrayInt* correspondence, - bool isNodal, - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type): - _is_nodal( isNodal ), - _loc_geo_type( loc_geo_type ), - _rem_geo_type( rem_geo_type ) -{ - MEDFileJointCorrespondence::setCorrespondence( correspondence ); -} - -MEDFileJointCorrespondence* MEDFileJointCorrespondence::New(DataArrayInt* correspondence, - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type) -{ - return new MEDFileJointCorrespondence(correspondence, /*isNodal=*/false, loc_geo_type, rem_geo_type ); -} - -/*! - * Returns a new MEDFileJointCorrespondence of nodes - */ -MEDFileJointCorrespondence *MEDFileJointCorrespondence::New(DataArrayInt* correspondence) -{ - return new MEDFileJointCorrespondence(correspondence); -} - -/*! - * Returns a new undefined MEDFileJointCorrespondence - */ - -MEDFileJointCorrespondence *MEDFileJointCorrespondence::New() -{ - return new MEDFileJointCorrespondence(); -} - -/*! - * Writes \a this joint into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \param [in] order - order. - * \param [in] iteration - iteration. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileJointCorrespondence::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - - std::ostringstream oss; oss << "MEDFileJointCorrespondence : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - - if (( !_is_nodal ) && - ( _loc_geo_type == INTERP_KERNEL::NORM_ERROR || - _rem_geo_type == INTERP_KERNEL::NORM_ERROR )) - { - throw INTERP_KERNEL::Exception( "Geometric type not specified for a cell Joint" ); - } - - if ( (const DataArrayInt *)_correspondence ) - { - writeLL(fid, localMeshName, jointName, order, iteration); - } - else - { - throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::write : correspondence array not defined"); - } -} - -void MEDFileJointCorrespondence::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const -{ - if ( _is_nodal ) - { - MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(), - order, iteration, - MED_NODE, MED_NONE, - MED_NODE, MED_NONE, - _correspondence->getNbOfElems()/2, - _correspondence->getConstPointer())); - } - else - { - MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(), - order, iteration, - MED_CELL, typmai3[ _loc_geo_type ], - MED_CELL, typmai3[ _rem_geo_type ], - _correspondence->getNbOfElems()/2, - _correspondence->getConstPointer())); - } -} - -void MEDFileJointCorrespondence::setCorrespondence(DataArrayInt *corr) -{ - _correspondence=corr; - if ( corr ) - corr->incrRef(); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileJointCorrespondence::isEqual(const MEDFileJointCorrespondence *other) const -{ - if(_is_nodal!=other->_is_nodal) - return false; - if(_loc_geo_type!=other->_loc_geo_type) - return false; - if(_rem_geo_type!=other->_rem_geo_type) - return false; - if(!_correspondence->isEqual(*other->_correspondence)) - return false; - return true; -} - -MEDFileJointCorrespondence *MEDFileJointCorrespondence::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJointCorrespondence(*this); - return ret.retn(); -} - -MEDFileJointCorrespondence *MEDFileJointCorrespondence::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJointCorrespondence(*this); - return ret.retn(); -} - -/*! - * Returns a string describing \a this mesh. This description includes the correspondence and - * the number correspondence. - * \return std::string - the joint information string. - */ -std::string MEDFileJointCorrespondence::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* JOINT_CORRESPOND INFORMATION: *)\n(*************************************)\n"; - oss << "- entity type of the correspondence : " << ( getIsNodal() ? "NODE" : "CELL" ) << "\n"; - oss << "- Local geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _loc_geo_type ).getRepr() << "\n"; - oss << "- Remote geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _rem_geo_type ).getRepr() << "\n"; - if ( (const DataArrayInt *)_correspondence ) - { - oss << "- Number entity of the correspondence : " << getCorrespondence()->getNumberOfTuples() << "\n"; - - const DataArrayInt* tmp=getCorrespondence(); - oss << "- Correspondence : <<"; - for(const int *it=tmp->begin();it!=tmp->end();it++) - oss<< *it << " "; - } - else - { - oss << "- Number entity of the correspondence : 0\n"; - } - oss << std::endl; - return oss.str(); -} - - -MEDFileJointOneStep::MEDFileJointOneStep():_order(-1),_iteration(-1) -{ -} - -std::size_t MEDFileJointOneStep::getHeapMemorySizeWithoutChildren() const -{ - return _correspondences.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileJointOneStep::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileJointOneStep *MEDFileJointOneStep::New(int dt, int it) -{ - MEDFileJointOneStep* j = new MEDFileJointOneStep(); - j->setOrder( dt ); - j->setIteration( it ); - return j; -} - -/*! - * Returns a new MEDFileJointOneStep. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] jointName - the joint name. - * \param [in] num - the number of an iteration. - * \return MEDFileMesh * - a new instance of MEDFileJointOneStep. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - */ -MEDFileJointOneStep *MEDFileJointOneStep::New(const std::string& fileName, const std::string& mName, const std::string& jointName, int num) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); - return new MEDFileJointOneStep(fid, mName, jointName, num); -} - -MEDFileJointOneStep* MEDFileJointOneStep::New(med_idt fid, const std::string& mName, const std::string& jointName, int num) -{ - return new MEDFileJointOneStep( fid, mName, jointName, num); -} - -MEDFileJointOneStep::MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int num) -{ - int order, iteration, ncorrespondence; - MEDFILESAFECALLERRD0(MEDsubdomainComputingStepInfo,(fid, mName.c_str(), jointName.c_str(), num, &order, &iteration, &ncorrespondence)); - MEDFileJointOneStep::setOrder(order); - MEDFileJointOneStep::setIteration(iteration); - for ( int cur_it = 1; cur_it <= ncorrespondence; ++cur_it ) - { - int num_entity; - med_entity_type loc_ent_type, rem_ent_type; - med_geometry_type loc_geo_type, rem_geo_type; - MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceSizeInfo,(fid, mName.c_str(), jointName.c_str(), order, iteration, cur_it, - &loc_ent_type, &loc_geo_type, &rem_ent_type, &rem_geo_type, &num_entity)); - if ( num_entity > 0 ) - { - MEDCouplingAutoRefCountObjectPtr correspondence=DataArrayInt::New(); - correspondence->alloc(num_entity*2, 1); - MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceRd,(fid, mName.c_str(), jointName.c_str(), order, iteration, loc_ent_type, - loc_geo_type, rem_ent_type, rem_geo_type, correspondence->getPointer())); - MEDFileJointCorrespondence *cor=MEDFileJointCorrespondence::New(); - cor->setIsNodal( loc_ent_type == MED_NODE ); - cor->setLocalGeometryType ( convertGeometryType( loc_geo_type )); - cor->setRemoteGeometryType( convertGeometryType( rem_geo_type )); - cor->setCorrespondence( correspondence ); - _correspondences.push_back(cor); - } - } -} - -/*! - * Writes \a this joint into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileJointOneStep::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileJointOneStep : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - if ( _correspondences.empty() ) - throw INTERP_KERNEL::Exception("MEDFileJointOneStep::write : no correspondences defined !"); - writeLL(fid, localMeshName, jointName); -} - -void MEDFileJointOneStep::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++) - { - (*it)->writeLL(fid, localMeshName, jointName, getOrder(), getIteration()); - } -} - -void MEDFileJointOneStep::pushCorrespondence(MEDFileJointCorrespondence* correspondence) -{ - if(!correspondence) - throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::pushCorrespondence : invalid input pointer ! should be different from 0 !"); - _correspondences.push_back(correspondence); - correspondence->incrRef(); -} - -int MEDFileJointOneStep::getNumberOfCorrespondences() const -{ - return _correspondences.size(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJointCorrespondence *MEDFileJointOneStep::getCorrespondenceAtPos(int i) const -{ - if(i<0 || i>=(int)_correspondences.size()) - { - std::ostringstream oss; oss << "MEDFileJointOneStep::getCorrespondenceAtPos : invalid correspondence id given in parameter ! Should be in [0;" << _correspondences.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileJointCorrespondence* ret = _correspondences[i]; - return const_cast( ret ); -} - -/*! - * Checks if \a this and another Joint are equal. - * \param [in] other - the Joint to compare with. - * \return bool - \c true if the Joints are equal, \c false, else. - */ -bool MEDFileJointOneStep::isEqual(const MEDFileJointOneStep *other) const -{ - if(_order!=other->_order) - return false; - if(_iteration!=other->_iteration) - return false; - if ( getNumberOfCorrespondences() != other->getNumberOfCorrespondences() ) - return false; - - std::vector found( getNumberOfCorrespondences(), false ); - for(int i=0; iisEqual(other->getCorrespondenceAtPos(j))) - { - found[ j ] = true; - break; - } - } - if ( j == getNumberOfCorrespondences() ) - return false; - } - return true; -} - -MEDFileJointOneStep *MEDFileJointOneStep::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > correspondences(_correspondences.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++,i++) - if((const MEDFileJointCorrespondence *)*it) - correspondences[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret= new MEDFileJointOneStep; - ret->_correspondences=correspondences; - return ret.retn(); -} - -MEDFileJointOneStep *MEDFileJointOneStep::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJointOneStep(*this); - return ret.retn(); -} - -/*! - * Returns a string describing \a this Joint. This description includes the correspondence and - * the number of correspondences. - * \return std::string - the joint information string. - */ -std::string MEDFileJointOneStep::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* JOINT_ONE_STEP INFORMATION: *)\n(*************************************)\n"; - oss << "- Number of the correspondences : <<" << _correspondences.size() << ">>\n"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++) - { - oss << (*it)->simpleRepr(); - } - return oss.str(); -} -INTERP_KERNEL::NormalizedCellType MEDFileJointOneStep::convertGeometryType(med_geometry_type geotype) -{ - INTERP_KERNEL::NormalizedCellType result=INTERP_KERNEL::NORM_ERROR; - for(int i=0; i); -} - -std::vector MEDFileJoint::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileJoint *MEDFileJoint::New() -{ - return new MEDFileJoint(); -} - -MEDFileJoint *MEDFileJoint::New(const std::string& fileName, const std::string& mName, int curJoint) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); - return new MEDFileJoint(fid,mName,curJoint); -} - -MEDFileJoint *MEDFileJoint::New(med_idt fid, const std::string& mName, int curJoint) -{ - return new MEDFileJoint(fid,mName,curJoint); -} - -MEDFileJoint *MEDFileJoint::New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum) -{ - MEDFileJoint* j = new MEDFileJoint(); - j->setJointName( jointName ); - j->setLocalMeshName( locMeshName ); - j->setRemoteMeshName( remoteMeshName ); - j->setDomainNumber( remoteMeshNum ); - return j; -} - -MEDFileJoint::MEDFileJoint() -{ -} - -/*! - * Returns a new MEDFileJoint holding the mesh data that has been read from a given MED - * file. The Joint to load is specified by mesh name and a Joint iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] curJoint - the iteration number of current joint. - * \return MEDFileJoint * - a new instance of MEDFileJoint. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - */ -MEDFileJoint::MEDFileJoint(med_idt fid, const std::string& mName, int curJoint) -{ - INTERP_KERNEL::AutoPtr joint_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc_name=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr rem_mesh_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - int domain_number=0, nstep=0, nocstpncorrespondence=0; - MEDFILESAFECALLERRD0(MEDsubdomainJointInfo,(fid,mName.c_str(), curJoint, joint_name, desc_name, &domain_number,rem_mesh_name, - &nstep, &nocstpncorrespondence)); - setLocalMeshName(mName); - setRemoteMeshName(MEDLoaderBase::buildStringFromFortran(rem_mesh_name,MED_NAME_SIZE)); - setDescription(MEDLoaderBase::buildStringFromFortran(desc_name,MED_COMMENT_SIZE)); - setJointName(MEDLoaderBase::buildStringFromFortran(joint_name,MED_NAME_SIZE)); - setDomainNumber(domain_number); - for(int cur_step=1; cur_step <= nstep; ++cur_step) - { - MEDFileJointOneStep *cor=MEDFileJointOneStep::New(fid, mName.c_str(), getJointName(), cur_step); - _joint.push_back(cor); - } -} - -/*! - * Writes \a this joint into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileJoint::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileJoint : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -void MEDFileJoint::write(med_idt fid) const -{ - // if ( _loc_mesh_name.empty() ) - // throw INTERP_KERNEL::Exception("MEDFileJoint::write : name of a local mesh not defined!"); - MEDFILESAFECALLERWR0(MEDsubdomainJointCr,(fid,getLocalMeshName().c_str(),getJointName().c_str(),getDescription().c_str(),getDomainNumber(),getRemoteMeshName().c_str())); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joint.begin();it!=_joint.end();it++) { - (*it)->writeLL(fid, getLocalMeshName(),getJointName()); - } -} - -void MEDFileJoint::pushStep(MEDFileJointOneStep* step) -{ - if(!step) - throw INTERP_KERNEL::Exception("MEDFileJoint::pushStep : invalid input pointer ! should be different from 0 !"); - _joint.push_back(step); - step->incrRef(); -} - -int MEDFileJoint::getNumberOfSteps() const -{ - return _joint.size(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJointOneStep *MEDFileJoint::getStepAtPos(int i) const -{ - if(i<0 || i>=(int)_joint.size()) - { - std::ostringstream oss; oss << "MEDFileJoint::getStepAtPos : invalid step id given in parameter ! Should be in [0;" << _joint.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileJointOneStep* ret = _joint[i]; - return const_cast( ret ); -} - -/*! - * Checks if \a this and another Joint are equal. - * \param [in] other - the Joint to compare with. - * \return bool - \c true if the Joints are equal, \c false, else. - */ -bool MEDFileJoint::isEqual(const MEDFileJoint *other) const -{ - if(_loc_mesh_name!=other->_loc_mesh_name) - return false; - if(_joint_name!=other->_joint_name) - return false; - if(_desc_name!=other->_desc_name) - return false; - if(_rem_mesh_name!=other->_rem_mesh_name) - return false; - if(_domain_number!=other->_domain_number) - return false; - std::vector found( getNumberOfSteps(), false ); - for(int i=0; iisEqual(other->getStepAtPos(j))) - { - found[ j ] = true; - break; - } - } - if ( j == getNumberOfSteps() ) - return false; - } - return true; -} - -MEDFileJoint *MEDFileJoint::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > joint(_joint.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joint.begin();it!=_joint.end();it++,i++) - if((const MEDFileJointOneStep *)*it) - joint[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileJoint::New(); - ret->_joint=joint; - return ret.retn(); -} - -MEDFileJoint *MEDFileJoint::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJoint(*this); - return ret.retn(); -} - -bool MEDFileJoint::changeJointNames(const std::vector< std::pair >& modifTab) -{ - for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) - { - if((*it).first==_joint_name) - { - _joint_name=(*it).second; - return true; - } - } - return false; -} - -/*! - * Returns a string describing \a this mesh. This description includes the correspondence and - * the number correspondence. - * \return std::string - the joint information string. - */ -std::string MEDFileJoint::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* JOINT INFORMATION: *)\n(*************************************)\n"; - oss << "- Local Mesh name : <<" << getLocalMeshName() << ">>\n"; - oss << "- Remote Mesh name : <<" << getRemoteMeshName() << ">>\n"; - oss << "- Description : <<" << getDescription() << ">>\n"; - oss << "- Joint name : <<" << getJointName() << ">>\n"; - oss << "- Domain number : " << getDomainNumber() << "\n"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joint.begin();it!=_joint.end();it++) - { - oss << (*it)->simpleRepr(); - } - return oss.str(); -} - -MEDFileJoints *MEDFileJoints::New() -{ - return new MEDFileJoints; -} - -MEDFileJoints *MEDFileJoints::New(const std::string& fileName, const std::string& meshName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); - return new MEDFileJoints( fid, meshName ); -} - -MEDFileJoints *MEDFileJoints::New(med_idt fid, const std::string& meshName) -{ - return new MEDFileJoints( fid, meshName ); -} - -void MEDFileJoints::write(med_idt fid) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++) - { - (*it)->write(fid); - } -} - -void MEDFileJoints::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileJoints : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -std::string MEDFileJoints::getMeshName() const -{ - for ( size_t i = 0; i <= _joints.size(); ++i ) - if ( (const MEDFileJoint*) _joints[i] ) - return _joints[i]->getLocalMeshName(); - - return ""; -} - -int MEDFileJoints::getNumberOfJoints() const -{ - return _joints.size(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJoint *MEDFileJoints::getJointAtPos(int i) const -{ - if(i<0 || i>=(int)_joints.size()) - { - std::ostringstream oss; oss << "MEDFileJoints::getJointAtPos : invalid joint id given in parameter ! Should be in [0;" << _joints.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileJoint* ret = _joints[i]; - return const_cast( ret ); -} - - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJoint *MEDFileJoints::getJointWithName(const std::string& jname) const -{ - std::vector js=getJointsNames(); - std::vector::iterator it=std::find(js.begin(),js.end(),jname); - if(it==js.end()) - { - std::ostringstream oss; oss << "MEDFileJoints::getJointWithName : Joint \"" << jname << "\" does not exist in this ! Existing are : "; - std::copy(js.begin(),js.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getJointAtPos((int)std::distance(js.begin(),it)); -} - -std::vector MEDFileJoints::getJointsNames() const -{ - std::vector ret(_joints.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++) - { - const MEDFileJoint *f=(*it); - if(f) - { - ret[i]=f->getJointName(); - } - else - { - std::ostringstream oss; oss << "MEDFileJoints::getJointsNames : At rank #" << i << " joint is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -bool MEDFileJoints::changeJointNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_joints.begin();it!=_joints.end();it++) - { - MEDFileJoint *cur(*it); - if(cur) - ret=cur->changeJointNames(modifTab) || ret; - } - return ret; -} - -void MEDFileJoints::resize(int newSize) -{ - _joints.resize(newSize); -} - -void MEDFileJoints::pushJoint(MEDFileJoint *joint) -{ - if(!joint) - throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : invalid input pointer ! should be different from 0 !"); - if ( !_joints.empty() && - _joints[0]->getLocalMeshName() != joint->getLocalMeshName() ) - throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : different names of local meshes ! should be equal !"); - - _joints.push_back(joint); - joint->incrRef(); -} - -void MEDFileJoints::setJointAtPos(int i, MEDFileJoint *joint) -{ - if(!joint) - throw INTERP_KERNEL::Exception("MEDFileJoints::setJointAtPos : invalid input pointer ! should be different from 0 !"); - if(i>=(int)_joints.size()) - _joints.resize(i+1); - _joints[i]=joint; - joint->incrRef(); -} - -void MEDFileJoints::destroyJointAtPos(int i) -{ - if(i<0 || i>=(int)_joints.size()) - { - std::ostringstream oss; oss << "MEDFileJoints::destroyJointAtPos : Invalid given id in input (" << i << ") should be in [0," << _joints.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _joints.erase(_joints.begin()+i); -} - -MEDFileJoints::MEDFileJoints() -{ -} - -MEDFileJoints::MEDFileJoints(med_idt fid, const std::string& meshName) -{ - int num_joint=MEDnSubdomainJoint(fid, meshName.c_str() ); - for(int i = 1; i <= num_joint; i++) - _joints.push_back(MEDFileJoint::New(fid,meshName,i)); -} - -MEDFileJoints *MEDFileJoints::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > joints(_joints.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++) - if((const MEDFileJoint *)*it) - joints[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileJoints::New(); - ret->_joints=joints; - return ret.retn(); -} - -std::size_t MEDFileJoints::getHeapMemorySizeWithoutChildren() const -{ - return _joints.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); -} - -std::vector MEDFileJoints::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++) - ret.push_back((const MEDFileJoint *)*it); - return ret; -} - -std::string MEDFileJoints::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*****************)\n(* MEDFileJoints *)\n(*****************)\n\n"; - simpleReprWithoutHeader(oss); - return oss.str(); -} - -void MEDFileJoints::simpleReprWithoutHeader(std::ostream& oss) const -{ - int nbOfJoints=getNumberOfJoints(); - oss << "There are " << nbOfJoints << " joints with the following names : \n"; - std::vector jns=getJointsNames(); - for(int i=0;i >::const_iterator it=_joints.begin();it!=_joints.end();it++) - { - oss << (*it)->simpleRepr(); - } -} diff --git a/medtool/src/MEDLoader/MEDFileJoint.hxx b/medtool/src/MEDLoader/MEDFileJoint.hxx deleted file mode 100644 index 1d32312f8..000000000 --- a/medtool/src/MEDLoader/MEDFileJoint.hxx +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDFILEJOINT_HXX__ -#define __MEDFILEJOINT_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ -/*! - * \brief Joint Correspondence enumerates pairs of corresponding entities of a - * certain geometrical type in adjacent mesh domains. - * Correspondence of nodes is constructed when you specify no cell type, - * else Correspondence of cells is constructed. - */ -class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable -{ -public: - MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(); - MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence); // nodes - MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence, // cells - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileJointCorrespondence *deepCpy() const; - MEDLOADER_EXPORT MEDFileJointCorrespondence *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileJointCorrespondence *other) const; - MEDLOADER_EXPORT void setIsNodal(bool isNodal) { _is_nodal = isNodal; } - MEDLOADER_EXPORT bool getIsNodal() const { return _is_nodal; } - MEDLOADER_EXPORT void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type) { _loc_geo_type=type; } - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const { return _loc_geo_type; } - MEDLOADER_EXPORT void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type) { _rem_geo_type=type; } - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const { return _rem_geo_type; } - MEDLOADER_EXPORT void setCorrespondence(DataArrayInt *corr); - MEDLOADER_EXPORT const DataArrayInt *getCorrespondence() const { return _correspondence; } - MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const; - - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const; -private: - MEDFileJointCorrespondence(); - MEDFileJointCorrespondence(DataArrayInt* correspondence, - bool is_nodal = true, - INTERP_KERNEL::NormalizedCellType loc_geo_type = INTERP_KERNEL::NORM_ERROR, - INTERP_KERNEL::NormalizedCellType rem_geo_type = INTERP_KERNEL::NORM_ERROR); -private: - bool _is_nodal; - INTERP_KERNEL::NormalizedCellType _loc_geo_type; - INTERP_KERNEL::NormalizedCellType _rem_geo_type; - MEDCouplingAutoRefCountObjectPtr _correspondence; -}; - -/*! - * \brief Joint of one iteration holds correspondences of entities of all types - */ -class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable -{ -public: - MEDLOADER_EXPORT static MEDFileJointOneStep *New(int dt=-1, int it=-1); - MEDLOADER_EXPORT static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1); - MEDLOADER_EXPORT static MEDFileJointOneStep *New(med_idt fid, const std::string& mName, const std::string& jointName, int number=1); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileJointOneStep *deepCpy() const; - MEDLOADER_EXPORT MEDFileJointOneStep *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileJointOneStep *other) const; - MEDLOADER_EXPORT void setOrder(int order) { _order=order; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT void pushCorrespondence(MEDFileJointCorrespondence* correspondence); - MEDLOADER_EXPORT int getNumberOfCorrespondences() const; - MEDLOADER_EXPORT MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const; - - MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const; - - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const; -private: - MEDFileJointOneStep(); - MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int number); - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType convertGeometryType(med_geometry_type geotype); -protected: - int _order; - int _iteration; -private: - std::vector > _correspondences; -}; - -/*! - * \brief Joint holds a sequence of joints of different iterations relating to - * a pair of mesh domains: a local one and a distant one - */ -class MEDFileJoint : public RefCountObject, public MEDFileWritable -{ -public: - MEDLOADER_EXPORT static MEDFileJoint *New(); - MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num); - MEDLOADER_EXPORT static MEDFileJoint *New(med_idt fid, const std::string& mName, int num); - MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileJoint *deepCpy() const; - MEDLOADER_EXPORT MEDFileJoint *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileJoint *other) const; - MEDLOADER_EXPORT void setLocalMeshName(const std::string& name) { _loc_mesh_name=name; } - MEDLOADER_EXPORT std::string getLocalMeshName() const { return _loc_mesh_name; } - MEDLOADER_EXPORT void setRemoteMeshName(const std::string& name) { _rem_mesh_name=name; } - MEDLOADER_EXPORT std::string getRemoteMeshName() const { return _rem_mesh_name; } - MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } - MEDLOADER_EXPORT void setJointName(const std::string& name) { _joint_name=name; } - MEDLOADER_EXPORT std::string getJointName() const { return _joint_name; } - MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT void setDomainNumber(const int& number) { _domain_number=number; } - MEDLOADER_EXPORT int getDomainNumber() const { return _domain_number; } - MEDLOADER_EXPORT void pushStep(MEDFileJointOneStep* step); - MEDLOADER_EXPORT int getNumberOfSteps() const; - MEDLOADER_EXPORT MEDFileJointOneStep *getStepAtPos(int i) const; - - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void write(med_idt fid) const; - - MEDLOADER_EXPORT std::string simpleRepr() const; - private: - MEDFileJoint(); - MEDFileJoint(med_idt fid, const std::string& mName, int num); - private: - std::string _loc_mesh_name; - std::string _joint_name; - std::string _desc_name; - int _domain_number; - std::string _rem_mesh_name; - std::vector< MEDCouplingAutoRefCountObjectPtr > _joint; - }; - - /*! - * \brief Joints of a mesh domain relating to all other mesh domains - */ - class MEDFileJoints : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileJoints *New(); - MEDLOADER_EXPORT static MEDFileJoints *New(const std::string& fileName, const std::string& meshName); - MEDLOADER_EXPORT static MEDFileJoints *New(med_idt fid, const std::string& meshName); - MEDLOADER_EXPORT MEDFileJoints *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void write(med_idt fid) const; - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT int getNumberOfJoints() const; - MEDLOADER_EXPORT MEDFileJoint *getJointAtPos(int i) const; - MEDLOADER_EXPORT MEDFileJoint *getJointWithName(const std::string& jname) const; - MEDLOADER_EXPORT std::vector getJointsNames() const; - MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair >& modifTab); - // - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushJoint(MEDFileJoint *joint); - MEDLOADER_EXPORT void setJointAtPos(int i, MEDFileJoint *joint); - MEDLOADER_EXPORT void destroyJointAtPos(int i); - private: - ~MEDFileJoints() { } - MEDFileJoints(); - MEDFileJoints(med_idt fid, const std::string& meshName); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _joints; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileMesh.cxx b/medtool/src/MEDLoader/MEDFileMesh.cxx deleted file mode 100644 index 761578f27..000000000 --- a/medtool/src/MEDLoader/MEDFileMesh.cxx +++ /dev/null @@ -1,6835 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileMesh.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileFieldOverView.hxx" -#include "MEDFileField.hxx" -#include "MEDLoader.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDLoaderBase.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include -#include - -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; - -MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true) -{ -} - -std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity()); - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string); - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - ret+=(*it2).capacity(); - } - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - ret+=(*it).first.capacity()+sizeof(int); - return ret; -} - -std::vector MEDFileMesh::getDirectChildrenWithNull() const -{ - std::vector ret(1); - ret[0]=(const MEDFileEquivalences *)_equiv; - return ret; -} - -/*! - * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED - * file. The first mesh in the file is loaded. - * \param [in] fileName - the name of MED file to read. - * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no meshes in the file. - * \throw If the mesh in the file is of a not supported type. - */ -MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - MEDCouplingAutoRefCountObjectPtr ret; - switch(meshType) - { - case UNSTRUCTURED: - { - ret=MEDFileUMesh::New(); - break; - } - case CARTESIAN: - { - ret=MEDFileCMesh::New(); - break; - } - case CURVE_LINEAR: - { - ret=MEDFileCurveLinearMesh::New(); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs); - return ret.retn(); -} - -/*! - * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED - * file. The mesh to load is specified by its name and numbers of a time step and an - * iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] dt - the number of a time step. - * \param [in] it - the number of an iteration. - * \param [in] joints - the sub-domain joints to use instead of those that can be read - * from the MED file. Usually this joints are those just read by another iteration - * of mName mesh, when this method is called by MEDFileMeshMultiTS::New() - * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - * \throw If the mesh in the file is of a not supported type. - */ -MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints) -{ - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dummy0,dummy1; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); - MEDCouplingAutoRefCountObjectPtr ret; - switch(meshType) - { - case UNSTRUCTURED: - { - ret=MEDFileUMesh::New(); - break; - } - case CARTESIAN: - { - ret=MEDFileCMesh::New(); - break; - } - case CURVE_LINEAR: - { - ret=MEDFileCurveLinearMesh::New(); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs); - return ret.retn(); -} - -/*! - * Writes \a this mesh into an open MED file specified by its descriptor. - * \param [in] fid - the MED file descriptor. - * \throw If the mesh name is not set. - * \throw If the file is open for reading only. - * \throw If the writing mode == 1 and the same data is present in an existing file. - */ -void MEDFileMesh::write(med_idt fid) const -{ - if(!existsFamily(0)) - const_cast(this)->addFamily(DFT_FAM_NAME,0); - if(_name.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !"); - writeLL(fid); - writeJoints(fid); - const MEDFileEquivalences *eqs(_equiv); - if(eqs) - eqs->write(fid); -} - -/*! - * Writes \a this mesh into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileMesh::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \param [in] eps - a precision used to compare real values. - * \param [in,out] what - the string returning description of unequal data. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(_order!=other->_order) - { - what="Orders differ !"; - return false; - } - if(_iteration!=other->_iteration) - { - what="Iterations differ !"; - return false; - } - if(fabs(_time-other->_time)>eps) - { - what="Time values differ !"; - return false; - } - if(_dt_unit!=other->_dt_unit) - { - what="Time units differ !"; - return false; - } - if(_name!=other->_name) - { - what="Names differ !"; - return false; - } - //univ_name has been ignored -> not a bug because it is a mutable attribute - if(_desc_name!=other->_desc_name) - { - what="Description names differ !"; - return false; - } - if(!areGrpsEqual(other,what)) - return false; - if(!areFamsEqual(other,what)) - return false; - if(!areEquivalencesEqual(other,what)) - return false; - return true; -} - -void MEDFileMesh::setName(const std::string& name) -{ - _name=name; -} - -/*! - * Clears redundant attributes of incorporated data arrays. - */ -void MEDFileMesh::clearNonDiscrAttributes() const -{ - -} - -bool MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab) -{ - for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) - { - if((*it).first==_name) - { - _name=(*it).second; - return true; - } - } - return false; -} - -/*! - * Copies data on groups and families from another mesh. - * \param [in] other - the mesh to copy the data from. - */ -void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other) -{ - _groups=other._groups; - _families=other._families; -} - - -/*! - * This method clear all the groups in the map. - * So this method does not operate at all on arrays. - * So this method can lead to orphan families. - * - * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps - */ -void MEDFileMesh::clearGrpMap() -{ - _groups.clear(); -} - -/*! - * This method clear all the families in the map. - * So this method does not operate at all on arrays. - * WARNING ! if there are some groups lying on cleared families, those groups will be impacted ! - * - * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps - */ -void MEDFileMesh::clearFamMap() -{ - _families.clear(); -} - -/*! - * This method clear all the families and groups in the map. - * So this method does not operate at all on arrays. - * As all groups and families entry will be removed after - * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object. - * - * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap - */ -void MEDFileMesh::clearFamGrpMaps() -{ - clearGrpMap(); - clearFamMap(); -} - -/*! - * Returns names of families constituting a group. - * \param [in] name - the name of the group of interest. - * \return std::vector - a sequence of names of the families. - * \throw If the name of a nonexistent group is specified. - */ -std::vector MEDFileMesh::getFamiliesOnGroup(const std::string& name) const -{ - std::string oname(name); - std::map >::const_iterator it=_groups.find(oname); - if(it==_groups.end()) - { - std::vector grps=getGroupsNames(); - std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return (*it).second; -} - -/*! - * Returns names of families constituting some groups. - * \param [in] grps - a sequence of names of groups of interest. - * \return std::vector - a sequence of names of the families. - * \throw If a name of a nonexistent group is present in \a grps. - */ -std::vector MEDFileMesh::getFamiliesOnGroups(const std::vector& grps) const -{ - std::set fams; - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++) - { - std::map >::const_iterator it2=_groups.find(*it); - if(it2==_groups.end()) - { - std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; - std::vector grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :"; - std::copy(grps2.begin(),grps2.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - fams.insert((*it2).second.begin(),(*it2).second.end()); - } - std::vector fams2(fams.begin(),fams.end()); - return fams2; -} - -/*! - * Returns ids of families constituting a group. - * \param [in] name - the name of the group of interest. - * \return std::vector - sequence of ids of the families. - * \throw If the name of a nonexistent group is specified. - */ -std::vector MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const -{ - std::string oname(name); - std::map >::const_iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); - if(it==_groups.end()) - { - std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getFamiliesIds((*it).second); -} - -/*! - * Sets names of families constituting a group. If data on families of this group is - * already present, it is overwritten. Every family in \a fams is checked, and if a - family is not yet in \a this mesh, the default group id \c 0 is assigned to it. - * \param [in] name - the name of the group of interest. - * \param [in] fams - a sequence of names of families constituting the group. - */ -void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector& fams) -{ - std::string oname(name); - _groups[oname]=fams; - for(std::vector::const_iterator it1=fams.begin();it1!=fams.end();it1++) - { - std::map::iterator it2=_families.find(*it1); - if(it2==_families.end()) - _families[*it1]=0; - } -} - -/*! - * Sets families constituting a group. The families are specified by their ids. - * If a family name is not found by its id, an exception is thrown. - * If several families have same id, the first one in lexical order is taken. - * \param [in] name - the name of the group of interest. - * \param [in] famIds - a sequence of ids of families constituting the group. - * \throw If a family name is not found by its id. - */ -void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds) -{ - std::string oname(name); - std::vector fams(famIds.size()); - int i=0; - for(std::vector::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++) - { - std::string name2=getFamilyNameGivenId(*it1); - fams[i]=name2; - } - _groups[oname]=fams; -} - -/*! - * Returns names of groups including a given family. - * \param [in] name - the name of the family of interest. - * \return std::vector - a sequence of names of groups including the family. - */ -std::vector MEDFileMesh::getGroupsOnFamily(const std::string& name) const -{ - std::vector ret; - for(std::map >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++) - { - for(std::vector::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++) - if((*it2)==name) - { - ret.push_back((*it1).first); - break; - } - } - return ret; -} - -/*! - * Adds an existing family to groups. - * \param [in] famName - a name of family to add to \a grps. - * \param [in] grps - a sequence of group names to add the family in. - * \throw If a family named \a famName not yet exists. - */ -void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector& grps) -{ - std::string fName(famName); - const std::map::const_iterator it=_families.find(fName); - if(it==_families.end()) - { - std::vector fams=getFamiliesNames(); - std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::vector::const_iterator it3=grps.begin();it3!=grps.end();it3++) - { - std::map< std::string, std::vector >::iterator it2=_groups.find(*it3); - if(it2!=_groups.end()) - (*it2).second.push_back(fName); - else - { - std::vector grps2(1,fName); - _groups[*it3]=grps2; - } - } -} - -/*! - * Returns names of all groups of \a this mesh. - * \return std::vector - a sequence of group names. - */ -std::vector MEDFileMesh::getGroupsNames() const -{ - std::vector ret(_groups.size()); - int i=0; - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++) - ret[i]=(*it).first; - return ret; -} - -/*! - * Returns names of all families of \a this mesh. - * \return std::vector - a sequence of family names. - */ -std::vector MEDFileMesh::getFamiliesNames() const -{ - std::vector ret(_families.size()); - int i=0; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++,i++) - ret[i]=(*it).first; - return ret; -} - -/*! - * Changes a name of every family, included in one group only, to be same as the group name. - * \throw If there are families with equal names in \a this mesh. - */ -void MEDFileMesh::assignFamilyNameWithGroupName() -{ - std::map > groups(_groups); - std::map newFams; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - std::vector grps=getGroupsOnFamily((*it).first); - if(grps.size()==1 && groups[grps[0]].size()==1) - { - if(newFams.find(grps[0])!=newFams.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - newFams[grps[0]]=(*it).second; - std::vector& grps2=groups[grps[0]]; - std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first)); - grps2[pos]=grps[0]; - } - else - { - if(newFams.find((*it).first)!=newFams.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - newFams[(*it).first]=(*it).second; - } - } - _families=newFams; - _groups=groups; -} - -/*! - * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched. - * - * \return the removed groups. - */ -std::vector MEDFileMesh::removeEmptyGroups() -{ - std::vector ret; - std::map > newGrps; - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - if((*it).second.empty()) - ret.push_back((*it).first); - else - newGrps[(*it).first]=(*it).second; - } - if(!ret.empty()) - _groups=newGrps; - return ret; -} - -/*! - * Removes a group from \a this mesh. - * \param [in] name - the name of the group to remove. - * \throw If no group with such a \a name exists. - */ -void MEDFileMesh::removeGroup(const std::string& name) -{ - std::string oname(name); - std::map >::iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); - if(it==_groups.end()) - { - std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _groups.erase(it); -} - -/*! - * Removes a family from \a this mesh. - * \param [in] name - the name of the family to remove. - * \throw If no family with such a \a name exists. - */ -void MEDFileMesh::removeFamily(const std::string& name) -{ - std::string oname(name); - std::map::iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) - { - std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families.erase(it); - for(std::map >::iterator it3=_groups.begin();it3!=_groups.end();it3++) - { - std::vector& v=(*it3).second; - std::vector::iterator it4=std::find(v.begin(),v.end(),oname); - if(it4!=v.end()) - v.erase(it4); - } -} - -/*! - * Removes all groups in \a this that are orphan. A group is orphan if this group lies on - * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in - * family field whatever its level. This method also suppresses the orphan families. - * - * \return - The list of removed groups names. - * - * \sa MEDFileMesh::removeOrphanFamilies. - */ -std::vector MEDFileMesh::removeOrphanGroups() -{ - removeOrphanFamilies(); - return removeEmptyGroups(); -} - -/*! - * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in - * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified. - * - * \return - The list of removed families names. - * \sa MEDFileMesh::removeOrphanGroups. - */ -std::vector MEDFileMesh::removeOrphanFamilies() -{ - MEDCouplingAutoRefCountObjectPtr allFamIdsInUse=computeAllFamilyIdsInUse(); - std::vector ret; - if(!((DataArrayInt*)allFamIdsInUse)) - { - ret=getFamiliesNames(); - _families.clear(); _groups.clear(); - return ret; - } - std::map famMap; - std::map > grps(_groups); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - if(allFamIdsInUse->presenceOfValue((*it).second)) - famMap[(*it).first]=(*it).second; - else - { - ret.push_back((*it).first); - std::vector grpsOnEraseFam=getGroupsOnFamily((*it).first); - for(std::vector::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++) - { - std::map >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy - std::vector& famv=(*it3).second; - std::vector::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy - famv.erase(it4); - } - } - } - if(!ret.empty()) - { _families=famMap; _groups=grps; } - return ret; -} - -/*! - * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever - * this family is orphan or not. - * - * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families. - */ -void MEDFileMesh::removeFamiliesReferedByNoGroups() -{ - std::map fams; - std::set sfams; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - sfams.insert((*it).first); - for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - for(std::vector::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) - sfams.erase(*it1); - for(std::set::const_iterator it=sfams.begin();it!=sfams.end();it++) - if(*it!=DFT_FAM_NAME) - _families.erase(*it); -} - -/*! - * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities - * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed. - * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group. - * - * \sa MEDFileMesh::removeOrphanFamilies - */ -void MEDFileMesh::rearrangeFamilies() -{ - checkOrphanFamilyZero(); - removeFamiliesReferedByNoGroups(); - // - std::vector levels(getNonEmptyLevelsExt()); - std::set idsRefed; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - idsRefed.insert((*it).second); - for(std::vector::const_iterator it=levels.begin();it!=levels.end();it++) - { - const DataArrayInt *fams(0); - try - { - fams=getFamilyFieldAtLevel(*it); - } - catch(INTERP_KERNEL::Exception& e) { } - if(!fams) - continue; - std::vector v(fams->getNumberOfTuples(),false); - for(std::set::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) - fams->switchOnTupleEqualTo(*pt,v); - MEDCouplingAutoRefCountObjectPtr unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v)); - if(!unfetchedIds->empty()) - { - MEDCouplingAutoRefCountObjectPtr newFams(fams->deepCpy()); - newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1); - setFamilyFieldArr(*it,newFams); - } - } - removeOrphanFamilies(); -} - -/*! - * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group). - */ -void MEDFileMesh::checkOrphanFamilyZero() const -{ - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Renames a group in \a this mesh. - * \param [in] oldName - a current name of the group to rename. - * \param [in] newName - a new group name. - * \throw If no group named \a oldName exists in \a this mesh. - * \throw If a group named \a newName already exists. - */ -void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName) -{ - std::string oname(oldName); - std::map >::iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); - if(it==_groups.end()) - { - std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string nname(newName); - std::map >::iterator it2=_groups.find(nname); - if(it2!=_groups.end()) - { - std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector cpy=(*it).second; - _groups.erase(it); - _groups[newName]=cpy; -} - -/*! - * Changes an id of a family in \a this mesh. - * This method calls changeFamilyIdArr(). - * \param [in] oldId - a current id of the family. - * \param [in] newId - a new family id. - */ -void MEDFileMesh::changeFamilyId(int oldId, int newId) -{ - changeFamilyIdArr(oldId,newId); - std::map fam2; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - if((*it).second==oldId) - fam2[(*it).first]=newId; - else - fam2[(*it).first]=(*it).second; - } - _families=fam2; -} - -/*! - * Renames a family in \a this mesh. - * \param [in] oldName - a current name of the family to rename. - * \param [in] newName - a new family name. - * \throw If no family named \a oldName exists in \a this mesh. - * \throw If a family named \a newName already exists. - */ -void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName) -{ - std::string oname(oldName); - std::map::iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) - { - std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string nname(newName); - std::map::iterator it2=_families.find(nname); - if(it2!=_families.end()) - { - std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int cpy=(*it).second; - _families.erase(it); - _families[newName]=cpy; - for(std::map >::iterator it3=_groups.begin();it3!=_groups.end();it3++) - { - std::vector& v=(*it3).second; - std::vector::iterator it4=std::find(v.begin(),v.end(),oname); - if(it4!=v.end()) - (*it4)=nname; - } -} - -/*! - * Checks if \a this and another mesh contains the same families. - * \param [in] other - the mesh to compare with \a this one. - * \param [in,out] what - an unused parameter. - * \return bool - \c true if number of families and their ids are the same in the two - * meshes. Families with the id == \c 0 are not considered. - */ -bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const -{ - if(_families==other->_families) - return true; - std::map fam0; - std::map fam1; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second!=0) - fam0[(*it).first]=(*it).second; - for(std::map::const_iterator it=other->_families.begin();it!=other->_families.end();it++) - if((*it).second!=0) - fam1[(*it).first]=(*it).second; - return fam0==fam1; -} - -/*! - * Checks if \a this and another mesh contains the same groups. - * \param [in] other - the mesh to compare with \a this one. - * \param [in,out] what - a string describing a difference of groups of the two meshes - * in case if this method returns \c false. - * \return bool - \c true if number of groups and families constituting them are the - * same in the two meshes. - */ -bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const -{ - if(_groups==other->_groups) - return true; - bool ret=true; - std::size_t sz=_groups.size(); - if(sz!=other->_groups.size()) - { - what="Groups differ because not same number !\n"; - ret=false; - } - if(ret) - { - std::map >::const_iterator it1=_groups.begin(); - for(std::size_t i=0;i >::const_iterator it2=other->_groups.find((*it1).first); - if(it2!=other->_groups.end()) - { - std::set s1((*it1).second.begin(),(*it1).second.end()); - std::set s2((*it2).second.begin(),(*it2).second.end()); - ret=(s1==s2); - } - else - { - ret=false; - what="A group in first mesh exists not in other !\n"; - } - } - } - if(!ret) - { - std::ostringstream oss; oss << "Groups description differs :\n"; - oss << "First group description :\n"; - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - oss << " Group \"" << (*it).first << "\" on following families :\n"; - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; - } - oss << "Second group description :\n"; - for(std::map >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) - { - oss << " Group \"" << (*it).first << "\" on following families :\n"; - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; - } - what+=oss.str(); - } - return ret; -} - -/*! - * Checks if a group with a given name exists in \a this mesh. - * \param [in] groupName - the group name. - * \return bool - \c true the group \a groupName exists in \a this mesh. - */ -bool MEDFileMesh::existsGroup(const std::string& groupName) const -{ - std::string grpName(groupName); - return _groups.find(grpName)!=_groups.end(); -} - -/*! - * Checks if a family with a given id exists in \a this mesh. - * \param [in] famId - the family id. - * \return bool - \c true the family with the id \a famId exists in \a this mesh. - */ -bool MEDFileMesh::existsFamily(int famId) const -{ - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - return true; - return false; -} - -/*! - * Checks if a family with a given name exists in \a this mesh. - * \param [in] familyName - the family name. - * \return bool - \c true the family \a familyName exists in \a this mesh. - */ -bool MEDFileMesh::existsFamily(const std::string& familyName) const -{ - std::string fname(familyName); - return _families.find(fname)!=_families.end(); -} - -/*! - * Sets an id of a family. - * \param [in] familyName - the family name. - * \param [in] id - a new id of the family. - */ -void MEDFileMesh::setFamilyId(const std::string& familyName, int id) -{ - std::string fname(familyName); - _families[fname]=id; -} - -void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id) -{ - std::string fname(familyName); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second==id) - { - if((*it).first!=familyName) - { - std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - _families[fname]=id; -} - -/*! - * Adds a family to \a this mesh. - * \param [in] familyName - a name of the family. - * \param [in] famId - an id of the family. - * \throw If a family with the same name or id already exists in \a this mesh. - */ -void MEDFileMesh::addFamily(const std::string& familyName, int famId) -{ - std::string fname(familyName); - std::map::const_iterator it=_families.find(fname); - if(it==_families.end()) - { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families[fname]=famId; - } - else - { - if((*it).second!=famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Creates a group including all mesh entities of given dimension. - * \warning This method does \b not guarantee that the created group includes mesh - * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is - * present in family fields of different dimensions. To assure this, call - * ensureDifferentFamIdsPerLevel() \b before calling this method. - * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to - * the group. - * \param [in] groupName - a name of the new group. - * \throw If a group named \a groupName already exists. - * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh. - * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh. - */ -void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) -{ - std::string grpName(groupName); - std::vector levs=getNonEmptyLevelsExt(); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl; - oss << "Available relative ext levels are : "; - std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(existsGroup(groupName)) - { - std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl; - oss << "Already existing groups are : "; - std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); - oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt); - if(fieldFamIds==0) - throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !"); - MEDCouplingAutoRefCountObjectPtr famIds=fieldFamIds->getDifferentValues(); - std::vector familiesOnWholeGroup; - for(const int *it=famIds->begin();it!=famIds->end();it++) - { - bool tmp; - familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp)); - } - _groups[grpName]=familiesOnWholeGroup; -} - -/*! - * Ensures that given family ids do not present in family fields of dimensions different - * than given ones. If a family id is present in the family fields of dimensions different - * than the given ones, a new family is created and the whole data is updated accordingly. - * \param [in] famIds - a sequence of family ids to check. - * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a - * famIds should exclusively belong. - * \return bool - \c true if no modification is done in \a this mesh by this method. - */ -bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& vMeshDimRelToMaxExt) -{ - std::set levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end()); - std::vector levs=getNonEmptyLevelsExt(); - std::set levs2(levs.begin(),levs.end()); - std::vector levsToTest; - std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector >(levsToTest)); - std::set famIds2(famIds.begin(),famIds.end()); - bool ret=true; - int maxFamId=1; - if(!_families.empty()) - maxFamId=getMaxFamilyId()+1; - std::vector allFams=getFamiliesNames(); - for(std::vector::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++) - { - const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it); - if(fieldFamIds) - { - MEDCouplingAutoRefCountObjectPtr famIds3=fieldFamIds->getDifferentValues(); - std::vector tmp; - std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector >(tmp)); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - { - ret=false; - std::string famName=getFamilyNameGivenId(*it2); - std::ostringstream oss; oss << "Family_" << maxFamId; - std::string zeName=CreateNameNotIn(oss.str(),allFams); - addFamilyOnAllGroupsHaving(famName,zeName); - _families[zeName]=maxFamId; - (const_cast(fieldFamIds))->changeValue(*it2,maxFamId); - maxFamId++; - } - } - } - return ret; -} - -/*! - * Adds a family to a given group in \a this mesh. If the group with a given name does - * not exist, it is created. - * \param [in] grpName - the name of the group to add the family in. - * \param [in] famName - the name of the family to add to the group named \a grpName. - * \throw If \a grpName or \a famName is an empty string. - * \throw If no family named \a famName is present in \a this mesh. - */ -void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName) -{ - std::string grpn(grpName); - std::string famn(famName); - if(grpn.empty() || famn.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !"); - std::vector fams=getFamiliesNames(); - if(std::find(fams.begin(),fams.end(),famn)==fams.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl; - oss << "Create this family or choose an existing one ! Existing fams are : "; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); oss << "."; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::map >::iterator it=_groups.find(grpn); - if(it==_groups.end()) - { - _groups[grpn].push_back(famn); - } - else - { - std::vector::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn); - if(it2==(*it).second.end()) - (*it).second.push_back(famn); - } -} - -/*! - * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'. - * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families. - * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method. - */ -void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName) -{ - std::string famNameCpp(famName); - std::string otherCpp(otherFamName); - for(std::map >::iterator it=_groups.begin();it!=_groups.end();it++) - { - std::vector& v=(*it).second; - if(std::find(v.begin(),v.end(),famNameCpp)!=v.end()) - { - v.push_back(otherCpp); - } - } -} - -/*! - * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). - * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed) - */ -void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) -{ - if(!ids) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); - std::string grpName(ids->getName()); - if(grpName.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !"); - ids->checkStrictlyMonotonic(true); - famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr famArrTmp(famArr); - std::vector grpsNames=getGroupsNames(); - if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) - { - std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::list< MEDCouplingAutoRefCountObjectPtr > allFamIds(getAllNonNullFamilyIds()); - allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); - MEDCouplingAutoRefCountObjectPtr famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); - MEDCouplingAutoRefCountObjectPtr diffFamIds=famIds->getDifferentValues(); - std::vector familyIds; - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerfamiliyIds; - int maxVal=getTheMaxAbsFamilyId()+1; - std::map families(_families); - std::map > groups(_groups); - std::vector fams; - bool created(false); - for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++) - { - MEDCouplingAutoRefCountObjectPtr ids2Tmp=famIds->getIdsEqual(*famId); - MEDCouplingAutoRefCountObjectPtr ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); - MEDCouplingAutoRefCountObjectPtr ids1=famArr->getIdsEqual(*famId); - MEDCouplingAutoRefCountObjectPtr ret0(ids1->buildSubstractionOptimized(ids2)); - if(ret0->empty()) - { - bool isFamPresent=false; - for(std::list< MEDCouplingAutoRefCountObjectPtr >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) - isFamPresent=(*itl)->presenceOfValue(*famId); - if(!isFamPresent) - { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp - else - { - familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2); - std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created); - fams.push_back(locFamName); - if(existsFamily(*famId)) - { - std::string locFamName2=getFamilyNameGivenId(*famId); std::vector v(2); v[0]=locFamName2; v[1]=locFamName; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); - } - maxVal++; - } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal - } - else - { - familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1 - familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1 - std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2); - if(existsFamily(*famId)) - { - std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector v(2); v[0]=n1; v[1]=n2; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); - } - maxVal+=2; - } - } - for(std::size_t i=0;isetPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); - } - _families=families; - _groups=groups; - _groups[grpName]=fams; -} - -void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames) -{ - ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames); -} - -void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const std::string& familyNameToChange, const std::vector& newFamiliesNames) -{ - std::string fam(familyNameToChange); - for(std::map >::iterator it=groups.begin();it!=groups.end();it++) - { - std::vector& fams((*it).second); - std::vector::iterator it2=std::find(fams.begin(),fams.end(),fam); - if(it2!=fams.end()) - { - fams.erase(it2); - fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end()); - } - } -} - -/*! - * Returns a name of the family having a given id or, if no such a family exists, creates - * a new uniquely named family and returns its name. - * \param [in] id - the id of the family whose name is required. - * \param [out] created - returns \c true if the new family has been created, \c false, else. - * \return std::string - the name of the existing or the created family. - * \throw If it is not possible to create a unique family name. - */ -std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) -{ - return FindOrCreateAndGiveFamilyWithId(_families,id,created); -} - -/*! - * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId. - * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false. - * If there is no family whose family id is equal to 'id' a family is created with a name different from those - * already existing. In this case 'created' will be returned with a value set to true, and internal state - * will be modified. - * This method will throws an exception if it is not possible to create a unique family name. - */ -std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created) -{ - std::vector famAlreadyExisting(families.size()); - int ii=0; - for(std::map::const_iterator it=families.begin();it!=families.end();it++,ii++) - { - if((*it).second!=id) - { - famAlreadyExisting[ii]=(*it).first; - } - else - { - created=false; - return (*it).first; - } - } - created=true; - std::ostringstream oss; oss << "Family_" << id; - std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting); - families[ret]=id; - return ret; -} - -/*! - * Sets names and ids of all families in \a this mesh. - * \param [in] info - a map of a family name to a family id. - */ -void MEDFileMesh::setFamilyInfo(const std::map& info) -{ - _families=info; -} - -/*! - * Sets names of all groups and families constituting them in \a this mesh. - * \param [in] info - a map of a group name to a vector of names of families - * constituting the group. - */ -void MEDFileMesh::setGroupInfo(const std::map >&info) -{ - _groups=info; -} - -/*! - * Returns an id of the family having a given name. - * \param [in] name - the name of the family of interest. - * \return int - the id of the family of interest. - * \throw If no family with such a \a name exists. - */ -int MEDFileMesh::getFamilyId(const std::string& name) const -{ - std::string oname(name); - std::map::const_iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) - { - std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return (*it).second; -} - -/*! - * Returns ids of the families having given names. - * \param [in] fams - a sequence of the names of families of interest. - * \return std::vector - a sequence of the ids of families of interest. - * \throw If \a fams contains a name of an inexistent family. - */ -std::vector MEDFileMesh::getFamiliesIds(const std::vector& fams) const -{ - std::vector ret(fams.size()); - int i=0; - for(std::vector::const_iterator it=fams.begin();it!=fams.end();it++,i++) - { - std::map::const_iterator it2=_families.find(*it); - if(it2==_families.end()) - { - std::vector fams2=getFamiliesNames(); - std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :"; - std::copy(fams2.begin(),fams2.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret[i]=(*it2).second; - } - return ret; -} - -/*! - * Returns a maximal abs(id) of families in \a this mesh. - * \return int - the maximal norm of family id. - * \throw If there are no families in \a this mesh. - */ -int MEDFileMesh::getMaxAbsFamilyId() const -{ - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - ret=std::max(std::abs((*it).second),ret); - } - return ret; -} - -/*! - * Returns a maximal id of families in \a this mesh. - * \return int - the maximal family id. - * \throw If there are no families in \a this mesh. - */ -int MEDFileMesh::getMaxFamilyId() const -{ - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - ret=std::max((*it).second,ret); - } - return ret; -} - -/*! - * Returns a minimal id of families in \a this mesh. - * \return int - the minimal family id. - * \throw If there are no families in \a this mesh. - */ -int MEDFileMesh::getMinFamilyId() const -{ - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !"); - int ret=std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - ret=std::min((*it).second,ret); - } - return ret; -} - -/*! - * Returns a maximal id of families in \a this mesh. Not only named families are - * considered but all family fields as well. - * \return int - the maximal family id. - */ -int MEDFileMesh::getTheMaxAbsFamilyId() const -{ - int m1=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - m1=std::max(std::abs((*it).second),m1); - int m2=getMaxAbsFamilyIdInArrays(); - return std::max(m1,m2); -} - -/*! - * Returns a maximal id of families in \a this mesh. Not only named families are - * considered but all family fields as well. - * \return int - the maximal family id. - */ -int MEDFileMesh::getTheMaxFamilyId() const -{ - int m1=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - m1=std::max((*it).second,m1); - int m2=getMaxFamilyIdInArrays(); - return std::max(m1,m2); -} - -/*! - * Returns a minimal id of families in \a this mesh. Not only named families are - * considered but all family fields as well. - * \return int - the minimal family id. - */ -int MEDFileMesh::getTheMinFamilyId() const -{ - int m1=std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - m1=std::min((*it).second,m1); - int m2=getMinFamilyIdInArrays(); - return std::min(m1,m2); -} - -/*! - * This method only considers the maps. The contain of family array is ignored here. - * - * \sa MEDFileMesh::computeAllFamilyIdsInUse - */ -DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::set v; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - v.insert((*it).second); - ret->alloc((int)v.size(),1); - std::copy(v.begin(),v.end(),ret->getPointer()); - return ret.retn(); -} - -/*! - * This method does not consider map of family name, family id. Only family field array on different levels is considered. - * - * \sa MEDFileMesh::getAllFamiliesIdsReferenced - */ -DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const -{ - std::vector famLevs=getFamArrNonEmptyLevelsExt(); - MEDCouplingAutoRefCountObjectPtr ret; - for(std::vector::const_iterator it=famLevs.begin();it!=famLevs.end();it++) - { - const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt - MEDCouplingAutoRefCountObjectPtr dv=arr->getDifferentValues(); - if((DataArrayInt *) ret) - ret=dv->buildUnion(ret); - else - ret=dv; - } - return ret.retn(); -} - -/*! - * true is returned if no modification has been needed. false if family - * renumbering has been needed. - */ -bool MEDFileMesh::ensureDifferentFamIdsPerLevel() -{ - std::vector levs=getNonEmptyLevelsExt(); - std::set allFamIds; - int maxId=getMaxFamilyId()+1; - std::map > famIdsToRenum; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - const DataArrayInt *fam=getFamilyFieldAtLevel(*it); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::set r2; - std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end())); - if(!r2.empty()) - famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end()); - std::set r3; - std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end())); - } - } - if(famIdsToRenum.empty()) - return true; - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - for(std::map >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++) - { - DataArrayInt *fam=const_cast(getFamilyFieldAtLevel((*it2).first)); - int *famIdsToChange=fam->getPointer(); - std::map ren; - for(std::vector::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++) - { - if(allIds->presenceOfValue(*it3)) - { - std::string famName=getFamilyNameGivenId(*it3); - std::vector grps=getGroupsOnFamily(famName); - ren[*it3]=maxId; - bool dummy; - std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy); - for(std::vector::const_iterator it4=grps.begin();it4!=grps.end();it4++) - addFamilyOnGrp((*it4),newFam); - } - } - MEDCouplingAutoRefCountObjectPtr ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); - for(const int *id=ids->begin();id!=ids->end();id++) - famIdsToChange[*id]=ren[famIdsToChange[*id]]; - } - return false; -} - -/*! - * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH. - * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0 - * This policy is those used by SMESH and Trio and that is the opposite of those in MED file. - * This method will throw an exception if a same family id is detected in different level. - * \warning This policy is the opposite of those in MED file documentation ... - */ -void MEDFileMesh::normalizeFamIdsTrio() -{ - ensureDifferentFamIdsPerLevel(); - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - std::vector levs=getNonEmptyLevelsExt(); - std::set levsS(levs.begin(),levs.end()); - std::set famsFetched; - std::map families; - if(std::find(levs.begin(),levs.end(),0)!=levs.end()) - { - levsS.erase(0); - const DataArrayInt *fam=getFamilyFieldAtLevel(0); - if(fam) - { - int refId=1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - if(std::find(levs.begin(),levs.end(),-1)!=levs.end()) - { - levsS.erase(-1); - const DataArrayInt *fam=getFamilyFieldAtLevel(-1); - if(fam) - { - int refId=-1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - for(std::set::const_iterator it2=levsS.begin();it2!=levsS.end();it2++) - { - DataArrayInt *fam=const_cast(getFamilyFieldAtLevel(*it2)); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - fam->fillWithZero(); - for(const int *it3=tmp->begin();it3!=tmp->end();it3++) - if(allIds->presenceOfValue(*it3)) - { - std::string famName=getFamilyNameGivenId(*it3); - families[famName]=0; - famsFetched.insert(famName); - } - } - } - // - std::vector allFams=getFamiliesNames(); - std::set allFamsS(allFams.begin(),allFams.end()); - std::set unFetchedIds; - std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end())); - for(std::set::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++) - families[*it4]=_families[*it4]; - _families=families; -} - -/*! - * This method normalizes fam id with the following policy. - * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0 - * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio. - * This method will throw an exception if a same family id is detected in different level. - */ -void MEDFileMesh::normalizeFamIdsMEDFile() -{ - ensureDifferentFamIdsPerLevel(); - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - std::vector levs=getNonEmptyLevelsExt(); - std::set levsS(levs.begin(),levs.end()); - std::set famsFetched; - std::map families; - int refId=1; - if(std::find(levs.begin(),levs.end(),1)!=levs.end()) - { - levsS.erase(1); - const DataArrayInt *fam=getFamilyFieldAtLevel(1); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - refId=-1; - for(std::set::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++) - { - const DataArrayInt *fam=getFamilyFieldAtLevel(*it2); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - // - std::vector allFams=getFamiliesNames(); - std::set allFamsS(allFams.begin(),allFams.end()); - std::set unFetchedIds; - std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end())); - for(std::set::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++) - families[*it4]=_families[*it4]; - _families=families; -} - -/*! - * Returns a name of the family by its id. If there are several families having the given - * id, the name first in lexical order is returned. - * \param [in] id - the id of the family whose name is required. - * \return std::string - the name of the found family. - * \throw If no family with the given \a id exists. - */ -std::string MEDFileMesh::getFamilyNameGivenId(int id) const -{ - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second==id) - return (*it).first; - std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * Returns a string describing \a this mesh. This description includes the mesh name and - * the mesh description string. - * \return std::string - the mesh information string. - */ -std::string MEDFileMesh::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n"; - oss << "- Name of the mesh : <<" << getName() << ">>\n"; - oss << "- Description associated to the mesh : " << getDescription() << std::endl; - return oss.str(); -} - -/*! - * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt - * an empty one is created. - */ -DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) -{ - DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt)); - if(ret) - return ret; - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::New()); - arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1); - arr->fillWithZero(); - setFamilyFieldArr(meshDimRelToMaxExt,arr); - return getFamilyFieldAtLevel(meshDimRelToMaxExt); -} - -/*! - * Returns ids of mesh entities contained in a given group of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] grp - the name of the group of interest. - * \param [in] renum - if \c true, the optional numbers of entities, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of mesh entities of the group. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const -{ - std::vector tmp(1); - tmp[0]=grp; - DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); - ret->setName(grp); - return ret; -} - -/*! - * Returns ids of mesh entities contained in given groups of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] grps - the names of the groups of interest. - * \param [in] renum - if \c true, the optional numbers of entities, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of mesh entities of the groups. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is present in \a grps. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const -{ - std::vector fams2=getFamiliesOnGroups(grps); - return getFamiliesArr(meshDimRelToMaxExt,fams2,renum); -} - -/*! - * Returns ids of mesh entities contained in a given family of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] fam - the name of the family of interest. - * \param [in] renum - if \c true, the optional numbers of entities, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of mesh entities of the family. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const -{ - std::vector tmp(1); - tmp[0]=fam; - DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); - ret->setName(fam); - return ret; -} - -/*! - * Returns ids of nodes contained in a given group. - * \param [in] grp - the name of the group of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the group. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const -{ - std::vector tmp(1); - tmp[0]=grp; - DataArrayInt *ret=getNodeGroupsArr(tmp,renum); - ret->setName(grp); - return ret; -} - -/*! - * Returns ids of nodes contained in given groups. - * \param [in] grps - the names of the groups of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the groups. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is present in \a grps. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum) const -{ - return getGroupsArr(1,grps,renum); -} - -/*! - * Returns ids of nodes contained in a given group. - * \param [in] grp - the name of the group of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the group. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const -{ - std::vector tmp(1); - tmp[0]=fam; - DataArrayInt *ret=getNodeFamiliesArr(tmp,renum); - ret->setName(fam); - return ret; -} - -/*! - * Returns ids of nodes contained in given families. - * \param [in] fams - the names of the families of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the families. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum) const -{ - return getFamiliesArr(1,fams,renum); -} - -/*! - * Adds groups of given dimension and creates corresponding families and family fields - * given ids of mesh entities of each group. - * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities. - * \param [in] grps - a sequence of arrays of ids each describing a group. - * \param [in] renum - \c true means that \a grps contains not ids but optional numbers - * of mesh entities. - * \throw If names of some groups in \a grps are equal. - * \throw If \a grps includes a group with an empty name. - * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ). - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum) -{ - if(grps.empty()) - return ; - std::set grpsName; - std::vector grpsName2(grps.size()); - int i=0; - - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++,i++) - { - grpsName.insert((*it)->getName()); - grpsName2[i]=(*it)->getName(); - } - if(grpsName.size()!=grps.size()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !"); - if(grpsName.find(std::string(""))!=grpsName.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !"); - int sz=getSizeAtLevel(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr fam; - std::vector< std::vector > fidsOfGroups; - if(!renum) - { - fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups); - } - else - { - std::vector< MEDCouplingAutoRefCountObjectPtr > grps2(grps.size()); - for(unsigned int ii=0;iisetName(grps[ii]->getName()); - } - std::vector grps3(grps2.begin(),grps2.end()); - fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); - } - int offset=1; - if(!_families.empty()) - offset=getMaxAbsFamilyId()+1; - TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups); - MEDCouplingAutoRefCountObjectPtr ids=fam->getDifferentValues(); - appendFamilyEntries(ids,fidsOfGroups,grpsName2); - setFamilyFieldArr(meshDimRelToMaxExt,fam); -} - -/*! - * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids - * not in '_families'. Groups information are given in parameters in order to give to families representative names. - * For the moment, the two last input parameters are not taken into account. - */ -void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) -{ - std::map famInv; - for(const int *it=famIds->begin();it!=famIds->end();it++) - { - std::ostringstream oss; - oss << "Family_" << (*it); - _families[oss.str()]=(*it); - famInv[*it]=oss.str(); - } - int i=0; - for(std::vector< std::vector >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) - { - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - { - _groups[grpNames[i]].push_back(famInv[*it2]); - } - } -} - -std::vector MEDFileMesh::getAllGeoTypes() const -{ - std::vector levs(getNonEmptyLevels()); - std::vector ret; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - std::vector elts(getGeoTypesAtLevel(*it)); - ret.insert(ret.end(),elts.begin(),elts.end()); - } - return ret; -} - -std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const -{ - MEDCouplingAutoRefCountObjectPtr mLev(getGenMeshAtLevel(meshDimRelToMax)); - return mLev->getDistributionOfTypes(); -} - -void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - loadLL(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); - loadEquivalences(fid); -} - -void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp) -{ - famArr->applyLin(offset>0?1:-1,offset,0); - for(std::vector< std::vector >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) - { - if(offset<0) - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate()); - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus(),offset)); - } -} - -/*! - * Warning no check is done on 'nameTry' in parameter. It should be non empty. - * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'. - * If this method fails to find such a name it will throw an exception. - */ -std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid) -{ - //attempt #0 - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end()) - return nameTry; - //attempt #1 - std::size_t len=nameTry.length(); - for(std::size_t ii=1;ii=1) - { - for(std::size_t i=1;i<30;i++) - { - std::string tmp1(nameTry.at(0),i); - tmp1+=nameTry; - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end()) - return tmp1; - } - } - //attempt #3 - std::string tmp2; - for(std::vector::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++) - tmp2+=(*it2); - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end()) - return tmp2; - throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !"); -} - -int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector& code, int strt) -{ - std::size_t nbOfChunks=code.size()/3; - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !"); - int ret=strt; - for(std::size_t i=0;igetName(); - else - { - std::string name(m->getName()); - if(!name.empty()) - { - if(_name!=name) - { - std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '"; - oss << name << "' ! Names must match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - if(_desc_name.empty()) - _desc_name=m->getDescription(); - else - { - std::string name(m->getDescription()); - if(!name.empty()) - { - if(_desc_name!=name) - { - std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '"; - oss << name << "' ! Names must match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -void MEDFileMesh::getFamilyRepr(std::ostream& oss) const -{ - oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n"; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl; - oss << " - Groups lying on this family : "; - std::vector grps=getGroupsOnFamily((*it).first); - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - oss << std::endl << std::endl; - } -} - -/*! - * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED - * file. The mesh to load is specified by its name and numbers of a time step and an - * iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] dt - the number of a time step. - * \param [in] it - the number of an iteration. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - * \throw If the mesh in the file is not an unstructured one. - */ -MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - return new MEDFileUMesh(fid,mName,dt,it,mrs); -} - -/*! - * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED - * file. The first mesh in the file is loaded. - * \param [in] fileName - the name of MED file to read. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no meshes in the file. - * \throw If the mesh in the file is not an unstructured one. - */ -MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileUMesh(fid,ms.front(),dt,it,mrs); -} - -/*! - * Returns an empty instance of MEDFileUMesh. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - */ -MEDFileUMesh *MEDFileUMesh::New() -{ - return new MEDFileUMesh; -} - -/*! - * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that - * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters - * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh. - * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce - * at most the memory consumtion. - * - * \param [in] fileName - the name of the file. - * \param [in] mName - the name of the mesh to be read. - * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most. - * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step. - * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step. - * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step. - * \param [in] mrs - the request for what to be loaded. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed. - */ -MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs); -} - -/*! - * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first). - * This method is \b NOT wrapped into python. - */ -MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); - return ret.retn(); -} - -std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); - ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; -} - -std::vector MEDFileUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayDouble*)_coords); - ret.push_back((const DataArrayInt *)_fam_coords); - ret.push_back((const DataArrayInt *)_num_coords); - ret.push_back((const DataArrayInt *)_rev_num_coords); - ret.push_back((const DataArrayAsciiChar *)_name_coords); - ret.push_back((const PartDefinition *)_part_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - ret.push_back((const MEDFileUMeshSplitL1*) *it); - return ret; -} - -MEDFileMesh *MEDFileUMesh::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); - return ret.retn(); -} - -MEDFileMesh *MEDFileUMesh::createNewEmpty() const -{ - return new MEDFileUMesh; -} - -MEDFileMesh *MEDFileUMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); - ret->deepCpyEquivalences(*this); - if((const DataArrayDouble*)_coords) - ret->_coords=_coords->deepCpy(); - if((const DataArrayInt*)_fam_coords) - ret->_fam_coords=_fam_coords->deepCpy(); - if((const DataArrayInt*)_num_coords) - ret->_num_coords=_num_coords->deepCpy(); - if((const DataArrayInt*)_rev_num_coords) - ret->_rev_num_coords=_rev_num_coords->deepCpy(); - if((const DataArrayAsciiChar*)_name_coords) - ret->_name_coords=_name_coords->deepCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - ret->_ms[i]=(*it)->deepCpy(ret->_coords); - } - if((const PartDefinition*)_part_coords) - ret->_part_coords=_part_coords->deepCpy(); - return ret.retn(); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \param [in] eps - a precision used to compare real values. - * \param [in,out] what - the string returning description of unequal data. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileMesh::isEqual(other,eps,what)) - return false; - const MEDFileUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is unstructured and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const DataArrayDouble *coo1=_coords; - const DataArrayDouble *coo2=otherC->_coords; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of coordinates ! One is defined and not other !"; - return false; - } - if(coo1) - { - bool ret=coo1->isEqual(*coo2,eps); - if(!ret) - { - what="Coords differ !"; - return false; - } - } - const DataArrayInt *famc1=_fam_coords; - const DataArrayInt *famc2=otherC->_fam_coords; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on nodes ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on node differ !"; - return false; - } - } - const DataArrayInt *numc1=_num_coords; - const DataArrayInt *numc2=otherC->_num_coords; - if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0)) - { - what="Mismatch of numbering arr on nodes ! One is defined and not other !"; - return false; - } - if(numc1) - { - bool ret=numc1->isEqual(*numc2); - if(!ret) - { - what="Numbering arr on node differ !"; - return false; - } - } - const DataArrayAsciiChar *namec1=_name_coords; - const DataArrayAsciiChar *namec2=otherC->_name_coords; - if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0)) - { - what="Mismatch of naming arr on nodes ! One is defined and not other !"; - return false; - } - if(namec1) - { - bool ret=namec1->isEqual(*namec2); - if(!ret) - { - what="Names arr on node differ !"; - return false; - } - } - if(_ms.size()!=otherC->_ms.size()) - { - what="Number of levels differs !"; - return false; - } - std::size_t sz=_ms.size(); - for(std::size_t i=0;i_ms[i]; - if((s1==0 && s2!=0) || (s1!=0 && s2==0)) - { - what="Mismatch of presence of sub levels !"; - return false; - } - if(s1) - { - bool ret=s1->isEqual(s2,eps,what); - if(!ret) - return false; - } - } - const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords); - if(!pd0 && !pd1) - return true; - if((!pd0 && pd1) || (pd0 && !pd1)) - { - what=std::string("node part def is defined only for one among this or other !"); - return false; - } - return pd0->isEqual(pd1,what); -} - -/*! - * Clears redundant attributes of incorporated data arrays. - */ -void MEDFileUMesh::clearNonDiscrAttributes() const -{ - MEDFileMesh::clearNonDiscrAttributes(); - const DataArrayDouble *coo1=_coords; - if(coo1) - (const_cast(coo1))->setName("");//This parameter is not discriminant for comparison - const DataArrayInt *famc1=_fam_coords; - if(famc1) - (const_cast(famc1))->setName("");//This parameter is not discriminant for comparison - const DataArrayInt *numc1=_num_coords; - if(numc1) - (const_cast(numc1))->setName("");//This parameter is not discriminant for comparison - const DataArrayAsciiChar *namc1=_name_coords; - if(namc1) - (const_cast(namc1))->setName("");//This parameter is not discriminant for comparison - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - const MEDFileUMeshSplitL1 *tmp=(*it); - if(tmp) - tmp->clearNonDiscrAttributes(); - } -} - -void MEDFileUMesh::setName(const std::string& name) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - if((MEDFileUMeshSplitL1 *)(*it)!=0) - (*it)->setName(name); - MEDFileMesh::setName(name); -} - -MEDFileUMesh::MEDFileUMesh() -{ -} - -MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -try -{ - loadLLWithAdditionalItems(fid,mName,dt,it,mrs); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -/*! - * This method loads only a part of specified cells (given by range of cell ID per geometric type) - * See MEDFileUMesh::LoadPartOf for detailed description. - * - * \sa loadLL - */ -void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUMeshL2 loaderl2; - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); - if(meshType!=UNSTRUCTURED) - { - std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); - dispatchLoadedPart(fid,loaderl2,mName,mrs); -} - -/*! - * \brief Write joints in a file - */ -void MEDFileMesh::writeJoints(med_idt fid) const -{ - if ( (const MEDFileJoints*) _joints ) - _joints->write(fid); -} - -/*! - * \brief Load joints in a file or use provided ones - */ -//================================================================================ -/*! - * \brief Load joints in a file or use provided ones - * \param [in] fid - MED file descriptor - * \param [in] toUseInstedOfReading - optional joints to use instead of reading, - * Usually this joints are those just read by another iteration - * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New() - */ -//================================================================================ - -void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading) -{ - if ( toUseInstedOfReading ) - setJoints( toUseInstedOfReading ); - else - _joints = MEDFileJoints::New( fid, _name ); -} - -void MEDFileMesh::loadEquivalences(med_idt fid) -{ - int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name)); - if(nbOfEq>0) - _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this); -} - -void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other) -{ - const MEDFileEquivalences *equiv(other._equiv); - if(equiv) - _equiv=equiv->deepCpy(this); -} - -bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const -{ - const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv); - if(!thisEq && !otherEq) - return true; - if(thisEq && otherEq) - return thisEq->isEqual(otherEq,what); - else - { - what+="Equivalence differs : defined in this and not in other (or reversely) !"; - return false; - } -} - -void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const -{ - const MEDFileEquivalences *equiv(_equiv); - if(!equiv) - return ; - oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n"; - _equiv->getRepr(oss); -} - -/*! - * \brief Return number of joints, which is equal to number of adjacent mesh domains - */ -int MEDFileMesh::getNumberOfJoints() const -{ - return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0; -} - -/*! - * \brief Return joints with all adjacent mesh domains - */ -MEDFileJoints * MEDFileMesh::getJoints() const -{ - return const_cast(& (*_joints)); -} - -void MEDFileMesh::setJoints( MEDFileJoints* joints ) -{ - if ( joints != _joints ) - { - _joints = joints; - if ( joints ) - joints->incrRef(); - } -} - -/*! - * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor. - * - * \sa loadPartUMeshFromFile - */ -void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUMeshL2 loaderl2; - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); - if(meshType!=UNSTRUCTURED) - { - std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - loaderl2.loadAll(fid,mid,mName,dt,it,mrs); - dispatchLoadedPart(fid,loaderl2,mName,mrs); -} - -void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs) -{ - int lev=loaderl2.getNumberOfLevels(); - _ms.resize(lev); - for(int i=0;iisNodeFamilyFieldReading()) - _fam_coords=loaderl2.getCoordsFamily(); - if(!mrs || mrs->isNodeNumFieldReading()) - _num_coords=loaderl2.getCoordsNum(); - if(!mrs || mrs->isNodeNameFieldReading()) - _name_coords=loaderl2.getCoordsName(); - _part_coords=loaderl2.getPartDefOfCoo(); - computeRevNum(); -} - -MEDFileUMesh::~MEDFileUMesh() -{ -} - -void MEDFileUMesh::writeLL(med_idt fid) const -{ - const DataArrayDouble *coo=_coords; - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - int spaceDim=coo?coo->getNumberOfComponents():0; - int mdim(0); - if(!_ms.empty()) - mdim=getMeshDimension(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - for(int i=0;igetInfoOnComponent(i); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - if(_univ_wr_status) - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - (*it)->write(fid,meshName,mdim); - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str); -} - -/*! - * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getNonEmptyLevels() const -{ - std::vector ret; - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - if(!(*it)->empty()) - ret.push_back(lev); - return ret; -} - -/*! - * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getNonEmptyLevelsExt() const -{ - std::vector ret0=getNonEmptyLevels(); - if((const DataArrayDouble *) _coords) - { - std::vector ret(ret0.size()+1); - ret[0]=1; - std::copy(ret0.begin(),ret0.end(),ret.begin()+1); - return ret; - } - return ret0; -} - -std::vector MEDFileUMesh::getFamArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *famCoo(_fam_coords); - if(famCoo) - ret.push_back(1); - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - { - const MEDFileUMeshSplitL1 *cur(*it); - if(cur) - if(cur->getFamilyField()) - ret.push_back(lev); - } - return ret; -} - -std::vector MEDFileUMesh::getNumArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *numCoo(_num_coords); - if(numCoo) - ret.push_back(1); - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - { - const MEDFileUMeshSplitL1 *cur(*it); - if(cur) - if(cur->getNumberField()) - ret.push_back(lev); - } - return ret; -} - -std::vector MEDFileUMesh::getNameArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayAsciiChar *nameCoo(_name_coords); - if(nameCoo) - ret.push_back(1); - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - { - const MEDFileUMeshSplitL1 *cur(*it); - if(cur) - if(cur->getNameField()) - ret.push_back(lev); - } - return ret; -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where a given group is defined. - * To include nodes, call getGrpNonEmptyLevelsExt() method. - * \param [in] grp - the name of the group of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const -{ - std::vector fams=getFamiliesOnGroup(grp); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where a given group is defined. - * \param [in] grp - the name of the group of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const -{ - std::vector fams=getFamiliesOnGroup(grp); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where a given family is defined. - * To include nodes, call getFamNonEmptyLevelsExt() method. - * \param [in] fam - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const -{ - std::vector fams(1,std::string(fam)); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where a given family is defined. - * \param [in] fam - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const -{ - std::vector fams(1,std::string(fam)); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where given groups are defined. - * To include nodes, call getGrpsNonEmptyLevelsExt() method. - * \param [in] grps - a sequence of names of the groups of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector& grps) const -{ - std::vector fams=getFamiliesOnGroups(grps); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where given groups are defined. - * \param [in] grps - a sequence of names of the groups of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector& grps) const -{ - std::vector fams=getFamiliesOnGroups(grps); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where given families are defined. - * To include nodes, call getFamsNonEmptyLevelsExt() method. - * \param [in] fams - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamsNonEmptyLevels(const std::vector& fams) const -{ - std::vector ret; - std::vector levs=getNonEmptyLevels(); - std::vector famIds=getFamiliesIds(fams); - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - if(_ms[-(*it)]->presenceOfOneFams(famIds)) - ret.push_back(*it); - return ret; -} - -/*! - * Returns all relative mesh levels (including nodes) where given families are defined. - * \param [in] fams - the names of the families of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector& fams) const -{ - std::vector ret0=getFamsNonEmptyLevels(fams); - const DataArrayInt *famCoords=_fam_coords; - if(!famCoords) - return ret0; - std::vector famIds=getFamiliesIds(fams); - if(famCoords->presenceOfValue(famIds)) - { - std::vector ret(ret0.size()+1); - ret[0]=1; - std::copy(ret0.begin(),ret0.end(),ret.begin()+1); - return ret; - } - else - return ret0; -} - -/*! - * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt. - * \param [in] meshDimRelToMaxExt - a relative dimension of interest. - * \return std::vector - a sequence of group names at \a meshDimRelToMaxExt - * level. - */ -std::vector MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const -{ - std::vector ret; - std::vector allGrps=getGroupsNames(); - for(std::vector::const_iterator it=allGrps.begin();it!=allGrps.end();it++) - { - std::vector levs=getGrpNonEmptyLevelsExt((*it)); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end()) - ret.push_back(*it); - } - return ret; -} - -int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) - { - int val=_fam_coords->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - { - const DataArrayInt *da=(*it)->getFamilyField(); - if(da) - { - int val=da->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - } - } - return ret; -} - -int MEDFileUMesh::getMaxFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) - { - int val=_fam_coords->getMaxValue(tmp); - ret=std::max(ret,val); - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - { - const DataArrayInt *da=(*it)->getFamilyField(); - if(da) - { - int val=da->getMaxValue(tmp); - ret=std::max(ret,val); - } - } - } - return ret; -} - -int MEDFileUMesh::getMinFamilyIdInArrays() const -{ - int ret=std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) - { - int val=_fam_coords->getMinValue(tmp); - ret=std::min(ret,val); - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - { - const DataArrayInt *da=(*it)->getFamilyField(); - if(da) - { - int val=da->getMinValue(tmp); - ret=std::min(ret,val); - } - } - } - return ret; -} - -/*! - * Returns the dimension on cells in \a this mesh. - * \return int - the mesh dimension. - * \throw If there are no cells in this mesh. - */ -int MEDFileUMesh::getMeshDimension() const -{ - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - return (*it)->getMeshDimension()+lev; - throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !"); -} - -/*! - * Returns the space dimension of \a this mesh that is equal to number of components in - * the node coordinates array. - * \return int - the space dimension of \a this mesh. - * \throw If the node coordinates array is not available. - */ -int MEDFileUMesh::getSpaceDimension() const -{ - const DataArrayDouble *coo=_coords; - if(!coo) - throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !"); - return coo->getNumberOfComponents(); -} - -/*! - * Returns a string describing \a this mesh. - * \return std::string - the mesh information string. - */ -std::string MEDFileUMesh::simpleRepr() const -{ - std::ostringstream oss; - oss << MEDFileMesh::simpleRepr(); - const DataArrayDouble *coo=_coords; - oss << "- The dimension of the space is "; - static const char MSG1[]= "*** NO COORDS SET ***"; - static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***"; - if(coo) - oss << _coords->getNumberOfComponents() << std::endl; - else - oss << MSG1 << std::endl; - oss << "- Type of the mesh : UNSTRUCTURED\n"; - oss << "- Number of nodes : "; - if(coo) - oss << _coords->getNumberOfTuples() << std::endl; - else - oss << MSG1 << std::endl; - std::size_t nbOfLev=_ms.size(); - oss << "- Number of levels allocated : " << nbOfLev << std::endl; - for(std::size_t i=0;igetMeshDimension() << std::endl; - lev->simpleRepr(oss); - } - else - oss << MSG2 << std::endl; - } - oss << "- Number of families : " << _families.size() << std::endl << std::endl; - if(coo) - { - oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n"; - oss << "- Names of coordinates :" << std::endl; - std::vector vars=coo->getVarsOnComponent(); - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - oss << std::endl << "- Units of coordinates : " << std::endl; - std::vector units=coo->getUnitsOnComponent(); - std::copy(units.begin(),units.end(),std::ostream_iterator(oss," ")); - } - oss << std::endl << std::endl; - getFamilyRepr(oss); - getEquivalencesRepr(oss); - return oss.str(); -} - -/*! - * Returns a full textual description of \a this mesh. - * \return std::string - the string holding the mesh description. - */ -std::string MEDFileUMesh::advancedRepr() const -{ - return simpleRepr(); -} - -/*! - * Returns number of mesh entities of a given relative dimension in \a this mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \return int - the number of entities. - * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. - */ -int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - { - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !"); - return _coords->getNumberOfTuples(); - } - return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize(); -} - -/*! - * Returns the family field for mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families - * each mesh entity belongs to. It can be \c NULL. - */ -const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - return _fam_coords; - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getFamilyField(); -} - -DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) -{ - if(meshDimRelToMaxExt==1) - return _fam_coords; - MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getFamilyField(); -} - -/*! - * Returns the optional numbers of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - return _num_coords; - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getNumberField(); -} - -const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - return _name_coords; - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getNameField(); -} - -/*! - * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file). - * - * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested. - * \param [in] gt - The input geometric type for which the part definition is requested. - * \return the part definition owned by \a this. So no need to deallocate the returned instance. - */ -const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const -{ - if(meshDimRelToMaxExt==1) - return _part_coords; - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getPartDef(gt); -} - -int MEDFileUMesh::getNumberOfNodes() const -{ - const DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !"); - return coo->getNumberOfTuples(); -} - -int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const -{ - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getNumberOfCells(); -} - -bool MEDFileUMesh::hasImplicitPart() const -{ - return false; -} - -int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const -{ - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); -} - -void MEDFileUMesh::releaseImplicitPartIfAny() const -{ -} - -void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const -{ - std::size_t sz(st.getNumberOfItems()); - for(std::size_t i=0;icomputeNodeIdsAlg(nodesFetched); - else - { - const DataArrayInt *arr(globs->getProfile(st[i].getPflName())); - MEDCouplingAutoRefCountObjectPtr m2(dynamic_cast(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); - m2->computeNodeIdsAlg(nodesFetched); - } - } -} - -/*! - * Returns the optional numbers of mesh entities of a given dimension transformed using - * DataArrayInt::invertArrayN2O2O2N(). - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers transformed using - * DataArrayInt::invertArrayN2O2O2N(). - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - { - if(!((const DataArrayInt *)_num_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !"); - return _rev_num_coords; - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getRevNumberField(); -} - -/*! - * Returns a pointer to the node coordinates array of \a this mesh \b without - * incrementing its reference counter, thus there is no need to decrRef() it by the caller. - */ -DataArrayDouble *MEDFileUMesh::getCoords() const -{ - MEDCouplingAutoRefCountObjectPtr tmp(_coords); - if((DataArrayDouble *)tmp) - { - return tmp; - } - return 0; -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given - * group of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] grp - the name of the group whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - std::vector tmp(1); - tmp[0]=grp; - return getGroups(meshDimRelToMaxExt,tmp,renum); -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given - * groups of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] grps - a sequence of group names whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If a name of a nonexistent group is present in \a grps. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - std::vector fams2=getFamiliesOnGroups(grps); - MEDCouplingAutoRefCountObjectPtr zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum); - if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet)) - zeRet->setName(grps[0]); - return zeRet.retn(); -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given - * family of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] fam - the name of the family whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If a name of a nonexistent family is present in \a grps. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - std::vector tmp(1); - tmp[0]=fam; - return getFamilies(meshDimRelToMaxExt,tmp,renum); -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given - * families of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] fams - a sequence of family names whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If a name of a nonexistent family is present in \a fams. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - if(meshDimRelToMaxExt==1) - { - MEDCouplingAutoRefCountObjectPtr arr=getFamiliesArr(1,fams,renum); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); - ret->setCoords(c); - return ret.retn(); - } - std::vector famIds=getFamiliesIds(fams); - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr zeRet; - if(!famIds.empty()) - zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum); - else - zeRet=l1->getFamilyPart(0,0,renum); - if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet)) - zeRet->setName(fams[0]); - return zeRet.retn(); -} - -/*! - * Returns ids of mesh entities contained in given families of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] fams - the names of the families of interest. - * \param [in] renum - if \c true, the optional numbers of entities, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of mesh entities of the families. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const -{ - std::vector famIds=getFamiliesIds(fams); - if(meshDimRelToMaxExt==1) - { - if((const DataArrayInt *)_fam_coords) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_coords->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_coords,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !"); - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - if(!famIds.empty()) - return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum); - else - return l1->getFamilyPartArr(0,0,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a given relative dimension. - * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not - * valid**. This is a feature, because MEDLoader does not create cells that do not exist! - * To build a valid MEDCouplingUMesh from the returned one in this case, - * call MEDCouplingUMesh::Build0DMeshFromCoords(). - * \param [in] meshDimRelToMax - the relative dimension of interest. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \sa getGenMeshAtLevel() - */ -MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - if(meshDimRelToMaxExt==1) - { - if(!renum) - { - MEDCouplingUMesh *umesh=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr cc=_coords->deepCpy(); - umesh->setCoords(cc); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh); - umesh->setName(getName()); - return umesh; - } - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getWholeMesh(renum); -} - -/*! - * Returns a MEDCouplingUMesh of a given relative dimension. - * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not - * valid**. This is a feature, because MEDLoader does not create cells that do not exist! - * To build a valid MEDCouplingUMesh from the returned one in this case, - * call MEDCouplingUMesh::Build0DMeshFromCoords(). - * \param [in] meshDimRelToMax - the relative dimension of interest. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh. - * \sa getMeshAtLevel() - */ -MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const -{ - return getMeshAtLevel(meshDimRelToMax,renum); -} - -std::vector MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const -{ - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax)); - return l1->getDistributionOfTypes(); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == 0. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const -{ - return getMeshAtLevel(0,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == -1. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const -{ - return getMeshAtLevel(-1,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == -2. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const -{ - return getMeshAtLevel(-2,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == -3. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const -{ - return getMeshAtLevel(-3,renum); -} - -/*! - * This method is for advanced users. There is two storing strategy of mesh in \a this. - * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances. - * When assignement is done the first one is done, which is not optimal in write mode for MED file. - * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode. - */ -void MEDFileUMesh::forceComputationOfParts() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - const MEDFileUMeshSplitL1 *elt(*it); - if(elt) - elt->forceComputationOfParts(); - } -} - -/*! - * This method returns a vector of mesh parts containing each exactly one geometric type. - * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown). - * This method is only for memory aware users. - * The returned pointers are **NOT** new object pointer. No need to mange them. - */ -std::vector MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const -{ - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); - return sp->getDirectUndergroundSingleGeoTypeMeshes(); -} - -/*! - * This method returns the part of \a this having the geometric type \a gt. - * If such part is not existing an exception will be thrown. - * The returned pointer is **NOT** new object pointer. No need to mange it. - */ -MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int lev=(int)cm.getDimension()-getMeshDimension(); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); - return sp->getDirectUndergroundSingleGeoTypeMesh(gt); -} - -/*! - * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this. - * \throw if the reqsuested \a meshDimRelToMax does not exist. - */ -std::vector MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const -{ - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); - return sp->getGeoTypes(); -} - -int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() )); - return sp->getNumberOfCellsWithType(ct); -} - -/*! - * This method extracts from whole family field ids the part relative to the input parameter \a gt. - * \param [in] gt - the geometric type for which the family field is asked. - * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to - * delete using decrRef() as it is no more needed. - * \sa MEDFileUMesh::extractNumberFieldOnGeoType - */ -DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int lev=(int)cm.getDimension()-getMeshDimension(); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); - return sp->extractFamilyFieldOnGeoType(gt); -} - -/*! - * This method extracts from whole number field ids the part relative to the input parameter \a gt. - * \param [in] gt - the geometric type for which the number field is asked. - * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to - * delete using decrRef() as it is no more needed. - * \sa MEDFileUMesh::extractFamilyFieldOnGeoType - */ -DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int lev=(int)cm.getDimension()-getMeshDimension(); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); - return sp->extractNumberFieldOnGeoType(gt); -} - -/*! - * This method returns for specified geometric type \a gt the relative level to \a this. - * If the relative level is empty an exception will be thrown. - */ -int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int ret((int)cm.getDimension()-getMeshDimension()); - getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level. - return ret; -} - -const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); - int tracucedRk=-meshDimRelToMaxExt; - if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[tracucedRk]; -} - -MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) -{ - if(meshDimRelToMaxExt==1) - throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); - int tracucedRk=-meshDimRelToMaxExt; - if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[tracucedRk]; -} - -void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const -{ - if(-meshDimRelToMax>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !"); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) - { - if(((const MEDFileUMeshSplitL1*) (*it))!=0) - { - int ref=(*it)->getMeshDimension(); - if(ref+i!=meshDim-meshDimRelToMax) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !"); - } - } -} - -/*! - * Sets the node coordinates array of \a this mesh. - * \param [in] coords - the new node coordinates array. - * \throw If \a coords == \c NULL. - */ -void MEDFileUMesh::setCoords(DataArrayDouble *coords) -{ - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !"); - coords->checkAllocated(); - int nbOfTuples=coords->getNumberOfTuples(); - _coords=coords; - coords->incrRef(); - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nbOfTuples,1); - _fam_coords->fillWithZero(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - if((MEDFileUMeshSplitL1 *)(*it)) - (*it)->setCoords(coords); -} - -/*! - * Removes all groups of a given dimension in \a this mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) -{ - if(meshDimRelToMaxExt==1) - { - if((DataArrayInt *)_fam_coords) - _fam_coords->fillWithZero(); - return ; - } - MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - l1->eraseFamilyField(); - optimizeFamilies(); -} - -/*! - * Removes all families with ids not present in the family fields of \a this mesh. - */ -void MEDFileUMesh::optimizeFamilies() -{ - std::vector levs=getNonEmptyLevelsExt(); - std::set allFamsIds; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - const DataArrayInt *ffield=getFamilyFieldAtLevel(*it); - MEDCouplingAutoRefCountObjectPtr ids=ffield->getDifferentValues(); - std::set res; - std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin())); - allFamsIds=res; - } - std::set famNamesToKill; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - if(allFamsIds.find((*it).second)!=allFamsIds.end()) - famNamesToKill.insert((*it).first); - } - for(std::set::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++) - _families.erase(*it); - std::vector grpNamesToKill; - for(std::map >::iterator it=_groups.begin();it!=_groups.end();it++) - { - std::vector tmp; - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - { - if(famNamesToKill.find(*it2)==famNamesToKill.end()) - tmp.push_back(*it2); - } - if(!tmp.empty()) - (*it).second=tmp; - else - tmp.push_back((*it).first); - } - for(std::vector::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++) - _groups.erase(*it); -} - -/** - * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity - * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1. - * The boundary is built according to the following method: - * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the - * coordinates array is extended). - * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. - * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the - * other side of the group is no more a neighbor) - * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells - * bordering the newly created boundary use the newly computed nodes. - * - * \param[in] grpNameM1 name of the (-1)-level group defining the boundary - * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of - * the coord array) - * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes) - * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged. - */ -void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, - DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) -{ - std::vector levs=getNonEmptyLevels(); - if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !"); - MEDCouplingAutoRefCountObjectPtr m0=getMeshAtLevel(0); - MEDCouplingAutoRefCountObjectPtr m1=getMeshAtLevel(-1); - int nbNodes=m0->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr m11=getGroup(-1,grpNameM1); - DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0; - m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22); - MEDCouplingAutoRefCountObjectPtr nodeIdsToDuplicate(tmp00); - MEDCouplingAutoRefCountObjectPtr cellsToModifyConn0(tmp11); - MEDCouplingAutoRefCountObjectPtr cellsToModifyConn1(tmp22); - MEDCouplingAutoRefCountObjectPtr tmp0=static_cast(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true)); - // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1 - MEDCouplingAutoRefCountObjectPtr descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0); - descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0; - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW3=static_cast(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true)); - DataArrayInt *cellsInM1ToRenumW4Tmp=0; - m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells()); - cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end()); - MEDCouplingAutoRefCountObjectPtr grpIds=getGroupArr(-1,grpNameM1); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds); - MEDCouplingAutoRefCountObjectPtr m1Part=static_cast(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true)); - m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); - m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part); - // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1' - tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end()); - m0->setCoords(tmp0->getCoords()); - m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0); - m1->setCoords(m0->getCoords()); - _coords=m0->getCoords(); _coords->incrRef(); - // duplication of cells in group 'grpNameM1' on level -1 - m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords()); - std::vector v(2); v[0]=m1; v[1]=m11; - MEDCouplingAutoRefCountObjectPtr newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11); - MEDCouplingAutoRefCountObjectPtr szOfCellGrpOfSameType(tmp00); - MEDCouplingAutoRefCountObjectPtr idInMsOfCellGrpOfSameType(tmp11); - // - newm1->setName(getName()); - const DataArrayInt *fam=getFamilyFieldAtLevel(-1); - if(!fam) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !"); - MEDCouplingAutoRefCountObjectPtr newFam=DataArrayInt::New(); - newFam->alloc(newm1->getNumberOfCells(),1); - // Get a new family ID: care must be taken if we need a positive ID or a negative one: - // Positive ID for family of nodes, negative for all the rest. - int idd; - if (m1->getMeshDimension() == 0) - idd=getMaxFamilyId()+1; - else - idd=getMinFamilyId()-1; - int globStart=0,start=0,end,globEnd; - int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples(); - for(int i=0;igetIJ(i,0); - if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0) - { - end=start+szOfCellGrpOfSameType->getIJ(i,0); - MEDCouplingAutoRefCountObjectPtr part=fam->selectByTupleId2(start,end,1); - newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true); - start=end; - } - else - { - newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1); - } - globStart=globEnd; - } - newm1->setCoords(getCoords()); - setMeshAtLevel(-1,newm1); - setFamilyFieldArr(-1,newFam); - std::string grpName2(grpNameM1); grpName2+="_dup"; - addFamily(grpName2,idd); - addFamilyOnGrp(grpName2,grpName2); - // - fam=_fam_coords; - if(fam) - { - int newNbOfNodes=getCoords()->getNumberOfTuples(); - newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1); - newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true); - newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1); - _fam_coords=newFam; - } - nodesDuplicated=nodeIdsToDuplicate.retn(); - cellsModified=cellsToModifyConn0.retn(); - cellsNotModified=cellsToModifyConn1.retn(); -} - -/*! - * \param [out] oldCode retrieves the distribution of types before the call if true is returned - * \param [out] newCode etrieves the distribution of types after the call if true is returned - * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells. - * - * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering. - * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered. - */ -bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) -{ - o2nRenumCell=0; oldCode.clear(); newCode.clear(); - std::vector levs=getNonEmptyLevels(); - bool ret=false; - std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow - std::vector< MEDCouplingAutoRefCountObjectPtr > memorySaverIfThrow;//same than renumCellsSplited only in case of throw - int start=0; - int end=0; - for(std::vector::reverse_iterator it=levs.rbegin();it!=levs.rend();it++) - { - MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*it); - std::vector code1=m->getDistributionOfTypes(); - end=PutInThirdComponentOfCodeOffset(code1,start); - oldCode.insert(oldCode.end(),code1.begin(),code1.end()); - bool hasChanged=m->unPolyze(); - DataArrayInt *fake=0; - MEDCouplingAutoRefCountObjectPtr o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, - MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); - fake->decrRef(); - renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart); - if(hasChanged) - { - MEDCouplingAutoRefCountObjectPtr o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel(); - m->renumberCells(o2nCellsPart2->getConstPointer(),false); - ret=true; - MEDCouplingAutoRefCountObjectPtr famField2,numField2; - const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast(famField); } - const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast(numField); } - setMeshAtLevel(*it,m); - std::vector code2=m->getDistributionOfTypes(); - end=PutInThirdComponentOfCodeOffset(code2,start); - newCode.insert(newCode.end(),code2.begin(),code2.end()); - // - if(o2nCellsPart2->isIdentity()) - continue; - if(famField) - { - MEDCouplingAutoRefCountObjectPtr newFamField=famField->renumber(o2nCellsPart2->getConstPointer()); - setFamilyFieldArr(*it,newFamField); - } - if(numField) - { - MEDCouplingAutoRefCountObjectPtr newNumField=numField->renumber(o2nCellsPart2->getConstPointer()); - setRenumFieldArr(*it,newNumField); - } - } - else - { - newCode.insert(newCode.end(),code1.begin(),code1.end()); - } - start=end; - } - if(ret) - { - MEDCouplingAutoRefCountObjectPtr renumCells=DataArrayInt::Aggregate(renumCellsSplited); - MEDCouplingAutoRefCountObjectPtr o2nRenumCellRet=renumCells->buildPermArrPerLevel(); - o2nRenumCell=o2nRenumCellRet.retn(); - } - return ret; -} - -/*! \cond HIDDEN_ITEMS */ -struct MEDLoaderAccVisit1 -{ - MEDLoaderAccVisit1():_new_nb_of_nodes(0) { } - int operator()(bool val) { return val?_new_nb_of_nodes++:-1; } - int _new_nb_of_nodes; -}; -/*! \endcond */ - -/*! - * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller. - * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method. - * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes. - * -1 values in returned array means that the corresponding old node is no more used. - * - * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing - * is modified in \a this. - * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of - * set coordinates. - */ -DataArrayInt *MEDFileUMesh::zipCoords() -{ - const DataArrayDouble *coo(getCoords()); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); - int nbOfNodes(coo->getNumberOfTuples()); - std::vector nodeIdsInUse(nbOfNodes,false); - std::vector neLevs(getNonEmptyLevels()); - for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) - { - const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev)); - if(zeLev->isMeshStoredSplitByType()) - { - std::vector ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes()); - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - if(*it) - (*it)->computeNodeIdsAlg(nodeIdsInUse); - } - else - { - MEDCouplingAutoRefCountObjectPtr mesh(zeLev->getWholeMesh(false)); - mesh->computeNodeIdsAlg(nodeIdsInUse); - } - } - int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); - if(nbrOfNodesInUse==nbOfNodes) - return 0;//no need to update _part_coords - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1); - std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); - MEDCouplingAutoRefCountObjectPtr ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); - MEDCouplingAutoRefCountObjectPtr newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); - MEDCouplingAutoRefCountObjectPtr newFamCoords; - MEDCouplingAutoRefCountObjectPtr newNameCoords; - if((const DataArrayInt *)_fam_coords) - newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - MEDCouplingAutoRefCountObjectPtr newNumCoords; - if((const DataArrayInt *)_num_coords) - newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - if((const DataArrayAsciiChar *)_name_coords) - newNameCoords=static_cast(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end())); - _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - { - if((MEDFileUMeshSplitL1*)*it) - { - (*it)->renumberNodesInConn(ret->begin()); - (*it)->setCoords(_coords); - } - } - // updates _part_coords - const PartDefinition *pc(_part_coords); - if(pc) - { - MEDCouplingAutoRefCountObjectPtr tmpPD(DataArrayPartDefinition::New(ret2)); - _part_coords=tmpPD->composeWith(pc); - } - return ret.retn(); -} - -/*! - * This method performs an extrusion along a path defined by \a m1D. - * \a this is expected to be a mesh with max mesh dimension equal to 2. - * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1. - * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this. - * This method scans all levels in \a this - * and put them in the returned mesh. All groups in \a this are also put in the returned mesh. - * - * \param [in] m1D - the mesh defining the extrusion path. - * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details) - * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this. - * - * \sa MEDCouplingUMesh::buildExtrudedMesh - */ -MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const -{ - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - m1D->checkCoherency(); - if(m1D->getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !"); - int nbRep(m1D->getNumberOfCells()); - std::vector levs(getNonEmptyLevels()); - std::vector grps(getGroupsNames()); - std::vector< MEDCouplingAutoRefCountObjectPtr > zeList; - DataArrayDouble *coords(0); - std::size_t nbOfLevsOut(levs.size()+1); - std::vector< MEDCouplingAutoRefCountObjectPtr > o2ns(nbOfLevsOut); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - MEDCouplingAutoRefCountObjectPtr item(getMeshAtLevel(*lev)); - item=item->clone(false); - item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data - MEDCouplingAutoRefCountObjectPtr tmp(static_cast(m1D->deepCpy())); - tmp->changeSpaceDimension(3+(*lev),0.); - MEDCouplingAutoRefCountObjectPtr elt(item->buildExtrudedMesh(tmp,policy)); - zeList.push_back(elt); - if(*lev==0) - coords=elt->getCoords(); - } - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !"); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=zeList.begin();it!=zeList.end();it++) - { - (*it)->setName(getName()); - (*it)->setCoords(coords); - } - for(std::size_t ii=0;ii!=zeList.size();ii++) - { - int lev(levs[ii]); - MEDCouplingAutoRefCountObjectPtr elt(zeList[ii]); - if(lev<=-1) - { - MEDCouplingAutoRefCountObjectPtr elt1(getMeshAtLevel(lev+1)); - MEDCouplingAutoRefCountObjectPtr elt2(elt1->clone(false)); - MEDCouplingAutoRefCountObjectPtr tmp(elt2->getNodalConnectivity()->deepCpy()); - elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex()); - elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes()); - elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords()); - std::vector elts(3); - elts[0]=elt; elts[1]=elt1; elts[2]=elt2; - elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts); - elt->setName(getName()); - } - // - o2ns[ii]=elt->sortCellsInMEDFileFrmt(); - ret->setMeshAtLevel(lev,elt); - } - MEDCouplingAutoRefCountObjectPtr endLev(getMeshAtLevel(levs.back())),endLev2; - endLev=endLev->clone(false); endLev->setCoords(coords); - MEDCouplingAutoRefCountObjectPtr tmp(endLev->getNodalConnectivity()->deepCpy()); - endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex()); - endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes()); - endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2); - o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt(); - endLev->setName(getName()); - ret->setMeshAtLevel(levs.back()-1,endLev); - // - for(std::size_t ii=0;ii!=zeList.size();ii++) - { - int lev(levs[ii]); - std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; - std::vector< const DataArrayInt * > outGrps2; - if(lev<=-1) - { - for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) - { - MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev+1,*grp)); - if(!grpArr->empty()) - { - MEDCouplingAutoRefCountObjectPtr grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy()); - int offset0(zeList[ii]->getNumberOfCells()); - int offset1(offset0+getNumberOfCellsAtLevel(lev+1)); - grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1); - std::ostringstream oss; oss << grpArr2->getName() << "_top"; - grpArr2->setName(oss.str()); - grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); - grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); - outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); - outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); - } - } - } - // - for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) - { - MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev,*grp)); - if(!grpArr->empty()) - { - int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); - std::vector< MEDCouplingAutoRefCountObjectPtr > grpArrs(nbRep); - std::vector< const DataArrayInt *> grpArrs2(nbRep); - for(int iii=0;iiideepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); - grpArrs2[iii]=grpArrs[iii]; - } - MEDCouplingAutoRefCountObjectPtr grpArrExt(DataArrayInt::Aggregate(grpArrs2)); - grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); - std::ostringstream grpName; grpName << *grp << "_extruded"; - grpArrExt->setName(grpName.str()); - outGrps.push_back(grpArrExt); - outGrps2.push_back(grpArrExt); - } - } - ret->setGroupsAtLevel(lev,outGrps2); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; - std::vector< const DataArrayInt * > outGrps2; - for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) - { - MEDCouplingAutoRefCountObjectPtr grpArr1(getGroupArr(levs.back(),*grp)); - if(grpArr1->empty()) - continue; - MEDCouplingAutoRefCountObjectPtr grpArr2(grpArr1->deepCpy()); - std::ostringstream grpName; grpName << *grp << "_top"; - grpArr2->setName(grpName.str()); - grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back())); - outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); - outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); - } - ret->setGroupsAtLevel(levs.back()-1,outGrps2); - return ret.retn(); -} - -/*! - * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy). - * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. - * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. - * - * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple - * corresponding quadratic cells. 1 is those creating the 'most' complex. - * \param [in] eps - detection threshold for coordinates. - * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. - * - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear - */ -MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - int initialNbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); - { - MEDCouplingAutoRefCountObjectPtr notUsed(m0->convertLinearCellsToQuadratic(conversionType)); - } - DataArrayDouble *zeCoords(m0->getCoords()); - ret->setMeshAtLevel(0,m0); - std::vector levs(getNonEmptyLevels()); - const DataArrayInt *famField(getFamilyFieldAtLevel(0)); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(0,famFieldCpy); - } - famField=getFamilyFieldAtLevel(1); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); - fam->fillWithZero(); - fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1); - ret->setFamilyFieldArr(1,fam); - } - ret->copyFamGrpMapsFrom(*this); - MEDCouplingAutoRefCountObjectPtr partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1)); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - if(*lev==0) - continue; - MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); - MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); - if(m1->getMeshDimension()!=0) - { - { - MEDCouplingAutoRefCountObjectPtr notUsed(m1->convertLinearCellsToQuadratic(conversionType)); - }//kill unused notUsed var - MEDCouplingAutoRefCountObjectPtr m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); - DataArrayInt *b(0); - bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); - if(!a) - { - std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - b->applyLin(1,initialNbNodes); - MEDCouplingAutoRefCountObjectPtr l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); - std::vector v(2); v[0]=l0; v[1]=b; - MEDCouplingAutoRefCountObjectPtr renum(DataArrayInt::Aggregate(v)); - m1->renumberNodesInConn(renum->begin()); - } - m1->setCoords(zeCoords); - ret->setMeshAtLevel(*lev,m1); - famField=getFamilyFieldAtLevel(*lev); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(*lev,famFieldCpy); - } - } - return ret.retn(); -} - -/*! - * This method converts all quadratic cells in \a this into linear cells. - * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. - * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. - * - * \param [in] eps - detection threshold for coordinates. - * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. - * - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic - */ -MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); - m0->convertQuadraticCellsToLinear(); - m0->zipCoords(); - DataArrayDouble *zeCoords(m0->getCoords()); - ret->setMeshAtLevel(0,m0); - std::vector levs(getNonEmptyLevels()); - const DataArrayInt *famField(getFamilyFieldAtLevel(0)); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(0,famFieldCpy); - } - famField=getFamilyFieldAtLevel(1); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1)); - ret->setFamilyFieldArr(1,fam); - } - ret->copyFamGrpMapsFrom(*this); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - if(*lev==0) - continue; - MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); - MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); - m1->convertQuadraticCellsToLinear(); - m1->zipCoords(); - DataArrayInt *b(0); - bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); - if(!a) - { - std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - m1->renumberNodesInConn(b->begin()); - m1->setCoords(zeCoords); - ret->setMeshAtLevel(*lev,m1); - famField=getFamilyFieldAtLevel(*lev); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(*lev,famFieldCpy); - } - } - return ret.retn(); -} - -void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) -{ - clearNonDiscrAttributes(); - forceComputationOfParts(); - tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; - std::vector layer0; - layer0.push_back(_order); //0 i - layer0.push_back(_iteration);//1 i - layer0.push_back(getSpaceDimension());//2 i - tinyDouble.push_back(_time);//0 d - tinyStr.push_back(_name);//0 s - tinyStr.push_back(_desc_name);//1 s - for(int i=0;igetInfoOnComponent(i)); - layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - tinyStr.push_back((*it).first); - layer0.push_back((*it).second); - } - layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0 - for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - { - layer0.push_back((int)(*it0).second.size()); - tinyStr.push_back((*it0).first); - for(std::vector::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++) - tinyStr.push_back(*it1); - } - // sizeof(layer0)==3+aa+1+bb layer#0 - bigArrayD=_coords;// 0 bd - bigArraysI.push_back(_fam_coords);// 0 bi - bigArraysI.push_back(_num_coords);// 1 bi - const PartDefinition *pd(_part_coords); - if(!pd) - layer0.push_back(-1); - else - { - std::vector tmp0; - pd->serialize(tmp0,bigArraysI); - tinyInt.push_back(tmp0.size()); - tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); - } - // - std::vector layer1; - std::vector levs(getNonEmptyLevels()); - layer1.push_back((int)levs.size());// 0 i <- key - layer1.insert(layer1.end(),levs.begin(),levs.end()); - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it)); - lev->serialize(layer1,bigArraysI); - } - // put layers all together. - tinyInt.push_back(layer0.size()); - tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end()); - tinyInt.push_back(layer1.size()); - tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end()); -} - -void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) -{ - int sz0(tinyInt[0]); - std::vector layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); - int sz1(tinyInt[sz0+1]); - std::vector layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1); - // - std::reverse(layer0.begin(),layer0.end()); - std::reverse(layer1.begin(),layer1.end()); - std::reverse(tinyDouble.begin(),tinyDouble.end()); - std::reverse(tinyStr.begin(),tinyStr.end()); - std::reverse(bigArraysI.begin(),bigArraysI.end()); - // - _order=layer0.back(); layer0.pop_back(); - _iteration=layer0.back(); layer0.pop_back(); - int spaceDim(layer0.back()); layer0.pop_back(); - _time=tinyDouble.back(); tinyDouble.pop_back(); - _name=tinyStr.back(); tinyStr.pop_back(); - _desc_name=tinyStr.back(); tinyStr.pop_back(); - _coords=bigArrayD; _coords->rearrange(spaceDim); - for(int i=0;isetInfoOnComponent(i,tinyStr.back()); - tinyStr.pop_back(); - } - int nbOfFams(layer0.back()); layer0.pop_back(); - _families.clear(); - for(int i=0;i fams(nbOfFamsOnGrp); - for(int j=0;j tmp0(layer0.begin(),layer0.begin()+isPd); - layer0.erase(layer0.begin(),layer0.begin()+isPd); - _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI); - } - if(!layer0.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !"); - // - int nbLevs(layer1.back()); layer1.pop_back(); - std::vector levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end()); - _ms.clear(); - int maxLev(-(*std::min_element(levs.begin(),levs.end()))); - _ms.resize(maxLev+1); - for(int i=0;igetName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) -{ - const DataArrayDouble *coords(_coords); - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); - int nbOfNodes(coords->getNumberOfTuples()); - if(!((DataArrayInt *)_fam_coords)) - { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } - // - addGroupUnderground(true,ids,_fam_coords); -} - -/*! - * Adds a group of nodes/cells/faces/edges to \a this mesh. - * - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. - * The ids should be sorted and different each other (MED file norm). - * - * \warning this method can alter default "FAMILLE_ZERO" family. - * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. - * - * \throw If the node coordinates array is not set. - * \throw If \a ids == \c NULL. - * \throw If \a ids->getName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) -{ - std::vector levs(getNonEmptyLevelsExt()); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) - { - std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in "; - std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(meshDimRelToMaxExt==1) - { addNodeGroup(ids); return ; } - MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt)); - DataArrayInt *fam(lev->getOrCreateAndGetFamilyField()); - addGroupUnderground(false,ids,fam); -} - -/*! - * Changes a name of a family specified by its id. - * \param [in] id - the id of the family of interest. - * \param [in] newFamName - the new family name. - * \throw If no family with the given \a id exists. - */ -void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) -{ - std::string oldName=getFamilyNameGivenId(id); - _families.erase(oldName); - _families[newFamName]=id; -} - -/*! - * Removes a mesh of a given dimension. - * \param [in] meshDimRelToMax - the relative dimension of interest. - * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh. - */ -void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) -{ - std::vector levSet=getNonEmptyLevels(); - std::vector::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax); - if(it==levSet.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !"); - int pos=(-meshDimRelToMax); - _ms[pos]=0; -} - -/*! - * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh. - * \param [in] meshDimRelToMax - a relative level to set the mesh at. - * \param [in] m - the new mesh to set. - * \throw If the name or the description of \a this mesh and \a m are not empty and are - * different. - * \throw If the node coordinates array is set \a this in mesh and \a m refers to - * another node coordinates array. - * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - */ -void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) -{ - MEDCouplingAutoRefCountObjectPtr elt(new MEDFileUMeshSplitL1(m)); - checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; -} - -/*! - * Sets a new MEDCouplingUMesh at a given level in \a this mesh. - * \param [in] meshDimRelToMax - a relative level to set the mesh at. - * \param [in] m - the new mesh to set. - * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for - * writing \a this mesh in a MED file. - * \throw If the name or the description of \a this mesh and \a m are not empty and are - * different. - * \throw If the node coordinates array is set \a this in mesh and \a m refers to - * another node coordinates array. - * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - */ -void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) -{ - MEDCouplingAutoRefCountObjectPtr elt(new MEDFileUMeshSplitL1(m,newOrOld)); - checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; -} - -MEDCouplingAutoRefCountObjectPtr& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m) -{ - dealWithTinyInfo(m); - std::vector levSet=getNonEmptyLevels(); - if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end()) - { - if((DataArrayDouble *)_coords==0) - { - DataArrayDouble *c=m->getCoords(); - if(c) - c->incrRef(); - _coords=c; - } - if(m->getCoords()!=_coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !"); - int sz=(-meshDimRelToMax)+1; - if(sz>=(int)_ms.size()) - _ms.resize(sz); - checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax); - return _ms[sz-1]; - } - else - return _ms[-meshDimRelToMax]; -} - -/*! - * This method allows to set at once the content of different levels in \a this. - * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel. - * - * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion. - * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted. - * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false. - * - * \throw If \a there is a null pointer in \a ms. - * \sa MEDFileUMesh::setMeshAtLevel - */ -void MEDFileUMesh::setMeshes(const std::vector& ms, bool renum) -{ - if(ms.empty()) - return ; - const MEDCouplingUMesh *mRef=ms[0]; - if(!mRef) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !"); - std::string name(mRef->getName()); - const DataArrayDouble *coo(mRef->getCoords()); - std::set s; - int zeDim=-1; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - { - const MEDCouplingUMesh *cur(*it); - if(!cur) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !"); - if(coo!=cur->getCoords()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !"); - int mdim=cur->getMeshDimension(); - zeDim=std::max(zeDim,mdim); - if(s.find(mdim)!=s.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !"); - } - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - { - int mdim=(*it)->getMeshDimension(); - setName((*it)->getName()); - setMeshAtLevel(mdim-zeDim,const_cast(*it),renum); - } - setName(name); -} - -/*! - * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of - * meshes each representing a group, and creates corresponding groups in \a this mesh. - * The given meshes must share the same node coordinates array. - * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at. - * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to - * create in \a this mesh. - * \throw If \a ms is empty. - * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - * \throw If the meshes in \a ms do not share the same node coordinates array. - * \throw If the node coordinates array of \a this mesh (if any) is not the same as that - * of the given meshes. - * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). - * \throw If names of some meshes in \a ms are equal. - * \throw If \a ms includes a mesh with an empty name. - */ -void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms, bool renum) -{ - if(ms.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !"); - int sz=(-meshDimRelToMax)+1; - if(sz>=(int)_ms.size()) - _ms.resize(sz); - checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax); - DataArrayDouble *coo=checkMultiMesh(ms); - if((DataArrayDouble *)_coords==0) - { - coo->incrRef(); - _coords=coo; - } - else - if((DataArrayDouble *)_coords!=coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !"); - std::vector corr; - MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr); - std::vector< MEDCouplingAutoRefCountObjectPtr > corr3(corr.begin(),corr.end()); - setMeshAtLevel(meshDimRelToMax,m,renum); - std::vector corr2(corr.begin(),corr.end()); - setGroupsAtLevel(meshDimRelToMax,corr2,true); -} - -/*! - * Creates groups at a given level in \a this mesh from a sequence of - * meshes each representing a group. - * The given meshes must share the same node coordinates array. - * \param [in] meshDimRelToMax - the relative dimension to create the groups at. - * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to - * create in \a this mesh. - * \param [in] renum - if \c true, then the optional numbers of entities are taken into - * account. - * \throw If \a ms is empty. - * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - * \throw If the meshes in \a ms do not share the same node coordinates array. - * \throw If the node coordinates array of \a this mesh (if any) is not the same as that - * of the given meshes. - * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). - * \throw If names of some meshes in \a ms are equal. - * \throw If \a ms includes a mesh with an empty name. - */ -void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum) -{ - if(ms.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !"); - int sz=(-meshDimRelToMax)+1; - if(sz>=(int)_ms.size()) - _ms.resize(sz); - checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax); - DataArrayDouble *coo=checkMultiMesh(ms); - if((DataArrayDouble *)_coords==0) - { - coo->incrRef(); - _coords=coo; - } - else - if((DataArrayDouble *)_coords!=coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !"); - MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum); - std::vector< MEDCouplingAutoRefCountObjectPtr > corr(ms.size()); - int i=0; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) - { - DataArrayInt *arr=0; - bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr); - corr[i]=arr; - if(!test) - { - std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - std::vector corr2(corr.begin(),corr.end()); - setGroupsAtLevel(meshDimRelToMax,corr2,renum); -} - -DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector& ms) const -{ - const DataArrayDouble *ret=ms[0]->getCoords(); - int mdim=ms[0]->getMeshDimension(); - for(unsigned int i=1;icheckCoherency(); - if(ms[i]->getCoords()!=ret) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !"); - if(ms[i]->getMeshDimension()!=mdim) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !"); - } - return const_cast(ret); -} - -/*! - * Sets the family field of a given relative dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which - * the family field is set. - * \param [in] famArr - the array of the family field. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a famArr has an invalid size. - */ -void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) -{ - if(meshDimRelToMaxExt==1) - { - if(!famArr) - { - _fam_coords=0; - return ; - } - DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !"); - famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! "); - famArr->incrRef(); - _fam_coords=famArr; - return ; - } - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !"); - int traducedRk=-meshDimRelToMaxExt; - if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[traducedRk]->setFamilyArr(famArr); -} - -/*! - * Sets the optional numbers of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] renumArr - the array of the numbers. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a renumArr has an invalid size. - */ -void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) -{ - if(meshDimRelToMaxExt==1) - { - if(!renumArr) - { - _num_coords=0; - _rev_num_coords=0; - return ; - } - DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !"); - renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! "); - renumArr->incrRef(); - _num_coords=renumArr; - computeRevNum(); - return ; - } - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !"); - int traducedRk=-meshDimRelToMaxExt; - if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[traducedRk]->setRenumArr(renumArr); -} - -/*! - * Sets the optional names of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] nameArr - the array of the names. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a nameArr has an invalid size. - */ -void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) -{ - if(meshDimRelToMaxExt==1) - { - if(!nameArr) - { - _name_coords=0; - return ; - } - DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !"); - nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! "); - nameArr->incrRef(); - _name_coords=nameArr; - return ; - } - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !"); - int traducedRk=-meshDimRelToMaxExt; - if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[traducedRk]->setNameArr(nameArr); -} - -void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1 *)(*it)) - (*it)->synchronizeTinyInfo(*this); -} - -/*! - * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification. - */ -void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) -{ - DataArrayInt *arr=_fam_coords; - if(arr) - arr->changeValue(oldId,newId); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - { - MEDFileUMeshSplitL1 *sp=(*it); - if(sp) - { - sp->changeFamilyIdArr(oldId,newId); - } - } -} - -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileUMesh::getAllNonNullFamilyIds() const -{ - std::list< MEDCouplingAutoRefCountObjectPtr > ret; - const DataArrayInt *da(_fam_coords); - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - const MEDFileUMeshSplitL1 *elt(*it); - if(elt) - { - da=elt->getFamilyField(); - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - } - } - return ret; -} - -void MEDFileUMesh::computeRevNum() const -{ - if((const DataArrayInt *)_num_coords) - { - int pos; - int maxValue=_num_coords->getMaxValue(pos); - _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1); - } -} - -std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileStructuredMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayInt *)_fam_nodes); - ret.push_back((const DataArrayInt *)_num_nodes); - ret.push_back((const DataArrayAsciiChar *)_names_nodes); - ret.push_back((const DataArrayInt *)_fam_cells); - ret.push_back((const DataArrayInt *)_num_cells); - ret.push_back((const DataArrayAsciiChar *)_names_cells); - ret.push_back((const DataArrayInt *)_fam_faces); - ret.push_back((const DataArrayInt *)_num_faces); - ret.push_back((const DataArrayInt *)_rev_num_nodes); - ret.push_back((const DataArrayAsciiChar *)_names_faces); - ret.push_back((const DataArrayInt *)_rev_num_cells); - ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); - return ret; -} - -int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) - { - int val=_fam_nodes->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - if((const DataArrayInt *)_fam_cells) - { - int val=_fam_cells->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - if((const DataArrayInt *)_fam_faces) - { - int val=_fam_faces->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - return ret; -} - -int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) - { - int val=_fam_nodes->getMaxValue(tmp); - ret=std::max(ret,val); - } - if((const DataArrayInt *)_fam_cells) - { - int val=_fam_cells->getMaxValue(tmp); - ret=std::max(ret,val); - } - if((const DataArrayInt *)_fam_faces) - { - int val=_fam_faces->getMaxValue(tmp); - ret=std::max(ret,val); - } - return ret; -} - -int MEDFileStructuredMesh::getMinFamilyIdInArrays() const -{ - int ret=std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) - { - int val=_fam_nodes->getMinValue(tmp); - ret=std::min(ret,val); - } - if((const DataArrayInt *)_fam_cells) - { - int val=_fam_cells->getMinValue(tmp); - ret=std::min(ret,val); - } - if((const DataArrayInt *)_fam_faces) - { - int val=_fam_faces->getMinValue(tmp); - ret=std::min(ret,val); - } - return ret; -} - -bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileMesh::isEqual(other,eps,what)) - return false; - const MEDFileStructuredMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is structured and other is NOT !"; - return false; - } - const DataArrayInt *famc1=_fam_nodes; - const DataArrayInt *famc2=otherC->_fam_nodes; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on nodes ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on nodes differ !"; - return false; - } - } - famc1=_fam_cells; - famc2=otherC->_fam_cells; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on cells ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on cells differ !"; - return false; - } - } - famc1=_fam_faces; - famc2=otherC->_fam_faces; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on faces ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on faces differ !"; - return false; - } - } - famc1=_num_nodes; - famc2=otherC->_num_nodes; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of numbering arr on nodes ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Numbering arr on nodes differ !"; - return false; - } - } - famc1=_num_cells; - famc2=otherC->_num_cells; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of numbering arr on cells ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Numbering arr on cells differ !"; - return false; - } - } - famc1=_num_faces; - famc2=otherC->_num_faces; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of numbering arr on faces ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Numbering arr on faces differ !"; - return false; - } - } - const DataArrayAsciiChar *d1=_names_cells; - const DataArrayAsciiChar *d2=otherC->_names_cells; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Mismatch of naming arr on cells ! One is defined and not other !"; - return false; - } - if(d1) - { - bool ret=d1->isEqual(*d2); - if(!ret) - { - what="Naming arr on cells differ !"; - return false; - } - } - d1=_names_faces; - d2=otherC->_names_faces; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Mismatch of naming arr on faces ! One is defined and not other !"; - return false; - } - if(d1) - { - bool ret=d1->isEqual(*d2); - if(!ret) - { - what="Naming arr on faces differ !"; - return false; - } - } - d1=_names_nodes; - d2=otherC->_names_nodes; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Mismatch of naming arr on nodes ! One is defined and not other !"; - return false; - } - if(d1) - { - bool ret=d1->isEqual(*d2); - if(!ret) - { - what="Naming arr on nodes differ !"; - return false; - } - } - return true; -} - -void MEDFileStructuredMesh::clearNonDiscrAttributes() const -{ - MEDFileMesh::clearNonDiscrAttributes(); - const DataArrayInt *tmp=_fam_nodes; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_num_nodes; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_fam_cells; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_num_cells; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_fam_faces; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_num_faces; - if(tmp) - (const_cast(tmp))->setName(""); -} - -/*! - * Returns ids of mesh entities contained in given families of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] fams - the names of the families of interest. - * \param [in] renum - if \c true, the optional numbers of entities, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of mesh entities of the families. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const -{ - std::vector famIds(getFamiliesIds(fams)); - switch(meshDimRelToMaxExt) - { - case 1: - { - if((const DataArrayInt *)_fam_nodes) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_nodes->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); - break; - } - case 0: - { - if((const DataArrayInt *)_fam_cells) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_cells->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_cells,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); - break; - } - case -1: - { - if((const DataArrayInt *)_fam_faces) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_faces->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_faces,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !"); - } - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !"); -} - -/*! - * Sets the family field of a given relative dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which - * the family field is set. - * \param [in] famArr - the array of the family field. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a famArr has an invalid size. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. - */ -void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) -{ - const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); - switch(meshDimRelToMaxExt) - { - case 0: - { - int nbCells=mesh->getNumberOfCells(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); - _fam_cells=famArr; - break; - } - case 1: - { - int nbNodes=mesh->getNumberOfNodes(); - famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _fam_nodes=famArr; - break; - } - case -1: - { - int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !"); - _fam_faces=famArr; - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !"); - } - if(famArr) - famArr->incrRef(); -} - -/*! - * Sets the optional numbers of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] renumArr - the array of the numbers. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a renumArr has an invalid size. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) -{ - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); - switch(meshDimRelToMaxExt) - { - case 0: - { - int nbCells=mesh->getNumberOfCells(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); - _num_cells=renumArr; - break; - } - case 1: - { - int nbNodes=mesh->getNumberOfNodes(); - renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _num_nodes=renumArr; - break; - } - case -1: - { - int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !"); - _num_faces=renumArr; - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !"); - } - if(renumArr) - renumArr->incrRef(); -} - -/*! - * Sets the optional names of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] nameArr - the array of the names. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a nameArr has an invalid size. - */ -void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) -{ - const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !"); - switch(meshDimRelToMaxExt) - { - case 0: - { - int nbCells=mesh->getNumberOfCells(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); - _names_cells=nameArr; - break; - } - case 1: - { - int nbNodes=mesh->getNumberOfNodes(); - nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); - _names_nodes=nameArr; - break; - } - case -1: - { - int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !"); - _names_cells=nameArr; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } - if(nameArr) - nameArr->incrRef(); -} - -/*! - * Adds a group of nodes to \a this mesh. - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. - * The ids should be sorted and different each other (MED file norm). - * - * \warning this method can alter default "FAMILLE_ZERO" family. - * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. - * - * \throw If the node coordinates array is not set. - * \throw If \a ids == \c NULL. - * \throw If \a ids->getName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids) -{ - addGroup(1,ids); -} - -/*! - * Adds a group of nodes/cells/faces/edges to \a this mesh. - * - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. - * The ids should be sorted and different each other (MED file norm). - * - * \warning this method can alter default "FAMILLE_ZERO" family. - * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. - * - * \throw If the node coordinates array is not set. - * \throw If \a ids == \c NULL. - * \throw If \a ids->getName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) -{ - DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt)); - addGroupUnderground(false,ids,fam); - return ; -} - -/*! - * Returns the family field for mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families - * each mesh entity belongs to. It can be \c NULL. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _fam_cells; - case 1: - return _fam_nodes; - case -1: - return _fam_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * Returns the family field for mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the family field. It is an array of ids of families - * each mesh entity belongs to. It can be \c NULL. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _fam_cells; - case 1: - return _fam_nodes; - case -1: - return _fam_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * Returns the optional numbers of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _num_cells; - case 1: - return _num_nodes; - case -1: - return _num_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * Returns the optional numbers of mesh entities of a given dimension transformed using - * DataArrayInt::invertArrayN2O2O2N(). - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \return const DataArrayInt * - the array of the entity numbers transformed using - * DataArrayInt::invertArrayN2O2O2N(). - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - { - if((const DataArrayInt *)_num_cells) - { - int pos; - int maxValue=_num_cells->getMaxValue(pos); - _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1); - return _rev_num_cells; - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !"); - } - else - { - if((const DataArrayInt *)_num_nodes) - { - int pos; - int maxValue=_num_nodes->getMaxValue(pos); - _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1); - return _rev_num_nodes; - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !"); - } -} - -const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _names_cells; - case 1: - return _names_nodes; - case -1: - return _names_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions: [0]. - */ -std::vector MEDFileStructuredMesh::getNonEmptyLevels() const -{ - std::vector ret(1); - return ret; -} - -/*! - * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions: [1,0]. - */ -std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const -{ - std::vector ret(2); - ret[0]=1; - return ret; -} - -/*! - * Returns the set of extensive levels (nodes included) where not NULL family arr are defined. - */ -std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); - if(famNodes) - ret.push_back(1); - if(famCells) - ret.push_back(0); - if(famFaces) - ret.push_back(-1); - return ret; -} - -/*! - * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined. - */ -std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); - if(numNodes) - ret.push_back(1); - if(numCells) - ret.push_back(0); - if(numFaces) - ret.push_back(-1); - return ret; -} - -/*! - * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined. - */ -std::vector MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces); - if(namesNodes) - ret.push_back(1); - if(namesCells) - ret.push_back(0); - if(namesFaces) - ret.push_back(-1); - return ret; -} - -/*! - * no implementation here, it is not a bug, but intresically no polyhedra in \a this. - */ -bool MEDFileStructuredMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) -{ - oldCode.clear(); newCode.clear(); o2nRenumCell=0; - return false; -} - -void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) -{ - DataArrayInt *arr=_fam_nodes; - if(arr) - arr->changeValue(oldId,newId); - arr=_fam_cells; - if(arr) - arr->changeValue(oldId,newId); - arr=_fam_faces; - if(arr) - arr->changeValue(oldId,newId); -} - -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileStructuredMesh::getAllNonNullFamilyIds() const -{ - std::list< MEDCouplingAutoRefCountObjectPtr > ret; - const DataArrayInt *da(_fam_nodes); - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - da=_fam_cells; - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - da=_fam_faces; - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - return ret; -} - -void MEDFileStructuredMesh::deepCpyAttributes() -{ - if((const DataArrayInt*)_fam_nodes) - _fam_nodes=_fam_nodes->deepCpy(); - if((const DataArrayInt*)_num_nodes) - _num_nodes=_num_nodes->deepCpy(); - if((const DataArrayAsciiChar*)_names_nodes) - _names_nodes=_names_nodes->deepCpy(); - if((const DataArrayInt*)_fam_cells) - _fam_cells=_fam_cells->deepCpy(); - if((const DataArrayInt*)_num_cells) - _num_cells=_num_cells->deepCpy(); - if((const DataArrayAsciiChar*)_names_cells) - _names_cells=_names_cells->deepCpy(); - if((const DataArrayInt*)_fam_faces) - _fam_faces=_fam_faces->deepCpy(); - if((const DataArrayInt*)_num_faces) - _num_faces=_num_faces->deepCpy(); - if((const DataArrayAsciiChar*)_names_faces) - _names_faces=_names_faces->deepCpy(); - if((const DataArrayInt*)_rev_num_nodes) - _rev_num_nodes=_rev_num_nodes->deepCpy(); - if((const DataArrayInt*)_rev_num_cells) - _rev_num_cells=_rev_num_cells->deepCpy(); -} - -/*! - * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh). - * - * \return a pointer to cartesian mesh that need to be managed by the caller. - * \warning the returned pointer has to be managed by the caller. - */ - -/*! - * Returns a pointer to MEDCouplingStructuredMesh held by \a this. - * \param [in] meshDimRelToMax - it must be \c 0 or \c -1. - * \param [in] renum - it must be \c false. - * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to - * delete using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const -{ - if(renum) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); - const MEDCouplingStructuredMesh *m(getStructuredMesh()); - switch(meshDimRelToMax) - { - case 0: - { - if(m) - m->incrRef(); - return const_cast(m); - } - case -1: - { - if(!m) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); - buildMinusOneImplicitPartIfNeeded(); - MEDCouplingMesh *ret(_faces_if_necessary); - if(ret) - ret->incrRef(); - return ret; - } - default: - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); - } -} - -/*! - * Returns number of mesh entities of a given relative dimension in \a this mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \return int - the number of entities. - * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. - */ -int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); - switch(meshDimRelToMaxExt) - { - case 0: - return cmesh->getNumberOfCells(); - case 1: - return cmesh->getNumberOfNodes(); - case -1: - return cmesh->getNumberOfCellsOfSubLevelMesh(); - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -int MEDFileStructuredMesh::getNumberOfNodes() const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); - return cmesh->getNumberOfNodes(); -} - -int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); - switch(meshDimRelToMaxExt) - { - case 0: - return cmesh->getNumberOfCells(); - case -1: - return cmesh->getNumberOfCellsOfSubLevelMesh(); - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !"); - } -} - -bool MEDFileStructuredMesh::hasImplicitPart() const -{ - return true; -} - -/*! - * \sa MEDFileStructuredMesh::getImplicitFaceMesh - */ -int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const -{ - static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !"; - const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); - if(!zeFaceMesh) - { - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))); - if(cm.getReverseExtrudedType()!=gt) - throw INTERP_KERNEL::Exception(MSG); - buildImplicitPart(); - return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh(); - } - else - { - if(gt!=zeFaceMesh->getCellModelEnum()) - throw INTERP_KERNEL::Exception(MSG); - return zeFaceMesh->getNumberOfCells(); - } -} - -void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const -{ - const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); - if(!zeFaceMesh) - buildImplicitPart(); -} - -void MEDFileStructuredMesh::buildImplicitPart() const -{ - const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh()); - if(!mcmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !"); - _faces_if_necessary=mcmesh->build1SGTSubLevelMesh(); -} - -void MEDFileStructuredMesh::releaseImplicitPartIfAny() const -{ - _faces_if_necessary=0; -} - -/*! - * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any. - * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method. - * - * \sa MEDFileStructuredMesh::buildImplicitPartIfAny - */ -MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const -{ - return _faces_if_necessary; -} - -std::vector MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !"); - switch(meshDimRelToMax) - { - case 0: - { - std::vector ret(1,cmesh->getTypeOfCell(0)); - return ret; - } - case -1: - { - int mdim(cmesh->getMeshDimension()); - if(mdim<1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !"); - std::vector ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1)); - return ret; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !"); - } -} - -int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const -{ - if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) - return 0; - else - return getNumberOfCellsAtLevel(0); -} - -void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const -{ - if(st.getNumberOfItems()!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !"); - if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !"); - if(getNumberOfNodes()!=(int)nodesFetched.size()) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !"); - if(st[0].getPflName().empty()) - { - std::fill(nodesFetched.begin(),nodesFetched.end(),true); - return ; - } - const DataArrayInt *arr(globs->getProfile(st[0].getPflName())); - const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before - int sz(nodesFetched.size()); - for(const int *work=arr->begin();work!=arr->end();work++) - { - std::vector conn; - cmesh->getNodeIdsOfCell(*work,conn); - for(std::vector::const_iterator it=conn.begin();it!=conn.end();it++) - if(*it>=0 && *it& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells) -{ - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); - int nbOfElt(0); - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - famCells=DataArrayInt::New(); - famCells->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - numCells=DataArrayInt::New(); - numCells->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - namesCells=DataArrayAsciiChar::New(); - namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer())); - namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end - } - } -} - -void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - setName(strm->getName()); - setDescription(strm->getDescription()); - setUnivName(strm->getUnivName()); - setIteration(strm->getIteration()); - setOrder(strm->getOrder()); - setTimeValue(strm->getTime()); - setTimeUnit(strm->getTimeUnit()); - MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf)); - if(nbOfElt>0) - { - if(!mrs || mrs->isNodeFamilyFieldReading()) - { - int nbNodes(getNumberOfNodes()); - if(nbOfElt>nbNodes) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !"); - _fam_nodes=DataArrayInt::New(); - _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. - if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... - _fam_nodes->fillWithZero(); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isNodeNumFieldReading()) - { - _num_nodes=DataArrayInt::New(); - _num_nodes->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isNodeNameFieldReading()) - { - _names_nodes=DataArrayAsciiChar::New(); - _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer())); - _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end - } - } - int meshDim(getStructuredMesh()->getMeshDimension()); - LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells); - if(meshDim>=1) - LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces); -} - -void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const -{ - int meshDim(getStructuredMesh()->getMeshDimension()); - med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); - // - if((const DataArrayInt *)_fam_cells) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer())); - if((const DataArrayInt *)_fam_faces) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer())); - if((const DataArrayInt *)_fam_nodes) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer())); - if((const DataArrayInt *)_num_cells) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer())); - if((const DataArrayInt *)_num_faces) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer())); - if((const DataArrayInt *)_num_nodes) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer())); - if((const DataArrayAsciiChar *)_names_cells) - { - if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer())); - } - if((const DataArrayAsciiChar *)_names_faces) - { - if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer())); - } - if((const DataArrayAsciiChar *)_names_nodes) - { - if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer())); - } - // - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str); -} - -/*! - * Returns an empty instance of MEDFileCMesh. - * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - */ -MEDFileCMesh *MEDFileCMesh::New() -{ - return new MEDFileCMesh; -} - -/*! - * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED - * file. The first mesh in the file is loaded. - * \param [in] fileName - the name of MED file to read. - * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no meshes in the file. - * \throw If the mesh in the file is not a Cartesian one. - */ -MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileCMesh(fid,ms.front(),dt,it,mrs); -} - -/*! - * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED - * file. The mesh to load is specified by its name and numbers of a time step and an - * iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] dt - the number of a time step. - * \param [in] it - the number of an iteration. - * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - * \throw If the mesh in the file is not a Cartesian one. - */ -MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - return new MEDFileCMesh(fid,mName,dt,it,mrs); -} - -std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileCMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); - ret.push_back((const MEDCouplingCMesh *)_cmesh); - return ret; -} - -/*! - * Returns the dimension on cells in \a this mesh. - * \return int - the mesh dimension. - * \throw If there are no cells in this mesh. - */ -int MEDFileCMesh::getMeshDimension() const -{ - if(!((const MEDCouplingCMesh*)_cmesh)) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); - return _cmesh->getMeshDimension(); -} - -/*! - * Returns the dimension on nodes in \a this mesh. - * \return int - the space dimension. - * \throw If there are no cells in this mesh. - */ -int MEDFileCMesh::getSpaceDimension() const -{ - if(!((const MEDCouplingCMesh*)_cmesh)) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !"); - return _cmesh->getSpaceDimension(); -} - -/*! - * Returns a string describing \a this mesh. - * \return std::string - the mesh information string. - */ -std::string MEDFileCMesh::simpleRepr() const -{ - return MEDFileStructuredMesh::simpleRepr(); -} - -/*! - * Returns a full textual description of \a this mesh. - * \return std::string - the string holding the mesh description. - */ -std::string MEDFileCMesh::advancedRepr() const -{ - return simpleRepr(); -} - -MEDFileMesh *MEDFileCMesh::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); - return ret.retn(); -} - -MEDFileMesh *MEDFileCMesh::createNewEmpty() const -{ - return new MEDFileCMesh; -} - -MEDFileMesh *MEDFileCMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); - ret->deepCpyEquivalences(*this); - if((const MEDCouplingCMesh*)_cmesh) - ret->_cmesh=static_cast(_cmesh->deepCpy()); - ret->deepCpyAttributes(); - return ret.retn(); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \param [in] eps - a precision used to compare real values. - * \param [in,out] what - the string returning description of unequal data. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileStructuredMesh::isEqual(other,eps,what)) - return false; - const MEDFileCMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is cartesian and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const MEDCouplingCMesh *coo1=_cmesh; - const MEDCouplingCMesh *coo2=otherC->_cmesh; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of cartesian meshes ! One is defined and not other !"; - return false; - } - if(coo1) - { - bool ret=coo1->isEqual(coo2,eps); - if(!ret) - { - what="cartesian meshes differ !"; - return false; - } - } - return true; -} - -/*! - * Clears redundant attributes of incorporated data arrays. - */ -void MEDFileCMesh::clearNonDiscrAttributes() const -{ - MEDFileStructuredMesh::clearNonDiscrAttributes(); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented -} - -MEDFileCMesh::MEDFileCMesh() -{ -} - -MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -try -{ - loadLLWithAdditionalItems(fid,mName,dt,it,mrs); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); - if(meshType!=CARTESIAN) - { - std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileCMeshL2 loaderl2; - loaderl2.loadAll(fid,mid,mName,dt,it); - MEDCouplingCMesh *mesh=loaderl2.getMesh(); - mesh->incrRef(); - _cmesh=mesh; - loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs); -} - -/*! - * Returns a const pointer to MEDCouplingCMesh held by \a this mesh. - * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh. - */ -const MEDCouplingCMesh *MEDFileCMesh::getMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _cmesh; -} - -const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _cmesh; -} - -/*! - * Sets the MEDCouplingCMesh holding the data of \a this mesh. - * \param [in] m - the new MEDCouplingCMesh to refer to. - * \throw If the name or the description of \a this mesh and \a m are not empty and are - * different. - */ -void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) -{ - dealWithTinyInfo(m); - if(m) - m->incrRef(); - _cmesh=m; -} - -void MEDFileCMesh::writeLL(med_idt fid) const -{ - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); - int spaceDim(_cmesh->getSpaceDimension()); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - for(int i=0;igetCoordsAt(i)->getInfoOnComponent(0)); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - if(_univ_wr_status) - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID)); - for(int i=0;igetCoordsAt(i); - MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer())); - } - // - std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileStructuredMesh::writeStructuredLL(fid,meshName); -} - -void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const -{ - const MEDCouplingCMesh *cmesh=_cmesh; - if(!cmesh) - return; - (const_cast(cmesh))->setName(_name); - (const_cast(cmesh))->setDescription(_desc_name); - (const_cast(cmesh))->setTime(_time,_iteration,_order); - (const_cast(cmesh))->setTimeUnit(_dt_unit); -} - -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() -{ - return new MEDFileCurveLinearMesh; -} - -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs); -} - -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs); -} - -std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileCurveLinearMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); - ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); - return ret; -} - -MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); - return ret.retn(); -} - -MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const -{ - return new MEDFileCurveLinearMesh; -} - -MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); - ret->deepCpyEquivalences(*this); - if((const MEDCouplingCurveLinearMesh*)_clmesh) - ret->_clmesh=static_cast(_clmesh->deepCpy()); - ret->deepCpyAttributes(); - return ret.retn(); -} - -int MEDFileCurveLinearMesh::getMeshDimension() const -{ - if(!((const MEDCouplingCurveLinearMesh*)_clmesh)) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); - return _clmesh->getMeshDimension(); -} - -std::string MEDFileCurveLinearMesh::simpleRepr() const -{ - return MEDFileStructuredMesh::simpleRepr(); -} - -std::string MEDFileCurveLinearMesh::advancedRepr() const -{ - return simpleRepr(); -} - -bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileStructuredMesh::isEqual(other,eps,what)) - return false; - const MEDFileCurveLinearMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is curve linear and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const MEDCouplingCurveLinearMesh *coo1=_clmesh; - const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of curve linear meshes ! One is defined and not other !"; - return false; - } - if(coo1) - { - bool ret=coo1->isEqual(coo2,eps); - if(!ret) - { - what="curve linear meshes differ !"; - return false; - } - } - return true; -} - -void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const -{ - MEDFileStructuredMesh::clearNonDiscrAttributes(); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented -} - -void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const -{ - const MEDCouplingCurveLinearMesh *clmesh=_clmesh; - if(!clmesh) - return; - (const_cast(clmesh))->setName(_name); - (const_cast(clmesh))->setDescription(_desc_name); - (const_cast(clmesh))->setTime(_time,_iteration,_order); - (const_cast(clmesh))->setTimeUnit(_dt_unit); -} - -const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _clmesh; -} - -void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) -{ - dealWithTinyInfo(m); - if(m) - m->incrRef(); - _clmesh=m; -} - -const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _clmesh; -} - -MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() -{ -} - -MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -try -{ - loadLLWithAdditionalItems(fid,mName,dt,it,mrs); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileCurveLinearMesh::writeLL(med_idt fid) const -{ - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); - int spaceDim=_clmesh->getSpaceDimension(); - int meshDim=_clmesh->getMeshDimension(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - const DataArrayDouble *coords=_clmesh->getCoords(); - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !"); - for(int i=0;igetCoords()->getInfoOnComponent(i)); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - if(_univ_wr_status) - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID)); - std::vector nodeGridSt=_clmesh->getNodeGridStructure(); - MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0])); - - MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin())); - // - std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileStructuredMesh::writeStructuredLL(fid,meshName); -} - -void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); - if(meshType!=CURVE_LINEAR) - { - std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileCLMeshL2 loaderl2; - loaderl2.loadAll(fid,mid,mName,dt,it); - MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh(); - mesh->incrRef(); - _clmesh=mesh; - loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs); -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() -{ - return new MEDFileMeshMultiTS; -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName) -{ - return new MEDFileMeshMultiTS(fileName); -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName) -{ - return new MEDFileMeshMultiTS(fileName,mName); -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshMultiTS::New(); - std::vector< MEDCouplingAutoRefCountObjectPtr > meshOneTs(_mesh_one_ts.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++) - if((const MEDFileMesh *)*it) - meshOneTs[i]=(*it)->deepCpy(); - ret->_mesh_one_ts=meshOneTs; - return ret.retn(); -} - -std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const -{ - return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileMeshMultiTS::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - ret.push_back((const MEDFileMesh *)*it); - return ret; -} - -std::string MEDFileMeshMultiTS::getName() const -{ - if(_mesh_one_ts.empty()) - throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !"); - return _mesh_one_ts[0]->getName(); -} - -void MEDFileMeshMultiTS::setName(const std::string& newMeshName) -{ - std::string oldName(getName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeNames(v); -} - -bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - MEDFileMesh *cur(*it); - if(cur) - ret=cur->changeNames(modifTab) || ret; - } - return ret; -} - -MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const -{ - if(_mesh_one_ts.empty()) - throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !"); - return const_cast(static_cast(_mesh_one_ts[0])); -} - -void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) -{ - if(!mesh1TimeStep) - throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !"); - _mesh_one_ts.resize(1); - mesh1TimeStep->incrRef(); - //MEDCouplingAutoRefCountObjectPtr toto=mesh1TimeStep; - _mesh_one_ts[0]=mesh1TimeStep; -} - -MEDFileJoints * MEDFileMeshMultiTS::getJoints() const -{ - if ( MEDFileMesh* m = getOneTimeStep() ) - return m->getJoints(); - return 0; -} - -/*! - * \brief Set Joints that are common to all time-stamps - */ -void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints ) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - (*it)->setJoints( joints ); - } -} - -void MEDFileMeshMultiTS::write(med_idt fid) const -{ - MEDFileJoints *joints(getJoints()); - bool jointsWritten(false); - - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - if ( jointsWritten ) - const_cast(**it).setJoints( 0 ); - else - jointsWritten = true; - - (*it)->copyOptionsFrom(*this); - (*it)->write(fid); - } - - (const_cast(this))->setJoints( joints ); // restore joints -} - -void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName) -{ - MEDFileJoints* joints = 0; - if ( !_mesh_one_ts.empty() && getOneTimeStep() ) - { - // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading - joints = getOneTimeStep()->getJoints(); - } - - _mesh_one_ts.clear(); //for the moment to be improved - _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints )); -} - -MEDFileMeshMultiTS::MEDFileMeshMultiTS() -{ -} - -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName) -try -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - loadFromFile(fileName,ms.front()); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) -try -{ - loadFromFile(fileName,mName); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileMeshes *MEDFileMeshes::New() -{ - return new MEDFileMeshes; -} - -MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName) -{ - return new MEDFileMeshes(fileName); -} - -void MEDFileMeshes::write(med_idt fid) const -{ - checkCoherency(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - { - (*it)->copyOptionsFrom(*this); - (*it)->write(fid); - } -} - -void MEDFileMeshes::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - checkCoherency(); - write(fid); -} - -int MEDFileMeshes::getNumberOfMeshes() const -{ - return _meshes.size(); -} - -MEDFileMeshesIterator *MEDFileMeshes::iterator() -{ - return new MEDFileMeshesIterator(this); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const -{ - if(i<0 || i>=(int)_meshes.size()) - { - std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _meshes[i]->getOneTimeStep(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const -{ - std::vector ms=getMeshesNames(); - std::vector::iterator it=std::find(ms.begin(),ms.end(),mname); - if(it==ms.end()) - { - std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : "; - std::copy(ms.begin(),ms.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getMeshAtPos((int)std::distance(ms.begin(),it)); -} - -std::vector MEDFileMeshes::getMeshesNames() const -{ - std::vector ret(_meshes.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) - { - const MEDFileMeshMultiTS *f=(*it); - if(f) - { - ret[i]=f->getName(); - } - else - { - std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} -/*const MEDFileJoints* MEDFileMeshes::getJoints() const -{ - const MEDFileJoints *ret=_joints; - if(!ret) - { - std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -}*/ - -bool MEDFileMeshes::changeNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_meshes.begin();it!=_meshes.end();it++) - { - MEDFileMeshMultiTS *cur(*it); - if(cur) - ret=cur->changeNames(modifTab) || ret; - } - return ret; -} - -void MEDFileMeshes::resize(int newSize) -{ - _meshes.resize(newSize); -} - -void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !"); - MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); - elt->setOneTimeStep(mesh); - _meshes.push_back(elt); -} - -void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !"); - if(i>=(int)_meshes.size()) - _meshes.resize(i+1); - MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); - elt->setOneTimeStep(mesh); - _meshes[i]=elt; -} - -void MEDFileMeshes::destroyMeshAtPos(int i) -{ - if(i<0 || i>=(int)_meshes.size()) - { - std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _meshes.erase(_meshes.begin()+i); -} - -void MEDFileMeshes::loadFromFile(const std::string& fileName) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - int i=0; - _meshes.resize(ms.size()); - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) - _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it)); -} - -MEDFileMeshes::MEDFileMeshes() -{ -} - -MEDFileMeshes::MEDFileMeshes(const std::string& fileName) -try -{ - loadFromFile(fileName); -} -catch(INTERP_KERNEL::Exception& /*e*/) -{ -} - -MEDFileMeshes *MEDFileMeshes::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > meshes(_meshes.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) - if((const MEDFileMeshMultiTS *)*it) - meshes[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshes::New(); - ret->_meshes=meshes; - return ret.retn(); -} - -std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const -{ - return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); -} - -std::vector MEDFileMeshes::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - ret.push_back((const MEDFileMeshMultiTS *)*it); - return ret; -} - -std::string MEDFileMeshes::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n"; - simpleReprWithoutHeader(oss); - return oss.str(); -} - -void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const -{ - int nbOfMeshes=getNumberOfMeshes(); - oss << "There are " << nbOfMeshes << " meshes with the following names : \n"; - std::vector mns=getMeshesNames(); - for(int i=0;i s; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) - { - const MEDFileMeshMultiTS *elt=(*it); - if(!elt) - { - std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t sz=s.size(); - s.insert(std::string((*it)->getName())); - if(s.size()==sz) - { - std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0) -{ - if(ms) - { - ms->incrRef(); - _nb_iter=ms->getNumberOfMeshes(); - } -} - -MEDFileMeshesIterator::~MEDFileMeshesIterator() -{ -} - -MEDFileMesh *MEDFileMeshesIterator::nextt() -{ - if(_iter_id<_nb_iter) - { - MEDFileMeshes *ms(_ms); - if(ms) - return ms->getMeshAtPos(_iter_id++); - else - return 0; - } - else - return 0; -} diff --git a/medtool/src/MEDLoader/MEDFileMesh.hxx b/medtool/src/MEDLoader/MEDFileMesh.hxx deleted file mode 100644 index 65c39d1c2..000000000 --- a/medtool/src/MEDLoader/MEDFileMesh.hxx +++ /dev/null @@ -1,563 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEMESH_HXX__ -#define __MEDFILEMESH_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDFileMeshLL.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDFileMeshReadSelector.hxx" -#include "MEDFileJoint.hxx" -#include "MEDFileEquivalence.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDFileFieldGlobsReal; - class MEDFileField1TSStructItem; - - class MEDFileMesh : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0, MEDFileJoints* joints=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT virtual MEDFileMesh *createNewEmpty() const = 0; - MEDLOADER_EXPORT virtual MEDFileMesh *deepCpy() const = 0; - MEDLOADER_EXPORT virtual MEDFileMesh *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT virtual void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT virtual void setName(const std::string& name); - MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT std::string getUnivName() const { return _univ_name; } - MEDLOADER_EXPORT bool getUnivNameWrStatus() const { return _univ_wr_status; } - MEDLOADER_EXPORT void setUnivNameWrStatus(bool newStatus) { _univ_wr_status=newStatus; } - MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } - MEDLOADER_EXPORT void setOrder(int order) { _order=order; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; } - MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; } - MEDLOADER_EXPORT double getTime(int& dt, int& it) const { dt=_iteration; it=_order; return _time; } - MEDLOADER_EXPORT double getTimeValue() const { return _time; } - MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; } - MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; } - MEDLOADER_EXPORT std::vector getAllGeoTypes() const; - MEDLOADER_EXPORT virtual int getNumberOfNodes() const = 0; - MEDLOADER_EXPORT virtual int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual bool hasImplicitPart() const = 0; - MEDLOADER_EXPORT virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const = 0; - MEDLOADER_EXPORT virtual void releaseImplicitPartIfAny() const = 0; - MEDLOADER_EXPORT virtual std::vector getGeoTypesAtLevel(int meshDimRelToMax) const = 0; - MEDLOADER_EXPORT virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const = 0; - MEDLOADER_EXPORT virtual std::vector getNonEmptyLevels() const = 0; - MEDLOADER_EXPORT virtual std::vector getNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual std::vector getFamArrNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual std::vector getNumArrNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual std::vector getNameArrNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT virtual void write(med_idt fid) const; - MEDLOADER_EXPORT virtual int getSizeAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const = 0; - MEDLOADER_EXPORT virtual std::vector getDistributionOfTypes(int meshDimRelToMax) const; - MEDLOADER_EXPORT virtual void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const = 0; - // - MEDLOADER_EXPORT bool areFamsEqual(const MEDFileMesh *other, std::string& what) const; - MEDLOADER_EXPORT bool areGrpsEqual(const MEDFileMesh *other, std::string& what) const; - MEDLOADER_EXPORT bool existsGroup(const std::string& groupName) const; - MEDLOADER_EXPORT bool existsFamily(int famId) const; - MEDLOADER_EXPORT bool existsFamily(const std::string& familyName) const; - MEDLOADER_EXPORT void setFamilyId(const std::string& familyName, int id); - MEDLOADER_EXPORT void setFamilyIdUnique(const std::string& familyName, int id); - MEDLOADER_EXPORT virtual void addFamily(const std::string& familyName, int id); - MEDLOADER_EXPORT virtual void createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName); - MEDLOADER_EXPORT virtual bool keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& levs); - MEDLOADER_EXPORT void addFamilyOnGrp(const std::string& grpName, const std::string& famName); - MEDLOADER_EXPORT std::string findOrCreateAndGiveFamilyWithId(int id, bool& created); - MEDLOADER_EXPORT void setFamilyInfo(const std::map& info); - MEDLOADER_EXPORT void setGroupInfo(const std::map >&info); - MEDLOADER_EXPORT void copyFamGrpMapsFrom(const MEDFileMesh& other); - MEDLOADER_EXPORT void clearGrpMap(); - MEDLOADER_EXPORT void clearFamMap(); - MEDLOADER_EXPORT void clearFamGrpMaps(); - MEDLOADER_EXPORT const std::map& getFamilyInfo() const { return _families; } - MEDLOADER_EXPORT const std::map >& getGroupInfo() const { return _groups; } - MEDLOADER_EXPORT std::vector getFamiliesOnGroup(const std::string& name) const; - MEDLOADER_EXPORT std::vector getFamiliesOnGroups(const std::vector& grps) const; - MEDLOADER_EXPORT std::vector getFamiliesIdsOnGroup(const std::string& name) const; - MEDLOADER_EXPORT void setFamiliesOnGroup(const std::string& name, const std::vector& fams); - MEDLOADER_EXPORT void setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds); - MEDLOADER_EXPORT std::vector getGroupsOnFamily(const std::string& name) const; - MEDLOADER_EXPORT void setGroupsOnFamily(const std::string& famName, const std::vector& grps); - MEDLOADER_EXPORT std::vector getGroupsNames() const; - MEDLOADER_EXPORT std::vector getFamiliesNames() const; - MEDLOADER_EXPORT void assignFamilyNameWithGroupName(); - MEDLOADER_EXPORT std::vector removeEmptyGroups(); - MEDLOADER_EXPORT void removeGroup(const std::string& name); - MEDLOADER_EXPORT void removeFamily(const std::string& name); - MEDLOADER_EXPORT std::vector removeOrphanGroups(); - MEDLOADER_EXPORT std::vector removeOrphanFamilies(); - MEDLOADER_EXPORT void removeFamiliesReferedByNoGroups(); - MEDLOADER_EXPORT void rearrangeFamilies(); - MEDLOADER_EXPORT void checkOrphanFamilyZero() const; - MEDLOADER_EXPORT void changeGroupName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT void changeFamilyName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT void changeFamilyId(int oldId, int newId); - MEDLOADER_EXPORT void changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames); - MEDLOADER_EXPORT int getFamilyId(const std::string& name) const; - MEDLOADER_EXPORT int getMaxAbsFamilyId() const; - MEDLOADER_EXPORT int getMaxFamilyId() const; - MEDLOADER_EXPORT int getMinFamilyId() const; - MEDLOADER_EXPORT int getTheMaxAbsFamilyId() const; - MEDLOADER_EXPORT int getTheMaxFamilyId() const; - MEDLOADER_EXPORT int getTheMinFamilyId() const; - MEDLOADER_EXPORT virtual int getMaxAbsFamilyIdInArrays() const = 0; - MEDLOADER_EXPORT virtual int getMaxFamilyIdInArrays() const = 0; - MEDLOADER_EXPORT virtual int getMinFamilyIdInArrays() const = 0; - MEDLOADER_EXPORT DataArrayInt *getAllFamiliesIdsReferenced() const; - MEDLOADER_EXPORT DataArrayInt *computeAllFamilyIdsInUse() const; - MEDLOADER_EXPORT std::vector getFamiliesIds(const std::vector& famNames) const; - MEDLOADER_EXPORT std::string getFamilyNameGivenId(int id) const; - MEDLOADER_EXPORT bool ensureDifferentFamIdsPerLevel(); - MEDLOADER_EXPORT void normalizeFamIdsTrio(); - MEDLOADER_EXPORT void normalizeFamIdsMEDFile(); - MEDLOADER_EXPORT virtual int getMeshDimension() const = 0; - MEDLOADER_EXPORT virtual std::string simpleRepr() const; - MEDLOADER_EXPORT virtual std::string advancedRepr() const = 0; - // - MEDLOADER_EXPORT virtual void setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false); - MEDLOADER_EXPORT virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) = 0; - MEDLOADER_EXPORT virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) = 0; - MEDLOADER_EXPORT virtual void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) = 0; - MEDLOADER_EXPORT virtual void addNodeGroup(const DataArrayInt *ids) = 0; - MEDLOADER_EXPORT virtual void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) = 0; - MEDLOADER_EXPORT virtual const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) = 0; - MEDLOADER_EXPORT DataArrayInt *getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT virtual const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const = 0; - MEDLOADER_EXPORT virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeGroupArr(const std::string& grp, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeGroupsArr(const std::vector& grps, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamiliesArr(const std::vector& fams, bool renum=false) const; - // tools - MEDLOADER_EXPORT virtual bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) = 0; - MEDLOADER_EXPORT int getNumberOfJoints() const; - MEDLOADER_EXPORT MEDFileJoints *getJoints() const; - MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints ); - MEDFileEquivalences *getEquivalences() { return _equiv; } - const MEDFileEquivalences *getEquivalences() const { return _equiv; } - void killEquivalences() { _equiv=(MEDFileEquivalences *)0; } - void initializeEquivalences() { _equiv=MEDFileEquivalences::New(this); } - protected: - MEDFileMesh(); - //! protected because no way in MED file API to specify this name - void setUnivName(const std::string& name) { _univ_name=name; } - void addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName); - virtual void writeLL(med_idt fid) const = 0; - void dealWithTinyInfo(const MEDCouplingMesh *m); - virtual void synchronizeTinyInfoOnLeaves() const = 0; - void getFamilyRepr(std::ostream& oss) const; - virtual void appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); - virtual void changeFamilyIdArr(int oldId, int newId) = 0; - virtual std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const = 0; - virtual void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) = 0; - void loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr); - static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); - static void ChangeAllGroupsContainingFamily(std::map >& groups, const std::string& familyNameToChange, const std::vector& newFamiliesNames); - static std::string FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created); - static std::string CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid); - static int PutInThirdComponentOfCodeOffset(std::vector& code, int strt); - void writeJoints(med_idt fid) const; - void loadJointsFromFile(med_idt fid, MEDFileJoints *toUseInstedOfReading=0); - void loadEquivalences(med_idt fid); - void deepCpyEquivalences(const MEDFileMesh& other); - bool areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const; - void getEquivalencesRepr(std::ostream& oss) const; - protected: - int _order; - int _iteration; - double _time; - std::string _dt_unit; - std::string _name; - //! this attribute do not impact the state of instance -> mutable - mutable std::string _univ_name; - bool _univ_wr_status; - std::string _desc_name; - MEDCouplingAutoRefCountObjectPtr _joints; - MEDCouplingAutoRefCountObjectPtr _equiv; - protected: - std::map > _groups; - std::map _families; - public: - MEDLOADER_EXPORT static const char DFT_FAM_NAME[]; - }; - - class MEDFileUMesh : public MEDFileMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileUMesh *New(); - MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; - MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; - MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT void setName(const std::string& name); - // - MEDLOADER_EXPORT int getMaxAbsFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMaxFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMinFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMeshDimension() const; - MEDLOADER_EXPORT int getSpaceDimension() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT std::string advancedRepr() const; - MEDLOADER_EXPORT int getSizeAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const PartDefinition *getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt=INTERP_KERNEL::NORM_ERROR) const; - MEDLOADER_EXPORT int getNumberOfNodes() const; - MEDLOADER_EXPORT int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT bool hasImplicitPart() const; - MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT void releaseImplicitPartIfAny() const; - MEDLOADER_EXPORT std::vector getGeoTypesAtLevel(int meshDimRelToMax) const; - MEDLOADER_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const; - MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const; - MEDLOADER_EXPORT std::vector getNonEmptyLevels() const; - MEDLOADER_EXPORT std::vector getNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getFamArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNumArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNameArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getGrpNonEmptyLevels(const std::string& grp) const; - MEDLOADER_EXPORT std::vector getGrpNonEmptyLevelsExt(const std::string& grp) const; - MEDLOADER_EXPORT std::vector getFamNonEmptyLevels(const std::string& fam) const; - MEDLOADER_EXPORT std::vector getFamNonEmptyLevelsExt(const std::string& fam) const; - MEDLOADER_EXPORT std::vector getGrpsNonEmptyLevels(const std::vector& grps) const; - MEDLOADER_EXPORT std::vector getGrpsNonEmptyLevelsExt(const std::vector& grps) const; - MEDLOADER_EXPORT std::vector getFamsNonEmptyLevels(const std::vector& fams) const; - MEDLOADER_EXPORT std::vector getFamsNonEmptyLevelsExt(const std::vector& fams) const; - MEDLOADER_EXPORT std::vector getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT DataArrayDouble *getCoords() const; - MEDLOADER_EXPORT MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; - MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; - MEDLOADER_EXPORT std::vector getDistributionOfTypes(int meshDimRelToMax) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const; - MEDLOADER_EXPORT void forceComputationOfParts() const; - MEDLOADER_EXPORT std::vector getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const; - MEDLOADER_EXPORT MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - // - MEDLOADER_EXPORT void setFamilyNameAttachedOnId(int id, const std::string& newFamName); - MEDLOADER_EXPORT void setCoords(DataArrayDouble *coords); - MEDLOADER_EXPORT void eraseGroupsAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); - MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); - MEDLOADER_EXPORT void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); - MEDLOADER_EXPORT void addNodeGroup(const DataArrayInt *ids); - MEDLOADER_EXPORT void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids); - MEDLOADER_EXPORT void removeMeshAtLevel(int meshDimRelToMax); - MEDLOADER_EXPORT void setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m); - MEDLOADER_EXPORT void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false); - MEDLOADER_EXPORT void setMeshes(const std::vector& ms, bool renum=false); - MEDLOADER_EXPORT void setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms, bool renum=false); - MEDLOADER_EXPORT void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum=false); - MEDLOADER_EXPORT void optimizeFamilies(); - // tools - MEDLOADER_EXPORT void buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified); - MEDLOADER_EXPORT bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); - MEDLOADER_EXPORT DataArrayInt *zipCoords(); - MEDLOADER_EXPORT MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const; - MEDLOADER_EXPORT MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const; - MEDLOADER_EXPORT MEDFileUMesh *quadraticToLinear(double eps=1e-12) const; - // serialization - MEDLOADER_EXPORT void serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD); - MEDLOADER_EXPORT void unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD); - private: - MEDLOADER_EXPORT ~MEDFileUMesh(); - void writeLL(med_idt fid) const; - MEDFileUMesh(); - MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs); - const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const; - MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt); - void checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const; - DataArrayDouble *checkMultiMesh(const std::vector& ms) const; - void computeRevNum() const; - void synchronizeTinyInfoOnLeaves() const; - void changeFamilyIdArr(int oldId, int newId); - std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const; - MEDCouplingAutoRefCountObjectPtr& checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _ms; - MEDCouplingAutoRefCountObjectPtr _coords; - MEDCouplingAutoRefCountObjectPtr _fam_coords; - MEDCouplingAutoRefCountObjectPtr _num_coords; - MEDCouplingAutoRefCountObjectPtr _name_coords; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_coords; - MEDCouplingAutoRefCountObjectPtr _part_coords; - }; - - class MEDFileStructuredMesh : public MEDFileMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT int getMaxAbsFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMaxFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMinFamilyIdInArrays() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; - MEDLOADER_EXPORT const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); - MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); - MEDLOADER_EXPORT void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); - MEDLOADER_EXPORT void addNodeGroup(const DataArrayInt *ids); - MEDLOADER_EXPORT void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids); - MEDLOADER_EXPORT const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT std::vector getNonEmptyLevels() const; - MEDLOADER_EXPORT std::vector getNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getFamArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNumArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNameArrNonEmptyLevelsExt() const; - MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; - MEDLOADER_EXPORT int getSizeAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT int getNumberOfNodes() const; - MEDLOADER_EXPORT int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT bool hasImplicitPart() const; - MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT void releaseImplicitPartIfAny() const; - MEDLOADER_EXPORT MEDCoupling1SGTUMesh *getImplicitFaceMesh() const; - MEDLOADER_EXPORT std::vector getGeoTypesAtLevel(int meshDimRelToMax) const; - MEDLOADER_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const; - MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const; - MEDLOADER_EXPORT virtual const MEDCouplingStructuredMesh *getStructuredMesh() const = 0; - // tools - MEDLOADER_EXPORT bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); - protected: - ~MEDFileStructuredMesh() { } - void changeFamilyIdArr(int oldId, int newId); - std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const; - void deepCpyAttributes(); - void loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void writeStructuredLL(med_idt fid, const std::string& maa) const; - void buildImplicitPart() const; - void buildMinusOneImplicitPartIfNeeded() const; - static med_geometry_type GetGeoTypeFromMeshDim(int meshDim); - private: - static void LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, - MEDCouplingAutoRefCountObjectPtr& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells); - private: - MEDCouplingAutoRefCountObjectPtr _fam_nodes; - MEDCouplingAutoRefCountObjectPtr _num_nodes; - MEDCouplingAutoRefCountObjectPtr _names_nodes; - MEDCouplingAutoRefCountObjectPtr _fam_cells; - MEDCouplingAutoRefCountObjectPtr _num_cells; - MEDCouplingAutoRefCountObjectPtr _names_cells; - MEDCouplingAutoRefCountObjectPtr _fam_faces; - MEDCouplingAutoRefCountObjectPtr _num_faces; - MEDCouplingAutoRefCountObjectPtr _names_faces; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_nodes; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_cells; - mutable MEDCouplingAutoRefCountObjectPtr _faces_if_necessary; - }; - - class MEDFileCMesh : public MEDFileStructuredMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT static MEDFileCMesh *New(); - MEDLOADER_EXPORT static MEDFileCMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileCMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; - MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; - MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT int getMeshDimension() const; - MEDLOADER_EXPORT int getSpaceDimension() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT std::string advancedRepr() const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT const MEDCouplingCMesh *getMesh() const; - MEDLOADER_EXPORT void setMesh(MEDCouplingCMesh *m); - private: - ~MEDFileCMesh() { } - const MEDCouplingStructuredMesh *getStructuredMesh() const; - void writeLL(med_idt fid) const; - MEDFileCMesh(); - void synchronizeTinyInfoOnLeaves() const; - MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - private: - MEDCouplingAutoRefCountObjectPtr _cmesh; - }; - - class MEDFileCurveLinearMesh : public MEDFileStructuredMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(); - MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; - MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; - MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT int getMeshDimension() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT std::string advancedRepr() const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT const MEDCouplingCurveLinearMesh *getMesh() const; - MEDLOADER_EXPORT void setMesh(MEDCouplingCurveLinearMesh *m); - private: - ~MEDFileCurveLinearMesh() { } - MEDFileCurveLinearMesh(); - MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - const MEDCouplingStructuredMesh *getStructuredMesh() const; - void synchronizeTinyInfoOnLeaves() const; - void writeLL(med_idt fid) const; - void loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);//to imp - private: - MEDCouplingAutoRefCountObjectPtr _clmesh; - }; - - class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(); - MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(const std::string& fileName, const std::string& mName); - MEDLOADER_EXPORT MEDFileMeshMultiTS *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT MEDFileMesh *getOneTimeStep() const; - MEDLOADER_EXPORT void write(med_idt fid) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void setOneTimeStep(MEDFileMesh *mesh1TimeStep); - MEDLOADER_EXPORT MEDFileJoints *getJoints() const; - MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints ); - private: - ~MEDFileMeshMultiTS() { } - void loadFromFile(const std::string& fileName, const std::string& mName); - MEDFileMeshMultiTS(); - MEDFileMeshMultiTS(const std::string& fileName); - MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _mesh_one_ts; - }; - - class MEDFileMeshesIterator; - - class MEDFileMeshes : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileMeshes *New(); - MEDLOADER_EXPORT static MEDFileMeshes *New(const std::string& fileName); - MEDLOADER_EXPORT MEDFileMeshes *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void write(med_idt fid) const; - MEDLOADER_EXPORT int getNumberOfMeshes() const; - MEDLOADER_EXPORT MEDFileMeshesIterator *iterator(); - MEDLOADER_EXPORT MEDFileMesh *getMeshAtPos(int i) const; - MEDLOADER_EXPORT MEDFileMesh *getMeshWithName(const std::string& mname) const; - MEDLOADER_EXPORT std::vector getMeshesNames() const; - MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair >& modifTab); - // - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushMesh(MEDFileMesh *mesh); - MEDLOADER_EXPORT void setMeshAtPos(int i, MEDFileMesh *mesh); - MEDLOADER_EXPORT void destroyMeshAtPos(int i); - private: - ~MEDFileMeshes() { } - void checkCoherency() const; - void loadFromFile(const std::string& fileName); - MEDFileMeshes(); - MEDFileMeshes(const std::string& fileName); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _meshes; - }; - - class MEDFileMeshesIterator - { - public: - MEDLOADER_EXPORT MEDFileMeshesIterator(MEDFileMeshes *ms); - MEDLOADER_EXPORT ~MEDFileMeshesIterator(); - MEDLOADER_EXPORT MEDFileMesh *nextt(); - private: - MEDCouplingAutoRefCountObjectPtr _ms; - int _iter_id; - int _nb_iter; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileMeshElt.cxx b/medtool/src/MEDLoader/MEDFileMeshElt.cxx deleted file mode 100644 index c2aa5504e..000000000 --- a/medtool/src/MEDLoader/MEDFileMeshElt.cxx +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileMeshElt.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileMeshReadSelector.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "InterpKernelException.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "CellModel.hxx" - -#include - -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs) -{ - med_entity_type whichEntity; - if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) - return 0; - return new MEDFileUMeshPerType(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,mrs); -} - -MEDFileUMeshPerType *MEDFileUMeshPerType::NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs) -{ - int geoElt2i((int)geoElt2); - if(geoElt2i<0 || geoElt2i>=34) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : Not recognized MEDCoupling/MEDLoader geometric type !"); - med_geometry_type geoElt(typmai3[geoElt2]); - med_entity_type whichEntity; - if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : The specified geo type is not present in the specified mesh !"); - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMeshPerType); - ret->loadPart(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,strt,stp,step,mrs); - return ret.retn(); -} - -std::size_t MEDFileUMeshPerType::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileUMeshPerType::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCoupling1GTUMesh *)_m); - ret.push_back((const DataArrayInt *)_num); - ret.push_back((const DataArrayInt *)_fam); - ret.push_back((const DataArrayAsciiChar *)_names); - return ret; -} - -bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity) -{ - static const med_entity_type entities[3]={MED_CELL,MED_DESCENDING_FACE,MED_DESCENDING_EDGE}; - int nbOfElt=0; - for(int i=0;i<3;i++) - { - med_bool changement,transformation; - int tmp(MEDmeshnEntity(fid,mName,dt,it,entities[i],geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - if(tmp>nbOfElt) - { - nbOfElt=tmp; - whichEntity=entities[i]; - if(i>0) - std::cerr << "WARNING : MEDFile has been detected to be no compilant with MED 3 : Please change entity in MEDFile for geotype " << geoElt << std::endl; - } - } - return nbOfElt>0; -} - -int MEDFileUMeshPerType::getDim() const -{ - return _m->getMeshDimension(); -} - -MEDFileUMeshPerType::MEDFileUMeshPerType() -{ -} - -MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs):_entity(entity) -{ - med_bool changement,transformation; - int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); - if(!cm.isDynamic()) - { - loadFromStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,mrs); - return; - } - if(type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG) - { - loadPolyg(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); - return; - } - //if(type==INTERP_KERNEL::NORM_POLYHED) - loadPolyh(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); - _pd=PartDefinition::New(strt,end,step); - if(!cm.isDynamic()) - { - loadPartStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,strt,end,step,mrs); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPart : not implemented yet for the dynamic type !"); -} - -void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - _m=MEDCoupling1SGTUMesh::New(mName,type); - MEDCoupling1SGTUMesh *mc(dynamic_cast((MEDCoupling1GTUMesh *)_m)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - int nbOfNodesPerCell(mc->getNumberOfNodesPerCell()); - conn->alloc(nbOfNodesPerCell*curNbOfElem,1); - MEDFILESAFECALLERRD0(MEDmeshElementConnectivityRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,MED_FULL_INTERLACE,conn->getPointer())); - std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus(),-1)); - mc->setNodalConnectivity(conn); - loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs) -{ - if(strt<0) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : start pos is negative !"); - if(end>curNbOfElem) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : end is after the authorized range !"); - int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,end,step,"MEDFileUMeshPerType::loadPartStaticType")); - _m=MEDCoupling1SGTUMesh::New(mName,type); - MEDCoupling1SGTUMesh *mc(dynamic_cast((MEDCoupling1GTUMesh *)_m)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - int nbOfNodesPerCell(mc->getNumberOfNodesPerCell()); - conn->alloc(nbOfNodesPerCell*nbOfEltsToLoad,1); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/nbOfNodesPerCell, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDmeshElementConnectivityAdvancedRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,&filter,conn->getPointer())); - MEDfilterClose(&filter); - std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus(),-1)); - mc->setNodalConnectivity(conn); - loadPartOfCellCommonPart(fid,mName,strt,end,step,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - _fam=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - _fam=DataArrayInt::New(); - _fam->alloc(curNbOfElem,1); - if(MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,entity,geoElt,_fam->getPointer())!=0) - std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); - } - } - _num=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - _num=DataArrayInt::New(); - _num->alloc(curNbOfElem,1); - if(MEDmeshEntityNumberRd(fid,mName,dt,it,entity,geoElt,_num->getPointer())!=0) - _num=0; - } - } - _names=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - _names=DataArrayAsciiChar::New(); - _names->alloc(curNbOfElem+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - if(MEDmeshEntityNameRd(fid,mName,dt,it,entity,geoElt,_names->getPointer())!=0) - _names=0; - else - _names->reAlloc(curNbOfElem);//not a bug to avoid the memory corruption due to last \0 at the end - } - } -} - -void MEDFileUMeshPerType::loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - _fam=0; - int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,stp,step,"MEDFileUMeshPerType::loadPartOfCellCommonPart")); - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - _fam=DataArrayInt::New(); - _fam->alloc(nbOfEltsToLoad,1); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_FAMILY_NUMBER,dt,it,entity,geoElt,&filter,_fam->getPointer())!=0) - _fam->fillWithZero(); - MEDfilterClose(&filter); - } - } - _num=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - _num=DataArrayInt::New(); - _num->alloc(nbOfEltsToLoad,1); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NUMBER,dt,it,entity,geoElt,&filter,_num->getPointer())!=0) - _num->fillWithZero(); - MEDfilterClose(&filter); - } - } - _names=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - _names=DataArrayAsciiChar::New(); - _names->alloc(nbOfEltsToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NAME,dt,it,entity,geoElt,&filter,_names->getPointer())!=0) - _names=0; - else - _names->reAlloc(nbOfEltsToLoad);//not a bug to avoid the memory corruption due to last \0 at the end - MEDfilterClose(&filter); - } - } -} - -void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - med_int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1); - _m=MEDCoupling1DGTUMesh::New(mName,geoElt==MED_POLYGON?INTERP_KERNEL::NORM_POLYGON:INTERP_KERNEL::NORM_QPOLYG); - MEDCouplingAutoRefCountObjectPtr mc(DynamicCast(_m)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - conn->alloc(arraySize,1); connI->alloc(curNbOfElem+1,1); - MEDFILESAFECALLERRD0(MEDmeshPolygon2Rd,(fid,mName,dt,it,MED_CELL,geoElt,MED_NODAL,connI->getPointer(),conn->getPointer())); - std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus(),-1)); - std::transform(connI->begin(),connI->end(),connI->getPointer(),std::bind2nd(std::plus(),-1)); - mc->setNodalConnectivity(conn,connI); - loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - med_int indexFaceLgth(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)); - int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1); - _m=MEDCoupling1DGTUMesh::New(mName,INTERP_KERNEL::NORM_POLYHED); - MEDCouplingAutoRefCountObjectPtr mc(DynamicCastSafe(_m)); - INTERP_KERNEL::AutoPtr index=new int[curNbOfElem+1]; - INTERP_KERNEL::AutoPtr indexFace=new int[indexFaceLgth]; - INTERP_KERNEL::AutoPtr locConn=new int[connFaceLgth]; - MEDFILESAFECALLERRD0(MEDmeshPolyhedronRd,(fid,mName,dt,it,MED_CELL,MED_NODAL,index,indexFace,locConn)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - int arraySize=connFaceLgth; - for(int i=0;ialloc(arraySize,1); - int *wFinalConn=conn->getPointer(); - connI->alloc(curNbOfElem+1,1); - int *finalIndex(connI->getPointer()); - finalIndex[0]=0; - for(int i=0;i(),-1)); - for(int j=index[i];j(),-1)); - } - } - mc->setNodalConnectivity(conn,connI); - loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,MED_POLYHEDRON,entity,mrs); -} - -void MEDFileUMeshPerType::Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names) -{ - int nbOfCells=m->getNumberOfCells(); - if(nbOfCells<1) - return ; - int dt,it; - double timm=m->getTime(dt,it); - INTERP_KERNEL::NormalizedCellType ikt=m->getTypeOfCell(0); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ikt); - med_geometry_type curMedType=typmai3[(int)ikt]; - if(!cm.isDynamic()) - { - const MEDCoupling1SGTUMesh *m0(dynamic_cast(m)); - if(!m0) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #1 !"); - MEDCouplingAutoRefCountObjectPtr arr(m0->getNodalConnectivity()->deepCpy()); - std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::plus(),1)); - MEDFILESAFECALLERWR0(MEDmeshElementConnectivityWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfCells,arr->begin())); - } - else - { - const MEDCoupling1DGTUMesh *m0(dynamic_cast(m)); - if(!m0) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #2 !"); - if(ikt==INTERP_KERNEL::NORM_POLYGON || ikt==INTERP_KERNEL::NORM_QPOLYG) - { - MEDCouplingAutoRefCountObjectPtr arr(m0->getNodalConnectivity()->deepCpy()),arrI(m0->getNodalConnectivityIndex()->deepCpy()); - std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::plus(),1)); - std::transform(arrI->begin(),arrI->end(),arrI->getPointer(),std::bind2nd(std::plus(),1)); - MEDFILESAFECALLERWR0(MEDmeshPolygon2Wr,(fid,mname.c_str(),dt,it,timm,MED_CELL,ikt==INTERP_KERNEL::NORM_POLYGON?MED_POLYGON:MED_POLYGON2,MED_NODAL,nbOfCells+1,arrI->begin(),arr->begin())); - } - else - { - const int *conn(m0->getNodalConnectivity()->begin()),*connI(m0->getNodalConnectivityIndex()->begin()); - int meshLgth=m0->getNodalConnectivityLength(); - int nbOfFaces=std::count(conn,conn+meshLgth,-1)+nbOfCells; - INTERP_KERNEL::AutoPtr tab1=new int[nbOfCells+1]; - int *w1=tab1; *w1=1; - INTERP_KERNEL::AutoPtr tab2=new int[nbOfFaces+1]; - int *w2=tab2; *w2=1; - INTERP_KERNEL::AutoPtr bigtab=new int[meshLgth]; - int *bt=bigtab; - for(int i=0;i(),1)); - int nbOfNode=std::distance(w,wend); - w2[1]=w2[0]+nbOfNode; - if(wend!=conn+connI[i+1]) - w=wend+1; - else - w=wend; - nbOfFaces2++; - } - w1[1]=w1[0]+nbOfFaces2; - } - MEDFILESAFECALLERWR0(MEDmeshPolyhedronWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,MED_NODAL,nbOfCells+1,tab1,nbOfFaces+1,tab2,bigtab)); - } - } - if(fam) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,fam->getConstPointer())); - if(num) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,num->getConstPointer())); - if(names) - { - if(names->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileUMeshPerType::write : expected a name field on cells with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << names->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,names->getConstPointer())); - } -} diff --git a/medtool/src/MEDLoader/MEDFileMeshElt.hxx b/medtool/src/MEDLoader/MEDFileMeshElt.hxx deleted file mode 100644 index 9d57bc1e8..000000000 --- a/medtool/src/MEDLoader/MEDFileMeshElt.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEMESHELT_HXX__ -#define __MEDFILEMESHELT_HXX__ - -#include "MEDCouplingMemArray.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include "med.h" - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class MEDFileMeshReadSelector; - - class MEDFileUMeshPerType : public RefCountObject - { - public: - static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs); - static MEDFileUMeshPerType *NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs); - static bool isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - int getDim() const; - MEDCoupling1GTUMesh *getMesh() const { return const_cast((const MEDCoupling1GTUMesh *)_m); } - const DataArrayInt *getFam() const { return _fam; } - const DataArrayInt *getNum() const { return _num; } - const DataArrayAsciiChar *getNames() const { return _names; } - const PartDefinition *getPartDef() const { return _pd; } - static void Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names); - private: - MEDFileUMeshPerType(); - MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs); - void loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs); - void loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs); - private: - MEDCouplingAutoRefCountObjectPtr _m; - MEDCouplingAutoRefCountObjectPtr _num; - MEDCouplingAutoRefCountObjectPtr _fam; - MEDCouplingAutoRefCountObjectPtr _names; - MEDCouplingAutoRefCountObjectPtr _pd; - med_entity_type _entity; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileMeshLL.cxx b/medtool/src/MEDLoader/MEDFileMeshLL.cxx deleted file mode 100644 index 6adf25496..000000000 --- a/medtool/src/MEDLoader/MEDFileMeshLL.cxx +++ /dev/null @@ -1,1728 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileMeshLL.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileMeshReadSelector.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "InterpKernelAutoPtr.hxx" -#include "CellModel.hxx" - -#include - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmainoeud[1]; - -using namespace ParaMEDMEM; - -MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_univ_name(MED_LNAME_SIZE),_dt_unit(MED_LNAME_SIZE) -{ -} - -std::size_t MEDFileMeshL2::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileMeshL2::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const std::string& mname, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1) -{ - med_mesh_type type_maillage; - char maillage_description[MED_COMMENT_SIZE+1]; - char dtunit[MED_LNAME_SIZE+1]; - med_int spaceDim,dim; - char nommaa[MED_NAME_SIZE+1]; - med_int n=MEDnMesh(fid); - bool found=false; - int ret=-1; - med_sorting_type stype; - std::vector ms; - int nstep; - med_axis_type axistype; - for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); - dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit)); - std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); - ms.push_back(cur); - if(cur==mname) - { - found=true; - ret=i+1; - } - } - if(!found) - { - std::ostringstream oss; - oss << "No such meshname (" << mname << ") in file ! Must be in : "; - std::copy(ms.begin(),ms.end(),std::ostream_iterator(oss,", ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(type_maillage) - { - case MED_UNSTRUCTURED_MESH: - meshType=UNSTRUCTURED; - break; - case MED_STRUCTURED_MESH: - { - med_grid_type gt; - MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mname.c_str(),>)); - switch(gt) - { - case MED_CARTESIAN_GRID: - meshType=CARTESIAN; - break; - case MED_CURVILINEAR_GRID: - meshType=CURVE_LINEAR; - break; - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); - } - med_int numdt,numit; - med_float dtt; - MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mname.c_str(),1,&numdt,&numit,&dtt)); - dt=numdt; it=numit; - return ret; -} - -double MEDFileMeshL2::CheckMeshTimeStep(med_idt fid, const std::string& mName, int nstep, int dt, int it) -{ - bool found=false; - med_int numdt,numit; - med_float dtt; - std::vector< std::pair > p(nstep); - for(int i=0;i MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim) -{ - med_mesh_type type_maillage; - med_int spaceDim; - med_sorting_type stype; - med_axis_type axistype; - int naxis(MEDmeshnAxis(fid,mId)); - INTERP_KERNEL::AutoPtr nameTmp=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr univTmp=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - if(MEDmeshInfo(fid,mId,nameTmp,&spaceDim,&Mdim,&type_maillage,_description.getPointer(),_dt_unit.getPointer(), - &stype,&nstep,&axistype,axisname,axisunit)!=0) - throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !"); - MEDmeshUniversalNameRd(fid,nameTmp,_univ_name.getPointer());// do not protect MEDFILESAFECALLERRD0 call : Thanks to fra.med. - switch(type_maillage) - { - case MED_UNSTRUCTURED_MESH: - meshType=UNSTRUCTURED; - break; - case MED_STRUCTURED_MESH: - { - med_grid_type gt; - MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),>)); - switch(gt) - { - case MED_CARTESIAN_GRID: - meshType=CARTESIAN; - break; - case MED_CURVILINEAR_GRID: - meshType=CURVE_LINEAR; - break; - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); - } - // - std::vector infosOnComp(naxis); - for(int i=0;i& fams, std::map >& grps, MEDFileMeshReadSelector *mrs) -{ - if(mrs && !(mrs->isCellFamilyFieldReading() || mrs->isNodeFamilyFieldReading())) - return ; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - int nfam=MEDnFamily(fid,meshName.c_str()); - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string famName=MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE); - fams[famName]=numfam; - for(int j=0;j& fams, const std::map >& grps, int tooLongStrPol) -{ - for(std::map::const_iterator it=fams.begin();it!=fams.end();it++) - { - std::vector grpsOfFam; - for(std::map >::const_iterator it1=grps.begin();it1!=grps.end();it1++) - { - if(std::find((*it1).second.begin(),(*it1).second.end(),(*it).first)!=(*it1).second.end()) - grpsOfFam.push_back((*it1).first); - } - int ngro=grpsOfFam.size(); - INTERP_KERNEL::AutoPtr groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro); - int i=0; - for(std::vector::const_iterator it2=grpsOfFam.begin();it2!=grpsOfFam.end();it2++,i++) - MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol); - INTERP_KERNEL::AutoPtr famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol); - int ret=MEDfamilyCr(fid,mname.c_str(),famName,(*it).second,ngro,groName); - ret++; - } -} - -MEDFileUMeshL2::MEDFileUMeshL2() -{ -} - -std::vector MEDFileUMeshL2::loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim) -{ - Mdim=-3; - _name.set(mName.c_str()); - int nstep; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::vector ret(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim)); - if(nstep==0) - { - Mdim=-4; - return std::vector(); - } - if(meshType!=UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !"); - _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); - _iteration=dt; - _order=it; - return ret; -} - -void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - int Mdim; - std::vector infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); - if(Mdim==-4) - return ; - loadConnectivity(fid,Mdim,mName,dt,it,mrs);//to improve check (dt,it) coherency - loadCoords(fid,mId,infosOnComp,mName,dt,it); -} - -void MEDFileUMeshL2::loadPart(med_idt fid, int mId, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - int Mdim; - std::vector infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); - if(Mdim==-4) - return ; - loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs); - med_bool changement,transformation; - int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); - std::vector fetchedNodeIds(nCoords,false); - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds); - int nMin(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true))); - int nMax(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true))); - nMax=nCoords-nMax; - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin); - loadPartCoords(fid,mId,infosOnComp,mName,dt,it,nMin,nMax); -} - -void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - _per_type_mesh.resize(1); - _per_type_mesh[0].clear(); - for(int j=0;j& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - std::size_t nbOfTypes(types.size()); - if(slicPerTyp.size()!=3*nbOfTypes) - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : The size of slicPerTyp array is expected to be equal to 3 times size of array types !"); - std::set types2(types.begin(),types.end()); - if(types2.size()!=nbOfTypes) - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : the geometric types in types array must appear once !"); - _per_type_mesh.resize(1); - _per_type_mesh[0].clear(); - for(std::size_t ii=0;ii tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,types[ii],strt,stp,step,mrs)); - _per_type_mesh[0].push_back(tmp); - } - sortTypes(); -} - -void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it) -{ - int spaceDim((int)infosOnComp.size()); - med_bool changement,transformation; - int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); - _coords=DataArrayDouble::New(); - _coords->alloc(nCoords,spaceDim); - double *coordsPtr(_coords->getPointer()); - if (nCoords) - MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,coordsPtr)); - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nCoords,1); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer())); - } - else - _fam_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _num_coords=DataArrayInt::New(); - _num_coords->alloc(nCoords,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer())); - } - else - _num_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - _name_coords=DataArrayAsciiChar::New(); - _name_coords->alloc(nCoords+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_name_coords->getPointer())); - _name_coords->reAlloc(nCoords);//not a bug to avoid the memory corruption due to last \0 at the end - } - else - _name_coords=0; - for(int i=0;isetInfoOnComponent(i,infosOnComp[i]); -} - -void MEDFileUMeshL2::loadPartCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax) -{ - med_bool changement,transformation; - int spaceDim((int)infosOnComp.size()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); - _coords=DataArrayDouble::New(); - int nbNodesToLoad(nMax-nMin); - _coords->alloc(nbNodesToLoad,spaceDim); - med_filter filter=MED_FILTER_INIT,filter2=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/nCoords,/*nvaluesperentity*/1,/*nconstituentpervalue*/spaceDim, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/nMin+1,/*stride*/1,/*count*/1,/*blocksize*/nbNodesToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateAdvancedRd,(fid,mName.c_str(),dt,it,&filter,_coords->getPointer())); - _part_coords=PartDefinition::New(nMin,nMax,1); - MEDfilterClose(&filter); - MEDfilterBlockOfEntityCr(fid,nCoords,1,1,MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE, - MED_NO_PROFILE,nMin+1,1,1,nbNodesToLoad,0,&filter2); - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nbNodesToLoad,1); - MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_FAMILY_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_fam_coords->getPointer())); - } - else - _fam_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _num_coords=DataArrayInt::New(); - _num_coords->alloc(nbNodesToLoad,1); - MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_num_coords->getPointer())); - } - else - _num_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - _name_coords=DataArrayAsciiChar::New(); - _name_coords->alloc(nbNodesToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NAME,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_name_coords->getPointer())); - _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end - } - else - _name_coords=0; - MEDfilterClose(&filter2); - _coords->setInfoOnComponents(infosOnComp); -} - -void MEDFileUMeshL2::sortTypes() -{ - std::set mdims; - std::vector< MEDCouplingAutoRefCountObjectPtr > tmp(_per_type_mesh[0]); - _per_type_mesh.clear(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) - mdims.insert((*it)->getDim()); - if(mdims.empty()) - return; - int mdim=*mdims.rbegin(); - _per_type_mesh.resize(mdim+1); - for(int dim=mdim+1;dim!=0;dim--) - { - std::vector< MEDCouplingAutoRefCountObjectPtr >& elt=_per_type_mesh[mdim+1-dim]; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) - if((*it)->getDim()==dim-1) - elt.push_back(*it); - } - // suppression of contiguous empty levels at the end of _per_type_mesh. - int nbOfUselessLev=0; - bool isFirst=true; - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::reverse_iterator it2=_per_type_mesh.rbegin();it2!=_per_type_mesh.rend();it2++) - { - if((*it2).empty() && isFirst) - { - nbOfUselessLev++; - } - else - isFirst=false; - } - _per_type_mesh.resize(_per_type_mesh.size()-nbOfUselessLev); -} - -void MEDFileUMeshL2::WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords) -{ - if(!coords) - return ; - MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,mname.c_str(),dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getConstPointer())); - if(famCoords) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getConstPointer())); - if(numCoords) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getConstPointer())); - if(nameCoords) - { - if(nameCoords->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << " MEDFileUMeshL2::WriteCoords : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << nameCoords->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,nameCoords->getNumberOfTuples(),nameCoords->getConstPointer())); - } -} - -bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) - if((*it)->getFam()==0) - return false; - return true; -} - -bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) - if((*it)->getNum()==0) - return false; - return true; -} - -bool MEDFileUMeshL2::isNamesDefinedOnLev(int levId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) - if((*it)->getNames()==0) - return false; - return true; -} - -MEDFileCMeshL2::MEDFileCMeshL2() -{ -} - -void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it) -{ - _name.set(mName.c_str()); - int nstep; - int Mdim; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim); - if(meshType!=CARTESIAN) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); - _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); - _iteration=dt; - _order=it; - // - med_grid_type gridtype; - MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gridtype)); - if(gridtype!=MED_CARTESIAN_GRID) - throw INTERP_KERNEL::Exception("Invalid structured mesh ! Expected cartesian mesh type !"); - _cmesh=MEDCouplingCMesh::New(); - for(int i=0;i da=DataArrayDouble::New(); - da->alloc(nbOfElt,1); - da->setInfoOnComponent(0,infosOnComp[i]); - MEDFILESAFECALLERRD0(MEDmeshGridIndexCoordinateRd,(fid,mName.c_str(),dt,it,i+1,da->getPointer())); - _cmesh->setCoordsAt(i,da); - } -} - -med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id) -{ - switch(id) - { - case 0: - return MED_COORDINATE_AXIS1; - case 1: - return MED_COORDINATE_AXIS2; - case 2: - return MED_COORDINATE_AXIS3; - default: - throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !"); - } -} - -MEDFileCLMeshL2::MEDFileCLMeshL2() -{ -} - -void MEDFileCLMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it) -{ - _name.set(mName.c_str()); - int nstep; - int Mdim; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim); - if(meshType!=CURVE_LINEAR) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); - _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); - _iteration=dt; - _order=it; - // - _clmesh=MEDCouplingCurveLinearMesh::New(); - INTERP_KERNEL::AutoPtr stGrid=new int[Mdim]; - MEDFILESAFECALLERRD0(MEDmeshGridStructRd,(fid,mName.c_str(),dt,it,stGrid)); - _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim); - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbNodes(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf)); - MEDCouplingAutoRefCountObjectPtr da=DataArrayDouble::New(); - da->alloc(nbNodes,infosOnComp.size()); - da->setInfoOnComponents(infosOnComp); - MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,da->getPointer())); - _clmesh->setCoords(da); -} - -MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0) -{ -} - -/*! - * Warning it returns an instance to deallocate !!!! - */ -MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const -{ - _st->_num->updateTime(); - if((MEDCouplingUMesh *)_m==0) - { - updateTime(); - _m=static_cast(_st->_m_by_types.getUmesh()->deepCpy()); - _m->renumberCells(_st->_num->getConstPointer(),true); - return _m.retn(); - } - else - { - if(_mpt_time==_st->_m_by_types.getTimeOfThis() && _num_time==_st->_num->getTimeOfThis()) - return _m.retn(); - else - { - updateTime(); - _m=static_cast(_st->_m_by_types.getUmesh()->deepCpy()); - _m->renumberCells(_st->_num->getConstPointer(),true); - return _m.retn(); - } - } -} - -void MEDFileUMeshPermCompute::operator=(MEDCouplingUMesh *m) -{ - _m=m; -} - -void MEDFileUMeshPermCompute::updateTime() const -{ - _mpt_time=_st->_m_by_types.getTimeOfThis(); - _num_time=_st->_num->getTimeOfThis(); -} - -std::vector MEDFileUMeshPermCompute::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCouplingUMesh *)_m); - return ret; -} - -std::size_t MEDFileUMeshPermCompute::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDFileUMeshPermCompute); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):RefCountObject(other),_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_names(other._names),_rev_num(other._rev_num),_m(this) -{ -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id):_m(this) -{ - const std::vector< MEDCouplingAutoRefCountObjectPtr >& v=l2.getLev(id); - if(v.empty()) - return; - int sz=v.size(); - std::vector ms(sz); - std::vector fams(sz),nums(sz); - std::vector names(sz); - std::vector pds(sz); - for(int i=0;igetMesh()); - MEDCouplingAutoRefCountObjectPtr tmp2=l2.getCoords(); - elt->setCoords(tmp2); - ms[i]=elt; - pds[i]=v[i]->getPartDef(); - } - _m_by_types.assignParts(ms); - _m_by_types.assignDefParts(pds); - if(l2.isFamDefinedOnLev(id)) - { - for(int i=0;igetFam(); - if(sz!=1) - _fam=DataArrayInt::Aggregate(fams); - else - { - fams[0]->incrRef(); - _fam=const_cast(fams[0]); - } - } - if(l2.isNumDefinedOnLev(id)) - { - for(int i=0;igetNum(); - if(sz!=1) - _num=DataArrayInt::Aggregate(nums); - else - { - nums[0]->incrRef(); - _num=const_cast(nums[0]); - } - computeRevNum(); - } - if(l2.isNamesDefinedOnLev(id)) - { - for(int i=0;igetNames(); - _names=dynamic_cast(DataArrayChar::Aggregate(names)); - } -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m):_m(this) -{ - std::vector< const MEDCoupling1GTUMesh * > v(1); - v[0]=m; - assignParts(v); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m):_m(this) -{ - assignMesh(m,true); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(this) -{ - assignMesh(m,newOrOld); -} - -void MEDFileUMeshSplitL1::setName(const std::string& name) -{ - _m_by_types.setName(name); -} - -std::size_t MEDFileUMeshSplitL1::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileUMeshSplitL1::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(&_m_by_types); - ret.push_back(&_m); - ret.push_back((const DataArrayInt*)_fam); - ret.push_back((const DataArrayInt*)_num); - ret.push_back((const DataArrayInt*)_rev_num); - ret.push_back((const DataArrayAsciiChar*)_names); - return ret; -} - -MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCpy(DataArrayDouble *coords) const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMeshSplitL1(*this); - ret->_m_by_types=_m_by_types.deepCpy(coords); - if((const DataArrayInt *)_fam) - ret->_fam=_fam->deepCpy(); - if((const DataArrayInt *)_num) - ret->_num=_num->deepCpy(); - if((const DataArrayInt *)_rev_num) - ret->_rev_num=_rev_num->deepCpy(); - if((const DataArrayAsciiChar *)_names) - ret->_names=_names->deepCpy(); - return ret.retn(); -} - -bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const -{ - if(!_m_by_types.isEqual(other->_m_by_types,eps,what)) - return false; - const DataArrayInt *d1=_fam; - const DataArrayInt *d2=other->_fam; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Presence of family arr in one sublevel and not in other!"; - return false; - } - if(d1) - if(!d1->isEqual(*d2)) - { - what="family arr at a sublevel are not deeply equal !"; - return false; - } - d1=_num; - d2=other->_num; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Presence of cell numbering arr in one sublevel and not in other!"; - return false; - } - if(d1) - if(!d1->isEqual(*d2)) - { - what="Numbering cell arr at a sublevel are not deeply equal !"; - return false; - } - const DataArrayAsciiChar *e1=_names; - const DataArrayAsciiChar *e2=other->_names; - if((e1==0 && e2!=0) || (e1!=0 && e2==0)) - { - what="Presence of cell names arr in one sublevel and not in other!"; - return false; - } - if(e1) - if(!e1->isEqual(*e2)) - { - what="Name cell arr at a sublevel are not deeply equal !"; - return false; - } - return true; -} - -void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const -{ - _m_by_types.synchronizeTinyInfo(master); -} - -void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const -{ - _m_by_types.clearNonDiscrAttributes(); -} - -void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp) -{ - if(!tmp) - return ; - (const_cast(tmp))->setName(""); - (const_cast(tmp))->setDescription(""); - (const_cast(tmp))->setTime(0.,-1,-1); - (const_cast(tmp))->setTimeUnit(""); -} - -void MEDFileUMeshSplitL1::setCoords(DataArrayDouble *coords) -{ - _m_by_types.setCoords(coords); -} - -void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) -{ - if(newOrOld) - { - m->incrRef(); - _m=m; - _m_by_types.assignUMesh(dynamic_cast(m->deepCpy())); - MEDCouplingAutoRefCountObjectPtr da=_m_by_types.getUmesh()->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); - if(!da->isIdentity()) - { - _num=da->invertArrayO2N2N2O(m->getNumberOfCells()); - _m.updateTime(); - computeRevNum(); - _m_by_types.getUmesh()->renumberCells(da->getConstPointer(),false); - } - } - else - { - if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO)) - throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh(): the mesh does not follow the MED file numbering convention! Invoke sortCellsInMEDFileFrmt() first!"); - m->incrRef(); - _m_by_types.assignUMesh(m); - } - assignCommonPart(); -} - -void MEDFileUMeshSplitL1::forceComputationOfParts() const -{ - _m_by_types.forceComputationOfPartsFromUMesh(); -} - -void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts) -{ - _m_by_types.assignParts(mParts); - assignCommonPart(); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1():_m(this) -{ -} - -void MEDFileUMeshSplitL1::assignCommonPart() -{ - _fam=DataArrayInt::New(); - _fam->alloc(_m_by_types.getSize(),1); - _fam->fillWithValue(0); -} - -bool MEDFileUMeshSplitL1::empty() const -{ - return _m_by_types.empty(); -} - -bool MEDFileUMeshSplitL1::presenceOfOneFams(const std::vector& ids) const -{ - const DataArrayInt *fam=_fam; - if(!fam) - return false; - return fam->presenceOfValue(ids); -} - -int MEDFileUMeshSplitL1::getMeshDimension() const -{ - return _m_by_types.getMeshDimension(); -} - -void MEDFileUMeshSplitL1::simpleRepr(std::ostream& oss) const -{ - std::vector code=_m_by_types.getDistributionOfTypes(); - int nbOfTypes=code.size()/3; - for(int i=0;i eltsToKeep=_fam->getIdsEqualList(idsBg,idsEnd); - MEDCouplingUMesh *m=(MEDCouplingUMesh *)_m_by_types.getUmesh()->buildPartOfMySelf(eltsToKeep->getConstPointer(),eltsToKeep->getConstPointer()+eltsToKeep->getNumberOfTuples(),true); - if(renum) - return renumIfNeeded(m,eltsToKeep->getConstPointer()); - return m; -} - -DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const -{ - MEDCouplingAutoRefCountObjectPtr da=_fam->getIdsEqualList(idsBg,idsEnd); - if(renum) - return renumIfNeededArr(da); - return da.retn(); -} - -std::vector MEDFileUMeshSplitL1::getGeoTypes() const -{ - return _m_by_types.getGeoTypes(); -} - -int MEDFileUMeshSplitL1::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const -{ - return _m_by_types.getNumberOfCellsWithType(ct); -} - -MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const -{ - MEDCouplingAutoRefCountObjectPtr tmp; - if(renum && ((const DataArrayInt *)_num)) - tmp=_m; - else - { tmp=_m_by_types.getUmesh(); if(tmp) tmp->incrRef(); } - return tmp.retn(); -} - -int MEDFileUMeshSplitL1::getNumberOfCells() const -{ - return _m_by_types.getNumberOfCells(); -} - -DataArrayInt *MEDFileUMeshSplitL1::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const DataArrayInt *fam(_fam); - if(!fam) - return 0; - int start(0),stop(0); - _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop); - return fam->selectByTupleId2(start,stop,1); -} - -DataArrayInt *MEDFileUMeshSplitL1::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const DataArrayInt *num(_num); - if(!num) - return 0; - int start(0),stop(0); - _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop); - return num->selectByTupleId2(start,stop,1); -} - -DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField() -{ - if((DataArrayInt *)_fam) - return _fam; - int nbOfTuples=_m_by_types.getSize(); - _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero(); - return _fam; -} - -const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const -{ - return _fam; -} - -const DataArrayInt *MEDFileUMeshSplitL1::getNumberField() const -{ - return _num; -} - -const DataArrayInt *MEDFileUMeshSplitL1::getRevNumberField() const -{ - return _rev_num; -} - -const DataArrayAsciiChar *MEDFileUMeshSplitL1::getNameField() const -{ - return _names; -} - -const PartDefinition *MEDFileUMeshSplitL1::getPartDef(INTERP_KERNEL::NormalizedCellType gt) const -{ - return _m_by_types.getPartDefOfWithoutComputation(gt); -} - -void MEDFileUMeshSplitL1::eraseFamilyField() -{ - _fam->fillWithZero(); -} - -/*! - * This method ignores _m and _m_by_types. - */ -void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector& ms, std::map& familyIds, - std::map >& groups) -{ - std::vector< DataArrayInt * > corr; - _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr); - std::vector< MEDCouplingAutoRefCountObjectPtr > corrMSafe(corr.begin(),corr.end()); - std::vector< std::vector > fidsOfGroups; - std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end()); - _fam=DataArrayInt::MakePartition(corr2,((MEDCouplingUMesh *)_m)->getNumberOfCells(),fidsOfGroups); - int nbOfCells=((MEDCouplingUMesh *)_m)->getNumberOfCells(); - std::map newfams; - std::map famIdTrad; - TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams); - int *w=_fam->getPointer(); - for(int i=0;i ms(_m_by_types.getParts()); - int start=0; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - { - int nbCells=(*it)->getNumberOfCells(); - int end=start+nbCells; - MEDCouplingAutoRefCountObjectPtr fam,num; - MEDCouplingAutoRefCountObjectPtr names; - if((const DataArrayInt *)_fam) - fam=_fam->substr(start,end); - if((const DataArrayInt *)_num) - num=_num->substr(start,end); - if((const DataArrayAsciiChar *)_names) - names=static_cast(_names->substr(start,end)); - MEDFileUMeshPerType::Write(fid,mName,mdim,(*it),fam,num,names); - start=end; - } -} - -void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - _m_by_types.renumberNodesInConnWithoutComputation(newNodeNumbersO2N); -} - -void MEDFileUMeshSplitL1::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - bigArraysI.push_back(_fam); - bigArraysI.push_back(_num); - _m_by_types.serialize(tinyInt,bigArraysI); -} - -void MEDFileUMeshSplitL1::unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - _fam=bigArraysI.back(); bigArraysI.pop_back(); - _num=bigArraysI.back(); bigArraysI.pop_back(); - _m_by_types.unserialize(name,coo,tinyInt,bigArraysI); -} - -void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) -{ - DataArrayInt *arr=_fam; - if(arr) - arr->changeValue(oldId,newId); -} - -void MEDFileUMeshSplitL1::setFamilyArr(DataArrayInt *famArr) -{ - if(!famArr) - { - _fam=0; - return ; - } - int sz(_m_by_types.getSize()); - famArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setFamilyArr : Problem in size of Family arr ! "); - famArr->incrRef(); - _fam=famArr; -} - -DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() -{ - return _fam; -} - -void MEDFileUMeshSplitL1::setRenumArr(DataArrayInt *renumArr) -{ - if(!renumArr) - { - _num=0; - _rev_num=0; - return ; - } - int sz(_m_by_types.getSize()); - renumArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setRenumArr : Problem in size of numbering arr ! "); - renumArr->incrRef(); - _num=renumArr; - computeRevNum(); -} - -void MEDFileUMeshSplitL1::setNameArr(DataArrayAsciiChar *nameArr) -{ - if(!nameArr) - { - _names=0; - return ; - } - int sz(_m_by_types.getSize()); - nameArr->checkNbOfTuplesAndComp(sz,MED_SNAME_SIZE,"MEDFileUMeshSplitL1::setNameArr : Problem in size of name arr ! "); - nameArr->incrRef(); - _names=nameArr; -} - -MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds) -{ - if(renum==0) - return m; - if(cellIds==0) - m->renumberCells(renum->getConstPointer(),true); - else - { - MEDCouplingAutoRefCountObjectPtr locnum=renum->selectByTupleId(cellIds,cellIds+m->getNumberOfCells()); - m->renumberCells(locnum->getConstPointer(),true); - } - return m; -} - -MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::Unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMeshSplitL1); - ret->unserialize(name,coo,tinyInt,bigArraysI); - return ret.retn(); -} - -MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const -{ - return Renumber2(_num,m,cellIds); -} - -DataArrayInt *MEDFileUMeshSplitL1::Renumber(const DataArrayInt *renum, const DataArrayInt *da) -{ - if((const DataArrayInt *)renum==0) - { - da->incrRef(); - return const_cast(da); - } - return renum->selectByTupleId(da->getConstPointer(),da->getConstPointer()+da->getNumberOfTuples()); -} - -DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) const -{ - return Renumber(_num,da); -} - -std::vector MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map& families) -{ - int id=-1; - for(std::map::const_iterator it=families.begin();it!=families.end();it++) - id=std::max(id,(*it).second); - if(id==-1) - id=0; - std::vector ret(nb); - for(int i=1;i<=nb;i++) - ret[i]=id+i; - return ret; -} - -void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, - std::map& famIdTrad, std::map& newfams) -{ - std::set allfids; - //tony -} - -void MEDFileUMeshSplitL1::computeRevNum() const -{ - int pos; - int maxValue=_num->getMaxValue(pos); - _rev_num=_num->invertArrayN2O2O2N(maxValue+1); -} - -//= - -MEDFileUMeshAggregateCompute::MEDFileUMeshAggregateCompute():_mp_time(0),_m_time(0) -{ -} - -void MEDFileUMeshAggregateCompute::setName(const std::string& name) -{ - if(_m_time>=_mp_time) - { - MEDCouplingUMesh *um(_m); - if(um) - um->setName(name); - } - if(_mp_time>=_m_time) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - MEDCoupling1GTUMesh *tmp(*it); - if(tmp) - tmp->setName(name); - } - } -} - -void MEDFileUMeshAggregateCompute::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts) -{ - std::size_t sz(mParts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(sz); - for(std::size_t i=0;i(elt); elt->incrRef(); - } - _m_parts=ret; - _part_def.clear(); _part_def.resize(sz); - _mp_time=std::max(_mp_time,_m_time)+1; - _m=0; -} - -void MEDFileUMeshAggregateCompute::assignDefParts(const std::vector& partDefs) -{ - if(_mp_time<_m_time) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : the parts require a computation !"); - std::size_t sz(partDefs.size()); - if(_part_def.size()!=partDefs.size() || _part_def.size()!=_m_parts.size()) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : sizes of vectors of part definition mismatch !"); - for(std::size_t i=0;iincrRef(); - _part_def[i]=const_cast(elt); - } -} - -void MEDFileUMeshAggregateCompute::assignUMesh(MEDCouplingUMesh *m) -{ - _m=m; - _m_parts.clear(); - _m_time=std::max(_mp_time,_m_time)+1; -} - -MEDCouplingUMesh *MEDFileUMeshAggregateCompute::getUmesh() const -{ - if(_mp_time<=_m_time) - return _m; - std::vector< const MEDCoupling1GTUMesh *> mp(_m_parts.size()); - std::copy(_m_parts.begin(),_m_parts.end(),mp.begin()); - _m=MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(mp); - _m_parts.clear();//to avoid memory peak ! - _m_time=_mp_time+1;//+1 is important ! That is to say that only _m is OK not _m_parts because cleared ! - return _m; -} - -int MEDFileUMeshAggregateCompute::getNumberOfCells() const -{ - if(_mp_time<=_m_time) - return _m->getNumberOfCells(); - int ret(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - ret+=(*it)->getNumberOfCells(); - return ret; -} - -std::vector MEDFileUMeshAggregateCompute::getGeoTypes() const -{ - if(_mp_time>=_m_time) - { - std::size_t sz(_m_parts.size()); - std::vector ret(sz); - for(std::size_t i=0;igetCellModelEnum(); - return ret; - } - else - return _m->getAllGeoTypesSorted(); -} - -int MEDFileUMeshAggregateCompute::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const -{ - if(_mp_time>=_m_time) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *elt(*it); - if(elt && elt->getCellModelEnum()==ct) - return elt->getNumberOfCells(); - } - return 0; - } - else - return _m->getNumberOfCellsWithType(ct); -} - -std::vector MEDFileUMeshAggregateCompute::retrievePartsWithoutComputation() const -{ - if(_mp_time<_m_time) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartsWithoutComputation : the parts require a computation !"); - // - std::vector ret(_m_parts.size()); - std::size_t i(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++,i++) - { - const MEDCoupling1GTUMesh *elt(*it); - ret[i]=const_cast(elt); - } - return ret; -} - -std::vector MEDFileUMeshAggregateCompute::getParts() const -{ - if(_mp_time<_m_time) - forceComputationOfPartsFromUMesh(); - return retrievePartsWithoutComputation(); -} - -MEDCoupling1GTUMesh *MEDFileUMeshAggregateCompute::retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const -{ - std::vector v(retrievePartsWithoutComputation()); - std::size_t sz(v.size()); - for(std::size_t i=0;igetCellModelEnum()==gt) - return v[i]; - } - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartWithoutComputation : the geometric type is not existing !"); -} - -void MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const -{ - start=0; stop=0; - std::vector v(retrievePartsWithoutComputation()); - std::size_t sz(v.size()); - for(std::size_t i=0;igetCellModelEnum()==gt) - { - stop=start+v[i]->getNumberOfCells(); - return; - } - else - start+=v[i]->getNumberOfCells(); - } - } - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation : the geometric type is not existing !"); -} - -void MEDFileUMeshAggregateCompute::renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N) -{ - if(_mp_time>_m_time) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - MEDCoupling1GTUMesh *m(*it); - if(m) - m->renumberNodesInConn(newNodeNumbersO2N); - } - } - else - { - MEDCouplingUMesh *m(getUmesh()); - if(!m) - return; - m->renumberNodesInConn(newNodeNumbersO2N); - } -} - -void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const -{ - const MEDCouplingUMesh *m(_m); - if(!m) - { - if(_m_parts.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh : null UMesh !"); - else - return ;// no needs to compte parts they are already here ! - } - std::vector ms(m->splitByType()); - std::vector< MEDCouplingAutoRefCountObjectPtr > msMSafe(ms.begin(),ms.end()); - std::size_t sz(msMSafe.size()); - _m_parts.resize(sz); - for(std::size_t i=0;igetCellModelEnum()==gt) - return _part_def[i]; - } - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : The input geo type is not existing in this !"); -} - -void MEDFileUMeshAggregateCompute::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - if(_mp_time<_m_time) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : the parts require a computation !"); - std::size_t sz(_m_parts.size()); - tinyInt.push_back((int)sz); - for(std::size_t i=0;igetCellModelEnum()); - const MEDCoupling1SGTUMesh *mesh1(dynamic_cast(mesh)); - const MEDCoupling1DGTUMesh *mesh2(dynamic_cast(mesh)); - if(mesh1) - { - DataArrayInt *elt(mesh1->getNodalConnectivity()); - if(elt) - elt->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt1(elt); - bigArraysI.push_back(elt1); - } - else if(mesh2) - { - DataArrayInt *elt1(mesh2->getNodalConnectivity()),*elt2(mesh2->getNodalConnectivityIndex()); - if(elt1) - elt1->incrRef(); - if(elt2) - elt2->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt11(elt1),elt22(elt2); - bigArraysI.push_back(elt11); bigArraysI.push_back(elt22); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : unrecognized single geo type mesh !"); - const PartDefinition *pd(_part_def[i]); - if(!pd) - tinyInt.push_back(-1); - else - { - std::vector tinyTmp; - pd->serialize(tinyTmp,bigArraysI); - tinyInt.push_back((int)tinyTmp.size()); - tinyInt.insert(tinyInt.end(),tinyTmp.begin(),tinyTmp.end()); - } - } -} - -void MEDFileUMeshAggregateCompute::unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - int nbParts(tinyInt.back()); tinyInt.pop_back(); - _part_def.clear(); _part_def.resize(nbParts); - _m_parts.clear(); _m_parts.resize(nbParts); - for(int i=0;i mesh(MEDCoupling1GTUMesh::New(name,tp)); - mesh->setCoords(coo); - MEDCoupling1SGTUMesh *mesh1(dynamic_cast((MEDCoupling1GTUMesh *) mesh)); - MEDCoupling1DGTUMesh *mesh2(dynamic_cast((MEDCoupling1GTUMesh *) mesh)); - if(mesh1) - { - mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back(); - } - else if(mesh2) - { - MEDCouplingAutoRefCountObjectPtr elt0,elt1; - elt0=bigArraysI.back(); bigArraysI.pop_back(); - elt1=bigArraysI.back(); bigArraysI.pop_back(); - mesh2->setNodalConnectivity(elt0,elt1); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::unserialize : unrecognized single geo type mesh !"); - _m_parts[i]=mesh; - int pdid(tinyInt.back()); tinyInt.pop_back(); - if(pdid!=-1) - _part_def[i]=PartDefinition::Unserialize(tinyInt,bigArraysI); - _mp_time=std::max(_mp_time,_m_time)+1; - } -} - -/*! - * This method returns true if \a this is stored split by type false if stored in a merged unstructured mesh. - */ -bool MEDFileUMeshAggregateCompute::isStoredSplitByType() const -{ - return _mp_time>=_m_time; -} - -std::size_t MEDFileUMeshAggregateCompute::getTimeOfThis() const -{ - if(_mp_time>_m_time) - return getTimeOfParts(); - if(_m_time>_mp_time) - return getTimeOfUMesh(); - return std::max(getTimeOfParts(),getTimeOfUMesh()); -} - -std::size_t MEDFileUMeshAggregateCompute::getTimeOfParts() const -{ - std::size_t ret(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *elt(*it); - if(!elt) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : null obj in parts !"); - ret=std::max(ret,elt->getTimeOfThis()); - } - if(ret==0) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : parts is empty !"); - return ret; -} - -std::size_t MEDFileUMeshAggregateCompute::getTimeOfUMesh() const -{ - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfUMesh : unmesh is null !"); - return m->getTimeOfThis(); -} - -std::size_t MEDFileUMeshAggregateCompute::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_m_parts.size()*sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; -} - -std::vector MEDFileUMeshAggregateCompute::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - ret.push_back((const MEDCoupling1GTUMesh *)*it); - ret.push_back((const MEDCouplingUMesh *)_m); - return ret; -} - -MEDFileUMeshAggregateCompute MEDFileUMeshAggregateCompute::deepCpy(DataArrayDouble *coords) const -{ - MEDFileUMeshAggregateCompute ret; - ret._m_parts.resize(_m_parts.size()); - for(std::size_t i=0;i<_m_parts.size();i++) - { - const MEDCoupling1GTUMesh *elt(_m_parts[i]); - if(elt) - { - ret._m_parts[i]=static_cast(elt->deepCpy()); - ret._m_parts[i]->setCoords(coords); - } - } - ret._mp_time=_mp_time; ret._m_time=_m_time; - if((const MEDCouplingUMesh *)_m) - { - ret._m=static_cast(_m->deepCpy()); - ret._m->setCoords(coords); - } - std::size_t sz(_part_def.size()); - ret._part_def.clear(); ret._part_def.resize(sz); - for(std::size_t i=0;ideepCpy(); - } - return ret; -} - -bool MEDFileUMeshAggregateCompute::isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const -{ - const MEDCouplingUMesh *m1(getUmesh()); - const MEDCouplingUMesh *m2(other.getUmesh()); - if((m1==0 && m2!=0) || (m1!=0 && m2==0)) - { - what="Presence of mesh in one sublevel and not in other!"; - return false; - } - if(m1) - { - std::string what2; - if(!m1->isEqualIfNotWhy(m2,eps,what2)) - { - what=std::string("meshes at a sublevel are not deeply equal (")+what2+std::string(")!"); - return false; - } - } - std::size_t sz(_part_def.size()); - if(sz!=other._part_def.size()) - { - what=std::string("number of subdivision per geo type for part definition is not the same !"); - return false; - } - for(std::size_t i=0;iisEqual(pd1,what)); - if(!ret) - return false; - } - return true; -} - -void MEDFileUMeshAggregateCompute::clearNonDiscrAttributes() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(*it); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_m); -} - -void MEDFileUMeshAggregateCompute::synchronizeTinyInfo(const MEDFileMesh& master) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *tmp(*it); - if(tmp) - { - (const_cast(tmp))->setName(master.getName().c_str()); - (const_cast(tmp))->setDescription(master.getDescription().c_str()); - (const_cast(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); - (const_cast(tmp))->setTimeUnit(master.getTimeUnit()); - } - } - const MEDCouplingUMesh *m(_m); - if(m) - { - (const_cast(m))->setName(master.getName().c_str()); - (const_cast(m))->setDescription(master.getDescription().c_str()); - (const_cast(m))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); - (const_cast(m))->setTimeUnit(master.getTimeUnit()); - } -} - -bool MEDFileUMeshAggregateCompute::empty() const -{ - if(_mp_time<_m_time) - return ((const MEDCouplingUMesh *)_m)==0; - //else _mp_time>=_m_time) - return _m_parts.empty(); -} - -int MEDFileUMeshAggregateCompute::getMeshDimension() const -{ - if(_mp_time<_m_time) - { - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : no umesh in this !"); - return m->getMeshDimension(); - } - else - { - if(_m_parts.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh is empty !"); - const MEDCoupling1GTUMesh *m(_m_parts[0]); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh contains null instance !"); - return m->getMeshDimension(); - } -} - -std::vector MEDFileUMeshAggregateCompute::getDistributionOfTypes() const -{ - if(_mp_time<_m_time) - { - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : no umesh in this !"); - return m->getDistributionOfTypes(); - } - else - { - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *tmp(*it); - if(!tmp) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : part mesh contains null instance !"); - std::vector ret0(tmp->getDistributionOfTypes()); - ret.insert(ret.end(),ret0.begin(),ret0.end()); - } - return ret; - } -} - -int MEDFileUMeshAggregateCompute::getSize() const -{ - if(_mp_time<_m_time) - { - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : no umesh in this !"); - return m->getNumberOfCells(); - } - else - { - int ret=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *m(*it); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : part mesh contains null instance !"); - ret+=m->getNumberOfCells(); - } - return ret; - } -} - -void MEDFileUMeshAggregateCompute::setCoords(DataArrayDouble *coords) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - MEDCoupling1GTUMesh *tmp(*it); - if(tmp) - (*it)->setCoords(coords); - } - MEDCouplingUMesh *m(_m); - if(m) - m->setCoords(coords); -} diff --git a/medtool/src/MEDLoader/MEDFileMeshLL.hxx b/medtool/src/MEDLoader/MEDFileMeshLL.hxx deleted file mode 100644 index a65e0c106..000000000 --- a/medtool/src/MEDLoader/MEDFileMeshLL.hxx +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEMESHLL_HXX__ -#define __MEDFILEMESHLL_HXX__ - -#include "MEDFileBasis.hxx" -#include "MEDFileMeshElt.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDCouplingCurveLinearMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "med.h" - -#include - -namespace ParaMEDMEM -{ - class MEDFileMeshReadSelector; - - class MEDFileMeshL2 : public RefCountObject - { - public: - MEDFileMeshL2(); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - const char *getName() const { return _name.getReprForWrite(); } - const char *getDescription() const { return _description.getReprForWrite(); } - const char *getUnivName() const { return _univ_name.getReprForWrite(); } - const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); } - int getIteration() const { return _iteration; } - int getOrder() const { return _order; } - double getTime() const { return _time; } - MEDCouplingAutoRefCountObjectPtr getPartDefOfCoo() const { return _part_coords; } - std::vector getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim); - static int GetMeshIdFromName(med_idt fid, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1); - static double CheckMeshTimeStep(med_idt fid, const std::string& mname, int nstep, int dt, int it); - static void ReadFamiliesAndGrps(med_idt fid, const std::string& mname, std::map& fams, std::map >& grps, MEDFileMeshReadSelector *mrs); - static void WriteFamiliesAndGrps(med_idt fid, const std::string& mname, const std::map& fams, const std::map >& grps, int tooLongStrPol); - protected: - MEDFileString _name; - MEDFileString _description; - MEDFileString _univ_name; - MEDFileString _dt_unit; - int _iteration; - int _order; - double _time; - MEDCouplingAutoRefCountObjectPtr _part_coords; - }; - - class MEDFileUMeshL2 : public MEDFileMeshL2 - { - public: - MEDFileUMeshL2(); - std::vector loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim); - void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadPart(med_idt fid, int mId, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it); - void loadPartCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax); - int getNumberOfLevels() const { return _per_type_mesh.size(); } - bool emptyLev(int levId) const { return _per_type_mesh[levId].empty(); } - const std::vector< MEDCouplingAutoRefCountObjectPtr >& getLev(int levId) const { return _per_type_mesh[levId]; } - bool isFamDefinedOnLev(int levId) const; - bool isNumDefinedOnLev(int levId) const; - bool isNamesDefinedOnLev(int levId) const; - MEDCouplingAutoRefCountObjectPtr getCoords() const { return _coords; } - MEDCouplingAutoRefCountObjectPtr getCoordsFamily() const { return _fam_coords; } - MEDCouplingAutoRefCountObjectPtr getCoordsNum() const { return _num_coords; } - MEDCouplingAutoRefCountObjectPtr getCoordsName() const { return _name_coords; } - static void WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords); - private: - void sortTypes(); - private: - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > _per_type_mesh; - MEDCouplingAutoRefCountObjectPtr _coords; - MEDCouplingAutoRefCountObjectPtr _fam_coords; - MEDCouplingAutoRefCountObjectPtr _num_coords; - MEDCouplingAutoRefCountObjectPtr _name_coords; - }; - - class MEDFileStrMeshL2 : public MEDFileMeshL2 - { - }; - - class MEDFileCMeshL2 : public MEDFileStrMeshL2 - { - public: - MEDFileCMeshL2(); - void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it); - MEDCouplingCMesh *getMesh() { return _cmesh; } - private: - static med_data_type GetDataTypeCorrespondingToSpaceId(int id); - private: - MEDCouplingAutoRefCountObjectPtr _cmesh; - }; - - class MEDFileCLMeshL2 : public MEDFileStrMeshL2 - { - public: - MEDFileCLMeshL2(); - void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it); - MEDCouplingCurveLinearMesh *getMesh() { return _clmesh; } - private: - MEDCouplingAutoRefCountObjectPtr _clmesh; - }; - - class MEDFileMesh; - class MEDFileUMeshSplitL1; - - class MEDFileUMeshPermCompute : public BigMemoryObject - { - public: - MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st); - operator MEDCouplingUMesh *() const; - void operator=(MEDCouplingUMesh *m); - void updateTime() const; - std::vector getDirectChildrenWithNull() const; - std::size_t getHeapMemorySizeWithoutChildren() const; - private: - const MEDFileUMeshSplitL1 *_st; - mutable std::size_t _mpt_time; - mutable std::size_t _num_time; - mutable MEDCouplingAutoRefCountObjectPtr _m; - }; - - class MEDFileUMeshAggregateCompute : public BigMemoryObject - { - public: - MEDFileUMeshAggregateCompute(); - void setName(const std::string& name); - void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts); - void assignDefParts(const std::vector& partDefs); - void assignUMesh(MEDCouplingUMesh *m); - MEDCouplingUMesh *getUmesh() const; - int getNumberOfCells() const; - std::vector getParts() const; - std::vector getGeoTypes() const; - int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const; - std::vector retrievePartsWithoutComputation() const; - MEDCoupling1GTUMesh *retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const; - void getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const; - void renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N); - bool isStoredSplitByType() const; - std::size_t getTimeOfThis() const; - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileUMeshAggregateCompute deepCpy(DataArrayDouble *coords) const; - bool isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const; - void clearNonDiscrAttributes() const; - void synchronizeTinyInfo(const MEDFileMesh& master) const; - bool empty() const; - int getMeshDimension() const; - std::vector getDistributionOfTypes() const; - int getSize() const; - void setCoords(DataArrayDouble *coords); - void forceComputationOfPartsFromUMesh() const; - const PartDefinition *getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const; - void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - void unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - private: - std::size_t getTimeOfParts() const; - std::size_t getTimeOfUMesh() const; - private: - mutable std::vector< MEDCouplingAutoRefCountObjectPtr > _m_parts; - mutable std::size_t _mp_time; - mutable std::size_t _m_time; - mutable MEDCouplingAutoRefCountObjectPtr _m; - mutable std::vector< MEDCouplingAutoRefCountObjectPtr > _part_def; - }; - - class MEDFileUMeshSplitL1 : public RefCountObject - { - friend class MEDFileUMeshPermCompute; - public: - MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other); - MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id); - MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m); - MEDFileUMeshSplitL1(MEDCouplingUMesh *m); - MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld); - void setName(const std::string& name); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileUMeshSplitL1 *deepCpy(DataArrayDouble *coords) const; - void setCoords(DataArrayDouble *coords); - bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const; - void clearNonDiscrAttributes() const; - void synchronizeTinyInfo(const MEDFileMesh& master) const; - void assignMesh(MEDCouplingUMesh *m, bool newOrOld); - void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts); - void forceComputationOfParts() const; - bool empty() const; - bool presenceOfOneFams(const std::vector& ids) const; - int getMeshDimension() const; - void simpleRepr(std::ostream& oss) const; - int getSize() const; - MEDCouplingUMesh *getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const; - DataArrayInt *getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const; - MEDCouplingUMesh *getWholeMesh(bool renum) const; - int getNumberOfCells() const; - bool isMeshStoredSplitByType() const { return _m_by_types.isStoredSplitByType(); } - std::vector getGeoTypes() const; - int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const; - std::vector getDirectUndergroundSingleGeoTypeMeshes() const { return _m_by_types.retrievePartsWithoutComputation(); } - MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const { return _m_by_types.retrievePartWithoutComputation(gt); } - DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - std::vector getDistributionOfTypes() const { return _m_by_types.getDistributionOfTypes(); } - DataArrayInt *getOrCreateAndGetFamilyField(); - const DataArrayInt *getFamilyField() const; - const DataArrayInt *getNumberField() const; - const DataArrayAsciiChar *getNameField() const; - const DataArrayInt *getRevNumberField() const; - const PartDefinition *getPartDef(INTERP_KERNEL::NormalizedCellType gt) const; - void eraseFamilyField(); - void setGroupsFromScratch(const std::vector& ms, std::map& familyIds, - std::map >& groups); - void write(med_idt fid, const std::string& mName, int mdim) const; - // - void setFamilyArr(DataArrayInt *famArr); - DataArrayInt *getFamilyField(); - void setRenumArr(DataArrayInt *renumArr); - void setNameArr(DataArrayAsciiChar *nameArr); - void changeFamilyIdArr(int oldId, int newId); - // - void renumberNodesInConn(const int *newNodeNumbersO2N); - // - void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - void unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - // - static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp); - static std::vector GetNewFamiliesNumber(int nb, const std::map& families); - static void TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, - std::map& famIdTrad, std::map& newfams); - static DataArrayInt *Renumber(const DataArrayInt *renum, const DataArrayInt *da); - static MEDCouplingUMesh *Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds); - static MEDFileUMeshSplitL1 *Unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - private: - MEDFileUMeshSplitL1(); - void assignCommonPart(); - MEDCouplingUMesh *renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const; - DataArrayInt *renumIfNeededArr(const DataArrayInt *da) const; - void computeRevNum() const; - private: - MEDFileUMeshAggregateCompute _m_by_types; - MEDCouplingAutoRefCountObjectPtr _fam; - MEDCouplingAutoRefCountObjectPtr _num; - MEDCouplingAutoRefCountObjectPtr _names; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num; - MEDFileUMeshPermCompute _m; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileMeshReadSelector.cxx b/medtool/src/MEDLoader/MEDFileMeshReadSelector.cxx deleted file mode 100644 index e7ac589b0..000000000 --- a/medtool/src/MEDLoader/MEDFileMeshReadSelector.cxx +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileMeshReadSelector.hxx" - -using namespace ParaMEDMEM; - -MEDFileMeshReadSelector::MEDFileMeshReadSelector():_code(0xFFFFFFFF) -{ -} - -MEDFileMeshReadSelector::MEDFileMeshReadSelector(unsigned int code):_code(code) -{ -} - -unsigned int MEDFileMeshReadSelector::getCode() const -{ - return _code; -} - -void MEDFileMeshReadSelector::setCode(unsigned int newCode) -{ - _code=newCode; -} - -bool MEDFileMeshReadSelector::isCellFamilyFieldReading() const -{ - return _code & 0x00000001; -} - -bool MEDFileMeshReadSelector::isNodeFamilyFieldReading() const -{ - return _code & 0x00000002; -} - -bool MEDFileMeshReadSelector::isCellNameFieldReading() const -{ - return _code & 0x00000004; -} - -bool MEDFileMeshReadSelector::isNodeNameFieldReading() const -{ - return _code & 0x00000008; -} - -bool MEDFileMeshReadSelector::isCellNumFieldReading() const -{ - return _code & 0x00000010; -} - -bool MEDFileMeshReadSelector::isNodeNumFieldReading() const -{ - return _code & 0x00000020; -} - -void MEDFileMeshReadSelector::setCellFamilyFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFFE); - unsigned int b2=b?1:0; - //b2<<=0; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setNodeFamilyFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFFD); - unsigned int b2=b?1:0; - b2<<=1; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setCellNameFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFFB); - unsigned int b2=b?1:0; - b2<<=2; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setNodeNameFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFF7); - unsigned int b2=b?1:0; - b2<<=3; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setCellNumFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFEF); - unsigned int b2=b?1:0; - b2<<=4; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setNodeNumFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFDF); - unsigned int b2=b?1:0; - b2<<=5; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::reprAll(std::ostream& str) const -{ - str << "MEDFileMeshReadSelector (code=" << _code << ") : \n"; - str << "Read family field on cells : " << ReprStatus(isCellFamilyFieldReading()) << std::endl; - str << "Read family field on nodes : " << ReprStatus(isNodeFamilyFieldReading()) << std::endl; - str << "Read name field on cells : " << ReprStatus(isCellNameFieldReading()) << std::endl; - str << "Read name field on nodes : " << ReprStatus(isNodeNameFieldReading()) << std::endl; - str << "Read number field on cells : " << ReprStatus(isCellNumFieldReading()) << std::endl; - str << "Read number field name on nodes : " << ReprStatus(isNodeNumFieldReading()); -} - -std::string MEDFileMeshReadSelector::ReprStatus(bool v) -{ - if(v) - return std::string("ON"); - else - return std::string("OFF"); -} - diff --git a/medtool/src/MEDLoader/MEDFileMeshReadSelector.hxx b/medtool/src/MEDLoader/MEDFileMeshReadSelector.hxx deleted file mode 100644 index 2a90b7dc0..000000000 --- a/medtool/src/MEDLoader/MEDFileMeshReadSelector.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEMESHREADSELECTOR_HXX__ -#define __MEDFILEMESHREADSELECTOR_HXX__ - -#include "MEDLoaderDefines.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDLOADER_EXPORT MEDFileMeshReadSelector - { - public: - MEDFileMeshReadSelector(); - MEDFileMeshReadSelector(unsigned int code); - unsigned int getCode() const; - void setCode(unsigned int newCode); - bool isCellFamilyFieldReading() const; - bool isNodeFamilyFieldReading() const; - bool isCellNameFieldReading() const; - bool isNodeNameFieldReading() const; - bool isCellNumFieldReading() const; - bool isNodeNumFieldReading() const; - void setCellFamilyFieldReading(bool b); - void setNodeFamilyFieldReading(bool b); - void setCellNameFieldReading(bool b); - void setNodeNameFieldReading(bool b); - void setCellNumFieldReading(bool b); - void setNodeNumFieldReading(bool b); - void reprAll(std::ostream& str) const; - private: - static std::string ReprStatus(bool v); - private: - //bit #0 cell family field - //bit #1 node family field - //bit #2 cell name field - //bit #3 node name field - //bit #4 cell num field - //bit #5 node num field - unsigned int _code; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileParameter.cxx b/medtool/src/MEDLoader/MEDFileParameter.cxx deleted file mode 100644 index d6aa3c46b..000000000 --- a/medtool/src/MEDLoader/MEDFileParameter.cxx +++ /dev/null @@ -1,920 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileParameter.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDLoaderBase.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDFileParameter1TS::MEDFileParameter1TS(int iteration, int order, double time):_iteration(iteration),_order(order),_time(time) -{ -} - -MEDFileParameter1TS::MEDFileParameter1TS():_iteration(-1),_order(-1),_time(0.) -{ -} - -bool MEDFileParameter1TS::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const -{ - std::ostringstream oss; - if(!other) - { what="Other is null"; return false; } - if(_iteration!=other->_iteration) - { oss << "iteration number mismatches " << _iteration << " != " << other->_iteration; what=oss.str(); return false; } - if(_order!=other->_order) - { oss << "order number mismatches " << _iteration << " != " << other->_iteration; what=oss.str(); return false; } - if(fabs(_time-other->_time)>eps) - { oss << "time mismatches " << _time << " != " << other->_time << " eps=" << eps; what=oss.str(); return false; } - return true; -} - -MEDFileParameter1TS *MEDFileParameterDouble1TSWTI::deepCpy() const -{ - return new MEDFileParameterDouble1TSWTI(*this); -} - -bool MEDFileParameterDouble1TSWTI::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const -{ - if(!MEDFileParameter1TS::isEqual(other,eps,what)) - return false; - const MEDFileParameterDouble1TSWTI *otherC=dynamic_cast(other); - if(!otherC) - { what="IsEqual fails because this is double parameter other no !"; return false; } - if(fabs(_arr-otherC->_arr)>eps) - { std::ostringstream oss; oss << "value differ " << _arr << " != " << otherC->_arr << " (eps=" << eps << ")"; return false; } - return true; -} - -std::size_t MEDFileParameterDouble1TSWTI::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDFileParameterDouble1TSWTI); -} - -std::vector MEDFileParameterDouble1TSWTI::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -std::string MEDFileParameterDouble1TSWTI::simpleRepr() const -{ - std::ostringstream oss; - simpleRepr2(0,oss); - return oss.str(); -} - -void MEDFileParameterDouble1TSWTI::simpleRepr2(int bkOffset, std::ostream& oss) const -{ - std::string startOfLine(bkOffset,' '); - oss << startOfLine << "ParameterDoubleItem with (iteration,order) = (" << _iteration << "," << _order << ")" << std::endl; - oss << startOfLine << "Time associacited = " << _time << std::endl; - oss << startOfLine << "The value is ***** " << _arr << " *****" << std::endl; -} - -MEDFileParameterDouble1TSWTI *MEDFileParameterDouble1TSWTI::New(int iteration, int order, double time) -{ - return new MEDFileParameterDouble1TSWTI(iteration,order,time); -} - -MEDFileParameterDouble1TSWTI::MEDFileParameterDouble1TSWTI():_arr(std::numeric_limits::max()) -{ -} - -MEDFileParameterDouble1TSWTI::MEDFileParameterDouble1TSWTI(int iteration, int order, double time):MEDFileParameter1TS(iteration,order,time) -{ -} - -void MEDFileParameterDouble1TSWTI::finishLoading(med_idt fid, const std::string& name, int dt, int it, int nbOfSteps) -{ - std::ostringstream oss; oss << "MEDFileParameterDouble1TS::finishLoading : no specified time step (" << dt << "," << it << ") ! Time steps available : "; - for(int i=0;i(&_arr))); - return ; - } - else - { - oss << "(" << locDt << "," << locIt << ")"; - if(i!=nbOfSteps-1) - oss << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void MEDFileParameterDouble1TSWTI::readValue(med_idt fid, const std::string& name) -{ - MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast(&_arr))); -} - -void MEDFileParameterDouble1TSWTI::finishLoading(med_idt fid, const std::string& name, int timeStepId) -{ - int locDt,locIt; - double dt; - MEDFILESAFECALLERRD0(MEDparameterComputationStepInfo,(fid,name.c_str(),timeStepId+1,&locDt,&locIt,&dt)); - _iteration=locDt; _order=locIt; _time=dt; - MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast(&_arr))); -} - -void MEDFileParameterDouble1TSWTI::writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const -{ - char nameW[MED_NAME_SIZE+1]; - MEDLoaderBase::safeStrCpy(name.c_str(),MED_NAME_SIZE,nameW,mw.getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDparameterValueWr,(fid,nameW,_iteration,_order,_time,reinterpret_cast(&_arr))); -} - -std::size_t MEDFileParameterTinyInfo::getHeapMemSizeOfStrings() const -{ - return _dt_unit.capacity()+_name.capacity()+_desc_name.capacity(); -} - -bool MEDFileParameterTinyInfo::isEqualStrings(const MEDFileParameterTinyInfo& other, std::string& what) const -{ - std::ostringstream oss; - if(_name!=other._name) - { oss << "name differ ! this=" << _name << " and other=" << other._name; what=oss.str(); return false; } - if(_desc_name!=other._desc_name) - { oss << "name differ ! this=" << _desc_name << " and other=" << other._desc_name; what=oss.str(); return false; } - if(_dt_unit!=other._dt_unit) - { oss << "unit of time differ ! this=" << _dt_unit << " and other=" << other._dt_unit; what=oss.str(); return false; } - return true; -} - -void MEDFileParameterTinyInfo::writeLLHeader(med_idt fid, med_parameter_type typ) const -{ - char nameW[MED_NAME_SIZE+1],descW[MED_COMMENT_SIZE+1],dtunitW[MED_SNAME_SIZE+1]; - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,nameW,getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,descW,getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_SNAME_SIZE,dtunitW,getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDparameterCr,(fid,nameW,typ,descW,dtunitW)); -} - -void MEDFileParameterTinyInfo::mainRepr(int bkOffset, std::ostream& oss) const -{ - std::string startOfLine(bkOffset,' '); - oss << startOfLine << "Parameter with name \"" << _name << "\"" << std::endl; - oss << startOfLine << "Parameter with description \"" << _desc_name << "\"" << std::endl; - oss << startOfLine << "Parameter with unit name \"" << _dt_unit << "\"" << std::endl; -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New() -{ - return new MEDFileParameterDouble1TS; -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName) -{ - return new MEDFileParameterDouble1TS(fileName); -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName, const std::string& paramName) -{ - return new MEDFileParameterDouble1TS(fileName,paramName); -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName, const std::string& paramName, int dt, int it) -{ - return new MEDFileParameterDouble1TS(fileName,paramName,dt,it); -} - -MEDFileParameterDouble1TS::MEDFileParameterDouble1TS() -{ -} - -MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i0) - { - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,_name,0); - return ; - } - else - { - std::ostringstream oss2; oss2 << "Param name \"" << paramName << "\" exists but no time steps on it !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - } - else - { - oss << paramNameCpp; - if(i!=nbPar-1) oss << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - if(nbPar<1) - { - std::ostringstream oss2; oss2 << "No parameter in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - int nbOfSteps; - MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,1,pName,¶mType,descName,unitName,&nbOfSteps)); - std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); - if(paramType==MED_FLOAT64) - { - if(nbOfSteps>0) - { - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,_name,0); - return ; - } - else - { - std::ostringstream oss2; oss2 << "Double param name \"" << paramNameCpp << "\" exists in file \""<< fileName << "\"but no time steps on it !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - } - else - { - std::ostringstream oss2; oss2 << "First parameter in file \"" << fileName << "\" is not double !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } -} - -bool MEDFileParameterDouble1TS::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const -{ - if(!MEDFileParameterDouble1TSWTI::isEqual(other,eps,what)) - return false; - const MEDFileParameterDouble1TS *otherC=dynamic_cast(other); - if(!otherC) - { what="Other is not of type MEDFileParameterDouble1TS as this"; return false; } - if(!isEqualStrings(*otherC,what)) - return false; - return true; -} - -MEDFileParameter1TS *MEDFileParameterDouble1TS::deepCpy() const -{ - return new MEDFileParameterDouble1TS(*this); -} - -std::string MEDFileParameterDouble1TS::simpleRepr() const -{ - std::ostringstream oss; - MEDFileParameterTinyInfo::mainRepr(0,oss); - MEDFileParameterDouble1TSWTI::simpleRepr2(0,oss); - return oss.str(); -} - -std::size_t MEDFileParameterDouble1TS::getHeapMemorySizeWithoutChildren() const -{ - return getHeapMemSizeOfStrings()+sizeof(MEDFileParameterDouble1TS); -} - -std::vector MEDFileParameterDouble1TS::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -void MEDFileParameterDouble1TS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - MEDFileParameterTinyInfo::writeLLHeader(fid,MED_FLOAT64); - MEDFileParameterDouble1TSWTI::writeLL(fid,_name,*this); -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::New() -{ - return new MEDFileParameterMultiTS; -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::New(const std::string& fileName) -{ - return new MEDFileParameterMultiTS(fileName); -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::New(const std::string& fileName, const std::string& paramName) -{ - return new MEDFileParameterMultiTS(fileName,paramName); -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS() -{ -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS(const MEDFileParameterMultiTS& other, bool deepCopy):MEDFileParameterTinyInfo(other),_param_per_ts(other._param_per_ts) -{ - if(deepCopy) - for(std::size_t i=0;i<_param_per_ts.size();i++) - { - const MEDFileParameter1TS *elt=_param_per_ts[i]; - if(elt) - _param_per_ts[i]=elt->deepCpy(); - } -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS(const std::string& fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - if(nbPar<1) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS : no parameter in file \"" << fileName << "\" !" ; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - int nbOfSteps; - MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,1,pName,¶mType,descName,unitName,&nbOfSteps)); - std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,paramType,nbOfSteps); -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i0) - { - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,paramType,nbOfSteps); - return ; - } - else - { - std::ostringstream oss2; oss2 << "Param name \"" << paramName << "\" exists but no time steps on it !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - } - else - { - oss << paramNameCpp; - if(i!=nbPar-1) oss << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void MEDFileParameterMultiTS::finishLoading(med_idt fid, med_parameter_type typ, int nbOfSteps) -{ - _param_per_ts.resize(nbOfSteps); - for(int i=0;ireadValue(fid,_name.c_str()); - break; - /*case MED_INT32; - _param_per_ts[i]=; - break;*/ - default: - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::finishLoading : supporting only FLOAT64 !"); - } - } -} - -std::size_t MEDFileParameterMultiTS::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDFileParameterMultiTS)); - ret+=sizeof(MEDCouplingAutoRefCountObjectPtr)*_param_per_ts.capacity(); - return ret; -} - -std::vector MEDFileParameterMultiTS::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - ret.push_back((const MEDFileParameter1TS *)*it); - return ret; -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::deepCpy() const -{ - return new MEDFileParameterMultiTS(*this,true); -} - -bool MEDFileParameterMultiTS::isEqual(const MEDFileParameterMultiTS *other, double eps, std::string& what) const -{ - if(!other) - { what="other is null !"; return false; } - if(_param_per_ts.size()!=other->_param_per_ts.size()) - { what="number of time steps differs !"; return false; } - std::ostringstream oss; - for(std::size_t i=0;i<_param_per_ts.size();i++) - { - const MEDFileParameter1TS *a(_param_per_ts[i]),*b(other->_param_per_ts[i]); - if((a && !b) || (!a && b)) - { oss << "At time step id #" << i << " pointer is defined on one side not in the other !"; what=oss.str(); return false; } - if(a) - if(!a->isEqual(b,eps,what)) - { oss << " At time step id #" << i << " non equality !"; what+=oss.str(); return false; } - } - return true; -} - -void MEDFileParameterMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid,*this); -} - -void MEDFileParameterMultiTS::writeLL(med_idt fid, const MEDFileWritable& mw) const -{ - std::set diffType; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(dynamic_cast(elt)) - diffType.insert(MED_FLOAT64); - } - if(diffType.size()>1) - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::writeLL : impossible to mix type of data in parameters in MED file ! Only float64 or only int32 ..."); - if(diffType.empty()) - return; - med_parameter_type typ=*diffType.begin(); - MEDFileParameterTinyInfo::writeLLHeader(fid,typ); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - elt->writeLL(fid,_name,mw); - } -} - -std::string MEDFileParameterMultiTS::simpleRepr() const -{ - std::ostringstream oss; - simpleRepr2(0,oss); - return oss.str(); -} - -void MEDFileParameterMultiTS::simpleRepr2(int bkOffset, std::ostream& oss) const -{ - MEDFileParameterTinyInfo::mainRepr(bkOffset,oss); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - elt->simpleRepr2(bkOffset+2,oss); - } -} - -void MEDFileParameterMultiTS::appendValue(int dt, int it, double time, double val) -{ - MEDCouplingAutoRefCountObjectPtr elt=MEDFileParameterDouble1TSWTI::New(dt,it,time); - elt->setValue(val); - MEDCouplingAutoRefCountObjectPtr elt2((MEDFileParameterDouble1TSWTI*)elt); elt2->incrRef(); - _param_per_ts.push_back(elt2); -} - -double MEDFileParameterMultiTS::getDoubleValue(int iteration, int order) const -{ - int pos=getPosOfTimeStep(iteration,order); - const MEDFileParameter1TS *elt=_param_per_ts[pos]; - if(!elt) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getDoubleValue : time iteration it=" << iteration << " order=" << order; - oss << " exists but elt is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileParameterDouble1TSWTI *eltC=dynamic_cast(elt); - if(!eltC) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getDoubleValue : time iteration it=" << iteration << " order=" << order; - oss << " exists but not double !"; - } - return eltC->getValue(); -} - -int MEDFileParameterMultiTS::getPosOfTimeStep(int iteration, int order) const -{ - int ret=0; - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getPosOfTimeStep : no such iteration=" << iteration << " order=" << order << " ! Possibilities are :"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++,ret++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - { - if(elt->getIteration()==iteration && elt->getOrder()==order) - return ret; - else - oss << "(" << elt->getIteration() << "," << elt->getOrder() << "), "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileParameterMultiTS::getPosGivenTime(double time, double eps) const -{ - int ret=0; - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getPosGivenTime : no such time=" << time << " ! Possibilities are :"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++,ret++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - { - if(fabs(elt->getTimeValue()-time)<=eps) - return ret; - else - oss << elt->getTimeValue() << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. - */ -MEDFileParameter1TS *MEDFileParameterMultiTS::getTimeStepAtPos(int posId) const -{ - if(posId<0 || posId>=(int)_param_per_ts.size()) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getTimeStepAtPos : invalid pos ! Should be in [0," << _param_per_ts.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return const_cast(static_cast(_param_per_ts[posId])); -} - -void MEDFileParameterMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) -{ - std::vector b(_param_per_ts.size(),true); - int len=(int)_param_per_ts.size(); - for(const int *w=startIds;w!=endIds;w++) - if(*w>=0 && *w > paramPerTs(newNb); - std::size_t j=0; - for(std::size_t i=0;i<_param_per_ts.size();i++) - if(b[i]) - paramPerTs[j++]=_param_per_ts[i]; - _param_per_ts=paramPerTs; -} - -int MEDFileParameterMultiTS::getNumberOfTS() const -{ - return (int) getIterations().size(); -} - -std::vector< std::pair > MEDFileParameterMultiTS::getIterations() const -{ - std::vector< std::pair > ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - ret.push_back(std::pair(elt->getIteration(),elt->getOrder())); - } - return ret; -} - -/*! - * \param [out] ret1 - */ -std::vector< std::pair > MEDFileParameterMultiTS::getTimeSteps(std::vector& ret1) const -{ - std::vector< std::pair > ret0; - ret1.clear(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - { - ret0.push_back(std::pair(elt->getIteration(),elt->getOrder())); - ret1.push_back(elt->getTimeValue()); - } - } - return ret0; -} - -MEDFileParameters *MEDFileParameters::New() -{ - return new MEDFileParameters; -} - -MEDFileParameters *MEDFileParameters::New(const std::string& fileName) -{ - return new MEDFileParameters(fileName); -} - -MEDFileParameters::MEDFileParameters(const std::string& fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - _params.resize(nbPar); - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i)*_params.capacity(); - return ret; -} - -std::vector MEDFileParameters::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++) - ret.push_back((const MEDFileParameterMultiTS *)*it); - return ret; -} - -MEDFileParameters *MEDFileParameters::deepCpy() const -{ - return new MEDFileParameters(*this,true); -} - -bool MEDFileParameters::isEqual(const MEDFileParameters *other, double eps, std::string& what) const -{ - if(!other) - { what="other is null !"; return false; } - if(_params.size()!=other->_params.size()) - { what="number of parameters differs !"; return false; } - std::ostringstream oss; - for(std::size_t i=0;i<_params.size();i++) - { - const MEDFileParameterMultiTS *a(_params[i]),*b(other->_params[i]); - if((a && !b) || (!a && b)) - { oss << "At param with id #" << i << " pointer is defined on one side not in the other !"; what=oss.str(); return false; } - if(a) - if(!a->isEqual(b,eps,what)) - { oss << " At param with id #" << i << " non equality !"; what+=oss.str(); return false; } - } - return true; -} - -MEDFileParameters::MEDFileParameters(const MEDFileParameters& other, bool deepCopy):MEDFileWritable(other),_params(other._params) -{ - if(deepCopy) - for(std::size_t i=0;i<_params.size();i++) - { - const MEDFileParameterMultiTS *elt=_params[i]; - if(elt) - _params[i]=elt->deepCpy(); - } -} - -void MEDFileParameters::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid); -} - -void MEDFileParameters::writeLL(med_idt fid) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++) - { - const MEDFileParameterMultiTS *elt(*it); - if(elt) - elt->writeLL(fid,*this); - } -} - -std::vector MEDFileParameters::getParamsNames() const -{ - std::vector ret(_params.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++,i++) - { - const MEDFileParameterMultiTS *p=(*it); - if(p) - { - ret[i]=p->getName(); - } - else - { - std::ostringstream oss; oss << "MEDFileParameters::getParamsNames : At rank #" << i << " param is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -std::string MEDFileParameters::simpleRepr() const -{ - std::ostringstream oss; - simpleReprWithoutHeader(oss); - return oss.str(); -} - -void MEDFileParameters::simpleReprWithoutHeader(std::ostream& oss) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++) - { - const MEDFileParameterMultiTS *elt(*it); - if(elt) - elt->simpleRepr2(2,oss); - } -} - -void MEDFileParameters::resize(int newSize) -{ - if(newSize<0) - throw INTERP_KERNEL::Exception("MEDFileParameters::resize : should be positive !"); - _params.resize(newSize); -} - -void MEDFileParameters::pushParam(MEDFileParameterMultiTS *param) -{ - if(param) - param->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt(param); - _params.push_back(elt); -} - -void MEDFileParameters::setParamAtPos(int i, MEDFileParameterMultiTS *param) -{ - if(i<0) - throw INTERP_KERNEL::Exception("MEDFileParameters::setParamAtPos : should be positive !"); - if(i>=(int)_params.size()) - _params.resize(i+1); - if(param) - param->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt(param); - _params[i]=elt; -} - -/*! - * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. - */ -MEDFileParameterMultiTS *MEDFileParameters::getParamAtPos(int i) const -{ - if(i<0 || i>=(int)_params.size()) - { - std::ostringstream oss; oss << "MEDFileParameters::getParamAtPos : should be in [0," << _params.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileParameterMultiTS *elt=_params[i]; - return const_cast(elt); -} - -/*! - * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. - */ -MEDFileParameterMultiTS *MEDFileParameters::getParamWithName(const std::string& paramName) const -{ - int pos=getPosFromParamName(paramName); - return getParamAtPos(pos); -} - -void MEDFileParameters::destroyParamAtPos(int i) -{ - if(i<0 || i>=(int)_params.size()) - { - std::ostringstream oss; oss << "MEDFileParameters::destroyParamAtPos : should be in [0," << _params.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _params[i]=MEDCouplingAutoRefCountObjectPtr(0); -} - -int MEDFileParameters::getPosFromParamName(const std::string& paramName) const -{ - std::ostringstream oss; oss << "MEDFileParameters::getPosFromParamName : no such name=" << paramName << " ! Possibilities are :"; - int ret=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++,ret++) - { - const MEDFileParameterMultiTS *elt(*it); - if(elt) - { - if(std::string(elt->getName())==paramName) - return ret; - else - oss << elt->getName() << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileParameters::getNumberOfParams() const -{ - return (int)_params.size(); -} diff --git a/medtool/src/MEDLoader/MEDFileParameter.hxx b/medtool/src/MEDLoader/MEDFileParameter.hxx deleted file mode 100644 index f223fc78c..000000000 --- a/medtool/src/MEDLoader/MEDFileParameter.hxx +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEPARAMETER_HXX__ -#define __MEDFILEPARAMETER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ - class MEDFileParameter1TS : public RefCountObject - { - public: - MEDLOADER_EXPORT virtual MEDFileParameter1TS *deepCpy() const = 0; - MEDLOADER_EXPORT virtual bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT virtual void simpleRepr2(int bkOffset, std::ostream& oss) const = 0; - MEDLOADER_EXPORT virtual void readValue(med_idt fid, const std::string& name) = 0; - MEDLOADER_EXPORT virtual void writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const = 0; - public: - MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT void setOrder(int order) { _order=order; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; } - MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; } - MEDLOADER_EXPORT double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; } - MEDLOADER_EXPORT double getTimeValue() const { return _time; } - protected: - MEDFileParameter1TS(int iteration, int order, double time); - MEDFileParameter1TS(); - protected: - int _iteration; - int _order; - double _time; - }; - - class MEDFileParameterDouble1TSWTI : public MEDFileParameter1TS - { - public: - MEDLOADER_EXPORT static MEDFileParameterDouble1TSWTI *New(int iteration, int order, double time); - MEDLOADER_EXPORT MEDFileParameter1TS *deepCpy() const; - MEDLOADER_EXPORT void setValue(double val) { _arr=val; } - MEDLOADER_EXPORT double getValue() const { return _arr; } - MEDLOADER_EXPORT bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT void readValue(med_idt fid, const std::string& name); - MEDLOADER_EXPORT std::string simpleRepr() const; - protected: - MEDFileParameterDouble1TSWTI(); - MEDFileParameterDouble1TSWTI(int iteration, int order, double time); - void simpleRepr2(int bkOffset, std::ostream& oss) const; - void finishLoading(med_idt fid, const std::string& name, int dt, int it, int nbOfSteps); - void finishLoading(med_idt fid, const std::string& name, int timeStepId); - void writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const; - protected: - double _arr; - }; - - class MEDFileParameterTinyInfo : public MEDFileWritable - { - public: - MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } - MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; } - MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; } - MEDLOADER_EXPORT std::size_t getHeapMemSizeOfStrings() const; - MEDLOADER_EXPORT bool isEqualStrings(const MEDFileParameterTinyInfo& other, std::string& what) const; - protected: - void writeLLHeader(med_idt fid, med_parameter_type typ) const; - void mainRepr(int bkOffset, std::ostream& oss) const; - protected: - std::string _dt_unit; - std::string _name; - std::string _desc_name; - }; - - class MEDFileParameterDouble1TS : public MEDFileParameterDouble1TSWTI, public MEDFileParameterTinyInfo - { - public: - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(); - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName); - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName, int dt, int it); - MEDLOADER_EXPORT virtual MEDFileParameter1TS *deepCpy() const; - MEDLOADER_EXPORT virtual bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT virtual std::string simpleRepr() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - private: - MEDFileParameterDouble1TS(); - MEDFileParameterDouble1TS(const std::string& fileName); - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName); - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it); - }; - - class MEDFileParameterMultiTS : public RefCountObject, public MEDFileParameterTinyInfo - { - public: - MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(); - MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(const std::string& fileName, const std::string& paramName); - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileParameterMultiTS *deepCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileParameterMultiTS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& mw) const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void appendValue(int dt, int it, double time, double val); - MEDLOADER_EXPORT double getDoubleValue(int iteration, int order) const; - MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT MEDFileParameter1TS *getTimeStepAtPos(int posId) const; - MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; - MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; - MEDLOADER_EXPORT void simpleRepr2(int bkOffset, std::ostream& oss) const; - protected: - MEDFileParameterMultiTS(); - MEDFileParameterMultiTS(const MEDFileParameterMultiTS& other, bool deepCopy); - MEDFileParameterMultiTS(const std::string& fileName); - MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName); - void finishLoading(med_idt fid, med_parameter_type typ, int nbOfSteps); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _param_per_ts; - }; - - class MEDFileParameters : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileParameters *New(); - MEDLOADER_EXPORT static MEDFileParameters *New(const std::string& fileName); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileParameters *deepCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileParameters *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT std::vector getParamsNames() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushParam(MEDFileParameterMultiTS *param); - MEDLOADER_EXPORT void setParamAtPos(int i, MEDFileParameterMultiTS *param); - MEDLOADER_EXPORT MEDFileParameterMultiTS *getParamAtPos(int i) const; - MEDLOADER_EXPORT MEDFileParameterMultiTS *getParamWithName(const std::string& paramName) const; - MEDLOADER_EXPORT void destroyParamAtPos(int i); - MEDLOADER_EXPORT int getPosFromParamName(const std::string& paramName) const; - MEDLOADER_EXPORT int getNumberOfParams() const; - protected: - void simpleRepr2(int bkOffset, std::ostream& oss) const; - MEDFileParameters(const std::string& fileName); - MEDFileParameters(const MEDFileParameters& other, bool deepCopy); - MEDFileParameters(); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _params; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDFileSafeCaller.txx b/medtool/src/MEDLoader/MEDFileSafeCaller.txx deleted file mode 100644 index 2ce1bd6cf..000000000 --- a/medtool/src/MEDLoader/MEDFileSafeCaller.txx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __MEDFILESAFECALLER_TXX__ -#define __MEDFILESAFECALLER_TXX__ - -#include "med.h" - -#include "InterpKernelException.hxx" - -#include - -// TXX extension to avoid to be installed. - -// This macro calls safely MEDFile functions returning 0 -#define MEDFILESAFECALLER0(a,b) { med_err retCode(a b); \ - if(retCode!=0) { std::ostringstream osszz; osszz << "Return code of MEDFile call \"" << #a << "\" is not 0 as expected ! ( Return code was "<< retCode << " at " << __FILE__ << ":" << __LINE__ << " )"; throw INTERP_KERNEL::Exception(osszz.str().c_str()); } } - -#define MEDFILESAFECALLERRD0(a,b) MEDFILESAFECALLER0(a,b) - -#define MEDFILESAFECALLERWR0(a,b) { med_err retCode(a b); \ - if(retCode!=0) { std::ostringstream osszz; osszz << "Return code of MEDFile call \"" << #a << "\" is not 0 as expected during writing operation ! ( Return code was "<< retCode << " at " << __FILE__ << ":" << __LINE__ << " ). Check write access on MED file ?"; throw INTERP_KERNEL::Exception(osszz.str().c_str()); } } - -#endif diff --git a/medtool/src/MEDLoader/MEDFileUtilities.cxx b/medtool/src/MEDLoader/MEDFileUtilities.cxx deleted file mode 100644 index a52d8a28b..000000000 --- a/medtool/src/MEDLoader/MEDFileUtilities.cxx +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDFileUtilities.hxx" -#include "MEDLoaderBase.hxx" - -#include - -med_access_mode MEDFileUtilities::TraduceWriteMode(int medloaderwritemode) -{ - switch(medloaderwritemode) - { - case 2: - return MED_ACC_CREAT; - case 1: - return MED_ACC_RDEXT; - case 0: - return MED_ACC_RDWR; - default: - throw INTERP_KERNEL::Exception("Invalid write mode specified ! must be 0(write with no question), 1(append) or 2(creation)"); - } -} - -const char *MEDFileUtilities::GetReadableMEDFieldType(med_field_type ft) -{ - static const char medFloat64[]="MED_FLOAT64"; - static const char medInt32[]="MED_INT32"; - static const char medInt64[]="MED_INT64"; - switch(ft) - { - case MED_FLOAT64: - return medFloat64; - case MED_INT32: - return medInt32; - case MED_INT64: - return medInt64; - default: - throw INTERP_KERNEL::Exception("Non supported field type ! Should be FLOAT64, INT32 or INT64 !"); - } -} - -void MEDFileUtilities::CheckMEDCode(int code, med_idt fid, const std::string& msg) -{ - if(code<0) - { - std::ostringstream oss; - oss << "MEDFile has returned an error code (" << code <<") : " << msg; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDFileUtilities::CheckFileForRead(const std::string& fileName) -{ - int status=MEDLoaderBase::getStatusOfFile(fileName); - std::ostringstream oss; - oss << " File : \"" << fileName << "\""; - switch(status) - { - case MEDLoaderBase::DIR_LOCKED: - { - oss << " has been detected as unreadable : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - case MEDLoaderBase::NOT_EXIST: - { - oss << " has been detected as NOT EXISTING : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - case MEDLoaderBase::EXIST_WRONLY: - { - oss << " has been detected as WRITE ONLY : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - if(fid<0) - { - oss << " has been detected as unreadable by MED file : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - oss << " has been detected readable but "; - int major,minor,release; - MEDfileNumVersionRd(fid,&major,&minor,&release); - if(major<2 || (major==2 && minor<2)) - { - oss << "version of MED file is < 2.2 : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDFileUtilities::AutoFid::AutoFid(med_idt fid):_fid(fid) -{ -} - -MEDFileUtilities::AutoFid::~AutoFid() -{ - MEDfileClose(_fid); -} - -ParaMEDMEM::MEDFileWritable::MEDFileWritable():_too_long_str(0),_zipconn_pol(2) -{ -} - -void ParaMEDMEM::MEDFileWritable::copyOptionsFrom(const MEDFileWritable& other) const -{ - _too_long_str=other._too_long_str; - _zipconn_pol=other._zipconn_pol; -} - -int ParaMEDMEM::MEDFileWritable::getTooLongStrPolicy() const -{ - return _too_long_str; -} - -void ParaMEDMEM::MEDFileWritable::setTooLongStrPolicy(int newVal) -{ - if(newVal!=2 && newVal!=1 && newVal!=0) - throw INTERP_KERNEL::Exception("MEDFileWritable::setTooLongStrPolicy : invalid policy should be in 0,1 or 2 !"); - _too_long_str=newVal; -} - -int ParaMEDMEM::MEDFileWritable::getZipConnPolicy() -{ - return _zipconn_pol; -} - -void ParaMEDMEM::MEDFileWritable::setZipConnPolicy(int newVal) -{ - _zipconn_pol=newVal; -} diff --git a/medtool/src/MEDLoader/MEDFileUtilities.hxx b/medtool/src/MEDLoader/MEDFileUtilities.hxx deleted file mode 100644 index ffac85a16..000000000 --- a/medtool/src/MEDLoader/MEDFileUtilities.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDFILEUTILITIES_HXX__ -#define __MEDFILEUTILITIES_HXX__ - -#include "InterpKernelException.hxx" -#include "MEDLoaderDefines.hxx" - -#include "med.h" - -namespace MEDFileUtilities -{ - med_access_mode TraduceWriteMode(int medloaderwritemode); - const char *GetReadableMEDFieldType(med_field_type ft); - void CheckMEDCode(int code, med_idt fid, const std::string& msg); - void CheckFileForRead(const std::string& fileName); - - class AutoFid - { - public: - AutoFid(med_idt fid); - operator med_idt() const { return _fid; } - ~AutoFid(); - private: - med_idt _fid; - }; -} - -namespace ParaMEDMEM -{ - class MEDLOADER_EXPORT MEDFileWritable - { - public: - MEDFileWritable(); - void copyOptionsFrom(const MEDFileWritable& other) const; - int getTooLongStrPolicy() const; - void setTooLongStrPolicy(int newVal); - int getZipConnPolicy(); - void setZipConnPolicy(int newVal); - protected://policies on write - mutable int _too_long_str; - mutable int _zipconn_pol; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/MEDLoader.cxx b/medtool/src/MEDLoader/MEDLoader.cxx deleted file mode 100644 index 70c6d889a..000000000 --- a/medtool/src/MEDLoader/MEDLoader.cxx +++ /dev/null @@ -1,1585 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "CellModel.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include "med.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -/*! \class MEDLoader - * - * \brief Static class offering the "basic" API to read and write MED files/ - * - * This class implements only static methods and offers the high level API to access MED files. - * Take a look at \ref medloader for more details. - * - */ - -med_geometry_type typmai[MED_N_CELL_FIXED_GEO] = { MED_POINT1, - MED_SEG2, - MED_SEG3, - MED_SEG4, - MED_TRIA3, - MED_QUAD4, - MED_TRIA6, - MED_TRIA7, - MED_QUAD8, - MED_QUAD9, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_OCTA12, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_HEXA27, - MED_POLYGON, - MED_POLYGON2, - MED_POLYHEDRON }; - -med_geometry_type typmainoeud[1] = { MED_NONE }; - -INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO] = { INTERP_KERNEL::NORM_POINT1, - INTERP_KERNEL::NORM_SEG2, - INTERP_KERNEL::NORM_SEG3, - INTERP_KERNEL::NORM_SEG4, - INTERP_KERNEL::NORM_TRI3, - INTERP_KERNEL::NORM_QUAD4, - INTERP_KERNEL::NORM_TRI6, - INTERP_KERNEL::NORM_TRI7, - INTERP_KERNEL::NORM_QUAD8, - INTERP_KERNEL::NORM_QUAD9, - INTERP_KERNEL::NORM_TETRA4, - INTERP_KERNEL::NORM_PYRA5, - INTERP_KERNEL::NORM_PENTA6, - INTERP_KERNEL::NORM_HEXA8, - INTERP_KERNEL::NORM_HEXGP12, - INTERP_KERNEL::NORM_TETRA10, - INTERP_KERNEL::NORM_PYRA13, - INTERP_KERNEL::NORM_PENTA15, - INTERP_KERNEL::NORM_HEXA20, - INTERP_KERNEL::NORM_HEXA27, - INTERP_KERNEL::NORM_POLYGON, - INTERP_KERNEL::NORM_QPOLYG, - INTERP_KERNEL::NORM_POLYHED }; - -med_geometry_type typmai3[34] = { MED_POINT1,//0 - MED_SEG2,//1 - MED_SEG3,//2 - MED_TRIA3,//3 - MED_QUAD4,//4 - MED_POLYGON,//5 - MED_TRIA6,//6 - MED_TRIA7,//7 - MED_QUAD8,//8 - MED_QUAD9,//9 - MED_SEG4,//10 - MED_NONE,//11 - MED_NONE,//12 - MED_NONE,//13 - MED_TETRA4,//14 - MED_PYRA5,//15 - MED_PENTA6,//16 - MED_NONE,//17 - MED_HEXA8,//18 - MED_NONE,//19 - MED_TETRA10,//20 - MED_NONE,//21 - MED_OCTA12,//22 - MED_PYRA13,//23 - MED_NONE,//24 - MED_PENTA15,//25 - MED_NONE,//26 - MED_HEXA27,//27 - MED_NONE,//28 - MED_NONE,//29 - MED_HEXA20,//30 - MED_POLYHEDRON,//31 - MED_POLYGON2,//32 - MED_NONE//33 -}; - -double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12; - -int MEDLoader::_COMP_FOR_CELL=0; - -int MEDLoader::_TOO_LONG_STR=0; - -using namespace ParaMEDMEM; - -/// @cond INTERNAL - -namespace MEDLoaderNS -{ - int readUMeshDimFromFile(const std::string& fileName, const std::string& meshName, std::vector& possibilities); - void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity); - void writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - med_int getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName); - std::vector getMeshNamesFid(med_idt fid); -} - -/// @endcond - - -/// @cond INTERNAL - -/*! - * This method returns a first quick overview of mesh with name \a meshName into the file \a fileName. - * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method. - * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned. - */ -int MEDLoaderNS::readUMeshDimFromFile(const std::string& fileName, const std::string& meshName, std::vector& possibilities) -{ - possibilities.clear(); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int ret; - std::set poss; - char nommaa[MED_NAME_SIZE+1]; - char maillage_description[MED_COMMENT_SIZE+1]; - med_mesh_type type_maillage; - med_int Sdim,Mdim; - std::string trueMeshName; - med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_sorting_type sortingType; - med_int nstep; - med_axis_type axisType; - int naxis(MEDmeshnAxis(fid,meshId)); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); - // limitation - if(nstep!=1) - { - throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); - } - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); - // endlimitation - for(int i=0;i0) - { - INTERP_KERNEL::NormalizedCellType type=typmai2[i]; - int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension(); - poss.insert(curDim); - } - } - if(!poss.empty()) - { - ret=*poss.rbegin(); - for(std::set::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) - possibilities.push_back(*it-ret); - } - else - ret=-2; - return ret; -} - -med_int MEDLoaderNS::getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName) - { - if(meshName.empty()) - { - std::vector meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - trueMeshName=meshes[0]; - return 1; - } - std::string meshNameStr(meshName); - std::vector meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - std::vector::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr); - if(iter==meshes.end()) - { - std::ostringstream os2; - os2 << "MeshName '" << meshName << "' not in file : meshes available : "; - std::copy(meshes.begin(),meshes.end(),std::ostream_iterator(os2," ")); - throw INTERP_KERNEL::Exception(os2.str().c_str()); - } - trueMeshName=meshName; - return iter-meshes.begin()+1; - } - -std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) -{ - med_mesh_type type_maillage; - char maillage_description[MED_COMMENT_SIZE+1]; - char dtunit[MED_COMMENT_SIZE+1]; - med_int space_dim; - med_int mesh_dim; - char nommaa[MED_NAME_SIZE+1]; - med_axis_type axistype; - med_sorting_type stype; - med_int n=MEDnMesh(fid); - std::vector ret(n); - for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - int nstep; - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); - std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); - ret[i]=cur; - } - return ret; -} - -/*! - * This methods allows to merger all entities and to considerate only cell types. - */ -void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity) -{ - if(nbOfElemCell>=nbOfElemFace) - { - whichEntity=MED_CELL; - nbOfElem=nbOfElemCell; - } - else - { - whichEntity=MED_CELL; - nbOfElem=nbOfElemFace; - } -} - -/// @endcond - -void MEDLoader::AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj) -{ - obj.setTooLongStrPolicy(_TOO_LONG_STR); -} - -bool MEDLoader::HasXDR() -{ -#ifdef HAS_XDR - return true; -#else - return false; -#endif -} - -std::string MEDLoader::MEDFileVersionStr() -{ - return std::string(MED_VERSION_STR); -} - -void MEDLoader::MEDFileVersion(int& major, int& minor, int& release) -{ - major=MED_NUM_MAJEUR; - minor=MED_NUM_MINEUR; - release=MED_NUM_RELEASE; -} - -/*! - * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh. - */ -void MEDLoader::SetEpsilonForNodeComp(double val) -{ - _EPS_FOR_NODE_COMP=val; -} - -/*! - * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer. - */ -void MEDLoader::SetCompPolicyForCell(int val) -{ - _COMP_FOR_CELL=val; -} - -/*! - * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file. - * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown. - */ -void MEDLoader::SetTooLongStrPolicy(int val) -{ - _TOO_LONG_STR=val; -} - -/*! - * Given a 'fileName' and a 'meshName' this method returns global information concerning this mesh. - * It returns, in this order : - * - number of cells sorted by dimension and by geometry type. The first entry in the vector is the maximal dimension, the 2nd in the vector is the maximal dimension-1... - * - the mesh dimension - * - the space dimension - * - the number of nodes - */ -std::vector< std::vector< std::pair > > MEDLoader::GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, int& numberOfNodes) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - std::set poss; - char nommaa[MED_NAME_SIZE+1]; - char maillage_description[MED_COMMENT_SIZE+1]; - med_mesh_type type_maillage; - std::string trueMeshName; - med_int meshId=MEDLoaderNS::getIdFromMeshName(fid,meshName,trueMeshName); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_sorting_type sortingType; - med_int nstep; - med_axis_type axisType; - int naxis(MEDmeshnAxis(fid,meshId)); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&spaceDim,&meshDim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); - if(type_maillage!=MED_UNSTRUCTURED_MESH) - { - std::ostringstream oss; oss << "MEDLoader::GetUMeshGlobalInfo : Mesh \""<< meshName << "\" in file \"" << fileName; - oss << "\" exists but it is not an unstructured mesh ! This method is not relevant for mesh types that are not unstructured !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // limitation - if(nstep!=1) - throw INTERP_KERNEL::Exception("MEDLoader::GetUMeshGlobalInfo : multisteps on mesh not managed !"); - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); - // endlimitation - std::vector dims; - std::vector< std::pair > geoTypes; - med_bool changement,transformation; - for(int i=0;i0) - { - INTERP_KERNEL::NormalizedCellType typp=typmai2[i]; - int mdimCell=INTERP_KERNEL::CellModel::GetCellModel(typp).getDimension(); - dims.push_back(mdimCell); - geoTypes.push_back(std::pair(typp,curNbOfElemM)); - } - } - int maxLev=*std::max_element(dims.begin(),dims.end()); - int lowLev=*std::min_element(dims.begin(),dims.end()); - int nbOfLevels=maxLev-lowLev+1; - std::vector< std::vector< std::pair > > ret(nbOfLevels); - for(std::size_t i=0;i MEDLoader::GetMeshNames(const std::string& fileName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); - return ret; -} - -std::vector< std::pair > MEDLoader::GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields(MEDnField(fid)); - std::vector fields(nbFields); - med_field_type typcha; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_int nbPdt; - med_bool localmesh; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - std::vector< std::pair > ret(ncomp); - for(int j=0;j(MEDLoaderBase::buildStringFromFortran(((char *)comp)+j*MED_SNAME_SIZE,MED_SNAME_SIZE), - MEDLoaderBase::buildStringFromFortran(((char *)unit)+j*MED_SNAME_SIZE,MED_SNAME_SIZE)); - return ret; - } - fields[i]=curFieldName; - } - std::ostringstream oss; oss << "MEDLoader::GetComponentsNamesOfField : no such field \"" << fieldName << "\" in file \"" << fileName << "\" !" << std::endl; - oss << "Possible field names are : " << std::endl; - std::copy(fields.begin(),fields.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -std::vector MEDLoader::GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::vector ret; - // - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - ret.push_back(meshName); - } - return ret; -} - -std::vector MEDLoader::GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret(nfam); - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - ret[i]=cur; - } - return ret; -} - - -std::vector MEDLoader::GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - for(int j=0;j MEDLoader::GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - bool found=false; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - found=(cur==famName); - if(found) - for(int j=0;j MEDLoader::GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - for(int j=0;j MEDLoader::GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - std::vector ret; - MEDCouplingAutoRefCountObjectPtr fs(MEDFileAnyTypeFieldMultiTS::New(fileName,fieldName,false)); - if(fs->getMeshName()!=meshName) - { - std::ostringstream oss; oss << "MEDLoader::GetTypesOfField : The field \"" << fieldName << "\" in file \"" << fileName << "\" is not lying on mesh \"" << meshName << "\""; - oss << " The name of the mesh in file is \"" << fs->getMeshName() << "\"!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTS(fs->getNumberOfTS()); - if(nbTS==0) - return ret; - for(int i=0;i f1ts(fs->getTimeStepAtPos(i)); - std::vector tof(f1ts->getTypesOfFieldAvailable()); - for(std::vector::const_iterator it=tof.begin();it!=tof.end();it++) - if(std::find(ret.begin(),ret.end(),*it)==ret.end()) - ret.push_back(*it); - } - // sort ret to put before ON_NODES then ON_CELLS then the remaining. - std::vector ret2; - if(std::find(ret.begin(),ret.end(),ON_NODES)!=ret.end()) - ret2.push_back(ON_NODES); - if(std::find(ret.begin(),ret.end(),ON_CELLS)!=ret.end()) - ret2.push_back(ON_CELLS); - for(std::vector::const_iterator it=ret.begin();it!=ret.end();it++) - if(*it!=ON_NODES && *it!=ON_CELLS) - ret2.push_back(*it); - return ret2; -} - -std::vector MEDLoader::GetAllFieldNames(const std::string& fileName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - med_field_type typcha; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - med_bool localmesh; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - ret.push_back(std::string(nomcha)); - } - return ret; -} - -std::vector MEDLoader::GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - med_bool localmesh; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - // - if(curMeshName==meshName) - ret.push_back(curFieldName); - } - delete [] maa_ass; - delete [] nomcha; - return ret; -} - -std::vector MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - switch(type) - { - case ON_CELLS: - return GetCellFieldNamesOnMesh(fileName,meshName); - case ON_NODES: - return GetNodeFieldNamesOnMesh(fileName,meshName); - default: - throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); - } -} - -std::vector MEDLoader::GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - med_int nbPdt; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - int profilesize,nbi; - if(curMeshName==meshName) - { - bool found=false; - for(int j=0;j0) - { - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); - med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi)); - if(nbOfVal>0) - { - found=true; - ret.push_back(curFieldName); - } - } - } - } - } - return ret; -} - -std::vector MEDLoader::GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - if(nbPdt>0) - { - int profilesize,nbi; - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); - med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi)); - if(curMeshName==meshName && nbOfVal>0) - { - ret.push_back(curFieldName); - } - } - } - return ret; -} - -std::vector< std::pair< std::pair, double> > MEDLoader::GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::vector< std::pair< std::pair, double > > ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - std::ostringstream oss; oss << "MEDLoader::GetAllFieldIterations : No field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - for(int k=0;k maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - // - bool found=false; - bool found2=false; - double ret=std::numeric_limits::max(); - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - found=true; - for(int k=0;k > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - switch(type) - { - case ON_CELLS: - return GetCellFieldIterations(fileName,meshName,fieldName); - case ON_NODES: - return GetNodeFieldIterations(fileName,meshName,fieldName); - default: - throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); - } -} - -std::vector< std::pair > MEDLoader::GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::string meshNameCpp(meshName); - std::vector< std::pair > ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - std::ostringstream oss; oss << "MEDLoader::GetCellFieldIterations : No cell Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; - std::set s2; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - bool found=false; - for(int j=0;j0) - { - if(meshNameCpp==maa_ass_cpp) - { - found=true; - ret.push_back(std::make_pair(numdt,numo)); - } - else - s2.insert(maa_ass_cpp); - } - } - } - } - else - { - oss << "\"" << curFieldName << "\""; - if(i!=nbFields-1) oss << ", "; - } - } - if(ret.empty()) - { - if(!s2.empty()) - { - oss << ". Cell Field \"" << fieldName << "\" exists but lies on meshes with names : \""; - std::copy(s2.begin(),s2.end(),std::ostream_iterator(oss,"\", \"")); - } - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -} - -std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::string meshNameCpp(meshName); - std::vector< std::pair > ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - std::ostringstream oss; oss << "MEDLoader::GetNodeFieldIterations : No node Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; - std::set s2; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - for(int k=0;k0) - { - if(meshNameCpp==maa_ass_cpp) - { ret.push_back(std::make_pair(numdt,numo)); } - else - s2.insert(maa_ass_cpp); - } - } - } - else - { - oss << "\"" << curFieldName << "\""; - if(i!=nbFields-1) oss << ", "; - } - } - if(ret.empty()) - { - if(!s2.empty()) - { - oss << ". Node Field \"" << fieldName << "\" exists but lies on meshes with names : \""; - std::copy(s2.begin(),s2.end(),std::ostream_iterator(oss,"\", \"")); - } - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -} - -ParaMEDMEM::MEDCouplingMesh *MEDLoader::ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,meshName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(mmuPtr) - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); - MEDFileCMesh *mmcPtr=dynamic_cast(mmPtr); - if(mmcPtr) - { - const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast(mmPtr); - if(mmc2Ptr) - { - const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - std::ostringstream oss; oss << "MEDLoader::ReadMeshFromFile : The mesh \"" << meshName << "\" in file \"" << fileName << "\" has not a recognized type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -ParaMEDMEM::MEDCouplingMesh *MEDLoader::ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(mmuPtr) - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); - MEDFileCMesh *mmcPtr=dynamic_cast(mmPtr); - if(mmcPtr) - { - const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast(mmPtr); - if(mmc2Ptr) - { - const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - std::ostringstream oss; oss << "MEDLoader::ReadMeshFromFile (2) : The first mesh \"" << mm->getName() << "\" in file \"" << fileName << "\" has not a recognized type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,meshName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName=\""<< meshName << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); -} - -int MEDLoader::ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector poss; - return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& fams) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,meshName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFamilies : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getFamilies(meshDimRelToMax,fams,true); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& grps) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromGroups : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getGroups(meshDimRelToMax,grps,true); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - CheckFileForRead(fileName); - switch(type) - { - case ON_CELLS: - return ReadFieldCell(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - case ON_NODES: - return ReadFieldNode(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - case ON_GAUSS_PT: - return ReadFieldGauss(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - case ON_GAUSS_NE: - return ReadFieldGaussNE(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - default: - throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES, ON_CELLS, ON_GAUSS_PT or ON_GAUSS_NE !"); - } -} - -std::vector MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - if(its.empty()) - return std::vector(); - CheckFileForRead(fileName); - std::vector ret(its.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(its.size()); - if(its.empty()) - return ret; - //Retrieving mesh of rank 0 and field on rank 0 too. - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldsOnSameMesh : only unstructured mesh is managed !"); - MEDCouplingAutoRefCountObjectPtr m=mmuPtr->getMeshAtLevel(meshDimRelToMax); - const DataArrayInt *o2n=mmuPtr->getNumberFieldAtLevel(meshDimRelToMax); - MEDCouplingAutoRefCountObjectPtr m2(m->clone(true)); - if(o2n) - m2->renumberCells(o2n->begin(),true); - int i=0; - for(std::vector >::const_iterator it=its.begin();it!=its.end();it++,i++) - { - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,(*it).first,(*it).second); - MEDCouplingAutoRefCountObjectPtr retElt=ff->getFieldOnMeshAtLevel(type,m); - if(o2n) - retElt->renumberCells(o2n->begin(),true); - retElt->setMesh(m2); - retSafe[i]=retElt; - } - i=0; - for(std::vector >::const_iterator it=its.begin();it!=its.end();it++,i++) - ret[i]=retSafe[i].retn(); - return ret; -} - -std::vector MEDLoader::ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -std::vector MEDLoader::ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -std::vector MEDLoader::ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -std::vector MEDLoader::ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_CELLS,m); - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - return ret.retn(); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_NODES,m); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - if(ff->getPflsReallyUsed().empty()) - { - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - } - else - { - DataArrayInt *pfl=0,*arr2=0; - MEDCouplingAutoRefCountObjectPtr arr=ff->getFieldWithProfile(ON_NODES,meshDimRelToMax,mm,pfl); - MEDCouplingAutoRefCountObjectPtr pflSafe(pfl); - MEDCouplingAutoRefCountObjectPtr mp=m->getCellIdsFullyIncludedInNodeIds(pfl->begin(),pfl->end()); - MEDCouplingAutoRefCountObjectPtr mzip=static_cast(m->buildPartAndReduceNodes(mp->begin(),mp->end(),arr2)); - MEDCouplingAutoRefCountObjectPtr arr2Safe(arr2); - MEDCouplingAutoRefCountObjectPtr arr3=arr2->invertArrayO2N2N2O(mzip->getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr pflSorted(pflSafe->deepCpy()); pflSorted->sort(true); - if(!arr3->isEqualWithoutConsideringStr(*pflSorted)) - throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldNode : not implemented yet !"); - if(!arr3->isEqualWithoutConsideringStr(*pflSafe)) - { - MEDCouplingAutoRefCountObjectPtr o2n2=pflSafe->checkAndPreparePermutation(); - MEDCouplingAutoRefCountObjectPtr n2o2=o2n2->invertArrayO2N2N2O(o2n2->getNumberOfTuples()); - mzip->renumberNodes(n2o2->begin(),n2o2->getNumberOfTuples()); - arr->setName(""); - ret->setArray(arr); - } - ret->setMesh(mzip); - } - return ret.retn(); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_PT,m); - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - return ret.retn(); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_NE,m); - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - return ret.retn(); -} - -void MEDLoader::WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDLoader::WriteMesh : input mesh is null !"); - const MEDCouplingUMesh *um(dynamic_cast(mesh)); - if(um) - { - WriteUMesh(fileName,um,writeFromScratch); - return ; - } - int mod=writeFromScratch?2:0; - const MEDCoupling1GTUMesh *um2(dynamic_cast(mesh)); - if(um2) - { - MEDCouplingAutoRefCountObjectPtr mmu(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*mmu); - mmu->setMeshAtLevel(0,const_cast(um2)); - mmu->write(fileName,mod); - return ; - } - const MEDCouplingCMesh *um3(dynamic_cast(mesh)); - if(um3) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCMesh::New()); - AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um3)); - mmc->write(fileName,mod); - return ; - } - const MEDCouplingCurveLinearMesh *um4(dynamic_cast(mesh)); - if(um4) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCurveLinearMesh::New()); - AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um4)); - mmc->write(fileName,mod); - return ; - } - throw INTERP_KERNEL::Exception("MEDLoader::WriteMesh : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); -} - -void MEDLoader::WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDLoader::WriteUMesh : input mesh is null !"); - int mod=writeFromScratch?2:0; - MEDCouplingAutoRefCountObjectPtr m(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*m); - MEDCouplingAutoRefCountObjectPtr mcpy(static_cast(mesh->deepCpy())); - m->setMeshAtLevel(0,mcpy,true); - m->write(fileName,mod); -} - -void MEDLoader::WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) -{ - MEDLoader::WriteUMesh(fileName,mesh,writeFromScratch); -} - -void MEDLoader::WriteUMeshesPartition(const std::string& fileName, const std::string& meshNameC, const std::vector& meshes, bool writeFromScratch) -{ - std::string meshName(meshNameC); - if(meshName.empty()) - throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !"); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr m(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*m); - m->setGroupsFromScratch(0,meshes,true); - m->setName(meshNameC); - int mod=writeFromScratch?2:0; - m->write(fileName,mod); -} - -void MEDLoader::WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshNameC, const std::vector& meshes, bool writeFromScratch) -{ - WriteUMeshesPartition(fileName,meshNameC,meshes,writeFromScratch); -} - -void MEDLoader::WriteUMeshes(const std::string& fileName, const std::vector& meshes, bool writeFromScratch) -{ - int mod=writeFromScratch?2:0; - MEDCouplingAutoRefCountObjectPtr m(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*m); - m->setMeshes(meshes,true); - m->write(fileName,mod); -} - -void MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) -{ - MEDCouplingAutoRefCountObjectPtr ff(MEDFileField1TS::New()); - MEDLoader::AssignStaticWritePropertiesTo(*ff); - MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); - const MEDCouplingMesh *m(f2->getMesh()); - const MEDCouplingUMesh *um(dynamic_cast(m)); - const MEDCoupling1GTUMesh *um2(dynamic_cast(m)); - const MEDCouplingCMesh *um3(dynamic_cast(m)); - const MEDCouplingCurveLinearMesh *um4(dynamic_cast(m)); - MEDCouplingAutoRefCountObjectPtr mm; - int mod=writeFromScratch?2:0; - if(um) - { - MEDCouplingAutoRefCountObjectPtr mmu(MEDFileUMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmu); - MEDCouplingAutoRefCountObjectPtr o2n(um->getRenumArrForMEDFileFrmt()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(o2n->getNumberOfTuples())); - f2->renumberCells(o2n->begin(),false); - mmu->setMeshAtLevel(0,const_cast(static_cast(f2->getMesh()))); - mmu->setRenumFieldArr(0,n2o); - ff->setFieldNoProfileSBT(f2); - mmu->write(fileName,mod); - } - else if(um2) - { - MEDCouplingAutoRefCountObjectPtr mmu(MEDFileUMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmu); - mmu->setMeshAtLevel(0,const_cast(um2)); - ff->setFieldNoProfileSBT(f2); - mmu->write(fileName,mod); - } - else if(um3) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um3)); - ff->setFieldNoProfileSBT(f2); - mmc->write(fileName,mod); - } - else if(um4) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCurveLinearMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um4)); - ff->setFieldNoProfileSBT(f2); - mmc->write(fileName,mod); - } - else - throw INTERP_KERNEL::Exception("MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); - ff->write(fileName,0); -} - -void MEDLoader::WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) -{ - if(!f) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : input field is NULL !"); - f->checkCoherency(); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(writeFromScratch || (!writeFromScratch && status==MEDLoaderBase::NOT_EXIST)) - { - MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,true); - } - else - { - std::vector meshNames=GetMeshNames(fileName); - if(!f->getMesh()) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : trying to write a field with no mesh !"); - std::string fileNameCpp(f->getMesh()->getName()); - if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) - MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,false); - else - { - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,f->getMesh()->getName().c_str())); - AssignStaticWritePropertiesTo(*mm); - const MEDFileMesh *mmPtr(mm); - const MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umeshes are supported now !"); - MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); - MEDCouplingUMesh *m=dynamic_cast(const_cast(f2->getMesh())); - if(!m) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umesh in input field supported !"); - MEDCouplingAutoRefCountObjectPtr o2n=m->getRenumArrForMEDFileFrmt(); - f2->renumberCells(o2n->begin(),false); - m=static_cast(const_cast(f2->getMesh())); - MEDCouplingAutoRefCountObjectPtr mread=mmuPtr->getMeshAtLevel(m->getMeshDimension()-mm->getMeshDimension()); - if(f2->getTypeOfField()!=ON_NODES) - { - m->tryToShareSameCoordsPermute(*mread,_EPS_FOR_NODE_COMP); - DataArrayInt *part=0; - bool b=mread->areCellsIncludedIn(m,_COMP_FOR_CELL,part); - MEDCouplingAutoRefCountObjectPtr partSafe(part); - if(!b) - { - std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart) with the mesh you intend to write ! This is maybe due to a too strict policy ! Try with to lease it by calling SetCompPolicyForCell !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr f1ts(MEDFileField1TS::New()); - AssignStaticWritePropertiesTo(*f1ts); - if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfCells()) - f1ts->setFieldNoProfileSBT(f2); - else - { - part->setName(f1ts->createNewNameOfPfl().c_str()); - f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); - } - f1ts->write(fileName,0); - return ; - } - else - { - DataArrayInt *part=0; - bool b=mread->getCoords()->areIncludedInMe(m->getCoords(),_EPS_FOR_NODE_COMP,part); - MEDCouplingAutoRefCountObjectPtr partSafe(part); - if(!b) - { - std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart regarding nodes) with the mesh you intend to write ! This is maybe due to a too strict epsilon ! Try with to lease it by calling SetEpsilonForNodeComp !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr f1ts(MEDFileField1TS::New()); - AssignStaticWritePropertiesTo(*f1ts); - if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfNodes()) - f1ts->setFieldNoProfileSBT(f2); - else - { - part->setName(f1ts->createNewNameOfPfl().c_str()); - f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); - } - f1ts->write(fileName,0); - } - } - } -} - -void MEDLoader::WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) -{ - WriteField(fileName,f,writeFromScratch); -} - -void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) -{ - if(!f) - throw INTERP_KERNEL::Exception("MEDLoader::WriteFieldUsingAlreadyWrittenMesh : input field is null !"); - f->checkCoherency(); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr f1ts(MEDFileField1TS::New()); - AssignStaticWritePropertiesTo(*f1ts); - MEDCouplingUMesh *m(dynamic_cast(const_cast(f->getMesh()))); - if(m) - { - MEDCouplingAutoRefCountObjectPtr o2n(m->getRenumArrForMEDFileFrmt()); - MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); - f2->renumberCells(o2n->begin(),false); - f1ts->setFieldNoProfileSBT(f2); - } - else - f1ts->setFieldNoProfileSBT(f); - f1ts->write(fileName,0); -} diff --git a/medtool/src/MEDLoader/MEDLoader.hxx b/medtool/src/MEDLoader/MEDLoader.hxx deleted file mode 100644 index df2bfa462..000000000 --- a/medtool/src/MEDLoader/MEDLoader.hxx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDLOADER_HXX__ -#define __MEDLOADER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "InterpKernelException.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class MEDCouplingMesh; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDFileWritable; -} - -class MEDLOADER_EXPORT MEDLoader -{ -public: - static void SetEpsilonForNodeComp(double val); - static void SetCompPolicyForCell(int val); - static void SetTooLongStrPolicy(int val); - static bool HasXDR(); - static std::string MEDFileVersionStr(); - static void MEDFileVersion(int& major, int& minor, int& release); - static void CheckFileForRead(const std::string& fileName); - static std::vector GetMeshNames(const std::string& fileName); - static std::vector< std::vector< std::pair > > GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, int& numberOfNodes); - static std::vector< std::pair > GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName); - static std::vector GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName); - static std::vector GetMeshGroupsNames(const std::string& fileName, const std::string& meshName); - static std::vector GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName); - static std::vector GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName); - static std::vector GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName); - static std::vector GetAllFieldNames(const std::string& fileName); - static std::vector GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); - static std::vector GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName); - static std::vector GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); - static std::vector GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); - static std::vector< std::pair > GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector< std::pair > GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector< std::pair > GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector< std::pair< std::pair, double> > GetAllFieldIterations(const std::string& fileName, const std::string& fieldName); - static double GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& fams); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& grps); - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0); - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax=0); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax=0); - static int ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static std::vector ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static void WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch); - static void WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); - static void WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); - static void WriteUMeshesPartition(const std::string& fileName, const std::string& meshName, const std::vector& meshes, bool writeFromScratch); - static void WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshName, const std::vector& meshes, bool writeFromScratch); - static void WriteUMeshes(const std::string& fileName, const std::vector& meshes, bool writeFromScratch); - static void WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - static void WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - static void WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); -public: - static void AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj); -private: - MEDLoader(); -public: - static double _EPS_FOR_NODE_COMP; - static int _COMP_FOR_CELL; - static int _TOO_LONG_STR; -}; - -#endif diff --git a/medtool/src/MEDLoader/MEDLoaderBase.cxx b/medtool/src/MEDLoader/MEDLoaderBase.cxx deleted file mode 100644 index 13db3d9d9..000000000 --- a/medtool/src/MEDLoader/MEDLoaderBase.cxx +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDLoaderBase.hxx" -#include "InterpKernelException.hxx" - -#include -#include -#include -#include - -const char MEDLoaderBase::WHITE_SPACES[]=" \n"; - -int MEDLoaderBase::getStatusOfFile(const std::string& fileName) -{ - std::ifstream ifs; - ifs.open(fileName.c_str()); - if((ifs.rdstate() & std::ifstream::failbit)!=0) - { - ifs.close(); - return NOT_EXIST; - } - std::ofstream ofs(fileName.c_str(),std::ios_base::app); - if((ofs.rdstate() & std::ofstream::failbit)!=0) - { - return EXIST_RDONLY; - } - return EXIST_RW; -} - -char *MEDLoaderBase::buildEmptyString(int lgth) -{ - char *ret=new char[lgth+1]; - std::fill(ret,ret+lgth,' '); - ret[lgth]='\0'; - return ret; -} - -void MEDLoaderBase::getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName) -{ - std::size_t pos=fullName.find_last_of(getPathSep()); - if(pos!=std::string::npos) - { - dirName=fullName.substr(0,pos); - baseName=fullName.substr(pos+1); - } - else - { - dirName.clear(); - baseName=fullName; - } -} - -std::string MEDLoaderBase::joinPath(const std::string& dirName, const std::string& baseName) -{ - if(!dirName.empty()) - return dirName+getPathSep()+baseName; - else - return baseName; -} - -std::string MEDLoaderBase::getPathSep() -{ -#ifndef WIN32 - return std::string("/"); -#else - return std::string("\\"); -#endif -} - -std::string MEDLoaderBase::buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth) -{ - std::string ret(buildStringFromFortran(name,nameLgth)); - std::string unitCpp(buildStringFromFortran(unit,unitLgth)); - if(unitCpp.empty() || unitCpp[0]=='\0') - return ret; - ret+=" ["; - ret+=unitCpp; - ret+="]"; - return ret; -} - -void MEDLoaderBase::splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit) -{ - std::string::size_type f1=s.find_first_of('['); - std::string::size_type f2=s.find_last_of(']'); - if(f1!=std::string::npos && f2!=std::string::npos) - { - if(f1maxLgth) - { - if(behaviour==0 || behaviour>1) - { - std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else if(behaviour==1) - { - std::string s=zipString(src,maxLgth); - std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; - std::cerr << "zipping to : " << s << "\n"; - strcpy(dest,s.c_str()); - return ; - } - } - strcpy(dest,src); -} - -/*! - * This method is equivalent to MEDLoaderBase::safeStrCpy except that here no '\0' car is put. - * This method should be used for multi string in one string. - */ -void MEDLoaderBase::safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour) -{ - if((int)strlen(src)>maxLgth) - { - if(behaviour==0 || behaviour>1) - { - std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else if(behaviour==1) - { - std::string s=zipString(src,maxLgth); - std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; - std::cerr << "zipping to : " << s << "\n"; - strcpy(dest,s.c_str()); - return ; - } - } - int n=strlen(src); - strncpy(dest,src,n); -} - -std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth) -{ - std::string ret(expr,lgth); - std::string whiteSpaces(WHITE_SPACES); - std::size_t lgthReal=strlen(ret.c_str()); - std::string ret2=ret.substr(0,lgthReal); - std::size_t found=ret2.find_last_not_of(whiteSpaces); - if (found!=std::string::npos) - ret2.erase(found+1); - else - ret2.clear();//ret is all whitespace - return ret2; -} - -/*! - * This method given the target size to respect 'sizeToRespect' tries to reduce size of 'src' string. - * This method uses several soft methods to do its job. But if it fails a simple cut of string will be performed. - */ -std::string MEDLoaderBase::zipString(const std::string& src, int sizeToRespect) -{ - std::string s(src); - strip(s); - if((int)s.length()<=sizeToRespect) - return s; - s=src; - zipEqualConsChar(s,3); - if((int)s.length()<=sizeToRespect) - return s; - s=src; - zipEqualConsChar(s,2); - if((int)s.length()<=sizeToRespect) - return s; - s=src; - return s.substr(0,sizeToRespect); -} - -/*! - * This method see if there is in 's' more than 'minConsSmChar' consecutive same character. - * If yes, the group will be zipped using only one character for this group. - * If no such group is found, s remains unchanged. - */ -void MEDLoaderBase::zipEqualConsChar(std::string& s, int minConsSmChar) -{ - for(std::string::iterator it=s.begin();it!=s.end();it++) - { - char tmp=*it; - int sz=1; - for(std::string::iterator it2=it+1;it2!=s.end() && *it2==tmp;it2++) - sz++; - if(sz>=minConsSmChar) - s.erase(it+1,it+sz); - } -} - diff --git a/medtool/src/MEDLoader/MEDLoaderBase.hxx b/medtool/src/MEDLoader/MEDLoaderBase.hxx deleted file mode 100644 index 5ff6cf6e8..000000000 --- a/medtool/src/MEDLoader/MEDLoaderBase.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDLOADERBASE_HXX__ -#define __MEDLOADERBASE_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "InterpKernelException.hxx" - -#include - -class MEDLOADER_EXPORT MEDLoaderBase -{ -public: - static int getStatusOfFile(const std::string& fileName); - static char *buildEmptyString(int lgth); - static void getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName); - static std::string getPathSep(); - static std::string joinPath(const std::string& dirName, const std::string& baseName); - static std::string buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth); - static void splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit); - static void strip(std::string& s); - static void safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour); - static void safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour); - static std::string buildStringFromFortran(const char *expr, int lgth); - static void zipEqualConsChar(std::string& s, int minConsSmChar); - static std::string zipString(const std::string& src, int sizeToRespect); -public: - static const int EXIST_RW=0; - static const int NOT_EXIST=1; - static const int EXIST_RDONLY=2; - static const int EXIST_WRONLY=3; - static const int DIR_LOCKED=4; - static const char WHITE_SPACES[]; -}; - -#endif diff --git a/medtool/src/MEDLoader/MEDLoaderDefines.hxx b/medtool/src/MEDLoader/MEDLoaderDefines.hxx deleted file mode 100644 index fd92fc66b..000000000 --- a/medtool/src/MEDLoader/MEDLoaderDefines.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDLOADERDEFINES_HXX__ -#define __MEDLOADERDEFINES_HXX__ - -#ifdef WIN32 -# if defined medloader_EXPORTS -# define MEDLOADER_EXPORT __declspec(dllexport) -# else -# define MEDLOADER_EXPORT __declspec(dllimport) -# endif -#else -# define MEDLOADER_EXPORT -#endif - -#endif diff --git a/medtool/src/MEDLoader/SauvMedConvertor.cxx b/medtool/src/MEDLoader/SauvMedConvertor.cxx deleted file mode 100644 index 8972744a4..000000000 --- a/medtool/src/MEDLoader/SauvMedConvertor.cxx +++ /dev/null @@ -1,3831 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvMedConvertor.cxx -// Created : Tue Aug 16 14:43:20 2011 -// Author : Edward AGAPOV (eap) -// - -#include "SauvMedConvertor.hxx" - -#include "CellModel.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "MEDFileData.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef WIN32 -#include -#else -#include -#endif - -#ifdef HAS_XDR -#include -#include -#endif - -using namespace SauvUtilities; -using namespace ParaMEDMEM; - -namespace -{ - // for ASCII file reader - const int GIBI_MaxOutputLen = 150; // max length of a line in the sauve file - const int GIBI_BufferSize = 16184; // for buffered reading - - using namespace INTERP_KERNEL; - - const size_t MaxMedCellType = NORM_ERROR; - const size_t NbGibiCellTypes = 47; - const TCellType GibiTypeToMed[NbGibiCellTypes] = - { - /*1 */ NORM_POINT1 ,/*2 */ NORM_SEG2 ,/*3 */ NORM_SEG3 ,/*4 */ NORM_TRI3 ,/*5 */ NORM_ERROR , - /*6 */ NORM_TRI6 ,/*7 */ NORM_ERROR ,/*8 */ NORM_QUAD4 ,/*9 */ NORM_ERROR ,/*10*/ NORM_QUAD8 , - /*11*/ NORM_ERROR ,/*12*/ NORM_ERROR ,/*13*/ NORM_ERROR ,/*14*/ NORM_HEXA8 ,/*15*/ NORM_HEXA20 , - /*16*/ NORM_PENTA6 ,/*17*/ NORM_PENTA15,/*18*/ NORM_ERROR ,/*19*/ NORM_ERROR ,/*20*/ NORM_ERROR , - /*21*/ NORM_ERROR ,/*22*/ NORM_ERROR ,/*23*/ NORM_TETRA4 ,/*24*/ NORM_TETRA10,/*25*/ NORM_PYRA5 , - /*26*/ NORM_PYRA13 ,/*27*/ NORM_ERROR ,/*28*/ NORM_ERROR ,/*29*/ NORM_ERROR ,/*30*/ NORM_ERROR , - /*31*/ NORM_ERROR ,/*32*/ NORM_ERROR ,/*33*/ NORM_ERROR ,/*34*/ NORM_ERROR ,/*35*/ NORM_ERROR , - /*36*/ NORM_ERROR ,/*37*/ NORM_ERROR ,/*38*/ NORM_ERROR ,/*39*/ NORM_ERROR ,/*40*/ NORM_ERROR , - /*41*/ NORM_ERROR ,/*42*/ NORM_ERROR ,/*43*/ NORM_ERROR ,/*44*/ NORM_ERROR ,/*45*/ NORM_ERROR , - /*46*/ NORM_ERROR ,/*47*/ NORM_ERROR - }; - - //================================================================================ - /*! - * \brief Return dimension of a group - */ - //================================================================================ - - unsigned getDim( const Group* grp ) - { - return SauvUtilities::getDimension( grp->_groups.empty() ? grp->_cellType : grp->_groups[0]->_cellType ); - } - - //================================================================================ - /*! - * \brief Converts connectivity of quadratic elements - */ - //================================================================================ - - inline void ConvertQuadratic( const INTERP_KERNEL::NormalizedCellType type, - const Cell & aCell ) - { - if ( const int * conn = getGibi2MedQuadraticInterlace( type )) - { - Cell* ma = const_cast(&aCell); - std::vector< Node* > new_nodes( ma->_nodes.size() ); - for (std:: size_t i = 0; i < new_nodes.size(); ++i ) - new_nodes[ i ] = ma->_nodes[ conn[ i ]]; - ma->_nodes.swap( new_nodes ); - } - } - - //================================================================================ - /*! - * \brief Returns a vector of pairs of node indices to inverse a med volume element - */ - //================================================================================ - - void getReverseVector (const INTERP_KERNEL::NormalizedCellType type, - std::vector > & swapVec ) - { - swapVec.clear(); - - switch ( type ) - { - case NORM_TETRA4: - swapVec.resize(1); - swapVec[0] = std::make_pair( 1, 2 ); - break; - case NORM_PYRA5: - swapVec.resize(1); - swapVec[0] = std::make_pair( 1, 3 ); - break; - case NORM_PENTA6: - swapVec.resize(2); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 4, 5 ); - break; - case NORM_HEXA8: - swapVec.resize(2); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 5, 7 ); - break; - case NORM_TETRA10: - swapVec.resize(3); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 4, 6 ); - swapVec[2] = std::make_pair( 8, 9 ); - break; - case NORM_PYRA13: - swapVec.resize(4); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 5, 8 ); - swapVec[2] = std::make_pair( 6, 7 ); - swapVec[3] = std::make_pair( 10, 12 ); - break; - case NORM_PENTA15: - swapVec.resize(4); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 4, 5 ); - swapVec[2] = std::make_pair( 6, 8 ); - swapVec[3] = std::make_pair( 9, 11 ); - break; - case NORM_HEXA20: - swapVec.resize(7); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 5, 7 ); - swapVec[2] = std::make_pair( 8, 11 ); - swapVec[3] = std::make_pair( 9, 10 ); - swapVec[4] = std::make_pair( 12, 15 ); - swapVec[5] = std::make_pair( 13, 14 ); - swapVec[6] = std::make_pair( 17, 19 ); - break; - // case NORM_SEG3: no need to reverse edges - // swapVec.resize(1); - // swapVec[0] = std::make_pair( 1, 2 ); - // break; - case NORM_TRI6: - swapVec.resize(2); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 3, 5 ); - break; - case NORM_QUAD8: - swapVec.resize(3); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 4, 7 ); - swapVec[2] = std::make_pair( 5, 6 ); - break; - default:; - } - } - - //================================================================================ - /*! - * \brief Inverses element orientation using vector of indices to swap - */ - //================================================================================ - - inline void reverse(const Cell & aCell, const std::vector > & swapVec ) - { - Cell* ma = const_cast(&aCell); - for ( unsigned i = 0; i < swapVec.size(); ++i ) - std::swap( ma->_nodes[ swapVec[i].first ], - ma->_nodes[ swapVec[i].second ]); - if ( swapVec.empty() ) - ma->_reverse = true; - else - ma->_reverse = false; - } - //================================================================================ - /*! - * \brief Comparator of cells by number used for ordering cells within a med group - */ - struct TCellByIDCompare - { - bool operator () (const Cell* i1, const Cell* i2) const - { - return i1->_number < i2->_number; - } - }; - typedef std::map< const Cell*, unsigned, TCellByIDCompare > TCellToOrderMap; - - //================================================================================ - /*! - * \brief Fill Group::_relocTable if necessary - */ - //================================================================================ - - void setRelocationTable( Group* grp, TCellToOrderMap& cell2order ) - { - if ( !grp->_isProfile ) return; - - // check if relocation table is necessary - bool isRelocated = false; - unsigned newOrder = 0; - TCellToOrderMap::iterator c2oIt = cell2order.begin(), c2oEnd = cell2order.end(); - for ( ; !isRelocated && c2oIt != c2oEnd; ++c2oIt, ++newOrder ) - isRelocated = ( c2oIt->second != newOrder ); - - if ( isRelocated ) - { - grp->_relocTable.resize( cell2order.size() ); - for ( newOrder = 0, c2oIt = cell2order.begin(); c2oIt != c2oEnd; ++c2oIt, ++newOrder ) - grp->_relocTable[ c2oIt->second ] = newOrder; - } - } -} - -namespace // define default GAUSS points -{ - typedef std::vector TDoubleVector; - typedef double* TCoordSlice; - typedef int TInt; - //--------------------------------------------------------------- - //! Shape function definitions - //--------------------------------------------------------------- - struct TShapeFun - { - TInt myDim; - TInt myNbRef; - TDoubleVector myRefCoord; - - TShapeFun(TInt theDim = 0, TInt theNbRef = 0) - :myDim(theDim),myNbRef(theNbRef),myRefCoord(theNbRef*theDim) {} - - TInt GetNbRef() const { return myNbRef; } - - TCoordSlice GetCoord(TInt theRefId) { return &myRefCoord[0] + theRefId * myDim; } - }; - //--------------------------------------------------------------- - /*! - * \brief Description of family of integration points - */ - //--------------------------------------------------------------- - struct TGaussDef - { - int myType; //!< element geometry (EGeometrieElement or med_geometrie_element) - TDoubleVector myRefCoords; //!< description of reference points - TDoubleVector myCoords; //!< coordinates of Gauss points - TDoubleVector myWeights; //!< weights, len(weights)== - - /*! - * \brief Creates definition of gauss points family - * \param geomType - element geometry (EGeometrieElement or med_geometrie_element) - * \param nbPoints - nb gauss point - * \param variant - [1-3] to choose the variant of definition - * - * Throws in case of invalid parameters - * variant == 1 refers to "Fonctions de forme et points d'integration - * des elements finis" v7.4 by J. PELLET, X. DESROCHES, 15/09/05 - * variant == 2 refers to the same doc v6.4 by J.P. LEFEBVRE, X. DESROCHES, 03/07/03 - * variant == 3 refers to the same doc v6.4, second variant for 2D elements - */ - TGaussDef(const int geomType, const int nbPoints, const int variant=1); - - int dim() const { return SauvUtilities::getDimension( NormalizedCellType( myType )); } - int nbPoints() const { return myWeights.capacity(); } - - private: - void add(const double x, const double weight); - void add(const double x, const double y, const double weight); - void add(const double x, const double y, const double z, const double weight); - void setRefCoords(const TShapeFun& aShapeFun) { myRefCoords = aShapeFun.myRefCoord; } - }; - struct TSeg2a: TShapeFun { - TSeg2a(); - }; - struct TSeg3a: TShapeFun { - TSeg3a(); - }; - struct TTria3a: TShapeFun { - TTria3a(); - }; - struct TTria6a: TShapeFun { - TTria6a(); - }; - struct TTria3b: TShapeFun { - TTria3b(); - }; - struct TTria6b: TShapeFun { - TTria6b(); - }; - struct TQuad4a: TShapeFun { - TQuad4a(); - }; - struct TQuad8a: TShapeFun { - TQuad8a(); - }; - struct TQuad4b: TShapeFun { - TQuad4b(); - }; - struct TQuad8b: TShapeFun { - TQuad8b(); - }; - struct TTetra4a: TShapeFun { - TTetra4a(); - }; - struct TTetra10a: TShapeFun { - TTetra10a(); - }; - struct TTetra4b: TShapeFun { - TTetra4b(); - }; - struct TTetra10b: TShapeFun { - TTetra10b(); - }; - struct THexa8a: TShapeFun { - THexa8a(); - }; - struct THexa20a: TShapeFun { - THexa20a(TInt theDim = 3, TInt theNbRef = 20); - }; - struct THexa27a: THexa20a { - THexa27a(); - }; - struct THexa8b: TShapeFun { - THexa8b(); - }; - struct THexa20b: TShapeFun { - THexa20b(TInt theDim = 3, TInt theNbRef = 20); - }; - struct TPenta6a: TShapeFun { - TPenta6a(); - }; - struct TPenta6b: TShapeFun { - TPenta6b(); - }; - struct TPenta15a: TShapeFun { - TPenta15a(); - }; - struct TPenta15b: TShapeFun { - TPenta15b(); - }; - struct TPyra5a: TShapeFun { - TPyra5a(); - }; - struct TPyra5b: TShapeFun { - TPyra5b(); - }; - struct TPyra13a: TShapeFun { - TPyra13a(); - }; - struct TPyra13b: TShapeFun { - TPyra13b(); - }; - - void TGaussDef::add(const double x, const double weight) - { - if ( dim() != 1 ) - THROW_IK_EXCEPTION("TGaussDef: dim() != 1"); - if ( myWeights.capacity() == myWeights.size() ) - THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); - myCoords.push_back( x ); - myWeights.push_back( weight ); - } - void TGaussDef::add(const double x, const double y, const double weight) - { - if ( dim() != 2 ) - THROW_IK_EXCEPTION("TGaussDef: dim() != 2"); - if ( myWeights.capacity() == myWeights.size() ) - THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); - myCoords.push_back( x ); - myCoords.push_back( y ); - myWeights.push_back( weight ); - } - void TGaussDef::add(const double x, const double y, const double z, const double weight) - { - if ( dim() != 3 ) - THROW_IK_EXCEPTION("TGaussDef: dim() != 3"); - if ( myWeights.capacity() == myWeights.size() ) - THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); - myCoords.push_back( x ); - myCoords.push_back( y ); - myCoords.push_back( z ); - myWeights.push_back( weight ); - } - - //--------------------------------------------------------------- - TSeg2a::TSeg2a():TShapeFun(1,2) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; break; - case 1: aCoord[0] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TSeg3a::TSeg3a():TShapeFun(1,3) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; break; - case 1: aCoord[0] = 1.0; break; - case 2: aCoord[0] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTria3a::TTria3a(): - TShapeFun(2,3) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - } - } - } - //--------------------------------------------------------------- - TTria6a::TTria6a():TShapeFun(2,6) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = -1.0; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTria3b::TTria3b(): - TShapeFun(2,3) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 0.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TTria6b::TTria6b(): - TShapeFun(2,6) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 0.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - - case 3: aCoord[0] = 0.5; aCoord[1] = 0.0; break; - case 4: aCoord[0] = 0.5; aCoord[1] = 0.5; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.5; break; - } - } - } - //--------------------------------------------------------------- - TQuad4a::TQuad4a(): - TShapeFun(2,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TQuad8a::TQuad8a(): - TShapeFun(2,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - - case 4: aCoord[0] = -1.0; aCoord[1] = 0.0; break; - case 5: aCoord[0] = 0.0; aCoord[1] = -1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 7: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TQuad4b::TQuad4b(): - TShapeFun(2,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TQuad8b::TQuad8b(): - TShapeFun(2,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - - case 4: aCoord[0] = 0.0; aCoord[1] = -1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 6: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra4a::TTetra4a(): - TShapeFun(3,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra10a::TTetra10a(): - TShapeFun(3,10) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 4: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 6: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - - case 7: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 8: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra4b::TTetra4b(): - TShapeFun(3,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra10b::TTetra10b(): - TShapeFun(3,10) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 6: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - - case 7: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 8: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - THexa8a::THexa8a(): - TShapeFun(3,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - THexa20a::THexa20a(TInt theDim, TInt theNbRef): - TShapeFun(theDim,theNbRef) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - - case 8: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 9: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 10: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 11: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 12: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 13: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 14: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 15: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 16: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 17: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 18: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 19: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - THexa27a::THexa27a(): - THexa20a(3,27) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 20: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 21: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 22: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 23: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 24: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 25: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 26: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - THexa8b::THexa8b(): - TShapeFun(3,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - THexa20b::THexa20b(TInt theDim, TInt theNbRef): - TShapeFun(theDim,theNbRef) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - - case 11: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 10: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 9: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 8: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 16: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 19: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 18: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 17: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 15: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 14: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 13: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 12: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta6a::TPenta6a(): - TShapeFun(3,6) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta6b::TPenta6b(): - TShapeFun(3,6) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta15a::TPenta15a(): - TShapeFun(3,15) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 6: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 8: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 10: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 11: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 12: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 13: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 14: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta15b::TPenta15b(): - TShapeFun(3,15) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 8: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 6: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 12: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 14: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 13: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 11: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 10: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 9: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPyra5a::TPyra5a(): - TShapeFun(3,5) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TPyra5b::TPyra5b(): - TShapeFun(3,5) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TPyra13a::TPyra13a(): - TShapeFun(3,13) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - - case 5: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 6: aCoord[0] = -0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 7: aCoord[0] = -0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 8: aCoord[0] = 0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 10: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 11: aCoord[0] = -0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 12: aCoord[0] = 0.0; aCoord[1] = -0.5; aCoord[2] = 0.5; break; - } - } - } - //--------------------------------------------------------------- - TPyra13b::TPyra13b(): - TShapeFun(3,13) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - - case 8: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 7: aCoord[0] = -0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 6: aCoord[0] = -0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 5: aCoord[0] = 0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 12: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 11: aCoord[0] = -0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 10: aCoord[0] = 0.0; aCoord[1] = -0.5; aCoord[2] = 0.5; break; - } - } - } - /*! - * \brief Fill definition of gauss points family - */ - - TGaussDef::TGaussDef(const int geom, const int nbGauss, const int variant) - { - myType = geom; - myCoords .reserve( nbGauss * dim() ); - myWeights.reserve( nbGauss ); - - switch ( geom ) { - - case NORM_SEG2: - case NORM_SEG3: - if (geom == NORM_SEG2) setRefCoords( TSeg2a() ); - else setRefCoords( TSeg3a() ); - switch ( nbGauss ) { - case 1: { - add( 0.0, 2.0 ); break; - } - case 2: { - const double a = 0.577350269189626; - add( a, 1.0 ); - add( -a, 1.0 ); break; - } - case 3: { - const double a = 0.774596669241; - const double P1 = 1./1.8; - const double P2 = 1./1.125; - add( -a, P1 ); - add( 0, P2 ); - add( a, P1 ); break; - } - case 4: { - const double a = 0.339981043584856, b = 0.861136311594053; - const double P1 = 0.652145154862546, P2 = 0.347854845137454 ; - add( a, P1 ); - add( -a, P1 ); - add( b, P2 ); - add( -b, P2 ); break; - } - default: - THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for SEG"< alfa - const double a = (6 + sqrt(15.))/21.; - const double b = (6 - sqrt(15.))/21.; - const double P1 = (155 + sqrt(15.))/2400.; - const double P2 = (155 - sqrt(15.))/2400.; //___ - add( -d, 1/3., 1/3., c1*9/80. );//___ - add( -d, a, a, c1*P1 ); - add( -d, 1-2*a, a, c1*P1 ); - add( -d, a, 1-2*a, c1*P1 );//___ - add( -d, b, b, c1*P2 ); - add( -d, 1-2*b, b, c1*P2 ); - add( -d, b, 1-2*b, c1*P2 );//___ - add( 0., 1/3., 1/3., c2*9/80. );//___ - add( 0., a, a, c2*P1 ); - add( 0., 1-2*a, a, c2*P1 ); - add( 0., a, 1-2*a, c2*P1 );//___ - add( 0., b, b, c2*P2 ); - add( 0., 1-2*b, b, c2*P2 ); - add( 0., b, 1-2*b, c2*P2 );//___ - add( d, 1/3., 1/3., c1*9/80. );//___ - add( d, a, a, c1*P1 ); - add( d, 1-2*a, a, c1*P1 ); - add( d, a, 1-2*a, c1*P1 );//___ - add( d, b, b, c1*P2 ); - add( d, 1-2*b, b, c1*P2 ); - add( d, b, 1-2*b, c1*P2 );//___ - break; - } - default: - THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PENTA: " < conn; - static const int hexa20 [] = {0,6,4,2, 12,18,16,14, 7,5,3,1, 19,17,15,13, 8,11,10,9}; - static const int penta15[] = {0,2,4, 9,11,13, 1,3,5, 10,12,14, 6,8,7}; - static const int pyra13 [] = {0,2,4,6, 12, 1,3,5,7, 8,9,10,11}; - static const int tetra10[] = {0,2,4, 9, 1,3,5, 6,7,8}; - static const int quad8 [] = {0,2,4,6, 1,3,5,7}; - static const int tria6 [] = {0,2,4, 1,3,5}; - static const int seg3 [] = {0,2,1}; - if ( conn.empty() ) - { - conn.resize( MaxMedCellType + 1, 0 ); - conn[ NORM_HEXA20 ] = hexa20; - conn[ NORM_PENTA15] = penta15; - conn[ NORM_PYRA13 ] = pyra13; - conn[ NORM_TETRA10] = tetra10; - conn[ NORM_SEG3 ] = seg3; - conn[ NORM_TRI6 ] = tria6; - conn[ NORM_QUAD8 ] = quad8; - } - return conn[ type ]; -} - -//================================================================================ -/*! - * \brief Avoid coping sortedNodeIDs - */ -//================================================================================ - -Cell::Cell(const Cell& ma) - : _nodes(ma._nodes), _reverse(ma._reverse), _sortedNodeIDs(0), _number(ma._number) -{ - if ( ma._sortedNodeIDs ) - { - _sortedNodeIDs = new int[ _nodes.size() ]; - std::copy( ma._sortedNodeIDs, ma._sortedNodeIDs + _nodes.size(), _sortedNodeIDs ); - } -} - -//================================================================================ -/*! - * \brief Rerturn the i-th link of face - */ -//================================================================================ - -SauvUtilities::Link Cell::link(int i) const -{ - int i2 = ( i + 1 ) % _nodes.size(); - if ( _reverse ) - return std::make_pair( _nodes[i2]->_number, _nodes[i]->_number ); - else - return std::make_pair( _nodes[i]->_number, _nodes[i2]->_number ); -} - -//================================================================================ -/*! - * \brief creates if needed and return _sortedNodeIDs - */ -//================================================================================ - -const TID* Cell::getSortedNodes() const -{ - if ( !_sortedNodeIDs ) - { - size_t l=_nodes.size(); - _sortedNodeIDs = new int[ l ]; - - for (size_t i=0; i!=l; ++i) - _sortedNodeIDs[i]=_nodes[i]->_number; - std::sort( _sortedNodeIDs, _sortedNodeIDs + l ); - } - return _sortedNodeIDs; -} - -//================================================================================ -/*! - * \brief Compare sorted ids of cell nodes - */ -//================================================================================ - -bool Cell::operator< (const Cell& ma) const -{ - if ( _nodes.size() == 1 ) - return _nodes[0] < ma._nodes[0]; - - const int* v1 = getSortedNodes(); - const int* v2 = ma.getSortedNodes(); - for ( const int* vEnd = v1 + _nodes.size(); v1 < vEnd; ++v1, ++v2 ) - if(*v1 != *v2) - return *v1 < *v2; - return false; -} - -//================================================================================ -/*! - * \brief Dump a Cell - */ -//================================================================================ - -std::ostream& SauvUtilities::operator<< (std::ostream& os, const SauvUtilities::Cell& ma) -{ - os << "cell " << ma._number << " (" << ma._nodes.size() << " nodes) : < " << ma._nodes[0]->_number; - for( size_t i=1; i!=ma._nodes.size(); ++i) - os << ", " << ma._nodes[i]->_number; -#ifdef _DEBUG_ - os << " > sortedNodes: "; - if ( ma._sortedNodeIDs ) { - os << "< "; - for( size_t i=0; i!=ma._nodes.size(); ++i) - os << ( i ? ", " : "" ) << ma._sortedNodeIDs[i]; - os << " >"; - } - else { - os << "NULL"; - } -#endif - return os; -} - -//================================================================================ -/*! - * \brief Return nb of elements in the group - */ -//================================================================================ - -int Group::size() const -{ - int sizze = 0; - if ( !_relocTable.empty() ) - sizze = _relocTable.size(); - else if ( _medGroup ) - sizze = _medGroup->getNumberOfTuples(); - else if ( !_cells.empty() ) - sizze = _cells.size(); - else - for ( size_t i = 0; i < _groups.size(); ++i ) - sizze += _groups[i]->size(); - return sizze; -} - -//================================================================================ -/*! - * \brief Conver gibi element type to med one - */ -//================================================================================ - -INTERP_KERNEL::NormalizedCellType SauvUtilities::gibi2medGeom( size_t gibiType ) -{ - if ( gibiType < 1 || gibiType > NbGibiCellTypes ) - return NORM_ERROR; - - return GibiTypeToMed[ gibiType - 1 ]; -} - -//================================================================================ -/*! - * \brief Conver med element type to gibi one - */ -//================================================================================ - -int SauvUtilities::med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType ) -{ - for ( unsigned int i = 0; i < NbGibiCellTypes; i++ ) - if ( GibiTypeToMed[ i ] == medGeomType ) - return i + 1; - - return -1; -} - -//================================================================================ -/*! - * \brief Remember the file name - */ -//================================================================================ - -FileReader::FileReader(const char* fileName):_fileName(fileName),_iRead(0),_nbToRead(0) -{ -} - -//================================================================================ -/*! - * \brief Constructor of ASCII sauve file reader - */ -//================================================================================ - -ASCIIReader::ASCIIReader(const char* fileName) - :FileReader(fileName), - _file(-1) -{ -} - -//================================================================================ -/*! - * \brief Return true - */ -//================================================================================ - -bool ASCIIReader::isASCII() const -{ - return true; -} - -//================================================================================ -/*! - * \brief Try to open an ASCII file - */ -//================================================================================ - -bool ASCIIReader::open() -{ -#ifdef WIN32 - _file = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY); -#else - _file = ::open (_fileName.c_str(), O_RDONLY); -#endif - if (_file >= 0) - { - _start = new char [GIBI_BufferSize]; // working buffer beginning - //_tmpBuf = new char [GIBI_MaxOutputLen]; - _ptr = _start; - _eptr = _start; - _lineNb = 0; - } - else - { - //THROW_IK_EXCEPTION("Can't open file "<<_fileName << " fd: " << _file); - } - return (_file >= 0); -} - -//================================================================================ -/*! - * \brief Close the file - */ -//================================================================================ - -ASCIIReader::~ASCIIReader() -{ - if (_file >= 0) - { - ::close (_file); - if (_start != 0L) - { - delete [] _start; - //delete [] _tmpBuf; - _start = 0; - } - _file = -1; - } -} - -//================================================================================ -/*! - * \brief Return a next line of the file - */ -//================================================================================ - -bool ASCIIReader::getNextLine (char* & line, bool raiseOEF /*= true*/ ) -{ - if ( getLine( line )) return true; - if ( raiseOEF ) - THROW_IK_EXCEPTION("Unexpected EOF on ln "<<_lineNb); - return false; -} - -//================================================================================ -/*! - * \brief Read a next line of the file if necessary - */ -//================================================================================ - -bool ASCIIReader::getLine(char* & line) -{ - bool aResult = true; - // Check the state of the buffer; - // if there is too little left, read the next portion of data - int nBytesRest = _eptr - _ptr; - if (nBytesRest < GIBI_MaxOutputLen) - { - if (nBytesRest > 0) - { - // move the remaining portion to the buffer beginning - for ( int i = 0; i < nBytesRest; ++i ) - _start[i] = _ptr[i]; - //memcpy (_tmpBuf, _ptr, nBytesRest); - //memcpy (_start, _tmpBuf, nBytesRest); - } - else - { - nBytesRest = 0; - } - _ptr = _start; - const int nBytesRead = ::read (_file, - &_start [nBytesRest], - GIBI_BufferSize - nBytesRest); - nBytesRest += nBytesRead; - _eptr = &_start [nBytesRest]; - } - // Check the buffer for the end-of-line - char * ptr = _ptr; - while (true) - { - // Check for end-of-the-buffer, the ultimate criterion for termination - if (ptr >= _eptr) - { - if (nBytesRest <= 0) - aResult = false; - else - _eptr[-1] = '\0'; - break; - } - // seek the line-feed character - if (ptr[0] == '\n') - { - if (ptr[-1] == '\r') - ptr[-1] = '\0'; - ptr[0] = '\0'; - ++ptr; - break; - } - ++ptr; - } - // Output the result - line = _ptr; - _ptr = ptr; - _lineNb++; - - return aResult; -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of values - * \param nbToRead - nb of fields to read - * \param nbPosInLine - nb of fields in one line - * \param width - field width - * \param shift - shift from line beginning to the field start - */ -//================================================================================ - -void ASCIIReader::init( int nbToRead, int nbPosInLine, int width, int shift /*= 0*/ ) -{ - _nbToRead = nbToRead; - _nbPosInLine = nbPosInLine; - _width = width; - _shift = shift; - _iPos = _iRead = 0; - if ( _nbToRead ) - { - getNextLine( _curPos ); - _curPos = _curPos + _shift; - } - else - { - _curPos = 0; - } - _curLocale.clear(); -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of string values - */ -//================================================================================ - -void ASCIIReader::initNameReading(int nbValues, int width /*= 8*/) -{ - init( nbValues, 72 / ( width + 1 ), width, 1 ); -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of integer values - */ -//================================================================================ - -void ASCIIReader::initIntReading(int nbValues) -{ - init( nbValues, 10, 8 ); -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of real values - */ -//================================================================================ - -void ASCIIReader::initDoubleReading(int nbValues) -{ - init( nbValues, 3, 22 ); - - // Correction 2 of getDouble(): set "C" numeric locale to read numbers - // with dot decimal point separator, as it is in SAUVE files - _curLocale = setlocale(LC_NUMERIC, "C"); -} - -//================================================================================ -/*! - * \brief Return true if not all values have been read - */ -//================================================================================ - -bool ASCIIReader::more() const -{ - bool result = false; - if ( _iRead < _nbToRead) - { - if ( _curPos ) result = true; - } - return result; -} - -//================================================================================ -/*! - * \brief Go to the nex value - */ -//================================================================================ - -void ASCIIReader::next() -{ - if ( !more() ) - THROW_IK_EXCEPTION("SauvUtilities::ASCIIReader::next(): no more() values to read"); - ++_iRead; - ++_iPos; - if ( _iRead < _nbToRead ) - { - if ( _iPos >= _nbPosInLine ) - { - getNextLine( _curPos ); - _curPos = _curPos + _shift; - _iPos = 0; - } - else - { - _curPos = _curPos + _width + _shift; - } - } - else - { - _curPos = 0; - if ( !_curLocale.empty() ) - { - setlocale(LC_NUMERIC, _curLocale.c_str()); - _curLocale.clear(); - } - } -} - -//================================================================================ -/*! - * \brief Return the current integer value - */ -//================================================================================ - -int ASCIIReader::getInt() const -{ - // fix for two glued ints (issue 0021009): - // Line nb | File contents - // ------------------------------------------------------------------------------------ - // 53619905 | 1 2 6 8 - // 53619906 | SCALAIRE - // 53619907 | -63312600499 1 0 0 0 -2 0 2 - // where -63312600499 is actualy -633 and 12600499 - char hold=_curPos[_width]; - _curPos[_width] = '\0'; - int result = atoi( _curPos ); - _curPos[_width] = hold; - return result; - //return atoi(str()); -} - -//================================================================================ -/*! - * \brief Return the current float value - */ -//================================================================================ - -float ASCIIReader::getFloat() const -{ - return getDouble(); -} - -//================================================================================ -/*! - * \brief Return the current double value - */ -//================================================================================ - -double ASCIIReader::getDouble() const -{ - //std::string aStr (_curPos); - - // Correction: add missing 'E' specifier - // int aPosStart = aStr.find_first_not_of(" \t"); - // if (aPosStart < (int)aStr.length()) { - // int aPosSign = aStr.find_first_of("+-", aPosStart + 1); // pass the leading symbol, as it can be a sign - // if (aPosSign < (int)aStr.length()) { - // if (aStr[aPosSign - 1] != 'e' && aStr[aPosSign - 1] != 'E') - // aStr.insert(aPosSign, "E", 1); - // } - // } - - // Different Correction (more optimal) - // Sample: - // 0.00000000000000E+00 -2.37822406690632E+01 6.03062748797469E+01 - // 7.70000000000000-100 7.70000000000000+100 7.70000000000000+100 - //0123456789012345678901234567890123456789012345678901234567890123456789 - const size_t posE = 18; - std::string aStr (_curPos); - if ( aStr.find('E') < 0 && aStr.find('e') < 0 ) - { - if ( aStr.size() < posE+1 ) - THROW_IK_EXCEPTION("No more doubles (line #" << lineNb() << ")"); - aStr.insert( posE, "E", 1 ); - return atof(aStr.c_str()); - } - return atof( _curPos ); -} - -//================================================================================ -/*! - * \brief Return the current string value - */ -//================================================================================ - -std::string ASCIIReader::getName() const -{ - int len = _width; - while (( _curPos[len-1] == ' ' || _curPos[len-1] == 0) && len > 0 ) - len--; - return std::string( _curPos, len ); -} - -//================================================================================ -/*! - * \brief Constructor of a binary sauve file reader - */ -//================================================================================ - -XDRReader::XDRReader(const char* fileName) :FileReader(fileName), _xdrs_file(NULL) -{ -} - -//================================================================================ -/*! - * \brief Close the XDR sauve file - */ -//================================================================================ - -XDRReader::~XDRReader() -{ -#ifdef HAS_XDR - if ( _xdrs_file ) - { - xdr_destroy((XDR*)_xdrs); - free((XDR*)_xdrs); - ::fclose(_xdrs_file); - _xdrs_file = NULL; - } -#endif -} - -//================================================================================ -/*! - * \brief Return false - */ -//================================================================================ - -bool XDRReader::isASCII() const -{ - return false; -} - -//================================================================================ -/*! - * \brief Try to open an XRD file - */ -//================================================================================ - -bool XDRReader::open() -{ - bool xdr_ok = false; -#ifdef HAS_XDR -#ifdef WIN32 - if ((_xdrs_file = ::fopen(_fileName.c_str(), "rb"))) -#else - if ((_xdrs_file = ::fopen(_fileName.c_str(), "r"))) -#endif - { - _xdrs = (XDR *)malloc(sizeof(XDR)); - xdrstdio_create((XDR*)_xdrs, _xdrs_file, XDR_DECODE); - - const int maxsize = 10; - char icha[maxsize+1]; - char* icha2 = icha; - if (( xdr_ok = xdr_string((XDR*)_xdrs, &icha2, maxsize))) - { - icha[maxsize] = '\0'; - xdr_ok = (strcmp(icha, "CASTEM XDR") == 0); - } - if ( !xdr_ok ) - { - xdr_destroy((XDR*)_xdrs); - free((XDR*)_xdrs); - fclose(_xdrs_file); - _xdrs_file = NULL; - } - } -#endif - return xdr_ok; -} - -//================================================================================ -/*! - * \brief A stub - */ -//================================================================================ - -bool XDRReader::getNextLine (char* &, bool ) -{ - return true; -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of values - * \param nbToRead - nb of fields to read - * \param width - field width - */ -//================================================================================ - -void XDRReader::init( int nbToRead, int width/*=0*/ ) -{ - if(_iRead < _nbToRead) - { - std::cout << "_iRead, _nbToRead : " << _iRead << " " << _nbToRead << std::endl; - std::cout << "Unfinished iteration before new one !" << std::endl; - THROW_IK_EXCEPTION("SauvUtilities::XDRReader::init(): Unfinished iteration before new one !"); - } - _iRead = 0; - _nbToRead = nbToRead; - _width = width; -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of string values - */ -//================================================================================ - -void XDRReader::initNameReading(int nbValues, int width) -{ - init( nbValues, width ); - _xdr_kind = _xdr_kind_char; - if(nbValues*width) - { - unsigned int nels = nbValues*width; - _xdr_cvals = (char*)malloc((nels+1)*sizeof(char)); -#ifdef HAS_XDR - xdr_string((XDR*)_xdrs, &_xdr_cvals, nels); -#endif - _xdr_cvals[nels] = '\0'; - } -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of integer values - */ -//================================================================================ - -void XDRReader::initIntReading(int nbValues) -{ - init( nbValues ); - _xdr_kind = _xdr_kind_int; - if(nbValues) - { -#ifdef HAS_XDR - unsigned int nels = nbValues; - unsigned int actual_nels; - _xdr_ivals = (int*)malloc(nels*sizeof(int)); - xdr_array((XDR*)_xdrs, (char **)&_xdr_ivals, &actual_nels, nels, sizeof(int), (xdrproc_t)xdr_int); -#endif - } -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of real values - */ -//================================================================================ - -void XDRReader::initDoubleReading(int nbValues) -{ - init( nbValues ); - _xdr_kind = _xdr_kind_double; - if(nbValues) - { -#ifdef HAS_XDR - unsigned int nels = nbValues; - unsigned int actual_nels; - _xdr_dvals = (double*)malloc(nels*sizeof(double)); - xdr_array((XDR*)_xdrs, (char **)&_xdr_dvals, &actual_nels, nels, sizeof(double), (xdrproc_t)xdr_double); -#endif - } -} - -//================================================================================ -/*! - * \brief Return true if not all values have been read - */ -//================================================================================ - -bool XDRReader::more() const -{ - return _iRead < _nbToRead; -} - -//================================================================================ -/*! - * \brief Go to the nex value - */ -//================================================================================ - -void XDRReader::next() -{ - if ( !more() ) - THROW_IK_EXCEPTION("SauvUtilities::XDRReader::next(): no more() values to read"); - - ++_iRead; - if ( _iRead < _nbToRead ) - { - } - else - { - if(_xdr_kind == _xdr_kind_char) free(_xdr_cvals); - if(_xdr_kind == _xdr_kind_int) free(_xdr_ivals); - if(_xdr_kind == _xdr_kind_double) free(_xdr_dvals); - _xdr_kind = _xdr_kind_null; - } -} - -//================================================================================ -/*! - * \brief Return the current integer value - */ -//================================================================================ - -int XDRReader::getInt() const -{ - if(_iRead < _nbToRead) - { - return _xdr_ivals[_iRead]; - } - else - { - int result = 0; -#ifdef HAS_XDR - xdr_int((XDR*)_xdrs, &result); -#endif - return result; - } -} - -//================================================================================ -/*! - * \brief Return the current float value - */ -//================================================================================ - -float XDRReader::getFloat() const -{ - float result = 0; -#ifdef HAS_XDR - xdr_float((XDR*)_xdrs, &result); -#endif - return result; -} - -//================================================================================ -/*! - * \brief Return the current double value - */ -//================================================================================ - -double XDRReader::getDouble() const -{ - if(_iRead < _nbToRead) - { - return _xdr_dvals[_iRead]; - } - else - { - double result = 0; -#ifdef HAS_XDR - xdr_double((XDR*)_xdrs, &result); -#endif - return result; - } -} - -//================================================================================ -/*! - * \brief Return the current string value - */ -//================================================================================ - -std::string XDRReader::getName() const -{ - int len = _width; - char* s = _xdr_cvals + _iRead*_width; - while (( s[len-1] == ' ' || s[len-1] == 0) && len > 0 ) - len--; - return std::string( s, len ); -} - -//================================================================================ -/*! - * \brief Throw an exception if not all needed data is present - */ -//================================================================================ - -void IntermediateMED::checkDataAvailability() const -{ - if ( _spaceDim == 0 ) - THROW_IK_EXCEPTION("Wrong file format"); // it is the first record in the sauve file - - if ( _groups.empty() ) - THROW_IK_EXCEPTION("No elements have been read"); - - if ( _points.empty() || _nbNodes == 0 ) - THROW_IK_EXCEPTION("Nodes of elements are not filled"); - - if ( _coords.empty() ) - THROW_IK_EXCEPTION("Node coordinates are missing"); - - if ( _coords.size() < _nbNodes * _spaceDim ) - THROW_IK_EXCEPTION("Nodes and coordinates mismatch"); -} - -//================================================================================ -/*! - * \brief Safely adds a new Group - */ -//================================================================================ - -Group* IntermediateMED::addNewGroup(std::vector* groupsToFix) -{ - if ( _groups.size() == _groups.capacity() ) // re-allocation would occure - { - std::vector newGroups( _groups.size() ); - newGroups.push_back( Group() ); - - for ( size_t i = 0; i < _groups.size(); ++i ) - { - // avoid copying _cells - std::vector cells; - cells.swap( _groups[i]._cells ); - newGroups[i] = _groups[i]; - newGroups[i]._cells.swap( cells ); - - // correct pointers to sub-groups - for ( size_t j = 0; j < _groups[i]._groups.size(); ++j ) - { - int iG = _groups[i]._groups[j] - &_groups[0]; - newGroups[i]._groups[j] = & newGroups[ iG ]; - } - } - - // fix given groups - if ( groupsToFix ) - for ( size_t i = 0; i < groupsToFix->size(); ++i ) - if ( (*groupsToFix)[i] ) - { - int iG = (*groupsToFix)[i] - &_groups[0]; - (*groupsToFix)[i] = & newGroups[ iG ]; - } - - // fix field supports - for ( int isNode = 0; isNode < 2; ++isNode ) - { - std::vector& fields = isNode ? _nodeFields : _cellFields; - for ( size_t i = 0; i < fields.size(); ++i ) - { - if ( !fields[i] ) continue; - for ( size_t j = 0; j < fields[i]->_sub.size(); ++j ) - if ( fields[i]->_sub[j]._support ) - { - int iG = fields[i]->_sub[j]._support - &_groups[0]; - fields[i]->_sub[j]._support = & newGroups[ iG ]; - } - if ( fields[i]->_group ) - { - int iG = fields[i]->_group - &_groups[0]; - fields[i]->_group = & newGroups[ iG ]; - } - } - } - - _groups.swap( newGroups ); - } - else - { - _groups.push_back( Group() ); - } - return &_groups.back(); -} - -//================================================================================ -/*! - * \brief Makes ParaMEDMEM::MEDFileData from self - */ -//================================================================================ - -ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS() -{ - MEDCouplingAutoRefCountObjectPtr< MEDFileUMesh > mesh = makeMEDFileMesh(); - MEDCouplingAutoRefCountObjectPtr< MEDFileFields > fields = makeMEDFileFields(mesh); - - MEDCouplingAutoRefCountObjectPtr< MEDFileMeshes > meshes = MEDFileMeshes::New(); - MEDCouplingAutoRefCountObjectPtr< MEDFileData > medData = MEDFileData::New(); - meshes->pushMesh( mesh ); - medData->setMeshes( meshes ); - if ( fields ) medData->setFields( fields ); - - return medData.retn(); -} - -//================================================================================ -/*! - * \brief Creates ParaMEDMEM::MEDFileUMesh from its data - */ -//================================================================================ - -ParaMEDMEM::MEDFileUMesh* IntermediateMED::makeMEDFileMesh() -{ - // check if all needed piles are present - checkDataAvailability(); - - // set long names - setGroupLongNames(); - - // fix element orientation - if ( _spaceDim == 2 || _spaceDim == 1 ) - orientElements2D(); - else if ( _spaceDim == 3 ) - orientElements3D(); - - // process groups - decreaseHierarchicalDepthOfSubgroups(); - eraseUselessGroups(); - //detectMixDimGroups(); - - // assign IDs - _points.numberNodes(); - numberElements(); - - // make the med mesh - - MEDFileUMesh* mesh = MEDFileUMesh::New(); - - DataArrayDouble *coords = getCoords(); - setConnectivity( mesh, coords ); - setGroups( mesh ); - - coords->decrRef(); - - if ( !mesh->getName().c_str() || strlen( mesh->getName().c_str() ) == 0 ) - mesh->setName( "MESH" ); - - return mesh; -} - -//================================================================================ -/*! - * \brief Set long names to groups - */ -//================================================================================ - -void IntermediateMED::setGroupLongNames() -{ - // IMP 0020434: mapping GIBI names to MED names - // set med names to objects (mesh, fields, support, group or other) - - std::set treatedGroups; - - std::list::iterator itGIBItoMED = _listGIBItoMED_mail.begin(); - for (; itGIBItoMED != _listGIBItoMED_mail.end(); itGIBItoMED++) - { - if ( (int)_groups.size() < itGIBItoMED->gibi_id ) continue; - - SauvUtilities::Group & grp = _groups[itGIBItoMED->gibi_id - 1]; - - // if there are several names for grp then the 1st name is the name - // of grp and the rest ones are names of groups referring grp (issue 0021311) - const bool isRefName = !treatedGroups.insert( itGIBItoMED->gibi_id ).second; - if ( !isRefName ) - { - grp._name = _mapStrings[ itGIBItoMED->med_id ]; - } - else if ( !grp._refNames.empty() && grp._refNames.back().empty() ) - { - for ( unsigned i = 0; i < grp._refNames.size(); ++i ) - if ( grp._refNames[i].empty() ) - grp._refNames[i] = _mapStrings[ (*itGIBItoMED).med_id ]; - } - else - { - grp._refNames.push_back( _mapStrings[ (*itGIBItoMED).med_id ]); - } - } -} - -//================================================================================ -/*! - * \brief Set long names to fields - */ -//================================================================================ - -void IntermediateMED::setFieldLongNames(std::set< std::string >& usedNames) -{ - std::list::iterator itGIBItoMED = _listGIBItoMED_cham.begin(); - for (; itGIBItoMED != _listGIBItoMED_cham.end(); itGIBItoMED++) - { - if (itGIBItoMED->gibi_pile == PILE_FIELD) - { - _cellFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id]; - } - else if (itGIBItoMED->gibi_pile == PILE_NODES_FIELD) - { - _nodeFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id]; - } - } // iterate on _listGIBItoMED_cham - - for (itGIBItoMED =_listGIBItoMED_comp.begin(); itGIBItoMED != _listGIBItoMED_comp.end(); itGIBItoMED++) - { - std::string medName = _mapStrings[itGIBItoMED->med_id]; - std::string gibiName = _mapStrings[itGIBItoMED->gibi_id]; - - bool name_found = false; - for ( int isNodal = 0; isNodal < 2 && !name_found; ++isNodal ) - { - std::vector & fields = isNodal ? _nodeFields : _cellFields; - for ( size_t ifi = 0; ifi < fields.size() && !name_found; ifi++) - { - if (medName.find( fields[ifi]->_name + "." ) == 0 ) - { - std::vector& aSubDs = fields[ifi]->_sub; - int nbSub = aSubDs.size(); - for (int isu = 0; isu < nbSub; isu++) - for (int ico = 0; ico < aSubDs[isu].nbComponents(); ico++) - { - if (aSubDs[isu].compName(ico) == gibiName) - { - std::string medNameCompo = medName.substr( fields[ifi]->_name.size() + 1 ); - fields[ifi]->_sub[isu].compName(ico) = medNameCompo; - } - } - } - } - } - } // iterate on _listGIBItoMED_comp - - for ( size_t i = 0; i < _nodeFields.size() ; i++) - usedNames.insert( _nodeFields[i]->_name ); - for ( size_t i = 0; i < _cellFields.size() ; i++) - usedNames.insert( _cellFields[i]->_name ); -} - -//================================================================================ -/*! - * \brief Decrease hierarchical depth of subgroups - */ -//================================================================================ - -void IntermediateMED::decreaseHierarchicalDepthOfSubgroups() -{ - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - for (size_t j = 0; j < grp._groups.size(); ++j ) - { - Group & sub_grp = *grp._groups[j]; - if ( !sub_grp._groups.empty() ) - { - // replace j with its 1st subgroup - grp._groups[j] = sub_grp._groups[0]; - // push back the rest subs - grp._groups.insert( grp._groups.end(), ++sub_grp._groups.begin(), sub_grp._groups.end() ); - } - } - // remove empty sub-_groups - std::vector< Group* > newSubGroups; - newSubGroups.reserve( grp._groups.size() ); - for (size_t j = 0; j < grp._groups.size(); ++j ) - if ( !grp._groups[j]->empty() ) - newSubGroups.push_back( grp._groups[j] ); - if ( newSubGroups.size() < grp._groups.size() ) - grp._groups.swap( newSubGroups ); - } -} - -//================================================================================ -/*! - * \brief Erase _groups that won't be converted - */ -//================================================================================ - -void IntermediateMED::eraseUselessGroups() -{ - // propagate _isProfile=true to sub-groups of composite groups - // for (size_t int i=0; i!=_groups.size(); ++i) - // { - // Group* grp = _groups[i]; - // if ( grp->_isProfile && !grp->_groups.empty() ) - // for (size_t j = 0; j < grp->_groups.size(); ++j ) - // grp->_groups[j]->_isProfile=true; - // } - std::set groups2convert; - // keep not named sub-groups of field supports - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - if ( grp._isProfile && !grp._groups.empty() ) - groups2convert.insert( grp._groups.begin(), grp._groups.end() ); - } - - // keep named groups and their subgroups - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - if ( !grp._name.empty() && !grp.empty() ) - { - groups2convert.insert( &grp ); - groups2convert.insert( grp._groups.begin(), grp._groups.end() ); - } - } - // erase groups that are not in groups2convert and not _isProfile - for (size_t i=0; i!=_groups.size(); ++i) - { - Group* grp = &_groups[i]; - if ( !grp->_isProfile && !groups2convert.count( grp ) ) - { - grp->_cells.clear(); - grp->_groups.clear(); - } - } -} - -//================================================================================ -/*! - * \brief Detect _groups of mixed dimension - */ -//================================================================================ - -void IntermediateMED::detectMixDimGroups() -{ - //hasMixedCells = false; - for ( size_t i=0; i < _groups.size(); ++i ) - { - Group& grp = _groups[i]; - if ( grp._groups.size() < 2 ) - continue; - - // check if sub-groups have different dimension - unsigned dim1 = getDim( &grp ); - for ( size_t j = 1; j < grp._groups.size(); ++j ) - { - unsigned dim2 = getDim( grp._groups[j] ); - if ( dim1 != dim2 ) - { - grp._cells.clear(); - grp._groups.clear(); - if ( !grp._name.empty() ) - std::cout << "Erase a group with elements of different dim |" << grp._name << "|"<< std::endl; - break; - } - } - } -} - -//================================================================================ -/*! - * \brief Fix connectivity of elements in 2D space - */ -//================================================================================ - -void IntermediateMED::orientElements2D() -{ - std::set::const_iterator elemIt, elemEnd; - std::vector< std::pair > swapVec; - - // ------------------------------------ - // fix connectivity of quadratic edges - // ------------------------------------ - std::set& quadEdges = _cellsByType[ INTERP_KERNEL::NORM_SEG3 ]; - if ( !quadEdges.empty() ) - { - elemIt = quadEdges.begin(), elemEnd = quadEdges.end(); - for ( ; elemIt != elemEnd; ++elemIt ) - ConvertQuadratic( INTERP_KERNEL::NORM_SEG3, *elemIt ); - } - - CellsByDimIterator faceIt( *this, 2 ); - while ( const std::set * faces = faceIt.nextType() ) - { - TCellType cellType = faceIt.type(); - bool isQuadratic = getGibi2MedQuadraticInterlace( cellType ); - - getReverseVector( cellType, swapVec ); - - // ------------------------------------ - // fix connectivity of quadratic faces - // ------------------------------------ - if ( isQuadratic ) - for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ ) - ConvertQuadratic( cellType, *elemIt ); - - // -------------------------- - // orient faces clockwise - // -------------------------- - // COMMENTED for issue 0022612 note 17739 - // int iQuad = isQuadratic ? 2 : 1; - // for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ ) - // { - // // look for index of the most left node - // int iLeft = 0, iNode, nbNodes = elemIt->_nodes.size() / iQuad; - // double x, minX = nodeCoords( elemIt->_nodes[0] )[0]; - // for ( iNode = 1; iNode < nbNodes; ++iNode ) - // if (( x = nodeCoords( elemIt->_nodes[ iNode ])[ 0 ]) < minX ) - // minX = x, iLeft = iNode; - - // // indeces of the nodes neighboring the most left one - // int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1; - // int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1; - // // find components of prev-left and left-next vectors - // double xP = nodeCoords( elemIt->_nodes[ iPrev ])[ 0 ]; - // double yP = nodeCoords( elemIt->_nodes[ iPrev ])[ 1 ]; - // double xN = nodeCoords( elemIt->_nodes[ iNext ])[ 0 ]; - // double yN = nodeCoords( elemIt->_nodes[ iNext ])[ 1 ]; - // double xL = nodeCoords( elemIt->_nodes[ iLeft ])[ 0 ]; - // double yL = nodeCoords( elemIt->_nodes[ iLeft ])[ 1 ]; - // double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector - // double xLN = xN - xL, yLN = yN - yL; // components of left-next vector - // // normalise y of the vectors - // double modPL = sqrt ( xPL * xPL + yPL * yPL ); - // double modLN = sqrt ( xLN * xLN + yLN * yLN ); - // if ( modLN > std::numeric_limits::min() && - // modPL > std::numeric_limits::min() ) - // { - // yPL /= modPL; - // yLN /= modLN; - // // summary direction of neighboring links must be positive - // bool clockwise = ( yPL + yLN > 0 ); - // if ( !clockwise ) - // reverse( *elemIt, swapVec ); - // } - // } - } -} - -//================================================================================ -/*! - * \brief Fix connectivity of elements in 3D space - */ -//================================================================================ - -void IntermediateMED::orientElements3D() -{ - // set _reverse flags of faces - // COMMENTED for issue 0022612 note 17739 - //orientFaces3D(); - - // ----------------- - // fix connectivity - // ----------------- - - std::set::const_iterator elemIt, elemEnd; - std::vector< std::pair > swapVec; - - for ( int dim = 1; dim <= 3; ++dim ) - { - CellsByDimIterator cellsIt( *this, dim ); - while ( const std::set * elems = cellsIt.nextType() ) - { - TCellType cellType = cellsIt.type(); - bool isQuadratic = getGibi2MedQuadraticInterlace( cellType ); - getReverseVector( cellType, swapVec ); - - elemIt = elems->begin(), elemEnd = elems->end(); - for ( ; elemIt != elemEnd; elemIt++ ) - { - // GIBI connectivity -> MED one - if( isQuadratic ) - ConvertQuadratic( cellType, *elemIt ); - - // reverse faces - if ( elemIt->_reverse ) - reverse ( *elemIt, swapVec ); - } - } - } - - // COMMENTED for issue 0022612 note 17739 - //orientVolumes(); -} - -//================================================================================ -/*! - * \brief Orient equally (by setting _reverse flag) all connected faces in 3D space - */ -//================================================================================ - -void IntermediateMED::orientFaces3D() -{ - // fill map of links and their faces - std::set faces; - std::map fgm; - std::map > linkFacesMap; - std::map >::iterator lfIt, lfIt2; - - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - if ( !grp._cells.empty() && getDimension( grp._cellType ) == 2 ) - for ( size_t j = 0; j < grp._cells.size(); ++j ) - if ( faces.insert( grp._cells[j] ).second ) - { - for ( size_t k = 0; k < grp._cells[j]->_nodes.size(); ++k ) - linkFacesMap[ grp._cells[j]->link( k ) ].push_back( grp._cells[j] ); - fgm.insert( std::make_pair( grp._cells[j], &grp )); - } - } - // dump linkFacesMap - // for ( lfIt = linkFacesMap.begin(); lfIt!=linkFacesMap.end(); lfIt++) { - // cout<< "LINK: " << lfIt->first.first << "-" << lfIt->first.second << std::endl; - // std::list & fList = lfIt->second; - // std::list::iterator fIt = fList.begin(); - // for ( ; fIt != fList.end(); fIt++ ) - // cout << "\t" << **fIt << fgm[*fIt]->nom << std::endl; - // } - - // Each oriented link must appear in one face only, else a face is reversed. - - std::queue faceQueue; /* the queue contains well oriented faces - whose neighbors orientation is to be checked */ - bool manifold = true; - while ( !linkFacesMap.empty() ) - { - if ( faceQueue.empty() ) - { - assert( !linkFacesMap.begin()->second.empty() ); - faceQueue.push( linkFacesMap.begin()->second.front() ); - } - while ( !faceQueue.empty() ) - { - const Cell* face = faceQueue.front(); - faceQueue.pop(); - - // loop on links of - for ( int i = 0; i < (int)face->_nodes.size(); ++i ) - { - Link link = face->link( i ); - // find the neighbor faces - lfIt = linkFacesMap.find( link ); - int nbFaceByLink = 0; - std::list< const Cell* > ml; - if ( lfIt != linkFacesMap.end() ) - { - std::list & fList = lfIt->second; - std::list::iterator fIt = fList.begin(); - assert( fIt != fList.end() ); - for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) - { - ml.push_back( *fIt ); - if ( *fIt != face ) // wrongly oriented neighbor face - { - const Cell* badFace = *fIt; - // reverse and remove badFace from linkFacesMap - for ( int j = 0; j < (int)badFace->_nodes.size(); ++j ) - { - Link badlink = badFace->link( j ); - if ( badlink == link ) continue; - lfIt2 = linkFacesMap.find( badlink ); - if ( lfIt2 != linkFacesMap.end() ) - { - std::list & ff = lfIt2->second; - std::list::iterator lfIt3 = find( ff.begin(), ff.end(), badFace ); - // check if badFace has been found, - // else we can't erase it - // case of degenerated face in edge - if (lfIt3 != ff.end()) - { - ff.erase( lfIt3 ); - if ( ff.empty() ) - linkFacesMap.erase( lfIt2 ); - } - } - } - badFace->_reverse = true; // reverse - //INFOS_MED( "REVERSE " << *badFace ); - faceQueue.push( badFace ); - } - } - linkFacesMap.erase( lfIt ); - } - // add good neighbors to the queue - Link revLink( link.second, link.first ); - lfIt = linkFacesMap.find( revLink ); - if ( lfIt != linkFacesMap.end() ) - { - std::list & fList = lfIt->second; - std::list::iterator fIt = fList.begin(); - for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) - { - ml.push_back( *fIt ); - if ( *fIt != face ) - faceQueue.push( *fIt ); - } - linkFacesMap.erase( lfIt ); - } - if ( nbFaceByLink > 2 ) - { - if ( manifold ) - { - std::list::iterator ii = ml.begin(); - std::cout << nbFaceByLink << " faces by 1 link:" << std::endl; - for( ; ii!= ml.end(); ii++ ) - std::cout << "in sub-mesh <" << fgm[ *ii ]->_name << "> " << **ii << std::endl; - } - manifold = false; - } - } // loop on links of the being checked face - } // loop on the face queue - } // while ( !linkFacesMap.empty() ) - - if ( !manifold ) - std::cout << " -> Non manifold mesh, faces orientation may be incorrect" << std::endl; -} - -//================================================================================ -/*! - * \brief Orient volumes according to MED conventions: - * normal of a bottom (first) face should be outside - */ -//================================================================================ - -void IntermediateMED::orientVolumes() -{ - std::set::const_iterator elemIt, elemEnd; - std::vector< std::pair > swapVec; - - CellsByDimIterator cellsIt( *this, 3 ); - while ( const std::set * elems = cellsIt.nextType() ) - { - TCellType cellType = cellsIt.type(); - elemIt = elems->begin(), elemEnd = elems->end(); - int nbBottomNodes = 0; - switch ( cellType ) - { - case NORM_TETRA4: - case NORM_TETRA10: - case NORM_PENTA6: - case NORM_PENTA15: - nbBottomNodes = 3; break; - case NORM_PYRA5: - case NORM_PYRA13: - case NORM_HEXA8: - case NORM_HEXA20: - nbBottomNodes = 4; break; - default: continue; - } - getReverseVector( cellType, swapVec ); - - for ( ; elemIt != elemEnd; elemIt++ ) - { - // find a normal to the bottom face - const double* n[4]; - n[0] = nodeCoords( elemIt->_nodes[0]); // 3 bottom nodes - n[1] = nodeCoords( elemIt->_nodes[1]); - n[2] = nodeCoords( elemIt->_nodes[2]); - n[3] = nodeCoords( elemIt->_nodes[nbBottomNodes]); // a top node - double vec01[3]; // vector n[0]-n[1] - vec01[0] = n[1][0] - n[0][0]; - vec01[1] = n[1][1] - n[0][1]; - vec01[2] = n[1][2] - n[0][2]; - double vec02 [3]; // vector n[0]-n[2] - vec02[0] = n[2][0] - n[0][0]; - vec02[1] = n[2][1] - n[0][1]; - vec02[2] = n[2][2] - n[0][2]; - double normal [3]; // vec01 ^ vec02 - normal[0] = vec01[1] * vec02[2] - vec01[2] * vec02[1]; - normal[1] = vec01[2] * vec02[0] - vec01[0] * vec02[2]; - normal[2] = vec01[0] * vec02[1] - vec01[1] * vec02[0]; - // check if the 102 angle is convex - if ( nbBottomNodes > 3 ) - { - const double* n3 = nodeCoords( elemIt->_nodes[nbBottomNodes-1] );// last bottom node - double vec03 [3]; // vector n[0]-n3 - vec03[0] = n3[0] - n[0][0]; - vec03[1] = n3[1] - n[0][1]; - vec03[2] = n3[2] - n[0][2]; - if ( fabs( normal[0]+normal[1]+normal[2] ) <= std::numeric_limits::max() ) // vec01 || vec02 - { - normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03 - normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2]; - normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0]; - } - else - { - double vec [3]; // normal ^ vec01 - vec[0] = normal[1] * vec01[2] - normal[2] * vec01[1]; - vec[1] = normal[2] * vec01[0] - normal[0] * vec01[2]; - vec[2] = normal[0] * vec01[1] - normal[1] * vec01[0]; - double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03 - if ( dot2 < 0 ) // concave -> reverse normal - { - normal[0] *= -1; - normal[1] *= -1; - normal[2] *= -1; - } - } - } - // direction from top to bottom - double tbDir[3]; - tbDir[0] = n[0][0] - n[3][0]; - tbDir[1] = n[0][1] - n[3][1]; - tbDir[2] = n[0][2] - n[3][2]; - - // compare 2 directions: normal and top-bottom - double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2]; - if ( dot < 0. ) // need reverse - reverse( *elemIt, swapVec ); - - } // loop on volumes of one geometry - } // loop on 3D geometry types - -} - -//================================================================================ -/*! - * \brief Assign new IDs to nodes by skipping not used nodes and return their number - */ -//================================================================================ - -int NodeContainer::numberNodes() -{ - int id = 1; - for ( size_t i = 0; i < _nodes.size(); ++i ) - for ( size_t j = 0; j < _nodes[i].size(); ++j ) - if ( _nodes[i][j].isUsed() ) - _nodes[i][j]._number = id++; - return id-1; -} - - -//================================================================================ -/*! - * \brief Assign new IDs to elements - */ -//================================================================================ - -void IntermediateMED::numberElements() -{ - std::set::const_iterator elemIt, elemEnd; - - // numbering _cells of type NORM_POINT1 by node number - { - const std::set& points = _cellsByType[ INTERP_KERNEL::NORM_POINT1 ]; - elemIt = points.begin(), elemEnd = points.end(); - for ( ; elemIt != elemEnd; ++elemIt ) - elemIt->_number = elemIt->_nodes[0]->_number; - } - - // numbering 1D-3D _cells - for ( int dim = 1; dim <= 3; ++dim ) - { - // check if re-numeration is needed (to try to keep elem oreder as in sauve file ) - bool ok = true, renumEntity = false; - CellsByDimIterator cellsIt( *this, dim ); - int prevNbElems = 0; - while ( const std::set * typeCells = cellsIt.nextType() ) - { - TID minNumber = std::numeric_limits::max(), maxNumber = 0; - for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) - { - if ( elemIt->_number < minNumber ) minNumber = elemIt->_number; - if ( elemIt->_number > maxNumber ) maxNumber = elemIt->_number; - } - TID typeSize = typeCells->size(); - if ( typeSize != maxNumber - minNumber + 1 ) - ok = false; - if ( prevNbElems != 0 ) { - if ( minNumber == 1 ) - renumEntity = true; - else if ( prevNbElems+1 != (int)minNumber ) - ok = false; - } - prevNbElems += typeSize; - } - - if ( ok && renumEntity ) // each geom type was numerated separately - { - cellsIt.init( dim ); - prevNbElems = cellsIt.nextType()->size(); // no need to renumber the first type - while ( const std::set * typeCells = cellsIt.nextType() ) - { - for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) - elemIt->_number += prevNbElems; - prevNbElems += typeCells->size(); - } - } - if ( !ok ) - { - int cellID=1; - cellsIt.init( dim ); - while ( const std::set * typeCells = cellsIt.nextType() ) - for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) - elemIt->_number = cellID++; - } - } -} - -//================================================================================ -/*! - * \brief Creates coord array - */ -//================================================================================ - -ParaMEDMEM::DataArrayDouble * IntermediateMED::getCoords() -{ - DataArrayDouble* coordArray = DataArrayDouble::New(); - coordArray->alloc( _nbNodes, _spaceDim ); - double * coordPrt = coordArray->getPointer(); - for ( int i = 0, nb = _points.size(); i < nb; ++i ) - { - Node* n = getNode( i+1 ); - if ( n->isUsed() ) - { - const double* nCoords = nodeCoords( n ); - std::copy( nCoords, nCoords+_spaceDim, coordPrt ); - coordPrt += _spaceDim; - } - } - return coordArray; -} - -//================================================================================ -/*! - * \brief Sets connectivity of elements to the mesh - * \param mesh - mesh to fill in - * \param coords - coordinates that must be shared by all meshes of different dim - */ -//================================================================================ - -void IntermediateMED::setConnectivity( ParaMEDMEM::MEDFileUMesh* mesh, - ParaMEDMEM::DataArrayDouble* coords ) -{ - int meshDim = 0; - - mesh->setCoords( coords ); - - std::set::const_iterator elemIt, elemEnd; - for ( int dim = 3; dim > 0; --dim ) - { - CellsByDimIterator dimCells( *this, dim ); - - int nbOfCells = 0; - while ( const std::set * cells = dimCells.nextType() ) - nbOfCells += cells->size(); - if ( nbOfCells == 0 ) - continue; - - if ( !meshDim ) meshDim = dim; - - MEDCouplingUMesh* dimMesh = MEDCouplingUMesh::New(); - dimMesh->setCoords( coords ); - dimMesh->setMeshDimension( dim ); - dimMesh->allocateCells( nbOfCells ); - - int prevNbCells = 0; - dimCells.init( dim ); - while ( const std::set * cells = dimCells.nextType() ) - { - // fill connectivity array to take into account order of elements in the sauv file - const int nbCellNodes = cells->begin()->_nodes.size(); - std::vector< TID > connectivity( cells->size() * nbCellNodes ); - int * nodalConnOfCell; - for ( elemIt = cells->begin(), elemEnd = cells->end(); elemIt != elemEnd; ++elemIt ) - { - const Cell& cell = *elemIt; - const int index = cell._number - 1 - prevNbCells; - nodalConnOfCell = &connectivity[ index * nbCellNodes ]; - if ( cell._reverse ) - for ( int i = nbCellNodes-1; i >= 0; --i ) - *nodalConnOfCell++ = cell._nodes[i]->_number - 1; - else - for ( int i = 0; i < nbCellNodes; ++i ) - *nodalConnOfCell++ = cell._nodes[i]->_number - 1; - } - prevNbCells += cells->size(); - - // fill dimMesh - TCellType cellType = dimCells.type(); - nodalConnOfCell = &connectivity[0]; - for ( size_t i = 0; i < cells->size(); ++i, nodalConnOfCell += nbCellNodes ) - dimMesh->insertNextCell( cellType, nbCellNodes, nodalConnOfCell ); - } - dimMesh->finishInsertingCells(); - mesh->setMeshAtLevel( dim - meshDim, dimMesh ); - dimMesh->decrRef(); - } -} - -//================================================================================ -/*! - * \brief Fill in the mesh with groups - * \param mesh - mesh to fill in - */ -//================================================================================ - -void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh ) -{ - bool isMeshNameSet = false; - const int meshDim = mesh->getMeshDimension(); - for ( int dim = 0; dim <= meshDim; ++dim ) - { - const int meshDimRelToMaxExt = ( dim == 0 ? 1 : dim - meshDim ); - - std::vector medGroups; - std::vector > refGroups; - for ( size_t i = 0; i < _groups.size(); ++i ) - { - Group& grp = _groups[i]; - if ( (int)getDim( &grp ) != dim && - grp._groups.empty() ) // to allow groups on diff dims - continue; - // convert only named groups or field supports - if ( grp.empty() || (grp._name.empty() && !grp._isProfile )) - continue; - //if ( grp._medGroup ) continue; // already converted - - // sort cells by ID and remember their initial order in the group - TCellToOrderMap cell2order; - unsigned orderInGroup = 0; - std::vector< Group* > groupVec; - if ( grp._groups.empty() ) groupVec.push_back( & grp ); - else groupVec = grp._groups; - for ( size_t iG = 0; iG < groupVec.size(); ++iG ) - { - Group* aG = groupVec[ iG ]; - if ( (int)getDim( aG ) != dim ) - continue; - for ( size_t iC = 0; iC < aG->_cells.size(); ++iC ) - cell2order.insert( cell2order.end(), std::make_pair( aG->_cells[iC], orderInGroup++ )); - } - if ( cell2order.empty() ) - continue; - bool isSelfIntersect = ( orderInGroup != cell2order.size() ); - if ( isSelfIntersect ) // self intersecting group - { - std::ostringstream msg; - msg << "Self intersecting sub-mesh: id = " << i+1 - << ", name = |" << grp._name << "|" << std::endl - << " nb unique elements = " << cell2order.size() << std::endl - << " total nb elements = " << orderInGroup; - if ( grp._isProfile ) - { - THROW_IK_EXCEPTION( msg.str() ); - } - else - { - std::cout << msg.str() << std::endl; - } - } - // create a med group - grp._medGroup = DataArrayInt::New(); - grp._medGroup->setName( grp._name.c_str() ); - grp._medGroup->alloc( cell2order.size(), /*nbOfCompo=*/1 ); - int * idsPtr = grp._medGroup->getPointer(); - TCellToOrderMap::iterator cell2orderIt, cell2orderEnd = cell2order.end(); - for ( cell2orderIt = cell2order.begin(); cell2orderIt != cell2orderEnd; ++cell2orderIt ) - *idsPtr++ = (*cell2orderIt).first->_number - 1; - - // try to set the mesh name - if ( !isMeshNameSet && - dim == meshDim && - !grp._name.empty() && - grp.size() == mesh->getSizeAtLevel( meshDimRelToMaxExt )) - { - mesh->setName( grp._name.c_str() ); - isMeshNameSet = true; - } - if ( !grp._name.empty() ) - { - medGroups.push_back( grp._medGroup ); - } - // set relocation table - setRelocationTable( &grp, cell2order ); - - // Issue 0021311. Use case: a gibi group has references (recorded in pile 1) - // and several names (pile 27) refer (pile 10) to this group. - // We create a copy of this group per each named reference - std::set uniqueNames; - uniqueNames.insert( grp._name ); - for ( unsigned iRef = 0 ; iRef < grp._refNames.size(); ++iRef ) - if ( !grp._refNames[ iRef ].empty() && - uniqueNames.insert( grp._refNames[ iRef ]).second ) // for name uniqueness (23155) - { - refGroups.push_back( grp._medGroup->deepCpy() ); - refGroups.back()->setName( grp._refNames[ iRef ].c_str() ); - medGroups.push_back( refGroups.back() ); - } - } - mesh->setGroupsAtLevel( meshDimRelToMaxExt, medGroups ); - } -} - -//================================================================================ -/*! - * \brief Return true if the group is on all elements and return its relative dimension - */ -//================================================================================ - -bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const -{ - int dim = getDim( grp ); - - int nbElems = 0; - if ( dim == 0 ) - { - nbElems = _nbNodes; - dimRel = 0; - } - else - { - CellsByDimIterator dimCells( *this, dim ); - while ( const std::set * cells = dimCells.nextType() ) - nbElems += cells->size(); - - int meshDim = 3; - for ( ; meshDim > 0; --meshDim ) - { - dimCells.init( meshDim ); - if ( dimCells.nextType() ) - break; - } - dimRel = dim - meshDim; - } - - bool onAll = ( nbElems == grp->size() ); - return onAll; -} - -//================================================================================ -/*! - * \brief Makes fields from own data - */ -//================================================================================ - -ParaMEDMEM::MEDFileFields * IntermediateMED::makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh) -{ - if ( _nodeFields.empty() && _cellFields.empty() ) return 0; - - // set long names - std::set< std::string > usedFieldNames; - setFieldLongNames(usedFieldNames); - - MEDFileFields* fields = MEDFileFields::New(); - - for ( size_t i = 0; i < _nodeFields.size(); ++i ) - setFields( _nodeFields[i], fields, mesh, i+1, usedFieldNames ); - - for ( size_t i = 0; i < _cellFields.size(); ++i ) - setFields( _cellFields[i], fields, mesh, i+1, usedFieldNames ); - - return fields; -} - -//================================================================================ -/*! - * \brief Make med fields from a SauvUtilities::DoubleField - */ -//================================================================================ - -void IntermediateMED::setFields( SauvUtilities::DoubleField* fld, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const TID castemID, - std::set< std::string >& usedFieldNames) -{ - bool sameNbGauss = true; - if ( !fld || !fld->isMedCompatible( sameNbGauss )) return; - - if ( !sameNbGauss ) - fld->splitSubWithDiffNbGauss(); - - // if ( !fld->hasCommonSupport() ): - // each sub makes MEDFileFieldMultiTS - // else: - // unite several subs into a MEDCouplingFieldDouble - - const bool uniteSubs = fld->hasCommonSupport() && sameNbGauss; - if ( !uniteSubs ) - std::cout << "Castem field #" << castemID << " <" << fld->_name - << "> is incompatible with MED format, so we split it into several fields:" << std::endl; - - for ( size_t iSub = 0; iSub < fld->_sub.size(); ) - { - // set field name - if ( !uniteSubs || fld->_name.empty() ) - makeFieldNewName( usedFieldNames, fld ); - - // allocate values - DataArrayDouble * values = DataArrayDouble::New(); - values->alloc( fld->getNbTuples(iSub), fld->_sub[iSub].nbComponents() ); - - // set values - double * valPtr = values->getPointer(); - if ( uniteSubs ) - { - int nbElems = fld->_group->size(); - for ( int elemShift = 0; elemShift < nbElems && iSub < fld->_sub.size(); ) - elemShift += fld->setValues( valPtr, iSub++, elemShift ); - setTS( fld, values, medFields, mesh ); - } - else - { - fld->setValues( valPtr, iSub ); - setTS( fld, values, medFields, mesh, iSub++ ); - - std::cout << fld->_name << " with compoments"; - for ( size_t i = 0; i < (size_t)fld->_sub[iSub-1].nbComponents(); ++i ) - std::cout << " " << fld->_sub[iSub-1]._comp_names[ i ]; - std::cout << std::endl; - } - } -} - -//================================================================================ -/*! - * \brief Store value array of a field into med fields - */ -//================================================================================ - -void IntermediateMED::setTS( SauvUtilities::DoubleField* fld, - ParaMEDMEM::DataArrayDouble* values, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const int iSub) -{ - // treat a field support - const Group* support = fld->getSupport( iSub ); - int dimRel; - const bool onAll = isOnAll( support, dimRel ); - if ( !onAll && support->_name.empty() ) - { - const_cast(support)->_name += "PFL_" + fld->_name; - support->_medGroup->setName( support->_name.c_str() ); - } - - // make and fill a time-stamp - - MEDCouplingFieldDouble * timeStamp = MEDCouplingFieldDouble::New( fld->getMedType( iSub ), - fld->getMedTimeDisc() ); - timeStamp->setName( fld->_name.c_str() ); - timeStamp->setDescription( fld->_description.c_str() ); - // set the mesh - if ( onAll ) - { - MEDCouplingAutoRefCountObjectPtr - < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel ); - timeStamp->setMesh( dimMesh ); - } - else if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_NODES ) - { - DataArrayDouble * coo = mesh->getCoords(); - MEDCouplingAutoRefCountObjectPtr - subCoo = coo->selectByTupleId(support->_medGroup->begin(), - support->_medGroup->end()); - MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > nodeSubMesh = - MEDCouplingUMesh::Build0DMeshFromCoords( subCoo ); - timeStamp->setMesh( nodeSubMesh ); - } - else - { - MEDCouplingAutoRefCountObjectPtr - < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel ); - MEDCouplingAutoRefCountObjectPtr - subMesh = dimMesh->buildPart(support->_medGroup->begin(), - support->_medGroup->end()); - timeStamp->setMesh( subMesh); - } - // set values - for ( size_t i = 0; i < (size_t)fld->_sub[iSub].nbComponents(); ++i ) - values->setInfoOnComponent( i, fld->_sub[iSub]._comp_names[ i ].c_str() ); - timeStamp->setArray( values ); - values->decrRef(); - // set gauss points - if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_GAUSS_PT ) - { - TGaussDef gaussDef( fld->_sub[iSub]._support->_cellType, - fld->_sub[iSub].nbGauss() ); - timeStamp->setGaussLocalizationOnType( fld->_sub[iSub]._support->_cellType, - gaussDef.myRefCoords, - gaussDef.myCoords, - gaussDef.myWeights ); - } - // get a field to add the time-stamp - bool isNewMedField = false; - if ( !fld->_curMedField || fld->_name != fld->_curMedField->getName() ) - { - fld->_curMedField = MEDFileFieldMultiTS::New(); - isNewMedField = true; - } - - // set an order - const int nbTS = fld->_curMedField->getNumberOfTS(); - if ( nbTS > 0 ) - timeStamp->setOrder( nbTS ); - - // add the time-stamp - timeStamp->checkCoherency(); - if ( onAll ) - fld->_curMedField->appendFieldNoProfileSBT( timeStamp ); - else - fld->_curMedField->appendFieldProfile( timeStamp, mesh, dimRel, support->_medGroup ); - timeStamp->decrRef(); - - if ( isNewMedField ) // timeStamp must be added before this - { - medFields->pushField( fld->_curMedField ); - } -} - -//================================================================================ -/*! - * \brief Make a new unique name for a field - */ -//================================================================================ - -void IntermediateMED::makeFieldNewName(std::set< std::string >& usedNames, - SauvUtilities::DoubleField* fld ) -{ - std::string base = fld->_name; - if ( base.empty() ) - { - base = "F_"; - } - else - { - std::string::size_type pos = base.rfind('_'); - if ( pos != std::string::npos ) - base = base.substr( 0, pos+1 ); - else - base += '_'; - } - - int i = 1; - do - { - fld->_name = base + SauvUtilities::toString( i++ ); - } - while( !usedNames.insert( fld->_name ).second ); -} - -//================================================================================ -/*! - * \brief Split sub-components with different nb of gauss points into several sub-components - * \param [in,out] fld - a field to split if necessary - */ -//================================================================================ - -void DoubleField::splitSubWithDiffNbGauss() -{ - for ( size_t iSub = 0; iSub < _sub.size(); ++iSub ) - { - if ( _sub[iSub].isSameNbGauss() ) continue; - - _sub.insert( _sub.begin() + iSub + 1, 1, _Sub_data() ); - _Sub_data & subToSplit = _sub[iSub]; - _Sub_data & subNew = _sub[iSub+1]; - size_t iDiff = 1; - while ( subToSplit._nb_gauss[ 0 ] == subToSplit._nb_gauss[ iDiff ] ) - ++iDiff; - subNew._support = subToSplit._support; - subNew._comp_names.assign( subToSplit._comp_names.begin() + iDiff, - subToSplit._comp_names.end() ); - subNew._nb_gauss.assign ( subToSplit._nb_gauss.begin() + iDiff, - subToSplit._nb_gauss.end() ); - subToSplit._comp_names.resize( iDiff ); - subToSplit._nb_gauss.resize ( iDiff ); - } -} - -//================================================================================ -/*! - * \brief Return a vector ready to fill in - */ -//================================================================================ - -std::vector< double >& DoubleField::addComponent( int nb_values ) -{ - _comp_values.push_back( std::vector< double >() ); - std::vector< double >& res = _comp_values.back(); - res.resize( nb_values ); - return res; -} - -DoubleField::~DoubleField() -{ - if(_curMedField) - _curMedField->decrRef(); -} - -//================================================================================ -/*! - * \brief Returns a supporting group - */ -//================================================================================ - -const Group* DoubleField::getSupport( const int iSub ) const -{ - return _group ? _group : _sub[iSub]._support; -} - -//================================================================================ -/*! - * \brief Return true if each sub-component is a time stamp - */ -//================================================================================ - -bool DoubleField::isMultiTimeStamps() const -{ - if ( _sub.size() < 2 ) - return false; - bool sameSupports = true; - Group* grpp1 = _sub[0]._support;// grpp NOT grp because XDR under Windows defines grp... - for ( size_t i = 1; i < _sub.size() && sameSupports; ++i ) - sameSupports = ( grpp1 == _sub[i]._support ); - - return sameSupports; -} - -//================================================================================ -/*! - * \brief True if the field can be converted into the med field - */ -//================================================================================ - -bool DoubleField::isMedCompatible(bool& sameNbGauss) const -{ - for ( size_t iSub = 0; iSub < _sub.size(); ++iSub ) - { - if ( !getSupport(iSub) || !getSupport(iSub)->_medGroup ) - THROW_IK_EXCEPTION("SauvReader INTERNAL ERROR: NULL field support"); - - sameNbGauss = true; - if ( !_sub[iSub].isSameNbGauss() ) - { - std::cout << "Field <" << _name << "> : different nb of gauss points in components" << std::endl; - sameNbGauss = false; - //return false; - } - } - return true; -} - -//================================================================================ -/*! - * \brief return true if all sub-components has same components and same nbGauss - */ -//================================================================================ - -bool DoubleField::hasSameComponentsBySupport() const -{ - std::vector< _Sub_data >::const_iterator sub_data = _sub.begin(); - const _Sub_data& first_sub_data = *sub_data; - for ( ++sub_data ; sub_data != _sub.end(); ++sub_data ) - { - if ( first_sub_data._comp_names != sub_data->_comp_names ) - return false; // diff names of components - - if ( first_sub_data._nb_gauss != sub_data->_nb_gauss && - first_sub_data._support->_cellType == sub_data->_support->_cellType) - return false; // diff nb of gauss points on same cell type - } - return true; -} - -//================================================================================ -/*! - * \brief Return type of MEDCouplingFieldDouble - */ -//================================================================================ - -ParaMEDMEM::TypeOfField DoubleField::getMedType( const int iSub ) const -{ - using namespace INTERP_KERNEL; - - const Group* grp = hasCommonSupport() ? _group : _sub[iSub]._support; - if ( _sub[iSub].nbGauss() > 1 ) - { - const CellModel& cm = CellModel::GetCellModel( _sub[iSub]._support->_cellType ); - return (int) cm.getNumberOfNodes() == _sub[iSub].nbGauss() ? ON_GAUSS_NE : ON_GAUSS_PT; - } - else - { - return getDim( grp ) == 0 ? ON_NODES : ON_CELLS; - } -} - -//================================================================================ -/*! - * \brief Return TypeOfTimeDiscretization - */ -//================================================================================ - -ParaMEDMEM::TypeOfTimeDiscretization DoubleField::getMedTimeDisc() const -{ - return ONE_TIME; - // NO_TIME = 4, - // ONE_TIME = 5, - // LINEAR_TIME = 6, - // CONST_ON_TIME_INTERVAL = 7 -} - -//================================================================================ -/*! - * \brief Return nb tuples to be used to allocate DataArrayDouble - */ -//================================================================================ - -int DoubleField::getNbTuples( const int iSub ) const -{ - int nb = 0; - if ( hasCommonSupport() && !_group->_groups.empty() ) - for ( size_t i = 0; i < _group->_groups.size(); ++i ) - nb += _sub[i].nbGauss() * _sub[i]._support->size(); - else - nb = _sub[iSub].nbGauss() * getSupport(iSub)->size(); - return nb; -} - -//================================================================================ -/*! - * \brief Store values of a sub-component and return nb of elements in the iSub - */ -//================================================================================ - -int DoubleField::setValues( double * valPtr, const int iSub, const int elemShift ) const -{ - // find values for iSub - int iComp = 0; - for ( int iS = 0; iS < iSub; ++iS ) - iComp += _sub[iS].nbComponents(); - const std::vector< double > * compValues = &_comp_values[ iComp ]; - - // Set values - - const std::vector< unsigned >& relocTable = getSupport( iSub )->_relocTable; - - const int nbElems = _sub[iSub]._support->size(); - const int nbGauss = _sub[iSub].nbGauss(); - const int nbComponents = _sub[iSub].nbComponents(); - const int nbValsByElem = nbComponents * nbGauss; - - // check nb values - int nbVals = 0; - for ( iComp = 0; iComp < nbComponents; ++iComp ) - nbVals += compValues[iComp].size(); - const bool isConstField = ( nbVals == nbComponents ); // one value per component (issue 22321) - if ( !isConstField && nbVals != nbElems * nbValsByElem ) - THROW_IK_EXCEPTION("SauvMedConvertor.cxx: support size mismatches field size"); - - // compute nb values in previous subs - int valsShift = 0; - for ( int iS = iSub-1, shift = elemShift; shift > 0; --iS) - { - int nbE = _sub[iS]._support->size(); - shift -= nbE; - valsShift += nbE * _sub[iS].nbComponents() * _sub[iS].nbGauss(); - } - - if ( isConstField ) - for ( int iE = 0; iE < nbElems; ++iE ) - { - int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift ); - for ( iComp = 0; iComp < nbComponents; ++iComp ) - valPtr[ iMed + iComp ] = compValues[iComp][ 0 ]; - } - else - for ( int iE = 0; iE < nbElems; ++iE ) - { - int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift ); - for ( iComp = 0; iComp < nbComponents; ++iComp ) - for ( int iG = 0; iG < nbGauss; ++iG ) - valPtr[ iMed + iG * nbComponents + iComp ] = compValues[iComp][ iE * nbGauss + iG ]; - } - return nbElems; -} - -//================================================================================ -/*! - * \brief Destructor of IntermediateMED - */ -//================================================================================ - -IntermediateMED::~IntermediateMED() -{ - for ( size_t i = 0; i < _nodeFields.size(); ++i ) - if ( _nodeFields[i] ) - delete _nodeFields[i]; - _nodeFields.clear(); - - for ( size_t i = 0; i < _cellFields.size(); ++i ) - if ( _cellFields[i] ) - delete _cellFields[i]; - _cellFields.clear(); - - for ( size_t i = 0; i < _groups.size(); ++i ) - if ( _groups[i]._medGroup ) - _groups[i]._medGroup->decrRef(); -} - -//================================================================================ -/*! - * \brief CellsByDimIterator constructor - */ -CellsByDimIterator::CellsByDimIterator( const IntermediateMED & medi, int dimm) -{ - myImed = & medi; - init( dimm ); -} -/*! - * \brief Initialize iteration on cells of given dimention - */ -void CellsByDimIterator::init(const int dimm) -{ - myCurType = -1; - myTypeEnd = INTERP_KERNEL::NORM_HEXA20 + 1; - myDim = dimm; -} -/*! - * \brief return next set of Cell's of required dimension - */ -const std::set< Cell > * CellsByDimIterator::nextType() -{ - while ( ++myCurType < myTypeEnd ) - if ( !myImed->_cellsByType[myCurType].empty() && ( myDim < 0 || dim(false) == myDim )) - return & myImed->_cellsByType[myCurType]; - return 0; -} -/*! - * \brief return dimension of cells returned by the last or further next() - */ -int CellsByDimIterator::dim(const bool last) const -{ - int typp = myCurType; - if ( !last ) - while ( typp < myTypeEnd && myImed->_cellsByType[typp].empty() ) - ++typp; - return typp < myTypeEnd ? getDimension( TCellType( typp )) : 4; -} -// END CellsByDimIterator ======================================================== - diff --git a/medtool/src/MEDLoader/SauvMedConvertor.hxx b/medtool/src/MEDLoader/SauvMedConvertor.hxx deleted file mode 100644 index b52cacd0f..000000000 --- a/medtool/src/MEDLoader/SauvMedConvertor.hxx +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvMedConvertor.hxx -// Created : Tue Aug 16 14:14:02 2011 -// Author : Edward AGAPOV (eap) -// - -#ifndef __SauvMedConvertor_HXX__ -#define __SauvMedConvertor_HXX__ - -#include "InterpKernelException.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "SauvUtilities.hxx" - -#include -#include -#include -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class DataArrayInt; - class MEDFileData; - class MEDFileFields; - class MEDFileFieldMultiTS; - class MEDFileUMesh; -} - -namespace SauvUtilities -{ - struct IntermediateMED; - - // ============================================================================== - typedef int TID; // an ID countered from 1 - typedef std::pair Link; // a pair of node numbers - - typedef INTERP_KERNEL::NormalizedCellType TCellType; - - // ============================================================================== - struct Node - { - TID _number; - size_t _coordID; - - Node():_number(0){} - bool isUsed() const { return _number != 0; } - }; - - // ============================================================================== - struct Cell - { - std::vector< Node* > _nodes; - mutable bool _reverse; // to reverse orienation of a face only - mutable TID* _sortedNodeIDs; // for comparison - mutable TID _number; - - Cell(size_t nnNodes=0) : _nodes(nnNodes),_reverse(false),_sortedNodeIDs(0),_number(0) {} - Cell(const Cell& ma); - void init() const { if ( _sortedNodeIDs ) delete [] _sortedNodeIDs; _sortedNodeIDs = 0; } - ~Cell() { init(); } - - const TID* getSortedNodes() const; // creates if needed and return _sortedNodeIDs - bool operator < (const Cell& ma) const; - Link link(int i) const; - - private: - Cell& operator=(const Cell& ma); - }; - std::ostream& operator << (std::ostream& os, const Cell& ma); - - // ============================================================================== - struct Group - { - TCellType _cellType; - std::string _name; - std::vector _cells; - std::vector< Group* > _groups; // des sous-groupes composant le Group - bool _isProfile; // is a field support or not - std::vector _refNames; /* names of groups referring this one; - _refNames is resized according to nb of references - while reading a group (pile 1) and it is filled with - names while reading long names (pile 27); each named - reference is converted into a copy of the medGroup - (issue 0021311) - */ - ParaMEDMEM::DataArrayInt* _medGroup; // result of conversion - std::vector< unsigned > _relocTable; // for _cells[i] gives its index in _medGroup - - bool empty() const { return _cells.empty() && _groups.empty(); } - int size() const; - Group():_cellType(INTERP_KERNEL::NORM_ERROR), _isProfile(false), _medGroup(NULL) {} - }; - - // ============================================================================== - struct DoubleField - { - // a field contains several subcomponents each referring to its own support and - // having several named components - // ---------------------------------------------------------------------------- - struct _Sub_data // a subcomponent - // -------------------------------- - { - Group* _support; // support - std::vector _comp_names; // component names - std::vector _nb_gauss; // nb values per element in a component - - void setData( int nb_comp, Group* supp ) - { _support = supp; _comp_names.resize(nb_comp); _nb_gauss.resize(nb_comp,1); } - int nbComponents() const { return _comp_names.size(); } - std::string & compName( int i_comp ) { return _comp_names[ i_comp ]; } - bool isSameNbGauss() const { return *std::max_element( _nb_gauss.begin(), _nb_gauss.end() ) == - *std::min_element( _nb_gauss.begin(), _nb_gauss.end() ); } - int nbGauss() const { return _nb_gauss[0] ? _nb_gauss[0] : 1; } - bool hasGauss() const { return nbGauss() > 1; } - }; - // ---------------------------------------------------------------------------- - TID _idInFile; - std::string _name; - std::string _description; // field description - std::vector< _Sub_data > _sub; - Group* _group; /* if _group == NULL then each subcomponent makes a - separate med field, else all subcomponents - are converted into timestamps of one med field. - The latter is possible only if nb of components in all subs - is the same and supports of subcomponents do not overlap - */ - std::vector< std::vector< double > > _comp_values; - ParaMEDMEM::MEDFileFieldMultiTS* _curMedField; - - DoubleField( int nb_sub, int total_nb_comp ) - : _sub(nb_sub), _group(NULL), _curMedField(NULL) { _comp_values.reserve( total_nb_comp ); } - ~DoubleField(); - std::vector< double >& addComponent( int nb_values ); // return a vector ready to fill in - bool hasCommonSupport() const { return _group; } // true if there is one support for all subs - bool hasSameComponentsBySupport() const; - - bool isMultiTimeStamps() const; - bool isMedCompatible(bool& sameNbGauss) const; - ParaMEDMEM::TypeOfField getMedType( const int iSub=0 ) const; - ParaMEDMEM::TypeOfTimeDiscretization getMedTimeDisc() const; - int getNbTuples( const int iSub=0 ) const; - int getNbValuesPerElement( const int iSub=0 ) const; - int getNbGauss( const int iSub=0 ) const; - const Group* getSupport( const int iSub=0 ) const; - int setValues( double * valPtr, const int iSub, const int elemShift=0 ) const; - void splitSubWithDiffNbGauss(); - - //virtual void dump(std::ostream&) const; - //virtual ~DoubleField() {} - }; - // ============================================================================== - /*! - * \if developper - * Iterator on set of Cell's of given dimension - * \endif - */ - class CellsByDimIterator - { - public: - CellsByDimIterator( const IntermediateMED & medi, int dim=-1); // dim=-1 - for all dimensions - void init(const int dim=-1); - - //!< return next set of Cell's of required dimension - const std::set * nextType(); - //!< return dimension of Cell's returned by the last or further next() - int dim(const bool last=true) const; - //!< return type of Cell's returned by the last next() - TCellType type() const { return TCellType( myCurType ); } - - private: - const IntermediateMED* myImed; - int myCurType, myTypeEnd; - int myDim; - }; - - // ============================================================================== - /*! - * \if developper - * Container of Node's. Prevents re-allocation at addition of Node's - * \endif - */ - class NodeContainer - { - std::vector< std::vector< Node > > _nodes; - public: - Node* getNode( const TID nID ) - { - const size_t chunkSize = 1000; - const size_t chunkID = (nID-1) / chunkSize; - const size_t pos = (nID-1) % chunkSize; - if ( _nodes.size() < chunkID+1 ) - { - std::vector< std::vector< Node > > newNodes(chunkID+1); - for ( size_t i = 0; i < _nodes.size(); ++i ) - newNodes[i].swap( _nodes[i] ); - for ( size_t i = _nodes.size(); i < newNodes.size(); ++i ) - newNodes[i].resize( chunkSize ); - _nodes.swap( newNodes ); - } - return & _nodes[chunkID][pos]; - } - bool empty() const { return _nodes.empty(); } - size_t size() const { return empty() ? 0 : _nodes.size() * _nodes[0].size(); } - int numberNodes(); - }; - - // ============================================================================== - /*! - * \if developper - * Intermediate structure used to store data read from the Sauve format file. - * The structure provides functions that transform the stored data to the MED format - * - * The elements inserted in maillage are ordered in order to avoid duplicated elements. - * \endif - */ - struct IntermediateMED - { - unsigned _spaceDim; - unsigned _nbNodes; - NodeContainer _points; - std::vector _coords; - std::vector _groups; - std::vector _nodeFields; - std::vector _cellFields; - - // IMP 0020434: mapping GIBI names to MED names - std::list _listGIBItoMED_mail; // to read from table "MED_MAIL" of PILE_TABLES - std::list _listGIBItoMED_cham; // to read from table "MED_CHAM" of PILE_TABLES - std::list _listGIBItoMED_comp; // to read from table "MED_COMP" of PILE_TABLES - std::map _mapStrings; // to read from PILE_STRINGS - - IntermediateMED(): _spaceDim(0), _nbNodes(0) {} - ~IntermediateMED(); - - Node* getNode( TID nID ) { return _points.getNode( nID ); } - int getNbCellsOfType( TCellType type ) const { return _cellsByType[type].size(); } - const Cell* insert(TCellType type, const Cell& ma) { return &( *_cellsByType[type].insert( ma ).first ); } - Group* addNewGroup(std::vector* groupsToFix=0); - ParaMEDMEM::MEDFileData* convertInMEDFileDS(); - - private: - - ParaMEDMEM::MEDFileUMesh* makeMEDFileMesh(); - ParaMEDMEM::DataArrayDouble * getCoords(); - void setConnectivity( ParaMEDMEM::MEDFileUMesh* mesh, ParaMEDMEM::DataArrayDouble* coords ); - void setGroups( ParaMEDMEM::MEDFileUMesh* mesh ); - ParaMEDMEM::MEDFileFields * makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh); - void setFields( SauvUtilities::DoubleField* fld, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const TID castemID, - std::set< std::string >& usedNames); - void setTS( SauvUtilities::DoubleField* fld, - ParaMEDMEM::DataArrayDouble* values, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const int iSub=0); - void checkDataAvailability() const; - void setGroupLongNames(); - void setFieldLongNames(std::set< std::string >& usedNames); - void makeFieldNewName(std::set< std::string >& usedNames, - SauvUtilities::DoubleField* fld ); - void decreaseHierarchicalDepthOfSubgroups(); - void eraseUselessGroups(); - void detectMixDimGroups(); - void orientElements2D(); - void orientElements3D(); - void orientFaces3D(); - void orientVolumes(); - void numberElements(); - bool isOnAll( const Group* grp, int & dimRel ) const; - const double* nodeCoords( const Node* n ) { return &_coords[ (n->_coordID-1) * _spaceDim ]; } - - // IntermediateMED() - // { myNodesNumerated = myMaillesNumerated = myGroupsTreated = false; currentTypeMailles = 0; } - // ~IntermediateMED(); - - //bool myNodesNumerated, myMaillesNumerated; - - // mailles groupped by geom type; use insert() for filling in and - // _CellsByDimIterator for exploring it - //std::set<_Cell> maillage; - std::set< Cell > _cellsByType[ INTERP_KERNEL::NORM_HEXA20 + 1 ]; - friend class CellsByDimIterator; - }; - -// ============================================================================== - /*! - * \brief ASCII sauve file reader - */ - class ASCIIReader : public FileReader - { - public: - ASCIIReader(const char* fileName); - virtual ~ASCIIReader(); - virtual bool isASCII() const; - virtual bool open(); - virtual bool getNextLine (char* & line, bool raiseOEF = true ); - virtual void initNameReading(int nbValues, int width = 8); - virtual void initIntReading(int nbValues); - virtual void initDoubleReading(int nbValues); - virtual bool more() const; - virtual void next(); - virtual int getInt() const; - virtual float getFloat() const; - virtual double getDouble() const; - virtual std::string getName() const; - int lineNb() const { return _lineNb; } - - private: - - bool getLine(char* & line); - void init( int nbToRead, int nbPosInLine, int width, int shift = 0 ); - - // getting a line from the file - int _file; - char* _start; // working buffer beginning - char* _ptr; - char* _eptr; - int _lineNb; - - // line parsing - int _iPos, _nbPosInLine, _width, _shift; - char* _curPos; - }; -// ============================================================================== - /*! - * \brief XDR (binary) sauve file reader - */ - class XDRReader : public FileReader - { - public: - XDRReader(const char* fileName); - virtual ~XDRReader(); - virtual bool isASCII() const; - virtual bool open(); - virtual bool getNextLine (char* & line, bool raiseOEF = true ); - virtual void initNameReading(int nbValues, int width = 8); - virtual void initIntReading(int nbValues); - virtual void initDoubleReading(int nbValues); - virtual bool more() const; - virtual void next(); - virtual int getInt() const; - virtual float getFloat() const; - virtual double getDouble() const; - virtual std::string getName() const; - - private: - - void init( int nbToRead, int width = 0 ); - - FILE* _xdrs_file; - void* _xdrs; - int* _xdr_ivals; - double* _xdr_dvals; - char* _xdr_cvals; - int _width; - int _xdr_kind; - enum - { - _xdr_kind_null, - _xdr_kind_char, - _xdr_kind_int, - _xdr_kind_double - }; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/SauvReader.cxx b/medtool/src/MEDLoader/SauvReader.cxx deleted file mode 100644 index 77c7c4f21..000000000 --- a/medtool/src/MEDLoader/SauvReader.cxx +++ /dev/null @@ -1,1216 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvReader.cxx -// Created : Tue Aug 16 13:57:42 2011 -// Author : Edward AGAPOV (eap) -// - -#include "SauvReader.hxx" - -#include "SauvMedConvertor.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingRefCountObject.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; -using namespace SauvUtilities; -using namespace std; - -#define GIBI_EQUAL(var_str, stat_str) (strncmp (var_str, stat_str, strlen(stat_str)) == 0) - -//================================================================================ -/*! - * \brief Creates a reader of a given sauve file - */ -//================================================================================ - -SauvReader* SauvReader::New(const std::string& fileName) -{ - if ( fileName.empty() ) THROW_IK_EXCEPTION("Invalid file name"); - - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr< SauvUtilities::FileReader> parser; - - // try to open as XRD - parser = new XDRReader( fileName.c_str() ); - if ( parser->open() ) - { - SauvReader* reader = new SauvReader; - reader->_fileReader = parser.retn(); - return reader; - } - - // try to open as ASCII - parser = new ASCIIReader( fileName.c_str() ); - if ( parser->open() ) - { - SauvReader* reader = new SauvReader; - reader->_fileReader = parser.retn(); - return reader; - } - - THROW_IK_EXCEPTION("Unable to open file |"<< fileName << "|"); -} -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -SauvReader::~SauvReader() -{ - _fileReader->decrRef(); -} - -std::size_t SauvReader::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector SauvReader::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -//================================================================================ -/*! - * \brief Return current line of ASCII file to report an error - */ -//================================================================================ - -std::string SauvReader::lineNb() const -{ - if ( isASCII() ) - return string(" (line #") + SauvUtilities::toString - ( static_cast( _fileReader )->lineNb() ) + ")"; - - return ""; -} - -//================================================================================ -/*! - * \brief Reads contents of the sauve file and convert it to MEDFileData - */ -//================================================================================ - -ParaMEDMEM::MEDFileData * SauvReader::loadInMEDFileDS() -{ - SauvUtilities::IntermediateMED iMed; // intermadiate DS - _iMed = &iMed; - - char* line; // a current line - const char* enregistrement_type=" ENREGISTREMENT DE TYPE"; - - while ( getNextLine(line, /*raiseOEF=*/false)) // external loop looking for "ENREGISTREMENT DE TYPE" - { - if ( isASCII() && !GIBI_EQUAL( line, enregistrement_type )) - continue; // "ENREGISTREMENT DE TYPE" not found -> read the next line - - // read the number of a record - int recordNumber; - if ( isASCII() ) - recordNumber = atoi( line + strlen(enregistrement_type) + 1 ); - else - recordNumber = getInt(); - - // read the record - if ( recordNumber == 2 ) - readRecord2(); - else if (recordNumber == 4 ) - readRecord4(); - else if (recordNumber == 7 ) - readRecord7(); - else if (recordNumber == 5 ) - break; // stop reading - else - if ( !isASCII() ) - THROW_IK_EXCEPTION("XDR : ENREGISTREMENT DE TYPE " << recordNumber << " not implemented!!!"); - } - - ParaMEDMEM::MEDFileData* medFileData = iMed.convertInMEDFileDS(); - - return medFileData; -} - -//================================================================================ -/*! - * \brief Reads "ENREGISTREMENT DE TYPE 4" - */ -//================================================================================ - -void SauvReader::readRecord4() -{ - if ( !isASCII() ) - { - getInt(); // skip NIVEAU - getInt(); // skip ERREUR - _iMed->_spaceDim = getInt(); - getFloat(); // skip DENSITE - } - else - { - char* line; - getNextLine(line); - const char* s = " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION"; - _iMed->_spaceDim = atoi( line + strlen( s ) + 1 ); - if ( !GIBI_EQUAL( line, " NIVEAU" )) - THROW_IK_EXCEPTION( "Could not read space dimension" << lineNb() ); - } - if ( _iMed->_spaceDim < 1 ) - THROW_IK_EXCEPTION( "Invalid space dimension:" << _iMed->_spaceDim ); -} - -//================================================================================ -/*! - * \brief Reads "ENREGISTREMENT DE TYPE 7" - */ -//================================================================================ - -void SauvReader::readRecord7() -{ - if ( !isASCII() ) - { - getInt(); // skip NOMBRE INFO CASTEM2000 - getInt(); // skip IFOUR - getInt(); // skip NIFOUR - getInt(); // skip IFOMOD - getInt(); // skip IECHO - getInt(); // skip IIMPI - getInt(); // skip IOSPI - getInt(); // skip ISOTYP - getInt(); // skip NSDPGE - } - else - { - // skip 3 lines: - // NOMBRE INFO CASTEM2000 8 - // IFOUR 2 NIFOUR 0 IFOMOD 2 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1 - // NSDPGE 0 - char* line; - getNextLine(line); - getNextLine(line); - getNextLine(line); - } -} - -//================================================================================ -/*! - * \brief Reads the pile number, nb of objects and nb named of objects - */ -//================================================================================ - -int SauvReader::readPileNumber(int& nbNamedObjects, int& nbObjects) -{ - // FORMAT(' PILE NUMERO',I4,'NBRE ObjectS NOMMES',I8,'NBRE ObjectS',I8) - int pileNumber; - if ( !isASCII() ) - { - initIntReading(3); - pileNumber = getInt(); next(); - nbNamedObjects = getInt(); next(); - nbObjects = getInt(); next(); - } - else - { - char* line; - getNextLine(line); - const char *s1 = " PILE NUMERO", *s2 = "NBRE ObjectS NOMMES", *s3 = "NBRE ObjectS"; - if ( ! GIBI_EQUAL( line, s1 ) ) - THROW_IK_EXCEPTION("Could not read the pile number " << lineNb() ); - line = line + strlen(s1); - pileNumber = atoi( line ); - line = line + 4 + strlen(s2); - nbNamedObjects = atoi( line ); - line = line + 8 + strlen(s3); - nbObjects = atoi( line ); - } - if ( nbNamedObjects<0 ) - THROW_IK_EXCEPTION("Invalid nb of named objects: " << nbNamedObjects << lineNb() ); - if ( nbObjects<0) - THROW_IK_EXCEPTION("Invalid nb of objects: " << nbObjects << lineNb() ); - // It appears to be a valid case - // if ( nbObjects_spaceDim == 0 ) - THROW_IK_EXCEPTION("Missing ENREGISTREMENT DE TYPE 4"); - - // read a pile number - int pileNumber, nbNamedObjects, nbObjects; - pileNumber = readPileNumber(nbNamedObjects, nbObjects); - - if ( !_encounteredPiles.insert( pileNumber ).second && // piles may repeat - isASCII()) - return; - - // read object names and their indices - vector objectNames(nbNamedObjects); - for ( initNameReading( nbNamedObjects ); more(); next() ) - objectNames[ index() ] = getName(); - - vector nameIndices(nbNamedObjects); - for ( initIntReading( nbNamedObjects ); more(); next() ) - nameIndices[ index() ] = getInt(); - - switch ( pileNumber ) - { - case PILE_SOUS_MAILLAGE: - read_PILE_SOUS_MAILLAGE(nbObjects, objectNames, nameIndices); - break; - case PILE_NODES_FIELD: - read_PILE_NODES_FIELD(nbObjects, objectNames, nameIndices); - break; - case PILE_TABLES: - read_PILE_TABLES(nbObjects, objectNames, nameIndices); - break; - case PILE_LREEL: - read_PILE_LREEL(nbObjects, objectNames, nameIndices); - break; - case PILE_LOGIQUES: - read_PILE_LOGIQUES(nbObjects, objectNames, nameIndices); - break; - case PILE_FLOATS: - read_PILE_FLOATS(nbObjects, objectNames, nameIndices); - break; - case PILE_INTEGERS: - read_PILE_INTEGERS(nbObjects, objectNames, nameIndices); - break; - case PILE_STRINGS: - read_PILE_STRINGS(nbObjects, objectNames, nameIndices); - break; - case PILE_LMOTS: - read_PILE_LMOTS(nbObjects, objectNames, nameIndices); - break; - case PILE_NOEUDS: - read_PILE_NOEUDS(nbObjects, objectNames, nameIndices); - break; - case PILE_COORDONNEES: - read_PILE_COORDONNEES(nbObjects, objectNames, nameIndices); - break; - case PILE_MODL: - read_PILE_MODL(nbObjects, objectNames, nameIndices); - break; - case PILE_FIELD: - read_PILE_FIELD(nbObjects, objectNames, nameIndices); - break; - default: - if ( !isASCII() ) - THROW_IK_EXCEPTION("XDR : reading PILE " << pileNumber << " not implemented !!!"); - } -} - -//================================================================================ -/*! - * \brief Reads "PILE NUMERO 1": gibi sub-meshes that are converted into med groups - */ -//================================================================================ - -void SauvReader::read_PILE_SOUS_MAILLAGE(const int nbObjects, - std::vector& objectNames, - std::vector& nameIndices) -{ - _iMed->_groups.reserve(nbObjects*2); // fields may add some groups - - char* line; - map strangeGroupType; - int i; - - for (int object=0; object!=nbObjects; ++object) // loop on sub-groups - { - initIntReading( 5 ); - int castemCellType = getIntNext(); - int nbSubGroups = getIntNext(); - int nbReferences = getIntNext(); - int nbNodesPerElem = getIntNext(); - int nbElements = getIntNext(); - - _iMed->_groups.push_back(Group()); - SauvUtilities::Group & group = _iMed->_groups.back(); - - // Issue 0021311. Allocate places for names of referring groups - // that will be possibly filled after reading long names from - // PILE_TABLES and PILE_STRINGS - group._refNames.resize( nbReferences ); - - // castemCellType=0 corresponds to a sub-mesh composed of other sub-meshes - if (castemCellType==0 && nbSubGroups>0) - { - group._groups.resize( nbSubGroups ); - for ( initIntReading( nbSubGroups ); more(); next() ) - group._groups[ index() ] = & _iMed->_groups[ getInt() - 1 ]; - //std::sort( group._groups.begin(), group._groups.end() ); // for _groups comparison in getFieldSupport() - } - // skip references - if ( isASCII() ) - for ( i = 0; i < nbReferences; i += 10 ) // FORMAT(10I8) - getNextLine(line); - else - for (initIntReading(nbReferences); more(); next()); - - // skip colors - if ( isASCII() ) - for ( i = 0; i < nbElements; i += 10 ) - getNextLine(line); - else - for (initIntReading(nbElements); more(); next()); - - // not a composite group - if (castemCellType>0 && nbSubGroups==0) - { - group._cellType = SauvUtilities::gibi2medGeom(castemCellType); - - initIntReading( nbElements * nbNodesPerElem ); - if ( group._cellType == INTERP_KERNEL::NORM_ERROR ) // look for group end - { - for ( ; more(); next()); - strangeGroupType.insert( make_pair( object, castemCellType )); - } - else - { - // if ( group._cellType == MED_POINT1 ) group._cellType = NORM_ERROR; // issue 21199 - - // read connectivity of elements of a group - SauvUtilities::Cell ma( nbNodesPerElem ); - SauvUtilities::Node* pNode; - group._cells.resize( nbElements ); - for ( i = 0; i < nbElements; ++i ) - { - ma.init(); - for ( int n = 0; n < nbNodesPerElem; ++n ) - { - int nodeID = getIntNext(); - pNode = _iMed->getNode( nodeID ); - ma._nodes[n] = pNode; - _iMed->_nbNodes += ( !pNode->isUsed() ); - pNode->_number = nodeID; - } - ma._number = _iMed->getNbCellsOfType( group._cellType ) + 1; - group._cells[i] = _iMed->insert( group._cellType, ma ); - } - } - } - } // loop on groups - - // set group names - for (i=0; i!=(int)objectNames.size(); ++i) - { - int grpID = nameIndices[i]; - SauvUtilities::Group & grp = _iMed->_groups[ grpID-1 ]; - if ( !grp._name.empty() ) // a group has several names - { // create a group with subgroup grp and named grp.name - SauvUtilities::Group* newGroup = _iMed->addNewGroup(); - newGroup->_groups.push_back( &_iMed->_groups[ grpID-1 ]); - newGroup->_name = grp._name; - } - grp._name=objectNames[i]; -#ifdef _DEBUG - map::iterator it = strangeGroupType.find( grpID - 1 ); - if ( it != strangeGroupType.end() ) - cout << "Skip " << grp._name << " of not supported CASTEM type: " << it->second << endl; -#endif - } -} // read_PILE_SOUS_MAILLAGE() - -//================================================================================ -/*! - * \brief Skip "PILE NUMERO 18" of XDR file - */ -//================================================================================ - -void SauvReader::read_PILE_LREEL (const int nbObjects, std::vector&, std::vector&) -{ - if ( isXRD() ) - { - for (int object=0; object!=nbObjects; ++object) // pour chaque Group - { - initIntReading(1); - int nb_vals = getIntNext(); - initDoubleReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - initIntReading(1); - int nb_vals = getIntNext(); - initIntReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - initIntReading(1); - int nb_vals = getIntNext(); - initDoubleReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - initIntReading(1); - int nb_vals = getIntNext(); - initIntReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - for (int object=0; object!=nbObjects; ++object) // pour chaque Group - { - initIntReading(2); - int len = getIntNext(); - int nb_vals = getIntNext(); - int nb_char = len*nb_vals; - int nb_char_tmp = 0; - int fixed_length = 71; - while (nb_char_tmp < nb_char) - { - int remain_len = nb_char - nb_char_tmp; - int width; - if ( remain_len > fixed_length ) - { - width = fixed_length; - } - else - { - width = remain_len; - } - initNameReading(1, width); - next(); - nb_char_tmp += width; - } - } - } -} - -//================================================================================ -/*! - * \brief Skip "PILE NUMERO 38" of XDR file - */ -//================================================================================ - -void SauvReader::read_PILE_MODL (const int nbObjects, std::vector&, std::vector&) -{ - if ( isXRD() ) - { - for (int object=0; object!=nbObjects; ++object) // pour chaque Group - { - // see wrmodl.eso - initIntReading(10); - int n1 = getIntNext(); - int nm2 = getIntNext(); - int nm3 = getIntNext(); - int nm4 = getIntNext(); - int nm5 = getIntNext(); - int n45 = getIntNext(); - /*int nm6 =*/ getIntNext(); - /*int nm7 =*/ getIntNext(); - next(); - next(); - int nm1 = n1 * n45; - int nm9 = n1 * 16; - for (initIntReading(nm1); more(); next()); - for (initIntReading(nm9); more(); next()); - for (initNameReading(nm5, 8); more(); next()); - for (initNameReading(nm2, 8); more(); next()); - for (initNameReading(nm3, 8); more(); next()); - for (initIntReading(nm4); more(); next()); - } - } -} // Fin case pile 38 - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 32": links to node coordinates - */ -//================================================================================ - -void SauvReader::read_PILE_NOEUDS (const int nbObjects, std::vector&, std::vector&) -{ - initIntReading(1); - int nb_indices = getIntNext(); - - if (nb_indices != nbObjects) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_NOEUDS << lineNb() ); - - for ( initIntReading( nbObjects ); more(); next() ) - { - int coordID = getInt(); - _iMed->getNode( index()+1 )->_coordID = coordID; - } -} - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 33": node coordinates - */ -//================================================================================ - -void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector&, std::vector&) -{ - initIntReading(1); - int nbReals = getIntNext(); - - if ( nbReals < (int)(_iMed->_nbNodes*(_iMed->_spaceDim+1)) ) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_COORDONNEES << lineNb() ); - - // there are coordinates + density for each node - _iMed->_coords.resize( nbReals - nbReals/(_iMed->_spaceDim+1)); - double* coordPtr = &_iMed->_coords[0]; - - initDoubleReading( nbReals ); - while ( more() ) - { - for (unsigned j = 0; j < _iMed->_spaceDim; ++j, next()) - *coordPtr++ = getDouble(); - // skip density - getDouble(); - next(); - } -} - -//================================================================================ -/*! - * \brief Find or create a Group equal to a given field support - */ -//================================================================================ - -void SauvReader::setFieldSupport(const vector& supports, - SauvUtilities::DoubleField* field) -{ - SauvUtilities::Group* group = NULL; - set sup_set( supports.begin(), supports.end() ); - if ( sup_set.size() == 1 ) // one or equal supports - { - group = supports[0]; - } - else - { - // check if sub-components are on cells of different types - map nbGaussByCellType; - for ( size_t i = 0; i < supports.size(); ++i ) - { - map::iterator ct2ng = nbGaussByCellType.find( supports[i]->_cellType ); - if ( ct2ng == nbGaussByCellType.end() ) - nbGaussByCellType[ supports[i]->_cellType ] = field->_sub[i].nbGauss(); - else if ( ct2ng->second != field->_sub[i].nbGauss() ) - return; - } - bool isSameCellType = ( nbGaussByCellType.size() == 1 ); - // try to find an existing composite group with the same sub-groups - if ( isSameCellType ) - for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i ) - { - Group & grp = _iMed->_groups[i]; - if (sup_set.size() == grp._groups.size()) - { - bool sameOrder = true; - for ( size_t j = 0; j < supports.size() && sameOrder; ++j ) - sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]); - if ( sameOrder ) - group = & _iMed->_groups[i]; - } - } - if ( !group ) // no such a group, add a new one - { - vector newGroups( supports.begin(), - supports.begin() + sup_set.size() ); - // check if supports includes newGroups in the same order - bool sameOrder = true; - for ( size_t j = newGroups.size(); j < supports.size() && sameOrder; ++j ) - sameOrder = ( supports[j] == newGroups[ j % newGroups.size() ]); - if ( sameOrder ) - { - group = _iMed->addNewGroup( & newGroups ); - group->_groups.swap( newGroups ); - } - } - // sort field sub-components and supports by cell type - if ( group && !isSameCellType ) - { - // sort groups - vector& groups = group->_groups; - bool isModified = false, isSwapped = true; - while ( isSwapped ) - { - isSwapped = false; - for ( size_t i = 1; i < groups.size(); ++i ) - { - int nbN1 = groups[i-1]->empty() ? 0 : groups[i-1]->_cells[0]->_nodes.size(); - int nbN2 = groups[i ]->empty() ? 0 : groups[i ]->_cells[0]->_nodes.size(); - if ( nbN1 > nbN2 ) - { - isSwapped = isModified = true; - std::swap( groups[i], groups[i-1] ); - } - } - } - // relocate sub-components according to a new order of groups - if ( isModified ) - { - vector< DoubleField::_Sub_data > newSub ( field->_sub.size() ); - vector< vector< double > > newValues( field->_comp_values.size() ); - size_t iFromSub = 0, iNewSub = 0, iNewComp = 0; - for ( ; iFromSub < field->_sub.size(); iFromSub += groups.size() ) - { - size_t iFromComp = iNewComp; - for ( size_t iG = 0; iG < groups.size(); ++iG ) - { - size_t iComp = iFromComp; - for ( size_t iSub = iFromSub; iSub < field->_sub.size(); ++iSub ) - if ( field->_sub[ iSub ]._support == groups[ iG ] ) - { - newSub[ iNewSub++ ] = field->_sub[ iSub ]; - int iC = 0, nbC = field->_sub[ iSub ].nbComponents(); - for ( ; iC < nbC; ++iC ) - newValues[ iNewComp++ ].swap( field->_comp_values[ iComp++ ]); - break; - } - else - { - iComp += field->_sub[ iSub ].nbComponents(); - } - } - } - field->_sub.swap( newSub ); - field->_comp_values.swap( newValues ); - } - } - } - if ( group ) - group->_isProfile = true; - - field->_group = group; -} - -//================================================================================ -/*! - * \brief Set field names - */ -//================================================================================ - -void SauvReader::setFieldNames(const vector& fields, - const vector& objets_nommes, - const vector& indices_objets_nommes) -{ - unsigned i; - for ( i = 0; i < indices_objets_nommes.size(); ++i ) - { - int fieldIndex = indices_objets_nommes[ i ]; - if ( fields[ fieldIndex - 1 ] ) - fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ]; - } -} - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 2": NODE FIELDS - */ -//================================================================================ - -void SauvReader::read_PILE_NODES_FIELD (const int nbObjects, - std::vector& objectNames, - std::vector& nameIndices) -{ - _iMed->_nodeFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 ); - for (int object=0; object!=nbObjects; ++object) // loop on fields - { - // EXAMPLE ( with no values ) - - // (1) 4 7 2 1 - // (2) -88 0 3 -89 0 1 -90 0 2 -91 - // (2) 0 1 - // (3) FX FY FZ FZ FX FY FLX - // (4) 0 0 0 0 0 0 0 - // (5) cree par muc pri - // (6) - // (7) 2 - - // (1): nb subcomponents, nb components(total), IFOUR, nb attributes - int nb_sub, total_nb_comp, nb_attr; - int i_sub, i_comp; - initIntReading( 4 ); - nb_sub = getIntNext(); - total_nb_comp = getIntNext(); - next(); // ignore IFOUR - nb_attr = getIntNext(); - if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 ) - THROW_IK_EXCEPTION("Error of field reading " << lineNb()); - - // (2) loop on subcomponents of a field, for each read - // (a) support, (b) number of values and (c) number of components - vector supports( nb_sub ); - vector nb_values ( nb_sub ); - vector nb_comps ( nb_sub ); - int total_nb_values = 0; - initIntReading( nb_sub * 3 ); - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { - int supId = -getIntNext(); // (a) reference to support - if ( supId < 1 || supId > (int)_iMed->_groups.size() ) - THROW_IK_EXCEPTION("Wrong mesh reference: "<< supId << lineNb() ); - supports[ i_sub ] = &_iMed->_groups[ supId-1 ]; // (a) reference to support - - nb_values[ i_sub ] = getIntNext(); // (b) nb points - total_nb_values += nb_values[ i_sub ]; - if ( nb_values[ i_sub ] < 0 ) - THROW_IK_EXCEPTION(" Wrong nb of points: " << nb_values[ i_sub ] << lineNb() ); - nb_comps[ i_sub ] = getInt(); next(); // (c) nb of components in i_sub - } - - // create a field if there are values - SauvUtilities::DoubleField* fdouble = 0; - if ( total_nb_values > 0 ) - fdouble = new DoubleField( nb_sub, total_nb_comp ); - _iMed->_nodeFields[ object ] = fdouble; - - // (3) component names - initNameReading( total_nb_comp, 4 ); - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { - // store support id and nb components of a sub - if ( fdouble ) - fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], supports[ i_sub ] ); - for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() ) - { - // store component name - string compName = getName(); - if ( fdouble ) - fdouble->_sub[ i_sub ].compName( i_comp ) = compName; - } - } - // (4) nb harmonics ( ignored ) - for ( initIntReading( total_nb_comp ); more(); next() ); - // (5) TYPE ( ignored ) - for (initNameReading(1, /*length=*/71); more(); next()); - // (6) TITRE ( ignored ) - for (initNameReading(1, /*length=*/71); more(); next()); - // (7) attributes ( ignored ) - for ( initIntReading( nb_attr ); more(); next() ); - - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { - // loop on components: read values - initDoubleReading( nb_values[ i_sub ] * nb_comps[ i_sub ] ); - for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp ) - { - if ( fdouble ) - { - vector& vals = fdouble->addComponent( nb_values[ i_sub ] ); - for ( int i = 0; more() && i < nb_values[ i_sub ]; next(), ++i ) - vals[ i ] = getDouble(); - } - else - { - for ( int i = 0; i < nb_values[ i_sub ]; next(), ++i ); - } - } - } // loop on subcomponents of a field - - // set a supporting group including all subs supports but only - // if all subs have the same components - if ( fdouble && fdouble->hasSameComponentsBySupport() ) - setFieldSupport( supports, fdouble ); - else - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - fdouble->_sub[ i_sub ]._support->_isProfile = true; - - } // end loop on field objects - - // set field names - setFieldNames( _iMed->_nodeFields, objectNames, nameIndices ); - -} // read_PILE_NODES_FIELD() - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 39": FIELDS - */ -//================================================================================ - -void SauvReader::read_PILE_FIELD (const int nbObjects, - std::vector& objectNames, - std::vector& nameIndices) -{ - // REAL EXAMPLE - - // (1) 1 2 6 16 - // (2) CARACTERISTIQUES - // (3) -15 317773 4 0 0 0 -2 0 3 - // (4) 317581 - // (5) 0 - // (6) 317767 317761 317755 317815 - // (7) YOUN NU H SIGY - // (8) REAL*8 REAL*8 REAL*8 REAL*8 - // (9) 1 1 0 0 - // (10) 2.00000000000000E+05 - // (11) 1 1 0 0 - // (12) 3.30000000000000E-01 - // (13) 1 1 0 0 - // (14) 1.00000000000000E+04 - // (15) 6 706 0 0 - // (16) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (17) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (18) ... - - _iMed->_cellFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 ); - for (int object=0; object!=nbObjects; ++object) // pour chaque field - { - initIntReading( 4 ); - int i_sub, nb_sub = getIntNext(); // (1) 2 6 - next(); // skip "2" - next(); // skip "6" - int title_length = getIntNext(); // <title length> - if ( nb_sub < 1 ) - THROW_IK_EXCEPTION("Error of field reading: wrong nb of subcomponents " << nb_sub << lineNb() ); - - string description; - if ( title_length ) - { - if ( isXRD() ) - { - initNameReading(1, title_length); - description = getName(); - next(); - } - else - { - char* line; - getNextLine( line ); // (2) title - const int len = 72; // line length - description = string(line + len - title_length, title_length); // title is right justified - } - } - // look for a line starting with '-' : <reference to support> - if ( isXRD() ) - { - initIntReading( nb_sub * 9 ); - } - else - { - do { - initIntReading( nb_sub * 9 ); - } while ( getInt() >= 0 ); - } - int total_nb_comp = 0; - vector<Group*> supports( nb_sub ); - vector<int> nb_comp( nb_sub ); - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { // (3) - int supportId = -getIntNext(); // <reference to support> - next(); // ignore <address> - nb_comp [ i_sub ] = getIntNext(); // <nb of components in the sub> - for ( int i = 0; i < 6; ++i ) next(); // ignore 6 ints, in example "0 0 0 -2 0 3" - - if ( supportId < 1 || supportId > (int)_iMed->_groups.size() ) - THROW_IK_EXCEPTION("Error of field reading: wrong mesh reference "<< supportId << lineNb() ); - if ( nb_comp[ i_sub ] < 0 ) - THROW_IK_EXCEPTION("Error of field reading: wrong nb of components " <<nb_comp[ i_sub ] << lineNb() ); - - supports[ i_sub ] = &_iMed->_groups[ supportId-1 ]; - total_nb_comp += nb_comp[ i_sub ]; - } - // (4) dummy strings - for ( initNameReading( nb_sub, 17 ); more(); next() ); - // (5) dummy strings - for ( initNameReading( nb_sub ); more(); next() ); - - // loop on subcomponents of a field, each of which refers to - // a certain support and has its own number of components; - // read component values - SauvUtilities::DoubleField* fdouble = 0; - for ( i_sub = 0; i_sub < nb_sub; ++ i_sub ) - { - vector<string> comp_names( nb_comp[ i_sub ]), comp_type( nb_comp[ i_sub ]); - // (6) nb_comp addresses of MELVAL structure - for ( initIntReading( nb_comp[ i_sub ] ); more(); next() ); - // (7) component names - for ( initNameReading( nb_comp[ i_sub ] ); more(); next() ) - comp_names[ index() ] = getName(); - // (8) component type - for ( initNameReading( nb_comp[ i_sub ], 17 ); more(); next() ) // 17 is name width - { - comp_type[ index() ] = getName(); - // component types must be the same - if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] ) - THROW_IK_EXCEPTION( "Error of field reading: diff component types <" - << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ] - << ">" << lineNb() ); - } - // now type is known, create a field, one for all subs - bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true; - if ( !fdouble && total_nb_comp ) - { - if ( !isReal ) - cout << "Warning: read NOT REAL field, type <" << comp_type[0] << ">" << lineNb() << endl; - _iMed->_cellFields[ object ] = fdouble = new SauvUtilities::DoubleField( nb_sub, total_nb_comp ); - fdouble->_description = description; - } - // store support id and nb components of a sub - if ( fdouble ) - fdouble->_sub[ i_sub ].setData( nb_comp[ i_sub ], supports[ i_sub ]); - // loop on components: read values - for ( int i_comp = 0; i_comp < nb_comp[ i_sub ]; ++i_comp ) - { - // (9) nb of values - initIntReading( 4 ); - int nb_val_by_elem = getIntNext(); - int nb_values = getIntNext(); - next(); - next(); - fdouble->_sub[ i_sub ]._nb_gauss[ i_comp ] = nb_val_by_elem; - - // (10) values - nb_values *= nb_val_by_elem; - if ( fdouble ) - { - vector<double> & vals = fdouble->addComponent( nb_values ); - for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next()) - vals[ index() ] = getDouble(); - // store component name - fdouble->_sub[ i_sub ].compName( i_comp ) = comp_names[ i_comp ]; - } - else - { - for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next() ) ; - } - } - } // loop on subcomponents of a field - - // set id of a group including all sub supports but only - // if all subs have the same nb of components - if ( fdouble && fdouble->hasSameComponentsBySupport() ) - setFieldSupport( supports, fdouble ); - else - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - fdouble->_sub[ i_sub ]._support->_isProfile = true; - - } // end loop on field objects - - // set field names - setFieldNames( _iMed->_cellFields, objectNames, nameIndices ); - -} // read_PILE_FIELD() - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 10": TABLES - */ -//================================================================================ - -void SauvReader::read_PILE_TABLES (const int nbObjects, - std::vector<std::string>& objectNames, - std::vector<int>& nameIndices) -{ - // IMP 0020434: mapping GIBI names to MED names - - string table_med_mail = "MED_MAIL"; - string table_med_cham = "MED_CHAM"; - string table_med_comp = "MED_COMP"; - int table_med_mail_id = -1; - int table_med_cham_id = -1; - int table_med_comp_id = -1; - for (size_t iname = 0; iname < objectNames.size(); iname++) - if (objectNames[iname] == table_med_mail) table_med_mail_id = nameIndices[iname]; - else if (objectNames[iname] == table_med_cham) table_med_cham_id = nameIndices[iname]; - else if (objectNames[iname] == table_med_comp) table_med_comp_id = nameIndices[iname]; - - if ( isASCII() ) - if (table_med_mail_id < 0 && table_med_cham_id < 0 && table_med_comp_id < 0) - return; - - for (int itable = 1; itable <= nbObjects; itable++) - { - // read tables "MED_MAIL", "MED_CHAM" and "MED_COMP", that keeps correspondence - // between GIBI names (8 symbols if any) and MED names (possibly longer) - initIntReading(1); - int nb_table_vals = getIntNext(); - if (nb_table_vals < 0) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO 10" << lineNb() ); - - int name_i_med_pile; - initIntReading(nb_table_vals); - for (int i = 0; i < nb_table_vals/4; i++) - { - if (itable == table_med_mail_id || - itable == table_med_cham_id || - itable == table_med_comp_id) - { - nameGIBItoMED name_i; - name_i_med_pile = getIntNext(); - name_i.med_id = getIntNext(); - name_i.gibi_pile = getIntNext(); - name_i.gibi_id = getIntNext(); - - if (name_i_med_pile != PILE_STRINGS) - { - // error: med(long) names are always kept in PILE_STRINGS - } - if (itable == table_med_mail_id) - { - if (name_i.gibi_pile != PILE_SOUS_MAILLAGE) { - // error: must be PILE_SOUS_MAILLAGE - } - _iMed->_listGIBItoMED_mail.push_back(name_i); - } - else if (itable == table_med_cham_id) - { - if (name_i.gibi_pile != PILE_FIELD && - name_i.gibi_pile != PILE_NODES_FIELD) - { - // error: must be PILE_FIELD or PILE_NODES_FIELD - } - _iMed->_listGIBItoMED_cham.push_back(name_i); - } - else if (itable == table_med_comp_id) - { - if (name_i.gibi_pile != PILE_STRINGS) - { - // error: gibi(short) names of components are kept in PILE_STRINGS - } - _iMed->_listGIBItoMED_comp.push_back(name_i); - } - } - else - { - // pass table - for ( int ii = 0; ii < 4; ++ii ) next(); - } - } - } // for (int itable = 0; itable < nbObjects; itable++) -} - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 27" - */ -//================================================================================ - -void SauvReader::read_PILE_STRINGS (const int nbObjects, - std::vector<std::string>& objectNames, - std::vector<int>& nameIndices) -{ - // IMP 0020434: mapping GIBI names to MED names - initIntReading(2); - int stringLen = getIntNext(); - int nbSubStrings = getIntNext(); - if (nbSubStrings != nbObjects) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO 27" << lineNb() ); - - string aWholeString; - if ( isXRD() ) - { - const int fixedLength = 71; - while ((int)aWholeString.length() < stringLen) - { - int remainLen = stringLen - aWholeString.length(); - int len; - if ( remainLen > fixedLength ) - { - len = fixedLength; - } - else - { - len = remainLen; - } - initNameReading(1, len); - aWholeString += getName(); - next(); - } - } - else - { - char* line; - const int fixedLength = 71; - while ((int)aWholeString.length() < stringLen) - { - getNextLine( line ); - int remainLen = stringLen - aWholeString.length(); - if ( remainLen > fixedLength ) - { - aWholeString += line + 1; - } - else - { - aWholeString += line + ( 72 - remainLen ); - } - } - } - int prevOffset = 0; - int currOffset = 0; - initIntReading(nbSubStrings); - for (int istr = 1; istr <= nbSubStrings; istr++, next()) - { - currOffset = getInt(); - // fill mapStrings - _iMed->_mapStrings[istr] = aWholeString.substr(prevOffset, currOffset - prevOffset); - prevOffset = currOffset; - } -} diff --git a/medtool/src/MEDLoader/SauvReader.hxx b/medtool/src/MEDLoader/SauvReader.hxx deleted file mode 100644 index 4be5977b3..000000000 --- a/medtool/src/MEDLoader/SauvReader.hxx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvReader.hxx -// Created : Tue Aug 16 13:04:25 2011 -// Author : Edward AGAPOV (eap) -// -#ifndef __SAUVREADER_HXX__ -#define __SAUVREADER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "InterpKernelException.hxx" -#include "SauvUtilities.hxx" -#include "MEDCouplingRefCountObject.hxx" - -#include <vector> -#include <string> -#include <set> - -namespace SauvUtilities -{ - class FileReader; - struct IntermediateMED; - struct Group; - struct DoubleField; -} -namespace ParaMEDMEM -{ - class MEDFileData; - -class SauvReader : public ParaMEDMEM::RefCountObject -{ - public: - MEDLOADER_EXPORT static SauvReader* New(const std::string& fileName); - MEDLOADER_EXPORT ParaMEDMEM::MEDFileData * loadInMEDFileDS(); - MEDLOADER_EXPORT ~SauvReader(); - - private: - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; - void readRecord2(); - void readRecord4(); - void readRecord7(); - - int readPileNumber(int& nbNamedObjects, int& nbObjects); - void read_PILE_SOUS_MAILLAGE(const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_NODES_FIELD (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_TABLES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_LREEL (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_LOGIQUES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_FLOATS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_INTEGERS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_STRINGS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_LMOTS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_NOEUDS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_COORDONNEES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_MODL (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_FIELD (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - - void setFieldSupport(const std::vector<SauvUtilities::Group*>& supports, - SauvUtilities::DoubleField* field); - void setFieldNames(const std::vector<SauvUtilities::DoubleField*>& fields, - const std::vector<std::string>& objectNames, - const std::vector<int>& nameIndices); - - bool isASCII() const { return _fileReader->isASCII(); } - bool isXRD() const { return !isASCII(); } - bool getNextLine (char* & line, bool raiseOEF = true ) { return _fileReader->getNextLine( line, raiseOEF ); } - void initNameReading(int nbValues, int width = 8) { _fileReader->initNameReading( nbValues, width ); } - void initIntReading(int nbValues) { _fileReader->initIntReading( nbValues ); } - void initDoubleReading(int nbValues) { _fileReader->initDoubleReading( nbValues ); } - bool more() const { return _fileReader->more(); } - void next() { _fileReader->next(); } - int index() const { return _fileReader->index(); } - int getInt() const { return _fileReader->getInt(); } - int getIntNext() { int i = getInt(); next(); return i; } - float getFloat() const { return _fileReader->getFloat(); } - double getDouble() const { return _fileReader->getDouble(); } - std::string getName() const { return _fileReader->getName(); } - std::string lineNb() const; - - - std::set<int> _encounteredPiles; - - SauvUtilities::FileReader* _fileReader; - SauvUtilities::IntermediateMED* _iMed; -}; -} -#endif diff --git a/medtool/src/MEDLoader/SauvUtilities.hxx b/medtool/src/MEDLoader/SauvUtilities.hxx deleted file mode 100644 index 3fa32d79e..000000000 --- a/medtool/src/MEDLoader/SauvUtilities.hxx +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvUtilities.hxx -// Created : Mon Aug 22 18:27:34 2011 -// Author : Edward AGAPOV (eap) - -#ifndef __SAUVUTILITIES_HXX__ -#define __SAUVUTILITIES_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include <string> -#include <sstream> - -#define THROW_IK_EXCEPTION(text) \ - { \ - std::ostringstream oss; oss << text; \ - throw INTERP_KERNEL::Exception(oss.str().c_str()); \ - } - -namespace SauvUtilities -{ - INTERP_KERNEL::NormalizedCellType MEDLOADER_EXPORT gibi2medGeom( size_t gibiType ); - int med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType ); - const int * getGibi2MedQuadraticInterlace( INTERP_KERNEL::NormalizedCellType type ); - unsigned getDimension( INTERP_KERNEL::NormalizedCellType type ); - - enum Readable_Piles - { - PILE_SOUS_MAILLAGE=1 , - PILE_NODES_FIELD =2 , - PILE_TABLES =10, - PILE_LREEL =18, - PILE_LOGIQUES =24, - PILE_FLOATS =25, - PILE_INTEGERS =26, - PILE_STRINGS =27, - PILE_LMOTS =29, - PILE_NOEUDS =32, - PILE_COORDONNEES =33, - PILE_MODL =38, - PILE_FIELD =39, - PILE_LAST_READABLE=39 - }; - - //================================================================================ - /*! - * \brief Converts anything to string - */ - //================================================================================ - - template<class T> std::string toString(const T& anything) - { - std::ostringstream s; s << anything; return s.str(); - } - - // ============================================================================== - // IMP 0020434: mapping GIBI names to MED names - struct nameGIBItoMED - { - // GIBI value - int gibi_pile; // PILE_SOUS_MAILLAGE or PILE_FIELD/PILE_NODES_FIELD, or PILE_STRINGS(for components) - int gibi_id; - std::string gibi_name; // used only for components - // MED value - // med_pile = 27; // PILE_STRINGS - int med_id; // used only on reading - std::string med_name; // used only on writing - }; - - // ============================================================================== - /*! - * \brief Base class for ASCII and XDR file readers - */ - class FileReader : public ParaMEDMEM::RefCountObject - { - public: - FileReader(const char* fileName); - virtual ~FileReader() {} - virtual bool isASCII() const = 0; - - virtual bool open() = 0; - virtual bool getNextLine (char* & line, bool raiseOEF = true ) = 0; - virtual void initNameReading(int nbValues, int width = 8) = 0; - virtual void initIntReading(int nbValues) = 0; - virtual void initDoubleReading(int nbValues) = 0; - virtual bool more() const = 0; - virtual void next() = 0; - virtual int index() const { return _iRead; } - virtual int getInt() const = 0; - virtual float getFloat() const = 0; - virtual double getDouble() const = 0; - virtual std::string getName() const = 0; - protected: - std::size_t getHeapMemorySizeWithoutChildren() const { return 0; } - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const { return std::vector<const BigMemoryObject *>(); } - protected: - std::string _fileName, _curLocale; - int _iRead, _nbToRead; - }; -} -#endif diff --git a/medtool/src/MEDLoader/SauvWriter.cxx b/medtool/src/MEDLoader/SauvWriter.cxx deleted file mode 100644 index 701ab1e95..000000000 --- a/medtool/src/MEDLoader/SauvWriter.cxx +++ /dev/null @@ -1,1378 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvWriter.cxx -// Created : Wed Aug 24 12:55:55 2011 -// Author : Edward AGAPOV (eap) - -#include "SauvWriter.hxx" - -#include "InterpKernelException.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "MEDFileData.hxx" -#include "CellModel.hxx" - -#include <fstream> -#include <sstream> -#include <iostream> -#include <cstdlib> -#include <iomanip> - -using namespace ParaMEDMEM; -using namespace SauvUtilities; -using namespace std; - -#define INFOS_MED(txt) cout << txt << endl; - -namespace -{ - const char* zeroI8 = " 0"; // FORMAT(I8) - - // ============================================================ - // the class writes endl to the file as soon as <limit> fields - // have been written after the last endl - // ============================================================ - - class TFieldCounter - { - fstream& _file; - int _count, _limit; - public: - TFieldCounter(fstream& f, int limit=0): _file(f), _limit(limit) { init(); } - void init(int limit=0) // init, is done by stop() as well - { if (limit) _limit = limit; _count = 0; } - void operator++(int) // next - { if ( ++_count == _limit ) { _file << endl; init(); }} - void stop() // init() and write endl if there was no endl after the last written field - { if ( _count ) _file << endl; init(); } - ~TFieldCounter() { stop(); } - }; - - //================================================================================ - /*! - * \brief Return a name of a field support on all elements - */ - //================================================================================ - - string noProfileName( INTERP_KERNEL::NormalizedCellType type ) - { - return "INTERP_KERNEL::NormalizedCellType_" + SauvUtilities::toString( type ); - } - - //================================================================================ - /*! - * \brief Remove white spaces from the head and tail - */ - //================================================================================ - - string cleanName( const string& theName ) - { - string name = theName; - if ( !name.empty() ) - { - // cut off leading white spaces - string::size_type firstChar = name.find_first_not_of(" \t"); - if (firstChar < name.length()) - { - name = name.substr(firstChar); - } - else - { - name = ""; // only whitespaces there - remove them - } - // cut off trailing white spaces - string::size_type lastChar = name.find_last_not_of(" \t"); - if (lastChar < name.length()) - name = name.substr(0, lastChar + 1); - } - return name; - } - - //================================================================================ - /*! - * \brief Converts MED long names into SAUVE short ones, returnes a healed long name - */ - //================================================================================ - - string addName (map<string,int>& nameMap, - map<string,int>& namePrefixesMap, - const string& theName, - const int index) - { - // Converts names like: - // MED: GIBI: - // TEMPERATURE_FLUIDE -> TEMPE001 - // TEMPERATURE_SOLIDE -> TEMPE002 - // PRESSION -> PRESSION - // NU -> NU - // VOLUM001 -> VOLUM001 - // VOLUMOFOBJECT -> VOLUM003 - // VOLUM002 -> VOLUM002 - string healedName = cleanName(theName); - int ind = index; - - if (!healedName.empty()) - { - string name = healedName; - int len = name.length(); - for (int i = 0; i < len; ++i) - name[i] = toupper(name[i]); - - bool doResave = false; // only for tracing - - // I. Save a short name as it is - if (len <= 8) - { - INFOS_MED("Save <" << theName << "> as <" << name << ">"); - - map<string,int>::iterator it = nameMap.find(name); - if (it != nameMap.end()) - { - // There is already such name in the map. - - // a. Replace in the map the old pair by the current one - int old_ind = nameMap[name]; - nameMap[name] = ind; - // b. Rebuild the old pair (which was in the map, - // it seems to be built automatically by step II) - ind = old_ind; - // continue with step II - doResave = true; // only for tracing - } - else - { - // Save in the map - nameMap.insert(make_pair(name, ind)); - - // Update loc_index for this name (if last free characters represents a number) - // to avoid conflicts with long names, same in first 5 characters - if (len == 8) - { - int new_loc_index = atoi(name.c_str() + 5); - if (new_loc_index > 0) - { - // prefix - string str = name.substr(0,5); - if (namePrefixesMap.find(str) != namePrefixesMap.end()) - { - int old_loc_index = namePrefixesMap[str]; - if (new_loc_index < old_loc_index) new_loc_index = old_loc_index; - } - namePrefixesMap[str] = new_loc_index; - } - } - return healedName; - } - } // if (len <= 8) - - // II. Cut long name and add a numeric suffix - - // first 5 or less characters of the name - if (len > 5) name = name.substr(0,5); - - // numeric suffix - map<string,int>::iterator name2ind = namePrefixesMap.insert( make_pair( name, 0 )).first; - string numSuffix = SauvUtilities::toString( ++(name2ind->second) ); - - if ( numSuffix.size() + name.size() > 8 ) - THROW_IK_EXCEPTION("Can't write not unique name: " << healedName); - - if ( numSuffix.size() < 3 ) - numSuffix.insert( 0, 3 - numSuffix.size(), '0' ); - - name += numSuffix; - nameMap.insert(make_pair(name, ind)); - - if (doResave) - { - INFOS_MED("Resave previous <" << healedName << "> as <" << name << ">"); - } - else - { - INFOS_MED("Save <" << theName << "> as <" << name << ">"); - } - } - return healedName; - } -} - -SauvWriter::SauvWriter():_cpy_grp_if_on_single_family(false) -{ -} - -SauvWriter* SauvWriter::New() -{ - return new SauvWriter; -} - -std::size_t SauvWriter::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector<const BigMemoryObject *> SauvWriter::getDirectChildrenWithNull() const -{ - return std::vector<const BigMemoryObject *>(); -} - -void SauvWriter::setCpyGrpIfOnASingleFamilyStatus(bool status) -{ - _cpy_grp_if_on_single_family=status; -} - -bool SauvWriter::getCpyGrpIfOnASingleFamilyStatus() const -{ - return _cpy_grp_if_on_single_family; -} - -//================================================================================ -/*! - * \brief Fills own DS by MEDFileData - */ -//================================================================================ - -void SauvWriter::setMEDFileDS(const MEDFileData* medData, - unsigned meshIndex) -{ - if ( !medData) THROW_IK_EXCEPTION("NULL MEDFileData"); - - MEDFileMeshes * meshes = medData->getMeshes(); - MEDFileFields * fields = medData->getFields(); - if ( !meshes) THROW_IK_EXCEPTION("No meshes in MEDFileData"); - - _fileMesh = meshes->getMeshAtPos( meshIndex ); - _fileMesh->incrRef(); - - if ( fields ) - for ( int i = 0; i < fields->getNumberOfFields(); ++i ) - { - MEDFileAnyTypeFieldMultiTS * fB = fields->getFieldAtPos(i); - MEDFileFieldMultiTS * f = dynamic_cast<MEDFileFieldMultiTS *>(fB); - if(!f) - continue;// fields on int32 not managed - if ( f->getMeshName() == _fileMesh->getName() ) - { - vector< vector<TypeOfField> > fTypes = f->getTypesOfFieldAvailable(); - if ( fTypes[0].size() == 1 && fTypes[0][0] == ON_NODES ) - _nodeFields.push_back( f ); - else - _cellFields.push_back( f ); - } - } -} - -//================================================================================ -/*! - * \brief Adds a submesh - */ -//================================================================================ - -SauvWriter::SubMesh* SauvWriter::addSubMesh(const std::string& name, int dimRelExt) -{ - if ( _subs.capacity() < _subs.size() + 1 ) - THROW_IK_EXCEPTION("SauvWriter: INTERNAL error, wrong evaluation of nb of sub-meshes"); - _subs.resize( _subs.size() + 1 ); - SubMesh& sm = _subs.back(); - sm._name = name; - sm._dimRelExt = dimRelExt; - return &sm; -} -//================================================================================ -/*! - * \brief Returns nb of cell types - */ -//================================================================================ - -int SauvWriter::SubMesh::nbTypes() const -{ - int nb = 0; - for (int i = 0; i < cellIDsByTypeSize(); ++i ) - nb += int( !_cellIDsByType[i].empty() ); - return nb; -} - -//================================================================================ -/*! - * \brief Fill _subs - */ -//================================================================================ - -void SauvWriter::fillSubMeshes( int& nbSauvObjects, map<string,int>& nameNbMap ) -{ - // evaluate nb of _subs in order to avoid re-allocation of _subs - int nbSubs = 1; // for the very mesh - nbSubs += _fileMesh->getFamilyInfo().size() + 4; // + 4 zero families (for each dimRelExt) - nbSubs += _fileMesh->getGroupInfo().size(); - nbSubs += evaluateNbProfileSubMeshes(); - _subs.clear(); - _subs.reserve( nbSubs ); - - fillFamilySubMeshes(); - fillGroupSubMeshes(); - fillProfileSubMeshes(); - - // fill names of SubMesh'es and count nb of sauv sub-meshes they will be stored into - nbSauvObjects = 0; - map<string,int> namePrefixMap; - for ( size_t i = 0; i < _subs.size(); ++i ) - { - SubMesh& sm = _subs[i]; - - sm._nbSauvObjects = 0; - if ( sm._subs.empty() ) - { - sm._nbSauvObjects = sm.nbTypes(); - } - else - { - sm._nbSauvObjects = 1; - } - - sm._id = nbSauvObjects+1; - nbSauvObjects += sm._nbSauvObjects; - - if ( sm._nbSauvObjects ) - sm._name = addName( nameNbMap, namePrefixMap, sm._name, sm._id ); - - if ( sm._nbSauvObjects && !sm._name.empty() ) - { - nameGIBItoMED aMEDName; - aMEDName.gibi_pile = PILE_SOUS_MAILLAGE; - aMEDName.gibi_id = sm._id; - aMEDName.med_name = sm._name; - _longNames[ LN_MAIL ].push_back(aMEDName); - } - } -} - -//================================================================================ -/*! - * \brief fill sub-meshes of families - */ -//================================================================================ - -void SauvWriter::fillFamilySubMeshes() -{ - SubMesh* nilSm = (SubMesh*) 0; - std::vector<int> dims = _fileMesh->getNonEmptyLevelsExt(); - for ( size_t iDim = 0; iDim < dims.size(); ++iDim ) - { - int dimRelExt = dims[ iDim ]; - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel(dimRelExt); - const DataArrayInt * famIds = _fileMesh->getFamilyFieldAtLevel(dimRelExt); - if ( !famIds ) continue; - - int curFamID = 0; - SubMesh* curSubMesh = addSubMesh( "", dimRelExt ); // submesh of zero family - _famIDs2Sub[0] = curSubMesh; - int sub0Index = _subs.size()-1; - - const int * famID = famIds->begin(), * famIDEnd = famIds->end(); - for ( int cellID = 0; famID < famIDEnd; ++famID, cellID++ ) - { - if ( *famID != curFamID ) - { - curFamID = *famID; - map< int, SubMesh* >::iterator f2s = _famIDs2Sub.insert( make_pair( curFamID, nilSm )).first; - if ( !f2s->second ) - f2s->second = addSubMesh( "", dimRelExt ); // no names for families - curSubMesh = f2s->second; - } - INTERP_KERNEL::NormalizedCellType cellType = - dimRelExt == 1 ? INTERP_KERNEL::NORM_POINT1 : mesh->getTypeOfCell( cellID ); - curSubMesh->_cellIDsByType[ cellType ].push_back( cellID ); - } - - if ( dimRelExt == 1 ) - { - // clear submesh of nodal zero family - _famIDs2Sub[0]->_cellIDsByType[ INTERP_KERNEL::NORM_POINT1 ].clear(); - } - else if ( dimRelExt == 0 ) - { - // make a submesh including all cells - if ( sub0Index == (int)(_subs.size()-1) ) - { - _famIDs2Sub[0]->_name = _fileMesh->getName(); // there is the zero family only - } - else - { - curSubMesh = addSubMesh( _fileMesh->getName(), dimRelExt ); - if ( _famIDs2Sub[0]->nbTypes() == 0 ) - sub0Index++; // skip an empty zero family - for ( size_t i = sub0Index; i < _subs.size()-1; ++i ) - curSubMesh->_subs.push_back( & _subs[i] ); - } - } - } -} - -//================================================================================ -/*! - * \brief fill sub-meshes of groups - */ -//================================================================================ - -void SauvWriter::fillGroupSubMeshes() -{ - const map<string, vector<string> >& grpFams = _fileMesh->getGroupInfo(); - map<string, vector<string> >::const_iterator g2ff = grpFams.begin(); - for ( ; g2ff != grpFams.end(); ++g2ff ) - { - const string& groupName = g2ff->first; - const vector<string>& famNames = g2ff->second; - if ( famNames.empty() ) continue; - std::vector<SubMesh*> famSubMeshes( famNames.size() ); - std::size_t k = 0; - for ( size_t i = 0; i < famNames.size(); ++i ) - { - int famID = _fileMesh->getFamilyId( famNames[i].c_str() ); - map< int, SubMesh* >::iterator i2f = _famIDs2Sub.find( famID ); - if ( i2f != _famIDs2Sub.end() ) - { - famSubMeshes[ k ] = i2f->second; - ++k; - } - } - // if a family exists but has no element, no submesh has been found for this family - // => we have to resize famSubMeshes with the number of submeshes stored - if (k != famNames.size()) - famSubMeshes.resize(k); - SubMesh* grpSubMesh = addSubMesh( groupName, famSubMeshes[0]->_dimRelExt ); - if(!_cpy_grp_if_on_single_family) - grpSubMesh->_subs.swap( famSubMeshes ); - else - { - /* If a group sub mesh consists of only one family, the group is written as - * a copy of this family. - * A mesh composed of only one submesh may cause an issue with some Gibi operators.*/ - if (famSubMeshes.size() == 1) - { - for(int i = 0; i < famSubMeshes[0]->cellIDsByTypeSize() ; i++) - { - grpSubMesh->_cellIDsByType[i] = famSubMeshes[0]->_cellIDsByType[i]; - } - } - else - grpSubMesh->_subs.swap( famSubMeshes ); - } - } -} - - -//================================================================================ -/*! - * \brief fill sub-meshes of profiles - */ -//================================================================================ - -void SauvWriter::fillProfileSubMeshes() -{ - _profile2Sub.clear(); - SubMesh* nilSm = (SubMesh*) 0; - for ( int isOnNodes = 0; isOnNodes < 2; ++isOnNodes ) - { - vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > - fields = isOnNodes ? _nodeFields : _cellFields; - for ( size_t i = 0; i < fields.size(); ++i ) - { - vector< pair<int,int> > iters = fields[i]->getIterations(); - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - fields[i]->getFieldSplitedByType( iters[0].first, iters[0].second, - _fileMesh->getName().c_str(), types, typesF, pfls, locs); - int dimRelExt; - for ( size_t iType = 0; iType < types.size(); ++iType ) - { - if ( types[iType] == INTERP_KERNEL::NORM_ERROR ) - dimRelExt = 1; // on nodes - else - dimRelExt = getDimension( types[iType] ) - _fileMesh->getMeshDimension(); - for ( size_t iPfl = 0; iPfl < pfls[iType].size(); ++iPfl ) - { - bool isOnAll = pfls[iType][iPfl].empty(); - if ( isOnAll ) pfls[iType][iPfl] = noProfileName( types[iType] ); - map< string, SubMesh* >::iterator pfl2sm = - _profile2Sub.insert( make_pair( pfls[iType][iPfl], nilSm )).first; - if ( !pfl2sm->second ) - { - SubMesh* sm = pfl2sm->second = addSubMesh( "", dimRelExt ); // no names for profiles - const DataArrayInt * pfl = isOnAll ? 0 : fields[i]->getProfile( pfls[iType][iPfl].c_str() ); - makeProfileIDs( sm, types[iType], pfl ); - } - } - } - } - } -} - -//================================================================================ -/*! - * \brief Return max possible nb of sub-meshes to decsribe field supports - */ -//================================================================================ - -int SauvWriter::evaluateNbProfileSubMeshes() const -{ - int nb = 0; - for ( size_t i = 0; i < _nodeFields.size(); ++i ) - nb += 1 + _nodeFields[i]->getPflsReallyUsed().size(); - - for ( size_t i = 0; i < _cellFields.size(); ++i ) - { - nb += _cellFields[i]->getPflsReallyUsed().size(); - - vector< pair<int,int> > iters = _cellFields[i]->getIterations(); - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - _cellFields[i]->getFieldSplitedByType( iters[0].first, iters[0].second, - _fileMesh->getName().c_str(), types, typesF, pfls, locs); - nb += 2 * types.size(); // x 2 - a type can be on nodes and on cells at the same time - } - - return nb; -} - -//================================================================================ -/*! - * \brief Transorm a profile into ids of mesh elements - */ -//================================================================================ - -void SauvWriter::makeProfileIDs( SubMesh* sm, - INTERP_KERNEL::NormalizedCellType type, - const DataArrayInt* profile ) -{ - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > - mesh = _fileMesh->getGenMeshAtLevel(sm->_dimRelExt); - const MEDCouplingUMesh* uMesh = dynamic_cast< const MEDCouplingUMesh* > ((const MEDCouplingMesh*) mesh ); - - if ( sm->_dimRelExt == 1 ) type = INTERP_KERNEL::NORM_POINT1; - vector< int >& ids = sm->_cellIDsByType[ type ]; - - if ( sm->_dimRelExt == 1 || !uMesh ) - { - // profile on nodes or mesh is CARTESIAN - if ( profile ) - { - ids.assign( profile->begin(), profile->end() ); - } - else // on all - { - ids.resize( sm->_dimRelExt == 1 ? mesh->getNumberOfNodes() : mesh->getNumberOfCells() ); - for ( size_t i = 0; i < ids.size(); ++i ) - ids[i]=i; - } - } - else - { - // profile on cells - vector<int> code(3); - code[0] = type; - if ( profile ) // on profile - { - code[1] = profile->getNumberOfTuples(); - code[2] = 0; - } - else // on all cells - { - code[1] = mesh->getNumberOfCellsWithType( type ); - code[2] = -1; - } - vector<const DataArrayInt *> idsPerType( 1, profile ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> - resIDs = uMesh->checkTypeConsistencyAndContig( code, idsPerType ); - if (( const DataArrayInt *) resIDs ) - { - ids.assign( resIDs->begin(), resIDs->end() ); - } - else // mesh includes only one type - { - int nbE = code[1]; - for ( ids.resize( nbE ); nbE; --nbE ) - ids[ nbE-1 ] = nbE-1; - } - } -} - -//================================================================================ -/*! - * \brief Write its data into the SAUVE file - */ -//================================================================================ - -void SauvWriter::write(const std::string& fileName) -{ - std::fstream fileStream; - fileStream.open( fileName.c_str(), ios::out); - if -#ifdef WIN32 - ( !fileStream || !fileStream.is_open() ) -#else - ( !fileStream || !fileStream.rdbuf()->is_open() ) -#endif - THROW_IK_EXCEPTION("Can't open the file |"<<fileName<<"|"); - _sauvFile = &fileStream; - - _subs.clear(); - _famIDs2Sub.clear(); - _profile2Sub.clear(); - _longNames[ LN_MAIL ].clear(); - _longNames[ LN_CHAM ].clear(); - _longNames[ LN_COMP ].clear(); - - map<string,int> fldNamePrefixMap; - - writeFileHead(); - writeSubMeshes(); - writeNodes(); - writeNodalFields(fldNamePrefixMap); - writeElemFields(fldNamePrefixMap); - writeLongNames(); - writeLastRecord(); - - _sauvFile->close(); -} -//================================================================================ -/*! - * \brief Writes "ENREGISTREMENT DE TYPE" 4 and 7 - */ -//================================================================================ - -void SauvWriter::writeFileHead() -{ - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel(0); - - *_sauvFile - << " ENREGISTREMENT DE TYPE 4" << endl - << " NIVEAU 16 NIVEAU ERREUR 0 DIMENSION " << mesh->getSpaceDimension() <<endl - << " DENSITE 0.00000E+00" << endl - << " ENREGISTREMENT DE TYPE 7" << endl - << " NOMBRE INFO CASTEM2000 8" <<endl - << " IFOUR -1 NIFOUR 0 IFOMOD -1 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1" << endl - << " NSDPGE 0" << endl; -} - -//================================================================================ -/*! - * \brief Writes names of objects - */ -//================================================================================ - -void SauvWriter::writeNames( const map<string,int>& nameNbMap ) -{ - if ( !nameNbMap.empty() ) - { - // write names of objects - // * 8001 FORMAT(8(1X,A8)) - TFieldCounter fcount( *_sauvFile, 8 ); - *_sauvFile << left; - map<string,int>::const_iterator nameNbIt = nameNbMap.begin(); - for ( ; nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) - *_sauvFile << " " << setw(8) << nameNbIt->first; - fcount.stop(); - *_sauvFile << right; - - // write IDs of named objects in the pile - // * 8000 FORMAT(10I8) - nameNbIt = nameNbMap.begin(); - for ( fcount.init(10); nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) - *_sauvFile << setw(8) << nameNbIt->second; - } -} - -//================================================================================ -/*! - * \brief Writes "PILE NUMERO 1" - */ -//================================================================================ - -void SauvWriter::writeSubMeshes() -{ - int nbSauvObjects; - map<string,int> nameNbMap; - fillSubMeshes( nbSauvObjects, nameNbMap ); - - // * 800 FORMAT (' ENREGISTREMENT DE TYPE', I4) - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl; - // * 801 FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8) - *_sauvFile << " PILE NUMERO 1NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() << - "NBRE OBJETS" << setw(8) << nbSauvObjects <<endl; - - writeNames( nameNbMap ); - - TFieldCounter fcount( *_sauvFile, 10 ); // 10 intergers per line - - for ( size_t iSub = 0; iSub < _subs.size(); ++iSub ) - { - SubMesh& sm = _subs[iSub]; - if ( sm._nbSauvObjects < 1 ) continue; - - // The first record of each sub-mesh writes - // - type of cells; zero means a compound object whose the 2nd record enumerates its components - // - number of components of a compound object - // - number of references; each reference means a "pointer" to this sub-mesh - // - number of nodes per cell - // - number of cells - - if ( !sm._subs.empty() ) - { - writeCompoundSubMesh(iSub); - } - else - { - // write each sub-type as a SAUV sub-mesh - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > - mesh = _fileMesh->getGenMeshAtLevel( sm._dimRelExt ); - MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh> - umesh = mesh->buildUnstructured(); - - for ( int iType=0; iType < sm.cellIDsByTypeSize(); ++iType ) - { - const vector<int>& cellIDs = sm._cellIDsByType[iType]; - if ( cellIDs.empty() ) continue; - - INTERP_KERNEL::NormalizedCellType - cellType = INTERP_KERNEL::NormalizedCellType( iType ); - const INTERP_KERNEL::CellModel & - cell = INTERP_KERNEL::CellModel::GetCellModel( cellType ); - int castemType = SauvUtilities::med2gibiGeom( cellType ); - unsigned nbElemNodes = cell.getNumberOfNodes(); - unsigned nbElems = cellIDs.size(); - - *_sauvFile << setw(8) << castemType - << zeroI8 - << zeroI8 - << setw(8) << nbElemNodes - << setw(8) << nbElems << endl; - - // write color of each element - // * 8000 FORMAT(10I8) - for ( size_t i = 0; i < nbElems; ++i, fcount++ ) *_sauvFile << zeroI8; - fcount.stop(); - - // write connectivity - // gibi IDs are in FORTRAN mode while MEDCoupling IDs are in C mode - if ( sm._dimRelExt == 1 ) // nodes - { - for ( size_t i = 0; i < nbElems; ++i, fcount++ ) - *_sauvFile << setw(8) << ( cellIDs[i] + 1 ); - } - else - { - // indices to transform MED connectivity to GIBI one - const int * toMedConn = getGibi2MedQuadraticInterlace( cellType ); - - vector< int > cellConn( nbElemNodes ), transformedConn( nbElemNodes ); - for ( size_t i = 0; i < nbElems; ++i ) - { - cellConn.clear(); - umesh->getNodeIdsOfCell( cellIDs[i], cellConn ); - if ( toMedConn ) - { - for ( unsigned j = 0; j < nbElemNodes; ++j ) - transformedConn[ toMedConn[ j ]] = cellConn[ j ]; - cellConn.swap( transformedConn ); - } - for ( unsigned j = 0; j < nbElemNodes; ++j, fcount++ ) - *_sauvFile << setw(8) << ( cellConn[j] + 1 ); - } - } - fcount.stop(); - - } // loop on cell types - } // not a compound object - } // loop on sub-meshes -} - -//================================================================================ -/*! - * \brief Writes a sum-mesh composed of other sum-meshes - * This submesh corresponds to a med mesh or group composed of families - */ -//================================================================================ - -void SauvWriter::writeCompoundSubMesh(int iSub) -{ - SubMesh& sm = _subs[iSub]; - if ( sm._nbSauvObjects < 1 || sm._subs.empty()) return; - - vector< int > subIDs; - for ( size_t i = 0; i < sm._subs.size(); ++i ) // loop on sub-meshes of families - for ( int j = 0; j < sm._subs[i]->_nbSauvObjects; ++j ) - subIDs.push_back( sm._subs[i]->_id + j ); - - *_sauvFile << zeroI8 - << setw(8) << subIDs.size() - << zeroI8 - << zeroI8 - << zeroI8 << endl; - - TFieldCounter fcount( *_sauvFile, 10 ); // 10 intergers per line - for ( size_t i = 0; i < subIDs.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << subIDs[i]; -} - -//================================================================================ -/*! - * \brief Write piles relating to nodes - */ -//================================================================================ - -void SauvWriter::writeNodes() -{ - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel( 1 ); - MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > umesh = mesh->buildUnstructured(); - - // write the index connecting nodes with their coodrinates - - const int nbNodes = umesh->getNumberOfNodes(); - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << " PILE NUMERO 32NBRE OBJETS NOMMES 0NBRE OBJETS" << setw(8) << nbNodes << endl; - *_sauvFile << setw(8) << nbNodes << endl; - // - TFieldCounter fcount( *_sauvFile, 10 );// * 8000 FORMAT(10I8) - for ( int i = 0; i < nbNodes; ++i, fcount++ ) - *_sauvFile << setw(8) << i + 1; - fcount.stop(); - - // write coordinates and density of nodes - - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl; - *_sauvFile << " PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1" << endl; - // - const int dim = umesh->getSpaceDimension(); - const int nbValues = nbNodes * ( dim + 1 ); - *_sauvFile << setw(8) << nbValues << endl; - - // * 8003 FORMAT(1P,3E22.14) - const char* density = " 0.00000000000000E+00"; - fcount.init(3); - _sauvFile->precision(14); - _sauvFile->setf( ios_base::scientific, ios_base::floatfield ); - _sauvFile->setf( ios_base::uppercase ); - MEDCouplingAutoRefCountObjectPtr< DataArrayDouble> coordArray = umesh->getCoordinatesAndOwner(); - const double precision = 1.e-99; // PAL12077 - for ( int i = 0; i < nbNodes; ++i) - { - for ( int j = 0; j < dim; ++j, fcount++ ) - { - double coo = coordArray->getIJ( i, j ); - bool zero = ( -precision < coo && coo < precision ); - *_sauvFile << setw(22) << ( zero ? 0.0 : coo ); - } - *_sauvFile << density; - fcount++; - } -} - -//================================================================================ -/*! - * \brief Store correspondence between GIBI (short) and MED (long) names - * - * IMP 0020434: mapping GIBI names to MED names - * Store correspondence between GIBI and MED names as one PILE_STRINGS and one - * PILE_TABLES (in three tables: MED_MAIL, MED_CHAM and MED_COMP) - */ -//================================================================================ - -void SauvWriter::writeLongNames() -{ - int nbTables = - 3 - _longNames[ LN_MAIL ].empty() - _longNames[ LN_CHAM ].empty() - _longNames[ LN_COMP ].empty(); - if (nbTables == 0) return; - - // --------------------- - // Write the TABLE pile - // --------------------- - - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << " PILE NUMERO 10NBRE OBJETS NOMMES" << setw(8) << nbTables - << "NBRE OBJETS" << setw(8) << nbTables << endl; - // table names - if (!_longNames[ LN_MAIL ].empty()) *_sauvFile << " MED_MAIL"; - if (!_longNames[ LN_CHAM ].empty()) *_sauvFile << " MED_CHAM"; - if (!_longNames[ LN_COMP ].empty()) *_sauvFile << " MED_COMP"; - *_sauvFile << endl; - // table indices - for ( int i = 0; i < nbTables; ++i ) *_sauvFile << setw(8) << i+1; - *_sauvFile << endl; - - string theWholeString; // concatenated long names - vector<int> theOffsets; - int iStr = 1; - TFieldCounter fcount (*_sauvFile, 10); - - for ( int iTbl = 0; iTbl < LN_NB; ++iTbl ) - { - vector<nameGIBItoMED>& longNames = _longNames[ iTbl ]; - if ( longNames.empty() ) continue; - const bool isComp = ( iTbl == LN_COMP); - - // to assure unique MED names - set<string> medUniqueNames; - - *_sauvFile << setw(8) << longNames.size()*4 << endl; // Nb of table values - - vector<nameGIBItoMED>::iterator itGIBItoMED = longNames.begin(); - for (; itGIBItoMED != longNames.end(); itGIBItoMED++, iStr++) - { - // PILE of i-th key (med name) - *_sauvFile << setw(8) << PILE_STRINGS; - fcount++; - // ID of i-th key (med name) - *_sauvFile << setw(8) << iStr; - fcount++; - // PILE of i-th value (gibi name) - *_sauvFile << setw(8) << itGIBItoMED->gibi_pile; - fcount++; - // ID of i-th value (gibi name) - *_sauvFile << setw(8) << ( isComp ? ++iStr : itGIBItoMED->gibi_id ); - fcount++; - - // add a MED name to the string (while making it be unique for sub-meshes and fields) - string aMedName = itGIBItoMED->med_name; - if ( !isComp ) - for (int ind = 1; !medUniqueNames.insert(aMedName).second; ++ind ) - aMedName = itGIBItoMED->med_name + "_" + SauvUtilities::toString( ind ); - theWholeString += aMedName; - - // add an offset - theOffsets.push_back( theWholeString.size() ); - if ( isComp ) - { - theWholeString += itGIBItoMED->gibi_name; - theOffsets.push_back( theWholeString.size() ); - } - } - fcount.stop(); - } - - // ---------------------- - // Write the STRING pile - // ---------------------- - - const int nbNames = theOffsets.size(); - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << " PILE NUMERO 27NBRE OBJETS NOMMES" << zeroI8 << "NBRE OBJETS" << setw(8) << nbNames << endl - << setw(8) << theWholeString.length() << setw(8) << nbNames << endl; - - // write the whole string - const int fixedLength = 71; - for ( string::size_type aPos = 0; aPos < theWholeString.length(); aPos += fixedLength) - *_sauvFile << setw(72) << theWholeString.substr(aPos, fixedLength) << endl; - - // write the offsets - for ( size_t i = 0; i < theOffsets.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << theOffsets[i]; -} - -//================================================================================ -/*! - * \brief Write beginning of field record - */ -//================================================================================ - -void SauvWriter::writeFieldNames( const bool isNodal, - std::map<std::string,int>& fldNamePrefixMap) -{ - vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > >& - flds = isNodal ? _nodeFields : _cellFields; - map<string,int> nameNbMap; - - for ( size_t iF = 0; iF < flds.size(); ++iF ) - { - string name = addName( nameNbMap, fldNamePrefixMap, flds[iF]->getName(), iF+1 ); - nameGIBItoMED aMEDName; - aMEDName.gibi_pile = isNodal ? PILE_NODES_FIELD : PILE_FIELD; - aMEDName.gibi_id = iF+1; - aMEDName.med_name = name; - _longNames[ LN_CHAM ].push_back(aMEDName); - } - - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << ( isNodal ? " PILE NUMERO 2" : " PILE NUMERO 39") - << "NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() - << "NBRE OBJETS" << setw(8) << flds.size() << endl; - writeNames( nameNbMap ); -} - -//================================================================================ -/*! - * \brief Make short names of field components - * - * IMP 0020434: mapping GIBI names to MED names - */ -//================================================================================ - -void SauvWriter::makeCompNames(const string& fieldName, - const vector<string>& compInfo, - map<string, string>& mapMedToGibi) -{ - for ( size_t i = 0; i < compInfo.size(); ++i ) - mapMedToGibi[compInfo[i]] = cleanName( compInfo[i] ); - - int compIndex = 1; - map<string, string>::iterator namesIt = mapMedToGibi.begin(); - for (; namesIt != mapMedToGibi.end(); namesIt++) - { - string & compGibiName = (*namesIt).second; - if (compGibiName.size() > 4) { - // use new name in form "CXXX", where "XXX" is a number - do - { - compGibiName = SauvUtilities::toString( compIndex++ ); - if ( compGibiName.size() < 3 ) - compGibiName.insert( 0, 3 - compGibiName.size(), '0' ); - compGibiName = "C" + compGibiName; - } - while (mapMedToGibi.count(compGibiName) > 0); // real component name could be CXXX - } - - string compMedName = fieldName + "." + namesIt->first; - nameGIBItoMED aMEDName; - aMEDName.med_name = compMedName; - aMEDName.gibi_pile = PILE_STRINGS; - aMEDName.gibi_name = compGibiName; - _longNames[ LN_COMP ].push_back(aMEDName); - } -} - -//================================================================================ -/*! - * \brief Writes "PILE NUMERO 2": fields on nodes - */ -//================================================================================ - -void SauvWriter::writeNodalFields(map<string,int>& fldNamePrefixMap) -{ - writeFieldNames( /*isNodal=*/true, fldNamePrefixMap ); - - TFieldCounter fcount (*_sauvFile, 10); - - // EXAMPLE ( with no values ) - - // (1) 4 7 2 1 - // (2) -88 0 3 -89 0 1 -90 0 2 -91 - // (2) 0 1 - // (3) FX FY FZ FZ FX FY FLX - // (4) 0 0 0 0 0 0 0 - // (5) cree par muc pri - // (6) - // (7) 2 - for ( size_t iF = 0; iF < _nodeFields.size(); ++iF ) - { - // (1) write nb subcomponents, nb components(total) - vector< pair<int,int> > iters = _nodeFields[iF]->getIterations(); - const vector<string>& compInfo = _nodeFields[iF]->getInfo(); - const int nbSub = iters.size(); - const int nbComp = compInfo.size(); - const int totalNbComp = nbSub * nbComp; - *_sauvFile << setw(8) << nbSub - << setw(8) << totalNbComp - << setw(8) << -1 // IFOUR - << setw(8) << 0 << endl; // nb attributes - - // (2) for each sub-component (iteration) - // write support, number of values and number of components - fcount.init(10); - vector< int > vals(3); - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec=_nodeFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - // believe that there can be only one type in a nodal field, - // so do not use a loop on types - if ( pfls[0][0].empty() ) pfls[0][0] = noProfileName( types[0] ); - map< string, SubMesh* >::iterator pfl2Sub = _profile2Sub.find( pfls[0][0] ); - if ( pfl2Sub == _profile2Sub.end() ) - THROW_IK_EXCEPTION( "SauvWriter::writeNodalFields(): no sub-mesh for profile |" - << pfls[0][0] << "|"); - vals[0] = -pfl2Sub->second->_id; - vals[1] = (valsVec[0][0].second-valsVec[0][0].first); - vals[2] = compInfo.size(); - for ( size_t i = 0; i < vals.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << vals[i]; - } - fcount.stop(); - - // (3) Write names of components - map<string, string> mapMedToGibi; - makeCompNames( _nodeFields[iF]->getName(), compInfo, mapMedToGibi ); - fcount.init(8); - *_sauvFile << left; - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - for ( size_t i = 0; i < compInfo.size(); ++i, fcount++ ) - *_sauvFile << " " << setw(4) << mapMedToGibi[compInfo[i]]; - *_sauvFile << right; - fcount.stop(); - - // (4) nb harmonics - fcount.init(10); - for ( size_t i = 0; i < (std::size_t)totalNbComp; ++i, fcount++ ) - *_sauvFile << " " << setw(8) << 0; - fcount.stop(); - - string description = _nodeFields[iF]->getName(); - *_sauvFile << endl; // (5) TYPE - *_sauvFile << setw(72) << description.substr(0,71) << endl; // (6) TITRE - //*_sauvFile << endl; // (7) 0 attributes - - // write values of each component - fcount.init( 3 ); // 3 values per a line - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec = _nodeFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - // believe that there can be only one type in a nodal field, - // so do not perform a loop on types - const DataArrayDouble* valsArray = _nodeFields[iF]->getUndergroundDataArray(it.first, it.second); - for ( size_t j = 0; j < compInfo.size(); ++j ) - { - for ( size_t i = valsVec[0][0].first; i < (std::size_t)valsVec[0][0].second; ++i, fcount++ ) - *_sauvFile << setw(22) << valsArray->getIJ( i, j ); - fcount.stop(); - } - } - } // loop on fiels -} - -//================================================================================ -/*! - * \brief Writes "PILE NUMERO 39": fields on cells - */ -//================================================================================ - -void SauvWriter::writeElemFields(map<string,int>& fldNamePrefixMap) -{ - writeFieldNames( /*isNodal=*/false, fldNamePrefixMap ); - - TFieldCounter fcount (*_sauvFile, 10); - - // REAL EXAMPLE - - // (1) 1 2 6 16 - // (2) CARACTERISTIQUES - // (3) -15 317773 4 0 0 0 -2 0 3 - // (4) 317581 - // (5) 0 - // (6) 317767 317761 317755 317815 - // (7) YOUN NU H SIGY - // (8) REAL*8 REAL*8 REAL*8 REAL*8 - // (9) 1 1 0 0 - // (10) 2.00000000000000E+05 - // (9) 1 1 0 0 - // (10) 3.30000000000000E-01 - // (9) 1 1 0 0 - // (10) 1.00000000000000E+04 - // (9) 6 706 0 0 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (10) ... - - for ( size_t iF = 0; iF < _cellFields.size(); ++iF ) - { - // count nb of sub-components - int iSub, nbSub = 0; - vector< pair<int,int> > iters = _cellFields[iF]->getIterations(); - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec = _cellFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - for ( size_t i = 0; i < valsVec.size(); ++i ) - nbSub += valsVec[i].size(); - } - // (1) write nb sub-components, title length - *_sauvFile << setw(8) << nbSub - << setw(8) << -1 // whatever - << setw(8) << 6 // whatever - << setw(8) << 72 << endl; // title length - // (2) title - string title = _cellFields[iF]->getName(); - *_sauvFile << setw(72) << title.substr(0,71) << endl; - *_sauvFile << setw(72) << " " << endl; - - // (3) support, nb components - vector<int> vals(9, 0); - const vector<string>& compInfo = _cellFields[iF]->getInfo(); - vals[2] = compInfo.size(); - fcount.init(10); - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - _cellFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - for ( size_t iType = 0; iType < pfls.size(); ++iType ) - for ( size_t iP = 0; iP < pfls[iType].size(); ++iP ) - { - if ( pfls[iType][iP].empty() ) pfls[iType][iP] = noProfileName( types[iType] ); - map< string, SubMesh* >::iterator pfl2Sub = _profile2Sub.find( pfls[iType][iP] ); - if ( pfl2Sub == _profile2Sub.end() ) - THROW_IK_EXCEPTION( "SauvWriter::writeElemFields(): no sub-mesh for profile |" - << pfls[iType][iP] << "|"); - const int supportID = pfl2Sub->second->_id; - vals[0] = -supportID; - - for ( size_t i = 0; i < vals.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << vals[ i ]; - } - } - fcount.stop(); - - // (4) dummy strings - for ( fcount.init(4), iSub = 0; iSub < nbSub; ++iSub, fcount++ ) - *_sauvFile << " "; - fcount.stop(); - - // (5) dummy strings - for ( fcount.init(8), iSub = 0; iSub < nbSub; ++iSub, fcount++ ) - *_sauvFile << " "; - fcount.stop(); - - // loop on sub-components of a field, each of which refers to - // a certain support and has its own number of components - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - writeElemTimeStamp( iF, it.first, it.second ); - } - } // loop on cell fields -} - -//================================================================================ -/*! - * \brief Write one elemental time stamp - */ -//================================================================================ - -void SauvWriter::writeElemTimeStamp(int iF, int iter, int order) -{ - // (6) 317767 317761 317755 317815 - // (7) YOUN NU H SIGY - // (8) REAL*8 REAL*8 REAL*8 REAL*8 - // (9) 1 1 0 0 - // (10) 2.00000000000000E+05 - // (9) 1 1 0 0 - // (10) 3.30000000000000E-01 - // (9) 1 1 0 0 - // (10) 1.00000000000000E+04 - // (9) 6 706 0 0 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - - TFieldCounter fcount (*_sauvFile, 10); - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec = _cellFields[iF]->getFieldSplitedByType( iter, order, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - for ( size_t iType = 0; iType < pfls.size(); ++iType ) - for ( size_t iP = 0; iP < pfls[iType].size(); ++iP ) - { - const vector<string>& compInfo = _cellFields[iF]->getInfo(); - - // (6) component addresses - int iComp = 0, nbComp = compInfo.size(); - for ( fcount.init(10); iComp < nbComp; ++iComp, fcount++ ) - *_sauvFile << setw(8) << 777; // a good number - fcount.stop(); - - // (7) component names - map<string, string> mapMedToGibi; - makeCompNames( _cellFields[iF]->getName(), compInfo, mapMedToGibi ); - *_sauvFile << left; - for ( fcount.init(8), iComp = 0; iComp < nbComp; ++iComp, fcount++ ) - *_sauvFile << " " << setw(8) << mapMedToGibi[compInfo[iComp]]; - fcount.stop(); - - // (8) component types - for ( fcount.init(4), iComp = 0; iComp < nbComp; ++iComp, fcount++ ) - *_sauvFile << " " << setw(17) << "REAL*8"; - fcount.stop(); - *_sauvFile << right; - - // (9) nb values per element, nb of elements - int nbPntPerCell = 1; - if ( !locs[iType][iP].empty() ) - { - int locID = _cellFields[iF]->getLocalizationId( locs[iType][iP].c_str() ); - nbPntPerCell = _cellFields[iF]->getNbOfGaussPtPerCell( locID ); - } - else if ( typesF[iType][iP] == ON_GAUSS_NE ) - { - nbPntPerCell = INTERP_KERNEL::CellModel::GetCellModel(types[iType]).getNumberOfNodes(); - } - - // (10) values - const std::pair<int,int>& bgEnd = valsVec[iType][iP]; - const DataArrayDouble* valArray = _cellFields[iF]->getUndergroundDataArray(iter, order); - for ( iComp = 0; iComp < nbComp; ++iComp ) - { - *_sauvFile << setw(8) << nbPntPerCell - << setw(8) << (bgEnd.second-bgEnd.first) / nbPntPerCell - << setw(8) << 0 - << setw(8) << 0 - << endl; - fcount.init(3); - for ( size_t i = bgEnd.first; i < (size_t) bgEnd.second; ++i, fcount++ ) - *_sauvFile << setw(22) << valArray->getIJ( i, iComp ); - fcount.stop(); - } - } -} - -//================================================================================ -/*! - * \brief Write the last record of the SAUV file - */ -//================================================================================ - -void SauvWriter::writeLastRecord() -{ - *_sauvFile << " ENREGISTREMENT DE TYPE 5" << endl; - *_sauvFile << "LABEL AUTOMATIQUE : 1" << endl; -} diff --git a/medtool/src/MEDLoader/SauvWriter.hxx b/medtool/src/MEDLoader/SauvWriter.hxx deleted file mode 100644 index 7887296e3..000000000 --- a/medtool/src/MEDLoader/SauvWriter.hxx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SauvWriter.hxx -// Created : Wed Aug 24 11:18:49 2011 -// Author : Edward AGAPOV (eap) - -#ifndef __SAUVWRITER_HXX__ -#define __SAUVWRITER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "SauvUtilities.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include <vector> -#include <string> -#include <map> - -namespace ParaMEDMEM -{ - class MEDFileData; - class MEDFileMesh; - class MEDFileFieldMultiTS; - class DataArrayInt; - - /*! - * \brief Class to write a MEDFileData into a SAUVE format file - */ - class SauvWriter : public ParaMEDMEM::RefCountObject - { - public: - MEDLOADER_EXPORT static SauvWriter *New(); - MEDLOADER_EXPORT void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0); - MEDLOADER_EXPORT void write(const std::string& fileName); - MEDLOADER_EXPORT void setCpyGrpIfOnASingleFamilyStatus(bool status); - MEDLOADER_EXPORT bool getCpyGrpIfOnASingleFamilyStatus() const; - private: - SauvWriter(); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; - /*! - * \brief Class representing a GIBI sub-mesh (described in the pile 1 of the SAUVE file). - * It stands for a named med sub-mesh (family, etc) and contains either cell IDs or other sub-meshes. - */ - struct SubMesh - { - std::vector<int> _cellIDsByType[ INTERP_KERNEL::NORM_MAXTYPE+1 ]; - std::vector<SubMesh*> _subs; - std::string _name; - int _id; - int _nbSauvObjects; - int _dimRelExt; - int nbTypes() const; - static int cellIDsByTypeSize() { return INTERP_KERNEL::NORM_MAXTYPE+1; } - }; - SubMesh* addSubMesh(const std::string& name, int dimRelExt); - - void fillSubMeshes(int& nbSauvObjects, std::map<std::string,int>& nameNbMap); - void fillFamilySubMeshes(); - void fillGroupSubMeshes(); - void fillProfileSubMeshes(); - int evaluateNbProfileSubMeshes() const; - void makeCompNames(const std::string& fieldName, - const std::vector<std::string>& compInfo, - std::map<std::string, std::string>& compMedToGibi ); - void makeProfileIDs( SubMesh* sm, - INTERP_KERNEL::NormalizedCellType type, - const DataArrayInt* profile ); - void writeFileHead(); - void writeSubMeshes(); - void writeCompoundSubMesh(int iSub); - void writeNodes(); - void writeLongNames(); - void writeNodalFields(std::map<std::string,int>& fldNamePrefixMap); - void writeElemFields(std::map<std::string,int>& fldNamePrefixMap); - void writeFieldNames(const bool isNodal, std::map<std::string,int>& fldNamePrefixMap); - void writeElemTimeStamp(int iF, int iter, int order); - void writeLastRecord(); - void writeNames( const std::map<std::string,int>& nameNbMap ); - - private: - - MEDCouplingAutoRefCountObjectPtr< MEDFileMesh > _fileMesh; - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > _nodeFields; - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > _cellFields; - - std::vector<SubMesh> _subs; - std::map< int, SubMesh* > _famIDs2Sub; - std::map< std::string, SubMesh* > _profile2Sub; - enum - { - LN_MAIL=0, LN_CHAM, LN_COMP, LN_NB - }; - std::vector<SauvUtilities::nameGIBItoMED> _longNames[ LN_NB ]; - - std::fstream* _sauvFile; - bool _cpy_grp_if_on_single_family; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/Swig/CMakeLists.txt b/medtool/src/MEDLoader/Swig/CMakeLists.txt deleted file mode 100644 index 405e7e570..000000000 --- a/medtool/src/MEDLoader/Swig/CMakeLists.txt +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -FIND_PACKAGE(SWIG REQUIRED) -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -SET_SOURCE_FILES_PROPERTIES(MEDLoader.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDLoader.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDLoader_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -SET (MEDLoader_SWIG_DPYS_FILES - MEDLoaderCommon.i - MEDLoaderTypemaps.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/GaussPoints - ${PROJECT_BINARY_DIR}/doc -) - -SET (SWIG_MODULE_MEDLoader_EXTRA_DEPS ${MEDLoader_SWIG_DPYS_FILES} - ${medloader_HEADERS_HXX} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -# SWIG must run after the doc if we want to have the docstrings extracted from Doxygen -# into the Python module: -IF(MEDCOUPLING_BUILD_DOC) - LIST(APPEND SWIG_MODULE_MEDLoader_EXTRA_FLAGS -DWITH_DOCSTRINGS) - LIST(APPEND SWIG_MODULE_MEDLoader_EXTRA_DEPS - ${PROJECT_BINARY_DIR}/doc/MEDLoader_doc.i - swig_ready) -ENDIF() - -SWIG_ADD_MODULE(MEDLoader python MEDLoader.i) -SWIG_LINK_LIBRARIES(MEDLoader ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medloader medcoupling) -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDLoader PROPERTIES DEBUG_OUTPUT_NAME _MEDLoader_d) -ENDIF(WIN32) - -INSTALL(TARGETS _MEDLoader DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) -INSTALL(FILES MEDLoader.i MEDLoaderTypemaps.i MEDLoaderCommon.i DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDLoader.py DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) - -INSTALL(FILES MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py MEDLoaderTest3.py MEDLoaderTest4.py SauvLoaderTest.py MEDLoaderExamplesTest.py MEDLoaderCouplingTrainingSession.py CaseIO.py CaseReader.py CaseWriter.py VTKReader.py MEDLoaderSplitter.py medutilities.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}) -INSTALL(FILES med2sauv PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDCOUPLING_INSTALL_BINS} ) -INSTALL(FILES sauv2med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDCOUPLING_INSTALL_BINS} ) -INSTALL(FILES case2med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDCOUPLING_INSTALL_BINS} ) -INSTALL(FILES med2case PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDCOUPLING_INSTALL_BINS} ) - -ADD_TEST(MEDLoaderTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest.py) -ADD_TEST(MEDLoaderTest2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest2.py) -ADD_TEST(MEDLoaderTest3 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest3.py) -ADD_TEST(MEDLoaderTest4 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest4.py) -ADD_TEST(MEDLoaderExamplesTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderExamplesTest.py) -ADD_TEST(SauvLoaderTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SauvLoaderTest.py) - -IF(NUMPY_FOUND) - ADD_TEST(MEDLoaderCouplingTrainingSession ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderCouplingTrainingSession.py) -ENDIF(NUMPY_FOUND) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDLoader/Swig) - -SET(MEDLOADER_TEST_FILES MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py MEDLoaderTest3.py MEDLoaderTest4.py SauvLoaderTest.py MEDLoaderExamplesTest.py MEDLoaderCouplingTrainingSession.py CaseIO.py CaseReader.py CaseWriter.py VTKReader.py MEDLoaderSplitter.py medutilities.py) - -FOREACH(testfile ${MEDLOADER_TEST_FILES}) - CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/${testfile}" "${CMAKE_CURRENT_BINARY_DIR}/${testfile}" COPYONLY) -ENDFOREACH(testfile) -INSTALL(FILES ${MEDLOADER_TEST_FILES} DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/MEDLoader/Swig/CTestTestfileInstall.cmake b/medtool/src/MEDLoader/Swig/CTestTestfileInstall.cmake deleted file mode 100644 index 819a91abd..000000000 --- a/medtool/src/MEDLoader/Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(MEDLoaderTest python MEDLoaderTest.py) -SET_TESTS_PROPERTIES(MEDLoaderTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderTest2 python MEDLoaderTest2.py) -SET_TESTS_PROPERTIES(MEDLoaderTest2 PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderTest3 python MEDLoaderTest3.py) -SET_TESTS_PROPERTIES(MEDLoaderTest3 PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderTest4 python MEDLoaderTest4.py) -SET_TESTS_PROPERTIES(MEDLoaderTest4 PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderExamplesTest python MEDLoaderExamplesTest.py) -SET_TESTS_PROPERTIES(MEDLoaderExamplesTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(SauvLoaderTest python SauvLoaderTest.py) -SET_TESTS_PROPERTIES(SauvLoaderTest PROPERTIES LABELS "${COMPONENT_NAME}") - -# if numpy is used -ADD_TEST(MEDLoaderCouplingTrainingSession python MEDLoaderCouplingTrainingSession.py) -SET_TESTS_PROPERTIES(MEDLoaderCouplingTrainingSession PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/MEDLoader/Swig/CaseIO.py b/medtool/src/MEDLoader/Swig/CaseIO.py deleted file mode 100644 index 1adece4ed..000000000 --- a/medtool/src/MEDLoader/Swig/CaseIO.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS) - -from MEDLoader import * - -class CaseIO: - dictMCTyp={NORM_HEXA8:"hexa8",NORM_POLYHED:"nfaced",NORM_QUAD4:"quad4",NORM_POLYGON:"nsided",NORM_POINT1:"point",NORM_SEG2:"bar2",NORM_SEG3:"bar3",NORM_TRI3:"tria3",NORM_TRI6:"tria6",NORM_QUAD8:"quad8",NORM_TETRA4:"tetra4",NORM_TETRA10:"tetra10",NORM_PYRA5:"pyramid5",NORM_PYRA13:"pyramid13",NORM_PENTA6:"penta6",NORM_PENTA15:"penta15",NORM_HEXA20:"hexa20"} - discSpatial={ON_CELLS:"element",ON_NODES:"node"} - dictCompo={1:"scalar",3:"vector",6:"tensor",9:"tensor9"} - dictMCTyp2=dict((v,k) for k,v in dictMCTyp.iteritems()) - discSpatial2=dict((v,k) for k,v in discSpatial.iteritems()) - dictCompo2=dict((v,k) for k,v in dictCompo.iteritems()) - pass diff --git a/medtool/src/MEDLoader/Swig/CaseReader.py b/medtool/src/MEDLoader/Swig/CaseReader.py deleted file mode 100644 index 7fc267180..000000000 --- a/medtool/src/MEDLoader/Swig/CaseReader.py +++ /dev/null @@ -1,419 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS) - -# http://www-vis.lbl.gov/NERSC/Software/ensight/doc/OnlineHelp/UM-C11.pdf -import numpy as np -from MEDLoader import * -from CaseIO import CaseIO -import sys,re - -class CaseReader(CaseIO): - """ Converting a file in the Case format (Ensight) to the MED format. - A new file with the same base name and the .med extension is created. - """ - - @classmethod - def New(cls,fileName): - """ Static constructor. """ - return CaseReader(fileName) - pass - - def __init__(self,fileName): - """ Constructor """ - self._fileName=fileName - self._dirName=os.path.dirname(self._fileName) - pass - - def __traduceMesh(self,name,typ,coords,cells): - """ Convert a CASE mesh into a MEDCouplingUMesh. """ - nbCoords=len(coords) - coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) - coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() - ct=self.dictMCTyp2[typ] - m=MEDCouplingUMesh(name,MEDCouplingUMesh.GetDimensionOfGeometricType(ct)) - m.setCoords(coo) - nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(ct) - cI=DataArrayInt(len(cells)+1) ; cI.iota() ; cI*=nbNodesPerCell+1 - # - cells2=cells.reshape(len(cells),nbNodesPerCell) - if cells2.dtype=='int32': - c2=DataArrayInt(cells2) - else: - c2=DataArrayInt(np.array(cells2,dtype="int32")) - pass - c=DataArrayInt(len(cells),nbNodesPerCell+1) ; c[:,0]=ct ; c[:,1:]=c2-1 ; c.rearrange(1) - m.setConnectivity(c,cI,True) - m.checkCoherency2() - return m - - def __traduceMeshForPolyhed(self,name,coords,arr0,arr1,arr2): - nbCoords=len(coords) - coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) - coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() - m=MEDCouplingUMesh(name,3) - m.setCoords(coo) - # - arr2=arr2[:]-1 - arr0mc0=DataArrayInt(arr0) ; arr0mc0.computeOffsets2() - arr0mc1=DataArrayInt(arr0).deepCpy() - arr0mc2=DataArrayInt(len(arr0),2) ; arr0mc2[:,0]=DataArrayInt(arr0)-1 ; arr0mc2[:,1]=1 ; arr0mc2.rearrange(1) ; arr0mc2.computeOffsets2() - arr0mc3=DataArrayInt.Range(0,2*len(arr0),2).buildExplicitArrByRanges(arr0mc2) - arr1mc0=DataArrayInt(arr1) ; arr1mc0.computeOffsets2() - arr1mc1=arr1mc0[arr0mc0] ; arr1mc1[1:]+=arr0mc0[1:] - arr1mc2=DataArrayInt(arr1).deepCpy() ; arr1mc2+=1 ; arr1mc2.computeOffsets2() - arr2mc0=(arr1mc2[1:])[arr0mc3] - # - c=DataArrayInt(arr1.size+arr2.size) - c[arr1mc1[:-1]]=NORM_POLYHED - c[arr2mc0]=-1 - a=arr2mc0.buildUnion(arr1mc1[:-1]).buildComplement(len(c)) - c[a]=DataArrayInt(arr2) - # - m.setConnectivity(c,arr1mc1,True) - m.checkCoherency2() - return m - - def __traduceMeshForPolygon(self,name,coords,arr0,arr1): - nbCoords=len(coords) - coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) - coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() - m=MEDCouplingUMesh(name,2) - m.setCoords(coo) - # - arr0_0=DataArrayInt(arr0+1) ; arr0_0.computeOffsets2() - arr0_1=DataArrayInt(len(arr0),2) ; arr0_1[:,1]=DataArrayInt(arr0) ; arr0_1[:,0]=1 ; arr0_1.rearrange(1) ; arr0_1.computeOffsets2() - arr0_2=DataArrayInt.Range(1,2*len(arr0),2).buildExplicitArrByRanges(arr0_1) - c=DataArrayInt(len(arr0)+len(arr1)) ; c[:]=0 ; c[arr0_0[:-1]]=NORM_POLYGON - c[arr0_2]=DataArrayInt(arr1-1) - # - m.setConnectivity(c,arr0_0,True) - m.checkCoherency2() - return m - - def __convertGeo2MED(self,geoFileName): - """ Convert all the geometry (all the meshes) contained in teh CASE file into MEDCouplingUMesh'es. """ - fd=open(os.path.join(self._dirName,geoFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) ; title=fd.read(80) - title=title.strip().lower() - if "binary" not in title: - raise Exception("Error only binary geo files are supported for the moment !") - pass - zeType=True - if "fortran" in title: - mcmeshes=self.__convertGeo2MEDFortran(fd,end) ; zeType=False - else: - mcmeshes=self.__convertGeo2MEDC(fd,end) - # - ms=MEDFileMeshes() - ms.resize(len(mcmeshes)) - for i,m in enumerate(mcmeshes): - mlm=MEDFileUMesh() - mlm.setMeshAtLevel(0,m) - ms.setMeshAtPos(i,mlm) - pass - return mcmeshes,ms,zeType - - def __convertGeo2MEDFortran(self,fd,end): - mcmeshes=[] - fd.read(80) # comment 1 - fd.read(80) # comment 2 - fd.read(80) # node id - fd.read(80) # element id - pos=fd.tell() - elt=fd.read(80) ; elt=elt.strip() ; pos=fd.tell() - mcmeshes2=[] - typ="part" - nbOfTurn=0 - while abs(pos-end)>8 and "part" in typ: - if "part" not in elt: - raise Exception("Error on reading mesh fortran #1 !") - fd.seek(fd.tell()+4)# skip # - tmp=fd.read(80) ; meshName=tmp.split("P")[-1] - tmp=fd.read(80) - if "coordinates" not in tmp: - raise Exception("Error on reading mesh fortran #2 !") - pos=fd.tell() # 644 - if nbOfTurn==0: - pos+=76 # what else ? - else: - pos+=40 - pass - nbNodes=np.memmap(fd,dtype='>i4',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=12 # what else ? - a=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos),shape=(nbNodes)) - b=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos+nbNodes*4+2*4),shape=(nbNodes)) - c=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos+nbNodes*2*4+4*4),shape=(nbNodes)) - coo=np.zeros(dtype=">f4",shape=(nbNodes*3)) - coo[:nbNodes]=a ; coo[nbNodes:2*nbNodes]=b ; coo[2*nbNodes:]=c - coo=coo.reshape(nbNodes,3) - pos+=nbNodes*3*4 ; fd.seek(pos)#np.array(0,dtype='float%i'%(typeOfCoo)).nbytes - typ=fd.read(80).strip() ; pos=fd.tell() - zeK="" - for k in self.dictMCTyp2.keys(): - if k in typ: - zeK=k - break - pass - pass - pos+=8*4 # yeh man ! - nbCellsOfType=np.memmap(fd,dtype='>i4',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=4 # for the number of cells - pos+=2*4 # because it's great ! - nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(self.dictMCTyp2[zeK]) - nodalConn=np.memmap(fd,dtype='>i4',mode='r',offset=pos,shape=(nbCellsOfType,nbNodesPerCell)) - meshName=meshName.strip() - mcmeshes2.append(self.__traduceMesh(meshName,zeK,coo,nodalConn)) - pos+=nbNodesPerCell*nbCellsOfType*4 - if abs(pos-end)>8: - fd.seek(pos) ;elt=fd.read(80) ; typ=elt[:] ; pos+=80 - pass - nbOfTurn+=1 - pass - #coo=mcmeshes2[0].getCoords() ; name=mcmeshes2[0].getName() - #for itmesh in mcmeshes2: itmesh.setCoords(coo) - #m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(mcmeshes2) ; m.setName(name) - #mcmeshes.append(m) - return mcmeshes2 - - def __convertGeo2MEDC(self,fd,end): - fd.readline() - name=fd.readline().strip() ; fd.readline() ; fd.readline() - pos=fd.tell() - mcmeshes=[] - elt=fd.read(80) ; elt=elt.strip() ; pos+=80 - while pos!=end: - if "part" not in elt: - raise Exception("Error on reading mesh #1 !") - fd.seek(fd.tell()+4) - meshName=fd.read(80).strip() - if fd.read(len("coordinates"))!="coordinates": - raise Exception("Error on reading mesh #2 !") - pos=fd.tell() - typeOfCoo=np.memmap(fd,dtype='byte',mode='r',offset=int(pos),shape=(1)).tolist()[0] - pos+=1+17*4 - nbNodes=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=4 - coo=np.memmap(fd,dtype='float32',mode='r',offset=int(pos),shape=(nbNodes,3)) - pos+=nbNodes*3*4 ; fd.seek(pos)#np.array(0,dtype='float%i'%(typeOfCoo)).nbytes - typ=fd.read(80).strip() ; pos=fd.tell() - mcmeshes2=[] - while pos!=end and typ!="part": - mctyp=self.dictMCTyp2[typ] - nbCellsOfType=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=4 - if mctyp!=NORM_POLYHED and mctyp!=NORM_POLYGON: - nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(mctyp) - cells=np.memmap(fd,dtype='int32',mode='r',offset=pos,shape=(nbCellsOfType,nbNodesPerCell)) - pos+=nbCellsOfType*nbNodesPerCell*4 - fd.seek(pos) - mcmeshes2.append(self.__traduceMesh(meshName,typ,coo,cells)) - elif mctyp==NORM_POLYHED: - nbOfFacesPerCell=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(nbCellsOfType,)) - pos+=nbCellsOfType*4 - szOfNbOfNodesPerFacePerCellArr=int(nbOfFacesPerCell.sum()) - arr1=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNbOfNodesPerFacePerCellArr,))#arr1 -> nbOfNodesPerFacePerCellArr - pos+=szOfNbOfNodesPerFacePerCellArr*4 - szOfNodesPerFacePerCellArr=arr1.sum() - arr2=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNodesPerFacePerCellArr,))#arr2 -> nodesPerFacePerCellArr - pos+=szOfNodesPerFacePerCellArr*4 ; fd.seek(pos) - mcmeshes2.append(self.__traduceMeshForPolyhed(meshName,coo,nbOfFacesPerCell,arr1,arr2)) - pass - else: - nbOfNodesPerCell=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(nbCellsOfType,)) - pos+=nbCellsOfType*4 - szOfNbOfNodesPerCellArr=int(nbOfNodesPerCell.sum()) - arr1=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNbOfNodesPerCellArr,)) - pos+=szOfNbOfNodesPerCellArr*4 ; fd.seek(pos) - mcmeshes2.append(self.__traduceMeshForPolygon(meshName,coo,nbOfNodesPerCell,arr1)) - if pos!=end: - elt=fd.read(80) ; elt=elt.strip() ; typ=elt[:] ; pos+=80 - pass - pass - coo=mcmeshes2[0].getCoords() ; name=mcmeshes2[0].getName() - for itmesh in mcmeshes2: itmesh.setCoords(coo) - m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(mcmeshes2) ; m.setName(name) - mcmeshes.append(m) - pass - return mcmeshes - - - def __convertField(self,mlfields, mcmeshes, fileName, fieldName, discr, nbCompo, locId, it): - """ Convert the fields. """ - stars=re.search("[\*]+",fileName).group() - st="%0"+str(len(stars))+"i" - trueFileName=fileName.replace(stars,st%(it)) - fd=open(os.path.join(self._dirName,trueFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) - name=fd.readline().strip().split(" ")[0] - if name!=fieldName: - raise Exception("ConvertField : mismatch") - pos=fd.tell() - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - while pos!=end: - if st!="part": - raise Exception("ConvertField : mismatch #2") - fdisc=MEDCouplingFieldDiscretization.New(self.discSpatial2[discr]) - meshId=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1)).tolist()[0]-1 - nbOfValues=fdisc.getNumberOfTuples(mcmeshes[meshId]) - vals2=DataArrayDouble(nbOfValues,nbCompo) - fd.seek(pos+4) - st=fd.read(80).strip() ; pos=fd.tell() - offset=0 - while pos!=end and st!="part": - if st!="coordinates": - nbOfValsOfTyp=mcmeshes[meshId].getNumberOfCellsWithType(self.dictMCTyp2[st]) - else: - nbOfValsOfTyp=nbOfValues - pass - vals=np.memmap(fd,dtype='float32',mode='r',offset=int(pos),shape=(nbOfValsOfTyp,nbCompo))#np.memmap(fd,dtype='int32',mode='r',offset=159,shape=(1)) - vals2[offset:offset+nbOfValsOfTyp]=DataArrayDouble(np.array(vals,dtype='float64')).fromNoInterlace() - pos+=nbOfValsOfTyp*nbCompo*4 ; fd.seek(pos) - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - offset+=nbOfValsOfTyp - pass - f=MEDCouplingFieldDouble(self.discSpatial2[discr],ONE_TIME) ; f.setName("%s_%s"%(fieldName,mcmeshes[meshId].getName())) - f.setMesh(mcmeshes[meshId]) ; f.setArray(vals2) ; f.setTime(float(it),it,-1) - f.checkCoherency() - mlfields[locId+meshId].appendFieldNoProfileSBT(f) - pass - - def __convertFieldFortran(self,mlfields, mcmeshes, fileName, fieldName, discr, nbCompo, locId, it): - """ Convert the fields. """ - if re.search("[\*]+",fileName): - stars=re.search("[\*]+",fileName).group() - st="%0"+str(len(stars))+"i" - trueFileName=fileName.replace(stars,st%(it)) - pass - else: - trueFileName=fileName - pass - fd=open(os.path.join(self._dirName,trueFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) - name=fd.read(80) - if fieldName not in name: - raise Exception("ConvertField : mismatch") - pos=fd.tell() - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - if "part" not in st: - raise Exception("ConvertField : mismatch #2") - st=fd.read(80).strip() ; pos=fd.tell() - pos+=12 # I love it - offset=0 - nbTurn=0 - while pos!=end and "part" not in st: - fdisc=MEDCouplingFieldDiscretization.New(self.discSpatial2[discr]) - nbOfValues=fdisc.getNumberOfTuples(mcmeshes[nbTurn]) - vals2=DataArrayDouble(nbOfValues,nbCompo) - pos+=24 # I love it again ! - nbOfValsOfTyp=np.memmap(fd,dtype='>i4',mode='r',offset=pos,shape=(1)).tolist()[0]/4 - pos+=4 - vals=np.zeros(dtype=">f4",shape=(nbOfValsOfTyp*nbCompo)) - for iii in xrange(nbCompo): - valsTmp=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos),shape=(nbOfValsOfTyp)) - vals[iii*nbOfValsOfTyp:(iii+1)*nbOfValsOfTyp]=valsTmp - pos+=nbOfValsOfTyp*4 - pos+=2*4 ## hey hey, that is the ultimate class ! - vals2.setInfoOnComponent(iii,chr(ord('X')+iii)) - pass - if pos>end: - pos=end - pass - vals=vals.reshape(nbOfValsOfTyp,nbCompo) - vals2[offset:offset+nbOfValsOfTyp]=DataArrayDouble(np.array(vals,dtype='float64')).fromNoInterlace() - if pos!=end: - fd.seek(pos) - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - pass - f=MEDCouplingFieldDouble(self.discSpatial2[discr],ONE_TIME) ; f.setName("%s_%s"%(fieldName,mcmeshes[nbTurn].getName())) - f.setMesh(mcmeshes[nbTurn]) ; f.setArray(vals2) ; f.setTime(float(it),it,-1) - f.checkCoherency() - mlfields[locId+nbTurn].appendFieldNoProfileSBT(f) - nbTurn+=1 - pass - pass - - def loadInMEDFileDS(self): - """ Load a CASE file into a MEDFileData object. """ - f=file(self._fileName) - lines=f.readlines() - ind=lines.index("GEOMETRY\n") - if ind==-1: - raise Exception("Error with file %s"%(fname)) - geoName=re.match("model:([\W]*)([\w\.]+)",lines[ind+1]).group(2) - m1,m2,typeOfFile=self.__convertGeo2MED(geoName) - fieldsInfo=[] ; nbOfTimeSteps=0 - if "VARIABLE\n" in lines: - ind=lines.index("VARIABLE\n") - end=len(lines)-1 - if "TIME\n" in lines: - end=lines.index("TIME\n") - pass - for i in xrange(ind+1,end): - m=re.match("^([\w]+)[\s]+\per[\s]+([\w]+)[\s]*\:[\s]*([\w]+)[\s]+([\S]+)$",lines[i]) - if m: - if m.groups()[0]=="constant": - continue - spatialDisc=m.groups()[1] ; fieldName=m.groups()[2] ; nbOfCompo=self.dictCompo2[m.groups()[0]] ; fieldFileName=m.groups()[3] - fieldsInfo.append((fieldName,spatialDisc,nbOfCompo,fieldFileName)) - pass - pass - - expr=re.compile("number[\s]+of[\s]+steps[\s]*\:[\s]*([\d]+)") - tmp=filter(expr.search,lines) - if len(tmp)!=0: - nbOfTimeSteps=int(expr.search(filter(expr.search,lines)[0]).group(1)) - expr=re.compile("filename[\s]+start[\s]+number[\s]*\:[\s]*([\d]+)") - startIt=int(expr.search(filter(expr.search,lines)[0]).group(1)) - expr=re.compile("filename[\s]+increment[\s]*\:[\s]*([\d]+)") - incrIt=int(expr.search(filter(expr.search,lines)[0]).group(1)) - else: - nbOfTimeSteps=1 - startIt=0 - incrIt=1 - pass - curIt=startIt - pass - mlfields=MEDFileFields() - mlfields.resize(len(fieldsInfo)*len(m1)) - i=0 - for field in fieldsInfo: - for m in m1: - mlfields.setFieldAtPos(i,MEDFileFieldMultiTS()) - i+=1 - pass - pass - for ts in xrange(nbOfTimeSteps): - i=0 - for field in fieldsInfo: - if typeOfFile: - self.__convertField(mlfields,m1,field[3],field[0],field[1],field[2],i,curIt); - else: - self.__convertFieldFortran(mlfields,m1,field[3],field[0],field[1],field[2],i,curIt) - pass - i+=len(m1) - pass - curIt+=incrIt - pass - ret=MEDFileData() - ret.setMeshes(m2) - del mlfields[filter(lambda x: len(mlfields[x])==0,range(len(mlfields)))] - ret.setFields(mlfields) - return ret - - pass diff --git a/medtool/src/MEDLoader/Swig/CaseWriter.py b/medtool/src/MEDLoader/Swig/CaseWriter.py deleted file mode 100644 index cb80579b5..000000000 --- a/medtool/src/MEDLoader/Swig/CaseWriter.py +++ /dev/null @@ -1,349 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS) - -import numpy as np -from CaseIO import CaseIO -from MEDLoader import * -import sys,re,os,mmap - -### www-vis.lbl.gov/NERSC/Software/ensight/doc/OnlineHelp/UM-C11.pdf - -class CaseWriter(CaseIO): - """ Converting MED file format in memory to a the Case file format (Ensight). - A new file with the same base name and the .case extension is created with its depencies (.geo ...). - """ - - header="""FORMAT -type: ensight gold -GEOMETRY -model: %(geofilewithoutpath)s -""" - header_varpart="""VARIABLE""" - header_timepart="""TIME -time set: 1 -number of steps: %(NbTimeSteps)i -filename start number: 0 -filename increment: 1 -time values: -%(TimeValues)s -""" - - @classmethod - def New(cls): - """ Static constructor. """ - return CaseWriter() - pass - - def __init__(self): - """ Constructor """ - self.__export_groups=False - pass - - def setMEDFileDS(self,medData): - """ Input should be MEDFileData instance """ - self._med_data=medData - pass - - def isExportingGroups(self): - """ return the status of exporting groups policy """ - return self.__export_groups - - def setExportingGroups(self,status): - assert(isinstance(status,bool)) - self.__export_groups=status - pass - - - def write(self,fileName): - """ Write into the specified fileName series the result """ - self._file_name=fileName - self._base_name_without_dir=os.path.splitext(os.path.basename(self._file_name))[0] - self._l=self._file_name.split(os.path.sep) ; self._l[-1]=os.path.splitext(self._l[-1])[0] - self._base_name_with_dir=os.path.sep.join(self._l) - self._real_written_file_name=[] - self._dico={} - for mesh in self._med_data.getMeshes(): - additionnalFileNamePart="" - if len(self._med_data.getMeshes())!=1: - additionnalFileNamePart="_%s"%(mesh.getName()) - pass - self._dico["geofilewithoutpath"]="%s%s.geo"%(self._base_name_without_dir,additionnalFileNamePart) - h0=self.header%self._dico - self.__writeMeshesPart(mesh,"%s%s.geo"%(self._base_name_with_dir,additionnalFileNamePart)) - # - h2=self.__writeFieldsPart(self._med_data.getFields().partOfThisLyingOnSpecifiedMeshName(mesh.getName())) - realWrittenCaseFileNameForCurMesh="%s%s.case"%(self._base_name_with_dir,additionnalFileNamePart) - fheader=open(realWrittenCaseFileNameForCurMesh,"w") ; fheader.write((h0+h2)%self._dico) - self._real_written_file_name.append(realWrittenCaseFileNameForCurMesh) - pass - return self._real_written_file_name - - def __writeMeshesPart(self,mdm,meshfn): - try: - os.remove(meshfn) - except: - pass - f=open(meshfn,"w+b") - sz=5*80 - # - assert(isinstance(mdm,MEDFileUMesh)) - ms2=[[mdm.getMeshAtLevel(lev) for lev in mdm.getNonEmptyLevels()[:1]]] - if self.__export_groups: - for grpnm in mdm.getGroupsNames(): - ms3=[] - for lev in mdm.getGrpNonEmptyLevels(grpnm)[:1]: - m=mdm.getGroup(lev,grpnm) ; m.zipCoords() - ms3.append(m) - pass - ms2.append(ms3) - pass - pass - for ms in ms2: - nn=ms[0].getNumberOfNodes() - sz+=self.__computeSizeOfGeoFile(ms,nn) - pass - pass - a=np.memmap(f,dtype='byte',mode='w+',offset=0,shape=(sz,)) ; a.flush() # truncate to set the size of the file - mm=mmap.mmap(f.fileno(),offset=0,length=0) - mm.write(self.__str80("C Binary")) - mm.write(self.__str80("Exported from MEDCoupling/MEDLoader version %s"%(MEDCouplingVersionStr()))) - mm.write(self.__str80("Conversion using CaseWriter class")) - mm.write(self.__str80("node id off")) - mm.write(self.__str80("element id off")) - for iii,ms in enumerate(ms2): - nn=ms[0].getNumberOfNodes() - mm.write(self.__str80("part")) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=iii+1 ; a.flush() ; mm.seek(mm.tell()+4) # part number maybe to change ? - name=ms[0].getName() - if iii>0: - name="%s_%s"%(ms2[0][0].getName(),name) - pass - mm.write(self.__str80(name)) - mm.write(self.__str80("coordinates")) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=nn ; a.flush() # number of nodes - mm.seek(mm.tell()+4) - coo=ms[0].getCoords() - spaceDim=coo.getNumberOfComponents() - if spaceDim!=3: - coo=coo.changeNbOfComponents(3,0.) - pass - a=np.memmap(f,dtype='float32',mode='w+',offset=mm.tell(),shape=(3,nn)) - c=coo.toNoInterlace() ; c.rearrange(1) ; cnp=c.toNumPyArray() ; cnp=cnp.reshape(3,nn) - a[:]=cnp ; a.flush() ; mm.seek(mm.tell()+3*nn*4) - for m in ms: - i=0 - for typ2,nbelem,dummy in m.getDistributionOfTypes(): - typ=typ2 - if typ not in self.dictMCTyp: - typ=MEDCouplingMesh.GetCorrespondingPolyType(typ) - pass - mp=m[i:i+nbelem] - mm.write(self.__str80(self.dictMCTyp[typ])) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=nbelem ; a.flush() ; mm.seek(mm.tell()+4) - if typ!=NORM_POLYHED and typ!=NORM_POLYGON: - nbNodesPerElem=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(typ) - c=mp.getNodalConnectivity() ; c.rearrange(nbNodesPerElem+1) ; c=c[:,1:] ; c.rearrange(1) ; c+=1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(nbNodesPerElem*nbelem,)) - a[:]=c.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+nbNodesPerElem*nbelem*4) - pass - elif typ==NORM_POLYHED: - mp.orientCorrectlyPolyhedrons() - c=mp.computeNbOfFacesPerCell() - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(nbelem,)) - a[:]=c.toNumPyArray(); a.flush() ; mm.seek(mm.tell()+nbelem*4) - c=mp.getNodalConnectivity()[:] ; c.pushBackSilent(-1) ; c[mp.getNodalConnectivityIndex()[:-1]]=-1 ; ids=c.getIdsEqual(-1) ; nbOfNodesPerFace=ids.deltaShiftIndex()-1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(nbOfNodesPerFace),)) - a[:]=nbOfNodesPerFace.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(nbOfNodesPerFace)*4) - ids2=ids.buildComplement(ids.back()+1) - c2=mp.getNodalConnectivity()[ids2]+1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(c2),)) - a[:]=c2.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(c2)*4) - pass - else: - nbOfNodesPerCell=mp.getNodalConnectivityIndex().deltaShiftIndex()-1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(nbOfNodesPerCell),)) - a[:]=nbOfNodesPerCell.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(nbOfNodesPerCell)*4) - ids2=mp.getNodalConnectivityIndex().buildComplement(mp.getNodalConnectivityIndex().back()+1) - c2=mp.getNodalConnectivity()[ids2]+1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(c2),)) - a[:]=c2.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(c2)*4) - pass - i+=nbelem - pass - pass - pass - pass - - def __writeFieldsPart(self,mdfs): - if not mdfs: - return "" - self._ze_top_dict={} - its,areForgottenTS=mdfs.getCommonIterations() - if areForgottenTS: - print "WARNING : some iterations are NOT present in all fields ! Kept iterations are : %s !"%(str(its)) - pass - TimeValues="" - for it in its: - TimeValues+="%s\n"%(str(mdfs[0][it].getTime()[-1])) - pass - dictVars={} - for mdf in mdfs: - nbCompo=mdf.getNumberOfComponents() - if nbCompo not in self.dictCompo: - l=filter(lambda x:x-nbCompo>0,self.dictCompo.keys()) - if len(l)==0: - print "Field \"%s\" will be ignored because number of components (%i) is too big to be %s supported by case files !"%(mdf.getName(),nbCompo,str(self.dictCompo.keys())) - continue - pass - print "WARNING : Field \"%s\" will have its number of components (%i) set to %i, in order to be supported by case files (must be in %s) !"%(mdf.getName(),nbCompo,l[0],str(self.dictCompo.keys())) - nbCompo=l[0] - pass - if nbCompo in dictVars: - dictVars[nbCompo].append(mdf) - pass - else: - dictVars[nbCompo]=[mdf] - pass - pass - for mdf in mdfs: - nbCompo=mdf.getNumberOfComponents() - if nbCompo not in self.dictCompo: - l=filter(lambda x:x-nbCompo>0,self.dictCompo.keys()) - if len(l)==0: - continue; - nbCompo=l[0] - pass - for iii,it in enumerate(its): - ff=mdf[it] - isMultiDisc=len(ff.getTypesOfFieldAvailable())>1 - for typ in ff.getTypesOfFieldAvailable(): - l=self._l[:] ; l[-1]="%s%s.%s"%(self._base_name_without_dir,str(iii).rjust(4,"0"),ff.getName()) - if isMultiDisc: - l[-1]="%s_%s"(l[-1],MEDCouplingFieldDiscretization.New(typ).getStringRepr()) - pass - fffn=l[-1] - try: - os.remove(os.path.sep.join(l)) - except: - pass - f=open(os.path.sep.join(l),"w+b") - summ=0 - for geo,[(curTyp,(bg,end),pfl,loc)] in ff.getFieldSplitedByType(): - if typ==curTyp: - summ+=4*nbCompo*(end-bg)+80 - pass - pass - a=np.memmap(f,dtype='byte',mode='w+',offset=0,shape=(2*80+4+summ,)) ; a.flush() # truncate to set the size of the file - mm=mmap.mmap(f.fileno(),offset=0,length=0) - k1=ff.getName() - if isMultiDisc: - k1="%s_%s"%(k1,MEDCouplingFieldDiscretization.New(typ).getStringRepr()) - pass - mm.write(self.__str80(k1)) - mm.write(self.__str80("part")) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=1 ; a.flush() ; mm.seek(mm.tell()+4) # part number maybe to change ? - for geo,[(curTyp,(bg,end),pfl,loc)] in ff.getFieldSplitedByType(): - if pfl!="": - raise Exception("Field \"%s\" contains profiles ! Profiles are not supported yet !"%(mdf.getName())) - if typ==curTyp: - arr=ff.getUndergroundDataArray()[bg:end].changeNbOfComponents(nbCompo,0.) ; arr=arr.toNoInterlace() - if typ==ON_CELLS: - mm.write(self.__str80(self.dictMCTyp[geo])) - pass - elif typ==ON_NODES: - mm.write(self.__str80("coordinates")) - pass - else: - print "UnManaged type of field for field \"%s\" !"%(mdf.getName()) - pass - a=np.memmap(f,dtype='float32',mode='w+',offset=mm.tell(),shape=(nbCompo,end-bg)) - b=arr.toNumPyArray() ; b=b.reshape(nbCompo,end-bg) - a[:]=b - a.flush() ; mm.seek(mm.tell()+nbCompo*(end-bg)*4) - pass - pass - k="%s per %s"%(self.dictCompo[nbCompo],self.discSpatial[typ]) - if k in self._ze_top_dict: - if k1 in self._ze_top_dict[k]: - self._ze_top_dict[k][k1].append(fffn) - pass - else: - self._ze_top_dict[k][k1]=[fffn] - pass - else: - self._ze_top_dict[k]={k1:[fffn]} - pass - pass - pass - pass - headerPart="" - if len(self._ze_top_dict)!=0: - hvp=self.header_varpart[:] - for k in self._ze_top_dict: - for k1 in self._ze_top_dict[k]: - hvp+="\n%s: %s %s"%(k,k1,re.sub("([\d]{4})",4*"*",self._ze_top_dict[k][k1][0])) - pass - pass - hvp+="\n" - headerPart+=hvp - # - ddd={"NbTimeSteps":len(its),"TimeValues":TimeValues} - htp=self.header_timepart%ddd - headerPart+=htp - pass - return headerPart - - @classmethod - def __str80(cls,st): - if len(st)>79: - raise Exception("String \"%s\" is too long (>79) !"%(st)) - return st.ljust(79)+"\n" - - def __computeSizeOfGeoFile(self,listOfMeshes,nn): - sz=0 - for m in listOfMeshes: - distribTypes=m.getDistributionOfTypes() - sz+=80+4+2*80+4+nn*3*4 - i=0 - for typ2,nbelem,dummy in distribTypes: - typ=typ2 - if typ not in self.dictMCTyp: - typ=MEDCouplingMesh.GetCorrespondingPolyType() - pass - if typ!=NORM_POLYHED and typ!=NORM_POLYGON: - sz+=80+4+MEDCouplingMesh.GetNumberOfNodesOfGeometricType(typ)*nbelem*4 - pass - elif typ==NORM_POLYHED: - mplh=m[i:i+nbelem] ; delta=len(mplh.getNodalConnectivity())+nbelem - sz+=80+4+delta*4 - pass - else: - mplh=m[i:i+nbelem] ; delta=len(mplh.getNodalConnectivity()) - sz+=80+4+delta*4 - pass - i+=nbelem - pass - pass - return sz diff --git a/medtool/src/MEDLoader/Swig/MEDLoader.i b/medtool/src/MEDLoader/Swig/MEDLoader.i deleted file mode 100644 index d85b63816..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoader.i +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -%include "MEDLoaderCommon.i" - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____imod___(self, self, *args) -def ParaMEDMEMDenseMatrixIadd(self,*args): - import _MEDLoader - return _MEDLoader.DenseMatrix____iadd___(self, self, *args) -def ParaMEDMEMDenseMatrixIsub(self,*args): - import _MEDLoader - return _MEDLoader.DenseMatrix____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCoupling1DGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCoupling1SGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingCurveLinearMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingCMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingIMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingExtrudedMesh____new___(cls,args) -%} - -%pythoncode %{ -def ParaMEDMEMMEDFileUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDFileUMesh____new___(cls,args) -%} - -%include "MEDCouplingFinalize.i" - -%pythoncode %{ -MEDFileUMesh.__new__=classmethod(ParaMEDMEMMEDFileUMeshnew) -del ParaMEDMEMMEDFileUMeshnew -%} diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderCommon.i b/medtool/src/MEDLoader/Swig/MEDLoaderCommon.i deleted file mode 100644 index 310810e20..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderCommon.i +++ /dev/null @@ -1,3693 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -%module MEDLoader - -#define MEDCOUPLING_EXPORT -#define MEDLOADER_EXPORT - -#ifdef WITH_DOCSTRINGS -%include "MEDLoader_doc.i" -#endif - -%include "MEDCouplingCommon.i" - -%{ -#include "MEDLoader.hxx" -#include "MEDFileJoint.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "MEDFileParameter.hxx" -#include "MEDFileData.hxx" -#include "MEDFileEquivalence.hxx" -#include "MEDFileMeshReadSelector.hxx" -#include "MEDFileFieldOverView.hxx" -#include "MEDLoaderTypemaps.i" -#include "SauvReader.hxx" -#include "SauvWriter.hxx" - -using namespace ParaMEDMEM; -%} - -#if SWIG_VERSION >= 0x010329 -%template() std::vector<std::string>; -#endif - -%typemap(out) ParaMEDMEM::MEDFileMesh* -{ - $result=convertMEDFileMesh($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDFileParameter1TS* -{ - $result=convertMEDFileParameter1TS($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDFileAnyTypeFieldMultiTS* -{ - $result=convertMEDFileFieldMultiTS($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDFileAnyTypeField1TS* -{ - $result=convertMEDFileField1TS($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDMeshMultiLev* -{ - $result=convertMEDMeshMultiLev($1,$owner); -} - -%newobject MEDLoader::ReadUMeshFromFamilies; -%newobject MEDLoader::ReadUMeshFromGroups; -%newobject MEDLoader::ReadUMeshFromFile; -%newobject MEDLoader::ReadMeshFromFile; -%newobject MEDLoader::ReadField; -%newobject MEDLoader::ReadFieldCell; -%newobject MEDLoader::ReadFieldNode; -%newobject MEDLoader::ReadFieldGauss; -%newobject MEDLoader::ReadFieldGaussNE; -%newobject ParaMEDMEM::MEDFileMesh::New; -%newobject ParaMEDMEM::MEDFileMesh::createNewEmpty; -%newobject ParaMEDMEM::MEDFileMesh::deepCpy; -%newobject ParaMEDMEM::MEDFileMesh::shallowCpy; -%newobject ParaMEDMEM::MEDFileMesh::getGenMeshAtLevel; -%newobject ParaMEDMEM::MEDFileMesh::__getitem__; -%newobject ParaMEDMEM::MEDFileMesh::getGroupArr; -%newobject ParaMEDMEM::MEDFileMesh::getGroupsArr; -%newobject ParaMEDMEM::MEDFileMesh::getFamilyArr; -%newobject ParaMEDMEM::MEDFileMesh::getFamiliesArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupsArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeFamilyArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeFamiliesArr; -%newobject ParaMEDMEM::MEDFileMesh::getAllFamiliesIdsReferenced; -%newobject ParaMEDMEM::MEDFileMesh::computeAllFamilyIdsInUse; -%newobject ParaMEDMEM::MEDFileMesh::getEquivalences; -%newobject ParaMEDMEM::MEDFileData::getJoints; -%newobject ParaMEDMEM::MEDFileStructuredMesh::getImplicitFaceMesh; -%newobject ParaMEDMEM::MEDFileUMesh::New; -%newobject ParaMEDMEM::MEDFileUMesh::LoadPartOf; -%newobject ParaMEDMEM::MEDFileUMesh::getCoords; -%newobject ParaMEDMEM::MEDFileUMesh::getPartDefAtLevel; -%newobject ParaMEDMEM::MEDFileUMesh::getGroup; -%newobject ParaMEDMEM::MEDFileUMesh::getGroups; -%newobject ParaMEDMEM::MEDFileUMesh::getFamily; -%newobject ParaMEDMEM::MEDFileUMesh::getFamilies; -%newobject ParaMEDMEM::MEDFileUMesh::getMeshAtLevel; -%newobject ParaMEDMEM::MEDFileUMesh::getLevel0Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh; -%newobject ParaMEDMEM::MEDFileUMesh::extractFamilyFieldOnGeoType; -%newobject ParaMEDMEM::MEDFileUMesh::extractNumberFieldOnGeoType; -%newobject ParaMEDMEM::MEDFileUMesh::zipCoords; -%newobject ParaMEDMEM::MEDFileUMesh::buildExtrudedMesh; -%newobject ParaMEDMEM::MEDFileUMesh::linearToQuadratic; -%newobject ParaMEDMEM::MEDFileUMesh::quadraticToLinear; -%newobject ParaMEDMEM::MEDFileCMesh::New; -%newobject ParaMEDMEM::MEDFileCurveLinearMesh::New; -%newobject ParaMEDMEM::MEDFileMeshMultiTS::New; -%newobject ParaMEDMEM::MEDFileMeshMultiTS::deepCpy; -%newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep; -%newobject ParaMEDMEM::MEDFileMeshes::New; -%newobject ParaMEDMEM::MEDFileMeshes::deepCpy; -%newobject ParaMEDMEM::MEDFileMeshes::getMeshAtPos; -%newobject ParaMEDMEM::MEDFileMeshes::getMeshWithName; -%newobject ParaMEDMEM::MEDFileMeshes::__getitem__; -%newobject ParaMEDMEM::MEDFileMeshes::__iter__; - -%newobject ParaMEDMEM::MEDFileFields::New; -%newobject ParaMEDMEM::MEDFileFields::LoadPartOf; -%newobject ParaMEDMEM::MEDFileFields::LoadSpecificEntities; -%newobject ParaMEDMEM::MEDFileFields::deepCpy; -%newobject ParaMEDMEM::MEDFileFields::shallowCpy; -%newobject ParaMEDMEM::MEDFileFields::getFieldWithName; -%newobject ParaMEDMEM::MEDFileFields::getFieldAtPos; -%newobject ParaMEDMEM::MEDFileFields::partOfThisLyingOnSpecifiedMeshName; -%newobject ParaMEDMEM::MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps; -%newobject ParaMEDMEM::MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps; -%newobject ParaMEDMEM::MEDFileFields::__iter__; - -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::New; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::deepCpy; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::shallowCpy; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStepAtPos; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStep; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::__iter__; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::New; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::LoadSpecificEntities; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevel; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtTopLevel; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldOnMeshAtLevel; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevelOld; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::convertToInt; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::New; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::LoadSpecificEntities; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::convertToDouble; - -%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::New; -%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::shallowCpy; -%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::deepCpy; -%newobject ParaMEDMEM::MEDFileField1TS::New; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevel; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtTopLevel; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldOnMeshAtLevel; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevelOld; -%newobject ParaMEDMEM::MEDFileField1TS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileField1TS::convertToInt; -%newobject ParaMEDMEM::MEDFileIntField1TS::New; -%newobject ParaMEDMEM::MEDFileIntField1TS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileIntField1TS::convertToDouble; - -%newobject ParaMEDMEM::MEDFileData::New; -%newobject ParaMEDMEM::MEDFileData::deepCpy; -%newobject ParaMEDMEM::MEDFileData::getMeshes; -%newobject ParaMEDMEM::MEDFileData::getFields; -%newobject ParaMEDMEM::MEDFileData::getParams; - -%newobject ParaMEDMEM::MEDFileParameterDouble1TS::New; -%newobject ParaMEDMEM::MEDFileParameterDouble1TS::deepCpy; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::New; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::deepCpy; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::getTimeStepAtPos; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::__getitem__; -%newobject ParaMEDMEM::MEDFileParameters::New; -%newobject ParaMEDMEM::MEDFileParameters::deepCpy; -%newobject ParaMEDMEM::MEDFileParameters::getParamAtPos; -%newobject ParaMEDMEM::MEDFileParameters::getParamWithName; -%newobject ParaMEDMEM::MEDFileParameters::__getitem__; - -%newobject ParaMEDMEM::MEDFileJointCorrespondence::New; -%newobject ParaMEDMEM::MEDFileJointCorrespondence::deepCpy; -%newobject ParaMEDMEM::MEDFileJointCorrespondence::shallowCpy; -%newobject ParaMEDMEM::MEDFileJointOneStep::New; -%newobject ParaMEDMEM::MEDFileJointOneStep::deepCpy; -%newobject ParaMEDMEM::MEDFileJointOneStep::shallowCpy; -%newobject ParaMEDMEM::MEDFileJoint::New; -%newobject ParaMEDMEM::MEDFileJoint::deepCpy; -%newobject ParaMEDMEM::MEDFileJoint::shallowCpy; -%newobject ParaMEDMEM::MEDFileJoints::New; -%newobject ParaMEDMEM::MEDFileJoints::deepCpy; -%newobject ParaMEDMEM::MEDFileJoints::getJointAtPos; -%newobject ParaMEDMEM::MEDFileJoints::getJointWithName; -%newobject ParaMEDMEM::MEDFileJoints::__getitem__; -%newobject ParaMEDMEM::MEDFileEquivalences::getEquivalence; -%newobject ParaMEDMEM::MEDFileEquivalences::getEquivalenceWithName; -%newobject ParaMEDMEM::MEDFileEquivalences::appendEmptyEquivalenceWithName; -%newobject ParaMEDMEM::MEDFileEquivalencePair::initCell; -%newobject ParaMEDMEM::MEDFileEquivalencePair::initNode; -%newobject ParaMEDMEM::MEDFileEquivalencePair::getCell; -%newobject ParaMEDMEM::MEDFileEquivalencePair::getNode; -%newobject ParaMEDMEM::MEDFileEquivalenceData::getArray; -%newobject ParaMEDMEM::MEDFileEquivalenceCell::getArray; - -%newobject ParaMEDMEM::SauvWriter::New; -%newobject ParaMEDMEM::SauvReader::New; -%newobject ParaMEDMEM::SauvReader::loadInMEDFileDS; - -%newobject ParaMEDMEM::MEDFileMeshStruct::New; -%newobject ParaMEDMEM::MEDMeshMultiLev::prepare; -%newobject ParaMEDMEM::MEDMeshMultiLev::buildDataArray; -%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::New; -%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport; - -%feature("unref") MEDFileMesh "$this->decrRef();" -%feature("unref") MEDFileUMesh "$this->decrRef();" -%feature("unref") MEDFileCMesh "$this->decrRef();" -%feature("unref") MEDFileMeshMultiTS "$this->decrRef();" -%feature("unref") MEDFileMeshes "$this->decrRef();" -%feature("unref") MEDFileFieldLoc "$this->decrRef();" -%feature("unref") MEDFileAnyTypeField1TS "$this->decrRef();" -%feature("unref") MEDFileField1TS "$this->decrRef();" -%feature("unref") MEDFileIntField1TS "$this->decrRef();" -%feature("unref") MEDFileAnyTypeFieldMultiTS "$this->decrRef();" -%feature("unref") MEDFileFieldMultiTS "$this->decrRef();" -%feature("unref") MEDFileIntFieldMultiTS "$this->decrRef();" -%feature("unref") MEDFileFields "$this->decrRef();" -%feature("unref") MEDFileParameter1TS "$this->decrRef();" -%feature("unref") MEDFileParameterDouble1TSWTI "$this->decrRef();" -%feature("unref") MEDFileParameterDouble1TS "$this->decrRef();" -%feature("unref") MEDFileParameterMultiTS "$this->decrRef();" -%feature("unref") MEDFileParameters "$this->decrRef();" -%feature("unref") MEDFileJointCorrespondence "$this->decrRef();" -%feature("unref") MEDFileJointOneStep "$this->decrRef();" -%feature("unref") MEDFileJoint "$this->decrRef();" -%feature("unref") MEDFileJoints "$this->decrRef();" -%feature("unref") MEDFileEquivalences "$this->decrRef();" -%feature("unref") MEDFileEquivalencePair "$this->decrRef();" -%feature("unref") MEDFileEquivalenceBase "$this->decrRef();" -%feature("unref") MEDFileEquivalenceData "$this->decrRef();" -%feature("unref") MEDFileEquivalenceCell "$this->decrRef();" -%feature("unref") MEDFileEquivalenceNode "$this->decrRef();" -%feature("unref") MEDFileData "$this->decrRef();" -%feature("unref") SauvReader "$this->decrRef();" -%feature("unref") SauvWriter "$this->decrRef();" -%feature("unref") MEDFileFastCellSupportComparator "$this->decrRef();" -%feature("unref") MEDMeshMultiLev "$this->decrRef();" -%feature("unref") MEDUMeshMultiLev "$this->decrRef();" -%feature("unref") MEDCMeshMultiLev "$this->decrRef();" -%feature("unref") MEDCurveLinearMeshMultiLev "$this->decrRef();" -%feature("unref") MEDFileMeshStruct "$this->decrRef();" - -class MEDLoader -{ -public: - static bool HasXDR(); - static std::string MEDFileVersionStr(); - static void SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); - static void SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); - static void SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); - static void CheckFileForRead(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshNames(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetAllFieldNames(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static double GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static void AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj) throw(INTERP_KERNEL::Exception); - %extend - { - static PyObject *MEDFileVersion() - { - int major,minor,release; - MEDLoader::MEDFileVersion(major,minor,release); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,SWIG_From_int(major)); - PyTuple_SetItem(ret,1,SWIG_From_int(minor)); - PyTuple_SetItem(ret,2,SWIG_From_int(release)); - return ret; - } - - static PyObject *GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=MEDLoader::GetFieldIterations(type,fileName,meshName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - static PyObject *GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair< std::pair<int,int>, double> > res=MEDLoader::GetAllFieldIterations(fileName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair< std::pair<int,int>, double> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(3); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first.first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).first.second)); - PyTuple_SetItem(elt,2,SWIG_From_double((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - static PyObject *GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=MEDLoader::GetCellFieldIterations(fileName,meshName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - static PyObject *GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=MEDLoader::GetNodeFieldIterations(fileName,meshName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - static PyObject *GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > res=MEDLoader::GetComponentsNamesOfField(fileName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<std::string,std::string> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,PyString_FromString((*iter).first.c_str())); - PyTuple_SetItem(elt,1,PyString_FromString((*iter).second.c_str())); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - static PyObject *GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception) - { - int meshDim,spaceDim,numberOfNodes; - std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > res=MEDLoader::GetUMeshGlobalInfo(fileName,meshName,meshDim,spaceDim,numberOfNodes); - PyObject *ret=PyTuple_New(4); - PyObject *elt0=PyList_New(res.size()); - int i=0; - for(std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > >::const_iterator it=res.begin();it!=res.end();it++,i++) - { - const std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >&obj2=(*it); - int j=0; - PyObject *elt1=PyList_New(obj2.size()); - for(std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >::const_iterator it2=obj2.begin();it2!=obj2.end();it2++,j++) - { - PyObject *elt2=PyTuple_New(2); - PyTuple_SetItem(elt2,0,SWIG_From_int((int)(*it2).first)); - PyTuple_SetItem(elt2,1,SWIG_From_int((*it2).second)); - PyList_SetItem(elt1,j,elt2); - } - PyList_SetItem(elt0,i,elt1); - } - PyTuple_SetItem(ret,0,elt0); - PyTuple_SetItem(ret,1,SWIG_From_int(meshDim)); - PyTuple_SetItem(ret,2,SWIG_From_int(spaceDim)); - PyTuple_SetItem(ret,3,SWIG_From_int(numberOfNodes)); - return ret; - } - static PyObject *ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, - const std::string& fieldName, PyObject *liIts) throw(INTERP_KERNEL::Exception) - { - std::vector<std::pair<int,int> > its=convertTimePairIdsFromPy(liIts); - std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> res=MEDLoader::ReadFieldsOnSameMesh(type,fileName,meshName,meshDimRelToMax,fieldName,its); - return convertFieldDoubleVecToPy(res); - } - static void WriteUMeshesPartition(const std::string& fileName, const std::string& meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); - MEDLoader::WriteUMeshesPartition(fileName,meshName,v,writeFromScratch); - } - static void WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); - MEDLoader::WriteUMeshesPartitionDep(fileName,meshName,v,writeFromScratch); - } - static void WriteUMeshes(const std::string& fileName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); - MEDLoader::WriteUMeshes(fileName,v,writeFromScratch); - } - static PyObject *GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,meshName,fieldName); - int size=v.size(); - PyObject *ret=PyList_New(size); - for(int i=0;i<size;i++) - PyList_SetItem(ret,i,PyInt_FromLong((int)v[i])); - return ret; - } - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector<std::string> grps; - converPyListToVecString(li,grps); - return MEDLoader::ReadUMeshFromGroups(fileName,meshName,meshDimRelToMax,grps); - } - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector<std::string> fams; - converPyListToVecString(li,fams); - return MEDLoader::ReadUMeshFromFamilies(fileName,meshName,meshDimRelToMax,fams); - } - } - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static int ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static void WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); -}; - -namespace ParaMEDMEM -{ - class MEDFileWritable - { - public: - void copyOptionsFrom(const MEDFileWritable& other) const; - int getTooLongStrPolicy() const throw(INTERP_KERNEL::Exception); - void setTooLongStrPolicy(int newVal) throw(INTERP_KERNEL::Exception); - int getZipConnPolicy() throw(INTERP_KERNEL::Exception); - void setZipConnPolicy(int newVal) throw(INTERP_KERNEL::Exception); - }; - - class MEDFileMeshReadSelector - { - public: - MEDFileMeshReadSelector(); - MEDFileMeshReadSelector(unsigned int code); - unsigned int getCode() const; - void setCode(unsigned int newCode); - bool isCellFamilyFieldReading() const; - bool isNodeFamilyFieldReading() const; - bool isCellNameFieldReading() const; - bool isNodeNameFieldReading() const; - bool isCellNumFieldReading() const; - bool isNodeNumFieldReading() const; - void setCellFamilyFieldReading(bool b); - void setNodeFamilyFieldReading(bool b); - void setCellNameFieldReading(bool b); - void setNodeNameFieldReading(bool b); - void setCellNumFieldReading(bool b); - void setNodeNumFieldReading(bool b); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprAll(oss); - return oss.str(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "MEDFileMeshReadSelector C++ instance at " << self << " (with code=" << self->getCode() << ")."; - return oss.str(); - } - } - }; - - class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJointCorrespondence *New() throw(INTERP_KERNEL::Exception); - static MEDFileJointCorrespondence *New(DataArrayInt* correspondence) // nodes - throw(INTERP_KERNEL::Exception); - static MEDFileJointCorrespondence *New(DataArrayInt* correspondence, // cells - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type) - throw(INTERP_KERNEL::Exception); - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; - MEDFileJointCorrespondence *deepCpy() const; - MEDFileJointCorrespondence *shallowCpy() const; - void setIsNodal(bool isNodal); - bool getIsNodal() const; - bool isEqual(const MEDFileJointCorrespondence *other) const; - void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type); - INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const; - void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type); - INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const; - void setCorrespondence(DataArrayInt *corr) throw(INTERP_KERNEL::Exception); - const DataArrayInt *getCorrespondence() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileJointCorrespondence() - { - return MEDFileJointCorrespondence::New(); - } - MEDFileJointCorrespondence(DataArrayInt* correspondence) throw(INTERP_KERNEL::Exception) - { - return MEDFileJointCorrespondence::New(correspondence); - } - MEDFileJointCorrespondence(DataArrayInt* correspondence, // cells - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type) throw(INTERP_KERNEL::Exception) - { - return MEDFileJointCorrespondence::New(correspondence, loc_geo_type, rem_geo_type); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJointOneStep *New(int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); - static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1) throw(INTERP_KERNEL::Exception); - MEDFileJointOneStep *deepCpy() const; - MEDFileJointOneStep *shallowCpy() const; - bool isEqual(const MEDFileJointOneStep *other) const; - void setOrder(int order); - int getOrder() const; - void setIteration(int it); - int getIteration() const; - void pushCorrespondence(MEDFileJointCorrespondence* correspondence); - int getNumberOfCorrespondences() const; - MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const; - void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileJointOneStep() - { - return MEDFileJointOneStep::New(); - } - - MEDFileJointOneStep(const std::string& fileName, const std::string& mName, const std::string& jointName, int number) throw(INTERP_KERNEL::Exception) - { - return MEDFileJointOneStep::New(fileName,mName,jointName,number); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileJoint : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJoint *New() throw(INTERP_KERNEL::Exception); - static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception); - static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ) throw(INTERP_KERNEL::Exception); - MEDFileJoint *deepCpy() const; - MEDFileJoint *shallowCpy() const; - bool isEqual(const MEDFileJoint *other) const; - void setLocalMeshName(const std::string& name); - std::string getLocalMeshName() const; - void setRemoteMeshName(const std::string& name); - std::string getRemoteMeshName() const; - void setDescription(const std::string& name); - std::string getDescription() const; - void setJointName(const std::string& name); - std::string getJointName() const; - bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception); - void setDomainNumber(const int& number); - int getDomainNumber() const; - void pushStep(MEDFileJointOneStep* step); - int getNumberOfSteps() const; - MEDFileJointOneStep *getStepAtPos(int i) const; - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const; - %extend - { - MEDFileJoint() - { - return MEDFileJoint::New(); - } - - MEDFileJoint(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception) - { - return MEDFileJoint::New(fileName,mName,num); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileJoints : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJoints *New() throw(INTERP_KERNEL::Exception); - static MEDFileJoints *New(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - MEDFileJoints *deepCpy() const; - std::string simpleRepr() const; - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::string getMeshName() const; - int getNumberOfJoints() const; - std::vector<std::string> getJointsNames() const; - bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception); - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushJoint(MEDFileJoint *joint); - void setJointAtPos(int i, MEDFileJoint *joint) throw(INTERP_KERNEL::Exception); - void destroyJointAtPos(int i) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileJoints() - { - return MEDFileJoints::New(); - } - - MEDFileJoints(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception) - { - return MEDFileJoints::New(fileName,meshName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileJoint *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(PyInt_Check(obj)) - { - MEDFileJoint *ret=self->getJointAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfJoints())); - if(ret) - ret->incrRef(); - return ret; - } - else if(PyString_Check(obj)) - { - MEDFileJoint *ret=self->getJointWithName(PyString_AsString(obj)); - if(ret) - ret->incrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("MEDFileJoints::__getitem__ : only integer or string with meshname supported !"); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfJoints(); - } - - MEDFileJoint *getJointAtPos(int i) const throw(INTERP_KERNEL::Exception) - { - MEDFileJoint *ret=self->getJointAtPos(i); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileJoint *getJointWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception) - { - MEDFileJoint *ret=self->getJointWithName(paramName); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileEquivalenceBase : public RefCountObject - { - private: - MEDFileEquivalenceBase(); - }; - - class MEDFileEquivalenceData : public MEDFileEquivalenceBase - { - private: - MEDFileEquivalenceData(); - public: - void setArray(DataArrayInt *data); - %extend - { - DataArrayInt *getArray() - { - DataArrayInt *ret(self->getArray()); - if(ret) ret->incrRef(); - return ret; - } - } - }; - - class MEDFileEquivalenceNode : public MEDFileEquivalenceData - { - private: - MEDFileEquivalenceNode(); - }; - - class MEDFileEquivalenceCell : public MEDFileEquivalenceBase - { - private: - MEDFileEquivalenceCell(); - public: - void clear(); - std::size_t size() const; - void setArray(int meshDimRelToMax, DataArrayInt *da) throw(INTERP_KERNEL::Exception); - void setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayInt *getArray(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret(self->getArray(type)); - if(ret) ret->incrRef(); - return ret; - } - - PyObject *getTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getTypes()); - std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - } - }; - - class MEDFileEquivalencePair : public RefCountObject - { - private: - MEDFileEquivalencePair(); - public: - std::string getName() const; - void setName(const std::string& name); - std::string getDescription() const; - void setDescription(const std::string& descr); - void setArray(int meshDimRelToMaxExt, DataArrayInt *da);; - %extend - { - MEDFileEquivalenceCell *initCell() - { - MEDFileEquivalenceCell *ret(self->initCell()); - if(ret) ret->incrRef(); - return ret; - } - - MEDFileEquivalenceNode *initNode() - { - MEDFileEquivalenceNode *ret(self->initNode()); - if(ret) ret->incrRef(); - return ret; - } - - MEDFileEquivalenceCell *getCell() - { - MEDFileEquivalenceCell *ret(self->getCell()); - if(ret) ret->incrRef(); - return ret; - } - - MEDFileEquivalenceNode *getNode() - { - MEDFileEquivalenceNode *ret(self->getNode()); - if(ret) ret->incrRef(); - return ret; - } - } - }; - - class MEDFileEquivalences : public RefCountObject - { - private: - MEDFileEquivalences(); - public: - int size() const; - std::vector<std::string> getEquivalenceNames() const throw(INTERP_KERNEL::Exception); - void killEquivalenceWithName(const std::string& name) throw(INTERP_KERNEL::Exception); - void killEquivalenceAt(int i) throw(INTERP_KERNEL::Exception); - void clear(); - %extend - { - MEDFileEquivalencePair *getEquivalence(int i) throw(INTERP_KERNEL::Exception) - { - MEDFileEquivalencePair *ret(self->getEquivalence(i)); - if(ret) ret->incrRef(); - return ret; - } - MEDFileEquivalencePair *getEquivalenceWithName(const std::string& name) throw(INTERP_KERNEL::Exception) - { - MEDFileEquivalencePair *ret(self->getEquivalenceWithName(name)); - if(ret) ret->incrRef(); - return ret; - } - - MEDFileEquivalencePair *appendEmptyEquivalenceWithName(const std::string& name) throw(INTERP_KERNEL::Exception) - { - MEDFileEquivalencePair *ret(self->appendEmptyEquivalenceWithName(name)); - if(ret) ret->incrRef(); - return ret; - } - } - }; - - class MEDFileMesh : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - virtual MEDFileMesh *createNewEmpty() const throw(INTERP_KERNEL::Exception); - virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); - virtual void clearNonDiscrAttributes() const throw(INTERP_KERNEL::Exception); - void setName(const std::string& name); - std::string getName(); - std::string getUnivName() const; - bool getUnivNameWrStatus() const; - void setUnivNameWrStatus(bool newStatus); - void setDescription(const std::string& name); - std::string getDescription() const; - void setOrder(int order); - int getOrder() const; - void setIteration(int it); - int getIteration(); - void setTimeValue(double time); - void setTime(int dt, int it, double time); - double getTimeValue() const; - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - virtual bool hasImplicitPart() const throw(INTERP_KERNEL::Exception); - virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - virtual void releaseImplicitPartIfAny() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getFamArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getNumArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getNameArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); - std::vector<int> getNonEmptyLevels() const throw(INTERP_KERNEL::Exception); - std::vector<int> getNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - // - bool existsGroup(const std::string& groupName) const throw(INTERP_KERNEL::Exception); - bool existsFamily(int famId) const throw(INTERP_KERNEL::Exception); - bool existsFamily(const std::string& familyName) const throw(INTERP_KERNEL::Exception); - void setFamilyId(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); - void setFamilyIdUnique(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); - void addFamily(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); - void addFamilyOnGrp(const std::string& grpName, const std::string& famName) throw(INTERP_KERNEL::Exception); - virtual void createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) throw(INTERP_KERNEL::Exception); - virtual bool keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& levs) throw(INTERP_KERNEL::Exception); - void copyFamGrpMapsFrom(const MEDFileMesh& other) throw(INTERP_KERNEL::Exception); - void clearGrpMap() throw(INTERP_KERNEL::Exception); - void clearFamMap() throw(INTERP_KERNEL::Exception); - void clearFamGrpMaps() throw(INTERP_KERNEL::Exception); - const std::map<std::string,int>& getFamilyInfo() const throw(INTERP_KERNEL::Exception); - const std::map<std::string, std::vector<std::string> >& getGroupInfo() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getFamiliesOnGroup(const std::string& name) const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamiliesIdsOnGroup(const std::string& name) const throw(INTERP_KERNEL::Exception); - void setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception); - void setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception); - std::vector<std::string> getGroupsOnFamily(const std::string& name) const throw(INTERP_KERNEL::Exception); - void setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception); - std::vector<std::string> getGroupsNames() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getFamiliesNames() const throw(INTERP_KERNEL::Exception); - void assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception); - std::vector<std::string> removeEmptyGroups() throw(INTERP_KERNEL::Exception); - void removeGroup(const std::string& name) throw(INTERP_KERNEL::Exception); - void removeFamily(const std::string& name) throw(INTERP_KERNEL::Exception); - std::vector<std::string> removeOrphanGroups() throw(INTERP_KERNEL::Exception); - std::vector<std::string> removeOrphanFamilies() throw(INTERP_KERNEL::Exception); - void removeFamiliesReferedByNoGroups() throw(INTERP_KERNEL::Exception); - void rearrangeFamilies() throw(INTERP_KERNEL::Exception); - void checkOrphanFamilyZero() const throw(INTERP_KERNEL::Exception); - void changeGroupName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - void changeFamilyName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception); - void changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception); - void setFamilyInfo(const std::map<std::string,int>& info); - void setGroupInfo(const std::map<std::string, std::vector<std::string> >&info); - int getFamilyId(const std::string& name) const throw(INTERP_KERNEL::Exception); - int getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception); - int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); - int getMinFamilyId() const throw(INTERP_KERNEL::Exception); - int getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception); - int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); - int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); - virtual int getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); - virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); - virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); - DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); - DataArrayInt *computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamiliesIds(const std::vector<std::string>& famNames) const throw(INTERP_KERNEL::Exception); - std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); - bool ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception); - void normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception); - void normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception); - virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception); - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - // - virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); - virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); - virtual void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception); - virtual void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); - virtual void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeGroupArr(const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - int getNumberOfJoints(); - MEDFileJoints *getJoints(); - void setJoints( MEDFileJoints* joints ); - void initializeEquivalences(); - void killEquivalences(); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDCouplingMesh *__getitem__(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - return self->getGenMeshAtLevel(meshDimRelToMaxExt,false); - } - - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp1)); - PyList_SetItem(res,1,SWIG_From_int(tmp2)); - PyList_SetItem(res,2,SWIG_From_double(tmp0)); - return res; - } - - virtual PyObject *isEqual(const MEDFileMesh *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - void setGroupsAtLevel(int meshDimRelToMaxExt, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const DataArrayInt *> grps; - convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",grps); - self->setGroupsAtLevel(meshDimRelToMaxExt,grps,renum); - } - - PyObject *areFamsEqual(const MEDFileMesh *other) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->areFamsEqual(other,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - PyObject *areGrpsEqual(const MEDFileMesh *other) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->areGrpsEqual(other,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - PyObject *getAllGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getAllGeoTypes()); - std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - PyObject *getGeoTypesAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getGeoTypesAtLevel(meshDimRelToMax)); - std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - PyObject *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getFamilyFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getNumberFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getRevNumberFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayAsciiChar *tmp=self->getNameFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar, SWIG_POINTER_OWN | 0 ); - } - - PyObject *findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception) - { - bool ret1; - std::string ret0=self->findOrCreateAndGiveFamilyWithId(id,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyString_FromString(ret0.c_str())); - PyTuple_SetItem(ret,1,SWIG_From_bool(ret1)); - return ret; - } - - PyObject *unPolyze() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret3=0; - std::vector<int> ret1,ret2; - bool ret0=self->unPolyze(ret1,ret2,ret3); - PyObject *ret=PyTuple_New(4); - PyTuple_SetItem(ret,0,SWIG_From_bool(ret0)); - // - PyObject *retLev1_0=PyList_New((int)ret1.size()/3); - for(int j=0;j<(int)ret1.size()/3;j++) - { - PyObject *retLev2=PyList_New(3); - PyList_SetItem(retLev2,0,SWIG_From_int(ret1[3*j])); - PyList_SetItem(retLev2,1,SWIG_From_int(ret1[3*j+1])); - PyList_SetItem(retLev2,2,SWIG_From_int(ret1[3*j+2])); - PyList_SetItem(retLev1_0,j,retLev2); - } - PyTuple_SetItem(ret,1,retLev1_0); - // - PyObject *retLev1_1=PyList_New((int)ret2.size()/3); - for(int j=0;j<(int)ret2.size()/3;j++) - { - PyObject *retLev2=PyList_New(3); - PyList_SetItem(retLev2,0,SWIG_From_int(ret2[3*j])); - PyList_SetItem(retLev2,1,SWIG_From_int(ret2[3*j+1])); - PyList_SetItem(retLev2,2,SWIG_From_int(ret2[3*j+2])); - PyList_SetItem(retLev1_1,j,retLev2); - } - PyTuple_SetItem(ret,2,retLev1_1); - // - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(ret3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - MEDFileEquivalences *getEquivalences() throw(INTERP_KERNEL::Exception) - { - MEDFileEquivalences *ret(self->getEquivalences()); - if(ret) ret->incrRef(); - return ret; - } - } - }; - - class MEDFileUMesh : public MEDFileMesh - { - public: - static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileUMesh *New(); - ~MEDFileUMesh(); - int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - // - std::vector<int> getGrpNonEmptyLevels(const std::string& grp) const throw(INTERP_KERNEL::Exception); - std::vector<int> getGrpNonEmptyLevelsExt(const std::string& grp) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamNonEmptyLevels(const std::string& fam) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamNonEmptyLevelsExt(const std::string& fam) const throw(INTERP_KERNEL::Exception); - std::vector<int> getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); - std::vector<int> getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - void forceComputationOfParts() const throw(INTERP_KERNEL::Exception); - // - void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception); - void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); - void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); - void setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) throw(INTERP_KERNEL::Exception); - void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); - void optimizeFamilies() throw(INTERP_KERNEL::Exception); - DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception); - DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const throw(INTERP_KERNEL::Exception); - MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const throw(INTERP_KERNEL::Exception); - MEDFileUMesh *quadraticToLinear(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileUMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileUMesh::New(fileName,mName,dt,it,mrs); - } - - MEDFileUMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileUMesh::New(fileName,mrs); - } - - MEDFileUMesh() - { - return MEDFileUMesh::New(); - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDFileUMesh"); - } - - static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - std::vector<int> typesCpp1; - convertPyToNewIntArr3(types,typesCpp1); - std::size_t sz(typesCpp1.size()); - std::vector<INTERP_KERNEL::NormalizedCellType> typesCpp2(sz); - for(std::size_t ii=0;ii<sz;ii++) - typesCpp2[ii]=(INTERP_KERNEL::NormalizedCellType)typesCpp1[ii]; - return MEDFileUMesh::LoadPartOf(fileName,mName,typesCpp2,slicPerTyp,dt,it,mrs); - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - {// put an empty dict in input to say to __new__ to call __init__... - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyTuple_SetItem(ret,0,ret0); - return ret; - } - - PyObject *__getstate__() throw(INTERP_KERNEL::Exception) - { - std::vector<double> a0; - std::vector<int> a1; - std::vector<std::string> a2; - std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3; - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4; - self->serialize(a0,a1,a2,a3,a4); - PyObject *ret(PyTuple_New(5)); - PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); - int sz(a2.size()); - PyObject *ret2(PyList_New(sz)); - for(int i=0;i<sz;i++) - PyList_SetItem(ret2,i,PyString_FromString(a2[i].c_str())); - PyTuple_SetItem(ret,2,ret2); - sz=a3.size(); - PyObject *ret3(PyList_New(sz)); - for(int i=0;i<sz;i++) - { - DataArrayInt *elt(a3[i]); - if(elt) - elt->incrRef(); - PyList_SetItem(ret3,i,SWIG_NewPointerObj(SWIG_as_voidptr(elt),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - } - PyTuple_SetItem(ret,3,ret3); - DataArrayDouble *ret4(a4); - if(ret4) - ret4->incrRef(); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(ret4),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDFileUMesh.__setstate__ : expected input is a tuple of size 4 !"; - if(!PyTuple_Check(inp)) - throw INTERP_KERNEL::Exception(MSG); - int sz(PyTuple_Size(inp)); - if(sz!=5) - throw INTERP_KERNEL::Exception(MSG); - std::vector<double> a0; - std::vector<int> a1; - std::vector<std::string> a2; - std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3; - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4; - // - PyObject *a0py(PyTuple_GetItem(inp,0)),*a1py(PyTuple_GetItem(inp,1)),*a2py(PyTuple_GetItem(inp,2)); - int tmp(-1); - fillArrayWithPyListDbl3(a0py,tmp,a0); - convertPyToNewIntArr3(a1py,a1); - fillStringVector(a2py,a2); - // - PyObject *b0py(PyTuple_GetItem(inp,3)),*b1py(PyTuple_GetItem(inp,4)); - void *argp(0); - int status(SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - a4=reinterpret_cast<DataArrayDouble *>(argp); - if((DataArrayDouble *)a4) - a4->incrRef(); - { - std::vector< DataArrayInt * > a3Tmp; - convertFromPyObjVectorOfObj<ParaMEDMEM::DataArrayInt *>(b0py,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",a3Tmp); - std::size_t sz(a3Tmp.size()); - a3.resize(sz); - for(std::size_t i=0;i<sz;i++) - { - a3[i]=a3Tmp[i]; - if(a3Tmp[i]) - a3Tmp[i]->incrRef(); - } - self->unserialize(a0,a1,a2,a3,a4); - } - } - - void __setitem__(int meshDimRelToMax, MEDCouplingPointSet *mesh) throw(INTERP_KERNEL::Exception) - { - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileUMesh::__setitem__ : Input mesh is NULL !"); - MEDCouplingUMesh *m0(dynamic_cast<MEDCouplingUMesh *>(mesh)); - if(m0) - { - self->setMeshAtLevel(meshDimRelToMax,m0,false); - return ; - } - MEDCoupling1GTUMesh *m1(dynamic_cast<MEDCoupling1GTUMesh *>(mesh)); - if(m1) - { - self->setMeshAtLevel(meshDimRelToMax,m1); - return ; - } - throw INTERP_KERNEL::Exception("MEDFileUMesh::__setitem__ : Not recognized input mesh !"); - } - - void __delitem__(int meshDimRelToMax) throw(INTERP_KERNEL::Exception) - { - self->removeMeshAtLevel(meshDimRelToMax); - } - - void setMeshes(PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const MEDCouplingUMesh *> ms; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); - self->setMeshes(ms,renum); - } - - void setGroupsFromScratch(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const MEDCouplingUMesh *> ms; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); - self->setGroupsFromScratch(meshDimRelToMax,ms,renum); - } - - void setGroupsOnSetMesh(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const MEDCouplingUMesh *> ms; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); - self->setGroupsOnSetMesh(meshDimRelToMax,ms,renum); - } - - DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getCoords(); - if(ret) - ret->incrRef(); - return ret; - } - - PartDefinition *getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt=INTERP_KERNEL::NORM_ERROR) const throw(INTERP_KERNEL::Exception) - { - const PartDefinition *ret(self->getPartDefAtLevel(meshDimRelToMaxExt,gt)); - if(ret) - ret->incrRef(); - return const_cast<PartDefinition *>(ret); - } - - PyObject *buildInnerBoundaryAlongM1Group(const std::string& grpNameM1) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret0=0,*ret1=0,*ret2=0; - self->buildInnerBoundaryAlongM1Group(grpNameM1,ret0,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception) - { - MEDCoupling1GTUMesh *ret(self->getDirectUndergroundSingleGeoTypeMesh(gt)); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) - { - std::vector<MEDCoupling1GTUMesh *> tmp(self->getDirectUndergroundSingleGeoTypeMeshes(meshDimRelToMax)); - std::size_t sz(tmp.size()); - PyObject *ret=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - if(tmp[i]) - tmp[i]->incrRef(); - PyList_SetItem(ret,i,convertMesh(tmp[i], SWIG_POINTER_OWN | 0 )); - } - return ret; - } - } - }; - - class MEDFileStructuredMesh : public MEDFileMesh - { - public: - %extend - { - MEDCoupling1SGTUMesh *getImplicitFaceMesh() const throw(INTERP_KERNEL::Exception) - { - MEDCoupling1SGTUMesh *ret(self->getImplicitFaceMesh()); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileCMesh : public MEDFileStructuredMesh - { - public: - static MEDFileCMesh *New(); - static MEDFileCMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileCMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - void setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception); - int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileCMesh() - { - return MEDFileCMesh::New(); - } - - MEDFileCMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCMesh::New(fileName,mrs); - } - - MEDFileCMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCMesh::New(fileName,mName,dt,it,mrs); - } - - PyObject *getMesh() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCMesh *tmp=self->getMesh(); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 ); - } - } - }; - - class MEDFileCurveLinearMesh : public MEDFileStructuredMesh - { - public: - static MEDFileCurveLinearMesh *New(); - static MEDFileCurveLinearMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileCurveLinearMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileCurveLinearMesh() - { - return MEDFileCurveLinearMesh::New(); - } - - MEDFileCurveLinearMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCurveLinearMesh::New(fileName,mrs); - } - - MEDFileCurveLinearMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCurveLinearMesh::New(fileName,mName,dt,it,mrs); - } - - PyObject *getMesh() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCurveLinearMesh *tmp=self->getMesh(); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh, SWIG_POINTER_OWN | 0 ); - } - } - }; - - class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileMeshMultiTS *New(); - static MEDFileMeshMultiTS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileMeshMultiTS *New(const std::string& fileName, const std::string& mName) throw(INTERP_KERNEL::Exception); - MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileMeshMultiTS() - { - return MEDFileMeshMultiTS::New(); - } - - MEDFileMeshMultiTS(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileMeshMultiTS::New(fileName); - } - - MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) throw(INTERP_KERNEL::Exception) - { - return MEDFileMeshMultiTS::New(fileName,mName); - } - - MEDFileMesh *getOneTimeStep() const throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->getOneTimeStep(); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileMeshesIterator - { - public: - %extend - { - PyObject *next() throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->nextt(); - if(ret) - { - ret->incrRef(); - return convertMEDFileMesh(ret,SWIG_POINTER_OWN | 0 ); - } - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDFileMeshes : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileMeshes *New(); - static MEDFileMeshes *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception); - // - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); - void setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); - void destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileMeshes() - { - return MEDFileMeshes::New(); - } - - MEDFileMeshes(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileMeshes::New(fileName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileMesh *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(PyInt_Check(obj)) - { - MEDFileMesh *ret=self->getMeshAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfMeshes())); - if(ret) - ret->incrRef(); - return ret; - } - else if(PyString_Check(obj)) - { - MEDFileMesh *ret=self->getMeshWithName(PyString_AsString(obj)); - if(ret) - ret->incrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("MEDFileMeshes::__getitem__ : only integer or string with meshname supported !"); - } - - MEDFileMeshes *__setitem__(int obj, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) - { - self->setMeshAtPos(obj,mesh); - return self; - } - - MEDFileMeshesIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfMeshes(); - } - - MEDFileMesh *getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->getMeshAtPos(i); - if(ret) - ret->incrRef(); - return ret; - } - MEDFileMesh *getMeshWithName(const std::string& mname) const throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->getMeshWithName(mname); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileFieldLoc : public RefCountObject - { - public: - std::string getName() const; - int getDimension() const; - int getNumberOfGaussPoints() const; - int getNumberOfPointsInCells() const; - const std::vector<double>& getRefCoords() const; - const std::vector<double>& getGaussCoords() const; - const std::vector<double>& getGaussWeights() const; - bool isEqual(const MEDFileFieldLoc& other, double eps) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - } - }; - - class MEDFileFieldGlobsReal - { - public: - void resetContent(); - void shallowCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void deepCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception); - void checkGlobsCoherency() const throw(INTERP_KERNEL::Exception); - void checkGlobsPflsPartCoherency() const throw(INTERP_KERNEL::Exception); - void checkGlobsLocsPartCoherency() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getPfls() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getLocs() const throw(INTERP_KERNEL::Exception); - bool existsPfl(const std::string& pflName) const throw(INTERP_KERNEL::Exception); - bool existsLoc(const std::string& locName) const throw(INTERP_KERNEL::Exception); - std::string createNewNameOfPfl() const throw(INTERP_KERNEL::Exception); - std::string createNewNameOfLoc() const throw(INTERP_KERNEL::Exception); - std::vector< std::vector<int> > whichAreEqualProfiles() const throw(INTERP_KERNEL::Exception); - std::vector< std::vector<int> > whichAreEqualLocs(double eps) const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getPflsReallyUsed() const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getLocsReallyUsed() const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getPflsReallyUsedMulti() const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getLocsReallyUsedMulti() const throw(INTERP_KERNEL::Exception); - void killProfileIds(const std::vector<int>& pflIds) throw(INTERP_KERNEL::Exception); - void killLocalizationIds(const std::vector<int>& locIds) throw(INTERP_KERNEL::Exception); - void changePflName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - void changeLocName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - int getNbOfGaussPtPerCell(int locId) const throw(INTERP_KERNEL::Exception); - int getLocalizationId(const std::string& loc) const throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getProfile(const std::string& pflName) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *ret=self->getProfile(pflName); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getProfileFromId(int pflId) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *ret=self->getProfileFromId(pflId); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getLocalizationFromId(int locId) const throw(INTERP_KERNEL::Exception) - { - const MEDFileFieldLoc *loc=&self->getLocalizationFromId(locId); - if(loc) - loc->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(loc),SWIGTYPE_p_ParaMEDMEM__MEDFileFieldLoc, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getLocalization(const std::string& locName) const throw(INTERP_KERNEL::Exception) - { - const MEDFileFieldLoc *loc=&self->getLocalization(locName); - if(loc) - loc->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(loc),SWIGTYPE_p_ParaMEDMEM__MEDFileFieldLoc, SWIG_POINTER_OWN | 0 ); - } - - PyObject *zipPflsNames() throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > ret=self->zipPflsNames(); - return convertVecPairVecStToPy(ret); - } - - PyObject *zipLocsNames(double eps) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > ret=self->zipLocsNames(eps); - return convertVecPairVecStToPy(ret); - } - - void changePflsNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changePflsNames(v); - } - - void changePflsRefsNamesGen(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changePflsRefsNamesGen(v); - } - - void changePflsNamesInStruct(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changePflsNamesInStruct(v); - } - - void changeLocsNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changeLocsNames(v); - } - - void changeLocsRefsNamesGen(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changeLocsRefsNamesGen(v); - } - - void changeLocsNamesInStruct(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changeLocsNamesInStruct(v); - } - - std::string simpleReprGlobs() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->simpleReprGlobs(oss); - return oss.str(); - } - } - }; - - class MEDFileAnyTypeField1TS : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - static MEDFileAnyTypeField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - void loadArrays() throw(INTERP_KERNEL::Exception); - void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); - void unloadArrays() throw(INTERP_KERNEL::Exception); - void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); - int getDimension() const throw(INTERP_KERNEL::Exception); - int getIteration() const throw(INTERP_KERNEL::Exception); - int getOrder() const throw(INTERP_KERNEL::Exception); - std::string getName() throw(INTERP_KERNEL::Exception); - void setName(const std::string& name) throw(INTERP_KERNEL::Exception); - std::string getMeshName() throw(INTERP_KERNEL::Exception); - void setMeshName(const std::string& newMeshName) throw(INTERP_KERNEL::Exception); - int getMeshIteration() const throw(INTERP_KERNEL::Exception); - int getMeshOrder() const throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); - bool isDealingTS(int iteration, int order) const throw(INTERP_KERNEL::Exception); - void setInfo(const std::vector<std::string>& infos) throw(INTERP_KERNEL::Exception); - const std::vector<std::string>& getInfo() const throw(INTERP_KERNEL::Exception); - bool presenceOfMultiDiscPerGeoType() const throw(INTERP_KERNEL::Exception); - void setTime(int iteration, int order, double val) throw(INTERP_KERNEL::Exception); - virtual MEDFileAnyTypeField1TS *shallowCpy() const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeField1TS *deepCpy() const throw(INTERP_KERNEL::Exception); - std::string getDtUnit() const throw(INTERP_KERNEL::Exception); - void setDtUnit(const std::string& dtUnit) throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp1)); - PyList_SetItem(res,1,SWIG_From_int(tmp2)); - PyList_SetItem(res,2,SWIG_From_double(tmp0)); - return res; - } - - PyObject *getDtIt() const throw(INTERP_KERNEL::Exception) - { - std::pair<int,int> res=self->getDtIt(); - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(res.first)); - PyTuple_SetItem(elt,1,SWIG_From_int(res.second)); - return elt; - } - - void setProfileNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception) - { - self->setProfileNameOnLeaf(0,typ,locId,newPflName,forceRenameOnGlob); - } - - void setLocNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception) - { - self->setLocNameOnLeaf(0,typ,locId,newLocName,forceRenameOnGlob); - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - - PyObject *getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) - { - std::vector<TypeOfField> ret=self->getTypesOfFieldAvailable(); - PyObject *ret2=PyList_New(ret.size()); - for(int i=0;i<(int)ret.size();i++) - PyList_SetItem(ret2,i,SWIG_From_int(ret[i])); - return ret2; - } - - PyObject *getNonEmptyLevels(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<int> ret1; - int ret0=self->getNonEmptyLevels(mname,ret1); - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); - PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); - return elt; - } - - PyObject *getFieldSplitedByType(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector< std::pair<int,int> > > ret=self->getFieldSplitedByType(mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector< std::pair<int,int> >& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyObject *elt4=PyTuple_New(2); PyTuple_SetItem(elt4,0,SWIG_From_int(dadsI[j].first)); PyTuple_SetItem(elt4,1,SWIG_From_int(dadsI[j].second)); - PyTuple_SetItem(elt3,1,elt4); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - PyObject *splitComponents() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitComponents(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitDiscretizations(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitMultiDiscrPerGeoTypes(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - } - }; - - class MEDFileField1TS : public MEDFileAnyTypeField1TS - { - public: - static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(); - ParaMEDMEM::MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - // - void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); - void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - void setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); - void setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileField1TS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileField1TS::New(fileName,loadAll); - } - - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileField1TS::New(fileName,fieldName,loadAll); - } - - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileField1TS::New(fileName,fieldName,iteration,order,loadAll); - } - - MEDFileField1TS() - { - return MEDFileField1TS::New(); - } - - void copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) - { - const DataArrayDouble *arr=0; - if(field) - arr=field->getArray(); - self->copyTinyInfoFrom(field,arr); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldSplitedByType2(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector<DataArrayDouble *> > ret=self->getFieldSplitedByType2(mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector<DataArrayDouble *>& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyTuple_SetItem(elt3,1,SWIG_NewPointerObj(SWIG_as_voidptr(dadsI[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - DataArrayDouble *getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getUndergroundDataArray(); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getUndergroundDataArrayExt() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > elt1Cpp; - DataArrayDouble *elt0=self->getUndergroundDataArrayExt(elt1Cpp); - if(elt0) - elt0->incrRef(); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - std::size_t sz=elt1Cpp.size(); - PyObject *elt=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - PyObject *elt1=PyTuple_New(2); - PyObject *elt2=PyTuple_New(2); - PyTuple_SetItem(elt2,0,SWIG_From_int((int)elt1Cpp[i].first.first)); - PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second)); - PyObject *elt3=PyTuple_New(2); - PyTuple_SetItem(elt3,0,SWIG_From_int(elt1Cpp[i].second.first)); - PyTuple_SetItem(elt3,1,SWIG_From_int(elt1Cpp[i].second.second)); - PyTuple_SetItem(elt1,0,elt2); - PyTuple_SetItem(elt1,1,elt3); - PyList_SetItem(elt,i,elt1); - } - PyTuple_SetItem(ret,1,elt); - return ret; - } - } - }; - - class MEDFileIntField1TS : public MEDFileAnyTypeField1TS - { - public: - static MEDFileIntField1TS *New(); - static MEDFileIntField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileField1TS *convertToDouble(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - // - void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) throw(INTERP_KERNEL::Exception); - void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileIntField1TS() throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(); - } - - MEDFileIntField1TS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(fileName,loadAll); - } - - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(fileName,fieldName,loadAll); - } - - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(fileName,fieldName,iteration,order,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevel(type,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtTopLevel(type,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,meshDimRelToMax,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevelOld(type,mname,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayInt *ret0=self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getUndergroundDataArray(); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileAnyTypeFieldMultiTSIterator - { - public: - %extend - { - PyObject *next() throw(INTERP_KERNEL::Exception) - { - MEDFileAnyTypeField1TS *ret=self->nextt(); - if(ret) - return convertMEDFileField1TS(ret, SWIG_POINTER_OWN | 0 ); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDFileAnyTypeFieldMultiTS : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - void setName(const std::string& name) throw(INTERP_KERNEL::Exception); - std::string getDtUnit() const throw(INTERP_KERNEL::Exception); - void setDtUnit(const std::string& dtUnit) throw(INTERP_KERNEL::Exception); - std::string getMeshName() const throw(INTERP_KERNEL::Exception); - void setMeshName(const std::string& newMeshName) throw(INTERP_KERNEL::Exception); - const std::vector<std::string>& getInfo() const throw(INTERP_KERNEL::Exception); - bool presenceOfMultiDiscPerGeoType() const throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); - int getNumberOfTS() const throw(INTERP_KERNEL::Exception); - void eraseEmptyTS() throw(INTERP_KERNEL::Exception); - int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); - int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - void loadArrays() throw(INTERP_KERNEL::Exception); - void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); - void unloadArrays() throw(INTERP_KERNEL::Exception); - void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); - // - virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); - void pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) throw(INTERP_KERNEL::Exception); - void synchronizeNameScope() throw(INTERP_KERNEL::Exception); - %extend - { - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfTS(); - } - - int getTimeId(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - int pos=PyInt_AS_LONG(elt0); - return pos; - } - else if(elt0 && PyTuple_Check(elt0)) - { - if(PyTuple_Size(elt0)==2) - { - PyObject *o0=PyTuple_GetItem(elt0,0); - PyObject *o1=PyTuple_GetItem(elt0,1); - if(PyInt_Check(o0) && PyInt_Check(o1)) - {//fmts(1,-1) - int iter=PyInt_AS_LONG(o0); - int order=PyInt_AS_LONG(o1); - return self->getPosOfTimeStep(iter,order); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); - } - else if(elt0 && PyFloat_Check(elt0)) - { - double val=PyFloat_AS_DOUBLE(elt0); - return self->getPosGivenTime(val); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int] or fmts[double] to request time step !"); - } - - PyObject *getIterations() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=self->getIterations(); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception) - { - std::vector<double> ret1; - std::vector< std::pair<int,int> > ret=self->getTimeSteps(ret1); - std::size_t sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - PyObject *elt=PyTuple_New(3); - PyTuple_SetItem(elt,0,SWIG_From_int(ret[i].first)); - PyTuple_SetItem(elt,1,SWIG_From_int(ret[i].second)); - PyTuple_SetItem(elt,2,SWIG_From_double(ret1[i])); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - PyObject *getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::vector<TypeOfField> > ret=self->getTypesOfFieldAvailable(); - PyObject *ret2=PyList_New(ret.size()); - for(int i=0;i<(int)ret.size();i++) - { - const std::vector<TypeOfField>& rett=ret[i]; - PyObject *ret3=PyList_New(rett.size()); - for(int j=0;j<(int)rett.size();j++) - PyList_SetItem(ret3,j,SWIG_From_int(rett[j])); - PyList_SetItem(ret2,i,ret3); - } - return ret2; - } - - PyObject *getNonEmptyLevels(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<int> ret1; - int ret0=self->getNonEmptyLevels(iteration,order,mname,ret1); - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); - PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); - return elt; - } - - PyObject *getFieldSplitedByType(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector< std::pair<int,int> > > ret=self->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector< std::pair<int,int> >& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyObject *elt4=PyTuple_New(2); PyTuple_SetItem(elt4,0,SWIG_From_int(dadsI[j].first)); PyTuple_SetItem(elt4,1,SWIG_From_int(dadsI[j].second)); - PyTuple_SetItem(elt3,1,elt4); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - std::vector<int> getTimeIds(PyObject *elts) const throw(INTERP_KERNEL::Exception) - { - if(PyList_Check(elts)) - { - int sz=PyList_Size(elts); - std::vector<int> ret(sz); - for(int i=0;i<sz;i++) - { - PyObject *elt=PyList_GetItem(elts,i); - ret[i]=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeId(self,elt); - } - return ret; - } - else - { - std::vector<int> ret(1); - ret[0]=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeId(self,elts); - return ret; - } - } - - void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) - { - if(PySlice_Check(elts)) - { - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *oC=reinterpret_cast<PySliceObject *>(elts); - GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__delitem__ : error in input slice !"); - self->eraseTimeStepIds2(strt,stp,step); - } - else - { - std::vector<int> idsToRemove=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeIds(self,elts); - if(!idsToRemove.empty()) - self->eraseTimeStepIds(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); - } - } - - void eraseTimeStepIds(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int pos1; - std::vector<int> pos2; - DataArrayInt *pos3=0; - DataArrayIntTuple *pos4=0; - convertObjToPossibleCpp1(li,sw,pos1,pos2,pos3,pos4); - switch(sw) - { - case 1: - { - self->eraseTimeStepIds(&pos1,&pos1+1); - return; - } - case 2: - { - if(pos2.empty()) - return; - self->eraseTimeStepIds(&pos2[0],&pos2[0]+pos2.size()); - return ; - } - case 3: - { - self->eraseTimeStepIds(pos3->begin(),pos3->end()); - return ; - } - default: - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds : unexpected input array type recognized !"); - } - } - - MEDFileAnyTypeFieldMultiTSIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - PyObject *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyList_Check(elt0)) - { - int sz=PyList_Size(elt0); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); da->alloc(sz,1); - int *pt=da->getPointer(); - for(int i=0;i<sz;i++,pt++) - { - PyObject *elt1=PyList_GetItem(elt0,i); - *pt=MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt1); - } - return convertMEDFileFieldMultiTS(self->buildSubPart(da->begin(),da->end()),SWIG_POINTER_OWN | 0); - } - else if(elt0 && PySlice_Check(elt0)) - { - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *oC=reinterpret_cast<PySliceObject *>(elt0); - GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__getitem__ : error in input slice !"); - return convertMEDFileFieldMultiTS(self->buildSubPartSlice(strt,stp,step),SWIG_POINTER_OWN | 0); - } - else - return convertMEDFileField1TS(self->getTimeStepAtPos(MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt0)),SWIG_POINTER_OWN | 0); - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - - PyObject *splitComponents() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitComponents(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitDiscretizations(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitMultiDiscrPerGeoTypes(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - void pushBackTimeSteps(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *argp(0); - int status(SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,0|0)); - if(SWIG_IsOK(status)) - { - self->pushBackTimeSteps(reinterpret_cast<MEDFileAnyTypeFieldMultiTS *>(argp)); - } - else - { - std::vector<MEDFileAnyTypeField1TS *> tmp; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeField1TS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeField1TS,"MEDFileAnyTypeField1TS",tmp); - self->pushBackTimeSteps(tmp); - } - } - - static PyObject *MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTS; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",vectFMTS); - std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret=MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(vectFMTS); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - std::size_t sz2=ret[i].size(); - PyObject *ret1Py=PyList_New(sz2); - for(std::size_t j=0;j<sz2;j++) - { - MEDFileAnyTypeFieldMultiTS *elt(ret[i][j]); - if(elt) - elt->incrRef(); - PyList_SetItem(ret1Py,j,convertMEDFileFieldMultiTS(elt,SWIG_POINTER_OWN | 0 )); - } - PyList_SetItem(retPy,i,ret1Py); - } - return retPy; - } - - static PyObject *MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(PyObject *li, const MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) - { - std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTS; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",vectFMTS); - std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> > ret2; - std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret=MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(vectFMTS,mesh,ret2); - if(ret2.size()!=ret.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport (PyWrap) : internal error ! Size of 2 vectors must match ! (" << ret.size() << "!=" << ret2.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - std::size_t sz2=ret[i].size(); - PyObject *ret0Py=PyTuple_New(2); - PyObject *ret1Py=PyList_New(sz2); - for(std::size_t j=0;j<sz2;j++) - { - MEDFileAnyTypeFieldMultiTS *elt(ret[i][j]); - if(elt) - elt->incrRef(); - PyList_SetItem(ret1Py,j,convertMEDFileFieldMultiTS(elt,SWIG_POINTER_OWN | 0 )); - } - PyTuple_SetItem(ret0Py,0,ret1Py); - PyTuple_SetItem(ret0Py,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret2[i].retn()),SWIGTYPE_p_ParaMEDMEM__MEDFileFastCellSupportComparator, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(retPy,i,ret0Py); - } - return retPy; - } - } - }; - - class MEDFileFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - static MEDFileFieldMultiTS *New() throw(INTERP_KERNEL::Exception); - static MEDFileFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - // - MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - // - void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); - void appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileFieldMultiTS() - { - return MEDFileFieldMultiTS::New(); - } - - MEDFileFieldMultiTS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileFieldMultiTS::New(fileName,loadAll); - } - - MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileFieldMultiTS::New(fileName,fieldName,loadAll); - } - - static MEDFileFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, PyObject *entities, bool loadAll=true) - { - std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); - std::size_t sz(tmp.size()); - std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); - for(std::size_t i=0;i<sz;i++) - { - entitiesCpp[i].first=(TypeOfField)tmp[i].first; - entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; - } - return MEDFileFieldMultiTS::LoadSpecificEntities(fileName,fieldName,entitiesCpp,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->getFieldWithProfile(type,iteration,order,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldSplitedByType2(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector<DataArrayDouble *> > ret=self->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector<DataArrayDouble *>& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyTuple_SetItem(elt3,1,SWIG_NewPointerObj(SWIG_as_voidptr(dadsI[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - DataArrayDouble *getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getUndergroundDataArray(iteration,order); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getUndergroundDataArrayExt(int iteration, int order) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > elt1Cpp; - DataArrayDouble *elt0=self->getUndergroundDataArrayExt(iteration,order,elt1Cpp); - if(elt0) - elt0->incrRef(); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - std::size_t sz=elt1Cpp.size(); - PyObject *elt=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - PyObject *elt1=PyTuple_New(2); - PyObject *elt2=PyTuple_New(2); - PyTuple_SetItem(elt2,0,SWIG_From_int(elt1Cpp[i].first.first)); - PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second)); - PyObject *elt3=PyTuple_New(2); - PyTuple_SetItem(elt3,0,SWIG_From_int(elt1Cpp[i].second.first)); - PyTuple_SetItem(elt3,1,SWIG_From_int(elt1Cpp[i].second.second)); - PyTuple_SetItem(elt1,0,elt2); - PyTuple_SetItem(elt1,1,elt3); - PyList_SetItem(elt,i,elt1); - } - PyTuple_SetItem(ret,1,elt); - return ret; - } - } - }; - - class MEDFileFieldsIterator - { - public: - %extend - { - PyObject *next() throw(INTERP_KERNEL::Exception) - { - MEDFileAnyTypeFieldMultiTS *ret=self->nextt(); - if(ret) - return convertMEDFileFieldMultiTS(ret, SWIG_POINTER_OWN | 0 ); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDFileIntFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - static MEDFileIntFieldMultiTS *New(); - static MEDFileIntFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileIntFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - // - void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) throw(INTERP_KERNEL::Exception); - void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileIntFieldMultiTS() - { - return MEDFileIntFieldMultiTS::New(); - } - - MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntFieldMultiTS::New(fileName,loadAll); - } - - MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntFieldMultiTS::New(fileName,fieldName,loadAll); - } - - static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, PyObject *entities, bool loadAll=true) - { - std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); - std::size_t sz(tmp.size()); - std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); - for(std::size_t i=0;i<sz;i++) - { - entitiesCpp[i].first=(TypeOfField)tmp[i].first; - entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; - } - return MEDFileIntFieldMultiTS::LoadSpecificEntities(fileName,fieldName,entitiesCpp,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevel(type,iteration,order,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtTopLevel(type,iteration,order,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,iteration,order,meshDimRelToMax,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,iteration,order,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevelOld(type,iteration,order,mname,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayInt *ret0=self->getFieldWithProfile(type,iteration,order,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getUndergroundDataArray(iteration,order); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileFields : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - static MEDFileFields *New() throw(INTERP_KERNEL::Exception); - static MEDFileFields *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileFields *LoadPartOf(const std::string& fileName, bool loadAll=true, const MEDFileMeshes *ms=0) throw(INTERP_KERNEL::Exception); - MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception); - MEDFileFields *shallowCpy() const throw(INTERP_KERNEL::Exception); - void loadArrays() throw(INTERP_KERNEL::Exception); - void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); - void unloadArrays() throw(INTERP_KERNEL::Exception); - void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getNumberOfFields() const; - std::vector<std::string> getFieldsNames() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception); - // - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushField(MEDFileAnyTypeFieldMultiTS *field) throw(INTERP_KERNEL::Exception); - void setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) throw(INTERP_KERNEL::Exception); - int getPosFromFieldName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const throw(INTERP_KERNEL::Exception); - void destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception); - bool removeFieldsWithoutAnyTimeStep() throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileFields() - { - return MEDFileFields::New(); - } - - MEDFileFields(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileFields::New(fileName,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - static MEDFileFields *LoadSpecificEntities(const std::string& fileName, PyObject *entities, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); - std::size_t sz(tmp.size()); - std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); - for(std::size_t i=0;i<sz;i++) - { - entitiesCpp[i].first=(TypeOfField)tmp[i].first; - entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; - } - return MEDFileFields::LoadSpecificEntities(fileName,entitiesCpp,loadAll); - } - - PyObject *getCommonIterations() const throw(INTERP_KERNEL::Exception) - { - bool ret1; - std::vector< std::pair<int,int> > ret0=self->getCommonIterations(ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret_0=PyList_New(ret0.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=ret0.begin();iter!=ret0.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret_0,rk,elt); - } - PyTuple_SetItem(ret,0,ret_0); - PyObject *ret_1=ret1?Py_True:Py_False; Py_XINCREF(ret_1); - PyTuple_SetItem(ret,1,ret_1); - return ret; - } - - MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(PyObject *timeSteps) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > ts=convertTimePairIdsFromPy(timeSteps); - return self->partOfThisLyingOnSpecifiedTimeSteps(ts); - } - - MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(PyObject *timeSteps) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > ts=convertTimePairIdsFromPy(timeSteps); - return self->partOfThisNotLyingOnSpecifiedTimeSteps(ts); - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(obj && PyList_Check(obj)) - { - int sz=PyList_Size(obj); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); da->alloc(sz,1); - int *pt=da->getPointer(); - for(int i=0;i<sz;i++,pt++) - { - PyObject *elt1=PyList_GetItem(obj,i); - *pt=MEDFileFieldsgetitemSingleTS__(self,elt1); - } - return SWIG_NewPointerObj(SWIG_as_voidptr(self->buildSubPart(da->begin(),da->end())),SWIGTYPE_p_ParaMEDMEM__MEDFileFields, SWIG_POINTER_OWN | 0 ); - } - else - return convertMEDFileFieldMultiTS(self->getFieldAtPos(MEDFileFieldsgetitemSingleTS__(self,obj)), SWIG_POINTER_OWN | 0 ); - } - - MEDFileFields *__setitem__(int obj, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) - { - self->setFieldAtPos(obj,field); - return self; - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfFields(); - } - - MEDFileFieldsIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - - int getPosOfField(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - return PyInt_AS_LONG(elt0); - } - else if(elt0 && PyString_Check(elt0)) - return self->getPosFromFieldName(PyString_AsString(elt0)); - else - throw INTERP_KERNEL::Exception("MEDFileFields::getPosOfField : invalid input params ! expected fields[int], fields[string_of_field_name] !"); - } - - std::vector<int> getPosOfFields(PyObject *elts) const throw(INTERP_KERNEL::Exception) - { - if(PyList_Check(elts)) - { - int sz=PyList_Size(elts); - std::vector<int> ret(sz); - for(int i=0;i<sz;i++) - { - PyObject *elt=PyList_GetItem(elts,i); - ret[i]=ParaMEDMEM_MEDFileFields_getPosOfField(self,elt); - } - return ret; - } - else - { - std::vector<int> ret(1); - ret[0]=ParaMEDMEM_MEDFileFields_getPosOfField(self,elts); - return ret; - } - } - - void pushFields(PyObject *fields) throw(INTERP_KERNEL::Exception) - { - std::vector<MEDFileAnyTypeFieldMultiTS *> tmp; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(fields,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",tmp); - self->pushFields(tmp); - } - - void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) - { - if(elts && PySlice_Check(elts)) - { - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *oC=reinterpret_cast<PySliceObject *>(elts); - GetIndicesOfSlice(oC,self->getNumberOfFields(),&strt,&stp,&step,"MEDFileFields.__delitem__ : error in input slice !"); - self->destroyFieldsAtPos2(strt,stp,step); - } - else - { - std::vector<int> idsToRemove=ParaMEDMEM_MEDFileFields_getPosOfFields(self,elts); - if(!idsToRemove.empty()) - self->destroyFieldsAtPos(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); - } - } - } - }; - - class MEDFileParameter1TS : public RefCountObject - { - public: - void setIteration(int it); - int getIteration() const; - void setOrder(int order); - int getOrder() const; - void setTimeValue(double time); - void setTime(int dt, int it, double time); - double getTime(int& dt, int& it); - double getTimeValue() const; - }; - - class MEDFileParameterDouble1TSWTI : public MEDFileParameter1TS - { - public: - void setValue(double val) throw(INTERP_KERNEL::Exception); - double getValue() const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileParameterTinyInfo : public MEDFileWritable - { - public: - void setDescription(const std::string& name); - std::string getDescription() const; - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - }; - - class MEDFileParameterDouble1TS : public MEDFileParameterDouble1TSWTI, public MEDFileParameterTinyInfo - { - public: - static MEDFileParameterDouble1TS *New(); - static MEDFileParameterDouble1TS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception); - static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName, int dt, int it) throw(INTERP_KERNEL::Exception); - virtual MEDFileParameter1TS *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - void setName(const std::string& name) throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileParameterDouble1TS() - { - return MEDFileParameterDouble1TS::New(); - } - - MEDFileParameterDouble1TS(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileParameterDouble1TS::New(fileName); - } - - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception) - { - return MEDFileParameterDouble1TS::New(fileName,paramName); - } - - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it) throw(INTERP_KERNEL::Exception) - { - return MEDFileParameterDouble1TS::New(fileName,paramName,dt,it); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *isEqual(const MEDFileParameter1TS *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - } - }; - - class MEDFileParameterMultiTS : public RefCountObject, public MEDFileParameterTinyInfo - { - public: - static MEDFileParameterMultiTS *New(); - static MEDFileParameterMultiTS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileParameterMultiTS *New(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception); - std::string getName() const; - void setName(const std::string& name); - MEDFileParameterMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - void appendValue(int dt, int it, double time, double val) throw(INTERP_KERNEL::Exception); - double getDoubleValue(int iteration, int order) const throw(INTERP_KERNEL::Exception); - int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); - int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); - int getNumberOfTS() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileParameterMultiTS() - { - return MEDFileParameterMultiTS::New(); - } - - MEDFileParameterMultiTS(const std::string& fileName) - { - return MEDFileParameterMultiTS::New(fileName); - } - - MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName) - { - return MEDFileParameterMultiTS::New(fileName,paramName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *isEqual(const MEDFileParameterMultiTS *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - void eraseTimeStepIds(PyObject *ids) throw(INTERP_KERNEL::Exception) - { - int sw; - int pos1; - std::vector<int> pos2; - DataArrayInt *pos3=0; - DataArrayIntTuple *pos4=0; - convertObjToPossibleCpp1(ids,sw,pos1,pos2,pos3,pos4); - switch(sw) - { - case 1: - { - self->eraseTimeStepIds(&pos1,&pos1+1); - return; - } - case 2: - { - if(pos2.empty()) - return; - self->eraseTimeStepIds(&pos2[0],&pos2[0]+pos2.size()); - return ; - } - case 3: - { - self->eraseTimeStepIds(pos3->begin(),pos3->end()); - return ; - } - default: - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::eraseTimeStepIds : unexpected input array type recognized !"); - } - } - - int getTimeStepId(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - int pos=InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); - return pos; - } - else if(elt0 && PyTuple_Check(elt0)) - { - if(PyTuple_Size(elt0)==2) - { - PyObject *o0=PyTuple_GetItem(elt0,0); - PyObject *o1=PyTuple_GetItem(elt0,1); - if(PyInt_Check(o0) && PyInt_Check(o1)) - {//fmts(1,-1) - int iter=PyInt_AS_LONG(o0); - int order=PyInt_AS_LONG(o1); - return self->getPosOfTimeStep(iter,order); - } - else - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); - } - else - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); - } - else if(elt0 && PyFloat_Check(elt0)) - { - double val=PyFloat_AS_DOUBLE(elt0); - return self->getPosGivenTime(val); - } - else - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input params ! expected fmts[int], fmts[int,int] or fmts[double] to request time step !"); - } - - MEDFileParameter1TS *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameter1TS *ret=self->getTimeStepAtPos(ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elt0)); - if(ret) - ret->incrRef(); - return ret; - } - - std::vector<int> getTimeStepIds(PyObject *elts) const throw(INTERP_KERNEL::Exception) - { - if(PyList_Check(elts)) - { - int sz=PyList_Size(elts); - std::vector<int> ret(sz); - for(int i=0;i<sz;i++) - { - PyObject *elt=PyList_GetItem(elts,i); - ret[i]=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elt); - } - return ret; - } - else - { - std::vector<int> ret(1); - ret[0]=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elts); - return ret; - } - } - - void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) - { - std::vector<int> idsToRemove=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepIds(self,elts); - if(!idsToRemove.empty()) - self->eraseTimeStepIds(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); - } - - MEDFileParameter1TS *getTimeStepAtPos(int posId) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameter1TS *ret=self->getTimeStepAtPos(posId); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getIterations() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=self->getIterations(); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception) - { - std::vector<double> res2; - std::vector< std::pair<int,int> > res=self->getTimeSteps(res2); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(3); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyTuple_SetItem(elt,2,SWIG_From_double(res2[rk])); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - } - }; - - class MEDFileParameters : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileParameters *New(); - static MEDFileParameters *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - MEDFileParameters *deepCpy() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getParamsNames() const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushParam(MEDFileParameterMultiTS *param) throw(INTERP_KERNEL::Exception); - void setParamAtPos(int i, MEDFileParameterMultiTS *param) throw(INTERP_KERNEL::Exception); - void destroyParamAtPos(int i) throw(INTERP_KERNEL::Exception); - int getPosFromParamName(const std::string& paramName) const throw(INTERP_KERNEL::Exception); - int getNumberOfParams() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileParameters() - { - return MEDFileParameters::New(); - } - - MEDFileParameters(const std::string& fileName) - { - return MEDFileParameters::New(fileName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileParameterMultiTS *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(PyInt_Check(obj)) - { - MEDFileParameterMultiTS *ret=self->getParamAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfParams())); - if(ret) - ret->incrRef(); - return ret; - } - else if(PyString_Check(obj)) - { - MEDFileParameterMultiTS *ret=self->getParamWithName(PyString_AsString(obj)); - if(ret) - ret->incrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("MEDFileParameters::__getitem__ : only integer or string with meshname supported !"); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfParams(); - } - - MEDFileParameterMultiTS *getParamAtPos(int i) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameterMultiTS *ret=self->getParamAtPos(i); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileParameterMultiTS *getParamWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameterMultiTS *ret=self->getParamWithName(paramName); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *isEqual(const MEDFileParameters *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - } - }; - - class MEDFileData : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileData *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileData *New(); - MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception); - void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); - void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception); - void setParams(MEDFileParameters *params) throw(INTERP_KERNEL::Exception); - int getNumberOfFields() const throw(INTERP_KERNEL::Exception); - int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); - int getNumberOfParams() const throw(INTERP_KERNEL::Exception); - // - bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName) throw(INTERP_KERNEL::Exception); - bool unPolyzeMeshes() throw(INTERP_KERNEL::Exception); - // - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileData(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileData::New(fileName); - } - - MEDFileData() - { - return MEDFileData::New(); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileMeshes *getMeshes() const throw(INTERP_KERNEL::Exception) - { - MEDFileMeshes *ret=self->getMeshes(); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileParameters *getParams() const throw(INTERP_KERNEL::Exception) - { - MEDFileParameters *ret=self->getParams(); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileFields *getFields() const throw(INTERP_KERNEL::Exception) - { - MEDFileFields *ret=self->getFields(); - if(ret) - ret->incrRef(); - return ret; - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - } - }; - - class SauvReader : public RefCountObject - { - public: - static SauvReader* New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - MEDFileData * loadInMEDFileDS() throw(INTERP_KERNEL::Exception); - %extend - { - SauvReader(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return SauvReader::New(fileName); - } - } - }; - - class SauvWriter : public RefCountObject - { - public: - static SauvWriter * New(); - void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0) throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName) throw(INTERP_KERNEL::Exception); - void setCpyGrpIfOnASingleFamilyStatus(bool status) throw(INTERP_KERNEL::Exception); - bool getCpyGrpIfOnASingleFamilyStatus() const throw(INTERP_KERNEL::Exception); - %extend - { - SauvWriter() throw(INTERP_KERNEL::Exception) - { - return SauvWriter::New(); - } - } - }; - - /////////////// - - class MEDFileMeshStruct; - - class MEDFileField1TSStructItem - { - public: - static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception); - }; - - class MEDFileMeshStruct : public RefCountObject - { - public: - static MEDFileMeshStruct *New(const MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); - protected: - ~MEDFileMeshStruct(); - }; - - class MEDMeshMultiLev : public RefCountObject - { - public: - virtual MEDMeshMultiLev *prepare() const throw(INTERP_KERNEL::Exception); - DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception); - protected: - ~MEDMeshMultiLev(); - public: - %extend - { - PyObject *retrieveFamilyIdsOnCells() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *famIds(0); - bool isWithoutCopy(false); - self->retrieveFamilyIdsOnCells(famIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(famIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *retrieveNumberIdsOnCells() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *numIds(0); - bool isWithoutCopy(false); - self->retrieveNumberIdsOnCells(numIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(numIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *retrieveFamilyIdsOnNodes() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *famIds(0); - bool isWithoutCopy(false); - self->retrieveFamilyIdsOnNodes(famIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(famIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *retrieveNumberIdsOnNodes() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *numIds(0); - bool isWithoutCopy(false); - self->retrieveNumberIdsOnNodes(numIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(numIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *getGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector< INTERP_KERNEL::NormalizedCellType > result(self->getGeoTypes()); - std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator iL(result.begin()); - PyObject *res(PyList_New(result.size())); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - } - }; - - class MEDUMeshMultiLev : public MEDMeshMultiLev - { - protected: - ~MEDUMeshMultiLev(); - public: - %extend - { - PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *coords(0); DataArrayByte *types(0); DataArrayInt *cellLocations(0),*cells(0),*faceLocations(0),*faces(0); - bool ncc(self->buildVTUArrays(coords,types,cellLocations,cells,faceLocations,faces)); - PyObject *ret0Py=ncc?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyObject *ret=PyTuple_New(7); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(coords),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(types),SWIGTYPE_p_ParaMEDMEM__DataArrayByte, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cellLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(cells),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(faceLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,6,SWIG_NewPointerObj(SWIG_as_voidptr(faces),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - } - }; - - class MEDStructuredMeshMultiLev : public MEDMeshMultiLev - { - protected: - ~MEDStructuredMeshMultiLev(); - }; - - class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev - { - protected: - ~MEDCMeshMultiLev(); - public: - %extend - { - PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) - { - bool isInternal; - std::vector< DataArrayDouble * > objs(self->buildVTUArrays(isInternal)); - std::size_t sz(objs.size()); - PyObject *ret(PyTuple_New(2)); - PyObject *ret0=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(ret0,i,SWIG_NewPointerObj(SWIG_as_voidptr(objs[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,0,ret0); - PyObject *ret1Py(isInternal?Py_True:Py_False); - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - } - }; - - class MEDCurveLinearMeshMultiLev : public MEDStructuredMeshMultiLev - { - protected: - ~MEDCurveLinearMeshMultiLev(); - public: - %extend - { - PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret0(0); - std::vector<int> ret1; - bool ret2; - self->buildVTUArrays(ret0,ret1,ret2); - std::size_t sz(ret1.size()); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyObject *ret1Py=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(ret1Py,i,SWIG_From_int(ret1[i])); - PyTuple_SetItem(ret,1,ret1Py); - PyObject *ret2Py(ret2?Py_True:Py_False); - Py_XINCREF(ret2Py); - PyTuple_SetItem(ret,2,ret2Py); - return ret; - } - } - }; - - class MEDFileFastCellSupportComparator : public RefCountObject - { - public: - static MEDFileFastCellSupportComparator *New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception); - MEDMeshMultiLev *buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); - bool isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); - int getNumberOfTS() const throw(INTERP_KERNEL::Exception); - protected: - ~MEDFileFastCellSupportComparator(); - public: - %extend - { - PyObject *getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const throw(INTERP_KERNEL::Exception) - { - std::vector< INTERP_KERNEL::NormalizedCellType > result(self->getGeoTypesAt(timeStepId,m)); - std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator iL(result.begin()); - PyObject *res(PyList_New(result.size())); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - } - }; -} diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py b/medtool/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py deleted file mode 100644 index 24520950d..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py +++ /dev/null @@ -1,597 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS) - -from MEDLoader import * -from MEDCouplingRemapper import * -import math, os - -d=DataArrayDouble.New(6,2) -d[:,0]=3. -d[:,1]=range(6) -d[:,1]*=math.pi/3. -d=d.fromPolarToCart() -d.setInfoOnComponents(["X [m]","Y [m]"]) -print d.getValues() -print d -print d.magnitude().isUniform(3.,1e-12) -# -radius=3. -translationToPerform=[[0.,0.],[3./2.*radius,-radius*math.sqrt(3.)/2],[3./2.*radius,radius*math.sqrt(3.)/2],[0.,radius*math.sqrt(3.)],[-3./2.*radius,radius*math.sqrt(3.)/2],[-3./2.*radius,-radius*math.sqrt(3.)/2],[0.,-radius*math.sqrt(3.)]] -ds=len(translationToPerform)*[None] -for pos,t in enumerate(translationToPerform): - ds[pos]=d[:] - ds[pos]+=t - pass -# -d2=DataArrayDouble.Aggregate(ds) -oldNbOfTuples=d2.getNumberOfTuples() -c,cI=d2.findCommonTuples(1e-12) -tmp=c[cI[0]:cI[0+1]] -print tmp -a=cI.deltaShiftIndex() -b=a-1 -myNewNbOfTuples=oldNbOfTuples-sum(b.getValues()) -o2n,newNbOfTuples=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfTuples,c,cI) -print "Ai je trouve le bon resultat ? %s"%(str(myNewNbOfTuples==newNbOfTuples)) ; assert myNewNbOfTuples==newNbOfTuples -# -d3=d2.renumberAndReduce(o2n,newNbOfTuples) -n2o=o2n.invertArrayO2N2N2O(newNbOfTuples) -d3_bis=d2[n2o] -print "Ai je trouve le bon resultat (2) ? %s"%(str(d3.isEqual(d3_bis,1e-12))) ; assert d3.isEqual(d3_bis,1e-12) -# -d3+=[3.3,4.4] -# d3 contains coordinates -m=MEDCouplingUMesh.New("My7hexagons",2) -m.setCoords(d3) -m.allocateCells(7) -for i in xrange(7): - m.insertNextCell(NORM_POLYGON,o2n[6*i:6*(i+1)].getValues()) - pass -m.finishInsertingCells() -m.checkCoherency() -# -m.writeVTK("My7hexagons.vtu") - -######## - -coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] -conn=[0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] -mesh3D=MEDCouplingUMesh.New("mesh3D",3); -mesh3D.allocateCells(18); -mesh3D.insertNextCell(NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(NORM_HEXA8,conn[110:118]); -mesh3D.insertNextCell(NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(NORM_HEXA8,conn[228:236]); -mesh3D.insertNextCell(NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(NORM_HEXA8,conn[346:354]); -mesh3D.finishInsertingCells(); -myCoords=DataArrayDouble.New(coords,60,3); -myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) -mesh3D.setCoords(myCoords); -mesh3D.orientCorrectlyPolyhedrons() -mesh3D.sortCellsInMEDFileFrmt() -mesh3D.checkCoherency() -renum=DataArrayInt.New(60) ; renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) -mesh3D.renumberNodes(renum,60) -# -mesh3D.getCoords()[:]*=100. -mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) -# -zLev=mesh3D.getCoords()[:,2] -zLev=zLev.getDifferentValues(1e-12) -zLev.sort() -# -tmp,cellIdsSol1=mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2],[0.,0.,1.],1e-12) -bary=mesh3D.getBarycenterAndOwner() -baryZ=bary[:,2] -cellIdsSol2=baryZ.getIdsInRange(zLev[1],zLev[2]) -nodeIds=mesh3D.findNodesOnPlane([0.,0.,zLev[0]],[0.,0.,1.],1e-10) -mesh2D=mesh3D.buildFacePartOfMySelfNode(nodeIds,True) -extMesh=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,0) -cellIdsSol3=extMesh.getMesh3DIds()[mesh2D.getNumberOfCells():2*mesh2D.getNumberOfCells()] -for i in xrange(3): - exec("print cellIdsSol%s.getValues()"%(i+1)) -# -mesh3DPart=mesh3D[cellIdsSol2] # equivalent to mesh3DPart=mesh3D.buildPartOfMySelf(cellIdsSol2,True) -mesh3DPart.zipCoords() -print mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) ; assert mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) -print mesh3DPart.checkConsecutiveCellTypes() ; assert mesh3DPart.checkConsecutiveCellTypes() -#print mesh3DPart.advancedRepr() -# -baryXY=bary[:,[0,1]] -baryXY-=[250.,150.] -magn=baryXY.magnitude() -cellIds2Sol1=magn.getIdsInRange(0.,1e-12) -# -bary2=mesh2D.getBarycenterAndOwner()[:,[0,1]] -bary2-=[250.,150.] -magn=bary2.magnitude() -ids=magn.getIdsInRange(0.,1e-12) -idStart=int(ids) # ids is assumed to contain only one value, if not an exception is thrown -cellIds2Sol2=extMesh.getMesh3DIds()[range(idStart,mesh3D.getNumberOfCells(),mesh2D.getNumberOfCells())] -# -mesh3DSlice2=mesh3D[cellIds2Sol1] -mesh3DSlice2.zipCoords() -# -mesh3DSlice2bis=mesh3DSlice2.deepCpy() -mesh3DSlice2bis.translate([0.,1000.,0.]) -mesh3DSlice2All=MEDCouplingUMesh.MergeUMeshes([mesh3DSlice2,mesh3DSlice2bis]) -mesh3DSlice2All.writeVTK("mesh3DSlice2All.vtu") -# -mesh3DSurf,desc,descIndx,revDesc,revDescIndx=mesh3D.buildDescendingConnectivity() -numberOf3DCellSharing=revDescIndx.deltaShiftIndex() -cellIds=numberOf3DCellSharing.getIdsNotEqual(1) -mesh3DSurfInside=mesh3DSurf[cellIds] -mesh3DSurfInside.writeVTK("mesh3DSurfInside.vtu") - -###### - -xarr=DataArrayDouble.New(11,1) -xarr.iota(0.) -cmesh=MEDCouplingCMesh.New() -cmesh.setCoords(xarr,xarr,xarr) -mesh=cmesh.buildUnstructured() -mesh.convertToPolyTypes(DataArrayInt.Range(0,mesh.getNumberOfCells(),2)) -# - -f=mesh.fillFromAnalytic(ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") -f.setName("MyField") -# -f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) -f2.setMesh(mesh) -f2.setName("MyField2") -f2.fillFromAnalytic(1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") -print "f and f2 are equal : %s"%(f.isEqualWithoutConsideringStr(f2,1e-13,1e-12)) ; assert f.isEqualWithoutConsideringStr(f2,1e-13,1e-12) -# -ids1=f.getArray().getIdsInRange(0.,5.) -fPart1=f.buildSubPart(ids1) -ids2=f.getArray().getIdsInRange(50.,1.e300) -fPart2=f.buildSubPart(ids2) -#Renumbering cells to follow MED file -fPart1Cpy=fPart1.deepCpy() -o2n=fPart1Cpy.getMesh().sortCellsInMEDFileFrmt() -fPart1Cpy.getArray().renumberInPlace(o2n) -#Check that fPart1Cpy and fPart1 are the same -fPart1Cpy.substractInPlaceDM(fPart1,12,1e-12) -fPart1Cpy.getArray().abs() -print "Fields are the same ? %s"%(fPart1Cpy.getArray().accumulate()[0]<1e-12) ; assert fPart1Cpy.getArray().accumulate()[0]<1e-12 -# -fPart12=MEDCouplingFieldDouble.MergeFields([fPart1,fPart2]) -# evaluation on points -bary=fPart12.getMesh().getBarycenterAndOwner() -arr1=fPart12.getValueOnMulti(bary) -arr2=f.getValueOnMulti(bary) -delta=arr1-arr2 -delta.abs() -print "Check OK : %s"%(delta.accumulate()[0]<1e-12) ; assert delta.accumulate()[0]<1e-12 -# -print abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0])<1e-10 ; assert abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0])<1e-10 -fPart12.getMesh().scale([0.,0.,0.],1.2) -print abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 ; assert abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 -# Explosion of field -fVec=mesh.fillFromAnalytic(ON_CELLS,3,"(x-5.)*IVec+(y-5.)*JVec+(z-5.)*KVec") -fVecPart1=fVec.buildSubPart(ids1) -fVecPart1.setName("fVecPart1") -cells=fPart1.getMesh().getNumberOfCells()*[None] -for icell,vec in enumerate(fVecPart1.getArray()): - m=fPart1.getMesh()[[icell]] - m.zipCoords() - m.translate(vec) - cells[icell]=m - pass -meshFVecPart1Exploded=MEDCouplingUMesh.MergeUMeshes(cells) -fPart1.setMesh(meshFVecPart1Exploded) - -#### - -targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; -targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; -targetMesh=MEDCouplingUMesh.New("MyMesh",2); -targetMesh.allocateCells(5); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); -targetMesh.finishInsertingCells(); -myCoords=DataArrayDouble.New(targetCoords,9,2); -myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) -targetMesh.setCoords(myCoords); -# -MEDLoader.WriteUMesh("TargetMesh.med",targetMesh,True) -# -meshRead=MEDLoader.ReadUMeshFromFile("TargetMesh.med",targetMesh.getName(),0) -print "Is the mesh read in file equals targetMesh ? %s"%(meshRead.isEqual(targetMesh,1e-12)) ; assert meshRead.isEqual(targetMesh,1e-12) -# -f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) -f.setTime(5.6,7,8) -f.setArray(targetMesh.getBarycenterAndOwner()) -f.setMesh(targetMesh) -f.setName("AFieldName") -MEDLoader.WriteField("MyFirstField.med",f,True) -# -f2=MEDLoader.ReadFieldCell("MyFirstField.med",f.getMesh().getName(),0,f.getName(),7,8) -print "Is the field read in file equals f ? %s"%(f2.isEqual(f,1e-12,1e-12)) ; assert f2.isEqual(f,1e-12,1e-12) -# -MEDLoader.WriteUMesh("MySecondField.med",f.getMesh(),True) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f) -# -f2=f.clone(True) -f2.getArray()[:]*=2.0 -f2.setTime(7.8,9,10) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f2) -# -f3=MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),7,8) -print "Is the field read in file equals f ? %s"%(f.isEqual(f3,1e-12,1e-12)) ; assert f.isEqual(f3,1e-12,1e-12) -f4=MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),9,10) -print "Is the field read in file equals f ? %s"%(f2.isEqual(f4,1e-12,1e-12)) ; assert f2.isEqual(f4,1e-12,1e-12) - -##### - -targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; -targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; -targetMesh=MEDCouplingUMesh.New("MyMesh",2); -targetMesh.allocateCells(5); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); -targetMesh.finishInsertingCells(); -myCoords=DataArrayDouble.New(targetCoords,9,2); -myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) -targetMesh.setCoords(myCoords); -# -targetMeshConsti=targetMesh.buildDescendingConnectivity()[0] -targetMesh1=targetMeshConsti[[3,4,7,8]] -targetMesh1.setName(targetMesh.getName()) -# -meshMEDFile=MEDFileUMesh.New() -meshMEDFile.setMeshAtLevel(0,targetMesh) -meshMEDFile.setMeshAtLevel(-1,targetMesh1) -# Some groups on cells Level 0 -grp0_0=DataArrayInt.New([0,1,3]) ; grp0_0.setName("grp0_Lev0") -grp1_0=DataArrayInt.New([1,2,3,4]) ; grp1_0.setName("grp1_Lev0") -meshMEDFile.setGroupsAtLevel(0,[grp0_0,grp1_0]) -# Some groups on cells Level -1 -grp0_M1=DataArrayInt.New([0,1]) ; grp0_M1.setName("grp0_LevM1") -grp1_M1=DataArrayInt.New([0,1,2]) ; grp1_M1.setName("grp1_LevM1") -grp2_M1=DataArrayInt.New([1,2,3]) ; grp2_M1.setName("grp2_LevM1") -meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) -# -meshMEDFile.write("TargetMesh2.med",2) # 2 stands for write from scratch -# -meshMEDFileRead=MEDFileMesh.New("TargetMesh2.med") -meshRead0=meshMEDFileRead.getMeshAtLevel(0) -meshRead1=meshMEDFileRead.getMeshAtLevel(-1) -print "Is the mesh at level 0 read in file equals targetMesh ? %s"%(meshRead0.isEqual(targetMesh,1e-12)) ; assert meshRead0.isEqual(targetMesh,1e-12) -print "Is the mesh at level -1 read in file equals targetMesh ? %s"%(meshRead1.isEqual(targetMesh1,1e-12)) ; assert meshRead1.isEqual(targetMesh1,1e-12) -# -print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") -grp0_0_read=meshMEDFileRead.getGroupArr(0,"grp0_Lev0") -print "Is group \"grp0_Lev0\" are the same ? %s"%(grp0_0_read.isEqual(grp0_0)) ; assert grp0_0_read.isEqual(grp0_0) -# -# Fields -# -f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) -f.setTime(5.6,7,8) -f.setArray(targetMesh.getBarycenterAndOwner()) -f.setMesh(targetMesh) -f.setName("AFieldName") -# -fMEDFile=MEDFileField1TS.New() -fMEDFile.setFieldNoProfileSBT(f) -# -fMEDFile.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it -# -fMEDFileRead=MEDFileField1TS.New("TargetMesh2.med",f.getName(),7,8) -fRead1=fMEDFileRead.getFieldOnMeshAtLevel(ON_CELLS,0,meshMEDFileRead) # fastest method. No read in file. -fRead2=fMEDFileRead.getFieldAtLevel(ON_CELLS,0) # basic method like, mesh is reread in file... -print "Does the field f remains the same using fast method ? %s"%(fRead1.isEqual(f,1e-12,1e-12)) ; assert fRead1.isEqual(f,1e-12,1e-12) -print "Does the field f remains the same using slow method ? %s"%(fRead2.isEqual(f,1e-12,1e-12)) ; assert fRead2.isEqual(f,1e-12,1e-12) -# -# Writing and Reading fields on profile using MEDLoader advanced API -# -pfl=DataArrayInt.New([1,2,3]) ; pfl.setName("My1stPfl") -fPart=f.buildSubPart(pfl) -fPart.setName("fPart") -# -fMEDFile2=MEDFileField1TS.New() -fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) -fMEDFile2.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it -# -fMEDFileRead2=MEDFileField1TS.New("TargetMesh2.med",fPart.getName(),7,8) -fPartRead,pflRead=fMEDFileRead2.getFieldWithProfile(ON_CELLS,0,meshMEDFileRead) -print fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) ; assert fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) -print pflRead.isEqualWithoutConsideringStr(pfl) ; assert pflRead.isEqualWithoutConsideringStr(pfl) - -##### - -m0=MEDCouplingCMesh() -arr=DataArrayDouble(31,1) ; arr.iota(0.) -m0.setCoords(arr,arr) -m0=m0.buildUnstructured() -m00=m0[::2] ; m00.simplexize(0) ; m01=m0[1::2] -m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) -m0.getCoords()[:]*=1/15. -m0.setName("mesh") -# -CellField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; CellField.setTime(5.6,5,6) ; CellField.setMesh(m0) -CellField.setName("CellField") -CellField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") -NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) -NodeField.setName("NodeField") -NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") -# -proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) -proc1=proc0.buildComplement(m0.getNumberOfCells()) -# -NodeField0=NodeField[proc0] ; NodeField0.getMesh().setName(m0.getName()) ; CellField0=CellField[proc0] ; CellField0.setMesh(NodeField0.getMesh()) -NodeField1=NodeField[proc1] ; NodeField1.getMesh().setName(m0.getName()) ; CellField1=CellField[proc1] ; CellField1.setMesh(NodeField1.getMesh()) -# -proc0_fname="proc0.med" -MEDLoader.WriteField(proc0_fname,NodeField0,True) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc0_fname,CellField0) -proc1_fname="proc1.med" -MEDLoader.WriteField(proc1_fname,NodeField1,True) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc1_fname,CellField1) -# -CellField0_read=MEDLoader.ReadFieldCell("proc0.med","mesh",0,"CellField",5,6) -CellField1_read=MEDLoader.ReadFieldCell("proc1.med","mesh",0,"CellField",5,6) -CellField_read=MEDCouplingFieldDouble.MergeFields([CellField0_read,CellField1_read]) -CellFieldCpy=CellField.deepCpy() -CellFieldCpy.substractInPlaceDM(CellField_read,10,1e-12) -CellFieldCpy.getArray().abs() -print CellFieldCpy.getArray().isUniform(0.,1e-12) -# -NodeField0_read=MEDLoader.ReadFieldNode("proc0.med","mesh",0,"NodeField",5,6) -NodeField1_read=MEDLoader.ReadFieldNode("proc1.med","mesh",0,"NodeField",5,6) -NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0_read,NodeField1_read]) -NodeField_read.mergeNodes(1e-10) -NodeFieldCpy=NodeField.deepCpy() -NodeFieldCpy.mergeNodes(1e-10) -NodeFieldCpy.substractInPlaceDM(NodeField_read,10,1e-12) -print NodeFieldCpy.getArray().isUniform(0.,1e-12) ; assert NodeFieldCpy.getArray().isUniform(0.,1e-12) -# -fileNames=["proc0.med","proc1.med"] -msML=[MEDFileMesh.New(fname) for fname in fileNames] -fsML=[MEDFileFields.New(fname) for fname in fileNames] -mergeMLMesh=MEDFileUMesh() -mergeMLFields=MEDFileFields() -for lev in msML[0].getNonEmptyLevels(): - o2nML=len(msML[0].getNonEmptyLevels())*[None] - cs=[mML.getCoords() for mML in msML] - mergeMLMesh.setCoords(DataArrayDouble.Aggregate(cs)) - ms=[mML.getMeshAtLevel(lev) for mML in msML] - m=MEDCouplingUMesh.MergeUMeshes(ms) ; m.setCoords(mergeMLMesh.getCoords()) - o2nML[lev]=m.sortCellsInMEDFileFrmt() - mergeMLMesh.setMeshAtLevel(lev,m) - pass -# -for fieldName in fsML[0].getFieldsNames(): - fmts=[fML[fieldName] for fML in fsML] - mergeField=MEDFileFieldMultiTS() - for dt,it,tim in fmts[0].getTimeSteps(): - fts=[fmt[dt,it] for fmt in fmts] - arrs=len(fts)*[None] - for typp in fts[0].getTypesOfFieldAvailable(): - arr1s=[] - if typp==ON_CELLS: - for ft in fts: - for geoTyp,smth in ft.getFieldSplitedByType(): - if geoTyp!=NORM_ERROR: - smth1=filter(lambda x:x[0]==ON_CELLS,smth) - arr2s=[ft.getUndergroundDataArray()[elt[1][0]:elt[1][1]] for elt in smth1] - arr1s.append(DataArrayDouble.Aggregate(arr2s)) - pass - pass - pass - pass - else: - for ft in fts: - smth=filter(lambda x:x[0]==NORM_ERROR,ft.getFieldSplitedByType()) - arr2=DataArrayDouble.Aggregate([ft.getUndergroundDataArray()[elt[1][0][1][0]:elt[1][0][1][1]] for elt in smth]) - arr1s.append(arr2) - pass - pass - arr=DataArrayDouble.Aggregate(arr1s) - if typp==ON_CELLS: - arr.renumberInPlace(o2nML[lev]) - mcf=MEDCouplingFieldDouble(typp,ONE_TIME) ; mcf.setName(fieldName) ; mcf.setTime(tim,dt,it) ; mcf.setArray(arr) - mcf.setMesh(mergeMLMesh.getMeshAtLevel(lev)) ; mcf.checkCoherency() - mergeField.appendFieldNoProfileSBT(mcf) - pass - pass - mergeMLFields.pushField(mergeField) - pass -mergeMLMesh.write("merge.med",2) -mergeMLFields.write("merge.med",0) - -##### - -arr=DataArrayDouble(11) ; arr.iota(0) -trgMesh=MEDCouplingCMesh() ; trgMesh.setCoords(arr,arr) ; trgMesh=trgMesh.buildUnstructured() -# -arr=DataArrayDouble(21) ; arr.iota(0) ; arr*=0.5 -srcMesh=MEDCouplingCMesh() ; srcMesh.setCoords(arr,arr) ; srcMesh=srcMesh.buildUnstructured() -# -tmp=srcMesh[:20] ; tmp.simplexize(0) -srcMesh=MEDCouplingUMesh.MergeUMeshes([tmp,srcMesh[20:]]) -# -remap=MEDCouplingRemapper() -remap.prepare(srcMesh,trgMesh,"P0P0") -# -myMatrix=remap.getCrudeMatrix() -print myMatrix # pour voir a quoi elle ressemble -sumByRows=DataArrayDouble(len(myMatrix)) -for i,wIt in enumerate(sumByRows): - su=0. - for it in myMatrix[i]: - su+=myMatrix[i][it] - wIt[0]=su -print "Does interpolation look OK ? %s"%(str(sumByRows.isUniform(1.,1e-12))) ; assert sumByRows.isUniform(1.,1e-12) -# -srcField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; srcField.setMesh(srcMesh) -srcField.fillFromAnalytic(1,"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") -# -#remap.transferField(srcField,1e300) -srcField.setNature(ConservativeVolumic) -trgFieldCV=remap.transferField(srcField,1e300) -# -print "ConservativeVolumic %lf == %lf"%(srcField.integral(True)[0],trgFieldCV.integral(True)[0]) ; assert abs(srcField.integral(True)[0]-trgFieldCV.integral(True)[0])<1e-6 -print "ConservativeVolumic %lf != %lf"%(srcField.getArray().accumulate()[0],trgFieldCV.getArray().accumulate()[0]) ; assert abs(srcField.getArray().accumulate()[0]-trgFieldCV.getArray().accumulate()[0])>1e-6 -# -srcField.setNature(Integral) -trgFieldI=remap.transferField(srcField,1e300) -# -print "IntegralGlobConstraint %lf != %lf"%(srcField.integral(True)[0],trgFieldI.integral(True)[0]) ; assert abs(srcField.integral(True)[0]-trgFieldI.integral(True)[0])>1e-6 -print "IntegralGlobConstraint %lf == %lf"%(srcField.getArray().accumulate()[0],trgFieldI.getArray().accumulate()[0]) ; assert abs(srcField.getArray().accumulate()[0]-trgFieldI.getArray().accumulate()[0])<1e-6 - -###### - -from numpy import * -from math import acos - -med_root_dir=os.getenv("MEDCOUPLING_ROOT_DIR") -if med_root_dir: - agitateur_file=os.path.join(os.getenv("MEDCOUPLING_ROOT_DIR"),"share","resources","med","agitateur.med") -else: - current_dir = os.path.dirname(os.path.realpath(__file__)) - agitateur_file=os.path.join(current_dir, "..", "..", "..", "resources","agitateur.med") - pass -data=MEDFileData(agitateur_file) -ts=data.getFields()[0].getTimeSteps() -print ts -# -fMts=data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"] -f1ts=fMts[(2,-1)] -fMc=f1ts.getFieldAtLevel(ON_CELLS,0) -arr=fMc.getArray() -arr.getMinMaxPerComponent() # juste pour voir la plage de variation du champ par compo -ids=arr.getIdsInRange(0.,1.) -f2Mc=fMc[ids] -# -pressMts=data.getFields()["PRESSION_ELEM_DOM"] -press1ts=pressMts[(2,-1)] -pressMc=press1ts.getFieldAtLevel(ON_CELLS,0) -pressOnAgitateurMc=pressMc[ids] -# -pressOnAgitateurMc.getMesh().zipCoords() -# -agitateurMesh3DMc=pressOnAgitateurMc.getMesh() -m3DSurf,desc,descI,revDesc,revDescI=agitateurMesh3DMc.buildDescendingConnectivity() -nbOf3DCellSharing=revDescI.deltaShiftIndex() -ids2=nbOf3DCellSharing.getIdsEqual(1) -agitateurSkinMc=m3DSurf[ids2] -OffsetsOfTupleIdsInField=revDescI[ids2] -tupleIdsInField=revDesc[OffsetsOfTupleIdsInField] -pressOnSkinAgitateurMc=pressOnAgitateurMc[tupleIdsInField] -pressOnSkinAgitateurMc.setMesh(agitateurSkinMc) -# -pressSkin=pressOnSkinAgitateurMc.getArray() -pressSkin*=1e5 -areaSkin=agitateurSkinMc.getMeasureField(True).getArray() -forceSkin=pressSkin*areaSkin -normalSkin=agitateurSkinMc.buildOrthogonalField().getArray() -forceVectSkin=forceSkin*normalSkin -# -singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() -singlePolyhedron.orientCorrectlyPolyhedrons() -centerOfMass=singlePolyhedron.getBarycenterAndOwner() - -barySkin=agitateurSkinMc.getBarycenterAndOwner() -posSkin=barySkin-centerOfMass - -torquePerCellOnSkin=DataArrayDouble.CrossProduct(posSkin,forceVectSkin) - -zeTorque=torquePerCellOnSkin.accumulate() -print "couple = %r N.m"%(zeTorque[2]) ; assert abs(zeTorque[2]-0.37)<1e-2 - -speedMts=data.getFields()["VITESSE_ELEM_DOM"] -speed1ts=speedMts[(2,-1)] -speedMc=speed1ts.getFieldAtLevel(ON_CELLS,0) -speedOnSkin=speedMc.getArray()[tupleIdsInField] -powerSkin=DataArrayDouble.Dot(forceVectSkin,speedOnSkin) -power=powerSkin.accumulate()[0] -print "power = %r W"%(power) ; assert abs(power-4.22)<1e-2 - -x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] -y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] -xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] -inertiaSkin=matrix([[x2,xy],[xy,y2]]) -inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) -pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] -vect0=inertiaSkinVects[pos].tolist()[0] -print vect0 - -def computeAngle(locAgitateur1ts): - fMc=locAgitateur1ts.getFieldAtLevel(ON_CELLS,0) - arr=fMc.getArray() - ids=arr.getIdsInRange(0.,1.) - f2Mc=fMc[ids] - m3DSurf,desc,descI,revDesc,revDescI=f2Mc.getMesh().buildDescendingConnectivity() - nbOf3DCellSharing=revDescI.deltaShiftIndex() - ids2=nbOf3DCellSharing.getIdsEqual(1) - agitateurSkinMc=m3DSurf[ids2] - # - singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() - singlePolyhedron.orientCorrectlyPolyhedrons() - centerOfMass=singlePolyhedron.getBarycenterAndOwner() - bary=agitateurSkinMc.getBarycenterAndOwner() - posSkin=bary-centerOfMass - x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] - y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] - xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] - inertiaSkin=matrix([[x2,xy],[xy,y2]]) - inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) - pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] - vect0=inertiaSkinVects[pos].tolist()[0] - return vect0 - -vects=len(ts)*[None] -for itts,locAgitateur1ts in zip(ts,data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"]): - angle=computeAngle(locAgitateur1ts) - vects[itts[0]]=angle - pass - -angle2=len(ts)*[0.] -for pos in xrange(2,len(vects)): - norm1=sqrt(vects[pos-1][0]*vects[pos-1][0]+vects[pos-1][1]*vects[pos-1][1]) - norm2=sqrt(vects[pos][0]*vects[pos][0]+vects[pos][1]*vects[pos][1]) - crs=vects[pos-1][0]*vects[pos][0]+vects[pos-1][1]*vects[pos][1] - crs/=norm1 ; crs/=norm2 ; crs=min(crs,1.) - angle2[pos]=acos(crs)#/(ts[pos][2]-ts[pos-1][2]) - pass - -omega=sum(angle2)/(ts[-1][2]-ts[0][2]) -print sum(angle2) ; assert abs(sum(angle2)-1.12)<1e-2 -print "Au pdt (%d,%d) a %r s le couple est de : %r N.m, power/omega=%r N.m"%(ts[2][0],ts[2][1],ts[2][2],zeTorque[2],power/omega) -assert abs(power/omega-0.37)<1e-2 diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderDataForTest.py b/medtool/src/MEDLoader/Swig/MEDLoaderDataForTest.py deleted file mode 100644 index e8f0f5332..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderDataForTest.py +++ /dev/null @@ -1,728 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -from MEDLoader import * -from math import pi,e,sqrt - -class MEDLoaderDataForTest: - def build1DMesh_1(cls): - coords=[ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 ] - conn=[ 0,1, 1,2, 2,3 , 3,4,5] - mesh=MEDCouplingUMesh.New(); - mesh.setName("1DMesh_1"); - mesh.setMeshDimension(1); - mesh.allocateCells(4); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) - mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) - mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) - mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) - mesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,6,1); - myCoords.setInfoOnComponent(0,"tototototototot [m*m*m*m*m*m*m*m]"); - mesh.setCoords(myCoords); - return mesh; - - def build2DCurveMesh_1(cls): - coords=[ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 ] - conn=[ 0,1, 1,2, 2,3 , 3,4,5] - mesh=MEDCouplingUMesh.New(); - mesh.setName("2DCurveMesh_1"); - mesh.setMeshDimension(1); - mesh.allocateCells(4); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) - mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) - mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) - mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) - mesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,6,2); - mesh.setCoords(myCoords); - return mesh; - - def build2DMesh_1(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(6); - targetMesh.setName("2DMesh_1"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,2); - myCoords.setInfoOnComponent(0,"tototototototot [m]"); - myCoords.setInfoOnComponent(1,"energie [kW]"); - targetMesh.setCoords(myCoords) - return targetMesh; - - def build2DMesh_2(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.setName("2DMesh_2"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,2); - myCoords.setInfoOnComponent(0,"toto [m]"); - myCoords.setInfoOnComponent(1,"energie [kW]"); - targetMesh.setCoords(myCoords); - return targetMesh; - - #this mesh has several cells duplicated ! it is not beautiful but efficient to test file WR. - def build2DMesh_3(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(13); - targetMesh.setName("2DMesh_3"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,2); - myCoords.setInfoOnComponent(0,"toto [m]"); - myCoords.setInfoOnComponent(1,"energie [kW]"); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DMesh_1(cls): - coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - conn=[ - # 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - # 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - # 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - # - ret=MEDCouplingUMesh.New(); - ret.setName("3DMesh_1"); - ret.setMeshDimension(3); - ret.allocateCells(18); - # - ret.insertNextCell(NORM_HEXA8,8,conn[0:8]) - ret.insertNextCell(NORM_HEXA8,8,conn[51:59]) - ret.insertNextCell(NORM_HEXA8,8,conn[59:67]) - ret.insertNextCell(NORM_HEXA8,8,conn[110:118]) - # - ret.insertNextCell(NORM_HEXA8,8,conn[118:126]) - ret.insertNextCell(NORM_HEXA8,8,conn[169:177]) - ret.insertNextCell(NORM_HEXA8,8,conn[177:185]) - ret.insertNextCell(NORM_HEXA8,8,conn[228:236]) - # - ret.insertNextCell(NORM_HEXA8,8,conn[236:244]) - ret.insertNextCell(NORM_HEXA8,8,conn[287:295]) - ret.insertNextCell(NORM_HEXA8,8,conn[295:303]) - ret.insertNextCell(NORM_HEXA8,8,conn[346:354]) - # - ret.insertNextCell(NORM_POLYHED,43,conn[8:51]) - ret.insertNextCell(NORM_POLYHED,43,conn[67:110]) - ret.insertNextCell(NORM_POLYHED,43,conn[126:169]) - ret.insertNextCell(NORM_POLYHED,43,conn[185:228]) - ret.insertNextCell(NORM_POLYHED,43,conn[244:287]) - ret.insertNextCell(NORM_POLYHED,43,conn[303:346]) - # - ret.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,60,3); - myCoords.setInfoOnComponent(0,"titi [m]"); - myCoords.setInfoOnComponent(1,"density power [MW/m^3]"); - myCoords.setInfoOnComponent(2,"t [kW]"); - ret.setCoords(myCoords); - return ret; - - def build3DSurfMesh_1(cls): - targetCoords=[-0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 - ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(6); - targetMesh.setName("3DSurfMesh_1"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,3); - myCoords.setInfoOnComponent(0,"toto [m]"); - myCoords.setInfoOnComponent(2,"ff [km]");#component 1 is not set for test - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DMesh_2(cls): - m3dsurfBase=MEDLoaderDataForTest.build3DSurfMesh_1(); - numbers=[0,1,2,3,5] - m3dsurf=m3dsurfBase.buildPartOfMySelf(numbers,False); - m1dBase=MEDLoaderDataForTest.build1DMesh_1(); - numbers2=[0,1,2,3] - m1d=m1dBase.buildPartOfMySelf(numbers2,False); - m1d.changeSpaceDimension(3); - vec=[0.,1.,0.] - pt=[0.,0.,0.] - m1d.rotate(pt,vec,-pi/2.); - ret=m3dsurf.buildExtrudedMesh(m1d,0); - return ret; - - def buildMultiLevelMesh_1(cls): - coo=[10.,0.,10.,1.25,10.,2.5,10.,3.75,10.,5.,8.75,0.,8.75,1.25,8.75,2.5,8.75,3.75,8.75,5.,7.5,0.,7.5,1.25,7.5,2.5,7.5,3.75,7.5,5.,6.25,0.,6.25,1.25,6.25,2.5,6.25,3.75,6.25,5.,5.,0.,5.,1.25,5.,2.5,5.,3.75,5.,5.,3.75,0.,3.75,1.25,3.75,2.5,3.75,3.75,3.75,5.,2.5,0.,2.5,1.25,2.5,2.5,2.5,3.75,2.5,5.,1.25,0.,1.25,1.25,1.25,2.5,1.25,3.75,1.25,5.,0.,1.25,0.,2.5,0.,3.75,0.,5.,0.,0.,0.,5.,10.,5.,0.,10.,10.,10.,5.,5.,5.,5.,5.,10.,5.,10.,0.625,5.,1.25,5.,1.875,5.,2.5,5.,3.125,5.,3.75,5.,4.375,5.,5.,6.25,5.,7.5,5.,8.75,4.375,10.,3.75,10.,3.125,10.,2.5,10.,1.875,10.,1.25,10.,0.625,10.,0.,8.75,0.,7.5,0.,6.25,4.375,6.25,4.375,7.5,4.375,8.75,3.75,6.25,3.75,7.5,3.75,8.75,3.125,6.25,3.125,7.5,3.125,8.75,2.5,6.25,2.5,7.5,2.5,8.75,1.875,6.25,1.875,7.5,1.875,8.75,1.25,6.25,1.25,7.5,1.25,8.75,0.625,6.25,0.625,7.5,0.625,8.75,5.625,5.,6.25,5.,6.875,5.,7.5,5.,8.125,5.,8.75,5.,9.375,5.,10.,6.25,10.,7.5,10.,8.75,9.375,10.,8.75,10.,8.125,10.,7.5,10.,6.875,10.,6.25,10.,5.625,10.,5.,8.75,5.,7.5,5.,6.25,9.375,6.25,9.375,7.5,9.375,8.75,8.75,6.25,8.75,7.5,8.75,8.75,8.125,6.25,8.125,7.5,8.125,8.75,7.5,6.25,7.5,7.5,7.5,8.75,6.875,6.25,6.875,7.5,6.875,8.75,6.25,6.25,6.25,7.5,6.25,8.75,5.625,6.25,5.625,7.5,5.625,8.75] - coo2=DataArrayDouble.New() - coo2.setValues(coo,135,2) - coo2=coo2.changeNbOfComponents(3,0.) - coo2.setInfoOnComponent(0,"X [INCONNUE]") - coo2.setInfoOnComponent(1,"Y [INCONNUE]") - coo2.setInfoOnComponent(2,"Z [INCONNUE]") - c2tri=[0,1,6,0,6,5,1,2,6,2,7,6,2,3,8,2,8,7,3,4,8,4,9,8,5,6,11,5,11,10,6,7,11,7,12,11,7,8,13,7,13,12,8,9,13,9,14,13,10,11,16,10,16,15,11,12,16,12,17,16,12,13,18,12,18,17,13,14,18,14,19,18,15,16,21,15,21,20,16,17,21,17,22,21,17,18,23,17,23,22,18,19,23,19,24,23,20,21,26,20,26,25,21,22,26,22,27,26,22,23,28,22,28,27,23,24,28,24,29,28,25,26,31,25,31,30,26,27,31,27,32,31,27,28,33,27,33,32,28,29,33,29,34,33,30,31,36,30,36,35,31,32,36,32,37,36,32,33,38,32,38,37,33,34,38,34,39,38,35,36,40,35,40,44,36,37,40,37,41,40,37,38,42,37,42,41,38,39,42,39,43,42] - c2quad4=[46,101,114,100,101,102,115,114,102,103,116,115,103,48,104,116,100,114,117,99,114,115,118,117,115,116,119,118,116,104,105,119,99,117,120,98,117,118,121,120,118,119,122,121,119,105,106,122,98,120,123,97,120,121,124,123,121,122,125,124,122,106,107,125,97,123,126,96,123,124,127,126,124,125,128,127,125,107,108,128,96,126,129,95,126,127,130,129,127,128,131,130,128,108,109,131,95,129,132,94,129,130,133,132,130,131,134,133,131,109,110,134,94,132,113,50,132,133,112,113,133,134,111,112,134,110,51,111,49,60,73,59,60,61,74,73,61,62,75,74,62,52,63,75,59,73,76,58,73,74,77,76,74,75,78,77,75,63,64,78,58,76,79,57,76,77,80,79,77,78,81,80,78,64,65,81,57,79,82,56,79,80,83,82,80,81,84,83,81,65,66,84,56,82,85,55,82,83,86,85,83,84,87,86,84,66,67,87,55,85,88,54,85,86,89,88,86,87,90,89,87,67,68,90,54,88,91,53,88,89,92,91,89,90,93,92,90,68,69,93,53,91,72,45,91,92,71,72,92,93,70,71,93,69,47,70] - m2=MEDCouplingUMesh.New("ma",2) - m2.setCoords(coo2) - m2.allocateCells(128) - nbTri=len(c2tri)/3 - for i in xrange(nbTri): - m2.insertNextCell(NORM_TRI3,3,c2tri[3*i:3*i+3]) - pass - nbQua=len(c2quad4)/4 - for i in xrange(nbQua): - m2.insertNextCell(NORM_QUAD4,4,c2quad4[4*i:4*i+4]) - pass - m2.finishInsertingCells() - m2.setDescription("CREE PAR CODE_ASTER") - m1=MEDCouplingUMesh.New("ma",1) - m1.setCoords(coo2) - c1seg=[0,1,1,2,2,3,3,4,4,9,9,14,14,19,19,24,24,29,29,34,34,39,39,43,43,42,42,41,41,40,40,44,44,35,35,30,30,25,25,20,20,15,15,10,10,5,5,0,43,39,39,34,34,29,29,24,24,19,19,14,14,9,9,4,45,53,53,54,54,55,55,56,56,57,57,58,58,59,59,49,49,60,60,61,61,62,62,52,52,63,63,64,64,65,65,66,66,67,67,68,68,69,69,47,47,70,70,71,71,72,72,45,50,94,94,95,95,96,96,97,97,98,98,99,99,100,100,46,46,101,101,102,102,103,103,48,48,104,104,105,105,106,106,107,107,108,108,109,109,110,110,51,51,111,111,112,112,113,113,50] - m1.allocateCells(80) - for i in xrange(80): - m1.insertNextCell(NORM_SEG2,2,c1seg[2*i:2*i+2]) - pass - m1.finishInsertingCells() - m1.setDescription("CREE PAR CODE_ASTER") - m0=MEDCouplingUMesh.New("ma",0) - m0.setCoords(coo2) - c0pt=[44,0,47,48] - m0.allocateCells(4) - for i in xrange(4): - m0.insertNextCell(NORM_POINT1,1,[c0pt[i]]) - pass - m0.finishInsertingCells() - f2=DataArrayInt.New() - f2.alloc(128,1) - f2[:64]=-1 - f2[64:96]=-2 - f2[96:]=-3 - f1=DataArrayInt.New() - f1.alloc(80,1) - f1[:4]=-8 - f1[4:12]=-9 - f1[12:16]=-10 - f1[16:24]=-11 - f1[24:28]=-12 - f1[28:32]=-13 - f1[32:40]=-14 - f1[40:44]=-15 - f1[44:52]=-16 - f1[52:56]=-17 - f1[56:64]=-18 - f1[64:68]=-19 - f1[68:76]=-20 - f1[76:]=-21 - f0=DataArrayInt.New() - f0.setValues([-4,-5,-6,-7],4,1) - p=DataArrayInt.New() - p.alloc(135,1) - p.fillWithZero() - p1=DataArrayInt.New() - p1.alloc(13,1) - p1.iota(1) - p[[0,4,24,43,44,45,46,47,48,49,50,51,52]]=p1 - n2=DataArrayInt.New() - n2.alloc(128,1) - n2.iota(1) - n1=DataArrayInt.New() - n1.alloc(80,1) - n1.iota(133) - n0=DataArrayInt.New() - n0.alloc(4,1) - n0.iota(129) - fns=['A1A2____________________________', 'A1______________________________', 'A2A4____________________________', 'A2______________________________', 'A3A1____________________________', 'A3C5____________________________', 'A3______________________________', 'A4A3____________________________', 'A4______________________________', 'B1C1____________________________', 'B1______________________________', 'B2B4____________________________', 'B2______________________________', 'B3B1____________________________', 'B3______________________________', 'B4C3____________________________', 'B4______________________________', 'C1C4____________________________', 'C1______________________________', 'C2B2____________________________', 'C2______________________________', 'C3C2____________________________', 'C3______________________________', 'C4B3____________________________', 'C4______________________________', 'C5A4____________________________', 'C5______PMMA____________________', 'FAMILLE_ZERO', 'MESH____APPS____AP1_____________', 'MESH____APPS____AP2_____________', 'MESH____APPS____AP3_____________', 'MESH____APPS____AP4_____________', 'MESH____DALQ1___DALLE___________', 'MESH____DALQ2___DALLE___________', 'MESH____DALT3___DALLE___________'] - fids=[-11, 5, -8, 1, -10, -12, 4, -9, 2, -14, 6, -19, 7, -17, 8, -20, 9, -15, 10, -18, 11, -21, 12, -16, 13, -13, 3, 0, -4, -5, -6, -7, -3, -2, -1] - grpns=['A1', 'A1A2', 'A2', 'A2A4', 'A3', 'A3A1', 'A3C5', 'A4', 'A4A3', 'AP1', 'AP2', 'AP3', 'AP4', 'APPS', 'B1', 'B1C1', 'B2', 'B2B4', 'B3', 'B3B1', 'B4', 'B4C3', 'C1', 'C1C4', 'C2', 'C2B2', 'C3', 'C3C2', 'C4', 'C4B3', 'C5', 'C5A4', 'DALLE', 'DALQ1', 'DALQ2', 'DALT3', 'MESH', 'PMMA'] - famIdsPerGrp=[[5],[-11],[1],[-8],[4],[-10],[-12],[2],[-9],[-4],[-5],[-6],[-7],[-4,-5,-6,-7],[6],[-14],[7],[-19],[8],[-17],[9],[-20],[10],[-15],[11],[-18],[12],[-21],[13],[-16],[3],[-13],[-3,-2,-1],[-3],[-2],[-1],[-4,-5,-6,-7,-3,-2,-1],[3]] - return m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp - - def buildMLMeshUnPolyze(cls,tester): - """Level 0 (meshDim=3) - 2 TETRA4 + 3 PENTA6 + 2 POLYH - # POLYH #0 becomes 1 TETRA4 - # POLYH #1 becomes HEXA8 - # Level -1 (meshDim=2) - 2 TRI3 + 3 QUAD4 + 4 POLYG - # POLYG #2 becomes TRI3""" - meshName="NightmareMesh" - # - coords=DataArrayDouble.New(38,3) ; coords.rearrange(1) ; coords.iota(1000.) ; coords.rearrange(3) ; coords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) - mesh0=MEDCouplingUMesh(meshName,3) - type0=[NORM_TETRA4,NORM_TETRA4, NORM_PENTA6,NORM_PENTA6,NORM_PENTA6, NORM_POLYHED,NORM_POLYHED] - conn0=[[0,1,2,3],[4,5,6,7], [8,9,10,11,12,13],[14,15,16,17,18,19],[20,21,22,23,24,25], [26,27,28,-1,26,29,27,-1,27,29,28,-1,28,29,26],[30,31,32,33,-1,34,37,36,35,-1,30,34,35,31,-1,31,35,36,32,-1,32,36,37,33,-1,33,37,34,30]] - mesh0.allocateCells(len(type0)) - for typ,nodalConn in zip(type0,conn0): - mesh0.insertNextCell(typ,nodalConn); - pass - mesh0.finishInsertingCells() - mesh0.setCoords(coords) - - meshM1=MEDCouplingUMesh(meshName,2) - typeM1=[NORM_TRI3,NORM_TRI3, NORM_QUAD4,NORM_QUAD4,NORM_QUAD4, NORM_POLYGON,NORM_POLYGON,NORM_POLYGON,NORM_POLYGON] - connM1=[[0,1,2],[3,4,5], [6,7,8,9],[10,11,12,13],[14,15,16,17], [18,19,20,21,22],[23,24,25,26,27],[28,29,30],[31,32,33,34,35,36,37]] - meshM1.allocateCells(len(typeM1)) - for typ,nodalConn in zip(typeM1,connM1): - meshM1.insertNextCell(typ,nodalConn); - pass - meshM1.finishInsertingCells() - meshM1.setCoords(coords) - # - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,mesh0) - mm.setMeshAtLevel(-1,meshM1) - grp0_L0=DataArrayInt.New([0,1,5,7]) ; grp0_L0.setName("grp0_L0") - grp1_L0=DataArrayInt.New([1,2,3,4,6]) ; grp1_L0.setName("grp1_L0") - tester.assertRaises(InterpKernelException,mm.setGroupsAtLevel,0,[grp0_L0,grp1_L0])# presence of 7 in grp0_L0 (only 7 cells at level 0) -> throw - grp0_L0=DataArrayInt.New([0,1,5,6]) ; grp0_L0.setName("grp0_L0") - mm.setGroupsAtLevel(0,[grp0_L0,grp1_L0]) - grp0_LM1=DataArrayInt.New([1,2,3,4,7]) ; grp0_LM1.setName("grp0_LM1") - grp1_LM1=DataArrayInt.New([2,3,4,5]) ; grp1_LM1.setName("grp1_LM1") - grp2_LM1=DataArrayInt.New([5,6,7,8]) ; grp2_LM1.setName("grp2_LM1") - mm.setGroupsAtLevel(-1,[grp0_LM1,grp1_LM1,grp2_LM1]) - grp0_Node=DataArrayInt.New([0,11,15,16]) ; grp0_Node.setName("grp0_Node") - grp1_Node=DataArrayInt.New([1,2,13,14,16]) ; grp1_Node.setName("grp1_Node") - mm.setGroupsAtLevel(1,[grp0_Node,grp1_Node]) - # - tester.assertRaises(InterpKernelException,mm.setRenumFieldArr,0,DataArrayInt.New([0,8,9,4,5,6,7,10]))# to big array - mm.setRenumFieldArr(0,DataArrayInt.New([0,8,9,4,5,6,7])) - da=DataArrayInt.New([0,8,9,4,5,6,7,11,12]) - mm.setRenumFieldArr(-1,da) - mm.setRenumFieldArr(-1,None) - mm.setRenumFieldArr(-1,da) - da=DataArrayInt.New(mm.getNumberOfNodes()+1) ; da.iota(8) ; tester.assertRaises(InterpKernelException,mm.setRenumFieldArr,1,da) # to big array more than number of nodes - da=DataArrayInt.New(mm.getNumberOfNodes()) ; da.iota(8) ; mm.setRenumFieldArr(1,da) - return mm - - def buildVecFieldOnCells_1(cls): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - nbOfCells=mesh.getNumberOfCells(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("VectorFieldOnCells"); - f1.setMesh(mesh); - array=DataArrayDouble.New(); - arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] - array.setValues(arr1,nbOfCells,3); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density [g/cm^3]"); - array.setInfoOnComponent(2,"temperature [K]"); - f1.setArray(array); - tmp=array.getPointer(); - f1.setTime(2.,0,1); - f1.checkCoherency(); - return f1; - - def buildVecFieldOnNodes_1(cls): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - nbOfNodes=mesh.getNumberOfNodes(); - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f1.setName("VectorFieldOnNodes"); - f1.setMesh(mesh); - array=DataArrayDouble.New(); - f1.setArray(array); - arr1=[70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., - 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025.] - array.setValues(arr1,nbOfNodes,3); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density [g/cm^3]"); - array.setInfoOnComponent(2,"temperature [K]"); - f1.setTime(2.12,2,3); - f1.checkCoherency(); - return f1; - - def buildVecFieldOnGauss_1(cls): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1; - _gsCoo1=gsCoo1; - _wg1=wg1; - m=MEDLoaderDataForTest.build2DMesh_2(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] - _refCoo2=refCoo2; - _gsCoo1=_gsCoo1[0:6]; - _gsCoo2=_gsCoo1 - _wg1=_wg1[0:3]; - _wg2=_wg1 - refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo3=refCoo3; - _gsCoo1=_gsCoo1[0:4]; - _wg1=_wg1[0:2]; - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - array=DataArrayDouble.New(); - array.alloc(19,2); - ptr=array.getPointer(); - for i in xrange(19*2): - array.setIJ(0,i,float(i+7)); - pass - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density"); - f.checkCoherency(); - return f; - - def buildVecFieldOnGauss_2(cls): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1; - _gsCoo1=gsCoo1; - _wg1=wg1; - m=MEDLoaderDataForTest.build2DMesh_3(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - di=DataArrayInt.New(); di.setValues([0,2,3],3,1) - f.setGaussLocalizationOnCells(di,_refCoo1,_gsCoo1,_wg1) - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([1,5],_refCoo1,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([4],_refCoo1,_gsCoo1,_wg1); - refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] - _refCoo2=refCoo2; - _gsCoo1=_gsCoo1[0:6]; - _gsCoo2=_gsCoo1 - _wg1=_wg1[0:3]; - _wg2=_wg1 - refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo3=refCoo3; - _gsCoo1=_gsCoo1[0:4]; - _wg1=_wg1[0:2]; - f.setGaussLocalizationOnCells([6,7,8],_refCoo3,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([9],_refCoo3,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - array=DataArrayDouble.New(); - array.alloc(53,2); - ptr=array.getPointer(); - for i in xrange(53*2): - array.setIJ(0,i,float(i+7)); - pass - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density"); - f.checkCoherency(); - return f; - - # idem buildVecFieldOnGauss_2 except that different discretizations are sorted inside one type - def buildVecFieldOnGauss_2_Simpler(cls): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1; - _gsCoo1=gsCoo1; - _wg1=wg1; - m=MEDLoaderDataForTest.build2DMesh_3(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - di=DataArrayInt.New(); di.setValues([0,1,2],3,1) - f.setGaussLocalizationOnCells(di,_refCoo1,_gsCoo1,_wg1) - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([3,4],_refCoo1,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([5],_refCoo1,_gsCoo1,_wg1); - refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] - _refCoo2=refCoo2; - _gsCoo1=_gsCoo1[0:6]; - _gsCoo2=_gsCoo1 - _wg1=_wg1[0:3]; - _wg2=_wg1 - refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo3=refCoo3; - _gsCoo1=_gsCoo1[0:4]; - _wg1=_wg1[0:2]; - f.setGaussLocalizationOnCells([6,7,8],_refCoo3,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([9],_refCoo3,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - array=DataArrayDouble.New(); - array.alloc(53,2); - ptr=array.getPointer(); - for i in xrange(53*2): - array.setIJ(0,i,float(i+7)); - pass - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density"); - f.checkCoherency(); - return f; - - def buildVecFieldOnGaussNE_1(cls): - m=MEDLoaderDataForTest.build2DMesh_2(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - array=DataArrayDouble.New(); - array.alloc(20,2); - for i in xrange(2*20): - array.setIJ(0,i,float(i+8)); - f.setArray(array); - array.setInfoOnComponent(0,"power [W]"); - array.setInfoOnComponent(1,"temperature"); - f.setName("MyFieldOnGaussNE"); - f.checkCoherency(); - return f; - - def buildACompleteMEDDataStructureWithFieldsOnCells_1(cls): - coo=DataArrayDouble([0,0,1,0,2,0,0,1,1,1,2,1,0,2,1,2,2,2],9,2) - m0=MEDCouplingUMesh("mesh",2) - m0.setCoords(coo) - m0.allocateCells() - m0.insertNextCell(NORM_TRI3,[1,4,2]) - m0.insertNextCell(NORM_TRI3,[4,5,2]) - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[6,7,4,3]) - m0.insertNextCell(NORM_QUAD4,[7,8,5,4]) - m1=m0.computeSkin() - mm=MEDFileUMesh() - #2 levels - mm.setMeshAtLevel(0,m0) ; mm.setMeshAtLevel(-1,m1) - #some grps/families on the 2 levels - grp0=DataArrayInt([0,2,4]); grp0.setName("gr0_0_2_4") - grp1=DataArrayInt([1,2,3,4]); grp1.setName("gr0_1_2_3_4") - grp2=DataArrayInt([0,4]); grp2.setName("gr0_0_4") - mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) - grp3=DataArrayInt([0,1]); grp3.setName("grM1_SegOnTri3") - grp4=DataArrayInt([2,3,4,5,6,7]); grp4.setName("grM1_SegOnQuad4") - grp5=DataArrayInt([0,3]); grp5.setName("grM1_bottom") - mm.setGroupsAtLevel(-1,[grp3,grp4,grp5]) - ms=MEDFileMeshes() - ms.pushMesh(mm) - # 3 fields - fs=MEDFileFields() - # 1st Field - fNoProfile - no profile on levels 0 - f1Name="fNoProfile" - timeStepsF1=[(0,-1,0.01),(1,-1,0.02)] - f1=MEDFileFieldMultiTS() - for i,(it,order,tim) in enumerate(timeStepsF1): - f11Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f11Tmp.setTime(tim,it,order) - f11Tmp.setMesh(m0) - arr=DataArrayDouble(m0.getNumberOfCells(),1) ; arr.iota() ; arr+=1+i ; arr*=0.1 - f11Tmp.setArray(arr) - f11Tmp.checkCoherency() - f11Tmp.setName(f1Name) - f1.appendFieldNoProfileSBT(f11Tmp) - pass - fs.pushField(f1) - # 2nd Field - fNoProfileMultiLevs - no profile on levels 0 and -1 - f2Name="fNoProfileMultiLevs" - timeStepsF2=[(0,-1,0.),(1,-1,0.1),(2,-1,0.2)] - f2=MEDFileFieldMultiTS() - for i,(it,order,tim) in enumerate(timeStepsF2): - f21Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f21Tmp.setTime(tim,it,order) - f21Tmp.setMesh(m0) - arr=DataArrayDouble(m0.getNumberOfCells(),1) ; arr.iota() ; arr+=1+i - f21Tmp.setArray(arr) - f21Tmp.checkCoherency() - f21Tmp.setName(f2Name) - f2.appendFieldNoProfileSBT(f21Tmp) - f22Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f22Tmp.setTime(tim,it,order) - f22Tmp.setMesh(m1) - arr=DataArrayDouble(m1.getNumberOfCells(),1) ; arr.iota() ; arr+=100+1+i - f22Tmp.setArray(arr) - f22Tmp.checkCoherency() - f22Tmp.setName(f2Name) - f2[it,order].setFieldNoProfileSBT(f22Tmp) - pass - fs.pushField(f2) - # 3rd field - fProfileMultiLevs - The most complex one - f3Name="fProfileMultiLevs" - timeStepsF3=[(0,-1,0.),(1,-1,10.),(2,-1,20.),(3,-1,30.),] - f3=MEDFileFieldMultiTS() - for i,(it,order,tim) in enumerate(timeStepsF3): - pfl1=DataArrayInt([0,1,3,4]) ; pfl1.setName("pfl1") - m0Part=m0[pfl1] - f31Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f31Tmp.setTime(tim,it,order) - f31Tmp.setMesh(m0Part) - arr=DataArrayDouble(m0Part.getNumberOfCells(),1) ; arr.iota() ; arr+=1000+i+1 - f31Tmp.setArray(arr) - f31Tmp.checkCoherency() - f31Tmp.setName(f3Name) - f3.appendFieldProfile(f31Tmp,mm,0,pfl1) - pfl2=DataArrayInt([0,3]) ; pfl2.setName("pfl2Bottom") - m1Part=m1[pfl2] - f32Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f32Tmp.setTime(tim,it,order) - f32Tmp.setMesh(m1Part) - arr=DataArrayDouble(m1Part.getNumberOfCells(),1) ; arr.iota() ; arr+=2000+1+i - f32Tmp.setArray(arr) - f32Tmp.checkCoherency() - f32Tmp.setName(f3Name) - f3[it,order].setFieldProfile(f32Tmp,mm,-1,pfl2) - pass - fs.pushField(f3) - # - data=MEDFileData() ; data.setMeshes(ms) ; data.setFields(fs) - return data - - def buildAMEDFileDataWithGroupOnOneFamilyForSauv(self): - # Coordinates - coords = [0.,0., 0.,1., 1.,1., 1.,0.] - # lvl 0 connectivity - conn2D = [1,2,3,4] - # lvl -1 connectivity - conn1D = [0,1, 1,2, 2,3, 4,1] - # lvl 0 mesh - mesh2D=MEDCouplingUMesh.New() - mesh2D.setMeshDimension(2) - mesh2D.allocateCells(1) - mesh2D.insertNextCell(NORM_QUAD4,4,conn2D) - mesh2D.finishInsertingCells() - # lvl -1 mesh - mesh1D=MEDCouplingUMesh.New() - mesh1D.setMeshDimension(1) - mesh1D.allocateCells(4) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[0:2]) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[2:4]) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[4:6]) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[6:8]) - mesh1D.finishInsertingCells() - # assigning coordinates - meshCoords=DataArrayDouble.New() - meshCoords.setValues(coords, 4, 2) - mesh2D.setCoords(meshCoords) - mesh1D.setCoords(meshCoords) - # Creating a multi level mesh - mm = MEDFileUMesh.New() - mm.setMeshAtLevel(0, mesh2D) - mm.setMeshAtLevel(-1, mesh1D) - mm.setName("carre") - # Creating groups - # Creating a group with an element on level -1 - grp0_LM1 = DataArrayInt.New([0]) - grp0_LM1.setName("grp0_LM1") - # Creating a group with all elements on level -1 - grp1_LM1 = DataArrayInt.New([0,1,2,3]) - grp1_LM1.setName("grp1_LM1") - # - mm.setGroupsAtLevel(-1,[grp0_LM1,grp1_LM1]) - # - ms=MEDFileMeshes.New() - ms.setMeshAtPos(0,mm) - mfd=MEDFileData.New() - mfd.setMeshes(ms) - # - return mfd - - build1DMesh_1=classmethod(build1DMesh_1) - build2DCurveMesh_1=classmethod(build2DCurveMesh_1) - build2DMesh_1=classmethod(build2DMesh_1) - build2DMesh_2=classmethod(build2DMesh_2) - build2DMesh_3=classmethod(build2DMesh_3) - build3DMesh_1=classmethod(build3DMesh_1) - build3DSurfMesh_1=classmethod(build3DSurfMesh_1) - build3DMesh_2=classmethod(build3DMesh_2) - buildMLMeshUnPolyze=classmethod(buildMLMeshUnPolyze) - buildMultiLevelMesh_1=classmethod(buildMultiLevelMesh_1) - buildVecFieldOnCells_1=classmethod(buildVecFieldOnCells_1) - buildVecFieldOnNodes_1=classmethod(buildVecFieldOnNodes_1) - buildVecFieldOnGauss_1=classmethod(buildVecFieldOnGauss_1) - buildVecFieldOnGauss_2=classmethod(buildVecFieldOnGauss_2) - buildVecFieldOnGauss_2_Simpler=classmethod(buildVecFieldOnGauss_2_Simpler) - buildVecFieldOnGaussNE_1=classmethod(buildVecFieldOnGaussNE_1) - buildACompleteMEDDataStructureWithFieldsOnCells_1=classmethod(buildACompleteMEDDataStructureWithFieldsOnCells_1) - buildAMEDFileDataWithGroupOnOneFamilyForSauv=classmethod(buildAMEDFileDataWithGroupOnOneFamilyForSauv) - pass diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderExamplesTest.py b/medtool/src/MEDLoader/Swig/MEDLoaderExamplesTest.py deleted file mode 100644 index d7b6aa4cb..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderExamplesTest.py +++ /dev/null @@ -1,252 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -from MEDLoader import * -import unittest -import os - -class MEDLoaderBasicsTest(unittest.TestCase): - def testExampleReadFieldOnAllEntity1(self): - from MEDLoaderDataForTest import MEDLoaderDataForTest -#! [PySnippetReadFieldOnAllEntity1_1] - fname="PyExamples1.med" - meshName="mesh" - fieldName="FieldOnAll" - iteration=3 - order=4 -#! [PySnippetReadFieldOnAllEntity1_1] -#! [PySnippetWriteFieldOnAllEntity1_2] - m=MEDLoaderDataForTest.build2DMesh_3() - m=m[:10] - m.setName(meshName) - f=m.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setTime(5.5,iteration,order) - f.setName(fieldName) - # MEDCoupling finished, MEDLoader advanced API specific part starting from here - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - ff=MEDFileField1TS.New() - ff.setFieldNoProfileSBT(f) - mm.write(fname,2) - ff.write(fname,0) -#! [PySnippetWriteFieldOnAllEntity1_2] -#! [PySnippetReadFieldOnAllEntity1_3] - medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) - mm=MEDFileMesh.New(fname) - fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) -#! [PySnippetReadFieldOnAllEntity1_3] -#! [PySnippetReadFieldOnAllEntity1_4] - medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName) - mm=MEDFileMesh.New(fname) - fread=medfileFieldMTS.getFieldOnMeshAtLevel(ON_CELLS,iteration,order,0,mm) - fread2=medfileFieldMTS.getFieldAtLevel(ON_CELLS,iteration,order,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) -#! [PySnippetReadFieldOnAllEntity1_4] -#! [PySnippetReadFieldOnAllEntity1_5] - medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName) - for medfileField1TS in medfileFieldMTS: - if medfileField1TS.getTime()[:2]==[iteration,order]: - fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) - pass - pass -#! [PySnippetReadFieldOnAllEntity1_5] - pass - - def testExampleReadFieldPartial1(self): - from MEDLoaderDataForTest import MEDLoaderDataForTest -#! [PySnippetReadFieldPartial1_1] - fname="PyExamples2.med" - meshName="mesh" - fieldName="FieldPartial" - iteration=3 - order=4 -#! [PySnippetReadFieldPartial1_1] -#! [PySnippetWriteFieldPartial1_2] - m=MEDLoaderDataForTest.build2DMesh_1() - m.sortCellsInMEDFileFrmt() - m.setName(meshName) - # end of generation of a mesh -> let's create a field on that mesh - f=m.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setTime(5.5,iteration,order) - f.setName(fieldName) - # The MEDCoupling part is finished -> let's perform advanced API - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) # the MED file data structure is ready for writing. Of course mm could have been more complicated with groups, families, multilevel - # Let's building a sub field - pfl=DataArrayInt.New([1,3,4,5]) - pfl.setName("myPfl") # here it is necessary to give a name to be compliant with MED file - f=f[pfl] ; f.getMesh().setName(m.getName()) # of course f should be in coherence with pfl -> f[pfl] - # - ff=MEDFileField1TS.New() - tmp=f.getMesh() # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile - f.setMesh(None) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile - ff.setFieldProfile(f,mm,0,pfl) - f.setMesh(tmp) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile - mm.write(fname,2) - ff.write(fname,0) -#! [PySnippetWriteFieldPartial1_2] -#! [PySnippetReadFieldPartial1_3] - mm=MEDFileMesh.New(fname) - medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) - fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) -#! [PySnippetReadFieldPartial1_3] -#! [PySnippetReadFieldPartial1_4] - medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) - mm=MEDFileMesh.New(fname) - valsRead,pflRead=medfileField1TS.getFieldWithProfile(ON_CELLS,0,mm) - self.assertEqual(valsRead.getName(),f.getName()) - valsRead.setName("") - self.assertTrue(valsRead.isEqual(f.getArray(),1e-12)) - pflRead.setName(pfl.getName()) - self.assertTrue(pflRead.isEqual(pfl)) -#! [PySnippetReadFieldPartial1_4] -#! [PySnippetReadFieldPartial1_5] - firstApproachMesh=fread.getMesh() - mm=MEDFileMesh.New(fname) - wholeMesh=mm.getMeshAtLevel(0) - wholeMesh.tryToShareSameCoords(firstApproachMesh,1e-12) - isIncluded,pflComputed=wholeMesh.areCellsIncludedIn(firstApproachMesh,2) - self.assertTrue(isIncluded) - self.assertEqual(pflComputed.getName(),mm.getName()) - pflComputed.setName(pflRead.getName()) - self.assertTrue(pflComputed.isEqual(pflRead)) -#! [PySnippetReadFieldPartial1_5] -#! [PySnippetReadFieldPartial1_6] - mm=MEDFileMesh.New(fname) - wholeMesh=mm.getMeshAtLevel(0) - computedMesh=wholeMesh[pflRead] ; computedMesh.setName(mm.getName()) - self.assertTrue(computedMesh.isEqual(fread.getMesh(),1e-12)) - fieldFromSecondApproach=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - fieldFromSecondApproach.setName(medfileField1TS.getName()) - fieldFromSecondApproach.setMesh(computedMesh) - fieldFromSecondApproach.setArray(valsRead) - fieldFromSecondApproach.setTime(medfileField1TS.getTime()[2],medfileField1TS.getTime()[0],medfileField1TS.getTime()[1]) - self.assertTrue(fieldFromSecondApproach.isEqual(fread,1e-12,1e-12)) -#! [PySnippetReadFieldPartial1_6] - pass - - def testExampleMeshAdvAPI1(self): - da=DataArrayDouble.New([0.,1.1,2.3,3.6]) - meshName="Example2" - cmesh=MEDCouplingCMesh.New() ; cmesh.setCoords(da,da,da) - myMesh=cmesh.buildUnstructured() -#! [PySnippetMeshAdvAPI1_1] - self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) - myMesh.setName(meshName) - MEDLoader.WriteUMesh("wFile1.med",myMesh,True) -#! [PySnippetMeshAdvAPI1_1] - os.remove("wFile1.med") -#! [PySnippetMeshAdvAPI1_2] - self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) - myMesh.setName(meshName) - MEDLoader.WriteUMesh("wFile1.med",myMesh,False) -#! [PySnippetMeshAdvAPI1_2] - f=myMesh.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setName("myField") -#! [PySnippetMeshAdvAPI1_3] - MEDLoader.WriteUMesh("file3.med",f.getMesh(),True) - f.setTime(1.2,1,0) - fileNameMultiTimeStep="file3.med" - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileNameMultiTimeStep,f) - f.setTime(1.3,2,0) - f.applyFunc("sqrt(x)"); - #Writing second time step with iteration==2 and order==0 - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file3.med",f); -#! [PySnippetMeshAdvAPI1_3] -#! [PySnippetMeshAdvAPI1_11] - timeStepsIds=MEDLoader.GetCellFieldIterations("file3.med","Example2","myField") - self.assertEqual([(1, 0),(2, 0)],timeStepsIds) - fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,"file3.med","Example2",0,"myField",timeStepsIds); -#! [PySnippetMeshAdvAPI1_11] - ### - myMesh0=myMesh[:] ; myMesh0.setName("Example2") - myMesh1=myMesh0.buildDescendingConnectivity()[0] ; myMesh1.setName(myMesh0.getName()) - myMesh2=myMesh1.buildDescendingConnectivity()[0] ; myMesh2.setName(myMesh0.getName()) - myMesh3=myMesh2.buildDescendingConnectivity()[0] ; myMesh3.setName(myMesh0.getName()) - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,myMesh0) - mm.setMeshAtLevel(-1,myMesh1) - mm.setMeshAtLevel(-2,myMesh2) - mm.setMeshAtLevel(-3,myMesh3) - mm.write("file2.med",2) - F1Cell=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - F1Cell.setMesh(myMesh0) - F1Cell.setArray(myMesh0.getCoords()[:myMesh0.getNumberOfCells()]) - F1Cell.setTime(1000.,2,3) - F1Cell.setName("F1Cell") - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file2.med",F1Cell) - F1Cell1=F1Cell.deepCpy() - F1Cell1.setMesh(myMesh1) - F1Cell1.setArray(myMesh1.getBarycenterAndOwner()) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file2.med",F1Cell1) -#! [PySnippetMeshAdvAPI1_12] - f1Cell_3D=MEDLoader.ReadFieldCell("file2.med","Example2",0,"F1Cell",2,3) -#! [PySnippetMeshAdvAPI1_12] -#! [PySnippetMeshAdvAPI1_13] - f1Cell_2D=MEDLoader.ReadFieldCell("file2.med","Example2",-1,"F1Cell",2,3) -#! [PySnippetMeshAdvAPI1_13] - self.assertTrue(F1Cell.isEqual(f1Cell_3D,1e-12,1e-12)) -#! [PySnippetMeshAdvAPI1_8] - self.assertEqual(3,MEDLoader.ReadUMeshDimFromFile("file2.med","Example2")) -#! [PySnippetMeshAdvAPI1_8] -#! [PySnippetMeshAdvAPI1_7] - m2D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",0) -#! [PySnippetMeshAdvAPI1_7] -#! [PySnippetMeshAdvAPI1_4] - m2D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-1) -#! [PySnippetMeshAdvAPI1_4] -#! [PySnippetMeshAdvAPI1_5] - m1D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-2) -#! [PySnippetMeshAdvAPI1_5] -#! [PySnippetMeshAdvAPI1_6] - m0D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-3) -#! [PySnippetMeshAdvAPI1_6] - for i in xrange(4): - mm.removeMeshAtLevel(-i) - pass - mm.setMeshAtLevel(0,myMesh1) - mm.setMeshAtLevel(-1,myMesh2) - mm.setName("MyMesh") - mm.write("file1.med",2) -#! [PySnippetMeshAdvAPI1_9] - m2D=MEDLoader.ReadUMeshFromFile("file1.med","MyMesh",0) -#! [PySnippetMeshAdvAPI1_9] -#! [PySnippetMeshAdvAPI1_10] - m1D=MEDLoader.ReadUMeshFromFile("file1.med","MyMesh",-1) -#! [PySnippetMeshAdvAPI1_10] - pass - - pass - -unittest.main() diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderSplitter.py b/medtool/src/MEDLoader/Swig/MEDLoaderSplitter.py deleted file mode 100644 index 41e766794..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderSplitter.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS) - -from MEDLoader import * -import os - -class MEDLoaderSplitter: - @classmethod - def New(cls,mfd,idsLst): - """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """ - return MEDLoaderSplitter(fileName) - pass - - def __init__(self,mfd,idsLst): - """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """ - mfmsh=mfd.getMeshes() - mfflds=mfd.getFields() - if len(mfmsh)!=1: - raise InterpKernelException("Works only with one mesh !") - mfflds=mfflds.partOfThisLyingOnSpecifiedMeshName(mfmsh[0].getName()) - retf=self.__splitFields(mfmsh[0],mfflds,idsLst) - retm=self.__splitMesh(mfmsh[0],idsLst) - self._mfd_splitted=[MEDFileData() for i in xrange(len(idsLst))] - for a,b,c in zip(self._mfd_splitted,retf,retm): - a.setFields(b) ; a.setMeshes(c) - pass - pass - - def getSplittedInstances(self): - return self._mfd_splitted - - @classmethod - def __splitMEDFileField1TSNode(cls,f,f1ts,ids): - fRet=f[ids] - f1ts.setFieldNoProfileSBT(fRet) - pass - - @classmethod - def __splitMEDFileField1TSCell(cls,f,f1ts,ids): - fRet=f[ids] - m=fRet.getMesh() ; m.zipCoords() - o2n=m.getRenumArrForMEDFileFrmt() ; fRet.renumberCells(o2n,False) - f1ts.setFieldNoProfileSBT(fRet) - pass - - def __splitMEDFileField1TS(self,mm,f1ts,idsLst): - ret=[MEDFileField1TS() for i in xrange(len(idsLst))] - dico={ON_CELLS:self.__splitMEDFileField1TSCell, - ON_NODES:self.__splitMEDFileField1TSNode, - ON_GAUSS_PT:self.__splitMEDFileField1TSCell, - ON_GAUSS_NE:self.__splitMEDFileField1TSCell} - for t in f1ts.getTypesOfFieldAvailable(): - f=f1ts.getFieldOnMeshAtLevel(t,0,mm) - for i,f0 in enumerate(ret): - dico[t](f,f0,idsLst[i]) - pass - pass - return ret - - def __splitFields(self,mm,mfflds,idsLst): - ret0=[MEDFileFields() for i in xrange(len(idsLst))] - for fmts in mfflds: - if len(fmts.getPflsReallyUsed())!=0: - print "Field \"%s\" contains profiles ! Not supported yet ! This field will be ignored !"%(fmts.getName()) - continue - pass - ret1=[MEDFileFieldMultiTS() for i in xrange(len(idsLst))] - for f1ts in fmts: - for fmtsPart,f1tsPart in zip(ret1,self.__splitMEDFileField1TS(mm,f1ts,idsLst)): - fmtsPart.pushBackTimeStep(f1tsPart) - pass - pass - for fieldsPart,fmtsPart in zip(ret0,ret1): - fieldsPart.pushField(fmtsPart); - pass - pass - return ret0 - - def __splitMesh(self,mfm,idsLst): - ret0=[MEDFileMeshes() for i in xrange(len(idsLst))] - m=mfm.getMeshAtLevel(0) - for ret,ids in zip(ret0,idsLst): - mlPart=mfm.createNewEmpty() - mPart=m[ids] ; trad=mPart.zipCoordsTraducer() - trad=trad.invertArrayO2N2N2O(mPart.getNumberOfNodes()) - mlPart.setMeshAtLevel(0,mPart) - if 0 in mfm.getFamArrNonEmptyLevelsExt(): - mlPart.setFamilyFieldArr(0,mfm.getFamilyFieldAtLevel(0)[ids]) - pass - if 1 in mfm.getFamArrNonEmptyLevelsExt(): - mlPart.setFamilyFieldArr(1,mfm.getFamilyFieldAtLevel(1)[trad]) - pass - mlPart.copyFamGrpMapsFrom(mfm) - ret.pushMesh(mlPart) - pass - return ret0 - pass diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderTest.py b/medtool/src/MEDLoader/Swig/MEDLoaderTest.py deleted file mode 100644 index 38ee4afa9..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderTest.py +++ /dev/null @@ -1,756 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -import MEDLoader -import unittest -from math import pi,e,sqrt -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDLoaderTest(unittest.TestCase): - def testMesh1DRW(self): - mesh=MEDLoaderDataForTest.build1DMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile1.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DCurveRW(self): - mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile2.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DRW(self): - mesh=MEDLoaderDataForTest.build2DMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile3.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DSurfRW(self): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile4.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DRW(self): - mesh=MEDLoaderDataForTest.build3DMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile5.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testFieldRW1(self): - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.MEDLoader.WriteField("Pyfile6.med",f1,True); - f2=MEDLoader.MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - MEDLoader.MEDLoader.WriteField("Pyfile7.med",f1,True); - f2=MEDLoader.MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,"Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); - pass - - def testFieldRW2(self): - fileName="Pyfile8.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #retrieving time steps... - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); - f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - #test of throw on invalid (dt,it) - self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,fileName,f1.getMesh().getName(),0,f1.getName(),28,19); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - fileName2="Pyfile9.med"; - MEDLoader.MEDLoader.WriteField(fileName2,f1,True); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); - f1.setTime(110.,108,109); - f1.getArray().setIJ(0,3,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); - f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - # - # Multi field in a same file, but this field has several - # - def testFieldRW3(self): - fileName="Pyfile11.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - name1="AField"; - name3="AMesh1"; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - f1.getMesh().setName(name3); - f1.setName(name1); - f1.setTime(10.,8,9); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.getMesh().setName(name3); - f1.setTime(10.55,28,29); - f1.getArray().setIJ(0,0,3*VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - vec=MEDLoader.MEDLoader.GetMeshNamesOnField(fileName,name1); - f1.setTime(10.66,38,39); - f1.getArray().setIJ(0,0,3*VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.77,48,49); - f1.getArray().setIJ(0,0,4*VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - f1.setName(name1); - f1.getMesh().setName(name3); - f1.setTime(110.,8,9); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # - it1=MEDLoader.MEDLoader.GetCellFieldIterations(fileName,name3,name1); - self.assertEqual(5,len(it1)); - self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); - self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); - self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); - self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); - self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); - it3=MEDLoader.MEDLoader.GetNodeFieldIterations(fileName,name3,name1); - self.assertEqual(3,len(it3)); - self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); - self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); - self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); - # - # - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); - self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); - self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); - self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); - # - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); - pass - - def testMultiMeshRW1(self): - fileName="Pyfile10.med"; - mesh1=MEDLoaderDataForTest.build3DMesh_1(); - part1=[1,2,4,13,15] - mesh2=mesh1.buildPartOfMySelf(part1,True); - mesh2.setName("mesh2"); - part2=[3,4,13,14] - mesh3=mesh1.buildPartOfMySelf(part2,True); - mesh3.setName("mesh3"); - mesh4=MEDLoader.MEDCouplingUMesh.New(); - mesh4.setName("mesh4"); - mesh4.setMeshDimension(3); - mesh4.allocateCells(1); - conn=[0,11,1,3] - mesh4.insertNextCell(MEDLoader.NORM_TETRA4,4,conn[0:4]) - mesh4.finishInsertingCells(); - mesh4.setCoords(mesh1.getCoords()); - meshes=[mesh1,mesh2,mesh3,mesh4] - mnane="3DToto"; - MEDLoader.MEDLoader.WriteUMeshesPartition(fileName,mnane,meshes,True); - # - mesh5=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,mnane); - mesh1.setName(mnane); - part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] - mesh6=mesh5.buildPartOfMySelf(part3,True); - mesh6.setName(mnane); - self.assertTrue(mesh6.isEqual(mesh1,1e-12)); - grps=MEDLoader.MEDLoader.GetMeshGroupsNames(fileName,mnane); - self.assertEqual(4,len(grps)); - grps.index("mesh2"); - grps.index("mesh3"); - grps.index("mesh4"); - grps.index("3DMesh_1"); - # - vec=("mesh2",); - mesh2_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - vec=["mesh3"]; - mesh3_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); - vec=["mesh4"]; - mesh4_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); - vec="3DMesh_1"; - mesh1_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - mesh1.setName("3DMesh_1"); - self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); - # - vec=["Family_-3","Family_-5"]; - mesh2_2=MEDLoader.MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); - mesh2_2.setName("mesh2"); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - # - ret=MEDLoader.MEDLoader.GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1"); - self.assertEqual(4,len(ret)); - self.assertEqual(ret[0],"Family_-2"); - self.assertEqual(ret[1],"Family_-3"); - self.assertEqual(ret[2],"Family_-4"); - self.assertEqual(ret[3],"Family_-5"); - # - ret1=MEDLoader.MEDLoader.GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3"); - self.assertEqual(2,len(ret1)); - self.assertEqual(ret1[0],"3DMesh_1"); - self.assertEqual(ret1[1],"mesh2"); - pass - - def testFieldProfilRW1(self): - fileName="Pyfile12.med"; - mesh1=MEDLoaderDataForTest.build3DMesh_1(); - da,b,newNbOfNodes=mesh1.mergeNodes(1e-12); - MEDLoader.MEDLoader.WriteUMesh(fileName,mesh1,True); - part1=[1,2,4,13,15] - mesh2=mesh1.buildPartOfMySelf(part1,True); - mesh2.setName(mesh1.getName());#<- important for the test - # - nbOfCells=mesh2.getNumberOfCells(); - self.assertEqual(5,nbOfCells); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("VectorFieldOnCells"); - f1.setMesh(mesh2); - array=MEDLoader.DataArrayDouble.New(); - array.alloc(nbOfCells,2); - f1.setArray(array); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] - array.setValues(arr1,nbOfCells,2); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - # - MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test - # - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - tt=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); - self.assertEqual(tt,[MEDLoader.ON_CELLS]); - f2.checkCoherency(); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - pass - - def testFieldGaussRW1(self): - fileName="Pyfile13.med"; - f1=MEDLoaderDataForTest.buildVecFieldOnGauss_1(); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f2=MEDLoader.MEDLoader.ReadField(MEDLoader.ON_GAUSS_PT,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - def testFieldGaussNERW1(self): - fileName="Pyfile14.med"; - f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - self.assertEqual([MEDLoader.ON_GAUSS_NE],MEDLoader.MEDLoader.GetTypesOfField(fileName,'2DMesh_2','MyFieldOnGaussNE')) #Bug 22/5/2014 - f2=MEDLoader.MEDLoader.ReadField(MEDLoader.ON_GAUSS_NE,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - def testMesh3DSurfShuffleRW(self): - fileName="Pyfile15.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - renumber1=[2,5,1,0,3,4] - mesh.renumberCells(renumber1,False); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh(fileName,mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMultiFieldShuffleRW1(self): - fileName="Pyfile17.med"; - m=MEDLoaderDataForTest.build3DMesh_2(); - self.assertEqual(20,m.getNumberOfCells()); - self.assertEqual(45,m.getNumberOfNodes()); - polys=[1,4,6] - m.convertToPolyTypes(polys); - renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] - m.renumberCells(renum,False); - m.orientCorrectlyPolyhedrons(); - # Writing - MEDLoader.MEDLoader.WriteUMesh(fileName,m,True); - f1Tmp=m.getMeasureField(False); - f1=f1Tmp.buildNewTimeReprFromThis(MEDLoader.ONE_TIME,False); - f1.setTime(0.,1,2); - f_1=f1.cloneWithMesh(True); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x"); - f1.setTime(0.01,3,4); - f_2=f1.cloneWithMesh(True); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x/3"); - f1.setTime(0.02,5,6); - f_3=f1.cloneWithMesh(True); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # Reading - its=[(1,2),(3,4),(5,6)]; - fs=MEDLoader.MEDLoader.ReadFieldsOnSameMesh(MEDLoader.ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); - self.assertEqual(3,len(fs)); - self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); - self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); - self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); - pass - - def testWriteUMeshesRW1(self): - fileName="Pyfile18.med"; - m3d=MEDLoaderDataForTest.build3DMesh_2(); - pt=[0.,0.,-0.3] - vec=[0.,0.,1.] - nodes=m3d.findNodesOnPlane(pt,vec,1e-12); - m2d=m3d.buildFacePartOfMySelfNode(nodes,True); - renumber=[1,2,0,4,3] - m2d.renumberCells(renumber,False); - m2d.setName("ExampleOfMultiDimW"); - meshes=[m2d,m3d] - MEDLoader.MEDLoader.WriteUMeshes(fileName,meshes,True); - m3d_bis=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); - self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); - m3d_bis.setName(m3d.getName()); - self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); - m2d_bis=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces - self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); - # Creation of a field on faces. - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("FieldOnFacesShuffle"); - f1.setMesh(m2d); - array=MEDLoader.DataArrayDouble.New(); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] - array.setValues(arr1,m2d.getNumberOfCells(),2); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f1.setArray(array); - tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); - self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); - pass - - def testFieldNodeProfilRW1(self): - fileName="Pyfile19.med"; - fileName2="Pyfile20.med"; - m=MEDLoaderDataForTest.build2DMesh_1(); - nbOfNodes=m.getNumberOfNodes(); - MEDLoader.MEDLoader.WriteUMesh(fileName,m,True); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f1.setName("VFieldOnNodes"); - f1.setMesh(m); - array=MEDLoader.DataArrayDouble.New(); - arr1=[1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.] - array.setValues(arr1,nbOfNodes,2); - f1.setArray(array); - array.setInfoOnComponent(0,"tyty [mm]"); - array.setInfoOnComponent(1,"uiop [MW]"); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - arr2=[1,4] - f2=f1.buildSubPart(arr2); - f2.getMesh().setName(f1.getMesh().getName()); - MEDLoader.MEDLoader.WriteField(fileName,f2,False);#<- False important for the test - # - f3=MEDLoader.MEDLoader.ReadFieldNode(fileName,f2.getMesh().getName(),0,f2.getName(),2,7); - f3.checkCoherency(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - # - arr3=[1,3,0,5,2,4] - f2.renumberNodes(arr3); - MEDLoader.MEDLoader.WriteUMesh(fileName2,m,True); - MEDLoader.MEDLoader.WriteField(fileName2,f2,False);#<- False important for the test - f3=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f2.getMesh().getName(),0,f2.getName(),2,7); - f3.checkCoherency(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - # - pass - - def testFieldNodeProfilRW2(self): - fileName="Pyfile23.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - MEDLoader.MEDLoader.WriteUMesh(fileName,mesh,True); - # - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f1.setName("FieldMix"); - f1.setMesh(mesh); - arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.]; - array=MEDLoader.DataArrayDouble.New(); - array.setValues(arr2,12,2); - f1.setArray(array); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - tmp=array.getPointer(); - f1.setTime(3.17,2,7); - # - renumArr=[3,7,2,1,5,11,10,0,9,6,8,4] - f1.renumberNodes(renumArr); - f1.checkCoherency(); - MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); - # - pass - - def testMixCellAndNodesFieldRW1(self): - fileName="Pyfile21.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("FieldMix"); - f1.setMesh(mesh); - array=MEDLoader.DataArrayDouble.New(); - f1.setArray(array); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] - array.setValues(arr1,6,2); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - # - f2=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f2.setName("FieldMix"); - f2.setMesh(mesh); - array=MEDLoader.DataArrayDouble.New(); - f2.setArray(array); - arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.] - array.setValues(arr2,12,2) - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f2.setTime(3.14,2,7); - f2.checkCoherency(); - # - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); - self.assertEqual(1,len(ts)); - self.assertEqual(MEDLoader.ON_CELLS,ts[0]); - fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); - self.assertEqual(1,len(fs)); - self.assertTrue(fs[0]=="FieldMix"); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f2); - fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); - self.assertEqual(1,len(fs)); - self.assertTrue(fs[0]=="FieldMix"); - # - ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); - self.assertEqual(2,len(ts)); - self.assertEqual(MEDLoader.ON_NODES,ts[0]); - self.assertEqual(MEDLoader.ON_CELLS,ts[1]); - # - f3=MEDLoader.MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f3=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - self.assertTrue(f3.isEqual(f1,1e-12,1e-12)); - # - pass - - def testGetAllFieldNamesRW1(self): - fileName="Pyfile22.med"; - mesh=MEDLoaderDataForTest.build2DMesh_2(); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f1.setName("Field1"); - f1.setTime(3.44,5,6); - f1.setMesh(mesh); - f1.fillFromAnalytic(2,"x+y"); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f1.setTime(1002.3,7,8); - f1.fillFromAnalytic(2,"x+77.*y"); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setName("Field2"); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); - f1.setName("Field3"); - mesh.setName("2DMesh_2Bis"); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("Field8"); - f1.setTime(8.99,7,9); - f1.setMesh(mesh); - f1.fillFromAnalytic(3,"3*x+y"); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); - fs=MEDLoader.MEDLoader.GetAllFieldNames(fileName); - self.assertEqual(4,len(fs)); - self.assertTrue(fs[0]=="Field1"); - self.assertTrue(fs[1]=="Field2"); - self.assertTrue(fs[2]=="Field3"); - self.assertTrue(fs[3]=="Field8"); - pass - - def testBigNbOfCompoNonReg(self): - fileName="Pyfile57.med" - m=MEDLoader.MEDCouplingCMesh() ; m.setCoords(MEDLoader.DataArrayDouble([0,1,2,3]),MEDLoader.DataArrayDouble([0,1]),MEDLoader.DataArrayDouble([0,1])) - m=m.buildUnstructured() ; m.setName("TinyMesh") - f=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_CELLS) ; f.setMesh(m) - nbOfCompo=4100 - arr=MEDLoader.DataArrayDouble(nbOfCompo*3) ; arr.iota() - arr.rearrange(nbOfCompo) - arr.setInfoOnComponents(["c%i"%(i) for i in xrange(nbOfCompo)]) - f.setArray(arr) - f.setName("FieldBigCompo") - MEDLoader.MEDLoader.WriteField(fileName,f,True) - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,m.getName(),0,f.getName(),-1,-1) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - def testMultiMeshTypeWrite0(self): - fname="Pyfile73.med" - m=MEDLoader.MEDCoupling1SGTUMesh("mesh",MEDLoader.NORM_QUAD4) ; m.allocateCells() - m.insertNextCell([0,2,1,3]) - m.setCoords(MEDLoader.DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) - # - ms=[m.deepCpy() for i in xrange(4)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,0.]) - pass - # - m0=MEDLoader.MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms) - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"merge",0,f.getName(),-1,-1) - fRead.setMesh(MEDLoader.MEDCoupling1SGTUMesh(fRead.getMesh())) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - # - m0=m0.buildUnstructured() ; m0.convertAllToPoly() - m0=MEDLoader.MEDCoupling1DGTUMesh(m0) - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"merge",0,f.getName(),-1,-1) - fRead.setMesh(MEDLoader.MEDCoupling1DGTUMesh(fRead.getMesh())) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - # - m0=MEDLoader.MEDCouplingCMesh() - arr=MEDLoader.DataArrayDouble(4) ; arr.iota() - m0.setCoords(arr,arr) - m0.setName("mesh") - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"mesh",0,f.getName(),-1,-1) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - # - c=m0.buildUnstructured().getCoords() - m0=MEDLoader.MEDCouplingCurveLinearMesh("mesh") - m0.setNodeGridStructure([4,4]) - m0.setCoords(c) - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"mesh",0,f.getName(),-1,-1) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - pass - - def testMultiMeshTypeWrite1(self): - fname="Pyfile74.med" - m=MEDLoader.MEDCoupling1SGTUMesh("mesh",MEDLoader.NORM_QUAD4) ; m.allocateCells() - m.insertNextCell([0,2,1,3]) - m.setCoords(MEDLoader.DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) - # - ms=[m.deepCpy() for i in xrange(4)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,0.]) - pass - m0=MEDLoader.MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms) - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,"merge",0) - self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingUMesh)) - mRead=MEDLoader.MEDCoupling1SGTUMesh(mRead) - self.assertTrue(m0.isEqual(mRead,1e-12)) - # - m0=m0.buildUnstructured() ; m0.convertAllToPoly() - m0=MEDLoader.MEDCoupling1DGTUMesh(m0) - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,"merge",0) - mRead=MEDLoader.MEDCoupling1DGTUMesh(mRead) - self.assertTrue(m0.isEqual(mRead,1e-12)) - # - m0=MEDLoader.MEDCouplingCMesh() - arr=MEDLoader.DataArrayDouble(4) ; arr.iota() - m0.setCoords(arr,arr) - m0.setName("mesh") - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,0) - self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingCMesh)) - self.assertTrue(m0.isEqual(mRead,1e-12)) - # - c=m0.buildUnstructured().getCoords() - m0=MEDLoader.MEDCouplingCurveLinearMesh("mesh") - m0.setNodeGridStructure([4,4]) - m0.setCoords(c) - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,0) - self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingCurveLinearMesh)) - self.assertTrue(m0.isEqual(mRead,1e-12)) - pass - - def testChangeGroupName(self): - """ This test is a non regression test on MEDFileUMesh.changeGroupName thanks to Alliance. - """ - mfd=MEDLoaderDataForTest.buildAMEDFileDataWithGroupOnOneFamilyForSauv() - mesh = mfd.getMeshes().getMeshAtPos(0) - mesh.changeGroupName("grp0_LM1", "xonall1") - self.assertTrue("xonall1" in mesh.getGroupsNames()) - pass - - def testFieldWithTooLongName(self): - """ This test is a non regression test, to check that in basic API the policies are taken into account. - """ - fname="Pyfile75.med" - # Coordinates - coords = [0.,0., 0.,1., 1.,1., 1.,0.] - # lvl 0 connectivity - conn2D = [1,2,3,4] - # lvl 0 mesh - m=MEDLoader.MEDCouplingUMesh.New("mesh",2) - m.allocateCells(1) - m.insertNextCell(MEDLoader.NORM_QUAD4,4,conn2D) - m.finishInsertingCells() - # assigning coordinates - meshCoords=MEDLoader.DataArrayDouble.New() - meshCoords.setValues(coords, 4, 2) - m.setCoords(meshCoords) - # - f=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME) - f.setMesh(m) - d=MEDLoader.DataArrayDouble.New() - d.alloc(1,1) - d.iota(1.) - # seting a long name - d.setInfoOnComponent(0,"CONCENTRATION of I129") - f.setArray(d) - f.setName("field") - # - mm=MEDLoader.MEDFileUMesh() - MEDLoader.MEDLoader.SetTooLongStrPolicy(2) - MEDLoader.MEDLoader.AssignStaticWritePropertiesTo(mm) - self.assertEqual(2,mm.getTooLongStrPolicy()) - MEDLoader.MEDLoader.SetTooLongStrPolicy(0) - MEDLoader.MEDLoader.AssignStaticWritePropertiesTo(mm) - self.assertEqual(0,mm.getTooLongStrPolicy()) - del mm - # - MEDLoader.MEDLoader.SetTooLongStrPolicy(2) - self.assertRaises(MEDLoader.InterpKernelException,MEDLoader.MEDLoader.WriteField,fname,f,True)# the component name is too long + policy 2 -> throw - f.getArray().setInfoOnComponent(0,'I129') - MEDLoader.MEDLoader.WriteField(fname,f,True) - pass - - def testUsingAlreadyWrittenMesh2(self): - """ This test focuses on MEDLoader.WriteFieldUsingAlreadyWrittenMesh with mesh different from UMesh. - """ - fname="Pyfile76.med" - mesh=MEDLoader.MEDCouplingCMesh("mesh") - arrX=MEDLoader.DataArrayDouble([0,1,2,3]) - arrY=MEDLoader.DataArrayDouble([0,2,3,5,7]) - arrZ=MEDLoader.DataArrayDouble([7]) - mesh.setCoords(arrX,arrY,arrZ) - # - f1=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_NODES) ; f1.setName("f1") - f1.setMesh(mesh) - arr=MEDLoader.DataArrayDouble(20) ; arr.iota() - f1.setArray(arr) - f1.checkCoherency() - # - f2=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_NODES) ; f2.setName("f2") - f2.setMesh(mesh) - arr=MEDLoader.DataArrayDouble(20) ; arr.iota() ; arr*=3 - f2.setArray(arr) - f2.checkCoherency() - # - f11=f1.deepCpy() ; (f11.getArray())[:]*=4 ; f11.setTime(1.1,5,6) - # - MEDLoader.MEDLoader.WriteMesh(fname,f1.getMesh(),True) - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f1) - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f11) - ## - f1r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f1",-1,-1); - self.assertTrue(f1.isEqual(f1r,1e-12,1e-12)) - self.assertTrue(f1r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.]),1e-12)) - f2r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f2",-1,-1); - self.assertTrue(f2.isEqual(f2r,1e-12,1e-12)) - self.assertTrue(f2r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,3.,6.,9.,12.,15.,18.,21.,24.,27.,30.,33.,36.,39.,42.,45.,48.,51.,54.,57.]),1e-12)) - f3r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f1",5,6); - self.assertTrue(f11.isEqual(f3r,1e-12,1e-12)) - self.assertTrue(f3r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,4.,8.,12.,16.,20.,24.,28.,32.,36.,40.,44.,48.,52.,56.,60.,64.,68.,72.,76.]),1e-12)) - pass - pass - -if __name__ == "__main__": - unittest.main() diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderTest2.py b/medtool/src/MEDLoader/Swig/MEDLoaderTest2.py deleted file mode 100644 index 06cc645d0..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderTest2.py +++ /dev/null @@ -1,341 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -from MEDLoader import * -import unittest -from math import pi,e,sqrt -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDLoaderTest(unittest.TestCase): - def testMesh1DRW(self): - mesh=MEDLoaderDataForTest.build1DMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile1.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DCurveRW(self): - mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile2.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DRW(self): - mesh=MEDLoaderDataForTest.build2DMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile3.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DSurfRW(self): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile4.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DRW(self): - mesh=MEDLoaderDataForTest.build3DMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile5.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testFieldRW1(self): - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.WriteFieldDep("Pyfile6.med",f1,False); - f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - MEDLoader.WriteFieldDep("Pyfile7.med",f1,False); - f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - def testFieldRW2(self): - fileName="Pyfile8.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.WriteFieldDep(fileName,f1,False); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #retrieving time steps... - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); - f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - fileName2="Pyfile9.med"; - MEDLoader.WriteFieldDep(fileName2,f1,False); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); - f1.setTime(110.,108,109); - f1.getArray().setIJ(0,3,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); - f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - # - # Multi field in a same file, but this field has several - # - def testFieldRW3(self): - fileName="Pyfile11.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - name1="AField"; - name3="AMesh1"; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - f1.getMesh().setName(name3); - f1.setName(name1); - f1.setTime(10.,8,9); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.WriteFieldDep(fileName,f1,False); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.getMesh().setName(name3); - f1.setTime(10.55,28,29); - f1.getArray().setIJ(0,0,3*VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.66,38,39); - f1.getArray().setIJ(0,0,3*VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.77,48,49); - f1.getArray().setIJ(0,0,4*VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - f1.setName(name1); - f1.getMesh().setName(name3); - f1.setTime(110.,8,9); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # - it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1); - self.assertEqual(5,len(it1)); - self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); - self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); - self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); - self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); - self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); - it3=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); - self.assertEqual(3,len(it3)); - self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); - self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); - self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); - # - # - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); - self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); - self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); - self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); - # - f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); - pass - - def testMultiMeshRW1(self): - fileName="Pyfile10.med"; - mesh1=MEDLoaderDataForTest.build3DMesh_1(); - part1=[1,2,4,13,15] - mesh2=mesh1.buildPartOfMySelf(part1,True); - mesh2.setName("mesh2"); - part2=[3,4,13,14] - mesh3=mesh1.buildPartOfMySelf(part2,True); - mesh3.setName("mesh3"); - mesh4=MEDCouplingUMesh.New(); - mesh4.setName("mesh4"); - mesh4.setMeshDimension(3); - mesh4.allocateCells(1); - conn=[0,11,1,3] - mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4]) - mesh4.finishInsertingCells(); - mesh4.setCoords(mesh1.getCoords()); - meshes=[mesh1,mesh2,mesh3,mesh4] - mnane="3DToto"; - MEDLoader.WriteUMeshesPartitionDep(fileName,mnane,meshes,False); - # - mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane); - mesh1.setName(mnane); - part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] - mesh6=mesh5.buildPartOfMySelf(part3,True); - mesh6.setName(mnane); - self.assertTrue(mesh6.isEqual(mesh1,1e-12)); - grps=MEDLoader.GetMeshGroupsNames(fileName,mnane); - self.assertEqual(4,len(grps)); - grps.index("mesh2"); - grps.index("mesh3"); - grps.index("mesh4"); - grps.index("3DMesh_1"); - # - vec=["mesh2"]; - mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - vec=["mesh3"]; - mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); - vec=["mesh4"]; - mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); - vec=["3DMesh_1"]; - mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - mesh1.setName("3DMesh_1"); - self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); - # - vec=["Family_-5","Family_-3"]; - mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); - mesh2_2.setName("mesh2"); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - pass - - def testMesh3DSurfShuffleRW(self): - fileName="Pyfile15.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - renumber1=[2,5,1,0,3,4] - mesh.renumberCells(renumber1,False); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep(fileName,mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMultiFieldShuffleRW1(self): - fileName="Pyfile17.med"; - m=MEDLoaderDataForTest.build3DMesh_2(); - self.assertEqual(20,m.getNumberOfCells()); - self.assertEqual(45,m.getNumberOfNodes()); - polys=[1,4,6] - m.convertToPolyTypes(polys); - renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] - m.renumberCells(renum,False); - m.orientCorrectlyPolyhedrons(); - # Writing - MEDLoader.WriteUMeshDep(fileName,m,False); - f1Tmp=m.getMeasureField(False); - f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False); - f1.setTime(0.,1,2); - f_1=f1.cloneWithMesh(True); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x"); - f1.setTime(0.01,3,4); - f_2=f1.cloneWithMesh(True); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x/3"); - f1.setTime(0.02,5,6); - f_3=f1.cloneWithMesh(True); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # Reading - its=[(1,2),(3,4),(5,6)]; - fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); - self.assertEqual(3,len(fs)); - self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); - self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); - self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); - pass - - def testWriteUMeshesRW1(self): - fileName="Pyfile18.med"; - m3d=MEDLoaderDataForTest.build3DMesh_2(); - pt=[0.,0.,-0.3] - vec=[0.,0.,1.] - nodes=m3d.findNodesOnPlane(pt,vec,1e-12); - m2d=m3d.buildFacePartOfMySelfNode(nodes,True); - renumber=[1,2,0,4,3] - m2d.renumberCells(renumber,False); - m2d.setName("ExampleOfMultiDimW"); - meshes=[m2d,m3d] - MEDLoader.WriteUMeshes(fileName,meshes,False); - m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); - self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); - m3d_bis.setName(m3d.getName()); - self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); - m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces - self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); - # Creation of a field on faces. - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("FieldOnFacesShuffle"); - f1.setMesh(m2d); - array=DataArrayDouble.New(); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] - array.setValues(arr1,m2d.getNumberOfCells(),2); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f1.setArray(array); - tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); - self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); - pass - pass - -if __name__ == "__main__": - unittest.main() diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderTest3.py b/medtool/src/MEDLoader/Swig/MEDLoaderTest3.py deleted file mode 100644 index ec4cf3132..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderTest3.py +++ /dev/null @@ -1,4715 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -from MEDLoader import * -import unittest -import platform -from math import pi,e,sqrt -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDLoaderTest(unittest.TestCase): - def testMEDMesh1(self): - fileName="Pyfile18.med" - mname="ExampleOfMultiDimW" - medmesh=MEDFileMesh.New(fileName,mname) - self.assertRaises(InterpKernelException,MEDFileMesh.New,fileName,"") - self.assertEqual((0,-1),medmesh.getNonEmptyLevels()) - m1_0=medmesh.getLevel0Mesh(True) - m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) - self.assertTrue(m1_0.isEqual(m1_1,1e-12)); - m2_0=medmesh.getLevelM1Mesh(True) - m2_1=MEDLoader.ReadUMeshFromFile(fileName,mname,-1) - self.assertTrue(m2_0.isEqual(m2_1,1e-12)); - pass - - def testMEDMesh2(self): - fileName="Pyfile10.med" - mname="3DToto" - outFileName="MEDFileMesh1.med" - medmesh=MEDFileUMesh.New(fileName,mname) - self.assertEqual((0,),medmesh.getNonEmptyLevels()) - m1_0=medmesh.getLevel0Mesh(True) - m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) - self.assertTrue(m1_0.isEqual(m1_1,1e-12)); - g1_0=medmesh.getGroup(0,"mesh2",True) - g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh2"]); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getGroup(0,"mesh3",True) - g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh3"]); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getGroups(0,["mesh3","mesh2"]) - g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh3","mesh2"]); - g1_1.setName(g1_0.getName()) - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getFamily(0,"Family_-3",True) - g1_1=MEDLoader.ReadUMeshFromFamilies(fileName,mname,0,["Family_-3"]); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getFamilies(0,["Family_-3","Family_-5"],True) - g1_1=MEDLoader.ReadUMeshFromFamilies(fileName,mname,0,["Family_-3","Family_-5"]); - g1_1.setName(g1_0.getName()) - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - medmesh.write(outFileName,2); - self.assertEqual([1,2,4,13,15],medmesh.getGroupArr(0,"mesh2",True).getValues()); - self.assertEqual([1,2,15],medmesh.getFamilyArr(0,"Family_-3",True).getValues()); - self.assertEqual([1,2,4,13,15],medmesh.getFamiliesArr(0,["Family_-5","Family_-3"],True).getValues()); - self.assertEqual([18,1,2,3,4,13,14,15],medmesh.getGroupsArr(0,["mesh2","mesh4","mesh3"],True).getValues()); - famn=medmesh.getFamilyNameGivenId(0) - self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,True); - #without renum - self.assertEqual([2,3,5,14,16],medmesh.getGroupArr(0,"mesh2").getValues()); - self.assertEqual([2,3,16],medmesh.getFamilyArr(0,"Family_-3").getValues()); - self.assertEqual([2,3,5,14,16],medmesh.getFamiliesArr(0,["Family_-5","Family_-3"]).getValues()); - self.assertEqual([0,2,3,4,5,14,15,16],medmesh.getGroupsArr(0,["mesh2","mesh3","mesh4"],False).getValues()); - self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,False); - pass - - # this tests emulates MEDMEM ( Except that it works ! ) The permutation are NOT taken into account - def testMEDMesh3(self): - outFileName="MEDFileMesh3.med" - c=DataArrayDouble.New() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - c.setValues(coords,9,2) - m=MEDCouplingUMesh.New(); - m.setMeshDimension(2); - m.allocateCells(5); - m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - m.insertNextCell(NORM_POLYGON,4,targetConn[10:14]) - m.insertNextCell(NORM_POLYGON,4,targetConn[14:18]) - m.finishInsertingCells(); - m.setCoords(c) - m.checkCoherency() - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(1); - m1.allocateCells(3); - m1.insertNextCell(NORM_SEG2,2,[1,4]) - m1.insertNextCell(NORM_SEG2,2,[3,6]) - m1.insertNextCell(NORM_SEG3,3,[2,8,5]) - m1.finishInsertingCells(); - m1.setCoords(c) - m1.checkCoherency() - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(0); - m2.allocateCells(4); - m2.insertNextCell(NORM_POINT1,1,[1]) - m2.insertNextCell(NORM_POINT1,1,[3]) - m2.insertNextCell(NORM_POINT1,1,[2]) - m2.insertNextCell(NORM_POINT1,1,[6]) - m2.finishInsertingCells(); - m2.setCoords(c) - m2.checkCoherency() - # - mm=MEDFileUMesh.New() - self.assertTrue(mm.getUnivNameWrStatus()) - mm.setName("MyFirstMEDCouplingMEDmesh") - mm.setDescription("IHopeToConvinceLastMEDMEMUsers") - mm.setCoords(c) - mm.setMeshAtLevel(-1,m1); - mm.setMeshAtLevel(0,m); - mm.setMeshAtLevel(-2,m2); - # playing with groups - g1_2=DataArrayInt.New() - g1_2.setValues([1,3],2,1) - g1_2.setName("G1") - g2_2=DataArrayInt.New() - g2_2.setValues([1,2,3],3,1) - g2_2.setName("G2") - mm.setGroupsAtLevel(0,[g1_2,g2_2],False) - g1_1=DataArrayInt.New() - g1_1.setValues([0,1,2],3,1) - g1_1.setName("G1") - g2_1=DataArrayInt.New() - g2_1.setValues([0,2],2,1) - g2_1.setName("G2") - mm.setGroupsAtLevel(-1,[g1_1,g2_1],False) - g1_N=DataArrayInt.New() - g1_N.setValues(range(8),8,1) - g1_N.setName("G1") - g2_N=DataArrayInt.New() - g2_N.setValues(range(9),9,1) - g2_N.setName("G2") - mm.setGroupsAtLevel(1,[g1_N,g2_N],False) - mm.createGroupOnAll(0,"GrpOnAllCell") - # check content of mm - t=mm.getGroupArr(0,"G1",False) - self.assertTrue(g1_2.isEqual(t)); - t=mm.getGroupArr(0,"G2",False) - self.assertTrue(g2_2.isEqual(t)); - t=mm.getGroupArr(-1,"G1",False) - self.assertTrue(g1_1.isEqual(t)); - t=mm.getGroupArr(-1,"G2",False) - self.assertTrue(g2_1.isEqual(t)); - t=mm.getGroupArr(1,"G1",False) - self.assertTrue(g1_N.isEqual(t)); - t=mm.getGroupArr(1,"G2",False) - self.assertTrue(g2_N.isEqual(t)); - self.assertTrue(mm.existsGroup("GrpOnAllCell")); - t=mm.getGroupArr(0,"GrpOnAllCell") - self.assertTrue(t.getValues()==range(5)) - # - mmCpy=mm.deepCpy() - self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) ; del mm - mmCpy.write(outFileName,2); - # - mm=MEDFileMesh.New(outFileName) - # - self.assertEqual([NORM_TRI3,NORM_QUAD4,NORM_POLYGON],mm.getGeoTypesAtLevel(0)) - self.assertEqual([NORM_SEG2,NORM_SEG3],mm.getGeoTypesAtLevel(-1)) - self.assertEqual([NORM_POINT1],mm.getGeoTypesAtLevel(-2)) - mm0=mm.getDirectUndergroundSingleGeoTypeMesh(NORM_POLYGON) - self.assertTrue(isinstance(mm0,MEDCoupling1DGTUMesh)) - self.assertTrue(mm0.getNodalConnectivity().isEqual(DataArrayInt([6,7,4,3,7,8,5,4]))) - self.assertTrue(mm0.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8]))) - lmm=mm.getDirectUndergroundSingleGeoTypeMeshes(0) - self.assertEqual(3,len(lmm)) - self.assertTrue(isinstance(lmm[0],MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(lmm[1],MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(lmm[2],MEDCoupling1DGTUMesh)) - # - self.assertTrue(mm.getUnivNameWrStatus()) - self.assertTrue(isinstance(mm.getUnivName(),str)) - self.assertTrue(len(mm.getUnivName())!=0) - mbis=mm.getMeshAtLevel(0) - m.setName(mm.getName()) ; m.setDescription(mm.getDescription()) - self.assertTrue(m.isEqual(mbis,1e-12)); - # - self.assertEqual(([[(3, 2), (4, 1), (5, 8)], [(1, 2), (2, 1)], [(0, 4)]], 2, 2, 9),MEDLoader.GetUMeshGlobalInfo(outFileName,"MyFirstMEDCouplingMEDmesh")) - pass - - # this test is the testMEDMesh3 except that permutation is dealed here - def testMEDMesh4(self): - outFileName="MEDFileMesh4.med" - c=DataArrayDouble.New() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - c.setValues(coords,9,2) - c.setInfoOnComponent(0,"abcdef [km]") - c.setInfoOnComponent(1,"ghij [MW]") - m=MEDCouplingUMesh.New(); - m.setMeshDimension(2); - m.allocateCells(5); - m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - m.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - m.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - m.finishInsertingCells(); - m.setCoords(c) - m.checkCoherency() - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(1); - m1.allocateCells(3); - m1.insertNextCell(NORM_SEG2,2,[1,4]) - m1.insertNextCell(NORM_SEG3,3,[2,8,5]) - m1.insertNextCell(NORM_SEG2,2,[3,6]) - m1.finishInsertingCells(); - m1.setCoords(c) - m1.checkCoherency() - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(0); - m2.allocateCells(4); - m2.insertNextCell(NORM_POINT1,1,[1]) - m2.insertNextCell(NORM_POINT1,1,[3]) - m2.insertNextCell(NORM_POINT1,1,[2]) - m2.insertNextCell(NORM_POINT1,1,[6]) - m2.finishInsertingCells(); - m2.setCoords(c) - m2.checkCoherency() - # - mm=MEDFileUMesh.New() - mm.setName("My2ndMEDCouplingMEDmesh") - mm.setDescription("ThisIsImpossibleToDoWithMEDMEM") - mm.setCoords(c) - renumNode=DataArrayInt.New() - renumNode.setValues([10,11,12,13,14,15,16,17,18],9,1) - mm.setRenumFieldArr(1,renumNode) - mm.setMeshAtLevel(-1,m1,True); - mm.setMeshAtLevel(0,m,True); - mm.setMeshAtLevel(-2,m2,True); - mm.removeMeshAtLevel(-2) - mm.setMeshAtLevel(-2,m2,True); - # playing with groups - g1_2=DataArrayInt.New() - g1_2.setValues([2,3],2,1) - g1_2.setName("G1") - g2_2=DataArrayInt.New() - g2_2.setValues([2,0,3],3,1) - g2_2.setName("G2") - mm.setGroupsAtLevel(0,[g1_2,g2_2],True) - g1_1=DataArrayInt.New() - g1_1.setValues([0,2,1],3,1) - g1_1.setName("G1") - g2_1=DataArrayInt.New() - g2_1.setValues([0,2],2,1) - g2_1.setName("G2") - mm.setGroupsAtLevel(-1,[g1_1,g2_1],True) - g1_N=DataArrayInt.New() - g1_N.setValues([10,11,12,13,14,15,16,17],8,1) - g1_N.setName("G1") - g2_N=DataArrayInt.New() - g2_N.setValues([10,11,12,13,14,15,16,17,18],9,1) - g2_N.setName("G2") - mm.setGroupsAtLevel(1,[g1_N,g2_N],True) - # check content of mm - t=mm.getGroupArr(0,"G1",True) - self.assertTrue(g1_2.isEqual(t)); - t=mm.getGroupArr(0,"G2",True) - self.assertTrue(g2_2.isEqual(t)); - t=mm.getGroupArr(-1,"G1",True) - self.assertTrue(g1_1.isEqual(t)); - t=mm.getGroupArr(-1,"G2",True) - self.assertTrue(g2_1.isEqual(t)); - self.assertTrue(not mm.existsGroup("GrpOnAllCell")); - # - mm.write(outFileName,2); - mm2=MEDFileMesh.New(outFileName) - res=mm.isEqual(mm2,1e-12) - self.assertTrue(res[0]) - l=list(mm2.getFamiliesOnGroup("G2")) ; l.sort() - self.assertEqual(['Family_-3','Family_-4','Family_-7','Family_10','Family_11'],l) - mm2.keepFamIdsOnlyOnLevs([3],[-1]) - for lev in mm.getGrpNonEmptyLevelsExt("G2"): - self.assertEqual(mm.getGroupArr(lev,"G2").getValues(),mm2.getGroupArr(lev,"G2").getValues()) - pass - l=list(mm2.getFamiliesOnGroup("G2")) ; l.sort() - self.assertEqual(['Family_-3','Family_-4','Family_-7','Family_10','Family_11'],l) - # - self.assertEqual([-7,-7,-6],mm2.getFamilyFieldAtLevel(-1).getValues()) - mm2.getFamilyFieldAtLevel(-1).setIJ(1,0,-8) - self.assertEqual([-7,-8,-6],mm2.getFamilyFieldAtLevel(-1).getValues()) - self.assertTrue(not mm2.existsFamily("Family_-8")) - mm2.createGroupOnAll(-1,"GrpOnAllFace") - self.assertTrue(mm2.existsFamily("Family_-8")) - self.assertEqual(range(3),mm2.getGroupArr(-1,"GrpOnAllFace").getValues()) - pass - - #testing persistence of retrieved arrays - def testMEDMesh5(self): - fileName="Pyfile18.med" - mname="ExampleOfMultiDimW" - medmesh=MEDFileUMesh.New(fileName,mname) - m1_0=medmesh.getLevel0Mesh(True) - da1=medmesh.getFamilyFieldAtLevel(0) - del medmesh - self.assertEqual(20,m1_0.getNumberOfCells()) - self.assertEqual(20,da1.getNumberOfTuples()) - pass - - def testMEDMesh6(self): - outFileName="MEDFileMesh5.med" - m=MEDFileCMesh.New() - m.setTime(-1,-1,2.3) - m1=MEDCouplingCMesh.New(); - da=DataArrayDouble.New() - da.setValues([0.,1.,2.],3,1) - da.setInfoOnComponent(0,"XX [mm]") - m1.setCoordsAt(0,da) - da=DataArrayDouble.New() - da.setValues([0.,1.2],2,1) - da.setInfoOnComponent(0,"YY [km]") - m1.setCoordsAt(1,da) - da=DataArrayDouble.New() - da.setValues([0.,1.3],2,1) - da.setInfoOnComponent(0,"ZZ [um]") - m1.setCoordsAt(2,da) - m.setMesh(m1) - self.assertTrue(m[0].isEqual(m1,1e-12)) - self.assertTrue(isinstance(m[0],MEDCouplingCMesh)) - m.setName("myFirstCartMesh") - m.setDescription("mmmmpppppppp") - m.setTimeValue(2.3) - m.setTimeUnit("ms") - da=DataArrayInt.New() - da.setValues([0,0,1,0,1,2,4,3,0,1,2,2],12,1) - m.setFamilyFieldArr(1,da) - m.setFamilyId("family1",1) - da=m.getFamilyArr(1,"family1") - expected1=[2,4,9] - self.assertEqual(expected1,da.getValues()) - self.assertTrue(m.getUnivNameWrStatus()) - m.write(outFileName,2); - mm=MEDFileMesh.New(outFileName) - self.assertEqual([NORM_HEXA8],mm.getGeoTypesAtLevel(0)) - self.assertTrue(isinstance(mm,MEDFileCMesh)) - self.assertTrue(isinstance(mm.getUnivName(),str)) - self.assertTrue(len(mm.getUnivName())!=0) - self.assertTrue(m.isEqual(mm,1e-12)[0]) - self.assertEqual(expected1,mm.getFamilyArr(1,"family1").getValues()) - m2=mm.getMesh() - tt=m.getTime() - m1.setTime(tt[2],tt[0],tt[1]) - m1.setName(m.getName()) - m1.setTimeUnit(m.getTimeUnit()) - m1.setDescription(m.getDescription()) - self.assertTrue(m2.isEqual(m1,1e-12)); - pass - - def testMEDMesh7(self): - fileName="Pyfile24.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setCoords(m2.getCoords()) - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - m.setFamilyFieldArr(0,f2) - m.setFamilyFieldArr(-1,f1) - m.setFamilyFieldArr(-2,f0) - m.setFamilyFieldArr(1,p) - m.setRenumFieldArr(0,n2) - m.setRenumFieldArr(-1,n1) - m.setRenumFieldArr(-2,n0) - nbOfFams=len(fns) - for i in xrange(nbOfFams): - m.addFamily(fns[i],fids[i]) - pass - nbOfGrps=len(grpns) - for i in xrange(nbOfGrps): - m.setFamiliesIdsOnGroup(grpns[i],famIdsPerGrp[i]) - pass - m.setName(m2.getName()) - m.setDescription(m2.getDescription()) - # - self.assertEqual((-1,),m.getGrpNonEmptyLevels("A2A4")) - self.assertEqual((),m.getGrpNonEmptyLevels("A1")) - self.assertEqual((-2,),m.getGrpNonEmptyLevels("AP2")) - self.assertEqual((-1,-2),m.getGrpsNonEmptyLevels(["A2A4","AP2"])) - self.assertEqual((-1,),m.getFamNonEmptyLevels('A4A3____________________________')) - self.assertEqual((0,),m.getFamNonEmptyLevels('MESH____DALT3___DALLE___________')) - self.assertEqual((0,-1,),m.getFamsNonEmptyLevels(['MESH____DALT3___DALLE___________','A4A3____________________________'])) - self.assertEqual(('A1A2','A2A4','A3A1','A3C5','A4A3','B1C1','B2B4','B3B1','B4C3','C1C4','C2B2','C3C2','C4B3','C5A4'),m.getGroupsOnSpecifiedLev(-1)) - self.assertEqual(('DALLE','DALQ1','DALQ2','DALT3','MESH'),m.getGroupsOnSpecifiedLev(0)) - # - m.write(fileName,2) - self.assertRaises(InterpKernelException,MEDFileField1TS,fileName)#throw because no field in file fileName - pass - - def funcToTestDelItem(self,ff): - del ff[[0.02,(3,4)]] - pass - - #emulation of pointe.med file. - def testMEDField1(self): - mm=MEDFileMesh.New("Pyfile17.med") - mm.write("Pyfile17_bis.med",2) - ff=MEDFileFieldMultiTS("Pyfile17.med") - tsExpected=[[1,2],[3,4],[5,6]] - self.assertEqual(3,len(ff)) - for pos,f1ts in enumerate(ff): - self.assertEqual(tsExpected[pos],f1ts.getTime()[:2]) - self.assertEqual(type(f1ts),MEDFileField1TS) - pass - self.assertEqual("MeasureOfMesh_Extruded",ff.getName()) - self.assertEqual([3,4],ff[1].getTime()[:-1]) - self.assertEqual([3,4],ff[3,4].getTime()[:-1]) - self.assertEqual([3,4],ff[0.01].getTime()[:-1]) - ff.write("Pyfile17_bis.med",0) - # - ts=ff.getTimeSteps() ; ts=[elt[:-1] for elt in ts] - self.assertEqual([(1,2),(3,4),(5,6)],ts) - self.funcToTestDelItem(ff) - ts=ff.getTimeSteps() ; ts=[elt[:-1] for elt in ts] - self.assertEqual([(1,2)],ts) - pass - - #profiles - def testMEDField2(self): - mm=MEDFileMesh.New("Pyfile19.med") - mm.write("Pyfile19_bis.med",2) - ff=MEDFileFieldMultiTS.New("Pyfile19.med") - ff.write("Pyfile19_bis.med",0) - self.assertEqual([('tyty','mm'),('uiop','MW')],MEDLoader.GetComponentsNamesOfField("Pyfile19_bis.med","VFieldOnNodes")) - pass - - #gauss points - def testMEDField3(self): - mm=MEDFileMesh.New("Pyfile13.med") - mm.write("Pyfile13_bis.med",2) - ff=MEDFileFieldMultiTS.New("Pyfile13.med","MyFirstFieldOnGaussPoint") - ff.write("Pyfile13_bis.med",0) - ff=MEDFileField1TS.New("Pyfile13.med","MyFirstFieldOnGaussPoint",1,5) - f=ff.getFieldAtLevel(ON_GAUSS_PT,0) - f2=MEDLoader.ReadFieldGauss("Pyfile13.med",'2DMesh_2',0,'MyFirstFieldOnGaussPoint',1,5) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - ff3=MEDFileField1TS.New("Pyfile13.med","MyFirstFieldOnGaussPoint") - f3=ff3.getFieldAtLevel(ON_GAUSS_PT,0) - self.assertTrue(f.isEqual(f3,1e-12,1e-12)) - ff4=MEDFileField1TS.New("Pyfile13.med") - f4=ff4.getFieldAtLevel(ON_GAUSS_PT,0) - self.assertTrue(f.isEqual(f4,1e-12,1e-12)) - pass - - #gauss NE - def testMEDField4(self): - mm=MEDFileMesh.New("Pyfile14.med") - mm.write("Pyfile14_bis.med",2) - ff=MEDFileFieldMultiTS.New("Pyfile14.med","MyFieldOnGaussNE") - ff.write("Pyfile14_bis.med",0) - ff=MEDFileField1TS.New("Pyfile14.med","MyFieldOnGaussNE",1,5) - f=ff.getFieldAtLevel(ON_GAUSS_NE,0) - f2=MEDLoader.ReadFieldGaussNE("Pyfile14.med",'2DMesh_2',0,"MyFieldOnGaussNE",1,5) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - # MEDField get/set on pointe.med - def testMEDField5(self): - ff=MEDFileField1TS.New("Pyfile17.med","MeasureOfMesh_Extruded",1,2) - f=ff.getFieldAtLevel(ON_CELLS,0) - f2=MEDLoader.ReadFieldCell("Pyfile17.med","Extruded",0,"MeasureOfMesh_Extruded",1,2) - self.assertTrue(f.getMesh().getCoords().isEqual(f2.getMesh().getCoords(),1e-12)) - f.getMesh().tryToShareSameCoords(f2.getMesh(),1e-12) - f.changeUnderlyingMesh(f2.getMesh(),22,1e-12) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - # no with renumbering - f=ff.getFieldAtLevel(ON_CELLS,0,1) - f2=MEDLoader.ReadFieldCell("Pyfile17.med","Extruded",0,"MeasureOfMesh_Extruded",1,2) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - f=ff.getFieldAtLevel(ON_CELLS,0,3) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - f=ff.getFieldAtLevel(ON_CELLS,0,2) - self.assertTrue(not f.isEqual(f2,1e-12,1e-12)) - f.changeUnderlyingMesh(f2.getMesh(),12,1e-12) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - # MEDField get/set on profiles nodes - def testMEDField6(self): - ff=MEDFileFieldMultiTS.New("Pyfile7.med","VectorFieldOnNodes") - its=ff.getIterations() - self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_CELLS,its[0][0],its[0][1],0)# request on cell and it is not on cells - f=ff.getFieldAtLevel(ON_NODES,its[0][0],its[0][1],0) - f2=MEDLoader.ReadFieldNode("Pyfile7.med",'3DSurfMesh_1',0,"VectorFieldOnNodes",its[0][0],its[0][1]) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - ff=MEDFileFieldMultiTS.New("Pyfile19.med","VFieldOnNodes") - its=ff.getIterations() - f=ff.getFieldAtLevel(ON_NODES,its[0][0],its[0][1],0) - f2=MEDLoader.ReadFieldNode("Pyfile19.med",'2DMesh_1',0,"VFieldOnNodes",its[0][0],its[0][1]) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_CELLS,its[0][0],its[0][1],0)# request on cell and it is not on cells - self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_NODES,its[0][0],its[0][1],0,1)#request renumber following mesh : it is on profile ! - pass - - # MEDField get/set on profiles cells - def testMEDField7(self): - ff=MEDFileFieldMultiTS.New("Pyfile12.med","VectorFieldOnCells") - its=ff.getIterations() - f=ff.getFieldAtLevel(ON_CELLS,its[0][0],its[0][1],0) - f2=MEDLoader.ReadFieldCell("Pyfile12.med",'3DMesh_1',0,"VectorFieldOnCells",its[0][0],its[0][1]) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - #first test of assignation. No profile and types sorted by type. - def testMEDField8(self): - fname="Pyfile25.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - f2=MEDLoader.ReadFieldCell(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]); - itt,orr,ti=ff1.getTime() - self.assertEqual(0,itt); self.assertEqual(1,orr); self.assertAlmostEqual(2.,ti,14); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - ff1.setTime(3,4,2.3) - itt,orr,ti=ff1.getTime() - self.assertEqual(3,itt); self.assertEqual(4,orr); self.assertAlmostEqual(2.3,ti,14); - da,infos=ff1.getUndergroundDataArrayExt() - f2.getArray().setName(da.getName())#da has the same name than f2 - self.assertTrue(da.isEqual(f2.getArray(),1e-12)) - self.assertEqual([((3, 0), (0, 2)), ((4, 0), (2, 4)), ((6, 0), (4, 5)), ((5, 0), (5, 6))],infos) - # - fname="Pyfile26.med" - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - nv=1456. - da=ff1.getUndergroundDataArray().setIJ(0,0,nv) - ff1.write(fname,0) - f2=MEDLoader.ReadFieldNode(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]) - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)) - f1.getArray().setIJ(0,0,nv) - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - # - fname="Pyfile27.med" - f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - f2=MEDLoader.ReadFieldGaussNE(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]) - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - da,infos=ff1.getUndergroundDataArrayExt() - f2.getArray().setName(da.getName())#da has the same name than f2 - self.assertTrue(da.isEqual(f2.getArray(),1e-12)) - self.assertEqual([((3, 0), (0, 6)), ((4, 0), (6, 14)), ((6, 0), (14, 20))],infos) - # - fname="Pyfile28.med" - f1=MEDLoaderDataForTest.buildVecFieldOnGauss_2_Simpler(); - f1InvalidCpy=f1.deepCpy() - f1InvalidCpy.setDiscretization(MEDCouplingFieldDiscretizationGauss()) - f1InvalidCpy2=f1.deepCpy() - f1InvalidCpy2.setDiscretization(MEDCouplingFieldDiscretizationGauss()) - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - self.assertRaises(InterpKernelException,ff1.setFieldNoProfileSBT,f1InvalidCpy) # fails because no Gauss localization per cell set !* - f1InvalidCpy2.getDiscretization().setArrayOfDiscIds(f1.getDiscretization().getArrayOfDiscIds()) # fails because no Gauss localization set whereas gauss locid per cell given ! - self.assertRaises(InterpKernelException,ff1.setFieldNoProfileSBT,f1InvalidCpy2) - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - ff2=MEDFileField1TS.New(fname,f1.getName(),f1.getTime()[1],f1.getTime()[2]) - f2=ff2.getFieldAtLevel(ON_GAUSS_PT,0) - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - sbt=ff2.getFieldSplitedByType2() - loc1=ff2.getLocalization("Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_5") - self.assertEqual("Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_5",loc1.getName()) - self.assertEqual((-1, 1,-1,-1,1,-1,-1,0,0,-1,0,0),loc1.getRefCoords()) - self.assertEqual(6,loc1.getNumberOfPointsInCells()) - self.assertEqual(3,loc1.getNumberOfGaussPoints()) - self.assertEqual(2,loc1.getDimension()) - da,infos=ff2.getUndergroundDataArrayExt() - f2.getArray().setName(da.getName())#da has the same name than f2 - self.assertTrue(da.isEqual(f2.getArray(),1e-12)) - self.assertEqual(53,da.getNumberOfTuples()) - self.assertEqual([((3, 0), (0, 18)), ((3, 1), (18, 30)), ((3, 2), (30, 36)), ((4, 0), (36, 42)), ((4, 1), (42, 44)), ((6, 0), (44, 53))],infos) - # - pass - - def testMEDFileData1(self): - fname="Pyfile29.med" - d=MEDFileData.New() - # - m1=MEDLoaderDataForTest.build1DMesh_1() - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mmm1=MEDFileMeshMultiTS.New() ; - mmm1.setOneTimeStep(mm1) - m2=MEDLoaderDataForTest.build2DCurveMesh_1() - mm2=MEDFileUMesh.New() ; mm2.setCoords(m2.getCoords()) ; mm2.setMeshAtLevel(0,m2) ; mm2.setName(m2.getName()) - mmm2=MEDFileMeshMultiTS.New() ; mmm2.setOneTimeStep(mm2) - ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm1) ; ms.setMeshAtPos(1,mm2) - d.setMeshes(ms) - for name,mmm in zip(["1DMesh_1","2DCurveMesh_1"],ms): - self.assertEqual(name,mmm.getName()) - self.assertEqual(type(mmm),MEDFileUMesh) - pass - self.assertEqual(('1DMesh_1', '2DCurveMesh_1'),d.getMeshes().getMeshesNames()) - # - ff1=MEDFileFieldMultiTS.New() - ff21=MEDFileFieldMultiTS.New() - ff22=MEDFileFieldMultiTS.New() - f1=m1.getMeasureField(True) ; f1.setName("f1") ; f1=f1.buildNewTimeReprFromThis(ONE_TIME,False) - f1.getArray().setInfoOnComponent(0,"power [kW]") - ff1.appendFieldNoProfileSBT(f1) - f21=m2.getMeasureField(True) ; f21.setName("f21") ; f21=f21.buildNewTimeReprFromThis(ONE_TIME,False) - f21.getArray().setInfoOnComponent(0,"sta [mm]") ; - ff21.appendFieldNoProfileSBT(f21) - f22=f21.deepCpy() ; f22.setName("f22") ; f22=f22.buildNewTimeReprFromThis(ONE_TIME,False) ; - f22.applyFunc(2,"3*x*IVec+2*x*JVec") - f22.getArray().setInfoOnComponent(0,"distance [km]") ; f22.getArray().setInfoOnComponent(1,"displacement [cm]") - ff22.appendFieldNoProfileSBT(f22) - fs=MEDFileFields.New() - fs.pushField(ff1) ; fs.pushField(ff21) ; fs.pushField(ff22) - for name,fmts in zip(["f1","f21","f22"],fs): - self.assertEqual(name,fmts.getName()) - pass - d.setFields(fs) - # - fname2="Pyfile29_2.med" - d.write(fname2,2) - # - d2=MEDFileData.New(fname2) - self.assertEqual(2,d2.getNumberOfMeshes()) - self.assertEqual(3,d2.getNumberOfFields()) - self.assertTrue(isinstance(d2.getMeshes().getMeshAtPos(0),MEDFileUMesh)) - self.assertTrue(isinstance(d2.getMeshes()[0],MEDFileUMesh)) - self.assertTrue(isinstance(d2.getMeshes()['2DCurveMesh_1'],MEDFileUMesh)) - m1bis=d2.getMeshes().getMeshAtPos(0).getMeshAtLevel(0) - self.assertTrue(m1.isEqual(m1bis,1e-12)) - self.assertEqual(('f1', 'f21', 'f22'),d2.getFields().getFieldsNames()) - self.assertEqual([(-1,-1,0.0)],d2.getFields().getFieldAtPos(2).getTimeSteps()) - self.assertEqual([(-1,-1,0.0)],d2.getFields()[2].getTimeSteps()) - self.assertEqual([(-1,-1,0.0)],d2.getFields().getFieldWithName("f21").getTimeSteps()) - self.assertEqual([(-1,-1,0.0)],d2.getFields()["f21"].getTimeSteps()) - pass - - def testMEDField9(self): - # first test field profile WR. Full type but with some type missing - fname="Pyfile30.med" - m1=MEDLoaderDataForTest.build2DMesh_3() - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F1") - d=DataArrayDouble.New() ; d.alloc(2*9,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.alloc(9,1) ; da.iota(0) ; da.setName("sup1") - # - ff1.setFieldProfile(f1,mm1,0,da) - ff1.changePflsNames([(["sup1_NORM_QUAD4"],"ForV650")]) - ff1=ff1.deepCpy() - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da))# profiles names cannot be contracted in pfl array name - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - ff3=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - ff2.deepCpyGlobs(ff3) - sbt=ff2.getFieldSplitedByType2() - self.assertEqual(3,sbt[0][0])#TRI3 - self.assertEqual(0,sbt[0][1][0][0])#CELL For TRI3 - self.assertEqual("",sbt[0][1][0][2])#no profile For TRI3 - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18],sbt[0][1][0][1].getValues())# values for TRI3 - self.assertEqual(4,sbt[1][0])#QUAD4 - self.assertEqual(0,sbt[1][1][0][0])#CELL For QUAD4 - self.assertEqual("ForV650",sbt[1][1][0][2])# profile For QUAD4 - self.assertEqual([19, 20, 21, 22, 23, 24],sbt[1][1][0][1].getValues())# values for QUAD4 - self.assertEqual([0],ff2.getTypesOfFieldAvailable()) - vals,pfl=ff2.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField10(self): - fname="Pyfile31.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") - d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ff1=ff1.deepCpy() - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_CELLS,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) - self.assertEqual([(-1,-1,0.0), (1,2,1.2)],ff2.getTimeSteps()) - vals,pfl=ff2.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff2.getFieldWithProfile(ON_CELLS,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - # idem testMEDField9 method except that here testing profile on nodes and not on cells. - def testMEDField11(self): - fname="Pyfile32.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f1.setName("F1Node") - d=DataArrayDouble.New() ; d.alloc(2*6,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") - # - ff1.setFieldProfile(f1,mm1,0,da) - self.assertEqual(ff1.getNonEmptyLevels(),(-1, [])) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - ## # - ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - vals,pfl=ff2.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField12(self): - fname="Pyfile33.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f1.setName("F1Node") - d=DataArrayDouble.New() ; d.alloc(2*6,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_NODES,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_NODES,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) - vals,pfl=ff2.getFieldWithProfile(ON_NODES,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff2.getFieldWithProfile(ON_NODES,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField13(self): - fname="Pyfile34.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - tmp=m1.getName(); - m1=m1.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) # suppression of last cell that is a polygon - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F3Node") - d=DataArrayDouble.New() ; d.alloc(2*11,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,2,3],3,1) ; da.setName("sup1NodeElt") - # - ff1.setFieldProfile(f1,mm1,0,da) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - vals,pfl=ff2.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField14(self): - fname="Pyfile35.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - tmp=m1.getName(); - m1=m1.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) # suppression of last cell that is a polygon - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F4Node") - d=DataArrayDouble.New() ; d.alloc(2*11,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,2,3],3,1) ; da.setName("sup1NodeElt") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - self.assertEqual([[3],[3]],ff1.getTypesOfFieldAvailable()) - # - ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - pass - # Tricky test of the case of in a MED file containing a Field on GAUSS_NE is lying on a profile that is reality represents all the geom entities of a level. - # By default when using setFieldProfile method such profile is not created because it is not useful ! So here a trick is used to force MEDLoader to do that - # for the necessity of the test ! The idea is too create artificially a mesh having one more fictious cell per type and to roll back right after ! - def testMEDField15(self): - fname="Pyfile36.med" - m0=MEDLoaderDataForTest.build2DMesh_1() - m0.renumberCells([0,1,4,2,3,5],False) - tmp=m0.getName(); - m1=m0.buildPartOfMySelf([0,1,1,2,3,3,4,4],True) ; m1.setName(tmp) # suppression of last cell that is a polygon and creation of one more cell per type - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F4Node") - d=DataArrayDouble.New() ; d.alloc(2*20,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,3,4,6],5,1) ; da.setName("sup1NodeElt") - # - ff1.setFieldProfile(f1,mm1,0,da) - m1=m0.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1.write(fname,0) - f1=ff1.getFieldOnMeshAtLevel(ON_GAUSS_NE,m1,0) - f2,p1=ff1.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; f2.setName("") - self.assertTrue(p1.isIdentity()) - self.assertEqual(5,p1.getNumberOfTuples()) - self.assertTrue(f1.getArray().isEqual(f2,1e-12)) - pass - # Test for getFieldAtTopLevel method - def testMEDField16(self): - fname="Pyfile37.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - m2=m1.buildDescendingConnectivity()[0] - m2.sortCellsInMEDFileFrmt() - m2.setName(m1.getName()) - mm1.setMeshAtLevel(-1,m2) - mm1.write(fname,2) - f2=m2.getMeasureField(True) - dd=DataArrayDouble.New() - dd.alloc(f2.getArray().getNumberOfTuples(),3) - dd[:,0]=f2.getArray() - dd[:,1]=2*f2.getArray() - dd[:,2]=3*f2.getArray() - f2=f2.buildNewTimeReprFromThis(ONE_TIME,False) - f2.setArray(dd) - f2.copyTinyStringsFrom(f1) - f2.copyTinyAttrFrom(f1) - ff1.setFieldNoProfileSBT(f2) - ff1.write(fname,0) - # Reading Pyfile37.med - ff2=MEDFileField1TS.New(fname,f2.getName(),0,1) - f1bis=ff2.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(f1.isEqual(f1bis,1e-12,1e-12)) - f1bis=ff2.getFieldAtLevel(ON_CELLS,-1) - self.assertTrue(f2.isEqual(f1bis,1e-12,1e-12)) - f1bis=ff2.getFieldAtTopLevel(ON_CELLS) - self.assertTrue(f1.isEqual(f1bis,1e-12,1e-12)) - # More complex - fname="Pyfile38.med" - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f2) - ff1.write(fname,0) - ff2=MEDFileField1TS.New(fname,f2.getName(),0,1) - f1bis=ff2.getFieldAtTopLevel(ON_CELLS) - self.assertTrue(f2.isEqual(f1bis,1e-12,1e-12)) - pass - - # Non regression test to check that globals are correctly appended on MEDFileFields::setFieldAtPos - def testMEDField17(self): - fname="Pyfile39.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mm1.write(fname,2) - ffs=MEDFileFields.New() - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") - d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ffs.resize(1) - ffs.setFieldAtPos(0,ff1) - ffs=ffs.deepCpy() - ffs.write(fname,0) - # - ffsr=MEDFileFields.New(fname) - ff3=ffsr.getFieldAtPos(0) - f4=ff3.getFieldAtTopLevel(ON_CELLS,1,2) - self.assertTrue(f4.getArray().isEqual(f1.getArray(),1e-12)) - pass - - # Non regression test to check that globals are correctly appended on MEDFileFields::setFieldAtPos - def testMEDField18(self): - fname="Pyfile40.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mm1.write(fname,2) - ffs=MEDFileFields.New() - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") - d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ffs.pushField(ff1) - ffs.write(fname,0) - # - ffsr=MEDFileFields.New(fname) - ff3=ffsr.getFieldAtPos(0) - f4=ff3.getFieldAtTopLevel(ON_CELLS,1,2) - self.assertTrue(f4.getArray().isEqual(f1.getArray(),1e-12)) - pass - - def testMEDFieldBug1(self): - fname="Pyfile13.med" - d=MEDFileData.New(fname) - self.assertEqual(('Loc_MyFirstFieldOnGaussPoint_NORM_QUAD4_1','Loc_MyFirstFieldOnGaussPoint_NORM_TRI3_0','Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_2'),d.getFields().getFieldAtPos(0).getLocs()) - pass - - def testMEDMesh8(self): - m=MEDLoaderDataForTest.build1DMesh_1() - m.convertQuadraticCellsToLinear() - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - g1=DataArrayInt.New() ; g1.setValues([0,2],2,1) ; g1.setName("g1") - g2=DataArrayInt.New() ; g2.setValues([1,3],2,1) ; g2.setName("g2") - g3=DataArrayInt.New() ; g3.setValues([1,2,3],3,1) ; g3.setName("g3") - mm.setGroupsAtLevel(0,[g1,g2],False) - self.assertEqual(('g1','g2'),mm.getGroupsNames()) - self.assertEqual(('Family_-2','Family_-3'),mm.getFamiliesNames()) - self.assertEqual(('Family_-2',),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('Family_-3',),mm.getFamiliesOnGroup('g2')) - mm.assignFamilyNameWithGroupName() - self.assertEqual(('g1','g2'),mm.getGroupsNames()) - self.assertEqual(('g1','g2'),mm.getFamiliesNames()) - self.assertEqual(('g1',),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('g2',),mm.getFamiliesOnGroup('g2')) - # - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setGroupsAtLevel(0,[g1,g2,g3],False) - self.assertEqual(('g1','g2','g3'),mm.getGroupsNames()) - self.assertEqual(('Family_-2', 'Family_-4', 'Family_-5'),mm.getFamiliesNames()) - self.assertEqual(('Family_-2', 'Family_-4'),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('Family_-5',),mm.getFamiliesOnGroup('g2')) - self.assertEqual(('Family_-4','Family_-5',),mm.getFamiliesOnGroup('g3')) - mm.assignFamilyNameWithGroupName() # here it does nothing because no such group-family bijection found - self.assertEqual(('g1','g2','g3'),mm.getGroupsNames()) - self.assertEqual(('Family_-2', 'Family_-4', 'Family_-5'),mm.getFamiliesNames()) - self.assertEqual(('Family_-2', 'Family_-4'),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('Family_-5',),mm.getFamiliesOnGroup('g2')) - self.assertEqual(('Family_-4','Family_-5',),mm.getFamiliesOnGroup('g3')) - mm.changeFamilyId(5,6) - g=mm.getGroupArr(0,"g3") - self.assertTrue(g.isEqual(g3)); - g=mm.getGroupArr(0,"g2") - self.assertTrue(g.isEqual(g2)); - g=mm.getGroupArr(0,"g1") - self.assertTrue(g.isEqual(g1)); - pass - - # bug detected by gauthier - def testMEDLoaderMEDLoaderNSReadFieldDoubleDataInMedFile(self): - fname="Pyfile41.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - # writing mesh1 and field1, now creation of mesh2 and field2 - f2=f1.deepCpy() - m2=f2.getMesh() - m2.translate([0.5,0.6,0.7]) - m2.setName("3DSurfMesh_2") - f2.getArray()[:]*=2. - f2.setName("VectorFieldOnCells2") - mm2=MEDFileUMesh.New() - mm2.setCoords(m2.getCoords()) - mm2.setMeshAtLevel(0,m2) - mm2.write(fname,0) - ff2=MEDFileField1TS.New() - ff2.setFieldNoProfileSBT(f2) - ff2.write(fname,0) - # - f3=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_1",0,"VectorFieldOnCells",0,1) - self.assertTrue(f3.isEqual(f1,1e-12,1e-12)) - f4=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_2",0,"VectorFieldOnCells2",0,1) - self.assertTrue(f4.isEqual(f2,1e-12,1e-12)) - pass - - def testMEDLoaderMultiLevelCellField1(self): - fname="Pyfile42.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setCoords(m2.getCoords()) - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - m.write(fname,2) - # - FieldName1="Field1" - compNames1=["comp1","comp2","comp3"] - ff1=MEDFileField1TS.New() - da2=DataArrayDouble.New() - da2.alloc(m2.getNumberOfCells()*len(compNames1),1) - da2.iota(7.) - da2.rearrange(len(compNames1)) - da2.setInfoOnComponents(compNames1) - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f2.setName(FieldName1) ; f2.setArray(da2) ; f2.setMesh(m2) ; f2.checkCoherency() - ff1.setFieldNoProfileSBT(f2) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0])) - da0=DataArrayDouble.New() - da0.alloc(m0.getNumberOfCells()*len(compNames1),1) - da0.iota(190.) - da0.rearrange(len(compNames1)) - da0.setInfoOnComponents(compNames1) - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName1) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() - ff1.setFieldNoProfileSBT(f0) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-2])) - da1=DataArrayDouble.New() - da1.alloc(m1.getNumberOfCells()*len(compNames1),1) - da1.iota(90.) - da1.rearrange(len(compNames1)) - da1.setInfoOnComponents(compNames1) - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName1) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() - ff1.setFieldNoProfileSBT(f1) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) - # - ff1.write(fname,0) - # - FieldName2="Field2" - compNames2=["comp11","comp22"] - ff2=MEDFileField1TS.New() - da0=DataArrayDouble.New() - da0.alloc(m0.getNumberOfCells()*2,1) - da0.iota(-190.) - da0.rearrange(2) - da0.setInfoOnComponents(compNames2) - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName2) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() - ff2.setFieldNoProfileSBT(f0) - self.assertEqual(ff2.getNonEmptyLevels(),(0, [0])) - da1=DataArrayDouble.New() - da1.alloc(m1.getNumberOfCells()*len(compNames2),1) - da1.iota(-90.) - da1.rearrange(len(compNames2)) - da1.setInfoOnComponents(compNames2) - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName2) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() - ff2.setFieldNoProfileSBT(f1) - self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) - # - ff2.write(fname,0) - # - ff1=MEDFileField1TS.New(fname,FieldName1,-1,-1) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) - self.assertEqual(ff1.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')]), (3, [(0, (84, 148), '', '')]), (4, [(0, (148, 212), '', '')])]) - ff2=MEDFileField1TS.New(fname,FieldName2,-1,-1) - self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) - self.assertEqual(ff2.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')])]) - pass - - def testFieldOnPflRetrieveOnMdimRelMax1(self): - fname="Pyfile43.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - f=MEDFileField1TS.New() - ff=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) - ff.setName("NodeFieldPfl") - arr=DataArrayDouble.New() ; arr.setValues([1.,10.,100.,2.,20.,200.],2,3) - ff.setArray(arr) - pfl=DataArrayInt.New() ; pfl.setValues([2,3],2,1) ; pfl.setName("PflNode") - f.setFieldProfile(ff,m,-2,pfl) - tes0=f.getFieldOnMeshAtLevel(ON_NODES,-1,m) - self.assertEqual(ON_NODES,tes0.getTypeOfField()) - self.assertEqual(1,tes0.getMesh().getMeshDimension()) - self.assertEqual(1,tes0.getMesh().getNumberOfCells()) - self.assertEqual(2,tes0.getMesh().getNumberOfNodes()) - self.assertEqual([1,0,1],tes0.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,3],tes0.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes0.getArray().getNumberOfTuples()) - self.assertEqual(3,tes0.getArray().getNumberOfComponents()) - expected1=[1.,10.,100.,2.,20.,200.] - nodeCoordsWithValue1=[10.,2.5,0.] - nodeCoordsWithValue2=[10.,3.75,0.] - for i in xrange(3): - self.assertAlmostEqual(nodeCoordsWithValue1[i],tes0.getMesh().getCoordinatesOfNode(0)[i],13); - self.assertAlmostEqual(nodeCoordsWithValue2[i],tes0.getMesh().getCoordinatesOfNode(1)[i],13); - pass - for i in xrange(6): - self.assertAlmostEqual(expected1[i],tes0.getArray().getIJ(0,i),13); - pass - del tes0 - # - tes1=f.getFieldOnMeshAtLevel(ON_NODES,1,m) - self.assertEqual(ON_CELLS,tes1.getTypeOfField())# it is not a bug even if ON_NODES has been sepecified - self.assertEqual(0,tes1.getMesh().getMeshDimension()) - self.assertEqual(2,tes1.getMesh().getNumberOfCells()) - self.assertEqual(135,tes1.getMesh().getNumberOfNodes()) - self.assertEqual([0,2,0,3],tes1.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,2,4],tes1.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes1.getArray().getNumberOfTuples()) - self.assertEqual(3,tes1.getArray().getNumberOfComponents()) - for i in xrange(6): - self.assertAlmostEqual(expected1[i],tes1.getArray().getIJ(0,i),13); - pass - m.write(fname,2) - f.write(fname,0) - # - pfl=DataArrayInt.New() ; pfl.setValues([3,2],2,1) ; pfl.setName("PflNode") - f=MEDFileField1TS.New() - f.setFieldProfile(ff,m,-2,pfl) - tes2=f.getFieldOnMeshAtLevel(ON_NODES,-1,m) - self.assertEqual(ON_NODES,tes2.getTypeOfField()) - self.assertEqual(1,tes2.getMesh().getMeshDimension()) - self.assertEqual(1,tes2.getMesh().getNumberOfCells()) - self.assertEqual(2,tes2.getMesh().getNumberOfNodes()) - self.assertEqual([1,0,1],tes2.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,3],tes2.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes2.getArray().getNumberOfTuples()) - self.assertEqual(3,tes2.getArray().getNumberOfComponents()) - expected2=[2.,20.,200.,1.,10.,100.] - for i in xrange(3): - self.assertAlmostEqual(nodeCoordsWithValue1[i],tes2.getMesh().getCoordinatesOfNode(0)[i],13); - self.assertAlmostEqual(nodeCoordsWithValue2[i],tes2.getMesh().getCoordinatesOfNode(1)[i],13); - pass - for i in xrange(6): - self.assertAlmostEqual(expected2[i],tes2.getArray().getIJ(0,i),13);#compare tes2 and tes3 - pass - # - tes3=f.getFieldOnMeshAtLevel(ON_NODES,1,m) - self.assertEqual(ON_CELLS,tes3.getTypeOfField())# it is not a bug even if ON_NODES has been sepecified - self.assertEqual(0,tes3.getMesh().getMeshDimension()) - self.assertEqual(2,tes3.getMesh().getNumberOfCells()) - self.assertEqual(135,tes3.getMesh().getNumberOfNodes()) - self.assertEqual([0,3,0,2],tes3.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,2,4],tes3.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes3.getArray().getNumberOfTuples()) - self.assertEqual(3,tes3.getArray().getNumberOfComponents()) - for i in xrange(6): - self.assertAlmostEqual(expected1[i],tes3.getArray().getIJ(0,i),13); - pass - pass - - def testBuildInnerBoundaryAlongM1Group1(self): - fname="Pyfile44.med" - m=MEDCouplingCMesh.New() - m.setCoordsAt(0,DataArrayDouble.New([0.,1.1,2.3,3.6,5.,6.5])) - m.setCoordsAt(1,DataArrayDouble.New([0.,1.1,2.3,3.6,5.])) - m=m.buildUnstructured() ; m.setName("AnthonyDuplicate") - m.getCoords().setInfoOnComponents(["X [km]","Z [mm]"]) - m2=m.buildDescendingConnectivity()[0][[8,11,14,20,21,22,23,24,25,26,31,32,33,34,35,36,37]] - m2.setName(m.getName()) - grp=DataArrayInt.New([4,6,8]) ; grp.setName("Grp") - grp2=DataArrayInt.New([9,16]) ; grp2.setName("Grp2") - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(-1,[grp,grp2]) - grpNode=DataArrayInt.New([4,21,23]) ; grpNode.setName("GrpNode") - mm.setGroupsAtLevel(1,[grpNode]) - ref0=[4,15,14,20,21,4,16,15,21,22,4,17,16,22,23] - ref1=[4,9,8,14,15,4,10,9,15,16,4,11,10,16,17] - ref2=[4,9,8,14,30,4,10,9,30,31,4,11,10,31,32] - # - self.assertEqual(30,mm.getNumberOfNodes()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues()) - self.assertEqual(ref1,mm.getMeshAtLevel(0)[[7,8,9]].getNodalConnectivity().getValues()) - # - nodes,cells,cells2=mm.buildInnerBoundaryAlongM1Group("Grp") - self.assertEqual([15,16,17],nodes.getValues()); - self.assertEqual([7,8,9],cells.getValues()); - self.assertEqual([12,13,14],cells2.getValues()); - self.assertEqual(33,mm.getNumberOfNodes()) - self.assertEqual([4,6,8],mm.getGroupArr(-1,"Grp").getValues()) - self.assertEqual([9,16],mm.getGroupArr(-1,"Grp2").getValues()) - self.assertEqual([4,21,23],mm.getGroupArr(1,"GrpNode").getValues()) - self.assertEqual([17,18,19],mm.getGroupArr(-1,"Grp_dup").getValues()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues())#cells 7,8,9 and 12,13,14 are lying on "Grp" but only 7,8 and 9 are renumbered - self.assertEqual(ref2,mm.getMeshAtLevel(0)[[7,8,9]].getNodalConnectivity().getValues())# - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only - mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates - refValues=DataArrayDouble.New([1.21,1.32,1.43,1.54,1.65,1.32,1.44,1.56,1.68,1.8,1.43,1.56,1.69,1.82,1.95,1.54,1.68,1.82,1.96,2.1]) - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - # - mm.getCoords()[-len(nodes):]+=[0.,-0.3] - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); - refValues2=refValues[:] ; refValues2[7:10]=[1.365,1.26,1.35] - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - mm.write(fname,2) - pass - - def testBuildInnerBoundaryAlongM1Group2(self): - fname="Pyfile45.med" - m=MEDCouplingCMesh.New() - m.setCoordsAt(0,DataArrayDouble.New([0.,1.1,2.3,3.6,5.,6.5])) - m.setCoordsAt(1,DataArrayDouble.New([0.,1.1,2.3,3.6,5.])) - m=m.buildUnstructured() ; m.setName("AnthonyDuplicate") - m.getCoords().setInfoOnComponents(["X [km]","Z [mm]"]) - m2=m.buildDescendingConnectivity()[0][[8,11,14,20,21,22,23,24,25,26,31,32,33,34,35,36,37]] - m2.setName(m.getName()) - grp=DataArrayInt.New([4,6]) ; grp.setName("Grp") - grp2=DataArrayInt.New([9,16]) ; grp2.setName("Grp2") - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(-1,[grp,grp2]) - grpNode=DataArrayInt.New([4,21,23]) ; grpNode.setName("GrpNode") - mm.setGroupsAtLevel(1,[grpNode]) - ref0=[4,15,14,20,21,4,16,15,21,22,4,17,16,22,23] - ref1=[4,9,8,14,15,4,10,9,15,16] - ref2=[4,9,8,14,30,4,10,9,30,16] - # - self.assertEqual(30,mm.getNumberOfNodes()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues()) - self.assertEqual(ref1,mm.getMeshAtLevel(0)[[7,8]].getNodalConnectivity().getValues()) - # - nodes,cells,cells2=mm.buildInnerBoundaryAlongM1Group("Grp") - self.assertEqual([15],nodes.getValues()); - self.assertEqual([7,8],cells.getValues()); - self.assertEqual([12,13],cells2.getValues()); - self.assertEqual(31,mm.getNumberOfNodes()) - self.assertEqual([4,6],mm.getGroupArr(-1,"Grp").getValues()) - self.assertEqual([9,16],mm.getGroupArr(-1,"Grp2").getValues()) - self.assertEqual([4,21,23],mm.getGroupArr(1,"GrpNode").getValues()) - self.assertEqual([17,18],mm.getGroupArr(-1,"Grp_dup").getValues()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues())#cells 7,8,9 and 12,13,14 are lying on "Grp" but only 7,8 and 9 are renumbered - self.assertEqual(ref2,mm.getMeshAtLevel(0)[[7,8]].getNodalConnectivity().getValues())# - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only - mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates - refValues=DataArrayDouble.New([1.21,1.32,1.43,1.54,1.65,1.32,1.44,1.56,1.68,1.8,1.43,1.56,1.69,1.82,1.95,1.54,1.68,1.82,1.96,2.1]) - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - # - mm.getCoords()[-len(nodes):]+=[0.,-0.3] - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); - refValues2=refValues[:] ; refValues2[7:9]=[1.365,1.47] - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - mm.write(fname,2) - pass - - def testBuildInnerBoundaryAlongM1Group3(self): - """ Test buildInnerBoundaryAlongM1Group() with *non-connex* cracks """ - fname = "Pyfile73.med" - m = MEDCouplingCMesh.New() - m.setCoordsAt(0, DataArrayDouble([0.0,1.1,2.3,3.6,5.0])) - m.setCoordsAt(1, DataArrayDouble([0.,1.,2.])) - m = m.buildUnstructured(); m.setName("simple") - m2 = m.buildDescendingConnectivity()[0] - m2.setName(m.getName()) - - # A crack in two non connected parts of the mesh: - grpSeg = DataArrayInt([3,19]) ; grpSeg.setName("Grp") - - mm = MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(-1,[grpSeg]) - nodes, cellsMod, cellsNotMod = mm.buildInnerBoundaryAlongM1Group("Grp") - self.assertEqual([1,13],nodes.getValues()); - self.assertEqual([0,6],cellsMod.getValues()); - self.assertEqual([1,7],cellsNotMod.getValues()); - self.assertEqual(17,mm.getNumberOfNodes()) - self.assertEqual([3,19],mm.getGroupArr(-1,"Grp").getValues()) - self.assertEqual([22,23],mm.getGroupArr(-1,"Grp_dup").getValues()) - ref0=[4, 15, 0, 5, 6, 4, 8, 7, 12, 16] - ref1=[4, 2, 1, 6, 7, 4, 9, 8, 13, 14] - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[0,6]].getNodalConnectivity().getValues()) - self.assertEqual(ref1,mm.getMeshAtLevel(0)[[1,7]].getNodalConnectivity().getValues()) - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only - mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates - - refValues=DataArrayDouble([1.1, 1.2, 1.3, 1.4, 1.1, 1.2, 1.3, 1.4]) - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-10) - # - mm.getCoords()[-len(nodes):]+=[0.,-0.3] - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); - refValues2=refValues[:] ; refValues2[0] = 1.265; refValues2[6] = 1.105 - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - mm.write(fname,2) - - def testBasicConstructors(self): - fname="Pyfile18.med" - m=MEDFileMesh.New(fname) - m=MEDFileMesh.New(fname,"ExampleOfMultiDimW",-1,-1) - m=MEDFileMesh.New(fname) - m=MEDFileUMesh(fname,"ExampleOfMultiDimW",-1,-1) - m=MEDFileUMesh(fname) - m=MEDFileUMesh() - self.testMEDMesh6() - m=MEDFileCMesh("MEDFileMesh5.med") - m=MEDFileCMesh("MEDFileMesh5.med","myFirstCartMesh",-1,-1) - m=MEDFileCMesh() - m=MEDFileMeshMultiTS() - m=MEDFileMeshMultiTS(fname) - m=MEDFileMeshMultiTS(fname,"ExampleOfMultiDimW") - m=MEDFileMeshes() - m=MEDFileMeshes(fname) - m=MEDFileField1TS() - m=MEDFileField1TS(fname,"FieldOnFacesShuffle",2,7) - m=MEDFileFieldMultiTS() - m=MEDFileFieldMultiTS(fname,"FieldOnFacesShuffle") - m=MEDFileFields() - m=MEDFileFields(fname) - m=MEDFileData() - m=MEDFileData(fname) - # - m=DataArrayInt() ; m=DataArrayInt(5,2) ; m=DataArrayInt([6,5,4,3,2,1],3,2) - m=DataArrayDouble() ; m=DataArrayDouble(5,2) ; m=DataArrayDouble([6,5,4,3,2,1],3,2) - m=MEDCouplingUMesh("jjj",2) ; m=MEDCouplingUMesh() - m=MEDCouplingCMesh() - m=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - m=MEDCouplingFieldTemplate(ON_NODES) - m=MEDCouplingMultiFields([]) - m=MEDCouplingFieldOverTime([]) - pass - - # This is a non regression test. When a field lies partially on a mesh but fully on one of its geometric type. - def testBugSemiPartialField(self): - fname="Pyfile46.med" - m=MEDLoaderDataForTest.build2DMesh_3() - m=m[:10] ; m.setName("mesh") - f=m.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setTime(5.5,3,4) - f.setName("SemiPartialField") - # - f1=f[:6] ; f1.getMesh().setName(m.getName()) - f2=f[6:] ; f2.getMesh().setName(m.getName()) - # - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - ff=MEDFileField1TS.New() - ff.setFieldProfile(f1,mm,0,DataArrayInt.Range(0,6,1)) # no name on profile -> normally it is an error but in this special case - mm.write(fname,2) - ff.write(fname,0) - # - ff2=MEDFileField1TS.New(fname,f.getName(),f.getTime()[1],f.getTime()[2]) - fread=ff2.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=ff2.getFieldAtLevel(ON_CELLS,0) - # - fread.checkCoherency() - fread2.checkCoherency() - self.assertTrue(fread.isEqual(f1,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f1,1e-12,1e-12)) - pass - - def testUnPolyze1(self): - fname="Pyfile47.med" - mm=MEDLoaderDataForTest.buildMLMeshUnPolyze(self) - ref=[13,14,14,12,12,12,12,12,12,12,12,13,12,14,14,13,15,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12] - self.assertEqual(ref,mm.getFamilyFieldAtLevel(1).getValues()) - self.assertEqual(mm.unPolyze()[:3],(True,[[3,2,0],[4,3,2],[5,4,5],[14,2,9],[16,3,11],[31,2,14]],[[3,3,0],[4,3,3],[5,3,6],[14,3,9],[16,3,12],[18,1,15]])) - mm.write(fname,2) - self.assertEqual(mm.getGroupArr(0,"grp0_L0").getValues(),[0,1,2,6]) - self.assertEqual(mm.getGroupArr(0,"grp1_L0").getValues(),[1,3,4,5,6]) - self.assertEqual(mm.getGroupArr(-1,"grp0_LM1").getValues(),[1,2,3,4,5]) - self.assertEqual(mm.getGroupArr(-1,"grp1_LM1").getValues(),[3,4,5,6]) - self.assertEqual(mm.getGroupArr(-1,"grp2_LM1").getValues(),[2,6,7,8]) - self.assertEqual(mm.getGroupArr(1,"grp0_Node").getValues(),[0,11,15,16]) - self.assertEqual(mm.getGroupArr(1,"grp1_Node").getValues(),[1,2,13,14,16]) - self.assertEqual(mm.getFamilyFieldAtLevel(1).getValues(),ref) - # to test - mm.setRenumFieldArr(0,None) - mm.setFamilyFieldArr(-1,None) - pass - - def testUnPolyze2(self): - fname="Pyfile48.med" - mfd=MEDFileData.New() - mm=MEDLoaderDataForTest.buildMLMeshUnPolyze(self) - meshes=MEDFileMeshes.New() - meshes.pushMesh(mm) - mfd.setMeshes(meshes) - fields=MEDFileFields.New() - mfd.setFields(fields) - ff=MEDFileFieldMultiTS.New() - fields.pushField(ff) - # - f0_0=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f0_0.setName("f0") - f0_0.setTime(9.5,3,4) - da=DataArrayDouble.New(38*2) ; da.iota(6.) ; da.rearrange(2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"]) - f0_0.setArray(da) - f0_0.setMesh(mm.getMeshAtLevel(0)) - ff.appendFieldNoProfileSBT(f0_0) - ff0=ff.getTimeStepAtPos(0) - f0_1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0_1.setName("f0") - f0_1.setTime(9.5,3,4) - pfl=DataArrayInt.New([1,4,5,6]) ; pfl.setName("pfltest") - f0_1.setMesh(mm.getMeshAtLevel(0)[pfl]) - da=DataArrayDouble.New([1401.,101401.,1602.,101602.,3100.,103100.,3101.,103101.],4,2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"]) - f0_1.setArray(da) - ff0.setFieldProfile(f0_1,mm,0,pfl) - f0_2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0_2.setName("f0")#provoquer error - f0_2.setTime(9.5,3,4) - pfl2=DataArrayInt.New([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfltestM1") - da=DataArrayDouble.New([300.,100300.,301.,100301.,400.,100400.,401.,100401.,402.,100402.,3200.,103200.,3201.,103201.,3203.,103203.],8,2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"])#provoquer error - f0_2.setMesh(mm.getMeshAtLevel(-1)[pfl2]) - f0_2.setArray(da) - ff0.setFieldProfile(f0_2,mm,-1,pfl2) - mfd.getFields().shallowCpyGlobs(ff0) - # - mfd.unPolyzeMeshes() - # - fmts=mfd.getFields()[0] - self.assertEqual(fmts.getNumberOfTS(),1) - self.assertEqual(fmts.getTimeSteps(),[(3,4,9.5)]) - arr,entry=fmts.getUndergroundDataArrayExt(3,4) - self.assertEqual(entry,[((3,0),(38,40)),((4,0),(40,43)),((5,0),(43,46)),((14,0),(46,48)),((16,0),(48,49)),((18,0),(49,50)),((40,0),(0,38))]) - self.assertTrue(arr[38:40].isEqualWithoutConsideringStr(DataArrayDouble([300.0,100300.0,301.0,100301.0],2,2),1e-8)) - self.assertTrue(arr[40:43].isEqualWithoutConsideringStr(DataArrayDouble([400.0,100400.0,401.0,100401.0,402.0,100402.0],3,2),1e-8)) - self.assertTrue(arr[43:46].isEqualWithoutConsideringStr(DataArrayDouble([3200.0,103200.0,3201.0,103201.0,3203.0,103203.0],3,2),1e-8)) - self.assertTrue(arr[46:48].isEqualWithoutConsideringStr(DataArrayDouble([1401.0,101401.0,3100.0,103100.0],2,2),1e-8)) - self.assertTrue(arr[48:49].isEqualWithoutConsideringStr(DataArrayDouble([1602.0,101602.0],1,2),1e-8)) - self.assertTrue(arr[49:50].isEqualWithoutConsideringStr(DataArrayDouble([3101.0,103101.0],1,2),1e-8)) - self.assertEqual(('NewPfl_0','NewPfl_1','NewPfl_2'),fmts.getPflsReallyUsed()) - self.assertEqual([(3,[(0,(38,40),'NewPfl_0','')]),(4,[(0,(40,43),'','')]),(5,[(0,(43,46),'','')]),(14,[(0,(46,48),'NewPfl_1','')]),(16,[(0,(48,49),'NewPfl_2','')]),(18,[(0,(49,50),'','')]),(40,[(1,(0,38),'','')])],fmts.getFieldSplitedByType(3,4)) - self.assertEqual(fmts.getProfile("NewPfl_0").getValues(),[0,1]) - self.assertEqual(fmts.getProfile("NewPfl_1").getValues(),[1,2]) - self.assertEqual(fmts.getProfile("NewPfl_2").getValues(),[2]) - ftest0=fmts.getFieldOnMeshAtLevel(ON_CELLS,3,4,0,mfd.getMeshes()[0]) - self.assertTrue(ftest0.getArray().isEqualWithoutConsideringStr(DataArrayDouble([1401.,101401.,3100.,103100.,1602.,101602.,3101.,103101.],4,2),1e-8)) - self.assertEqual(ftest0.getMesh().getNodalConnectivity().getValues(),[14,4,5,6,7,14,26,27,28,29,16,20,21,22,23,24,25,18,30,31,32,33,34,35,36,37]) - self.assertEqual(ftest0.getMesh().getNodalConnectivityIndex().getValues(),[0,5,10,17,26]) - ftest1=fmts.getFieldOnMeshAtLevel(ON_CELLS,3,4,-1,mfd.getMeshes()[0]) - self.assertTrue(ftest1.getArray().isEqualWithoutConsideringStr(DataArrayDouble([300.,100300.,301.,100301.,400.,100400.,401.,100401.,402.,100402.,3200.,103200.,3201.,103201.,3203.,103203.]),1e-8)) - self.assertEqual(ftest1.getMesh().getNodalConnectivity().getValues(),[3,0,1,2,3,3,4,5,4,6,7,8,9,4,10,11,12,13,4,14,15,16,17,5,18,19,20,21,22,5,23,24,25,26,27,5,31,32,33,34,35,36,37]) - self.assertEqual(ftest1.getMesh().getNodalConnectivityIndex().getValues(),[0,4,8,13,18,23,29,35,43]) - # - mfd.write(fname,2) - pass - - def testGaussWriteOnPfl1(self): - fname="Pyfile49.med" - fname2="Pyfile50.med" - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2) - mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords) - mQ8.allocateCells(1) - mQ8.insertNextCell(NORM_QUAD8,range(8)) - mQ8.finishInsertingCells() - mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords) - mQ4.allocateCells(1) - mQ4.insertNextCell(NORM_QUAD4,range(4)) - mQ4.finishInsertingCells() - mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords) - mT3.allocateCells(1) - mT3.insertNextCell(NORM_TRI3,range(3)) - mT3.finishInsertingCells() - - tr=[[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.]] - ms=11*[mT3]+2*[mQ4]+7*[mQ8] - ms[:]=(elt.deepCpy() for elt in ms) - for m,t in zip(ms,tr): - d=m.getCoords() ; d+= t - pass - m=MEDCouplingUMesh.MergeUMeshes(ms) - m.setName("mesh") - m2=m[:13] ; m2.setName(m.getName()) - ### Use case 1 : Pfl on all tri3 and on all quad4. If we were on CELLS or GAUSS_NE no pfl were needed. But here 2 discs in tri3. - ### So here 2 pfls will be created (pfl_TRI3_loc_0 and pfl_TRI3_loc_1) - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) - f.setMesh(m2) - f.setTime(4.5,1,2) - da=DataArrayDouble(34) ; da.iota(3.) - f.setArray(da) - f.setName("fieldCellOnPflWithoutPfl") - fInvalid=f.deepCpy() - f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) - f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) - f.checkCoherency() - fInvalid2=fInvalid.deepCpy() - fInvalid2.getDiscretization().setArrayOfDiscIds(f.getDiscretization().getArrayOfDiscIds()) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.write(fname,2) - # - f1ts=MEDFileField1TS.New() - pfl=DataArrayInt(range(13)) ; pfl.setName("pfl") - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,fInvalid,mm,0,pfl) # fails because no Gauss localization per cell set ! - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,fInvalid2,mm,0,pfl) # fails because no Gauss localization set whereas gauss locid per cell given ! - f1ts.setFieldProfile(f,mm,0,pfl) - f1ts.write(fname,0) - # - self.assertEqual(f1ts.getPfls(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1')) - self.assertEqual(f1ts.getPflsReallyUsed(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1')) - da1=DataArrayInt([0,1,2,3,4,5,6,7,8]) ; da1.setName("pfl_NORM_TRI3_loc_0") - self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_0").isEqual(da1)) - da1=DataArrayInt([9,10]) ; da1.setName("pfl_NORM_TRI3_loc_1") - self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_1").isEqual(da1)) - self.assertEqual(f1ts.getLocs(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2')) - self.assertEqual(f1ts.getLocsReallyUsed(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2')) - # - dataRead=MEDFileData.New(fname) - mRead=dataRead.getMeshes()[0] - f1tsRead=dataRead.getFields()[0][0] - f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f2=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - f2_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f2_bis.checkCoherency() - self.assertTrue(f.isEqual(f2_bis,1e-12,1e-12)) - # - MEDLoader.WriteField(fname2,f,True) - f2_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - self.assertTrue(f.isEqual(f2_ter,1e-12,1e-12)) - ## Use case 2 : Pfl on part tri3 with 2 disc and on part quad8 with 1 disc - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) - pfl=DataArrayInt([1,2,5,6,8,9,15,16,17,18]) ; pfl.setName("pfl2") - m2=m[pfl] ; m2.setName(m.getName()) - f.setMesh(m2) - f.setTime(4.5,1,2) - da=DataArrayDouble(35) ; da.iota(3.) - f.setArray(da) - f.setName("fieldCellOnPflWithoutPfl2") - f.setGaussLocalizationOnCells([0,1,3],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([2,4,5],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) - f.setGaussLocalizationOnCells([6,7,8,9],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) - f.checkCoherency() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.write(fname,2) - f1ts=MEDFileField1TS.New() - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertEqual(f1ts.getPfls(),('pfl2_NORM_TRI3_loc_0','pfl2_NORM_TRI3_loc_1','pfl2_NORM_QUAD8_loc_2')) - self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_0").getValues(),[1,2,6]) - self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_1").getValues(),[5,8,9]) - self.assertEqual(f1ts.getProfile("pfl2_NORM_QUAD8_loc_2").getValues(),[2,3,4,5]) - f1ts.write(fname,0) - dataRead=MEDFileData.New(fname) - mRead=dataRead.getMeshes()[0] - f1tsRead=dataRead.getFields()[0][0] - f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f3.renumberCells([0,1,3,2,4,5,6,7,8,9]) - self.assertTrue(f.isEqual(f3,1e-12,1e-12)) - f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_bis.renumberCells([0,1,3,2,4,5,6,7,8,9]) - self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12)) - # - MEDLoader.WriteField(fname2,f,True) - f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_ter.renumberCells([0,1,3,2,4,5,6,7,8,9]) - self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) - ## Use case 3 : no pfl but creation of pfls due to gauss pts - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) - f.setMesh(m) - f.setTime(4.5,1,2) - da=DataArrayDouble(60) ; da.iota(3.) - f.setArray(da) - f.setName("fieldCellWithoutPfl") - f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) - f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) - f.setGaussLocalizationOnCells([13,14,15,17,18],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8],[0.8,0.1,0.03,0.07]) - f.setGaussLocalizationOnCells([16,19],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.1,0.1]) - f.checkCoherency() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - f1ts=MEDFileField1TS.New() - f1ts.setFieldNoProfileSBT(f) - self.assertEqual(f1ts.getPfls(),('Pfl_fieldCellWithoutPfl_NORM_TRI3_0','Pfl_fieldCellWithoutPfl_NORM_TRI3_1','Pfl_fieldCellWithoutPfl_NORM_QUAD8_3','Pfl_fieldCellWithoutPfl_NORM_QUAD8_4')) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_0").getValues(),[0,1,2,3,4,5,6,7,8]) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_1").getValues(),[9,10]) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_3").getValues(),[0,1,2,4,5]) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_4").getValues(),[3,6]) - mm.write(fname,2) - f1ts.write(fname,0) - # - dataRead=MEDFileData.New(fname) - mRead=dataRead.getMeshes()[0] - f1tsRead=dataRead.getFields()[0][0] - f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f3.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) - self.assertTrue(f.isEqual(f3,1e-12,1e-12)) - f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_bis.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) - self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12)) - # - MEDLoader.WriteField(fname2,f,True) - f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_ter.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) - self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) - pass - - # Testing profile on nodes when the profile is identity but not on all nodes. - def testMEDFieldPflOnNode1(self): - fname="Pyfile51.med" - coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) - m0=MEDCouplingUMesh("Mesh",2) - m0.allocateCells(5) - m0.insertNextCell(NORM_TRI3,[1,4,2]) - m0.insertNextCell(NORM_TRI3,[4,5,2]) - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) - m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) - m0.finishInsertingCells() - m0.setCoords(coo) - m1=MEDCouplingUMesh(m0.getName(),1) - m1.allocateCells(9) - conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] - for i in xrange(9): - m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) - pass - m1.finishInsertingCells() - m1.setCoords(coo) - # - m=MEDFileUMesh() - m.setMeshAtLevel(0,m0) - m.setMeshAtLevel(-1,m1) - # - dt=3 ; it=2 ; tim=4.5 - fieldNode0=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) - fieldNode0.setName("fieldNode0") - fieldNode0.setTime(tim,dt,it) - pfl0=DataArrayInt([0,1,2,3,4]) ; pfl0.setName("PflIdentity0") # important to keep like that - arr=DataArrayDouble([10,11,12,13,14]) - fieldNode0.setArray(arr) - f0=MEDFileField1TS() - f0.setFieldProfile(fieldNode0,m,0,pfl0) - m.write(fname,2) ; f0.write(fname,0) - fieldNode1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) - fieldNode1.setName("fieldNode1") - fieldNode1.setTime(tim,dt,it) - pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") - arr1=DataArrayDouble([20,21,22,23,24,25,26]) - fieldNode1.setArray(arr1) - f1=MEDFileField1TS() - f1.setFieldProfile(fieldNode1,m,-1,pfl1) - f1.write(fname,0) - del m,f0,m0,m1,f1 - ## Reading from file - m=MEDFileMesh.New(fname) - m0=m.getMeshAtLevel(0) - m00=m0.deepCpy() ; m00=m00[[0,2]] ; m00.setName(m.getName()) ; m00.zipCoords() - fieldNode0.setMesh(m00) - f0=MEDFileField1TS.New(fname,fieldNode0.getName(),dt,it) - ff0_1=f0.getFieldOnMeshAtLevel(ON_NODES,m0) - ff0_1.checkCoherency() - self.assertTrue(ff0_1.isEqual(fieldNode0,1e-12,1e-12)) - ff0_2=f0.getFieldAtLevel(ON_NODES,0) - ff0_2.checkCoherency() - self.assertTrue(ff0_2.isEqual(fieldNode0,1e-12,1e-12)) - ff0_3=f0.getFieldOnMeshAtLevel(ON_NODES,0,m) - ff0_3.checkCoherency() - self.assertTrue(ff0_3.isEqual(fieldNode0,1e-12,1e-12)) - ff0_4=MEDLoader.ReadFieldNode(fname,m.getName(),0,fieldNode0.getName(),dt,it) - ff0_4.checkCoherency() - self.assertTrue(ff0_4.isEqual(fieldNode0,1e-12,1e-12)) - f1=MEDFileField1TS.New(fname,fieldNode1.getName(),dt,it) - m1=m.getMeshAtLevel(-1) - m10=m1.deepCpy() ; m10=m10[[0,1,2,3,4,5,6,7]] ; m10.setName(m.getName()) ; m10.zipCoords() - fieldNode1.setMesh(m10) - ff1_1=f1.getFieldOnMeshAtLevel(ON_NODES,m1) - ff1_1.checkCoherency() - self.assertTrue(ff1_1.isEqual(fieldNode1,1e-12,1e-12)) - ff1_2=f1.getFieldAtLevel(ON_NODES,-1) - ff1_2.checkCoherency() - self.assertTrue(ff1_2.isEqual(fieldNode1,1e-12,1e-12)) - ff1_3=f1.getFieldOnMeshAtLevel(ON_NODES,-1,m) - ff1_3.checkCoherency() - self.assertTrue(ff1_3.isEqual(fieldNode1,1e-12,1e-12)) - ff1_4=MEDLoader.ReadFieldNode(fname,m.getName(),-1,fieldNode1.getName(),dt,it) - ff1_4.checkCoherency() - self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,m0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_NODES,0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,0,m) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] - arr_r,pfl1_r=f1.getFieldWithProfile(ON_NODES,-1,m) - arr_r.setName(fieldNode1.getArray().getName()) - self.assertTrue(arr_r.isEqual(fieldNode1.getArray(),1e-12)) - pfl1_r.setName(pfl1.getName()) - self.assertTrue(pfl1_r.isEqual(pfl1)) - pass - - # Testing profile on nodes when the profile is identity but not on all nodes. - def testMEDFieldPflOnCell1(self): - fname="Pyfile52.med" - coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) - m0=MEDCouplingUMesh("Mesh",2) - m0.allocateCells(5) - m0.insertNextCell(NORM_TRI3,[1,4,2]) - m0.insertNextCell(NORM_TRI3,[4,5,2]) - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) - m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) - m0.finishInsertingCells() - m0.setCoords(coo) - m1=MEDCouplingUMesh(m0.getName(),1) - m1.allocateCells(9) - conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] - for i in xrange(9): - m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) - pass - m1.finishInsertingCells() - m1.setCoords(coo) - # - m=MEDFileUMesh() - m.setMeshAtLevel(0,m0) - m.setMeshAtLevel(-1,m1) - # - dt=3 ; it=2 ; tim=4.5 - fieldCell0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - fieldCell0.setName("fieldCell0") - fieldCell0.setTime(tim,dt,it) - pfl0=DataArrayInt([0,1,2]) ; pfl0.setName("PflIdentity0") # important to keep like that - arr=DataArrayDouble([10,11,12]) - fieldCell0.setArray(arr) - f0=MEDFileField1TS() - f0.setFieldProfile(fieldCell0,m,0,pfl0) - m.write(fname,2) ; f0.write(fname,0) - fieldCell1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - fieldCell1.setName("fieldCell1") - fieldCell1.setTime(tim,dt,it) - pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") - arr1=DataArrayDouble([20,21,22,23,24,25,26]) - fieldCell1.setArray(arr1) - f1=MEDFileField1TS() - f1.setFieldProfile(fieldCell1,m,-1,pfl1) - f1.write(fname,0) - del m,f0,m0,m1,f1 - ## Reading from file - m=MEDFileMesh.New(fname) - m0=m.getMeshAtLevel(0) - m00=m0.deepCpy() ; m00=m00[pfl0] ; m00.setName(m.getName()) - fieldCell0.setMesh(m00) - f0=MEDFileField1TS.New(fname,fieldCell0.getName(),dt,it) - ff0_1=f0.getFieldOnMeshAtLevel(ON_CELLS,m0) - ff0_1.checkCoherency() - self.assertTrue(ff0_1.isEqual(fieldCell0,1e-12,1e-12)) - ff0_2=f0.getFieldAtLevel(ON_CELLS,0) - ff0_2.checkCoherency() - self.assertTrue(ff0_2.isEqual(fieldCell0,1e-12,1e-12)) - ff0_3=f0.getFieldOnMeshAtLevel(ON_CELLS,0,m) - ff0_3.checkCoherency() - self.assertTrue(ff0_3.isEqual(fieldCell0,1e-12,1e-12)) - ff0_4=MEDLoader.ReadFieldCell(fname,m.getName(),0,fieldCell0.getName(),dt,it) - ff0_4.checkCoherency() - self.assertTrue(ff0_4.isEqual(fieldCell0,1e-12,1e-12)) - f1=MEDFileField1TS.New(fname,fieldCell1.getName(),dt,it) - m1=m.getMeshAtLevel(-1) - m10=m1.deepCpy() ; m10=m10[pfl1] ; m10.setName(m.getName()) - fieldCell1.setMesh(m10) - ff1_1=f1.getFieldOnMeshAtLevel(ON_CELLS,m1) - ff1_1.checkCoherency() - self.assertTrue(ff1_1.isEqual(fieldCell1,1e-12,1e-12)) - ff1_2=f1.getFieldAtLevel(ON_CELLS,-1) - ff1_2.checkCoherency() - self.assertTrue(ff1_2.isEqual(fieldCell1,1e-12,1e-12)) - ff1_3=f1.getFieldOnMeshAtLevel(ON_CELLS,-1,m) - ff1_3.checkCoherency() - self.assertTrue(ff1_3.isEqual(fieldCell1,1e-12,1e-12)) - ff1_4=MEDLoader.ReadFieldCell(fname,m.getName(),-1,fieldCell1.getName(),dt,it) - ff1_4.checkCoherency() - self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,m0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_CELLS,0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,0,m) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] - arr_r,pfl1_r=f1.getFieldWithProfile(ON_CELLS,-1,m) - arr_r.setName(fieldCell1.getArray().getName()) - self.assertTrue(arr_r.isEqual(fieldCell1.getArray(),1e-12)) - pfl1_r.setName(pfl1.getName()) - self.assertTrue(pfl1_r.isEqual(pfl1)) - pass - - def testMEDFileUMeshZipCoords1(self): - m=MEDFileUMesh() - coo=DataArrayDouble(30) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) - m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) - m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) - m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) - m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) - m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) - m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) - numCoo=DataArrayInt(10) ; numCoo.iota(3) ; m.setRenumFieldArr(1,numCoo) - famCoo=DataArrayInt(10) ; famCoo.iota(4) ; m.setFamilyFieldArr(1,famCoo) - da=DataArrayInt([20,30,40]) ; m.setRenumFieldArr(0,da) ; da=DataArrayInt([200,300,400]) ; m.setFamilyFieldArr(0,da) - da=DataArrayInt([50,60]) ; m.setRenumFieldArr(-1,da) ; da=DataArrayInt([500,600]) ; m.setFamilyFieldArr(-1,da) - da=DataArrayInt([70,80,90]) ; m.setRenumFieldArr(-2,da) ; da=DataArrayInt([700,800,900]) ; m.setFamilyFieldArr(-2,da) - o2n=m.zipCoords() - self.assertTrue(o2n.isEqual(DataArrayInt([-1,0,1,2,3,-1,4,5,6,-1]))) - self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt([4,5,6,7,9,10,11]))) - self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([5,6,7,8,10,11,12]))) - self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,4,1,3,2,3,5,0,4,4,4,1]))) - self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,9,15]))) - self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivity().isEqual(DataArrayInt([1,0,4,1,5,2]))) - self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) - self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivity().isEqual(DataArrayInt([0,1,0,4,0,6]))) - self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivityIndex().isEqual(DataArrayInt([0,2,4,6]))) - pass - - def testMEDUMeshAddNodeGroup1(self): - fname="Pyfile53.med" - m=MEDFileUMesh() - coo=DataArrayDouble(39) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) - m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) - m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) - m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) - m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) - m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) - m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) - # - mm=m.deepCpy() - famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(1,famCoo) - da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(0,da0) - da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) - da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) - mm.setFamilyId("MyFam",2) - mm.setFamilyId("MyOtherFam",3) - mm.setFamilyId("MyOther-1",-1) - mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) - mm.setFamiliesOnGroup("grpA",["MyOther-1"]) - # - daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") - mm.addNodeGroup(daTest) - self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) - for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - mm.write(fname,2) - mm=MEDFileMesh.New(fname) - self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) - for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - pass - - def testMEDUMeshAddGroup1(self): - fname="Pyfile54.med" - m=MEDFileUMesh() - coo=DataArrayDouble(9) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) - m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) - for i in xrange(7): - m0.insertNextCell(NORM_TRI3,[1,2,1]) - pass - for i in xrange(4): - m0.insertNextCell(NORM_QUAD4,[1,1,2,0]) - pass - for i in xrange(2): - m0.insertNextCell(NORM_POLYGON,[0,0,1,1,2,2]) - pass - m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) - m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) - m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) - m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) - m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) - # - mm=m.deepCpy() - famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(0,famCoo) - da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(1,da0) - da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) - da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) - mm.setFamilyId("MyFam",2) - mm.setFamilyId("MyOtherFam",3) - mm.setFamilyId("MyOther-1",-1) - mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) - mm.setFamiliesOnGroup("grpA",["MyOther-1"]) - # - daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") - mm.addGroup(0,daTest) - self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-6,2,-6,-8,2,-6,-5,-6,-6,-7,-7,-4,-8]))) - for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('Family_-4','Family_-5','Family_-7','Family_-8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_-4',-4),('Family_-5',-5),('Family_-7',-7),('Family_-8',-8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_-8')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - mm.write(fname,2) - mm=MEDFileMesh.New(fname) - self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-6,2,-6,-8,2,-6,-5,-6,-6,-7,-7,-4,-8]))) - for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_-4','Family_-5','Family_-7','Family_-8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_-4',-4),('Family_-5',-5),('Family_-7',-7),('Family_-8',-8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_-8','MyOtherFam')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - pass - - def testHeapMem1(self): - a=DataArrayInt() ; aa=a.getHeapMemorySize() - a.alloc(0,1) - strMulFac=a.getHeapMemorySize()-aa ; del a ; del aa - # - m=MEDCouplingCMesh() - arr=DataArrayDouble(10,1) ; arr.iota(0) - m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName("mm") - f=m.getMeasureField(ON_CELLS) - self.assertIn(m.getHeapMemorySize(),xrange(3552-100,3552+100+4*strMulFac)) - self.assertIn(f.getHeapMemorySize(),xrange(4215-100,4215+100+8*strMulFac)) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - self.assertIn(mm.getHeapMemorySize(),xrange(3889-100,3889+100+10*strMulFac)) - ff=MEDFileField1TS() - ff.setFieldNoProfileSBT(f) - self.assertIn(ff.getHeapMemorySize(),xrange(771-40,771+21+(4+1)*strMulFac)) - # - fff=MEDFileFieldMultiTS() - fff.appendFieldNoProfileSBT(f) - self.assertIn(fff.getHeapMemorySize(),xrange(815-50,815+30+(6+2)*strMulFac)) - f.setTime(1.,0,-1) - fff.appendFieldNoProfileSBT(f) - self.assertIn(fff.getHeapMemorySize(),xrange(1594-90,1594+50+(10+1)*strMulFac)) - self.assertIn(fff[0,-1].getHeapMemorySize(),xrange(771-40,771+20+(4+1)*strMulFac)) - f2=f[:50] - f2.setTime(2.,1,-1) - pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") - fff.appendFieldProfile(f2,mm,0,pfl) - self.assertIn(fff.getHeapMemorySize(),xrange(2348-130,2348+100+(10+2)*strMulFac)) - self.assertIn(fff.getProfile("pfl").getHeapMemorySize(),xrange(204-10,204+10+2*strMulFac)) - self.assertIn(fff[1,-1].getHeapMemorySize(),xrange(738-50,738+30+4*strMulFac)) - pass - - def testCurveLinearMesh1(self): - fname="Pyfile55.med" - mesh=MEDCouplingCurveLinearMesh(); - mesh.setTime(2.3,4,5); - mesh.setTimeUnit("us"); - mesh.setName("Example of Cuve linear mesh"); - mesh.setDescription("buildCLMesh"); - a1=DataArrayDouble(3*20,1); - a1.iota(7.) ; a1.rearrange(3); - mesh.setCoords(a1); - mesh.setNodeGridStructure([4,5]); - mesh.checkCoherency(); - # - m=MEDFileCurveLinearMesh() - m.setMesh(mesh) - d=DataArrayInt(20) ; d.iota(4) - m.setFamilyFieldArr(1,d) - d3=DataArrayInt(20) ; d3.iota(400) - m.setRenumFieldArr(1,d3) - d2=DataArrayInt(12) ; d2.iota(40) - m.setFamilyFieldArr(0,d2) - d4=DataArrayInt(21) ; d4.iota(4000) - self.assertRaises(InterpKernelException,m.setRenumFieldArr,1,d4) - d4.popBackSilent() - m.setRenumFieldArr(1,d4) - m.write(fname,2) - # - m1=MEDFileCurveLinearMesh(fname) - mm=m1.getMesh() - self.assertTrue(mm.isEqual(mesh,1e-12)) - self.assertEqual(mm.getSpaceDimension(),3) - self.assertEqual(mm.getSpaceDimensionOnNodeStruct(),2) - # - m1=MEDFileMesh.New(fname) - self.assertTrue(isinstance(m1,MEDFileCurveLinearMesh)) - self.assertTrue(isinstance(m1.getUnivName(),str)) - self.assertTrue(len(m1.getUnivName())!=0) - self.assertTrue(m1.getMesh().isEqual(mesh,1e-12)) - pass - - def testParameters1(self): - fname="Pyfile56.med" - m=MEDCouplingCMesh() ; arr=DataArrayDouble([0.,1.2,3.5]) ; m.setCoords(arr,arr) ; m.setName("mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) - ms=MEDFileMeshes() ; ms.pushMesh(mm) - data=MEDFileData() - p=MEDFileParameters() - data.setParams(p) ; data.setMeshes(ms) - pts=MEDFileParameterMultiTS() - pts.setName("A") ; pts.setDescription("An example of parameter") ; pts.setTimeUnit("ms") - pts.appendValue(1,2,3.4,567.89) - pts.appendValue(2,3,5.6,999.123) - pts2=pts.deepCpy() ; pts2.setName("B") ; pts2.setDescription("A second example") - p.pushParam(pts) ; p.pushParam(pts2) - data.write(fname,2) - p2=MEDFileParameters(fname) - self.assertTrue(p.isEqual(p2,1e-14)[0]) - self.assertAlmostEqual(p[1][1,2].getValue(),567.89,13) - p3=p.deepCpy() - pts4=pts2.deepCpy() - pts3=pts2.deepCpy() - self.assertTrue(pts3.isEqual(pts2,1e-14)[0]) - pts2.eraseTimeStepIds([0]) - self.assertTrue(not pts3.isEqual(pts2,1e-14)[0]) - del pts3[[3.4]] - self.assertTrue(pts3.isEqual(pts2,1e-14)[0]) - self.assertRaises(InterpKernelException,p[1].__getitem__,(1,2)) - self.assertRaises(InterpKernelException,p["B"].__getitem__,(1,2)) - self.assertAlmostEqual(p[0][1,2].getValue(),567.89,13) - self.assertAlmostEqual(p["A"][1,2].getValue(),567.89,13) - p=p3 - self.assertTrue(p.isEqual(p2,1e-14)[0]) - self.assertTrue(p2["B"].isEqual(pts,1e-14)[0]) - self.assertTrue(not p2["B"].isEqual(pts2,1e-14)[0]) - self.assertAlmostEqual(p2[0][1,2].getValue(),567.89,13) - self.assertEqual(p.getParamsNames(),('A','B')) - ptsr=MEDFileParameterMultiTS(fname,"B") - self.assertTrue(ptsr.isEqual(pts4,1e-14)[0]) - ptsr=MEDFileParameterMultiTS(fname) - self.assertTrue(ptsr.isEqual(pts,1e-14)[0]) - p1tsr=MEDFileParameterDouble1TS(fname) - self.assertEqual(p1tsr.getName(),"A") - self.assertAlmostEqual(p1tsr.getValue(),567.89,13) - p1tsr=MEDFileParameterDouble1TS(fname,"B") - self.assertEqual(p1tsr.getName(),"B") - self.assertAlmostEqual(p1tsr.getValue(),567.89,13) - p1tsr=MEDFileParameterDouble1TS(fname,"B",2,3) - self.assertEqual(p1tsr.getName(),"B") - self.assertAlmostEqual(p1tsr.getValue(),999.123,13) - data2=MEDFileData(fname) - self.assertEqual(2,data2.getNumberOfParams()) - self.assertAlmostEqual(data2.getParams()["B"][1,2].getValue(),567.89,13) - pass - - def testNamesOnCellAndNodesInMeshes1(self): - fname="Pyfile58.med" - fname2="Pyfile59.med" - m=MEDLoaderDataForTest.build3DSurfMesh_1() - m1=m.buildDescendingConnectivity()[0] - m1.sortCellsInMEDFileFrmt() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m1) - namesCellL0=DataArrayAsciiChar(6,16) - namesCellL0[:]=["CellL0#%.3d "%(i) for i in xrange(6)] - mm.setNameFieldAtLevel(0,namesCellL0) - namesCellL1=DataArrayAsciiChar.Aggregate([namesCellL0,namesCellL0,namesCellL0.substr(2)]) - namesCellL1[:]=["CellLM1#%.3d "%(i) for i in xrange(16)] - mm.setNameFieldAtLevel(-1,namesCellL1) - namesNodes=namesCellL1.substr(4,16) - namesNodes[:]=["Node#%.3d "%(i) for i in xrange(12)] - mm.setNameFieldAtLevel(1,namesNodes) - mm.write(fname,2) - # - mmr=MEDFileMesh.New(fname) - self.assertTrue(mm.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["CellL0#%.3d "%(i) for i in xrange(6)]))) - self.assertTrue(mm.getNameFieldAtLevel(-1).isEqual(DataArrayAsciiChar(["CellLM1#%.3d "%(i) for i in xrange(16)]))) - self.assertTrue(mm.getNameFieldAtLevel(1).isEqual(DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(12)]))) - self.assertTrue(mm.isEqual(mmr,1e-12)[0]) - mmr.getNameFieldAtLevel(1).setIJ(0,0,'M') - self.assertTrue(not mm.isEqual(mmr,1e-12)[0]) - mmr.getNameFieldAtLevel(1).setIJ(0,0,'N') - self.assertTrue(mm.isEqual(mmr,1e-12)[0]) - mmCpy=mm.deepCpy() - self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) - # remove names on nodes - mmCpy.setNameFieldAtLevel(1,None) - self.assertTrue(not mm.isEqual(mmCpy,1e-12)[0]) - mm.setNameFieldAtLevel(1,None) - self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) - mm.setNameFieldAtLevel(-1,None) - mm.write(fname,2) - mmr=MEDFileMesh.New(fname) - self.assertEqual(mmr.getNameFieldAtLevel(1),None) - self.assertTrue(mmr.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["CellL0#%.3d "%(i) for i in xrange(6)]))) - self.assertEqual(mmr.getNameFieldAtLevel(-1),None) - # - c=MEDCouplingCMesh() - arr=DataArrayDouble([0.,1.1,2.3]) - c.setCoords(arr,arr) - c.setName("cmesh") - cc=MEDFileCMesh() - cc.setMesh(c) - cc.setNameFieldAtLevel(0,DataArrayAsciiChar(["Cell#%.3d "%(i) for i in xrange(4)])) - cc.setNameFieldAtLevel(1,DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(9)])) - cc.write(fname2,2) - ccr=MEDFileMesh.New(fname2) - self.assertTrue(ccr.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["Cell#%.3d "%(i) for i in xrange(4)]))) - self.assertTrue(ccr.getNameFieldAtLevel(1).isEqual(DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(9)]))) - self.assertTrue(cc.isEqual(ccr,1e-12)[0]) - ccr.getNameFieldAtLevel(1).setIJ(0,0,'M') - self.assertTrue(not cc.isEqual(ccr,1e-12)[0]) - ccr.getNameFieldAtLevel(1).setIJ(0,0,'N') - self.assertTrue(cc.isEqual(ccr,1e-12)[0]) - ccCpy=cc.deepCpy() - self.assertTrue(cc.isEqual(ccCpy,1e-12)[0]) - pass - - def testToExportInExamples1(self): - m=MEDCouplingCMesh() - arr=DataArrayDouble([0.,1.,2.,3.,4.]) - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.setName("mesh") - grp1=DataArrayInt([0,1,2,4,5,6,8,9,10,12,13,14]) ; grp1.setName("grp1") - grp2=DataArrayInt([3,7,11,15]) ; grp2.setName("grp2") - m2=m.computeSkin() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(0,[grp1,grp2]) - mm.write("example.med",2) - # - m0=mm.getMeshAtLevel(0) - m1=mm.getMeshAtLevel(-1) - grp1=mm.getGroupArr(0,"grp1") - grp2=mm.getGroupArr(0,"grp2") - grps=[grp1,grp2] - whichGrp=DataArrayInt(m0.getNumberOfCells()) - whichGrp.fillWithValue(-1) - for grpId,grp in enumerate(grps): - whichGrp[grp]=grpId - pass - a,b,bI,c,cI=m0.buildDescendingConnectivity() - e,f=a.areCellsIncludedIn(m1,2) - self.assertTrue(e) - c2,c2I=MEDCouplingUMesh.ExtractFromIndexedArrays(f,c,cI) - self.assertTrue(c2I.deltaShiftIndex().isUniform(1)) - c2.transformWithIndArr(whichGrp) - splitOfM1=len(grps)*[None] - for grpId,grp in enumerate(grps): - tmp=c2.getIdsEqual(grpId) - splitOfM1[grpId]=tmp - pass - splitOfM1[0].isEqual(DataArrayInt([0,1,2,3,6,8,10,11,12,13])) - splitOfM1[1].isEqual(DataArrayInt([4,5,7,9,14,15])) - pass - - def testBugCorrection1(self): - fs=MEDFileFields() - fs.resize(3) - self.assertEqual(fs[0],None) - self.assertEqual(3,len(fs)) - pass - - def testCompareMEDFilesContainingOnlyFieldsOnCell1(self): - f1Name="Pyfile60.med" - f2Name="Pyfile61.med" - d1=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - d1.write(f1Name,2) - d2=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - d2.write(f2Name,2) - # reading and compare - d1=MEDFileData(f1Name) ; d2=MEDFileData(f2Name) - for mn in d1.getMeshes().getMeshesNames(): - m1=d1.getMeshes()[mn] - m2=d2.getMeshes()[mn] - for lev in m1.getNonEmptyLevels(): - grpsNames=m1.getGroupsOnSpecifiedLev(lev) - for grpName in grpsNames: - self.assertTrue(m1.getGroupArr(lev,grpName).isEqual(m2.getGroupArr(lev,grpName))) # compare groups - pass - pass - pass - for fieldn in d1.getFields().getFieldsNames(): - f1=d1.getFields()[fieldn] - f2=d2.getFields()[fieldn] - for it,order,tim in f1.getTimeSteps(): - f1t=f1[it,order] - f2t=f2[it,order] - if len(f1t.getPflsReallyUsed())!=0: - # profile case - for lev in f1t.getNonEmptyLevels()[1]: - arr1,pfl1=f1t.getFieldWithProfile(ON_CELLS,lev,m1) - arr2,pfl2=f2t.getFieldWithProfile(ON_CELLS,lev,m2) - self.assertTrue(pfl1.isEqual(pfl2)) - self.assertTrue(arr1.isEqual(arr2,1e-10)) - pass - pass - else: - # no profile case - for lev in f1t.getNonEmptyLevels()[1]: - f1mc=f1t.getFieldOnMeshAtLevel(ON_CELLS,lev,m1) - f2mc=f2t.getFieldOnMeshAtLevel(ON_CELLS,lev,m2) - self.assertTrue(f1mc.isEqual(f2mc,1e-10,1e-10)) - pass - pass - pass - pass - pass - - def testNonRegBugNormalizeFamIdsMEDFile1(self): - m=MEDCouplingCMesh() - arr=DataArrayDouble([0.,1.,2.,3.,4.]) - m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m2=m.buildDescendingConnectivity()[0] - m.setName("mesh") - g1=DataArrayInt([0,1,2,3]) ; g1.setName("g1") - g2=DataArrayInt([2,3,5,6]) ; g2.setName("g2") - g1Face=DataArrayInt([20,21,22,23]) ; g1Face.setName("g1Face") - g2Face=DataArrayInt([22,23,25,26]) ; g2Face.setName("g2Face") - g1Node=DataArrayInt([10,11,12,13]) ; g1Node.setName("g1Node") - g2Node=DataArrayInt([12,13,15,16]) ; g2Node.setName("g2Node") - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setGroupsAtLevel(0,[g1,g2]) - s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - mm.normalizeFamIdsMEDFile() - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) - self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) - self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) - self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) - for g in mm.getGroupsOnSpecifiedLev(0): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f<0) - pass - pass - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(0,[g1,g2]) - mm.setGroupsAtLevel(-1,[g1Face,g2Face]) - s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) - s3=set(mm.getFamiliesOnGroup("g1Face")) ; s4=set(mm.getFamiliesOnGroup("g2Face")) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - mm.normalizeFamIdsMEDFile() - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) - self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) - self.assertTrue(mm.getGroupArr(-1,"g1Face").isEqual(g1Face)) - self.assertTrue(mm.getGroupArr(-1,"g2Face").isEqual(g2Face)) - self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) - self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) - self.assertEqual(s3,set(mm.getFamiliesOnGroup("g1Face"))) - self.assertEqual(s4,set(mm.getFamiliesOnGroup("g2Face"))) - for lev in [0,-1]: - for g in mm.getGroupsOnSpecifiedLev(lev): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f<0) - pass - pass - pass - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(0,[g1,g2]) - mm.setGroupsAtLevel(-1,[g1Face,g2Face]) - mm.setGroupsAtLevel(1,[g1Node,g2Node]) - s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) - s3=set(mm.getFamiliesOnGroup("g1Face")) ; s4=set(mm.getFamiliesOnGroup("g2Face")) - s5=set(mm.getFamiliesOnGroup("g1Node")) ; s6=set(mm.getFamiliesOnGroup("g2Node")) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Node"),(1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Node"),(1,)) - mm.normalizeFamIdsMEDFile() - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Node"),(1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Node"),(1,)) - self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) - self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) - self.assertTrue(mm.getGroupArr(-1,"g1Face").isEqual(g1Face)) - self.assertTrue(mm.getGroupArr(-1,"g2Face").isEqual(g2Face)) - self.assertTrue(mm.getGroupArr(1,"g1Node").isEqual(g1Node)) - self.assertTrue(mm.getGroupArr(1,"g2Node").isEqual(g2Node)) - self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) - self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) - self.assertEqual(s3,set(mm.getFamiliesOnGroup("g1Face"))) - self.assertEqual(s4,set(mm.getFamiliesOnGroup("g2Face"))) - self.assertEqual(s5,set(mm.getFamiliesOnGroup("g1Node"))) - self.assertEqual(s6,set(mm.getFamiliesOnGroup("g2Node"))) - for lev in [0,-1]: - for g in mm.getGroupsOnSpecifiedLev(lev): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f<0) - pass - pass - pass - for g in mm.getGroupsOnSpecifiedLev(1): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f>0) - pass - pass - pass - - def testNonRegressionMantis22212ChangeGrpName(self): - fileName="Pyfile62.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setCoords(m2.getCoords()) - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - m.setFamilyFieldArr(0,f2) - m.setFamilyFieldArr(-1,f1) - m.setFamilyFieldArr(-2,f0) - m.setFamilyFieldArr(1,p) - nbOfFams=len(fns) - for i in xrange(nbOfFams): - m.addFamily(fns[i],fids[i]) - pass - nbOfGrps=len(grpns) - for i in xrange(nbOfGrps): - m.setFamiliesIdsOnGroup(grpns[i],famIdsPerGrp[i]) - pass - m.setName(m2.getName()) - m.setDescription(m2.getDescription()) - m.write(fileName,2) - # - mm0=MEDFileMesh.New(fileName) - mm1=MEDFileMesh.New(fileName) - groupNamesIni=MEDLoader.GetMeshGroupsNames(fileName,"ma") - for name in groupNamesIni: - mm1.changeGroupName(name,name+'N') - pass - mm1.write(fileName,2) - del mm1 - # - mm2=MEDFileMesh.New(fileName) - for name in groupNamesIni: - for lev in mm0.getGrpNonEmptyLevelsExt(name): - arr0=mm0.getGroupArr(lev,name) - arr2=mm2.getGroupArr(lev,name+'N') - arr0.setName(name+'N') - self.assertTrue(arr0.isEqual(arr2)) - pass - pass - pass - - def testInt32InMEDFileFieldStar1(self): - fname="Pyfile63.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - arr=f1.getArray().convertToIntArr() - f1.setArray(None) - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileIntField1TS() - ff1.setFieldNoProfileSBT(f1,arr) - a,b=ff1.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertEqual(b.getInfoOnComponents(),['power [MW/m^3]','density [g/cm^3]','temperature [K]']) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - ff1.write(fname,0) - ff2=MEDFileAnyTypeField1TS.New(fname) - self.assertEqual(ff2.getName(),"VectorFieldOnCells") - self.assertEqual(ff2.getTime(),[0,1,2.0]) - self.assertTrue(isinstance(ff2,MEDFileIntField1TS)) - a,b=ff1.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertEqual(b.getInfoOnComponents(),['power [MW/m^3]','density [g/cm^3]','temperature [K]']) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - ff2.setTime(1,2,3.) - c=ff2.getUndergroundDataArray() ; c*=2 - ff2.write(fname,0) # 2 time steps in - ffs1=MEDFileAnyTypeFieldMultiTS.New(fname,"VectorFieldOnCells") - self.assertEqual(ffs1.getTimeSteps(),[(0, 1, 2.0), (1, 2, 3.0)]) - self.assertEqual(len(ffs1),2) - self.assertTrue(isinstance(ffs1,MEDFileIntFieldMultiTS)) - a,b=ffs1[2.].getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - a,b=ffs1[2.].getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - it=ffs1.__iter__() ; it.next() ; ff2bis=it.next() - a,b=ff2bis.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertTrue(b.isEqual(2*arr)) - f1.setTime(3.,1,2) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - bc=DataArrayInt(6,3) ; bc[:]=0 ; bc.setInfoOnComponents(['power [MW/m^3]','density [g/cm^3]','temperature [K]']) - for it in ffs1: - a,b=it.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - bc+=b - pass - self.assertTrue(bc.isEqual(3*arr)) - nf1=MEDCouplingFieldDouble(ON_NODES) - nf1.setTime(9.,10,-1) - nf1.setMesh(f1.getMesh()) - narr=DataArrayInt(12,2) ; narr.setInfoOnComponents(["aa [u1]","bbbvv [ppp]"]) ; narr[:,0]=range(12) ; narr[:,1]=2*narr[:,0] - nf1.setName("VectorFieldOnNodes") - nff1=MEDFileIntField1TS.New() - nff1.setFieldNoProfileSBT(nf1,narr) - self.assertEqual(nff1.getInfo(),('aa [u1]','bbbvv [ppp]')) - self.assertEqual(nff1.getTime(),[10,-1,9.0]) - nff1.write(fname,0) - # - nf2=MEDCouplingFieldDouble(ON_NODES) - nf2.setTime(19.,20,-11) - nf2.setMesh(f1.getMesh()) - narr2=DataArrayInt(8,2) ; narr.setInfoOnComponents(["aapfl [u1]","bbbvvpfl [ppp]"]) ; narr2[:,0]=range(8) ; narr2[:,0]+=10 ; narr2[:,1]=3*narr2[:,0] - nf2.setName("VectorFieldOnNodesPfl") ; narr2.setName(nf2.getName()) - nff2=MEDFileIntField1TS.New() - npfl=DataArrayInt([1,2,4,5,6,7,10,11]) ; npfl.setName("npfl") - nff2.setFieldProfile(nf2,narr2,mm1,0,npfl) - nff2.getFieldWithProfile(ON_NODES,0,mm1) - a,b=nff2.getFieldWithProfile(ON_NODES,0,mm1) ; b.setName(npfl.getName()) - self.assertTrue(b.isEqual(npfl)) - self.assertTrue(a.isEqual(narr2)) - nff2.write(fname,0) - nff2bis=MEDFileIntField1TS(fname,"VectorFieldOnNodesPfl") - a,b=nff2bis.getFieldWithProfile(ON_NODES,0,mm1) ; b.setName(npfl.getName()) - self.assertTrue(b.isEqual(npfl)) - self.assertTrue(a.isEqual(narr2)) - # - nf3=MEDCouplingFieldDouble(ON_NODES) - nf3.setName("VectorFieldOnNodesDouble") - nf3.setTime(29.,30,-21) - nf3.setMesh(f1.getMesh()) - nf3.setArray(f1.getMesh().getCoords()) - nff3=MEDFileField1TS.New() - nff3.setFieldNoProfileSBT(nf3) - nff3.write(fname,0) - fs=MEDFileFields(fname) - self.assertEqual(len(fs),4) - ffs=[it for it in fs] - self.assertTrue(isinstance(ffs[0],MEDFileIntFieldMultiTS)) - self.assertTrue(isinstance(ffs[1],MEDFileIntFieldMultiTS)) - self.assertTrue(isinstance(ffs[2],MEDFileFieldMultiTS)) - self.assertTrue(isinstance(ffs[3],MEDFileIntFieldMultiTS)) - # - self.assertTrue(fs["VectorFieldOnCells"][0].getUndergroundDataArray().isEqualWithoutConsideringStr(arr)) - self.assertTrue(fs["VectorFieldOnCells"][1,2].getUndergroundDataArray().isEqualWithoutConsideringStr(2*arr)) - self.assertTrue(fs["VectorFieldOnNodesPfl"][0].getUndergroundDataArray().isEqualWithoutConsideringStr(narr2)) - self.assertTrue(fs["VectorFieldOnNodes"][9.].getUndergroundDataArray().isEqualWithoutConsideringStr(narr)) - self.assertTrue(fs["VectorFieldOnNodesDouble"][29.].getUndergroundDataArray().isEqualWithoutConsideringStr(f1.getMesh().getCoords(),1e-12)) - # - nf3_read=MEDFileFieldMultiTS(fname,"VectorFieldOnNodesDouble") - self.assertTrue(nf3_read[29.].getUndergroundDataArray().isEqualWithoutConsideringStr(f1.getMesh().getCoords(),1e-12)) - self.assertRaises(InterpKernelException,MEDFileIntFieldMultiTS.New,fname,"VectorFieldOnNodesDouble")# exception because trying to read a double field with int instance - self.assertRaises(InterpKernelException,MEDFileFieldMultiTS.New,fname,"VectorFieldOnNodes")# exception because trying to read a int field with double instance - MEDFileField1TS.New(fname,"VectorFieldOnNodesDouble",30,-21) - self.assertRaises(InterpKernelException,MEDFileIntField1TS.New,fname,"VectorFieldOnNodesDouble",30,-21)# exception because trying to read a double field with int instance - MEDFileIntField1TS.New(fname,"VectorFieldOnNodes",10,-1) - self.assertRaises(InterpKernelException,MEDFileField1TS.New,fname,"VectorFieldOnNodes",10,-1)# exception because trying to read a double field with int instance - # - self.assertEqual(fs.getMeshesNames(),('3DSurfMesh_1','3DSurfMesh_1','3DSurfMesh_1','3DSurfMesh_1')) - self.assertTrue(fs.changeMeshNames([('3DSurfMesh_1','3DSurfMesh')])) - self.assertEqual(fs.getMeshesNames(),('3DSurfMesh','3DSurfMesh','3DSurfMesh','3DSurfMesh')) - self.assertTrue(not fs.changeMeshNames([('3DSurfMesh_1','3DSurfMesh')])) - pass - - def testMEDFileFields1(self): - fname="Pyfile64.med" - f1=MEDCouplingFieldDouble(ON_NODES) - f1.setTime(0.001,0,-1) ; f1.setTimeUnit("us") - c=DataArrayDouble(12) ; c.iota(); m=MEDCouplingCMesh() ; m.setCoordsAt(0,c) ; m.setName("mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) ; mm.write(fname,2) - f1.setMesh(m) - arr=DataArrayDouble(12,2) ; arr.setInfoOnComponents(["aa [u1]","bbbvv [ppp]"]) ; arr[:,0]=range(12) ; arr[:,1]=2*arr[:,0] - f1.setArray(arr) - f1.setName("Field1") - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - self.assertEqual(ff1.getDtUnit(),"us") - ff1.write(fname,0) - f1.setTime(1.001,1,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - f1.setTime(2.001,2,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - # - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],False)) - ff1s=MEDFileFieldMultiTS(fname,"Field1") - ff1s.setName("Field2") - ff1s.write(fname,0) - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],False)) - f1.setTime(3.001,3,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],True)) - self.assertEqual(MEDFileFields(fname).partOfThisLyingOnSpecifiedTimeSteps([(1,-1)]).getCommonIterations(),([(1,-1)],False)) - self.assertEqual(MEDFileFields(fname).partOfThisNotLyingOnSpecifiedTimeSteps([(1,-1)]).getCommonIterations(),([(0,-1),(2,-1)],True)) - f1.setName("Field2") ; f1.setTime(3.001,3,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1),(3,-1)],False)) - self.assertEqual(MEDFileFields(fname)[1].getDtUnit(),"us") - pass - - # Multi time steps and multi fields management without Globals (profiles, locs) aspects - def testMEDFileFields2(self): - fname="Pyfile65.med" - # to check that all is initialize - MEDFileField1TS().__str__() - MEDFileFieldMultiTS().__str__() - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - # - fmts0_0=MEDFileFieldMultiTS() - fmts0_1=MEDFileFieldMultiTS() - # time steps - for i in xrange(10): - infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" - d=DataArrayDouble(18) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - fmts0_0.appendFieldNoProfileSBT(f) - f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) ; fmts0_1.pushBackTimeStep(f1ts) - self.assertEqual(fmts0_1.getName(),name1) - self.assertEqual(fmts0_0.getInfo(),('aa [bb]','ccc [ddd]')) - self.assertEqual(fmts0_1.getInfo(),('aa [bb]','ccc [ddd]')) - if i>1: - # components names have been modified to generate errors - d.setInfoOnComponents(['aa [bb]','eee [dd]']) - self.assertRaises(InterpKernelException,fmts0_0.appendFieldNoProfileSBT,f) - self.assertRaises(InterpKernelException,f1ts.setInfo,['aa [bb]'])#throw because mismatch of number of components - f1ts.setInfo(['aa [bb]','eee [dd]']) - self.assertRaises(InterpKernelException,fmts0_1.pushBackTimeStep,f1ts) - pass - # add a mismatch of nb of compos - pass - fmts0_2=fmts0_0.deepCpy() - fmts0_3=fmts0_0.deepCpy() - fmts0_4=fmts0_0.deepCpy() - fmts0_5=fmts0_0.shallowCpy() - self.assertTrue(len(fmts0_0)==10 and len(fmts0_1)==10 and len(fmts0_2)==10 and len(fmts0_3)==10 and len(fmts0_4)==10 and len(fmts0_5)==10) - del fmts0_2[::2] - self.assertTrue(len(fmts0_2)==5 and fmts0_2.getIterations()==[(2,-2),(4,-4),(6,-6),(8,-8),(10,-10)]) - del fmts0_3[[1.1,(6,-6),9]] - self.assertTrue(len(fmts0_3)==7 and fmts0_3.getIterations()==[(2,-2),(3,-3),(4,-4),(5,-5),(7,-7),(8,-8),(9,-9)]) - fmts0_6=fmts0_4[[1.1,(6,-6),8]] - self.assertTrue(isinstance(fmts0_6,MEDFileFieldMultiTS)) - self.assertTrue(len(fmts0_6)==3 and fmts0_6.getIterations()==[(1,-1),(6,-6),(9,-9)]) - fmts0_7=fmts0_4[::-3] - self.assertTrue(isinstance(fmts0_7,MEDFileFieldMultiTS)) - self.assertTrue(len(fmts0_7)==4 and fmts0_7.getIterations()==[(10,-10),(7,-7),(4,-4),(1,-1)]) - # - fs0=MEDFileFields() - fs0.pushField(fmts0_0) - fmts0_2.setName("2ndField") ; fs0.pushField(fmts0_2) - fmts0_3.setName("3rdField") ; fs0.pushField(fmts0_3) - fmts0_4.setName("4thField") ; fs0.pushField(fmts0_4) - self.assertTrue(len(fs0)==4 and fs0.getFieldsNames()==('1stField','2ndField','3rdField','4thField')) - fs0.write(fname,2) - fs0=MEDFileFields(fname) - self.assertEqual(fs0.getCommonIterations(),([(2,-2),(4,-4),(8,-8)],True)) - fs1=fs0.partOfThisLyingOnSpecifiedTimeSteps(fs0.getCommonIterations()[0]) - self.assertTrue(fs1.getFieldsNames()==('1stField','2ndField','3rdField','4thField') and fs1.getCommonIterations()==([(2,-2),(4,-4),(8,-8)],False)) - del fs1[["2ndField",3]] - self.assertTrue(fs1.getFieldsNames()==('1stField','3rdField') and fs1.getCommonIterations()==([(2,-2),(4,-4),(8,-8)],False)) - fs2=fs0[[0,"4thField"]] - self.assertTrue(isinstance(fs2,MEDFileFields)) - self.assertEqual(fs2.getFieldsNames(),('1stField','4thField')) - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,0) - pass - - # Multi time steps and multi fields management with Globals (profiles, locs) aspects - def testMEDFileFields3(self): - fname="Pyfile66.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) - # - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - pfl2=DataArrayInt([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfl2") - fmts0_0=MEDFileFieldMultiTS() - fmts0_1=MEDFileFieldMultiTS() - # time steps - for i in xrange(10): - infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" - d=DataArrayDouble(14) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - fmts0_0.appendFieldProfile(f,mm,0,pfl) - f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl) ; fmts0_1.pushBackTimeStep(f1ts) - self.assertEqual(fmts0_0.getInfo(),('aa [bb]','ccc [ddd]')) - self.assertEqual(fmts0_1.getInfo(),('aa [bb]','ccc [ddd]')) - pass - # - self.assertEqual(fmts0_0.getPfls(),10*('pfl_NORM_QUAD4',)) - self.assertEqual(fmts0_1.getPfls(),('pfl_NORM_QUAD4',)) - fmts0_0.zipPflsNames() - self.assertEqual(fmts0_0.getPfls(),('pfl_NORM_QUAD4',)) - self.assertTrue(fmts0_1.getProfile("pfl_NORM_QUAD4").isEqual(fmts0_0.getProfile("pfl_NORM_QUAD4"))) - fmts0_2=fmts0_0.deepCpy() - fmts0_3=fmts0_0.deepCpy() - fmts0_4=fmts0_0.deepCpy() - fs0=MEDFileFields() - fs0.pushField(fmts0_0) - fmts0_2.setName("2ndField") ; fs0.pushField(fmts0_2) - fmts0_3.setName("3rdField") ; fs0.pushField(fmts0_3) - fmts0_4.setName("4thField") ; fs0.pushField(fmts0_4) - self.assertEqual(fs0.getPfls(),('pfl_NORM_QUAD4',)) - # - fmts0_5=MEDFileFieldMultiTS() - for i in xrange(7): - infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" - d=DataArrayDouble(16) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl2) ; fmts0_5.pushBackTimeStep(f1ts) - pass - fmts0_5.setName("5thField") ; fs0.pushField(fmts0_5) - self.assertEqual(fs0.getPfls(),('pfl_NORM_QUAD4','pfl2_NORM_QUAD4')) - fs0.checkGlobsCoherency() - fs0.write(fname,0) - pass - - def testSplitComponents1(self): - fname="Pyfile67.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) - # - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - pfl2=DataArrayInt([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfl2") - fs=MEDFileFields() - fmts0_1=MEDFileFieldMultiTS() - # time steps - infos1=['aa [bb]','ccc [ddd]',"ZZZZ [MW*s]"] - for i in xrange(10): - name1="1stField" - d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl) ; fmts0_1.pushBackTimeStep(f1ts) - self.assertEqual(fmts0_1.getInfo(),tuple(infos1)) - pass - fs.pushField(fmts0_1) - self.assertEqual(1,len(fs)) - l=fmts0_1.splitComponents() - self.assertEqual(3,len(l)) - for elt in l: self.assertEqual(10,len(elt)) - for elt in l: self.assertTrue(isinstance(elt,MEDFileFieldMultiTS)) - for elt in l: - elt.setName("%s_%s"%(elt.getName(),DataArray.GetVarNameFromInfo(elt.getInfo()[0]))) - pass - fs.pushFields(l) - self.assertEqual(4,len(fs)) - for elt in fs: self.assertEqual(10,len(elt)) - self.assertEqual(fs.getPfls(),('pfl_NORM_QUAD4',)) - self.assertEqual(fs.getPflsReallyUsed(),('pfl_NORM_QUAD4',)) - # - fs.write(fname,0) ; del fs - # - fs1=MEDFileFields(fname) - self.assertEqual(fs1.getPfls(),('pfl_NORM_QUAD4',)) - self.assertEqual(fs1.getPflsReallyUsed(),('pfl_NORM_QUAD4',)) - self.assertEqual(4,len(fs1)) - for i in xrange(10): - for j,fieldName in enumerate(['1stField_aa','1stField_ccc','1stField_ZZZZ']): - f1ts=fs1[fieldName][i] - f=f1ts.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d=d[:,j] ; d.setInfoOnComponent(0,infos1[j]) - self.assertTrue(d.isEqual(f.getArray(),1e-13)) - pass - f1ts=fs1["1stField"][i] - f=f1ts.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d.setInfoOnComponents(infos1) - self.assertTrue(d.isEqual(f.getArray(),1e-13)) - pass - pass - - def testMEDFileFieldConvertTo1(self): - fname="Pyfile68.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) - # - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCell") - f0.checkCoherency() - ff0.setFieldNoProfileSBT(f0) - # - fspExp=[(3,[(0,(0,4),'','')]),(4,[(0,(4,9),'','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - # - ff0i=ff0.convertToInt() - self.assertEqual(ff0i.getFieldSplitedByType(),fspExp) - self.assertTrue(arr.convertToIntArr().isEqual(ff0i.getUndergroundDataArray())) - # - ff1=ff0i.convertToDouble() - self.assertTrue(ff1.getUndergroundDataArray().isEqual(ff0.getUndergroundDataArray(),1e-13)) - self.assertEqual(ff1.getFieldSplitedByType(),fspExp) - # With profiles - del arr,f0,ff0,ff1,ff0i,fspExp - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["XX [pm]","YYY [hm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellPfl") - f0.checkCoherency() - pfl=DataArrayInt.Range(0,7,1) ; pfl.setName("pfl") - ff0.setFieldProfile(f0,mm,0,pfl) - fspExp=[(3,[(0,(0,4),'','')]),(4,[(0,(4,7),'pfl_NORM_QUAD4','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - # - ff0i=ff0.convertToInt() - self.assertTrue(isinstance(ff0i,MEDFileIntField1TS)) - self.assertEqual(ff0i.getFieldSplitedByType(),fspExp) - self.assertTrue(arr.convertToIntArr().isEqual(ff0i.getUndergroundDataArray())) - # - ff1=ff0i.convertToDouble() - self.assertTrue(isinstance(ff1,MEDFileField1TS)) - self.assertTrue(ff1.getUndergroundDataArray().isEqual(ff0.getUndergroundDataArray(),1e-13)) - self.assertEqual(ff1.getFieldSplitedByType(),fspExp) - ## MultiTimeSteps - ff0=MEDFileFieldMultiTS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(0.1,0,10) - f0.checkCoherency() - ff0.appendFieldProfile(f0,mm,0,pfl) - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota(100) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(1.1,1,11) - f0.checkCoherency() - ff0.appendFieldProfile(f0,mm,0,pfl) - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota(200) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(2.1,2,12) - f0.checkCoherency() - ff0.appendFieldProfile(f0,mm,0,pfl) - ff1=ff0.convertToInt() - self.assertTrue(isinstance(ff1,MEDFileIntFieldMultiTS)) - self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) - for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): - self.assertEqual(ff1.getFieldSplitedByType(dt,it),fspExp) - arr=ff1.getUndergroundDataArray(dt,it) - arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1)) - pass - self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4', 'pfl_NORM_QUAD4', 'pfl_NORM_QUAD4')) - # - mm.write(fname,2) - ff1.write(fname,0) - # - ff1=ff1.convertToDouble() - self.assertTrue(isinstance(ff1,MEDFileFieldMultiTS)) - self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) - for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): - self.assertEqual(ff1.getFieldSplitedByType(dt,it),fspExp) - arr=ff1.getUndergroundDataArray(dt,it) - arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1).convertToDblArr(),1e-14) - pass - self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4', 'pfl_NORM_QUAD4', 'pfl_NORM_QUAD4')) - # - ff1=MEDFileAnyTypeFieldMultiTS.New(fname,"FieldCellMTime") - self.assertTrue(isinstance(ff1,MEDFileIntFieldMultiTS)) - self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) - for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): - self.assertTrue(ff1.getFieldSplitedByType(dt,it),fspExp) - arr=ff1.getUndergroundDataArray(dt,it) - arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1)) - pass - self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4',)) - pass - - def testMEDFileFieldPartialLoading(self): - fname="Pyfile69.med" - # - a=DataArrayInt() ; aa=a.getHeapMemorySize() - a.alloc(0,1) - strMulFac=a.getHeapMemorySize()-aa ; del a ; del aa - # building a mesh containing 30 tri3 + 40 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(30)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(40)] - for i,elt in enumerate(quads): elt.translate([40+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) - # - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCell") - f0.checkCoherency() - ff0.setFieldNoProfileSBT(f0) - ff0.write(fname,0) - # - fspExp=[(3,[(0,(0,30),'','')]),(4,[(0,(30,70),'','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - # With profiles - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:50]) ; arr=DataArrayDouble(50*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["XX [pm]","YYY [hm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellPfl") - f0.checkCoherency() - pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") - ff0.setFieldProfile(f0,mm,0,pfl) - fspExp=[(3,[(0,(0,30),'','')]),(4,[(0,(30,50),'pfl_NORM_QUAD4','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - ff0.write(fname,0) - # - ff0=MEDFileField1TS(fname,False) - self.assertEqual(ff0.getName(),"FieldCell") - self.assertTrue(not ff0.getUndergroundDataArray().isAllocated()) - self.assertEqual(ff0.getUndergroundDataArray().getInfoOnComponents(),['X [km]','YY [mm]']) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(182,298+2*strMulFac)) - ff0.loadArrays() ## - arr=DataArrayDouble(140) ; arr.iota() ; arr.rearrange(2) - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,70*8*2) - # - ff0=MEDFileField1TS(fname,"FieldCellPfl",False) - self.assertEqual(ff0.getUndergroundDataArray().getInfoOnComponents(),["XX [pm]","YYY [hm]"]) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(350,415+6*strMulFac)) - ff0.loadArrays() ## - arr=DataArrayDouble(100) ; arr.iota() ; arr.rearrange(2) - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) - ff0.loadArrays() ## - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) - ff0.getUndergroundDataArray().setIJ(30,1,5.5) - self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - ff0.loadArrays() ## - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - ff0.getUndergroundDataArray().setIJ(30,1,5.5) - self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - ff0.loadArraysIfNecessary() ## - self.assertEqual(ff0.getUndergroundDataArray().getIJ(30,1),5.5) - self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(1100,1215+2*strMulFac)) - ff0.unloadArrays() - hmd=ff0.getHeapMemorySize()-heap_memory_ref - self.assertEqual(hmd,-800) # -50*8*2 - ff0.loadArrays() ## - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,0) - # - ff0=MEDFileField1TS(fname,"FieldCellPfl",-1,-1,False) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(299,415+6*strMulFac)) - ff0.loadArrays() ## - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) - # - fieldName="FieldCellMultiTS" - ff0=MEDFileFieldMultiTS() - for t in xrange(20): - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota(float(t+1000)) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName(fieldName) - f0.setTime(float(t)+0.1,t,100+t) - f0.checkCoherency() - ff0.appendFieldNoProfileSBT(f0) - pass - ff0.write(fname,0) - # - ff0=MEDFileAnyTypeFieldMultiTS.New(fname,fieldName,False) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(5536,5956+(80+26)*strMulFac)) - ff0.loadArrays() - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,20*70*8*2) - del ff0 - # - ffs=MEDFileFields(fname,False) - heap_memory_ref=ffs.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(5335,6687+(80+50)*strMulFac)) - ffs.loadArrays() - self.assertEqual(ffs.getHeapMemorySize()-heap_memory_ref,20*70*8*2+70*8*2+50*8*2) - pass - - def testMEDFileMeshReadSelector1(self): - mrs=MEDFileMeshReadSelector() - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs.__str__() ; mrs.__repr__() - # - mrs=MEDFileMeshReadSelector(0) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(1) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(2) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(3) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(4) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(5) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(6) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(7) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(8) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(9) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(10) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(11) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(12) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(13) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(14) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(15) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(16) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(17) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(18) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(19) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(20) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(21) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(22) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(23) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(24) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(25) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(26) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(27) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(28) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(29) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(30) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(31) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(32) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(33) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(34) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(35) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(36) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(37) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(38) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(39) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(40) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(41) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(42) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(43) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(44) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(45) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(46) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(47) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(48) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(49) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(50) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(51) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(52) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(53) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(54) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(55) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(56) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(57) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(58) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(59) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(60) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(61) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(62) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(63) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - # - mrs=MEDFileMeshReadSelector(63) - mrs.setCellFamilyFieldReading(False) - self.assertEqual(mrs.getCode(),62) - mrs.setCellFamilyFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setNodeFamilyFieldReading(False) - self.assertEqual(mrs.getCode(),61) - mrs.setNodeFamilyFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setCellNameFieldReading(False) - self.assertEqual(mrs.getCode(),59) - mrs.setCellNameFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setNodeNameFieldReading(False) - self.assertEqual(mrs.getCode(),55) - mrs.setNodeNameFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setCellNumFieldReading(False) - self.assertEqual(mrs.getCode(),47) - mrs.setCellNumFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setNodeNumFieldReading(False) - self.assertEqual(mrs.getCode(),31) - mrs.setNodeNumFieldReading(True) - self.assertEqual(mrs.getCode(),63) - pass - - def testPartialReadOfMeshes(self): - fname="Pyfile70.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - grp0=DataArrayInt([1,2,3,5,6]) ; grp0.setName("grp0") - grp1=DataArrayInt([1,2,3,5,7,8]) ; grp1.setName("grp1") - mm.setGroupsAtLevel(0,[grp0,grp1]) - grp2=DataArrayInt.Range(0,32,2) ; grp2.setName("grp2") - grp3=DataArrayInt.Range(1,32,7) ; grp3.setName("grp3") - mm.setGroupsAtLevel(-1,[grp2,grp3]) - grp4=DataArrayInt.Range(0,32,2) ; grp4.setName("grp4") - grp5=DataArrayInt.Range(1,32,7) ; grp5.setName("grp5") - mm.setGroupsAtLevel(1,[grp4,grp5]) - mm.setRenumFieldArr(0,DataArrayInt.Range(2,11,1)) - mm.setRenumFieldArr(-1,DataArrayInt.Range(3,35,1)) - mm.setRenumFieldArr(1,DataArrayInt.Range(4,36,1)) - # - mm.write(fname,2) - ## - mm=MEDFileMesh.New(fname,"mesh",-1,-1,MEDFileMeshReadSelector()) - b4_ref_heap_mem=mm.getHeapMemorySize() - mm.getMeshAtLevel(0)## please let this line : force to move 1GTUMesh -> UMesh - mm.getMeshAtLevel(-1)## please let this line : force to move 1GTUMesh -> UMesh - ref_heap_mem=mm.getHeapMemorySize() - # check the gain of memory using 1GTUMesh instead of UMesh - self.assertTrue(ref_heap_mem-b4_ref_heap_mem>=(32+9)*4*2-32)# 32+9=nbCells 4=sizeof(int) 2=the types+index -32=loss linked to vector - # - mm=MEDFileMesh.New(fname,MEDFileMeshReadSelector(0)) - self.assertEqual(len(mm.getGroupsNames()),0) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0) is None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1) is None) - self.assertTrue(mm.getFamilyFieldAtLevel(1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(0) is None) - self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta1=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta1>=4*(32+9)*3+32*4*3) - # - mm=MEDFileMesh.New(fname,MEDFileMeshReadSelector(1)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(0) is None) - self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta2=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta2<delta1) - self.assertTrue(delta2>=4*(32+9)*1+32*4*3) - # - mm=MEDFileUMesh(fname,MEDFileMeshReadSelector(3)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(0) is None) - self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta3=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta3<delta2) - self.assertTrue(delta3>=4*(32+9)*1+32*4*1) - # - mm=MEDFileUMesh(fname,"mesh",-1,-1,MEDFileMeshReadSelector(19)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(0)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(-1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta4=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta4<delta3) - self.assertTrue(delta4>=32*4*2) - # - mm=MEDFileUMesh.New(fname,"mesh",-1,-1,MEDFileMeshReadSelector(51)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(0)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(-1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(1)!=None) - delta5=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta5<delta4) - self.assertEqual(delta5,0) - pass - - # this test checks that setFieldProfile perform a check of the array length - # compared to the profile length. This test also checks that mesh attribute of field - # is not used by setFieldProfile (because across this test mesh is equal to None) - def testCheckCompatibilityPfl1(self): - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_NODES) - vals=DataArrayDouble(7) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - f1ts.setFieldProfile(f,mm,0,pfl) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_NODES) - vals=DataArrayDouble(8) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_CELLS) - vals=DataArrayDouble(7) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - vals=DataArrayDouble(27) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") - f.setMesh(m[pfl]) - f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.1,0.1],[0.3,0.6,0.1]) - f.setGaussLocalizationOnCells([2],[0.,0.,1.,0.,1.,1.],[0.3,0.3],[1.]) - f.setGaussLocalizationOnCells([3,4,5,6],[0.,0.,1.,0.,1.,1.,0.,1.],[0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.5,0.5],[0.2,0.3,0.4,0.07,0.03]) - f.setMesh(None) - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - vals=DataArrayDouble(26) ; vals.iota(1040) ; f.setArray(vals) - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - vals=DataArrayDouble(27) ; vals.iota(1000) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_GAUSS_NE) - vals=DataArrayDouble(25) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - vals2=DataArrayDouble(26) ; vals2.iota(1050) - f.setArray(vals2) - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - # - f1ts=MEDFileField1TS() - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - f.setArray(vals) - f1ts.setFieldProfile(f,mm,0,pfl) - pass - - def testWRMeshWithNoCells(self): - fname="Pyfile71.med" - a=DataArrayDouble(4) ; a.iota() - c=MEDCouplingCMesh() ; c.setCoords(a,a) ; m0=c.buildUnstructured() - m00=MEDCouplingUMesh("mesh",1) ; m00.setCoords(m0.getCoords()) ; m00.allocateCells(0) - m=MEDFileUMesh() - m.setMeshAtLevel(0,m00) - m.setRenumFieldArr(1,DataArrayInt(range(10,26))) - m.setFamilyFieldArr(1,DataArrayInt([-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,0,-1,-3,-3,-3])) - m.write(fname,2) - del m,a,c,m0,m00 - # - m=MEDFileMesh.New(fname) - self.assertEqual((),m.getNonEmptyLevels()) - self.assertTrue(m.getCoords().isEqual(DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2),(0,3),(1,3),(2,3),(3,3)]),1e-12)) - self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt(range(10,26)))) - self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,0,-1,-3,-3,-3]))) - pass - - def testWRQPolyg1(self): - fname="Pyfile72.med" - m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.allocateCells() - m.insertNextCell([0,2,1,3]) - m.setCoords(DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) - # - ms=[m.deepCpy() for i in xrange(4)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,0.]) - pass - m0=MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms).buildUnstructured() - m0.convertAllToPoly() - # - ms=[m.deepCpy() for i in xrange(5)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,1.5]) - pass - m1=MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms).buildUnstructured() - m1.convertAllToPoly() - m1.convertLinearCellsToQuadratic() - # - m=MEDCouplingUMesh.MergeUMeshes(m0,m1) - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - grp0=DataArrayInt([0,2,3]) ; grp0.setName("grp0") - grp1=DataArrayInt([4,6,7]) ; grp1.setName("grp1") - grp2=DataArrayInt([0,1,2,4,5,6]) ; grp2.setName("grp2") - mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) - ## - mm.write(fname,2) - del mm - # - mm_read=MEDFileUMesh(fname) - self.assertTrue(mm_read.getGroupArr(0,"grp0").isEqual(grp0)) - self.assertTrue(mm_read.getGroupArr(0,"grp1").isEqual(grp1)) - self.assertTrue(mm_read.getGroupArr(0,"grp2").isEqual(grp2)) - self.assertTrue(mm_read.getMeshAtLevel(0).isEqual(m,1e-12)) - ## - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName("MyFirstField") - f.setMesh(m) - arr0=DataArrayDouble(9) ; arr0.iota() - arr1=DataArrayDouble(9) ; arr1.iota(100) - arr=DataArrayDouble.Meld(arr0,arr1) ; arr.setInfoOnComponents(["mm [kg]","sds [m]"]) - f.setArray(arr) ; f.checkCoherency() - f.setTime(5.6,1,2) - ff=MEDFileField1TS() - ff.setFieldNoProfileSBT(f) - ff.write(fname,0) - ## - ff_read=MEDFileField1TS(fname) - f_read=ff_read.getFieldOnMeshAtLevel(ON_CELLS,0,mm_read) - self.assertTrue(f_read.isEqual(f,1e-12,1e-12)) - pass - - def testLoadIfNecessaryOnFromScratchFields0(self): - """ - This test checks that a call to loadArraysIfNecessary works (does nothing) on field data structure whatever its level 1TS, MTS, Fields. - """ - fname="Pyfile77.med" - coords=DataArrayDouble([(0,0,0),(2,1,0),(1,0,0),(1,1,0),(2,0,0),(0,1,0)]) - m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_QUAD4,[0,5,3,2]) - m.insertNextCell(NORM_QUAD4,[4,2,3,1]) - m.finishInsertingCells() - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) - ms=MEDFileMeshes() ; ms.pushMesh(mm) - fs=MEDFileFields() - arrs=4*[None] - # - ff0=MEDFileFieldMultiTS() ; fs.pushField(ff0) - f0=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f0.setMesh(m) ; f0.setTimeUnit("ms") - f0.setTime(1.1,1,1) - f0.setName("myELNOField") - arrs[0]=DataArrayDouble([7,5,3,1,5,3,1,7]) ; arrs[0].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[0]) - ff0.appendFieldNoProfileSBT(f0) - # - f0.setTime(2.2,2,1) - arrs[1]=DataArrayDouble([1,7,5,3,7,5,3,1]) ; arrs[1].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[1]) - ff0.appendFieldNoProfileSBT(f0) - # - f0.setTime(3.3,3,1) - arrs[2]=DataArrayDouble([3,1,7,5,1,7,5,3]) ; arrs[2].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[2]) - ff0.appendFieldNoProfileSBT(f0) - # - f0.setTime(4.4,4,1) - arrs[3]=DataArrayDouble([5,3,1,7,3,1,7,5]) ; arrs[3].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[3]) - ff0.appendFieldNoProfileSBT(f0) - # - for i,arr in enumerate(arrs): - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - fs[0][i].loadArraysIfNecessary() - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - fs.loadArraysIfNecessary() - for i,arr in enumerate(arrs): - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - fs[0].loadArraysIfNecessary() - for i,arr in enumerate(arrs): - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - pass - - def testField1TSSetFieldNoProfileSBTPerGeoTypes(self): - """ This test is very important, because the same mechanism is used by the MEDReader to generate a field on all the mesh without any processing and memory. - """ - fname="Pyfile78.med" - coords=DataArrayDouble([-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ],9,3) - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - m0=MEDCouplingUMesh("mesh",3) ; m0.setCoords(coords) - m0.allocateCells() - for elt in [[0,1,2,3],[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7],[5,6,7,8]]:#6 - m0.insertNextCell(NORM_TETRA4,elt) - pass - for elt in [[0,1,2,3,4],[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8]]:#5 - m0.insertNextCell(NORM_PYRA5,elt) - pass - for elt in [[0,1,2,3,4,5],[1,2,3,4,5,6],[2,3,4,5,6,7],[3,4,5,6,7,8]]:#4 - m0.insertNextCell(NORM_PENTA6,elt) - pass - m0.checkCoherency2() - m1=MEDCouplingUMesh(); m1.setName("mesh") - m1.setMeshDimension(2); - m1.allocateCells(5); - m1.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - m1.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - m1.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - m1.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - m1.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - m1.setCoords(coords); - m3=MEDCouplingUMesh("mesh",0) ; m3.setCoords(coords) - m3.allocateCells() - m3.insertNextCell(NORM_POINT1,[2]) - m3.insertNextCell(NORM_POINT1,[3]) - m3.insertNextCell(NORM_POINT1,[4]) - m3.insertNextCell(NORM_POINT1,[5]) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setMeshAtLevel(-1,m1) - mm.setMeshAtLevel(-3,m3) - mm.write(fname,2) - #### The file is written only with one mesh and no fields. Let's put a field on it geo types per geo types. - mm=MEDFileMesh.New(fname) - fs=MEDFileFields() - fmts=MEDFileFieldMultiTS() - f1ts=MEDFileField1TS() - for lev in mm.getNonEmptyLevels(): - for gt in mm.getGeoTypesAtLevel(lev): - p0=mm.getDirectUndergroundSingleGeoTypeMesh(gt) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(p0) - arr=DataArrayDouble(f.getNumberOfTuplesExpected()) ; arr.iota() - f.setArray(arr) ; f.setName("f0") - f1ts.setFieldNoProfileSBT(f) - pass - pass - self.assertEqual(mm.getNonEmptyLevels(),(0,-1,-3)) - for lev in [0,-1,-3]: - mm.getDirectUndergroundSingleGeoTypeMeshes(lev) # please let this line, it is for the test to emulate that - pass - fmts.pushBackTimeStep(f1ts) - fs.pushField(fmts) - fs.write(fname,0) - del fs,fmts,f1ts - #### The file contains now one mesh and one cell field with all cells wathever their level ang type fetched. - fs=MEDFileFields(fname) - self.assertEqual(len(fs),1) - self.assertEqual(len(fs[0]),1) - f1ts=fs[0][0] - self.assertEqual(f1ts.getFieldSplitedByType(),[(0,[(0,(0,4),'','')]),(3,[(0,(4,6),'','')]),(4,[(0,(6,9),'','')]),(14,[(0,(9,15),'','')]),(15,[(0,(15,20),'','')]),(16,[(0,(20,24),'','')])]) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0,1,2,3,0,1,0,1,2,0,1,2,3,4,5,0,1,2,3,4,0,1,2,3]),1e-12)) - pass - - def testMEDFileUMeshSetName(self): - """ This test is a small but important one for MEDReader in sauv mode. When .sauv file is loaded the convertion is performed in memory and a preparation is done then. - This preparation makes access to internal MEDCouplingMesh pointers whose name must be updated. - """ - fname="Pyfile79.med" - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - mm=MEDFileUMesh() - m0=MEDCouplingUMesh() ; m0.setMeshDimension(2) # important no name here. - coords=DataArrayDouble([-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ],9,3) - m0.allocateCells(5); - m0.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - m0.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - m0.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - m0.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - m0.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - m0.setCoords(coords); - mm.setMeshAtLevel(0,m0) - m2=MEDCouplingUMesh() ; m2.setMeshDimension(0) ; m2.setCoords(coords) # important no name here. - m2.allocateCells() - m2.insertNextCell(NORM_POINT1,[2]) - m2.insertNextCell(NORM_POINT1,[3]) - m2.insertNextCell(NORM_POINT1,[4]) - m2.insertNextCell(NORM_POINT1,[5]) - mm.setMeshAtLevel(-2,m2) - self.assertEqual(mm.getName(),"") - self.assertEqual(mm.getMeshAtLevel(0).getName(),"") - mm.forceComputationOfParts() - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_TRI3).getName(),"") - mm.setName("abc") - self.assertEqual(mm.getName(),"abc") - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_TRI3).getName(),"abc") - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getName(),"abc") - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_POINT1).getName(),"abc") - self.assertEqual(mm.getMeshAtLevel(0).getName(),"abc") - pass - - def testMEDFileFieldsUnloadArraysWithoutDataLoss1(self): - fileName="Pyfile80.med" - m=MEDCouplingCMesh() ; m.setName("cmesh") - arr=DataArrayDouble(6) ; arr.iota() - m.setCoords(arr,arr) - nbCells=m.getNumberOfCells() - self.assertEqual(25,nbCells) - f=MEDCouplingFieldDouble(ON_CELLS) - f.setName("FieldOnCell") ; f.setMesh(m) - arr=DataArrayDouble(nbCells) ; arr.iota() - mm=MEDFileCMesh() - mm.setMesh(m) - # - fmts=MEDFileFieldMultiTS() - # - for i in xrange(nbCells): - t=(float(i)+0.1,i+1,-i-2) - f.setTime(*t) - arr2=DataArrayDouble(nbCells) - perm=DataArrayInt(nbCells) ; perm.iota(i) ; perm%=nbCells - arr2[perm]=arr - f.setArray(arr2) - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - fmts.pushBackTimeStep(f1ts) - pass - fmts.unloadArraysWithoutDataLoss() - self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fs=MEDFileFields() ; fs.pushField(fmts) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fs.unloadArraysWithoutDataLoss() - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - f1ts=fs[0][0] - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - f1ts.unloadArraysWithoutDataLoss() - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - mm.write(fileName,2) - fs.write(fileName,0) - del m,fmts,mm,f,f1ts - ## - mm=MEDFileMesh.New(fileName) - fmts=MEDFileFieldMultiTS(fileName) - self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fmts.unloadArraysWithoutDataLoss() - self.assertTrue(not fmts[0].getUndergroundDataArray().isAllocated()) - fmts.loadArraysIfNecessary() - self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - del mm,fmts - fs=MEDFileFields(fileName) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fs.unloadArraysWithoutDataLoss() - self.assertTrue(not fs[0][0].getUndergroundDataArray().isAllocated()) - fs.loadArraysIfNecessary() - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - del fs - f1ts=MEDFileField1TS(fileName) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - f1ts.unloadArraysWithoutDataLoss() - self.assertTrue(not f1ts.getUndergroundDataArray().isAllocated()) - f1ts.loadArraysIfNecessary() - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - pass - - def testMEDFileUMeshLoadPart1(self): - """ This method tests MEDFileUMesh.LoadPart that loads only a part of a specified mesh in a MED file. The part is specfied using a slice of cell ids. Only nodes on which cells lies are loaded to reduce at most the amount of - memory of the returned instance. - """ - fileName="Pyfile81.med" - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName("Mesh") - m.changeSpaceDimension(3,0.) - infos=["aa [b]","cc [de]","gg [klm]"] - m.getCoords().setInfoOnComponents(infos) - m.checkCoherency2() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - m1=MEDCouplingCMesh() ; m1.setCoords(arr) ; m1.setName("Mesh") - m1=m1.buildUnstructured() ; m1.setCoords(m.getCoords()) - mm.setMeshAtLevel(-1,m1) - renum0=DataArrayInt([3,6,7,10,11,0,2,1,9,8,5,4,12,13,14,24,23,22,21,20,19,18,17,16,15]) - famField0=DataArrayInt([-3,-6,-7,-10,-11,0,-2,-1,-9,-8,-5,-4,-12,-13,-14,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15]) - namesCellL0=DataArrayAsciiChar(25,16) - namesCellL0[:]=["Cell#%.3d "%(i) for i in xrange(25)] - renumM1=DataArrayInt([3,4,0,2,1]) - famFieldM1=DataArrayInt([-3,-4,0,-2,-1]) - mm.setRenumFieldArr(0,renum0) - mm.setFamilyFieldArr(0,famField0) - mm.setNameFieldAtLevel(0,namesCellL0) - mm.setRenumFieldArr(-1,renumM1) - mm.setFamilyFieldArr(-1,famFieldM1) - renum1=DataArrayInt([13,16,17,20,21,10,12,11,19,18,15,14,22,23,24,34,33,32,31,30,29,28,27,26,25,45,44,43,42,41,40,39,38,37,36,35]) - famField1=DataArrayInt([-13,-16,-17,-20,-21,-10,-12,-11,-19,-18,-15,-14,-22,-23,-24,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35]) - namesNodes=DataArrayAsciiChar(36,16) - namesNodes[:]=["Node#%.3d "%(i) for i in xrange(36)] - mm.setRenumFieldArr(1,renum1) - mm.setFamilyFieldArr(1,famField1) - mm.setNameFieldAtLevel(1,namesNodes) - mm.setFamilyId("Fam7",77) - mm.setFamilyId("Fam8",88) - mm.setGroupsOnFamily("Fam7",["Grp0","Grp1"]) - mm.setGroupsOnFamily("Fam8",["Grp1","Grp2"]) - mm.write(fileName,2) - # - mm0=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[0,10,1]) - self.assertEqual(mm0.getAllGeoTypes(),[NORM_QUAD4]) - self.assertTrue(mm0.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17]))) - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos) - self.assertTrue(mm0.getCoords().isEqual(coo,1e-12)) - self.assertTrue(mm0.getFamilyFieldAtLevel(0).isEqual(famField0[:10])) - self.assertTrue(mm0.getNumberFieldAtLevel(0).isEqual(renum0[:10])) - self.assertTrue(mm0.getNameFieldAtLevel(0).isEqual(namesCellL0[:10])) - self.assertTrue(mm0.getFamilyFieldAtLevel(1).isEqual(famField1[:18])) - self.assertTrue(mm0.getNumberFieldAtLevel(1).isEqual(renum1[:18])) - self.assertTrue(mm0.getNameFieldAtLevel(1).isEqual(namesNodes[:18])) - # - mm1=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[11,25,1]) - self.assertEqual(mm1.getAllGeoTypes(),[NORM_QUAD4]) - self.assertTrue(mm1.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,6,5,11,12,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,12,11,17,18,13,12,18,19,14,13,19,20,15,14,20,21,16,15,21,22]))) - coo=DataArrayDouble([(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(5,3,0),(0,4,0),(1,4,0),(2,4,0),(3,4,0),(4,4,0),(5,4,0),(0,5,0),(1,5,0),(2,5,0),(3,5,0),(4,5,0),(5,5,0)]) ; coo.setInfoOnComponents(infos) - self.assertTrue(mm1.getCoords().isEqual(coo,1e-12)) - self.assertTrue(mm1.getFamilyFieldAtLevel(0).isEqual(famField0[11:])) - self.assertTrue(mm1.getNumberFieldAtLevel(0).isEqual(renum0[11:])) - self.assertTrue(mm1.getNameFieldAtLevel(0).isEqual(namesCellL0[11:])) - self.assertTrue(mm1.getFamilyFieldAtLevel(1).isEqual(famField1[13:])) - self.assertTrue(mm1.getNumberFieldAtLevel(1).isEqual(renum1[13:])) - self.assertTrue(mm1.getNameFieldAtLevel(1).isEqual(namesNodes[13:])) - # - mm2=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_SEG2,NORM_QUAD4],[0,5,1,1,10,1]) - self.assertEqual(mm2.getAllGeoTypes(),[NORM_QUAD4,NORM_SEG2]) - self.assertTrue(mm2.getFamilyFieldAtLevel(0).isEqual(famField0[1:10])) - self.assertTrue(mm2.getNumberFieldAtLevel(0).isEqual(renum0[1:10])) - self.assertTrue(mm2.getNameFieldAtLevel(0).isEqual(namesCellL0[1:10])) - self.assertTrue(mm2.getFamilyFieldAtLevel(-1).isEqual(famFieldM1)) - self.assertTrue(mm2.getNumberFieldAtLevel(-1).isEqual(renumM1)) - self.assertTrue(mm2.getNameFieldAtLevel(-1) is None) - self.assertTrue(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17]))) - self.assertTrue(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_SEG2).getNodalConnectivity().isEqual(DataArrayInt([0,1,1,2,2,3,3,4,4,5]))) - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos) - self.assertTrue(mm2.getCoords().isEqual(coo,1e-12)) - self.assertTrue(mm2.getFamilyFieldAtLevel(1).isEqual(famField1[:18])) - self.assertTrue(mm2.getNumberFieldAtLevel(1).isEqual(renum1[:18])) - self.assertTrue(mm2.getNameFieldAtLevel(1).isEqual(namesNodes[:18])) - pass - - def testMEDFileFieldsLoadPart1(self): - """This method tests partial loading on fields on CELL. It is the same principle than those in testMEDFileUMeshLoadPart1. - """ - fileName="Pyfile82.med" - meshName="Mesh" - compos=["aa [kg]","bbb [m/s]"] - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName(meshName) - m.changeSpaceDimension(3,0.) - infos=["aa [b]","cc [de]","gg [klm]"] - m.getCoords().setInfoOnComponents(infos) - m.checkCoherency2() - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) - f.setName("Field") - arr=DataArrayDouble(25,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(25) - arr[:,1]=range(100,125) - f.setArray(arr) - MEDLoader.WriteField(fileName,f,2) - f=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; f.setMesh(m) - f.setName("FieldNode") - arr=DataArrayDouble(36,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(200,236) - arr[:,1]=range(300,336) - f.setArray(arr) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f) - # - ms=MEDFileMeshes() - mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[0,6,1]) - ms.pushMesh(mm) - fs=MEDFileFields.LoadPartOf(fileName,False,ms) - self.assertEqual(fs[1][0].getFieldSplitedByType(),[(40,[(1,(0,14),'','')])]) - # - ms=MEDFileMeshes() - mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[3,15,1]) - ms.pushMesh(mm) - fs=MEDFileFields.LoadPartOf(fileName,False,ms) - fs=fs.deepCpy() - fs[0][0].loadArrays() - arr=DataArrayDouble(12,2) ; arr[:,0]=range(3,15) ; arr[:,1]=range(103,115) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(arr,1e-12)) - fs[1][0].loadArrays() - arr=DataArrayDouble(21,2) ; arr[:,0]=range(203,224) ; arr[:,1]=range(303,324) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - - def testMEDFileWithoutCells1(self): - fileName="Pyfile83.med" - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) - coo.setInfoOnComponents(["aa [m]","bbb [s]","cccc [m/s]"]) - mm=MEDFileUMesh() - mm.setCoords(coo) - mm.setName("mesh") - mm.write(fileName,2) - # - mm=MEDFileMesh.New(fileName) - self.assertEqual(mm.getName(),"mesh") - self.assertTrue(mm.getCoords().isEqual(coo,1e-12)) - pass - - def testZipCoordsWithLoadPart1(self): - """ Test close to Pyfile82.med except that here zipCoords on MEDFileUMesh is invoked here to see if the PartDef is correctly updated. - """ - fileName="Pyfile84.med" - meshName="Mesh" - compos=["aa [kg]","bbb [m/s]"] - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName(meshName) - m.changeSpaceDimension(3,0.) - infos=["aa [b]","cc [de]","gg [klm]"] - m.getCoords().setInfoOnComponents(infos) - m.checkCoherency2() - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) - f.setName("Field") - arr=DataArrayDouble(25,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(25) - arr[:,1]=range(100,125) - f.setArray(arr) - MEDLoader.WriteField(fileName,f,2) - f=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; f.setMesh(m) - f.setName("FieldNode") - arr=DataArrayDouble(36,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(200,236) - arr[:,1]=range(300,336) - f.setArray(arr) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f) - # - ms=MEDFileMeshes() - mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[4,6,1]) - ms.pushMesh(mm) - spd=mm.getPartDefAtLevel(0,NORM_QUAD4) - self.assertEqual(spd.getSlice(),slice(4,6,1)) - spd=mm.getPartDefAtLevel(1) - self.assertEqual(spd.getSlice(),slice(4,14,1)) - self.assertTrue(spd.getNumberOfElems()==10 and spd.getNumberOfElems()==mm.getNumberOfNodes()) - mm.zipCoords() # <- The important line is here ! - spd=mm.getPartDefAtLevel(0,NORM_QUAD4) - self.assertEqual(spd.getSlice(),slice(4,6,1)) - spd=mm.getPartDefAtLevel(1) - self.assertTrue(spd.getNumberOfElems()==8 and spd.getNumberOfElems()==mm.getNumberOfNodes()) - self.assertTrue(spd.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13]))) - fs=MEDFileFields.LoadPartOf(fileName,False,ms) - fs[0][0].loadArrays() - arr=DataArrayDouble([(4,104),(5,105)]) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(arr,1e-12)) - fs[1][0].loadArrays() - arr=DataArrayDouble([(204,304),(205,305),(206,306),(207,307),(210,310),(211,311),(212,312),(213,313)]) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - - def testMEDFileCMeshSetGroupsAtLevel(self): - """ Non regression test to check that setGroupsAtLevel is available with MEDFileCMesh. - """ - m=MEDCouplingCMesh() ; m.setCoords(DataArrayDouble([0,1,2,3,4]),DataArrayDouble([0,1,2,3,4])) - m.setName("Mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) - grp=DataArrayInt([1,3,4,5,7]) ; grp.setName("MyAssembly") - mm.setGroupsAtLevel(0,[grp]) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-1,-2,-1,-2,-2,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1]))) - pass - - def testMEDFileUMeshBuildExtrudedMesh1(self): - """ New functionality of MEDFileUMesh.buildExtrudedMesh.""" - fileName="Pyfile85.med" - meshName2D="Mesh" - meshName1D="Mesh1D" - meshName3DOut="Mesh3D" - # - d1=DataArrayInt([0,4,20,24]) - d2=DataArrayInt([0,1,2,3,7,8,12,13,17,18,19,20]) - # - a=DataArrayDouble(6) ; a.iota() - m=MEDCouplingCMesh() ; m.setCoords(a,a) - m=m.buildUnstructured() - d1c=d1.buildComplement(m.getNumberOfCells()) - m=m[d1c] ; m.zipCoords() - m0=m[d2] ; m1=m[d2.buildComplement(m.getNumberOfCells())] - m0.simplexize(0) - m=MEDCouplingUMesh.MergeUMeshesOnSameCoords([m0,m1]) - m.setName(meshName2D) - mMinus1,a,b,c,d=m.buildDescendingConnectivity() - e=d.deltaShiftIndex().getIdsEqual(1) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) ; mm.setMeshAtLevel(-1,mMinus1) - grp0=DataArrayInt([0,1,2,3,4,5,24,25,26]) ; grp0.setName("grp0") - mm.setGroupsAtLevel(0,[grp0]) - grp1=e ; grp1.setName("grp1") - mm.setGroupsAtLevel(-1,[grp1]) - mm.write(fileName,2) - # - a=DataArrayDouble(3) ; a.iota() - tmp=MEDCouplingCMesh() ; tmp.setCoords(a) ; tmp=tmp.buildUnstructured() - tmp.setName(meshName1D) - tmp.changeSpaceDimension(3) - tmp.setCoords(tmp.getCoords()[:,[1,2,0]]) - mm1D=MEDFileUMesh() - mm1D.setMeshAtLevel(0,tmp) - mm1D.write(fileName,0) - # test is here ! - mm2D=MEDFileMesh.New(fileName,meshName2D) - mm1D=MEDFileMesh.New(fileName,meshName1D) - m1D=mm1D.getMeshAtLevel(0) - mm3D=mm2D.buildExtrudedMesh(m1D,0) - # - self.assertEqual(mm3D.getName(),mm2D.getName()) - self.assertEqual(mm3D.getNumberOfCellsAtLevel(0),66) - self.assertEqual(mm3D.getNumberOfCellsAtLevel(-1),194) - self.assertEqual(mm3D.getGroupsNames(),('grp0','grp0_extruded','grp0_top','grp1','grp1_extruded','grp1_top')) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0"),(-1,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0_top"),(-1,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0_extruded"),(0,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1"),(-2,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1_top"),(-2,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1_extruded"),(-1,)) - d=DataArrayDouble([(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(4.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(4.,1.,0.),(5.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(4.,2.,0.),(5.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.),(4.,3.,0.),(5.,3.,0.),(0.,4.,0.),(1.,4.,0.),(2.,4.,0.),(3.,4.,0.),(4.,4.,0.),(5.,4.,0.),(1.,5.,0.),(2.,5.,0.),(3.,5.,0.),(4.,5.,0.),(1.,0.,1.),(2.,0.,1.),(3.,0.,1.),(4.,0.,1.),(0.,1.,1.),(1.,1.,1.),(2.,1.,1.),(3.,1.,1.),(4.,1.,1.),(5.,1.,1.),(0.,2.,1.),(1.,2.,1.),(2.,2.,1.),(3.,2.,1.),(4.,2.,1.),(5.,2.,1.),(0.,3.,1.),(1.,3.,1.),(2.,3.,1.),(3.,3.,1.),(4.,3.,1.),(5.,3.,1.),(0.,4.,1.),(1.,4.,1.),(2.,4.,1.),(3.,4.,1.),(4.,4.,1.),(5.,4.,1.),(1.,5.,1.),(2.,5.,1.),(3.,5.,1.),(4.,5.,1.),(1.,0.,2.),(2.,0.,2.),(3.,0.,2.),(4.,0.,2.),(0.,1.,2.),(1.,1.,2.),(2.,1.,2.),(3.,1.,2.),(4.,1.,2.),(5.,1.,2.),(0.,2.,2.),(1.,2.,2.),(2.,2.,2.),(3.,2.,2.),(4.,2.,2.),(5.,2.,2.),(0.,3.,2.),(1.,3.,2.),(2.,3.,2.),(3.,3.,2.),(4.,3.,2.),(5.,3.,2.),(0.,4.,2.),(1.,4.,2.),(2.,4.,2.),(3.,4.,2.),(4.,4.,2.),(5.,4.,2.),(1.,5.,2.),(2.,5.,2.),(3.,5.,2.),(4.,5.,2.)]) - self.assertTrue(mm3D.getCoords().isEqual(d,1e-12)) - d=DataArrayInt([16,1,0,5,33,32,37,16,1,5,6,33,37,38,16,2,1,6,34,33,38,16,2,6,7,34,38,39,16,3,2,7,35,34,39,16,3,7,8,35,39,40,16,5,4,10,37,36,42,16,5,10,11,37,42,43,16,9,8,14,41,40,46,16,9,14,15,41,46,47,16,11,10,16,43,42,48,16,11,16,17,43,48,49,16,15,14,20,47,46,52,16,15,20,21,47,52,53,16,17,16,22,49,48,54,16,17,22,23,49,54,55,16,21,20,26,53,52,58,16,21,26,27,53,58,59,16,24,23,28,56,55,60,16,24,28,29,56,60,61,16,25,24,29,57,56,61,16,25,29,30,57,61,62,16,26,25,30,58,57,62,16,26,30,31,58,62,63,16,33,32,37,65,64,69,16,33,37,38,65,69,70,16,34,33,38,66,65,70,16,34,38,39,66,70,71,16,35,34,39,67,66,71,16,35,39,40,67,71,72,16,37,36,42,69,68,74,16,37,42,43,69,74,75,16,41,40,46,73,72,78,16,41,46,47,73,78,79,16,43,42,48,75,74,80,16,43,48,49,75,80,81,16,47,46,52,79,78,84,16,47,52,53,79,84,85,16,49,48,54,81,80,86,16,49,54,55,81,86,87,16,53,52,58,85,84,90,16,53,58,59,85,90,91,16,56,55,60,88,87,92,16,56,60,61,88,92,93,16,57,56,61,89,88,93,16,57,61,62,89,93,94,16,58,57,62,90,89,94,16,58,62,63,90,94,95,18,6,5,11,12,38,37,43,44,18,7,6,12,13,39,38,44,45,18,8,7,13,14,40,39,45,46,18,12,11,17,18,44,43,49,50,18,13,12,18,19,45,44,50,51,18,14,13,19,20,46,45,51,52,18,18,17,23,24,50,49,55,56,18,19,18,24,25,51,50,56,57,18,20,19,25,26,52,51,57,58,18,38,37,43,44,70,69,75,76,18,39,38,44,45,71,70,76,77,18,40,39,45,46,72,71,77,78,18,44,43,49,50,76,75,81,82,18,45,44,50,51,77,76,82,83,18,46,45,51,52,78,77,83,84,18,50,49,55,56,82,81,87,88,18,51,50,56,57,83,82,88,89,18,52,51,57,58,84,83,89,90]) - self.assertTrue(mm3D[0].getNodalConnectivity().isEqual(d)) - d=DataArrayInt([0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,345,354,363,372,381,390,399,408,417,426,435,444,453,462,471,480,489,498]) - self.assertTrue(mm3D[0].getNodalConnectivityIndex().isEqual(d)) - d=DataArrayInt([3,1,0,5,3,1,5,6,3,2,1,6,3,2,6,7,3,3,2,7,3,3,7,8,3,5,4,10,3,5,10,11,3,9,8,14,3,9,14,15,3,11,10,16,3,11,16,17,3,15,14,20,3,15,20,21,3,17,16,22,3,17,22,23,3,21,20,26,3,21,26,27,3,24,23,28,3,24,28,29,3,25,24,29,3,25,29,30,3,26,25,30,3,26,30,31,3,65,64,69,3,65,69,70,3,66,65,70,3,66,70,71,3,67,66,71,3,67,71,72,3,69,68,74,3,69,74,75,3,73,72,78,3,73,78,79,3,75,74,80,3,75,80,81,3,79,78,84,3,79,84,85,3,81,80,86,3,81,86,87,3,85,84,90,3,85,90,91,3,88,87,92,3,88,92,93,3,89,88,93,3,89,93,94,3,90,89,94,3,90,94,95,4,1,0,32,33,4,0,5,37,32,4,5,1,33,37,4,5,6,38,37,4,6,1,33,38,4,2,1,33,34,4,6,2,34,38,4,6,7,39,38,4,7,2,34,39,4,3,2,34,35,4,7,3,35,39,4,7,8,40,39,4,8,3,35,40,4,5,4,36,37,4,4,10,42,36,4,10,5,37,42,4,10,11,43,42,4,11,5,37,43,4,9,8,40,41,4,8,14,46,40,4,14,9,41,46,4,14,15,47,46,4,15,9,41,47,4,10,16,48,42,4,16,11,43,48,4,16,17,49,48,4,17,11,43,49,4,14,20,52,46,4,20,15,47,52,4,20,21,53,52,4,21,15,47,53,4,16,22,54,48,4,22,17,49,54,4,22,23,55,54,4,23,17,49,55,4,20,26,58,52,4,26,21,53,58,4,26,27,59,58,4,27,21,53,59,4,24,23,55,56,4,23,28,60,55,4,28,24,56,60,4,28,29,61,60,4,29,24,56,61,4,25,24,56,57,4,29,25,57,61,4,29,30,62,61,4,30,25,57,62,4,26,25,57,58,4,30,26,58,62,4,30,31,63,62,4,31,26,58,63,4,11,12,44,43,4,12,6,38,44,4,12,13,45,44,4,13,7,39,45,4,13,14,46,45,4,17,18,50,49,4,18,12,44,50,4,18,19,51,50,4,19,13,45,51,4,19,20,52,51,4,24,18,50,56,4,25,19,51,57,4,33,32,64,65,4,32,37,69,64,4,37,33,65,69,4,37,38,70,69,4,38,33,65,70,4,34,33,65,66,4,38,34,66,70,4,38,39,71,70,4,39,34,66,71,4,35,34,66,67,4,39,35,67,71,4,39,40,72,71,4,40,35,67,72,4,37,36,68,69,4,36,42,74,68,4,42,37,69,74,4,42,43,75,74,4,43,37,69,75,4,41,40,72,73,4,40,46,78,72,4,46,41,73,78,4,46,47,79,78,4,47,41,73,79,4,42,48,80,74,4,48,43,75,80,4,48,49,81,80,4,49,43,75,81,4,46,52,84,78,4,52,47,79,84,4,52,53,85,84,4,53,47,79,85,4,48,54,86,80,4,54,49,81,86,4,54,55,87,86,4,55,49,81,87,4,52,58,90,84,4,58,53,85,90,4,58,59,91,90,4,59,53,85,91,4,56,55,87,88,4,55,60,92,87,4,60,56,88,92,4,60,61,93,92,4,61,56,88,93,4,57,56,88,89,4,61,57,89,93,4,61,62,94,93,4,62,57,89,94,4,58,57,89,90,4,62,58,90,94,4,62,63,95,94,4,63,58,90,95,4,43,44,76,75,4,44,38,70,76,4,44,45,77,76,4,45,39,71,77,4,45,46,78,77,4,49,50,82,81,4,50,44,76,82,4,50,51,83,82,4,51,45,77,83,4,51,52,84,83,4,56,50,82,88,4,57,51,83,89,4,6,5,11,12,4,7,6,12,13,4,8,7,13,14,4,12,11,17,18,4,13,12,18,19,4,14,13,19,20,4,18,17,23,24,4,19,18,24,25,4,20,19,25,26,4,70,69,75,76,4,71,70,76,77,4,72,71,77,78,4,76,75,81,82,4,77,76,82,83,4,78,77,83,84,4,82,81,87,88,4,83,82,88,89,4,84,83,89,90]) - self.assertTrue(mm3D[-1].getNodalConnectivity().isEqual(d)) - d=DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,197,202,207,212,217,222,227,232,237,242,247,252,257,262,267,272,277,282,287,292,297,302,307,312,317,322,327,332,337,342,347,352,357,362,367,372,377,382,387,392,397,402,407,412,417,422,427,432,437,442,447,452,457,462,467,472,477,482,487,492,497,502,507,512,517,522,527,532,537,542,547,552,557,562,567,572,577,582,587,592,597,602,607,612,617,622,627,632,637,642,647,652,657,662,667,672,677,682,687,692,697,702,707,712,717,722,727,732,737,742,747,752,757,762,767,772,777,782,787,792,797,802,807,812,817,822,827,832,837,842,847,852,857,862,867,872,877,882,887,892,897,902,907,912,917,922]) - self.assertTrue(mm3D[-1].getNodalConnectivityIndex().isEqual(d)) - d=DataArrayInt([1,1,0,1,0,5,1,5,1,1,5,6,1,6,1,1,2,1,1,6,2,1,6,7,1,7,2,1,3,2,1,7,3,1,7,8,1,8,3,1,5,4,1,4,10,1,10,5,1,10,11,1,11,5,1,9,8,1,8,14,1,14,9,1,14,15,1,15,9,1,10,16,1,16,11,1,16,17,1,17,11,1,14,20,1,20,15,1,20,21,1,21,15,1,16,22,1,22,17,1,22,23,1,23,17,1,20,26,1,26,21,1,26,27,1,27,21,1,24,23,1,23,28,1,28,24,1,28,29,1,29,24,1,25,24,1,29,25,1,29,30,1,30,25,1,26,25,1,30,26,1,30,31,1,31,26,1,11,12,1,12,6,1,12,13,1,13,7,1,13,14,1,17,18,1,18,12,1,18,19,1,19,13,1,19,20,1,24,18,1,25,19,1,65,64,1,64,69,1,69,65,1,69,70,1,70,65,1,66,65,1,70,66,1,70,71,1,71,66,1,67,66,1,71,67,1,71,72,1,72,67,1,69,68,1,68,74,1,74,69,1,74,75,1,75,69,1,73,72,1,72,78,1,78,73,1,78,79,1,79,73,1,74,80,1,80,75,1,80,81,1,81,75,1,78,84,1,84,79,1,84,85,1,85,79,1,80,86,1,86,81,1,86,87,1,87,81,1,84,90,1,90,85,1,90,91,1,91,85,1,88,87,1,87,92,1,92,88,1,92,93,1,93,88,1,89,88,1,93,89,1,93,94,1,94,89,1,90,89,1,94,90,1,94,95,1,95,90,1,75,76,1,76,70,1,76,77,1,77,71,1,77,78,1,81,82,1,82,76,1,82,83,1,83,77,1,83,84,1,88,82,1,89,83]) - self.assertTrue(mm3D[-2].getNodalConnectivity().isEqual(d)) - d=DataArrayInt(129) ; d.iota() ; d*=3 - self.assertTrue(mm3D[-2].getNodalConnectivityIndex().isEqual(d)) - # - self.assertEqual(mm3D.getGroupArr(-1,"grp0").getName(),"grp0") - self.assertEqual(mm3D.getGroupArr(-2,"grp1").getName(),"grp1") - self.assertTrue(mm3D.getGroupArr(-1,"grp0").isEqualWithoutConsideringStr(DataArrayInt([0,1,2,3,4,5,176,177,178]))) - self.assertTrue(mm3D.getGroupArr(-1,"grp0_top").isEqualWithoutConsideringStr(DataArrayInt([24,25,26,27,28,29,185,186,187]))) - self.assertTrue(mm3D.getGroupArr(-2,"grp1").isEqualWithoutConsideringStr(DataArrayInt([0,1,5,9,12,13,14,18,22,23,30,31,33,37,38,40,42,46,50,51]))) - self.assertTrue(mm3D.getGroupArr(-2,"grp1_top").isEqualWithoutConsideringStr(DataArrayInt([64,65,69,73,76,77,78,82,86,87,94,95,97,101,102,104,106,110,114,115]))) - self.assertTrue(mm3D.getGroupArr(0,"grp0_extruded").isEqualWithoutConsideringStr(DataArrayInt([0,1,2,3,4,5,24,25,26,27,28,29,48,49,50,57,58,59]))) - self.assertTrue(mm3D.getGroupArr(-1,"grp1_extruded").isEqualWithoutConsideringStr(DataArrayInt([48,49,53,57,60,61,62,66,70,71,78,79,81,85,86,88,90,94,98,99,112,113,117,121,124,125,126,130,134,135,142,143,145,149,150,152,154,158,162,163]))) - mm3D.setName("MeshExtruded") - mm3D.write(fileName,0) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def testMEDFileUMeshPickeling1(self): - import cPickle - outFileName="Pyfile86.med" - c=DataArrayDouble([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2) - c.setInfoOnComponents(["aa","bbb"]) - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - m=MEDCouplingUMesh(); - m.setMeshDimension(2); - m.allocateCells(5); - m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - m.insertNextCell(NORM_POLYGON,4,targetConn[10:14]) - m.insertNextCell(NORM_POLYGON,4,targetConn[14:18]) - m.finishInsertingCells(); - m.setCoords(c) - m.checkCoherency() - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(1); - m1.allocateCells(3); - m1.insertNextCell(NORM_SEG2,2,[1,4]) - m1.insertNextCell(NORM_SEG2,2,[3,6]) - m1.insertNextCell(NORM_SEG3,3,[2,8,5]) - m1.finishInsertingCells(); - m1.setCoords(c) - m1.checkCoherency() - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(0); - m2.allocateCells(4); - m2.insertNextCell(NORM_POINT1,1,[1]) - m2.insertNextCell(NORM_POINT1,1,[3]) - m2.insertNextCell(NORM_POINT1,1,[2]) - m2.insertNextCell(NORM_POINT1,1,[6]) - m2.finishInsertingCells(); - m2.setCoords(c) - m2.checkCoherency() - # - mm=MEDFileUMesh.New() - self.assertTrue(mm.getUnivNameWrStatus()) - mm.setName("MyFirstMEDCouplingMEDmesh") - mm.setDescription("IHopeToConvinceLastMEDMEMUsers") - mm.setCoords(c) - mm[-1]=m1; - mm[0]=m; - mm.setRenumFieldArr(0,DataArrayInt([32,41,50,56,7])) - mm[-2]=m2; - mm.setRenumFieldArr(-2,DataArrayInt([102,52,45,63])) - # playing with groups - g1_2=DataArrayInt.New() - g1_2.setValues([1,3],2,1) - g1_2.setName("G1") - g2_2=DataArrayInt.New() - g2_2.setValues([1,2,3],3,1) - g2_2.setName("G2") - mm.setGroupsAtLevel(0,[g1_2,g2_2],False) - g1_1=DataArrayInt.New() - g1_1.setValues([0,1,2],3,1) - g1_1.setName("G1") - g2_1=DataArrayInt.New() - g2_1.setValues([0,2],2,1) - g2_1.setName("G2") - mm.setGroupsAtLevel(-1,[g1_1,g2_1],False) - g1_N=DataArrayInt.New() - g1_N.setValues(range(8),8,1) - g1_N.setName("G1") - g2_N=DataArrayInt.New() - g2_N.setValues(range(9),9,1) - g2_N.setName("G2") - mm.setGroupsAtLevel(1,[g1_N,g2_N],False) - mm.createGroupOnAll(0,"GrpOnAllCell") - # check content of mm - t=mm.getGroupArr(0,"G1",False) - self.assertTrue(g1_2.isEqual(t)); - t=mm.getGroupArr(0,"G2",False) - self.assertTrue(g2_2.isEqual(t)); - t=mm.getGroupArr(-1,"G1",False) - self.assertTrue(g1_1.isEqual(t)); - t=mm.getGroupArr(-1,"G2",False) - self.assertTrue(g2_1.isEqual(t)); - t=mm.getGroupArr(1,"G1",False) - self.assertTrue(g1_N.isEqual(t)); - t=mm.getGroupArr(1,"G2",False) - self.assertTrue(g2_N.isEqual(t)); - self.assertTrue(mm.existsGroup("GrpOnAllCell")); - t=mm.getGroupArr(0,"GrpOnAllCell") - # - st=cPickle.dumps(mm,cPickle.HIGHEST_PROTOCOL) - mm2=cPickle.loads(st) - self.assertTrue(mm.isEqual(mm2,1e-12)[0]) - pass - - def testMEDFileFieldsLoadSpecificEntities1(self): - nbNodes=11 - fieldName="myField" - fileName="Pyfile87.med" - nbPdt=10 - meshName="Mesh" - # - m=MEDCouplingCMesh() - arr=DataArrayDouble(nbNodes) ; arr.iota() - m.setCoords(arr) - m=m.buildUnstructured() - m.setName(meshName) - # - fmts=MEDFileFieldMultiTS() - for i in xrange(nbPdt): - f=MEDCouplingFieldDouble(ON_NODES) - f.setMesh(m) - arr=DataArrayDouble(nbNodes) ; arr.iota() ; arr*=i - f.setArray(arr) - f.setName(fieldName) - f.setTime(float(i),i,0) - fmts.appendFieldNoProfileSBT(f) - pass - # - mm=MEDFileUMesh() ; mm[0]=m - fmts.write(fileName,2) - mm.write(fileName,0) - # - fs=MEDFileFields(fileName,False) - fs2=MEDFileFields.LoadSpecificEntities(fileName,[(ON_NODES,NORM_ERROR)],False) - fs.loadArraysIfNecessary() - fs2.loadArraysIfNecessary() - for i in xrange(nbPdt): - self.assertTrue(fs[fieldName][i].getUndergroundDataArray().isEqual(fs2[fieldName][i].getUndergroundDataArray(),1e-12)) - pass - m1=MEDCouplingCMesh() ; m1.setCoords(DataArrayDouble([0,1,2,3]),DataArrayDouble([0,1])) ; m1=m1.buildUnstructured() ; m1.simplexize(0) - m2=MEDCouplingCMesh() ; m2.setCoords(DataArrayDouble([3,4,5]),DataArrayDouble([0,1])) ; m2=m2.buildUnstructured() - m3=MEDCouplingUMesh.MergeUMeshes(m1,m2) ; m3.setName(meshName) - fmts=MEDFileFieldMultiTS() - for i in xrange(nbPdt): - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m3) - arr=DataArrayDouble(8) ; arr.iota() ; arr*=i - f.setArray(arr) - f.setName(fieldName) - f.setTime(float(i),i,0) - fmts.appendFieldNoProfileSBT(f) - pass - mm=MEDFileUMesh() ; mm[0]=m3 - del mm[0] - self.assertEqual(mm.getNonEmptyLevels(),()) - mm[0]=m3 - self.assertEqual(mm.getNonEmptyLevels(),(0,)) - fmts.write(fileName,2) - fs=MEDFileFields(fileName,False) - fs2=MEDFileFields.LoadSpecificEntities(fileName,[(ON_CELLS,NORM_TRI3)],False) - fs3=MEDFileFieldMultiTS.LoadSpecificEntities(fileName,fieldName,[(ON_CELLS,NORM_QUAD4)],False) - fs4=MEDFileFields.LoadSpecificEntities(fileName,[(ON_CELLS,NORM_TRI3),(ON_CELLS,NORM_QUAD4)],False) - fs.loadArraysIfNecessary() - fs2.loadArraysIfNecessary() - fs3.loadArraysIfNecessary() - fs4.loadArraysIfNecessary() - for i in xrange(nbPdt): - self.assertTrue(fs[fieldName][i].getUndergroundDataArray()[:6].isEqual(fs2[fieldName][i].getUndergroundDataArray(),1e-12)) - self.assertTrue(fs[fieldName][i].getUndergroundDataArray()[6:8].isEqual(fs3[i].getUndergroundDataArray(),1e-12)) - self.assertTrue(fs[fieldName][i].getUndergroundDataArray().isEqual(fs4[fieldName][i].getUndergroundDataArray(),1e-12)) - pass - pass - - def testMEDFileLotsOfTSRW1(self): - nbNodes=11 - fieldName="myField" - fileName="Pyfile88.med" - nbPdt=300 # <- perftest = 30000 - meshName="Mesh" - # - maxPdt=100 # <- optimum = 500 - m=MEDCouplingCMesh() - arr=DataArrayDouble(nbNodes) ; arr.iota() - m.setCoords(arr) - m=m.buildUnstructured() - m.setName(meshName) - # - nbOfField=nbPdt/maxPdt - fs=MEDFileFields() - for j in xrange(nbOfField): - fmts=MEDFileFieldMultiTS() - s=DataArray.GetSlice(slice(0,nbPdt,1),j,nbOfField) - for i in xrange(s.start,s.stop,s.step): - f=MEDCouplingFieldDouble(ON_NODES) - f.setMesh(m) - arr=DataArrayDouble(nbNodes) ; arr.iota() ; arr*=i - f.setArray(arr) - f.setName("%s_%d"%(fieldName,j)) - f.setTime(float(i),i,0) - fmts.appendFieldNoProfileSBT(f) - pass - fs.pushField(fmts) - pass - # - mm=MEDFileUMesh() ; mm[0]=m - fs.write(fileName,2) - mm.write(fileName,0) - ############ - def appendInDict(d,key,val): - if key in d: - d[key].append(val) - else: - d[key]=[val] - pass - import re - allFields=MEDLoader.GetAllFieldNames(fileName) - allFieldsDict={} - pat=re.compile("([\d]+)([\s\S]+)$") - for st in allFields: - stRev=st[::-1] - m=pat.match(stRev) - if m: - appendInDict(allFieldsDict,m.group(2)[::-1],m.group(1)[::-1]) - pass - else: - appendInDict(allFieldsDict,st,'') - pass - pass - fs2=MEDFileFields() - for k in allFieldsDict: - if allFieldsDict[k]!=['']: - allFieldsDict[k]=sorted(allFieldsDict[k],key=lambda x: int(x)) - pass - fmts2=[] - for it in allFieldsDict[k]: - fmts2.append(MEDFileFieldMultiTS.LoadSpecificEntities(fileName,k+it,[(ON_NODES,NORM_ERROR)])) - pass - fmts2.reverse() - zeResu=fmts2.pop() - nbIter=len(fmts2) - for ii in xrange(nbIter): - zeResu.pushBackTimeSteps(fmts2.pop()) - pass - zeResu.setName(k) - fs2.pushField(zeResu) - pass - self.assertEqual(fs2[0].getTimeSteps(),[(i,0,float(i)) for i in xrange(nbPdt)]) - pass - - def testMEDFileMeshRearrangeFamIds1(self): - """ Test for bug EDF10720. The aim of this test is the call of MEDFileMesh.rearrangeFamilies.""" - fileName="Pyfile89.med" - meshName='Maillage_2' - mm=MEDFileUMesh() - coords=DataArrayDouble([(0.,0.,0.),(0.,0.,200.),(0.,200.,200.),(0.,200.,0.),(200.,0.,0.),(200.,0.,200.),(200.,200.,200.),(200.,200.,0.),(0.,0.,100.),(0.,100.,200.),(0.,200.,100.),(0.,100.,0.),(200.,0.,100.),(200.,100.,200.),(200.,200.,100.),(200.,100.,0.),(100.,0.,0.),(100.,0.,200.),(100.,200.,0.),(100.,200.,200.),(0.,116.87743909766768,83.12256090233232),(200.,116.87743909766768,83.12256090233232),(116.87743909766769,0.,116.87743909766769),(116.87743909766769,200.,116.87743909766769),(116.87743909766769,116.87743909766769,0.),(116.87743909766769,116.87743909766769,200.),(63.3851584383713,56.1391811199829,119.728314479261),(138.008709441123,116.039297556044,119.903790959468)]) - # - c0=DataArrayInt([14,1,26,9,8,14,17,26,1,8,14,27,26,17,22,14,26,16,20,8,14,8,0,16,11,14,16,20,11,24,14,25,20,26,27,14,22,26,24,27,14,26,16,22,24,14,8,26,22,17,14,20,9,25,26,14,19,20,25,23,14,23,6,27,25,14,19,23,10,20,14,27,22,21,24,14,27,21,14,18,14,26,9,25,17,14,13,27,25,17,14,27,18,24,21,14,22,21,15,12,14,27,20,24,18,14,23,25,27,20,14,13,27,6,25,14,23,27,6,14,14,15,16,22,12,14,27,17,13,22,14,22,27,21,13,14,24,16,22,15,14,24,18,7,21,14,12,4,15,16,14,22,12,5,13,14,8,26,16,22,14,13,27,21,14,14,20,18,10,3,14,14,27,18,23,14,14,27,6,13,14,21,22,13,12,14,25,26,17,27,14,19,9,25,20,14,26,24,20,16,14,22,24,15,21,14,9,26,1,17,14,23,27,18,20,14,20,11,18,3,14,14,18,21,7,14,19,2,9,10,14,19,23,25,6,14,18,23,20,10,14,20,26,8,9,14,22,13,5,17,14,24,11,18,20,14,21,15,7,24,14,19,20,10,9,14,20,26,27,24,14,16,8,11,20]) - c0i=DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275]) - m0=MEDCouplingUMesh(meshName,3) ; m0.setCoords(coords) - m0.setConnectivity(c0,c0i) - mm[0]=m0 - # - c1=DataArrayInt([3,8,20,11,3,8,9,20,3,9,2,10,3,20,9,10,3,0,8,11,3,9,8,1,3,20,10,3,3,11,20,3,3,15,21,12,3,5,12,13,3,21,13,12,3,15,12,4,3,14,6,13,3,14,13,21,3,7,14,21,3,7,21,15,3,5,22,12,3,4,12,16,3,17,1,8,3,16,8,0,3,5,17,22,3,12,22,16,3,22,17,8,3,16,22,8,3,10,2,19,3,7,18,14,3,14,23,6,3,3,10,18,3,23,19,6,3,18,23,14,3,10,19,23,3,10,23,18,3,3,18,11,3,7,24,18,3,15,4,16,3,11,16,0,3,7,15,24,3,18,24,11,3,24,15,16,3,11,24,16,3,9,19,2,3,19,25,6,3,17,5,13,3,1,17,9,3,25,13,6,3,9,25,19,3,17,13,25,3,17,25,9]) - c1i=DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192]) - m1=MEDCouplingUMesh(meshName,2) ; m1.setCoords(coords) - m1.setConnectivity(c1,c1i) - mm[-1]=m1 - # - c2=DataArrayInt([0,8,8,1,1,9,9,2,3,10,10,2,0,11,11,3,4,12,12,5,5,13,13,6,7,14,14,6,4,15,15,7,0,16,16,4,1,17,17,5,3,18,18,7,2,19,19,6]) - m2=MEDCoupling1SGTUMesh(meshName,NORM_SEG2) - m2.setNodalConnectivity(c2) ; m2.setCoords(coords) - mm[-2]=m2.buildUnstructured() - # - ref0=DataArrayInt(55) ; ref0[:]=0 - mm.setFamilyFieldArr(0,ref0) - mm.setFamilyFieldArr(1,DataArrayInt([0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])) - ref1=DataArrayInt([0,0,0,0,0,0,0,0,-6,-6,-6,-6,-6,-6,-6,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - mm.setFamilyFieldArr(-1,ref1) - ref2=DataArrayInt([0,0,-7,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - mm.setFamilyFieldArr(-2,ref2) - # - for f,fid in (('FAMILLE_ZERO',0),('FAM_-6_Groupe_1',-6),('FAM_-7_Groupe_2',-7),('FAM_2_Groupe_3',2)): - mm.setFamilyId(f,fid) - for grp,fams in [('Groupe_1',('FAM_-6_Groupe_1',)),('Groupe_2',('FAM_-7_Groupe_2',)),('Groupe_3',('FAM_2_Groupe_3',))]: - mm.setFamiliesOnGroup(grp,fams) - mm.write(fileName,2) - # - mm=MEDFileMesh.New(fileName) - grp=mm.getGroup(-1,"Groupe_1") - dai=grp.computeFetchedNodeIds() - dai.setName("TOTO") - mm.addGroup(1,dai) - mm.rearrangeFamilies() # <- the aim of the test - self.assertTrue(dai.isEqual(mm.getGroupArr(1,"TOTO"))) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(ref0)) - self.assertTrue(mm.getFamilyFieldAtLevel(-1).isEqual(ref1)) - self.assertTrue(mm.getFamilyFieldAtLevel(-2).isEqual(ref2)) - self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([0,0,2,0,9,9,9,9,0,0,0,0,9,9,9,9,0,0,0,0,0,9,0,0,0,0,0,0]))) - allGrps=[('Groupe_1',('FAM_-6_Groupe_1',)),('Groupe_2',('FAM_-7_Groupe_2',)),('Groupe_3',('FAM_2_Groupe_3',)),('TOTO',('Family_9',))] - allFams=[('FAMILLE_ZERO',0),('FAM_-6_Groupe_1',-6),('FAM_-7_Groupe_2',-7),('FAM_2_Groupe_3',2),('Family_9',9)] - self.assertEqual(list(mm.getGroupsNames()),[elt[0] for elt in allGrps]) - for elt,fams in allGrps: - self.assertEqual(mm.getFamiliesOnGroup(elt),fams) - self.assertEqual(list(mm.getFamiliesNames()),[elt[0] for elt in allFams]) - for elt,eltId in allFams: - self.assertEqual(mm.getFamilyId(elt),eltId) - pass - - def testNonRegrCMeshSetFieldPfl1(self): - """ Non regression test. For structured mesh, push a false partial field in MEDFileField1TS using setFieldProfile.""" - ff=MEDFileField1TS() - meshName="mesh" - mm=MEDFileCMesh() - m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr) - m.setName(meshName) - mm.setMesh(m) - field=MEDCouplingFieldDouble(ON_CELLS) - field.setMesh(m) - field.setArray(DataArrayDouble([1.2,2.3,3.4,4.5])) - field.setName("Field") - field.checkCoherency() - pfl=DataArrayInt([0,1,2,3]) ; pfl.setName("TUTU") #<- false profile because defined on all cells ! - ff.setFieldProfile(field,mm,0,pfl) # <- bug was revealed here ! - self.assertEqual(ff.getPfls(),()) - field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - self.assertTrue(field.isEqual(field2,1e-12,1e-12)) - del ff,mm,field,field2,pfl - # same with unstructured mesh - ff=MEDFileField1TS() - meshName="mesh" - mm=MEDFileUMesh() - m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr) - m.setName(meshName) - m=m.buildUnstructured() - mm[0]=m - field=MEDCouplingFieldDouble(ON_CELLS) - field.setMesh(m) - field.setArray(DataArrayDouble([1.2,2.3,3.4,4.5])) - field.setName("Field") - field.checkCoherency() - pfl=DataArrayInt([0,1,2,3]) ; pfl.setName("TUTU") - ff.setFieldProfile(field,mm,0,pfl) - self.assertEqual(ff.getPfls(),()) - field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - self.assertTrue(field.isEqual(field2,1e-12,1e-12)) - pass - - def testMEDFileUMeshLinearToQuadraticAndRev1(self): - meshName="mesh" - fileName="Pyfile90.med" - fileName2="Pyfile91.med" - arr=DataArrayDouble(5) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - d=DataArrayInt([3,7,11,15]) - m1=m[d] - m1.simplexize(0) - m2=m[d.buildComplement(m.getNumberOfCells())] - m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) - m.changeSpaceDimension(3,0.) - arr=DataArrayDouble(3) ; arr.iota() - m1D=MEDCouplingCMesh() ; m1D.setCoords(arr) ; m1D=m1D.buildUnstructured() ; m1D.changeSpaceDimension(3,0.) - m1D.setCoords(m1D.getCoords()[:,[1,2,0]]) - delta=m.getNumberOfNodes()*(m1D.getNumberOfNodes()-1) - m3D=m.buildExtrudedMesh(m1D,0) - m3D.sortCellsInMEDFileFrmt() - m3D.setName(meshName) - m2D=m ; m2D.setCoords(m3D.getCoords()) ; m2D.shiftNodeNumbersInConn(delta) ; m2D.setName(meshName) ; m2D.checkCoherency2() - m1D=m2D.computeSkin() ; m1D.setName(meshName) - m0D=MEDCouplingUMesh.Build0DMeshFromCoords(m3D.getCoords()) ; m0D.setName(meshName) ; m0D=m0D[[2,4,10]] - # - mm=MEDFileUMesh() - mm[0]=m3D ; mm[-1]=m2D ; mm[-2]=m1D ; mm[-3]=m0D - grpEdge0=DataArrayInt([1,2,3,5]) ; grpEdge0.setName("East") - grpEdge1=DataArrayInt([0,1]) ; grpEdge1.setName("Corner1") - grpFaceSouth=DataArrayInt([0,1,8,9,10]) ; grpFaceSouth.setName("SouthFace") - grpFaceNorth=DataArrayInt([6,7,17,18,19]) ; grpFaceNorth.setName("NorthFace") - diagFace=DataArrayInt([0,1,13,15,17]) ; diagFace.setName("DiagFace") - vol1=DataArrayInt([20,21,23,24]) ; vol1.setName("vol1") - vol2=DataArrayInt([2,3,4,5,21,24]) ; vol2.setName("vol2") - mm.setGroupsAtLevel(0,[vol1,vol2]) - mm.setGroupsAtLevel(-1,[grpFaceSouth,grpFaceNorth,diagFace]) - mm.setGroupsAtLevel(-2,[grpEdge0,grpEdge1]) - # - mmOut1=mm.linearToQuadratic(0,0.) - mmOut1.write(fileName2,2) - mmOut2=mmOut1.quadraticToLinear(0.) - self.assertTrue(mm.isEqual(mmOut2,1e-12)[0]) - pass - - def testMEDFileMeshAddGroup1(self): - m=MEDCouplingCMesh() - arrX=DataArrayDouble(9) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - m.setCoords(arrX,arrY) - m.setName("mesh") - mm=MEDFileCMesh() - mm.setMesh(m) - grp0=DataArrayInt([3,5,6,21,22]) ; grp0.setName("grp0") - mm.addGroup(0,grp0) - grp1=DataArrayInt([3,4,5,8,18,19,22]) ; grp1.setName("grp1") - mm.addGroup(0,grp1) - grp2=DataArrayInt([0,1,2,10,11]) ; grp2.setName("grp2") - mm.addGroup(0,grp2) - grp3=DataArrayInt([23]) ; grp3.setName("grp3") - mm.addGroup(0,grp3) - for grp in [grp0,grp1,grp2,grp3]: - self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grp2','grp3')) - delta=12 - for grp in [grp0,grp1,grp2,grp3]: - grpNode=grp.deepCpy() ; grpNode+=delta ; grpNode.setName("%s_node"%grp.getName()) - mm.addGroup(1,grpNode) - self.assertEqual(mm.getGroupsNames(),('grp0','grp0_node','grp1','grp1_node','grp2','grp2_node','grp3','grp3_node')) - for grp in [grp0,grp1,grp2,grp3]: - self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) - for grp in [grp0,grp1,grp2,grp3]: - grpExp=grp+delta ; grpExp.setName("%s_node"%grp.getName()) - self.assertTrue(mm.getGroupArr(1,"%s_node"%grp.getName()).isEqual(grpExp)) - mm.normalizeFamIdsMEDFile() - for grp in [grp0,grp1,grp2,grp3]: - self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) - for grp in [grp0,grp1,grp2,grp3]: - grpExp=grp+delta ; grpExp.setName("%s_node"%grp.getName()) - self.assertTrue(mm.getGroupArr(1,"%s_node"%grp.getName()).isEqual(grpExp)) - pass - - pass - def testMEDFileJoint1(self): - fileName="Pyfile92.med" - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) - coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"]) - mm=MEDFileUMesh() - mm.setCoords(coo) - mm.setName("maa1") - mm.setDescription("un maillage") - mm.write(fileName,2) - node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8])) - cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3) - one_step_joint=MEDFileJointOneStep() - one_step_joint.pushCorrespondence(cell_correspond) - one_step_joint.pushCorrespondence(node_correspond) - one_joint=MEDFileJoint() - one_joint.pushStep(one_step_joint) - one_joint.setLocalMeshName("maa1") - one_joint.setRemoteMeshName("maa1") - one_joint.setDescription("joint_description") - one_joint.setJointName("joint_1") - one_joint.setDomainNumber(1) - self.assertEqual( one_joint.getLocalMeshName(), "maa1") - self.assertEqual( one_joint.getRemoteMeshName(), "maa1") - self.assertEqual( one_joint.getDescription(), "joint_description") - self.assertEqual( one_joint.getJointName(), "joint_1") - self.assertEqual( one_joint.getDomainNumber(), 1) - joints=MEDFileJoints() - joints.pushJoint(one_joint); - joints.write(fileName,0) - # read back - jointsR=MEDFileJoints(fileName,mm.getName()) - self.assertEqual( jointsR.getNumberOfJoints(), 1 ) - jR = jointsR.getJointAtPos(0) - self.assertTrue( jR.isEqual( one_joint )) - self.assertRaises( InterpKernelException, jointsR.getJointAtPos,1) - self.assertRaises( InterpKernelException, jointsR.destroyJointAtPos,1) - jointsR.destroyJointAtPos(0) - - pass - def testMEDFileJoint2(self): - fileNameWr="Pyfile93.med" - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) - coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"]) - mm=MEDFileUMesh() - mm.setCoords(coo) - mm.setName("maa1") - mm.setDescription("un maillage") - node_correspond=MEDFileJointCorrespondence(DataArrayInt([13,14,15,16])) - cell_correspond=MEDFileJointCorrespondence(DataArrayInt([17,18]),NORM_TETRA4,NORM_PENTA6) - one_step_joint=MEDFileJointOneStep() - two_step_joint=MEDFileJointOneStep() - one_joint=MEDFileJoint() - two_joint=MEDFileJoint() - one_step_joint.pushCorrespondence(node_correspond) - one_joint.pushStep(one_step_joint) - two_step_joint.pushCorrespondence(cell_correspond) - two_step_joint.pushCorrespondence(node_correspond) - two_joint.pushStep(two_step_joint) - one_joint.setLocalMeshName("maa1") - one_joint.setRemoteMeshName("maa1") - one_joint.setDescription("joint_description_1") - one_joint.setJointName("joint_1") - one_joint.setDomainNumber(1) - two_joint.setLocalMeshName("maa1") - two_joint.setRemoteMeshName("maa1") - two_joint.setDescription("joint_description_2") - two_joint.setJointName("joint_2") - two_joint.setDomainNumber(2) - joints=MEDFileJoints() - joints.pushJoint(one_joint) - joints.pushJoint(two_joint) - mm.setJoints( joints ) - mm.write(fileNameWr,2) - # - mm=MEDFileMesh.New(fileNameWr) - self.assertEqual( mm.getNumberOfJoints(), 2) - jointsR = mm.getJoints(); - self.assertEqual( jointsR.getMeshName(), mm.getName() ) - self.assertEqual( len( jointsR ), 2 ) - jointR1 = jointsR[0] - jointR2 = jointsR[1] - self.assertFalse( jointR1 is None ) - self.assertFalse( jointR2 is None ) - self.assertTrue( jointR1.isEqual( one_joint )) - self.assertTrue( jointR2.isEqual( two_joint )) - pass - - def testMEDFileJoint1(self): - node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8])) - cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3) - cell_correspon2=MEDFileJointCorrespondence(DataArrayInt([9,10,11]),NORM_TRI3,NORM_TRI3) - cell_correspon3=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_QUAD4) - joint1st_1=MEDFileJointOneStep() - joint1st_1.pushCorrespondence(cell_correspond) - joint1st_1.pushCorrespondence(node_correspond) - joint1st_2=MEDFileJointOneStep() - joint1st_2.pushCorrespondence(cell_correspond) - joint1st_2.pushCorrespondence(node_correspond) - joint1st_3=MEDFileJointOneStep() - joint1st_3.pushCorrespondence(node_correspond) - joint1st_3.pushCorrespondence(cell_correspond) - joint1st_4=MEDFileJointOneStep() - joint1st_4.pushCorrespondence(cell_correspond) - joint1st_5=MEDFileJointOneStep() - joint1st_5.pushCorrespondence(cell_correspon2) - joint1st_6=MEDFileJointOneStep() - joint1st_6.pushCorrespondence(cell_correspon3) - self.assertTrue( joint1st_1.isEqual( joint1st_2 )) - self.assertTrue( joint1st_1.isEqual( joint1st_3 )) - self.assertFalse( joint1st_1.isEqual( joint1st_4 )) - self.assertFalse( joint1st_4.isEqual( joint1st_5 )) - self.assertFalse( joint1st_4.isEqual( joint1st_6 )) - one_joint=MEDFileJoint() - one_joint.pushStep(joint1st_1) - one_joint.setLocalMeshName("maa1") - one_joint.setRemoteMeshName("maa2") - one_joint.setDescription("joint_description") - one_joint.setJointName("joint_1") - one_joint.setDomainNumber(1) - self.assertEqual( "maa1", one_joint.getLocalMeshName()) - self.assertEqual( "maa2", one_joint.getRemoteMeshName()) - self.assertEqual( "joint_description", one_joint.getDescription()) - self.assertEqual( 1, one_joint.getDomainNumber()) - self.assertEqual( "joint_1", one_joint.getJointName()) - pass - - @unittest.skipUnless('linux'==platform.system().lower(),"stderr redirection not ported on Windows ?") - def testMEDFileSafeCall0(self): - """ EDF11242 : check status of MED file calls to detect problems immediately. Sorry this test generates awful messages !""" - fname="Pyfile94.med" - errfname="Pyfile94.err" - class StdOutRedirect(object): - def __init__(self,fileName): - import os,sys - sys.stderr.flush() - self.stdoutOld=os.dup(2) - self.fdOfSinkFile=os.open(fileName,os.O_CREAT | os.O_RDWR) - fd2=os.dup2(self.fdOfSinkFile,2) - self.origPyVal=sys.stderr - class FlushFile(object): - def __init__(self,f): - self.f=f - def write(self,st): - self.f.write(st) - self.f.flush() - def flush(self): - return self.f.flush() - def isatty(self): - return self.f.isatty() - sys.stderr=FlushFile(os.fdopen(self.fdOfSinkFile,"w")) - def __del__(self): - import os,sys - sys.stderr=self.origPyVal - #os.fsync(self.fdOfSinkFile) - os.fsync(2) - os.dup2(self.stdoutOld,2) - os.close(self.stdoutOld) - import os - # first clean file if needed - if os.path.exists(fname): - os.remove(fname) - pass - # second : build a file from scratch - m=MEDCouplingCMesh() - arr=DataArrayDouble(11) ; arr.iota() - m.setCoords(arr,arr) - mm=MEDFileCMesh() - mm.setMesh(m) - mm.setName("mesh") - mm.write(fname,2) - # third : change permissions to remove write access on created file - os.chmod(fname,0444) - # four : try to append data on file -> check that it raises Exception - f=MEDCouplingFieldDouble(ON_CELLS) - f.setName("field") - f.setMesh(m) - f.setArray(DataArrayDouble(100)) - f.getArray()[:]=100. - f.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - # redirect stderr - tmp=StdOutRedirect(errfname) - self.assertRaises(InterpKernelException,f1ts.write,fname,0) # it should raise ! - del tmp - # - if os.path.exists(errfname): - os.remove(errfname) - # - pass - - def testUnivStatus1(self): - """ Non regression test to check the effectiveness of univ write status.""" - fname="Pyfile95.med" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) ; m.setName("mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) - mm.setUnivNameWrStatus(False) # test is here - mm.write(fname,2) - mm=MEDFileCMesh(fname) - self.assertEqual(mm.getUnivName(),"") - mm.setUnivNameWrStatus(True) - mm.write(fname,2) - mm=MEDFileCMesh(fname) - self.assertTrue(mm.getUnivName()!="") - pass - - def testEmptyMesh(self): - """ MEDLoader should be able to consistently write and read an empty mesh (coords array - with 0 tuples """ - fname = "Pyfile96.med" - m = MEDCouplingUMesh('toto', 2) - m.setCoords(DataArrayDouble([], 0, 2)) - m.setConnectivity(DataArrayInt([]), DataArrayInt([0])) - mfu = MEDFileUMesh() - mfu.setMeshAtLevel(0, m) - mfu.write(fname, 2) - mfu2 = MEDFileUMesh(fname) - self.assertEqual('toto', mfu2.getName()) - lvl = mfu2.getNonEmptyLevels() - self.assertEqual((), lvl) - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def testMEDFileUMeshPickeling2(self): - """ Check that pickalization can be performed on a unpickalized instance. Non regression test.""" - name="Mesh_1" - grpName1="HAUT" - grpName2="BASE" - hauteur=1. - nbOfNodesPerAxis=3 - arr=DataArrayDouble(nbOfNodesPerAxis) ; arr.iota() ; arr/=(nbOfNodesPerAxis-1) ; arr*=hauteur - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) ; m=m.buildUnstructured() ; m.setName(name) - mesh=MEDFileUMesh() ; mesh[0]=m - m1=m.computeSkin() ; mesh[-1]=m1 - # - bary1=m1.getBarycenterAndOwner()[:,2] - grp1=bary1.getIdsInRange(hauteur-1e-12,hauteur+1e-12) ; grp1.setName(grpName1) - grp2=bary1.getIdsInRange(0.-1e-12,0.+1e-12) ; grp2.setName(grpName2) - mesh.setGroupsAtLevel(-1,[grp1,grp2]) - - import cPickle - st=cPickle.dumps(mesh,2) - mm=cPickle.loads(st) - st2=cPickle.dumps(mm,2) - mm2=cPickle.loads(st2) - self.assertTrue(mesh.isEqual(mm2,1e-12)[0]) - pass - - def testMEDFileEquivalence1(self): - """ First check of equivalence implementation in MEDFileMesh""" - fileName="Pyfile97.med" - meshName="M_01" - mm=MEDFileUMesh() - coo=DataArrayDouble([(0,0,0),(6,0,0),(19,0,0),(36,0,0),(0,4,0),(6,4,0),(19,4,0),(36,4,0),(0,13,0),(6,13,0),(19,13,0),(36,13,0),(0,24,0),(6,24,0),(19,24,0),(36,24,0),(0,0,6),(6,0,6),(19,0,6),(36,0,6),(0,4,6),(6,4,6),(19,4,6),(36,4,6),(0,13,6),(6,13,6),(19,13,6),(36,13,6),(0,24,6),(6,24,6),(19,24,6),(36,24,6),(6,0,3),(6,2,0),(12.5,0,0),(19,0,3),(19,2,0),(6,4,3),(12.5,4,0),(19,4,3),(6,2,6),(12.5,0,6),(19,2,6),(12.5,4,6),(6,2,3),(12.5,0,3),(12.5,2,0),(19,2,3),(12.5,4,3),(12.5,2,6),(12.5,2,3)]) - coo.setInfoOnComponents(["X [Sans_unite]","Y [Sans_unite]","Z [Sans_unite]"]) - connQ4=DataArrayInt([1,17,21,5,2,18,22,6,21,5,6,22,1,32,44,33,17,40,44,32,21,37,44,40,5,33,44,37,2,35,47,36,18,42,47,35,22,39,47,42,6,36,47,39,21,37,48,43,5,38,48,37,6,39,48,38,22,43,48,39]) - m1=MEDCoupling1SGTUMesh(meshName,NORM_QUAD4) ; m1.setCoords(coo) ; m1.setNodalConnectivity(connQ4) ; mm[-1]=m1 - connH8=DataArrayInt([20,16,17,21,4,0,1,5,22,18,19,23,6,2,3,7,24,20,21,25,8,4,5,9,25,21,22,26,9,5,6,10,26,22,23,27,10,6,7,11,28,24,25,29,12,8,9,13,29,25,26,30,13,9,10,14,30,26,27,31,14,10,11,15,21,40,49,43,37,44,50,48,40,17,41,49,44,32,45,50,49,41,18,42,50,45,35,47,43,49,42,22,48,50,47,39,44,32,45,50,33,1,34,46,37,44,50,48,5,33,46,38,48,50,47,39,38,46,36,6,50,45,35,47,46,34,2,36]) - m0=MEDCoupling1SGTUMesh(meshName,NORM_HEXA8) ; m0.setCoords(coo) ; m0.setNodalConnectivity(connH8) ; mm[0]=m0 - mm.getFamilyFieldAtLevel(-1)[:]=-2 - mm.getFamilyFieldAtLevel(0)[:]=0 - mm.addFamily("HOMARD________-1",-1) - mm.addFamily("HOMARD________-2",-2) - mm.addFamily("HOMARD________-3",-3) - mm.setFamiliesIdsOnGroup("HOMARD",[-1,-2,-3]) - - eqName="MAILLES_A_RECOLLER_APRES_HOMARD" - descEq="Cette equivalence decrit les mailles a recoller. Dans chaque correspondance, le premier numero est celui de la maille coupee ; le second numero est celui d'une des petites mailles en regard." - mm.initializeEquivalences() - eqs=mm.getEquivalences() - eq0=eqs.appendEmptyEquivalenceWithName(eqName) - eq0.setDescription(descEq) - corr=DataArrayInt([(0,3),(0,4),(0,5),(0,6),(1,7),(1,8),(1,9),(1,10),(2,11),(2,12),(2,13),(2,14)]) - eq0.setArray(-1,corr) - self.assertEqual(eq0.getCell().size(),1) - self.assertTrue(eq0.getCell().getArray(NORM_QUAD4).isEqual(corr)) - eq0.getCell().clear() - self.assertEqual(eq0.getCell().size(),0) - eq0.getCell().setArrayForType(NORM_QUAD4,corr) - self.assertEqual(eq0.getCell().size(),1) - self.assertTrue(eq0.getCell().getArray(NORM_QUAD4).isEqual(corr)) - mm.killEquivalences() - mm.initializeEquivalences() - eqs=mm.getEquivalences() - eq0=eqs.appendEmptyEquivalenceWithName(eqName) - eq0.setDescription(descEq) - c=eq0.initCell() - c.setArrayForType(NORM_QUAD4,corr) - self.assertEqual(eq0.getCell().size(),1) - self.assertTrue(eq0.getCell().getArray(NORM_QUAD4).isEqual(corr)) - mm2=mm.deepCpy() - self.assertTrue(mm.isEqual(mm2,1e-12)[0]) - self.assertEqual(mm2.getEquivalences().size(),1) - self.assertTrue(mm2.getEquivalences().getEquivalence(0).getCell().getArray(NORM_QUAD4).isEqual(corr)) - mm2.getEquivalences().getEquivalence(0).getCell().getArray(NORM_QUAD4)[0,0]=2 - self.assertTrue(not mm.isEqual(mm2,1e-12)[0]) - mm2.getEquivalences().getEquivalence(0).getCell().getArray(NORM_QUAD4)[0,0]=0 - self.assertTrue(mm.isEqual(mm2,1e-12)[0]) - mm.write(fileName,2) - # - mm3=MEDFileMesh.New(fileName) - self.assertTrue(mm.isEqual(mm3,1e-12)[0]) - pass - - pass - -if __name__ == "__main__": - unittest.main() diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderTest4.py b/medtool/src/MEDLoader/Swig/MEDLoaderTest4.py deleted file mode 100644 index 706b63b09..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderTest4.py +++ /dev/null @@ -1,5120 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -from MEDLoader import * -import unittest -from math import pi,e,sqrt - -class MEDLoaderTest4(unittest.TestCase): - """ - Test series to emulate the future MEDReader plugin for PARAVIS. - """ - def test1(self): - """ - This test is the most simple one. One time serie of one field with only cell fields with no profiles. - The only "difficulty" is that the cell field is lying on different levels (2D and 1D) to maximize the compatibility with ParaVIS. - """ - fname="ForMEDReader1.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - fam=DataArrayInt(9) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) - fam=DataArrayInt(32) ; fam.iota(20) ; mm.setFamilyFieldArr(-1,fam) ; del fam - num=DataArrayInt(9) ; num.iota(100) ; mm.setRenumFieldArr(0,num) - num=DataArrayInt(32) ; num.iota(120) ; mm.setRenumFieldArr(-1,num) ; del num - # - fieldName="zeField" - fs=MEDFileFieldMultiTS() - ##### Time step 0 - i=0 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 1 - i=1 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(1100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(1200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 2 - i=2 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 3 - i=3 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(3100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(3200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fs.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - mm.write(fname,2) - fs.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,m1,mm,fs,f,fCell0,fCell1 - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) # False is important to not read the values - fields.removeFieldsWithoutAnyTimeStep() - refMem=fields.getHeapMemorySize() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - for fmts in allFMTSLeavesToDisplay[0]: - self.assertEqual(fmts.getTimeSteps(),[(0,0,0.),(1,0,1.),(2,0,2.),(3,0,3.),(4,0,4.)]) # All discretizations have the same time series - pass - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,0,1,2,3,4,5,6,7,8]))) - self.assertTrue(not a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,100,101,102,103,104,105,106,107,108]))) - self.assertTrue(not a9) - for i in xrange(5): - fsst=MEDFileField1TSStructItem.BuildItemFrom(fields[0][i],mst) - fields[0][i].loadArraysIfNecessary() - tmpMem=fields.getHeapMemorySize() - self.assertTrue(tmpMem-refMem>=41*2*8) - refMem=tmpMem - v=mml.buildDataArray(fsst,fields,fields[0][i].getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),fields[0][i].getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test2(self): - """ - One time serie of one field with cell and node discretization in the same field with no profiles. - Here as there is no profile only one VTK support is requested. - """ - fname="ForMEDReader2.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - fieldName="zeField" - fs=MEDFileFieldMultiTS() - ##### Time step 0 - i=0 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 1 - i=1 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(1100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(1200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(1300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 2 - i=2 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(2300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 3 - i=3 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(3100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(3200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(3300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - # - fs.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(4300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - # - fs.pushBackTimeStep(f) - mm.write(fname,2) - fs.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,m1,mm,fs,f,fCell0,fCell1 - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - for fmts in allFMTSLeavesToDisplay[0]: - self.assertEqual(fmts.getTimeSteps(),[(0,0,0.),(1,0,1.),(2,0,2.),(3,0,3.),(4,0,4.)]) # All discretizations have the same time series - pass - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - assert isinstance(mml2,MEDUMeshMultiLev) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - # for cells - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([300.,301.,302.,303.,304.,305.,306.,307.,308.,309.,310.,311.,312.,313.,314.,315.,316.,317.,318.,319.,320.,321.,322.,323.,324.,325.,326.,327.,328.,329.,330.,331.,332.,333.,334.,335.,336.,337.,338.,339.,340.,341.,342.,343.,344.,345.,346.,347.,348.,349.,350.,351.,352.,353.,354.,355.,356.,357.,358.,359.,360.,361.,362.,363.],32,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test3(self): - """ This test is more advanced a same field is defined on CELLS for time steps 0, 2 and 4, and on NODES for time steps 1 and 3. - So two time step series on the same field. No profile here neither on cells nor on nodes. - """ - fname="ForMEDReader3.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - fieldName="zeField" - fs=MEDFileFieldMultiTS() - ##### Time step 0 on cells - i=0 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 1 on nodes - i=1 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(1300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 2 on cells - i=2 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 3 on nodes - i=3 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(3300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fs.pushBackTimeStep(f) - mm.write(fname,2) - fs.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,m1,mm,fs,f,fCell0,fCell1 - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),2) # two time series here : one for the cells, the second one for the nodes - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[1]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] # start with the cells - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,3): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - assert a4 is None - assert a5 is None - # for cells - for i in xrange(3): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - self.assertEqual(f.getName(),"zeField") - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*2000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # for nodes - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[1],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,2): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,9,9,9,9,9,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,21,26,31,36,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31,2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - self.assertEqual(f.getName(),"zeField") - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([300.,301.,302.,303.,304.,305.,306.,307.,308.,309.,310.,311.,312.,313.,314.,315.,316.,317.,318.,319.,320.,321.,322.,323.,324.,325.,326.,327.,328.,329.,330.,331.,332.,333.,334.,335.,336.,337.,338.,339.,340.,341.,342.,343.,344.,345.,346.,347.,348.,349.,350.,351.,352.,353.,354.,355.,356.,357.,358.,359.,360.,361.,362.,363.],32,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*2000+1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test4(self): - """ This test defines 3 fields on nodes on the same mesh. All of these fields have no profile. - """ - fname="ForMEDReader4.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName1="zeField1" - fieldName2="zeField2" - fieldName3="zeField3" - fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - ##### Time step 0 - i=0 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 1 - i=1 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 2 - i=2 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 3 - i=3 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - # - mm.write(fname,2) - fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 3 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,21,26,31,36]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - # test all the time steps of the 1/1 time step serie, on field 1 - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # test all the time steps of the 1/1 time step serie, on field 2 - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) ; vExp+=i*1000+100 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # test all the time steps of the 1/1 time step serie, on field 3 - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) ; vExp+=i*1000+200 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test5(self): - """ This test plays with profiles both cell profiles and node profiles. Two first fields (resp on cells and on nodes) lie on the same mesh support whereas the third - mesh lies on a different mesh. - """ - fname="ForMEDReader5.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - fam=DataArrayInt(11) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(11) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - # - fieldName1="zeField1" ; pfl1=DataArrayInt([0,1,2,3,4,5]) ; pfl1.setName("pfl1") # on cells - fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,13,14]) ; pfl2.setName("pfl2") # on nodes - fieldName3="zeField3" ; pfl3=DataArrayInt([0,1,2,3,4,5,9,10]) ; pfl3.setName("pfl3") # on cells but different support - fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - # - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*6) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*8) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*8) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl3) - fs3.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 3 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - ms[0].getDirectUndergroundSingleGeoTypeMeshes(0) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),2) # 2 support here - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp[pfl2].changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,3,1,3,3,4,1,3,1,4,2,3,4,5,2,3,6,5,4,3,6,7,5]))) - assert a4 is None - assert a5 is None - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertTrue(not a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105]))) - self.assertTrue(not a9) - for i in xrange(5): - nbOfT=[6,8] - fieldNames=[fieldName1,fieldName2] - for j in xrange(2): - m={"i":j} - f=allFMTSLeavesPerCommonSupport[0][0][j][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldNames[j]) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(nbOfT[j]*2) ; vExp.iota(j*100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_%(i)i [m]'%m,'Com2_%(i)i [s^2]'%m]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - # Let's go for the 2nd support - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20,24,29]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,7,3,3,7,8,3,3,3,8,4,3,8,9,4,3,13,9,8,3,13,14,9,4,6,11,12,7,4,12,13,8,7]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,9,10]))) - self.assertTrue(not a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,109,110]))) - self.assertTrue(not a9) - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),"zeField3") - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(8*2) ; vExp.iota(200+1000*i) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]'%m,'Com2_2 [s^2]'%m]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test6(self): - """ This test plays with cartesian mesh and profiles. When a sub cartesian mesh can also be considered as a cartesian mesh it is done. - """ - fname="ForMEDReader6.med" - m=MEDCouplingCMesh("mesh") - coordsX=DataArrayDouble([0,1.1,2.2,3.3,4.4]) ; coordsX.setInfoOnComponents(["XX [m]"]) - coordsY=DataArrayDouble([0,1.7,3.4]) ; coordsY.setInfoOnComponents(["YYY [km]"]) - m.setCoords(coordsX,coordsY) - mm=MEDFileCMesh() ; mm.setMesh(m) - fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - num=DataArrayInt(15) ; num.iota(200) ; mm.setRenumFieldArr(1,num) ; del num - # - fieldName0="zeField0" ; # on cells - fieldName1="zeField1" ; pfl1=DataArrayInt([2,3,6,7]) ; pfl1.setName("pfl1") # on cells - fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,12,13,14]) ; pfl2.setName("pfl2") # on nodes - fieldName3="zeField3" ; pfl3=DataArrayInt([2,3,5,7]) ; pfl3.setName("pfl3") # on cells but different support - fieldName4="zeField4" ;# on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() ; fs4=MEDFileFieldMultiTS() - # - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*8) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*4) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - self.assertEqual(pfl1.getName(),"pfl1") - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - self.assertEqual(pfl2.getName(),"pfl2") - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*4) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl3) - self.assertEqual(pfl3.getName(),"pfl3") - fs3.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName4) ; fNode.setMesh(m) - arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_4 [m]","Com2_4 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs4.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) ; fs4.write(fname,0) - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 5 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - (a,b),c=mml2.buildVTUArrays() - self.assertTrue(c)# c is True here because the returned array is directly those coming from internal structure - self.assertTrue(a.isEqual(coordsX,1e-12)) - self.assertTrue(b.isEqual(coordsY,1e-12)) - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - self.assertTrue(a7) # True because no copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) - self.assertTrue(a9) # True because no copy - a10,a11=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([200,201,202,203,204,205,206,207,208,209,210,211,212,213,214]))) - self.assertTrue(a11) # True because no copy - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(8*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName4) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_4 [m]','Com2_4 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here the 2nd support is a part of CMesh that is also a CMesh -> CMesh not a UMesh - (a,b),c=mml2.buildVTUArrays() - self.assertTrue(not c)# c is False because this a sub support specialy built for buildVTUArrays - self.assertTrue(a.isEqual(coordsX[[2,3,4]],1e-12)) - self.assertTrue(b.isEqual(coordsY,1e-12)) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,6,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,106,107]))) - self.assertTrue(not a9) # False because copy - a10,a11=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([202,203,204,207,208,209,212,213,214]))) - self.assertTrue(not a11) # False because copy - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[1][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here the 3rd support is a part of CMesh but impossible to simplify more than a UMesh - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) - a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,3,2,7,8,4,4,3,8,9,4,7,6,11,12,4,9,8,13,14]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,5,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,105,107]))) - self.assertTrue(not a9) # False because copy - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test7(self): - """ This test plays with curvilinear mesh and profiles. When a sub curvilinear mesh can also be considered as a cartesian mesh it is done. - This test is very similar to the test6. - """ - fname="ForMEDReader7.med" - m=MEDCouplingCurveLinearMesh("mesh") ; m.setNodeGridStructure([5,3]) - a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) - a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(a0Exp) - mm=MEDFileCurveLinearMesh() ; mm.setMesh(m) - fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - # - fieldName0="zeField0" ; # on cells - fieldName1="zeField1" ; pfl1=DataArrayInt([2,3,6,7]) ; pfl1.setName("pfl1") # on cells - fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,12,13,14]) ; pfl2.setName("pfl2") # on nodes - fieldName3="zeField3" ; pfl3=DataArrayInt([2,3,5,7]) ; pfl3.setName("pfl3") # on cells but different support - fieldName4="zeField4" ;# on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() ; fs4=MEDFileFieldMultiTS() - # - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*8) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*4) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - self.assertEqual(pfl1.getName(),"pfl1") - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - self.assertEqual(pfl2.getName(),"pfl2") - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*4) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl3) - self.assertEqual(pfl3.getName(),"pfl3") - fs3.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName4) ; fNode.setMesh(m) - arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_4 [m]","Com2_4 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs4.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) ; fs4.write(fname,0) - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 5 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCurveLinearMeshMultiLev)) - a,b,c=mml2.buildVTUArrays() - self.assertTrue(c)#True here because a is directly coming from internal data without copy - self.assertTrue(a.isEqual(a0Exp,1e-12)) - self.assertEqual(b,[5,3]) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - self.assertTrue(a7) # True because no copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) - self.assertTrue(a9) # True because no copy - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(8*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName4) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_4 [m]','Com2_4 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCurveLinearMeshMultiLev)) # here the 2nd support is a part of CMesh that is also a CMesh -> CMesh not a UMesh - a,b,c=mml2.buildVTUArrays() - self.assertTrue(not c)#False here because a is the result of a computation not the internal strucutre - self.assertTrue(a.isEqual(a0Exp[pfl2],1e-12)) - self.assertEqual(b,[3,3]) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,6,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,106,107]))) - self.assertTrue(not a9) # False because copy - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[1][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here the 3rd support is a part of CMesh but impossible to simplify more than a UMesh - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) - a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,3,2,7,8,4,4,3,8,9,4,7,6,11,12,4,9,8,13,14]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,5,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,105,107]))) - self.assertTrue(not a9) # False because copy - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test8(self): - """ This test plays with with gauss fields with no profiles. - """ - fname="ForMEDReader8.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" - fieldName3="zeField3" - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_NE) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*38) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*11) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,1,2,3],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([4,5],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,7,8],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([9,10],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(4*2+2*5+3*4+2*7)) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - # - pass - # - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),4) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20,24,29,34,39,44]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,7,3,3,7,8,3,3,3,8,4,3,8,9,4,3,13,9,8,3,13,14,9,4,0,5,6,1,4,1,6,7,2,4,5,10,11,6,4,6,11,12,7,4,12,13,8,7]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(38*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(11*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(44*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][3][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - pass - - def test9(self): - """ This test plays with with gauss fields with profiles. - """ - fname="ForMEDReader9.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" - fieldName3="zeField3" - pfl1=DataArrayInt([0,1,7,9,10]) ; pfl1.setName("pfl1") # on cells - pfl2=DataArrayInt([1,2,3,6,7,8,11,12,13]) ; pfl2.setName("pfl2") # on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_NE) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) - arr=DataArrayDouble(2*18) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*5) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m[pfl1]) - fNode.setGaussLocalizationOnCells([0],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([2,3],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([4],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*1+5*1+4*2+7*1)) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() - f.setFieldProfile(fNode,mm,0,pfl1) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*9) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - fs3.pushBackTimeStep(f) - # - pass - # - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),4) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp[pfl2].changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,1,4,2,3,4,5,2,4,0,3,4,1,4,3,6,7,4,4,7,8,5,4]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(18*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(5*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(22*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][3][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test10(self): - """ This test plays with fields only on nodes containing profiles. - """ - fname="ForMEDReader10.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" - pfl1=DataArrayInt([1,2,3,6,7,8,11,12,13]) ; pfl1.setName("pfl1") # on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) - arr=DataArrayDouble(2*9) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*9) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs2.pushBackTimeStep(f) - # - pass - # - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp[pfl1].changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,1,4,2,3,4,5,2,4,0,3,4,1,4,3,6,7,4,4,7,8,5,4]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(9*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(9*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test11(self): - """ This test is the ultimate test for the profiles with gauss points. It tests that even if there is non contiguous parts in definition of gauss points, it works ! - WARNING here, as no other discretizations exists, the priority is given to the field -> the mesh is renumbered to accelerate the build of array of field. - """ - fname="ForMEDReader11.med" - m=MEDCouplingCMesh("mesh") - arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fs0=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 1 field is defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,9,8,13,14,4,19,18,23,24,4,2,1,6,7,4,7,6,11,12,4,11,10,15,16,4,12,11,16,17,4,8,7,12,13,4,13,12,17,18,4,17,16,21,22,4,14,13,18,19,4,16,15,20,21,4,18,17,22,23]))) # <- here the mesh is renumbered : the mesh is equal to m[[0,2,3,4,7,15, 1,5,8,9, 6,10,13, 11,12,14]] - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,44.,45.,46.,47.,126.,127.,128.,129.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.,64.,65.,66.,67.,36.,37.,38.,39.,40.,41.,42.,43.,68.,69.,70.,71.,72.,73.,74.,75.,104.,105.,106.,107.,108.,109.,110.,111.,76.,77.,78.,79.,80.,81.,82.,83.,84.,85.,86.,87.,88.,89.,90.,91.,92.,93.,94.,95.,96.,97.,98.,99.,100.,101.,102.,103.,112.,113.,114.,115.,116.,117.,118.,119.,120.,121.,122.,123.,124.,125.],65,2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test12(self): - """ This test is the second ultimate test for the profiles with gauss points. - This test is close to test11 but here a 2nd field on cells without profile. So here the mesh is expected to be the same than m. - """ - fname="ForMEDReader12.med" - m=MEDCouplingCMesh("mesh") - arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*16) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0,fs1,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) # <- here the mesh is NOT renumbered : the mesh is equal to m - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug : huge reordering performed ! - vExp=DataArrayDouble(65*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug : huge reordering performed ! - vExp=DataArrayDouble(16*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test13(self): - """ Testing polyhedrons mixed with hexa8""" - fname="ForMEDReader13.med" - m=MEDCouplingUMesh("mesh",3) - m.allocateCells() - m.insertNextCell(NORM_HEXA8,[1,0,6,7,13,12,18,19]) ; m.insertNextCell(NORM_HEXA8,[2,1,7,8,14,13,19,20]) - m.insertNextCell(NORM_POLYHED,[3,2,8,9,-1,15,21,20,14,-1,3,15,14,2,-1,2,14,20,8,-1,8,20,21,9,-1,9,21,15,3]) - m.insertNextCell(NORM_POLYHED,[4,3,9,10,-1,16,22,21,15,-1,4,16,15,3,-1,3,15,21,9,-1,9,21,22,10,-1,10,22,16,4]) - m.insertNextCell(NORM_POLYHED,[5,4,10,11,-1,17,23,22,16,-1,5,17,16,4,-1,4,16,22,10,-1,10,22,23,11,-1,11,23,17,5]) - coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,5.,1.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,1.,4.,0.,1.,5.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,3.,1.,1.,4.,1.,1.,5.,1.,1.],24,3) ; coords.setInfoOnComponents(["XX [m]","YYY [km]","ZZZZ [Mm]"]) - m.setCoords(coords) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" ; pfl1=DataArrayInt([2,3]) ; pfl1.setName("pfl1") - fieldName3="zefield3" ; pfl2=DataArrayInt([2,3,4]) ; pfl2.setName("pfl2") - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*5) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*5) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m[pfl1]) - arr=DataArrayDouble(2*2) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() - f.setFieldProfile(fNode,mm,0,pfl1) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m[pfl2]) - arr=DataArrayDouble(2*3) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) ; fNode.checkCoherency() - f.setFieldProfile(fNode,mm,0,pfl2) - fs3.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0 - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([12,12,42,42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,6,7,13,12,18,19,8,2,1,7,8,14,13,19,20,8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) - self.assertTrue(a4.isEqual(DataArrayInt([-1,-1,0,31,62]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(5*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(5*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22]))) - self.assertTrue(a4.isEqual(DataArrayInt([0,31]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(2*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([42,42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) - self.assertTrue(a4.isEqual(DataArrayInt([0,31,62]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(3*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test14(self): - """ Testing only polyhedrons""" - fname="ForMEDReader14.med" - m=MEDCouplingUMesh("mesh",3) - m.allocateCells() - m.insertNextCell(NORM_POLYHED,[3,2,8,9,-1,15,21,20,14,-1,3,15,14,2,-1,2,14,20,8,-1,8,20,21,9,-1,9,21,15,3]) - m.insertNextCell(NORM_POLYHED,[4,3,9,10,-1,16,22,21,15,-1,4,16,15,3,-1,3,15,21,9,-1,9,21,22,10,-1,10,22,16,4]) - m.insertNextCell(NORM_POLYHED,[5,4,10,11,-1,17,23,22,16,-1,5,17,16,4,-1,4,16,22,10,-1,10,22,23,11,-1,11,23,17,5]) - coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,5.,1.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,1.,4.,0.,1.,5.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,3.,1.,1.,4.,1.,1.,5.,1.,1.],24,3) ; coords.setInfoOnComponents(["XX [m]","YYY [km]","ZZZZ [Mm]"]) - m.setCoords(coords) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() - fieldName0="zeField0" - fieldName1="zeField1" - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*3) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*3) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0 - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([42,42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) - self.assertTrue(a4.isEqual(DataArrayInt([0,31,62]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0]))) - self.assertTrue(a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(3*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(3*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test15(self): - """ - "ForMEDReader15.med" file has a spaceDim 3 mesh "mesh" (it is important !) - and a field "zeField" lying on a single geometric type for Cell discr and node part. - Test that can appear the most simple but it hides a big issue of MEDReader - that copies are reduced at most. So it can leads to SIGSEGV if the memory management is not OK for int* and double * similar between VTK and MEDCoupling. - """ - fname="ForMEDReader15.med" - m0=MEDCouplingCMesh() - arr=DataArrayDouble(3) ; arr.iota(0) - m0.setCoords(arr,arr,arr) - m0.setName("mesh") - m0=m0.buildUnstructured() - # - fieldName="zeField" - fCell=MEDCouplingFieldDouble(ON_CELLS) - fCell.setName(fieldName) - fCell.setMesh(m0) - # - fNode=MEDCouplingFieldDouble(ON_NODES) - fNode.setName(fieldName) - fNode.setMesh(m0) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - # - ffs=MEDFileFieldMultiTS() - # TimeStep 0 - t=(1.,0,0) ; off=0. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # TimeStep 1 - t=(2.1,1,0) ; off=100. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # TimeStep 2 - t=(3.2,2,0) ; off=200. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # TimeStep 3 - t=(4.3,3,1) ; off=300. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # - mm.write(fname,2) - ffs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.0],27,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([12,12,12,12,12,12,12,12]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36,45,54,63]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,3,4,10,9,12,13,8,2,1,4,5,11,10,13,14,8,4,3,6,7,13,12,15,16,8,5,4,7,8,14,13,16,17,8,10,9,12,13,19,18,21,22,8,11,10,13,14,20,19,22,23,8,13,12,15,16,22,21,24,25,8,14,13,16,17,23,22,25,26]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) - self.assertTrue(a9) # no copy here - pass - - def test16(self): - """ Here 2 meshes "mesh1" and "mesh2" and 4 fields (no profiles here) : - - "zeField1_0" (CELLS) and "zeField2_0" (NODES) on "mesh1" - - "zeField3_1" (CELLS) and "zeField4_1" (NODES) on "mesh2" - time steps series are the same for the whole 4 fields - """ - fname="ForMEDReader16.med" - m0=MEDCouplingCMesh() - arr=DataArrayDouble(3) ; arr.iota(0) - m0.setCoords(arr,arr,arr) - m0.setName("mesh1") - m0=m0.buildUnstructured() - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) - fCell1.setName("zeField1_0") - fCell1.setMesh(m0) - # - fNode1=MEDCouplingFieldDouble(ON_NODES) - fNode1.setName("zeField2_0") - fNode1.setMesh(m0) - # - mms=MEDFileMeshes() - mm1=MEDFileUMesh() - mm1.setMeshAtLevel(0,m0) - fam=DataArrayInt([0,1,0,1,2,3,2,3]); mm1.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm1.setRenumFieldArr(0,num) ; del num - mm1.setFamilyId("FAMILLE_ZERO",0) ; mm1.setFamilyId("Family1_1",1) ; mm1.setFamilyId("Family1_2",2) ; mm1.setFamilyId("Family1_3",3) ; mm1.setFamilyId("Family1_4",4) - mm1.setFamiliesIdsOnGroup("Grp1_1",[0,1]) ; mm1.setFamiliesIdsOnGroup("Grp1_2",[2,3]) - mms.pushMesh(mm1) ; del mm1 - # - m1=m0.deepCpy() ; m1.translate([2.5,0.,0.]) ; m1.setName("mesh2") - # - fCell2=MEDCouplingFieldDouble(ON_CELLS) - fCell2.setName("zeField3_1") - fCell2.setMesh(m1) - # - fNode2=MEDCouplingFieldDouble(ON_NODES) - fNode2.setName("zeField4_1") - fNode2.setMesh(m1) - # - mm2=MEDFileUMesh() - mm2.setMeshAtLevel(0,m1) - fam=DataArrayInt([0,1,0,1,2,3,2,3]); mm2.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(200) ; mm2.setRenumFieldArr(0,num) ; del num - mm2.setFamilyId("FAMILLE_ZERO",0) ; mm2.setFamilyId("Family2_1",1) ; mm2.setFamilyId("Family2_2",2) ; mm2.setFamilyId("Family2_3",3) ; mm2.setFamilyId("Family2_4",4) - mm2.setFamiliesIdsOnGroup("Grp2_1",[0,1]) ; mm2.setFamiliesIdsOnGroup("Grp2_2",[2,3]) ; mm2.setFamiliesIdsOnGroup("Grp2_3",[1,2,3]) - mms.pushMesh(mm2) ; del mm2 - ffs1_1=MEDFileFieldMultiTS() - ffs1_2=MEDFileFieldMultiTS() - ffs2_1=MEDFileFieldMultiTS() - ffs2_2=MEDFileFieldMultiTS() - mts=MEDFileFields() - for elt in ffs1_1,ffs1_2,ffs2_1,ffs2_2: - mts.pushField(elt) - pass - # TimeStep 0 - t=(1.,0,0) ; off=0. - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell1.setArray(a) - fCell1.setTime(*t) - fCell1.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode1.setArray(a) - fNode1.setTime(*t) - fNode1.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) - # - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) - fCell2.setArray(a) - fCell2.setTime(*t) - fCell2.checkCoherency() - a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode2.setArray(a) - fNode2.setTime(*t) - fNode2.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) - # TimeStep 1 - t=(2.1,1,0) ; off=100. - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell1.setArray(a) - fCell1.setTime(*t) - fCell1.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode1.setArray(a) - fNode1.setTime(*t) - fNode1.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) - # - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) - fCell2.setArray(a) - fCell2.setTime(*t) - fCell2.checkCoherency() - a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode2.setArray(a) - fNode2.setTime(*t) - fNode2.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) - # TimeStep 2 - t=(3.1,2,0) ; off=200. - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell1.setArray(a) - fCell1.setTime(*t) - fCell1.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode1.setArray(a) - fNode1.setTime(*t) - fNode1.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) - # - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) - fCell2.setArray(a) - fCell2.setTime(*t) - fCell2.checkCoherency() - a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode2.setArray(a) - fNode2.setTime(*t) - fNode2.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) - # - mms.write(fname,2) ; mts.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),2) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - self.assertEqual(len(allFMTSLeavesToDisplay[1]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - allFMTSLeavesPerCommonSupport2=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport2),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport2[0][0]),2) - pass - - def test17(self): - """ First test on GAUSS_NE (Elno). Here no Profiles. - 2 times steps. - """ - fname="ForMEDReader17.med" - fieldName1="MyFirstElno" - fieldName2="ACellField" - fieldName3="ANodeField" - coo=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.],6,2) - m=MEDCouplingUMesh("mesh",2) - m.setCoords(coo) - m.allocateCells() - m.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m.insertNextCell(NORM_QUAD4,[1,4,5,2]) - m.checkCoherency2() - # - t=(1.1,0,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f.setTime(*t) ; f.setMesh(m) - f.setArray(DataArrayDouble([3.,5.,7.,6.,2.,3.,11.,8.])) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteField(fname,f,True) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([7.,11.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([1.,2.,4.,1.,2.,4.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - # - t=(2.1,1,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f.setTime(*t) ; f.setMesh(m) - f.setArray(DataArrayDouble([7.,6.,3.,5.,11.,8.,2.,3.])) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([11.,7.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([4.,2.,1.,4.,2.,1.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) - self.assertTrue(a9) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] - vExp1=[DataArrayDouble([3.,5.,7.,6.,2.,3.,11.,8.]),DataArrayDouble([7.,6.,3.,5.,11.,8.,2.,3.])] - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp0[i],1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp1[i],1e-12)) - pass - pass - - def test18(self): - """ First test on GAUSS_PT. Here no Profiles. 2 times steps. - """ - fname="ForMEDReader18.med" - fieldName1="MyFirstGauss" - fieldName2="ACellField" - fieldName3="ANodeField" - coo=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.],6,2) - m=MEDCouplingUMesh("mesh",2) - m.setCoords(coo) - m.allocateCells() - m.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m.insertNextCell(NORM_QUAD4,[1,4,5,2]) - m.checkCoherency2() - # - t=(1.1,0,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f.setTime(*t) ; f.setMesh(m) - f.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.2,0.2,0.8,0.8],[0.7,0.3]) - f.setArray(DataArrayDouble([3.,5.,4.,6.])) ; f.getArray().setInfoOnComponents(["Smth"]) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteField(fname,f,True) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([7.,11.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([1.,2.,4.,1.,2.,4.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - # - t=(2.1,1,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f.setTime(*t) ; f.setMesh(m) - f.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.2,0.2,0.8,0.8],[0.7,0.3]) - f.setArray(DataArrayDouble([5.,3.,6.,4.])) ; f.getArray().setInfoOnComponents(["Smth"]) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([11.,7.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([4.,2.,1.,4.,2.,1.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - self.assertEqual([NORM_QUAD4],fcscp.getGeoTypesAt(0,ms[0])) - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) - self.assertTrue(a9) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] - vExp1=[DataArrayDouble([3.,5.,4.,6.]),DataArrayDouble([5.,3.,6.,4.])] - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp0[i],1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp1[i].setInfoOnComponents(["Smth"]) - self.assertTrue(v.isEqual(vExp1[i],1e-12)) - pass - ## Now same exercise but with a different load strategy. All is load directly. - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname) # here all is read, the SauvReader (or other Reader) is emulated - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) - self.assertTrue(a9) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] - vExp1=[DataArrayDouble([3.,5.,4.,6.]),DataArrayDouble([5.,3.,6.,4.])] - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) # no load needed here - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp0[i],1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) # no load needed here - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp1[i].setInfoOnComponents(["Smth"]) - self.assertTrue(v.isEqual(vExp1[i],1e-12)) - pass - pass - - def test19(self): - """ - This test is a simple non profile CELL field but lying on cells of dimension -1 (not 0 as "usual"). - """ - fname="ForMEDReader19.med" - fieldName="ACellFieldOnDimM1" - coo=DataArrayDouble(3) ; coo.iota() - m=MEDCouplingCMesh() ; m.setCoords(coo,coo,coo) ; m.setName("mesh") - m0=m.buildUnstructured() ; del m - m1=m0.computeSkin() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setMeshAtLevel(-1,m1) - ff=MEDFileFieldMultiTS() - # time 0 - t=(1.1,1,-1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setTime(*t) ; f.setMesh(m1) - f.setName(fieldName) - arr=DataArrayDouble(24) ; arr.iota() ; arr.setInfoOnComponents(["AStr"]) - f.setArray(arr) - f.checkCoherency() - f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) - ff.pushBackTimeStep(f1ts) - # time 1 - t=(2.1,2,-2) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setTime(*t) ; f.setMesh(m1) - f.setName(fieldName) - arr=DataArrayDouble(24) ; arr.iota() ; arr.reverse() ; arr.setInfoOnComponents(["AStr"]) - f.setArray(arr) - f.checkCoherency() - f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) - ff.pushBackTimeStep(f1ts) - # - mm.write(fname,2) - ff.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.],27,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,3,4,4,1,10,9,0,4,0,9,12,3,4,2,1,4,5,4,2,11,10,1,4,5,14,11,2,4,4,3,6,7,4,3,12,15,6,4,6,15,16,7,4,5,4,7,8,4,7,16,17,8,4,8,17,14,5,4,19,22,21,18,4,10,19,18,9,4,9,18,21,12,4,20,23,22,19,4,11,20,19,10,4,14,23,20,11,4,22,25,24,21,4,12,21,24,15,4,15,24,25,16,4,23,26,25,22,4,16,25,26,17,4,17,26,23,14]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) # no copy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(not a10) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(not a12) - self.assertTrue(a13) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(24) ; vExp.iota() - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["AStr"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test20(self): - """ This test works with groups/families on cells AND on nodes. Here 4 fields each on same time steps (2). - 1 field on CELLS without profile, 1 field on CELLS with profile, 1 field on NODES without profile, 1 field on NODES with profile. - All of these 4 fields lies on a single mesh "mesh". The 2 fields on profile lies on a same support. - One drawback of this test : no multi geom type. Coming soon ! - """ - fname="ForMEDReader20.med" - fieldName0="ANodeField" - fieldName1="ACellField" - fieldName2="ANodeFieldPfl" - fieldName3="ACellFieldPfl" - pfl2=DataArrayInt([5,6,7,10,11,12,15,16,17,20,21,22]) ; pfl2.setName("pfl2") - pfl3=DataArrayInt([4,5,8,9,12,13]) ; pfl3.setName("pfl3") - # - arr=DataArrayDouble(5) ; arr.iota() - m=MEDCouplingCMesh("mesh") ; m.setCoords(arr,arr) - m=m.buildUnstructured() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - fs=MEDFileFields() - fmts0=MEDFileFieldMultiTS() ; fs.pushField(fmts0) - fmts0.setDtUnit("s") - fmts1=MEDFileFieldMultiTS() ; fs.pushField(fmts1) - fmts1.setDtUnit("s") - fmts2=MEDFileFieldMultiTS() ; fs.pushField(fmts2) - fmts2.setDtUnit("s") - fmts3=MEDFileFieldMultiTS() ; fs.pushField(fmts3) - fmts3.setDtUnit("s") - #### - t=(1.1,0,-2) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m) - f0.setName(fieldName0) ; f0.setTime(*t) - da=m.getCoords().magnitude() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(m) - f1.setName(fieldName1) ; f1.setTime(*t) - da=m.getBarycenterAndOwner().magnitude() ; da.setInfoOnComponents(["zeInfoCell"]) - f1.setArray(da) - f1.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f1) - fmts1.pushBackTimeStep(f1ts) - # - f2=MEDCouplingFieldDouble(ON_NODES) ; mTmp=m[pfl3] ; mTmp.zipCoords() ; mTmp.setName(m.getName()) ; f2.setMesh(mTmp) - f2.setName(fieldName2) ; f2.setTime(*t) - da=m.getCoords().magnitude()[pfl2] ; da.setInfoOnComponents(["zzzz"]) - f2.setArray(da) - f2.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f2,mm,0,pfl2) - fmts2.pushBackTimeStep(f1ts) - # - f3=MEDCouplingFieldDouble(ON_CELLS) ; mTmp=m[pfl3] ; mTmp.setName(m.getName()) ; f3.setMesh(mTmp) - f3.setName(fieldName3) ; f3.setTime(*t) - da=mTmp.getBarycenterAndOwner().magnitude() ; da.setInfoOnComponents(["abcdefg"]) - f3.setArray(da) - f3.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f3,mm,0,pfl3) - fmts3.pushBackTimeStep(f1ts) - #### - t=(2.1,1,-3) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m) - f0.setName(fieldName0) ; f0.setTime(*t) - da=m.getCoords().magnitude() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(m) - f1.setName(fieldName1) ; f1.setTime(*t) - da=m.getBarycenterAndOwner().magnitude() ; da.reverse() ; da.setInfoOnComponents(["zeInfoCell"]) - f1.setArray(da) - f1.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f1) - fmts1.pushBackTimeStep(f1ts) - # - f2=MEDCouplingFieldDouble(ON_NODES) ; mTmp=m[pfl3] ; mTmp.zipCoords() ; mTmp.setName(m.getName()) ; f2.setMesh(mTmp) - f2.setName(fieldName2) ; f2.setTime(*t) - da=m.getCoords().magnitude()[pfl2] ; da.reverse() ; da.setInfoOnComponents(["zzzz"]) - f2.setArray(da) - f2.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f2,mm,0,pfl2) - fmts2.pushBackTimeStep(f1ts) - # - f3=MEDCouplingFieldDouble(ON_CELLS) ; mTmp=m[pfl3] ; mTmp.setName(m.getName()) ; f3.setMesh(mTmp) - f3.setName(fieldName3) ; f3.setTime(*t) - da=mTmp.getBarycenterAndOwner().magnitude() ; da.reverse() ; da.setInfoOnComponents(["abcdefg"]) - f3.setArray(da) - f3.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f3,mm,0,pfl3) - fmts3.pushBackTimeStep(f1ts) - #### - grp1=DataArrayInt([6,7,8,11,12,13,16,17,18]) ; grp1.setName("grp1") - grp2=DataArrayInt([10,11,15,16,20,21]) ; grp2.setName("grp2") - mm.setGroupsAtLevel(1,[grp1,grp2]) - grp3=DataArrayInt([4,5,6]) ; grp3.setName("grp3") - grp4=DataArrayInt([8,9,10]) ; grp4.setName("grp4") - mm.setGroupsAtLevel(0,[grp3,grp4]) - d=DataArrayInt(25) ; d.iota() ; d*=10 ; mm.setRenumFieldArr(1,d) - d=DataArrayInt(16) ; d.iota() ; d*=11 ; mm.setRenumFieldArr(0,d) - mm.write(fname,2) - fs.appendGlobs(fmts2,1e-12) - fs.appendGlobs(fmts3,1e-12) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,3.,2.,0.,4.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,3.,3.,0.,4.,3.,0.,0.,4.,0.,1.,4.,0.,2.,4.,0.,3.,4.,0.,4.,4.,0.],25,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-5,-5,-5,-5,-6,-6,-6,-5,-7,-7,-7,-5,-5,-5,-5,-5]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,11,22,33,44,55,66,77,88,99,110,121,132,143,154,165]))) - self.assertTrue(a9) # no copy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([1,1,1,1,1,1,2,2,2,1,3,4,2,2,1,3,4,2,2,1,3,3,1,1,1]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240]))) - self.assertTrue(a13) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.7071067811865476,1.5811388300841898,2.5495097567963922,3.5355339059327378,1.5811388300841898,2.1213203435596424,2.9154759474226504,3.8078865529319543,2.5495097567963922,2.9154759474226504,3.5355339059327378,4.301162633521313,3.5355339059327378,3.8078865529319543,4.301162633521313,4.949747468305833]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["zeInfoCell"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,1.,1.4142135623730951,2.23606797749979,3.1622776601683795,4.123105625617661,2.,2.23606797749979,2.8284271247461903,3.605551275463989,4.47213595499958,3.,3.1622776601683795,3.605551275463989,4.242640687119285,5.,4.,4.123105625617661,4.47213595499958,5.,5.656854249492381]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["zeInfo"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - ### Testing the 2nd support - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,4.,0.,1.,4.,0.,2.,4.,0.],12,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,3,4,4,2,1,4,5,4,4,3,6,7,4,5,4,7,8,4,7,6,9,10,4,8,7,10,11]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-6,-6,-7,-7,-5,-5]))) - self.assertTrue(not a7) # copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([44,55,88,99,132,143]))) - self.assertTrue(not a9) # copy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([1,2,2,3,4,2,3,4,2,3,3,1]))) - self.assertTrue(not a11) # copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([50,60,70,100,110,120,150,160,170,200,210,220]))) - self.assertTrue(not a13) # copy here - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([1.5811388300842,2.1213203435596,2.5495097567964,2.9154759474227,3.5355339059327,3.807886552932]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["abcdefg"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[1][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([1.,1.4142135623731,2.2360679774998,2.,2.2360679774998,2.8284271247462,3.,3.1622776601684,3.605551275464,4.,4.1231056256177,4.4721359549996]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["zzzz"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test21(self): - """ Here the created MED file contains only a mesh. The aim here is to test capability of MEDReader to support no fields. - This test checks nothing but write a MED file to be used by MEDReader tests. - """ - fname="ForMEDReader21.med" - mm=MEDFileUMesh() - # - m0=MEDCouplingCMesh("mesh") ; arr=DataArrayDouble(5) ; arr.iota() ; m0.setCoords(arr,arr) ; m0=m0.buildUnstructured() - mm.setMeshAtLevel(0,m0) - grp0=DataArrayInt([5,6,9,10]) ; grp0.setName("Inside2D") - grp1=DataArrayInt([0,1,2,3,4,7,8,11,12,13,14,15]) ; grp1.setName("Border2D") - grp2=DataArrayInt([2,3,6,7]) ; grp2.setName("LowerRight2D") - mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) - # - m1=MEDCouplingUMesh(m0.getName(),1) ; m1.setCoords(m0.getCoords()) ; m1.allocateCells() - for elt in [[0,1],[1,2],[2,3],[3,4],[4,9],[9,14],[14,19],[19,24],[24,23],[23,22],[22,21],[21,20],[20,15],[15,10],[10,5],[5,0],[2,7],[7,12],[12,17],[17,22], - [10,11],[11,12],[12,13],[13,14]]: - m1.insertNextCell(NORM_SEG2,elt) - pass - mm.setMeshAtLevel(-1,m1) - grp4=DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) ; grp4.setName("Border1D") - grp5=DataArrayInt([16,17,18,19,20,21,22,23]) ; grp5.setName("Inside1D") - grp6=DataArrayInt([18,19,22,23]) ; grp6.setName("UpperRight1D") - mm.setGroupsAtLevel(-1,[grp4,grp5,grp6]) - # - grp7=DataArrayInt([1,2,3,6,7,8,11,12,13,16,17,18,21,22,23]) ; grp7.setName("InsideYNode") - grp8=DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) ; grp8.setName("InsideXNode") - mm.setGroupsAtLevel(1,[grp7,grp8]) - # - mm.write(fname,2) - pass - - def test22(self): - """ Use case where a field on nodes (ANodeField) on a mesh defined both in meshdim 2 and meshdim 1. - The only possible geometrical support that suits the field is those with meshdim equal to 1 (-1 in relative). - """ - fname="ForMEDReader22.med" - fieldName0="ANodeField" - mm=MEDFileUMesh() - coo=DataArrayDouble([(4.,3.),(7.,3.),(2.,5.),(6.,5.),(9.,5.),(4.,7.),(8.,7.),(3.,8.),(9.,8.)]) - m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coo) ; m0.allocateCells() ; m0.insertNextCell(NORM_TRI3,[2,3,0]) ; m0.insertNextCell(NORM_TRI3,[3,1,0]) ; m0.insertNextCell(NORM_TRI3,[3,4,1]) - mm.setMeshAtLevel(0,m0) - m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coo) ; m1.allocateCells() ; m1.insertNextCell(NORM_SEG2,[2,0]) ; m1.insertNextCell(NORM_SEG2,[0,1]) ; m1.insertNextCell(NORM_SEG2,[1,4]) - m1.insertNextCell(NORM_SEG2,[3,5]) ; m1.insertNextCell(NORM_SEG2,[5,7]) ; m1.insertNextCell(NORM_SEG2,[3,6]) ; m1.insertNextCell(NORM_SEG2,[6,8]) - mm.setMeshAtLevel(-1,m1) - fs=MEDFileFields() - fmts0=MEDFileFieldMultiTS() ; fs.pushField(fmts0) - fmts0.setDtUnit("s") - # - t=(1.1,0,-2) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(9) ; da.iota() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - t=(2.1,1,-3) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(9) ; da.iota() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - self.assertEqual([NORM_TRI3,NORM_SEG2],fcscp.getGeoTypesAt(0,ms[0]))#contains all cell types of underlying mesh because only nodes with no profiles - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(4.,3.,0.),(7.,3.,0.),(2.,5.,0.),(6.,5.,0.),(9.,5.,0.),(4.,7.,0.),(8.,7.,0.),(3.,8.,0.),(9.,8.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,3,3,3,3,3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,15,18,21,24,27,30]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,3,0,3,3,1,0,3,3,4,1,2,2,0,2,0,1,2,1,4,2,3,5,2,5,7,2,3,6,2,6,8]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0]))) - self.assertTrue(not a7) # copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(not a8) - self.assertTrue(a9) # nocopy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(not a10) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(not a12) - self.assertTrue(a13) # no copy here - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][1] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) ; vExp.reverse() - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test23(self): - """ Non regression test 2219 of modes. Idem than test22 except that here the node field is on profile. - """ - fname="ForMEDReader23.med" - fieldName0="ANodeField" - mm=MEDFileUMesh() - coo=DataArrayDouble([(4.,3.),(7.,3.),(2.,5.),(6.,5.),(9.,5.),(4.,7.),(8.,7.),(3.,8.),(9.,8.)]) - m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coo) ; m0.allocateCells() ; m0.insertNextCell(NORM_TRI3,[2,3,0]) ; m0.insertNextCell(NORM_TRI3,[3,1,0]) ; m0.insertNextCell(NORM_TRI3,[3,4,1]) - mm.setMeshAtLevel(0,m0) - m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coo) ; m1.allocateCells() ; m1.insertNextCell(NORM_SEG2,[2,0]) ; m1.insertNextCell(NORM_SEG2,[0,1]) ; m1.insertNextCell(NORM_SEG2,[1,4]) - m1.insertNextCell(NORM_SEG2,[3,5]) ; m1.insertNextCell(NORM_SEG2,[5,7]) ; m1.insertNextCell(NORM_SEG2,[3,6]) ; m1.insertNextCell(NORM_SEG2,[6,8]) - mm.setMeshAtLevel(-1,m1) - fmts0=MEDFileFieldMultiTS() - fmts0.setDtUnit("s") - # - pfl=DataArrayInt([0,1,2,4]) ; pfl.setName("pfl") - pflCell=DataArrayInt([0,1,2]) ; m1Part=m1[pflCell] ; m1Part.zipCoords() - # - t=(1.1,0,-2) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1Part) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(4) ; da.iota() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f0,mm,-1,pfl) - fmts0.pushBackTimeStep(f1ts) - # - t=(2.1,1,-3) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1Part) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(4) ; da.iota() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f0,mm,-1,pfl) - fmts0.pushBackTimeStep(f1ts) - mm.write(fname,2) - fmts0.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(4.,3.,0.),(7.,3.,0.),(2.,5.,0.),(9.,5.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,2,0,2,0,1,2,1,3]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0]))) - self.assertTrue(not a7) # copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(not a8) - self.assertTrue(a9) # nocopy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(not a10) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(not a12) - self.assertTrue(a13) # no copy here - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble(4) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][1] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble(4) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) ; vExp.reverse() - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test24(self): - """ Non regression test for cartesian mesh whose the 3rd direction has only one node. It a false 3D mesh. - """ - fname="ForMEDReader24.med" - fieldName0="zeFieldNode" - cmesh=MEDCouplingCMesh("mesh") - arr0=DataArrayDouble([0.,1.1,2.2,3.3,4.4]) - arr1=DataArrayDouble([0.,1.4,2.3]) - arr2=DataArrayDouble([5.]) - cmesh.setCoords(arr0,arr1,arr2) - fmts0=MEDFileFieldMultiTS() - fmts0.setDtUnit("s") - # - t=(1.1,2,3) - f=MEDCouplingFieldDouble(ON_NODES) ; f.setName(fieldName0) - f.setMesh(cmesh) - arr=DataArrayDouble(15) ; arr.setInfoOnComponents(["tutu"]) ; arr.iota() - f.setArray(arr) - f.setTime(*t) - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - fmts0.pushBackTimeStep(f1ts) - # - t=(3.3,4,5) - arr=DataArrayDouble(15) ; arr.setInfoOnComponents(["tutu"]) ; arr.iota() - arr.reverse() - f.setArray(arr) - f.setTime(*t) - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - fmts0.pushBackTimeStep(f1ts) - # - mm=MEDFileCMesh() ; mm.setMesh(cmesh) - mm.write(fname,2) - fmts0.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) - (a,b,c),d=mml2.buildVTUArrays() - self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure - self.assertTrue(a.isEqual(arr0,1e-12)) - self.assertTrue(b.isEqual(arr1,1e-12)) - self.assertTrue(c.isEqual(arr2,1e-12)) - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15) ; vExp.iota(0) ; vExp.setInfoOnComponents(["tutu"]) - if i==1: - vExp.reverse() - pass - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test25(self): - """ A tricky test that reproduces an invalid behaviour - Here a same field is defined both on CELLS and GAUSS_PT, with a profile for each. - The problem appears on array computation when performing CELLS then GAUSS_PT and CELLS again. - """ - fname="ForMEDReader25.med" - m=MEDFileUMesh() - coords=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.,0.,2.,1.,2.,2.,2.,0.,3.,1.,3.,2.,3.,1.,4.,1.,5.,1.,6.],15,2) - m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coords) - m0.allocateCells() - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[1,4,5,2]) - m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) - m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) - m0.insertNextCell(NORM_QUAD4,[6,9,10,7]) - m0.insertNextCell(NORM_QUAD4,[7,10,11,8]) - m.setMeshAtLevel(0,m0) - m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coords) - m1.allocateCells() - m1.insertNextCell(NORM_SEG2,[10,12]) - m1.insertNextCell(NORM_SEG2,[12,13]) - m1.insertNextCell(NORM_SEG2,[13,14]) - m.setMeshAtLevel(-1,m1) - m.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6])) - m.setFamilyFieldArr(-1,DataArrayInt([-7,-8,-9])) - m.setFamilyFieldArr(1,DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])) - m.setRenumFieldArr(0,DataArrayInt([101,102,103,104,105,106])) - m.setRenumFieldArr(-1,DataArrayInt([107,108,109])) - m.setRenumFieldArr(1,DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217])) - # - fmts=MEDFileFieldMultiTS() - info0=["aa","bbb"] - name0="zeField" - pflName0="pfl" - pflName1="pfl2" - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name0) - arr=DataArrayDouble([(-1,-11),(-2,-22)]) ; arr.setInfoOnComponents(info0) - f.setArray(arr) - pfl0=DataArrayInt([0,1]) ; pfl0.setName(pflName0) - f1ts.setFieldProfile(f,m,-1,pfl0) - del f - f2=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f2.setName(name0) - arr=DataArrayDouble(15) ; arr.iota(1) - arr=DataArrayDouble.Meld(arr,arr+10) ; arr.setInfoOnComponents(info0) - f2.setArray(arr) - pfl1=DataArrayInt([1,3,5]) ; pfl1.setName(pflName1) - tmp=m0[pfl1] ; f2.setMesh(tmp) - f2.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,0.,0.],[0.1,0.1,0.1,0.1,0.6]) - f2.checkCoherency() - f1ts.setFieldProfile(f2,m,0,pfl1) - fmts.pushBackTimeStep(f1ts) - # - m.write(fname,2) - fmts.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) # false is absolutely necessary for the test - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - ### here the test is important !!! Pointers must be different ! - self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - ### here the test is important !!! Pointers must be different ! - self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # emulate first click - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - self.assertEqual([NORM_SEG2],fcscp.getGeoTypesAt(0,ms[0])) - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # copy here because 2D -> 3D - expCoords=coords.changeNbOfComponents(3,0.) - self.assertTrue(a0.isEqual(expCoords,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,10,12,2,12,13]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-7,-8]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([107,108]))) - self.assertTrue(not a9) # copy here because profile on cells - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) - self.assertTrue(a13) # no copy here - fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - self.assertEqual([ON_CELLS],fff0.getTypesOfFieldAvailable()) - v=mml.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),name0) - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([(-1,-11),(-2,-22)]) ; vExp.setInfoOnComponents(info0) - self.assertTrue(v.isEqual(vExp,1e-12)) - del fff0 - # emulate second click - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - self.assertEqual([NORM_QUAD4],fcscp.getGeoTypesAt(0,ms[0])) - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # copy here because 2D -> 3D - expCoords=coords.changeNbOfComponents(3,0.) - self.assertTrue(a0.isEqual(expCoords,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,4,5,2,4,4,7,8,5,4,7,10,11,8]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-2,-4,-6]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,104,106]))) - self.assertTrue(not a9) # copy here because profile on cells - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) - self.assertTrue(a13) # no copy here - fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - self.assertEqual([ON_GAUSS_PT],fff1.getTypesOfFieldAvailable()) - v=mml.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),name0) - self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.,8.,18.,9.,19.,10.,20.,11.,21.,12.,22.,13.,23.,14.,24.,15.,25.],15,2) ; vExp.setInfoOnComponents(info0) - self.assertTrue(v.isEqual(vExp,1e-12)) - # emulate third click - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # copy here because 2D -> 3D - expCoords=coords.changeNbOfComponents(3,0.) - self.assertTrue(a0.isEqual(expCoords,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,10,12,2,12,13]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-7,-8]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([107,108]))) - self.assertTrue(not a9) # copy here because profile on cells - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) - self.assertTrue(a13) # no copy here - fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - self.assertEqual([ON_CELLS],fff0.getTypesOfFieldAvailable()) - v=mml.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),name0) - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([(-1,-11),(-2,-22)]) ; vExp.setInfoOnComponents(info0) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - del fff0 - pass - - def test26(self): - """ Test focused on field on nodes (here f0Node and f1Node) lying on a profile of nodes that do not match perfectly a sub set of cells of its underlying mesh. See bug EDF 2405 and 2177. - For this type of fields the support will contain only vertices. - """ - fname="ForMEDReader26.med" - coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) - m0=MEDCouplingUMesh("mesh",2) - m0.allocateCells() - for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]: - m0.insertNextCell(NORM_TRI3,elt) - pass - for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]: - m0.insertNextCell(NORM_QUAD4,elt) - pass - m0.setCoords(coords) - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11])) - mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) - # - f1ts0Node=MEDFileField1TS() - f1ts1Node=MEDFileField1TS() - f1ts2Cell=MEDFileField1TS() - f1ts3Cell=MEDFileField1TS() - f1ts4Cell=MEDFileField1TS() - f1ts5Node=MEDFileField1TS() - # - pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0") - pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1") - pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2") - # - f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node") - arr0=DataArrayDouble(6) ; arr0.iota() - f0Node.setArray(arr0) - f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0) - # - f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node") - arr1=DataArrayDouble(6) ; arr1.iota() ; arr1.reverse() - f1Node.setArray(arr1) - f1ts1Node.setFieldProfile(f1Node,mm,0,pfl0) - # - f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell") - arr2=DataArrayDouble([2,3,0,1,4,5]) - f2Cell.setArray(arr2) - f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1) - # - f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell") - arr3=DataArrayDouble([5,4,3,2,1,0]) - f3Cell.setArray(arr3) - f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1) - # - f4Cell=MEDCouplingFieldDouble(ON_CELLS) ; f4Cell.setName("f4Cell") - arr4=DataArrayDouble([2,2,0,1,1,0]) - f4Cell.setArray(arr4) - f1ts4Cell.setFieldProfile(f4Cell,mm,0,pfl1) - # - f5Node=MEDCouplingFieldDouble(ON_NODES) ; f5Node.setName("f5Node") - arr5=DataArrayDouble([0,1,2,3,10,11,13,2,11,1,10,0]) - f5Node.setArray(arr5) - f1ts5Node.setFieldProfile(f5Node,mm,0,pfl2) - # - fs=MEDFileFields() - for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell,f1ts4Cell,f1ts5Node]: - fmts=MEDFileFieldMultiTS() - fmts.pushBackTimeStep(f) - fs.pushField(fmts) - pass - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),6) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),6) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),4) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2)# <- the smart one is here - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - self.assertEqual([3,4,0],mml2.getGeoTypes()) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,9,1]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,9]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,5]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,13]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) # no copy here because no number field - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13]))) - self.assertTrue(not a11) # copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12 is None) - self.assertTrue(a13) # no copy here because no number field - # - fff0=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),"f0Node") - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.]) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - # - fff1=allFMTSLeavesPerCommonSupport1[1][0][1][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),"f1Node") - self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([5.,4.,3.,2.,1.,0.]) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - pass - - def test27(self): - """ This test defines 2 fields f0 and f1 on nodes lying on an unstructured mesh with no cells. - f0 is a field on all nodes. f1 is a partial field on nodes. - """ - fname="ForMEDReader27.med" - coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) - m0=MEDCouplingUMesh("mesh",2) - m0.allocateCells() - m0.setCoords(coords) - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) - # - f1ts0=MEDFileField1TS() - f1ts1=MEDFileField1TS() - # - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m0) ; f0.setName("f0NoPfl") - arr0=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4.]) - f0.setArray(arr0) - f0.checkCoherency() - f1ts0.setFieldNoProfileSBT(f0) - self.assertEqual(f1ts0.getMeshName(),"mesh") - # - pfl1=DataArrayInt([0,1,2,3,4,5,6,8,9,12]) ; pfl1.setName("pfl1") - f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setName("f1Pfl") - arr1=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2]) - f1.setArray(arr1) - f1ts1.setFieldProfile(f1,mm,0,pfl1) - self.assertEqual(f1ts1.getMeshName(),"mesh") - # - fs=MEDFileFields() - fmts0=MEDFileFieldMultiTS() - fmts0.pushBackTimeStep(f1ts0) - fmts1=MEDFileFieldMultiTS() - fmts1.pushBackTimeStep(f1ts1) - fs.pushField(fmts0) ; fs.pushField(fmts1) - self.assertEqual(fs[0].getMeshName(),"mesh") - self.assertEqual(fs[1].getMeshName(),"mesh") - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - self.assertEqual(fields[0].getMeshName(),"mesh") - self.assertEqual(fields[1].getMeshName(),"mesh") - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - self.assertEqual(fields_per_mesh[0][0].getMeshName(),"mesh") - self.assertEqual(fields_per_mesh[0][1].getMeshName(),"mesh") - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([]))) - self.assertTrue(a2.isEqual(DataArrayInt([]))) - self.assertTrue(a3.isEqual(DataArrayInt([]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - # - fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),"f0NoPfl") - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(0,2,0),(1,2,0),(0,3,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([]))) - self.assertTrue(a2.isEqual(DataArrayInt([]))) - self.assertTrue(a3.isEqual(DataArrayInt([]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),"f1Pfl") - self.assertNotEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) # pointers are not equal because Profile - vExp=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test28(self): - """ This test defines 2 fields f0,f1,f2,f3 lying on an unstructured mesh whith cells including NORM_POINT1. - Both f0 and f1 are on NODES and f2 and f3 are on cells. f1 and f2 share the same support. - f0 is on a nodal support that is not matchable with any cells (including NORM_POINT1) - This test is a more aggressive version of test26. - """ - fname="ForMEDReader28.med" - coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) - m0=MEDCouplingUMesh("mesh",2) - m0.allocateCells() - for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]: - m0.insertNextCell(NORM_TRI3,elt) - pass - for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]: - m0.insertNextCell(NORM_QUAD4,elt) - pass - m0.setCoords(coords) - m2=MEDCouplingUMesh("mesh",0) ; m2.setCoords(coords) - m2.allocateCells() - for elt in [[8],[13]]: - m2.insertNextCell(NORM_POINT1,elt) - pass - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setMeshAtLevel(-2,m2) - mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11])) - mm.setFamilyFieldArr(-2,DataArrayInt([-12,-13])) - mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) - # - f1ts0Node=MEDFileField1TS() - f1ts1Node=MEDFileField1TS() - f1ts2Cell=MEDFileField1TS() - f1ts3Cell=MEDFileField1TS() - # - pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0") - pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1") - pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2") - # - f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node") - arr0=DataArrayDouble(6) ; arr0.iota() - f0Node.setArray(arr0) - f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0) - # - f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node") - arr1=DataArrayDouble(12) ; arr1.iota() ; arr1.reverse() - f1Node.setArray(arr1) - f1ts1Node.setFieldProfile(f1Node,mm,0,pfl2) - # - f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell") - arr2=DataArrayDouble([2,3,0,1,4,5]) - f2Cell.setArray(arr2) - f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1) - # - f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell") - arr3=DataArrayDouble([5,4,3,2,1,0]) ; f3Cell.setArray(arr3) - f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1) - f3Cell.setMesh(m2) - arr3=DataArrayDouble([-1.1,-3.1]) ; f3Cell.setArray(arr3) - f1ts3Cell.setFieldNoProfileSBT(f3Cell) - # - fs=MEDFileFields() - for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell]: - fmts=MEDFileFieldMultiTS() - fmts.pushBackTimeStep(f) - fs.pushField(fmts) - pass - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,9,1,1]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,9,11]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,3,1,5]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,-12,13]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) # no copy here because no number field - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13]))) - self.assertTrue(not a11) # copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12 is None) - self.assertTrue(a13) # no copy here because no number field - # - fff0=allFMTSLeavesPerCommonSupport1[2][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),"f0Node") - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.]) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - ### - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(2,2,0),(3,2,0),(2,3,0),(3,3,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18,23]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,8,9,7,4,8,10,11,9]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - fff1=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),"f2Cell") - self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([2,3,0,1,4,5]) - self.assertTrue(v.isEqual(vExp,1e-12)) - fff2=allFMTSLeavesPerCommonSupport1[0][0][1][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff2,mst) - fff2.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff2.getUndergroundDataArray()) - self.assertEqual(fff2.getName(),"f1Node") - self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([11,10,9,8,7,6,5,4,3,2,1,0]) - self.assertTrue(v.isEqual(vExp,1e-12)) - ### - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc)# here all the 16 nodes are taken - self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([1,1,5,5,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,2,4,8,12,17,22,27]))) - self.assertTrue(a3.isEqual(DataArrayInt([1,8,1,13,3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,10,11,7,4,10,14,15,11]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - fff3=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff3,mst) - fff3.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff3.getUndergroundDataArray()) - self.assertEqual(fff3.getName(),"f3Cell") - self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([-1.1,-3.1,5,4,3,2,1,0]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test29(self): - """ This test focused on HEXA27 cell for which the MED numbering is not equal to the VTK numbering. So here the HEXA27 cell is those in MED file documentation (reference element). - """ - fname="ForMEDReader29.med" - coo=DataArrayDouble([[0.,2.,2.],[0.,0.,2.],[2.,0.,2.],[2.,2.,2.],[0.,2.,0.],[0.,0.,0.],[2.,0.,0.],[2.,2.,0.], [0.,1.,2.],[1.,0.,2.],[2.,1.,2.],[1.,2.,2.], [0.,1.,0.],[1.,0.,0.],[2.,1.,0.],[1.,2.,0.], [0.,2.,1.],[0.,0.,1.],[2.,0.,1.],[2.,2.,1.], [1.,1.,2.], [0.,1.,1.],[1.,0.,1.],[2.,1.,1.],[1.,2.,1.], [1.,1.,0.], [1.,1.,1.]]) - m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) - m.allocateCells() - # MED = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26] - # VTK = [0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26] - m.insertNextCell(NORM_HEXA27,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) - fCell=MEDCouplingFieldDouble(ON_CELLS) ; fCell.setName("fCell") - arrCell=DataArrayDouble([7.]) ; arrCell.setInfoOnComponent(0,"smth") ; fCell.setArray(arrCell) - fCell.setMesh(m) - MEDLoader.WriteField(fname,fCell,True) - refCoo=[-1.,-1.,-1.,-1.,1.,-1.,1.,1.,-1.,1.,-1.,-1.,-1.,-1.,1.,-1.,1.,1.,1.,1.,1.,1.,-1.,1.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.] - weights=[0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.7023319615912209,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571] - gCoords=[-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,0.0,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.0,0.0,0.0,0.0,0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,0.0,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483] - fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") - fGauss.setMesh(m) - fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) - arrGauss=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arrGauss.setInfoOnComponent(0,"gaussc") ; arrGauss.iota() - fGauss.setArray(arrGauss) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fGauss) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(a0.isEqual(coo,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([29]))) - self.assertTrue(a2.isEqual(DataArrayInt([0]))) - # the connectivity must be not a iota as declared in m.insertNextCell - self.assertTrue(a3.isEqual(DataArrayInt([27,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26])))# the test is on this line to check that connectivity has been processed for HEXA27 - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - self.assertEqual(ffCell.getName(),"fCell") - self.assertTrue(v.isEqual(arrCell,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble([7.]),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["smth"]) - del ffCell - # - ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffGauss,mst) - ffGauss.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffGauss.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffGauss.getUndergroundDataArray().getHiddenCppPointer()) - self.assertEqual(ffGauss.getName(),"fGauss") - self.assertTrue(v.isEqual(arrGauss,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble(range(27)),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["gaussc"]) - ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] - pass - - def test30(self): - """ This test is focused on cartesian meshes. Here the cartesian mesh "CartMesh" has a field on HEXA8 (FieldOnCells) and a field on QUAD4 (FieldOnFaces). - So the first one (FieldOnCells) lies on a cartesian mesh whereas the second one lies on unstructured one. - """ - fname="ForMEDReader30.med" - c=MEDCouplingCMesh() - arrX=DataArrayDouble(3) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(5) ; arrZ.iota() - c.setCoords(arrX,arrY,arrZ) - c.setName("CartMesh") - cc=MEDFileCMesh() - cc.setMesh(c) - tmpFacesMesh=c.build1SGTSubLevelMesh() - famIdFaces=DataArrayInt(98) ; famIdFaces[:36]=-1 ; famIdFaces[36:68]=-2 ; famIdFaces[68:]=-3 - famIdCells=DataArrayInt(24) ; famIdCells[:]=0 - #cc.setFamilyFieldArr(0,famIdCells) - #cc.setFamilyFieldArr(-1,famIdFaces) - cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) - cc.setFamiliesOnGroup("FacesX1",["FacesX"]) - cc.setFamiliesOnGroup("FacesY1",["FacesY"]) - cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) - # - fmts0=MEDFileFieldMultiTS() - fmts1=MEDFileFieldMultiTS() - for i in xrange(30): - f1ts=MEDFileField1TS() - fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnFaces") - arr=DataArrayDouble(98) ; arr.iota() ; arr[i]=100. - fFaces.setArray(arr) - fFaces.setTime(float(i)+0.1,i,-1) - fFaces.setMesh(tmpFacesMesh) - f1ts.setFieldNoProfileSBT(fFaces) - fmts0.pushBackTimeStep(f1ts) - # - f1ts=MEDFileField1TS() - fCells=MEDCouplingFieldDouble(ON_CELLS) ; fCells.setName("FieldOnCells") - arr=DataArrayDouble(24) ; arr.iota() ; arr[i%24]=30. - fCells.setArray(arr) - fCells.setTime(float(i)+0.1,i,-1) - fCells.setMesh(c) - f1ts.setFieldNoProfileSBT(fCells) - fmts1.pushBackTimeStep(f1ts) - pass - fs=MEDFileFields() - fs.pushField(fmts0) - fs.pushField(fmts1) - cc.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here CMesh is important - (a,b,c),d=mml2.buildVTUArrays() - self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure - self.assertTrue(a.isEqual(arrX,1e-12)) - self.assertTrue(b.isEqual(arrY,1e-12)) - self.assertTrue(c.isEqual(arrZ,1e-12)) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(24) ; myarr.iota() ; myarr[i%24]=30. - self.assertEqual(ffCell.getName(),"FieldOnCells") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important - ref=ms[0].getImplicitFaceMesh().getCoords().getHiddenCppPointer() - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertEqual(ref,a0.getHiddenCppPointer()) - self.assertTrue(ncc) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275,280,285,290,295,300,305,310,315,320,325,330,335,340,345,350,355,360,365,370,375,380,385,390,395,400,405,410,415,420,425,430,435,440,445,450,455,460,465,470,475,480,485]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,12,15,3,4,12,24,27,15,4,24,36,39,27,4,36,48,51,39,4,3,15,18,6,4,15,27,30,18,4,27,39,42,30,4,39,51,54,42,4,6,18,21,9,4,18,30,33,21,4,30,42,45,33,4,42,54,57,45,4,1,13,16,4,4,13,25,28,16,4,25,37,40,28,4,37,49,52,40,4,4,16,19,7,4,16,28,31,19,4,28,40,43,31,4,40,52,55,43,4,7,19,22,10,4,19,31,34,22,4,31,43,46,34,4,43,55,58,46,4,2,14,17,5,4,14,26,29,17,4,26,38,41,29,4,38,50,53,41,4,5,17,20,8,4,17,29,32,20,4,29,41,44,32,4,41,53,56,44,4,8,20,23,11,4,20,32,35,23,4,32,44,47,35,4,44,56,59,47,4,0,12,13,1,4,12,24,25,13,4,24,36,37,25,4,36,48,49,37,4,1,13,14,2,4,13,25,26,14,4,25,37,38,26,4,37,49,50,38,4,3,15,16,4,4,15,27,28,16,4,27,39,40,28,4,39,51,52,40,4,4,16,17,5,4,16,28,29,17,4,28,40,41,29,4,40,52,53,41,4,6,18,19,7,4,18,30,31,19,4,30,42,43,31,4,42,54,55,43,4,7,19,20,8,4,19,31,32,20,4,31,43,44,32,4,43,55,56,44,4,9,21,22,10,4,21,33,34,22,4,33,45,46,34,4,45,57,58,46,4,10,22,23,11,4,22,34,35,23,4,34,46,47,35,4,46,58,59,47,4,0,1,4,3,4,3,4,7,6,4,6,7,10,9,4,1,2,5,4,4,4,5,8,7,4,7,8,11,10,4,12,13,16,15,4,15,16,19,18,4,18,19,22,21,4,13,14,17,16,4,16,17,20,19,4,19,20,23,22,4,24,25,28,27,4,27,28,31,30,4,30,31,34,33,4,25,26,29,28,4,28,29,32,31,4,31,32,35,34,4,36,37,40,39,4,39,40,43,42,4,42,43,46,45,4,37,38,41,40,4,40,41,44,43,4,43,44,47,46,4,48,49,52,51,4,51,52,55,54,4,54,55,58,57,4,49,50,53,52,4,52,53,56,55,4,55,56,59,58]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(98) ; myarr.iota() ; myarr[i]=100. - self.assertEqual(ffCell.getName(),"FieldOnFaces") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test31(self): - """non regression test of EDF 7972""" - fname="ForMEDReader31.med" - c=MEDCouplingCMesh() - arrX=DataArrayDouble(3) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(5) ; arrZ.iota() - c.setCoords(arrX,arrY,arrZ) - c.setName("CartMesh") - cc=MEDFileCMesh() - cc.setMesh(c) - famIdCells=DataArrayInt(24) ; famIdCells[:]=0 - cc.setFamilyFieldArr(0,famIdCells) - #cc.setFamilyFieldArr(-1,famIdFaces) - cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) - cc.setFamiliesOnGroup("FacesX1",["FacesX"]) - cc.setFamiliesOnGroup("FacesY1",["FacesY"]) - cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) - fmts0=MEDFileFieldMultiTS() - fmts1=MEDFileFieldMultiTS() - pfl=DataArrayInt(11) ; pfl.iota() ; pfl.setName("PflOnHECA8") - for i in xrange(30): - f1ts=MEDFileField1TS() - fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnCells") - arr=DataArrayDouble(11) ; arr.iota() ; arr[i%11]=100. - fFaces.setArray(arr) - fFaces.setTime(float(i)+0.1,i,-1) - fFaces.setMesh(c.buildUnstructured()[:11]) - f1ts.setFieldProfile(fFaces,cc,0,pfl)# here, a test is done to check that "NORM_HEXA8" string is not 30 times appended at the end of pfl name. - self.assertEqual("PflOnHECA8",pfl.getName()) - fmts0.pushBackTimeStep(f1ts) - pass - fs=MEDFileFields() - fs.pushField(fmts0) - cc.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. This is the most important line in the test. - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,3.,1.,1.,3.,1.,2.,3.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.,0.,3.,2.,1.,3.,2.,2.,3.,2.,0.,0.,3.,1.,0.,3.,2.,0.,3.,0.,1.,3.,1.,1.,3.,2.,1.,3.,0.,2.,3.,1.,2.,3.,2.,2.,3.,0.,3.,3.,1.,3.,3.,2.,3.,3.,0.,0.,4.,1.,0.,4.,2.,0.,4.,0.,1.,4.,1.,1.,4.,2.,1.,4.,0.,2.,4.,1.,2.,4.,2.,2.,4.,0.,3.,4.,1.,3.,4.,2.,3.,4.],60,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([12,12,12,12,12,12,12,12,12,12,12]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36,45,54,63,72,81,90]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,3,4,13,12,15,16,8,2,1,4,5,14,13,16,17,8,4,3,6,7,16,15,18,19,8,5,4,7,8,17,16,19,20,8,7,6,9,10,19,18,21,22,8,8,7,10,11,20,19,22,23,8,13,12,15,16,25,24,27,28,8,14,13,16,17,26,25,28,29,8,16,15,18,19,28,27,30,31,8,17,16,19,20,29,28,31,32,8,19,18,21,22,31,30,33,34]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - # self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) # to be improved... maybe this line could be true - myarr=DataArrayDouble(11) ; myarr.iota() ; myarr[i%11]=100. - self.assertEqual(ffCell.getName(),"FieldOnCells") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test32(self): - """ This test is close to test30 except that here the profiles on dim-1 of structured mesh is considered here.""" - fname="ForMEDReader32.med" - c=MEDCouplingCMesh() - arrX=DataArrayDouble(3) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(5) ; arrZ.iota() - c.setCoords(arrX,arrY,arrZ) - c.setName("CartMesh") - cc=MEDFileCMesh() - cc.setMesh(c) - tmpFacesMesh=c.build1SGTSubLevelMesh() - famIdFaces=DataArrayInt(98) ; famIdFaces[:36]=-1 ; famIdFaces[36:68]=-2 ; famIdFaces[68:]=-3 - famIdCells=DataArrayInt(24) ; famIdCells[:]=0 - cc.setFamilyFieldArr(0,famIdCells) - #cc.setFamilyFieldArr(-1,famIdFaces) - cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) - cc.setFamiliesOnGroup("FacesX1",["FacesX"]) - cc.setFamiliesOnGroup("FacesY1",["FacesY"]) - cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) - fmts0=MEDFileFieldMultiTS() - fmts1=MEDFileFieldMultiTS() - pfl=DataArrayInt(31) ; pfl.iota() ; pfl.setName("PflOnQUAD4") - for i in xrange(30): - f1ts=MEDFileField1TS() - fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnFaces") - arr=DataArrayDouble(31) ; arr.iota() ; arr[i]=100. - fFaces.setArray(arr) - fFaces.setTime(float(i)+0.1,i,-1) - fFaces.setMesh(tmpFacesMesh[:31]) - f1ts.setFieldProfile(fFaces,cc,-1,pfl)# here, a test is done to check that "NORM_QUAD4" string is not 30 times appended at the end of pfl name. - self.assertEqual("PflOnQUAD4",pfl.getName()) - fmts0.pushBackTimeStep(f1ts) - # - f1ts=MEDFileField1TS() - fCells=MEDCouplingFieldDouble(ON_CELLS) ; fCells.setName("FieldOnCells") - arr=DataArrayDouble(24) ; arr.iota() ; arr[i%24]=30. - fCells.setArray(arr) - fCells.setTime(float(i)+0.1,i,-1) - fCells.setMesh(c) - f1ts.setFieldNoProfileSBT(fCells) - fmts1.pushBackTimeStep(f1ts) - pass - fs=MEDFileFields() - fs.pushField(fmts0) - fs.pushField(fmts1) - cc.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here CMesh is important - (a,b,c),d=mml2.buildVTUArrays() - self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure - self.assertTrue(a.isEqual(arrX,1e-12)) - self.assertTrue(b.isEqual(arrY,1e-12)) - self.assertTrue(c.isEqual(arrZ,1e-12)) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(24) ; myarr.iota() ; myarr[i%24]=30. - self.assertEqual(ffCell.getName(),"FieldOnCells") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc)# True because, the coords are computed by the implicit unstructured level -1 structured mesh - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,3.,1.,1.,3.,1.,2.,3.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.,0.,3.,2.,1.,3.,2.,2.,3.,2.,0.,0.,3.,1.,0.,3.,2.,0.,3.,0.,1.,3.,1.,1.,3.,2.,1.,3.,0.,2.,3.,1.,2.,3.,2.,2.,3.,0.,3.,3.,1.,3.,3.,2.,3.,3.,0.,0.,4.,1.,0.,4.,2.,0.,4.,0.,1.,4.,1.,1.,4.,2.,1.,4.,0.,2.,4.,1.,2.,4.,2.,2.,4.,0.,3.,4.,1.,3.,4.,2.,3.,4.],60,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,12,15,3,4,12,24,27,15,4,24,36,39,27,4,36,48,51,39,4,3,15,18,6,4,15,27,30,18,4,27,39,42,30,4,39,51,54,42,4,6,18,21,9,4,18,30,33,21,4,30,42,45,33,4,42,54,57,45,4,1,13,16,4,4,13,25,28,16,4,25,37,40,28,4,37,49,52,40,4,4,16,19,7,4,16,28,31,19,4,28,40,43,31,4,40,52,55,43,4,7,19,22,10,4,19,31,34,22,4,31,43,46,34,4,43,55,58,46,4,2,14,17,5,4,14,26,29,17,4,26,38,41,29,4,38,50,53,41,4,5,17,20,8,4,17,29,32,20,4,29,41,44,32]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6 is None) - self.assertTrue(a7) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(31) ; myarr.iota() ; myarr[i]=100. - self.assertEqual(ffCell.getName(),"FieldOnFaces") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test33(self): - """Non regression test concerning polygons. Thanks Adrien. This bug can't be shown by simply reading an displaying a MED file containing only polygons. A filter must be applied on it to show it. The a2 array was responsible of that bug.""" - fname="ForMEDReader33.med" - fieldName="ACellField" - coo=DataArrayDouble([(5.5,0.5),(5.5,-0.5),(6.5,0.5),(6.5,-0.5),(6.5,1.5),(7.5,0.5),(7.5,-0.5),(7.5,1.5),(7.5,2.5),(8.5,0.5),(8.5,-0.5),(8.5,1.5),(8.5,2.5),(8.5,3.5),(8.55,0.5),(8.55,-0.5),(8.55,1.5),(8.55,2.5),(8.55,3.5)]) - m=MEDCouplingUMesh("mesh",2) - m.setCoords(coo) - m.allocateCells() - for i,c in enumerate([(1,0,2,3),(3,2,5,6),(2,4,7,5),(6,5,9,10),(5,7,11,9),(7,8,12,11),(10,9,14,15),(9,11,16,14),(11,12,17,16),(12,13,18,17)]): - if i<6: - typ=NORM_QUAD4 - pass - else: - typ=NORM_POLYGON - pass - m.insertNextCell(typ,c) - pass - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.write(fname,2) - for i in xrange(15): - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i)+0.1,i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(m.getNumberOfCells()) ; arr.iota(0) ; arr[i%10]=100. - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]"]) - fCell0.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fCell0) - pass - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# false beacause 2D in MED file - self.assertTrue(a0.isEqual(DataArrayDouble([(5.5,0.5,0),(5.5,-0.5,0),(6.5,0.5,0),(6.5,-0.5,0),(6.5,1.5,0),(7.5,0.5,0),(7.5,-0.5,0),(7.5,1.5,0),(7.5,2.5,0),(8.5,0.5,0),(8.5,-0.5,0),(8.5,1.5,0),(8.5,2.5,0),(8.5,3.5,0),(8.55,0.5,0),(8.55,-0.5,0),(8.55,1.5,0),(8.55,2.5,0),(8.55,3.5,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,7,7,7,7]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45])))# the bug was here. - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,2,3,4,3,2,5,6,4,2,4,7,5,4,6,5,9,10,4,5,7,11,9,4,7,8,12,11,4,10,9,14,15,4,9,11,16,14,4,11,12,17,16,4,12,13,18,17]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(15): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(10) ; myarr.iota() ; myarr[i%10]=100. ; myarr.setInfoOnComponent(0,"Comp1 [m]") - self.assertEqual(ffCell.getName(),fieldName) - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test34(self): - """ This test is the thirs ultimate test (base on test12) for the profiles with gauss points. - This test highlight the hidden imp linked to bug #8655. - This test is close to test11 but here a 2nd field on cells without profile. So here the mesh is expected to be the same than m. - """ - fname="ForMEDReader34.med" - m=MEDCouplingCMesh("mesh") - arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*16) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0,fs1,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - if itmp.presenceOfMultiDiscPerGeoType(): - tmp2=itmp.splitMultiDiscrPerGeoTypes() - for iii,itmp2 in enumerate(tmp2): - name="%s_%i"%(itmp2.getName(),iii) - itmp2.setName(name) - allFMTSLeavesToDisplay2.append(itmp2) - pass - pass - else: - allFMTSLeavesToDisplay2.append(itmp) - pass - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - # Here 2 MED fields in input and at the end 5 ! 1+4 ! 4 fields have been built from zeField0 due to subspliting per dis / per geo type - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),5) - for i in xrange(5): - self.assertEqual(len(allFMTSLeavesPerCommonSupport[i][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[4][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) # <- here the mesh is NOT renumbered : the mesh is equal to m - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(0.,1.),(2.,3.),(14.,15.),(16.,17.),(18.,19.),(20.,21.),(22.,23.),(24.,25.),(44.,45.),(46.,47.),(126.,127.),(128.,129.)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(4.,5.),(6.,7.),(8.,9.),(10.,11.),(12.,13.),(26.,27.),(28.,29.),(30.,31.),(32.,33.),(34.,35.),(48.,49.),(50.,51.),(52.,53.),(54.,55.),(56.,57.),(58.,59.),(60.,61.),(62.,63.),(64.,65.),(66.,67.)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(36.,37.),(38.,39.),(40.,41.),(42.,43.),(68.,69.),(70.,71.),(72.,73.),(74.,75.),(104.,105.),(106.,107.),(108.,109.),(110.,111.)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[3][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(76,77),(78,79),(80,81),(82,83),(84,85),(86,87),(88,89),(90,91),(92,93),(94,95),(96,97),(98,99),(100,101),(102,103),(112,113),(114,115),(116,117),(118,119),(120,121),(122,123),(124,125)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[4][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(16*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test35(self): - """ Emulate MEDReader in // mode context. Here a Simple mesh having more nodes than really needed. This test focuses on that point particulary.""" - fname="ForMEDReader35.med" - arrX=DataArrayDouble(7) ; arrX.iota() - arrY=DataArrayDouble([0.,1.]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) ; m=m.buildUnstructured() ; m=m[[0,5,1,4,2,3]] ; m.changeSpaceDimension(3,0.) ; m.setName("Mesh") - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(m) ; f.setName("Field") ; f.setArray(DataArrayDouble([(0.1,1.1),(2.1,3.1),(4.1,5.1),(6.1,7.1),(8.1,9.1),(10.1,11.1)])) ; f.getArray().setInfoOnComponents(["aa","bbb"]) - MEDLoader.WriteUMesh(fname,m,True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes() # here we reproduce what is done by ParaMEDFileMeshes.ParaNew - ms.pushMesh(MEDFileUMesh.LoadPartOf(fname,"Mesh",[NORM_QUAD4],[0,2,1],-1,-1)); - ms[0].zipCoords() - # - fields=MEDFileFields.LoadPartOf(fname,False,ms); - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - if itmp.presenceOfMultiDiscPerGeoType(): - tmp2=itmp.splitMultiDiscrPerGeoTypes() - for iii,itmp2 in enumerate(tmp2): - name="%s_%i"%(itmp2.getName(),iii) - itmp2.setName(name) - allFMTSLeavesToDisplay2.append(itmp2) - pass - pass - else: - allFMTSLeavesToDisplay2.append(itmp) - pass - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - # - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(m.getCoords()[[0,1,5,6,7,8,12,13]],1e-12))# <- the aim of the test - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,4,5,4,3,2,6,7]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - f2=allFMTSLeavesPerCommonSupport[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f2,mst) - f2.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f2.getUndergroundDataArray()) - self.assertEqual(f2.getName(),f.getName()) - vExp=DataArrayDouble([(0.1,1.1),(2.1,3.1)]) - vExp.setInfoOnComponents(['aa','bbb']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test36(self): - """Bug EDF11027. Here mesh at level 0 (TRI3) does not fetch all the nodes. Level -1 (SEG2) does not fetch all the nodes neither. But all TRI3 + all SEG2 fetch all nodes. - aaa field on GAUSSPoints lying only on TRI3 share the same support than profile node field ccc. - But bbb field on all nodes is not on the same support. Past optimization that make the assumtion a support on all lev0 cells lies on all nodes is now over.""" - meshName="mesh" - fname="ForMEDReader36.med" - c=DataArrayDouble([(0,0),(1,0),(1,1),(0,1),(2,0),(-1,0),(1,2)]) - m0=MEDCoupling1SGTUMesh(meshName,NORM_TRI3) - m0.setCoords(c) - m0.setNodalConnectivity(DataArrayInt([0,2,1,3,2,0,2,4,1])) - mm=MEDFileUMesh() - mm[0]=m0 - m1=MEDCoupling1SGTUMesh(meshName,NORM_SEG2) - m1.setCoords(c) - m1.setNodalConnectivity(DataArrayInt([5,0,0,3,3,2,2,6])) - mm[-1]=m1 - # - zeTime=(1.1,2,3) - ff1=MEDFileField1TS() - f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setMesh(m0) - arr=DataArrayDouble(7) ; arr.iota(2000) - f1.setArray(arr) - f1.setName("bbb") - f1.checkCoherency() - f1.setTime(*zeTime) - ff1.setFieldNoProfileSBT(f1) - # - ff2=MEDFileField1TS() - f2=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f2.setMesh(m0) - arr=DataArrayDouble(9) ; arr.iota(4000) - f2.setArray(arr) - f2.setName("ddd") - f2.checkCoherency() - f2.setTime(*zeTime) - ff2.setFieldNoProfileSBT(f2) - # - ff3=MEDFileField1TS() - f3=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f3.setMesh(m0) - f3.setGaussLocalizationOnType(NORM_TRI3,[0,0,1,0,0,1],[0.333333,0.333333],[0.5]) - arr=DataArrayDouble(3) ; arr.iota(1000) - f3.setArray(arr) - f3.checkCoherency() - f3.setTime(*zeTime) - f3.setName("aaa") - ff3.setFieldNoProfileSBT(f3) - # - ff4=MEDFileField1TS() - m0d=m0.deepCpy() ; m0d.zipCoords() - f4=MEDCouplingFieldDouble(ON_NODES) ; f4.setMesh(m0d) - arr=DataArrayDouble(5) ; arr.iota(3000) - f4.setArray(arr) - f4.setName("ccc") - f4.checkCoherency() - f4.setTime(*zeTime) - pfl=DataArrayInt([0,1,2,3,4]) ; pfl.setName("PFL") - ff4.setFieldProfile(f4,mm,0,pfl) - # - mm.write(fname,2) - ff3.write(fname,0) - ff1.write(fname,0) - ff4.write(fname,0) - ### - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(2,0,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,2,1,3,3,2,0,3,2,4,1]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - v.isEqual(DataArrayDouble([1000,1001,1002]),1e-12) - # - ffCell=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - v.isEqual(DataArrayDouble([3000,3001,3002,3003,3004]),1e-12) - pass - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(2,0,0),(-1,0,0),(1,2,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,3,3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,15,18,21]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,2,1,3,3,2,0,3,2,4,1,2,5,0,2,0,3,2,3,2,2,2,6]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1): - ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - v.isEqual(DataArrayDouble([2000,2001,2002,2003,2004,2005,2006]),1e-12) - pass - pass - - pass - -if __name__ == "__main__": - unittest.main() diff --git a/medtool/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/medtool/src/MEDLoader/Swig/MEDLoaderTypemaps.i deleted file mode 100644 index 5a415a685..000000000 --- a/medtool/src/MEDLoader/Swig/MEDLoaderTypemaps.i +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include <vector> - -static PyObject *convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!mesh) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileUMesh,owner); - if(dynamic_cast<ParaMEDMEM::MEDFileCMesh *>(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCMesh,owner); - if(dynamic_cast<ParaMEDMEM::MEDFileCurveLinearMesh *>(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCurveLinearMesh,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileMesh on downcast !"); - return ret; -} - -static PyObject *convertMEDFileParameter1TS(ParaMEDMEM::MEDFileParameter1TS* p1ts, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p1ts) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDFileParameterDouble1TS *>(p1ts)) - ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_ParaMEDMEM__MEDFileParameterDouble1TS,owner); - if(dynamic_cast<MEDFileParameterDouble1TSWTI *>(p1ts)) - ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_ParaMEDMEM__MEDFileParameterDouble1TSWTI,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileParameter1TS on downcast !"); - return ret; -} - -static PyObject *convertMEDFileField1TS(ParaMEDMEM::MEDFileAnyTypeField1TS *p, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDFileField1TS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileField1TS,owner); - if(dynamic_cast<MEDFileIntField1TS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileIntField1TS,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeField1TS on downcast !"); - return ret; -} - -static PyObject *convertMEDFileFieldMultiTS(ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *p, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDFileFieldMultiTS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileFieldMultiTS,owner); - if(dynamic_cast<MEDFileIntFieldMultiTS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileIntFieldMultiTS,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeFieldMultiTS on downcast !"); - return ret; -} - -static PyObject *convertMEDMeshMultiLev(ParaMEDMEM::MEDMeshMultiLev *p, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDUMeshMultiLev *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDUMeshMultiLev,owner); - if(dynamic_cast<MEDCMeshMultiLev *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCMeshMultiLev,owner); - if(dynamic_cast<MEDCurveLinearMeshMultiLev *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCurveLinearMeshMultiLev,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDMeshMultiLev on downcast !"); - return ret; -} - -static std::vector<std::pair<int,int> > convertTimePairIdsFromPy(PyObject *pyLi) throw(INTERP_KERNEL::Exception) -{ - std::vector<std::pair<int,int> > ret; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(PyTuple_Check(o)) - { - std::pair<int,int> p; - int size2=PyTuple_Size(o); - if(size2!=2) - throw INTERP_KERNEL::Exception("tuples in list must be of size 2 (dt,it) !"); - PyObject *o0=PyTuple_GetItem(o,0); - if(PyInt_Check(o0)) - p.first=(int)PyInt_AS_LONG(o0); - else - throw INTERP_KERNEL::Exception("First elem of tuples in list must be integer : dt !"); - PyObject *o1=PyTuple_GetItem(o,1); - if(PyInt_Check(o1)) - p.second=(int)PyInt_AS_LONG(o1); - else - throw INTERP_KERNEL::Exception("Second elem of tuples in list must be integer : dt !"); - ret[i]=p; - } - else - throw INTERP_KERNEL::Exception("list must contain tuples only"); - } - } - else - throw INTERP_KERNEL::Exception("convertTimePairIdsFromPy : not a list"); - return ret; -} - -static void converPyListToVecString(PyObject *pyLi, std::vector<std::string>& v) -{ - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - v.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(!PyString_Check(o)) - throw INTERP_KERNEL::Exception("In list passed in argument some elements are NOT strings ! Expected a list containing only strings !"); - const char *st=PyString_AsString(o); - v[i]=std::string(st); - } - } - else if(PyTuple_Check(pyLi)) - { - int size=PyTuple_Size(pyLi); - v.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyTuple_GetItem(pyLi,i); - if(!PyString_Check(o)) - throw INTERP_KERNEL::Exception("In tuple passed in argument some elements are NOT strings ! Expected a tuple containing only strings !"); - const char *st=PyString_AsString(o); - v[i]=std::string(st); - } - } - else if(PyString_Check(pyLi)) - { - v.resize(1); - v[0]=std::string((const char *)PyString_AsString(pyLi)); - } - else - { - throw INTERP_KERNEL::Exception("Unrecognized python argument : expected a list of string or tuple of string or string !"); - } -} - -static PyObject *convertFieldDoubleVecToPy(const std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>& li) -{ - int sz=li.size(); - PyObject *ret=PyList_New(sz); - for(int i=0;i<sz;i++) - { - PyObject *o=SWIG_NewPointerObj((void*)li[i],SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,SWIG_POINTER_OWN | 0); - PyList_SetItem(ret,i,o); - } - return ret; -} - -PyObject *convertVecPairVecStToPy(const std::vector< std::pair<std::vector<std::string>, std::string > >& vec) -{ - int sz=(int)vec.size(); - PyObject *ret=PyList_New(sz); - for(int i=0;i<sz;i++) - { - PyObject *t=PyTuple_New(2); - int sz2=(int)vec[i].first.size(); - PyObject *ll=PyList_New(sz2); - for(int j=0;j<sz2;j++) - PyList_SetItem(ll,j,PyString_FromString(vec[i].first[j].c_str())); - PyTuple_SetItem(t,0,ll); - PyTuple_SetItem(t,1,PyString_FromString(vec[i].second.c_str())); - PyList_SetItem(ret,i,t); - } - return ret; -} - -std::vector< std::pair<std::string, std::string > > convertVecPairStStFromPy(PyObject *pyLi) -{ - std::vector< std::pair<std::string, std::string > > ret; - const char *msg="convertVecPairStStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is one string and the 2nd one a string !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(PyTuple_Check(o)) - { - std::pair<std::string, std::string> p; - int size2=PyTuple_Size(o); - if(size2!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *o0=PyTuple_GetItem(o,0); - if(PyString_Check(o0)) - p.first=std::string(PyString_AsString(o0)); - else - throw INTERP_KERNEL::Exception(msg); - PyObject *o1=PyTuple_GetItem(o,1); - if(PyString_Check(o1)) - p.second=std::string(PyString_AsString(o1)); - else - throw INTERP_KERNEL::Exception(msg); - ret[i]=p; - } - else - throw INTERP_KERNEL::Exception(msg); - } - return ret; - } - throw INTERP_KERNEL::Exception(msg); -} - -std::vector< std::pair<std::vector<std::string>, std::string > > convertVecPairVecStFromPy(PyObject *pyLi) -{ - std::vector< std::pair<std::vector<std::string>, std::string > > ret; - const char *msg="convertVecPairVecStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is a list of strings and the 2nd one a string !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(PyTuple_Check(o)) - { - std::pair<std::vector<std::string>, std::string> p; - int size2=PyTuple_Size(o); - if(size2!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *o0=PyTuple_GetItem(o,0); - if(PyList_Check(o0)) - { - int size3=PyList_Size(o0); - p.first.resize(size3); - for(int j=0;j<size3;j++) - { - PyObject *o0j=PyList_GetItem(o0,j); - if(PyString_Check(o0j)) - { - p.first[j]=std::string(PyString_AsString(o0j)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - } - else - throw INTERP_KERNEL::Exception(msg); - PyObject *o1=PyTuple_GetItem(o,1); - if(PyString_Check(o1)) - p.second=std::string(PyString_AsString(o1)); - else - throw INTERP_KERNEL::Exception(msg); - ret[i]=p; - } - else - throw INTERP_KERNEL::Exception(msg); - } - return ret; - } - throw INTERP_KERNEL::Exception(msg); -} - -/*! - * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a elt0 is neither a list nor a slice. - * In this case a MEDFileAnyTypeField1TS object is returned. - */ -int MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(const MEDFileAnyTypeFieldMultiTS *self, PyObject *elt0) throw(INTERP_KERNEL::Exception) -{ - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - return InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); - } - else if(elt0 && PyTuple_Check(elt0)) - { - if(PyTuple_Size(elt0)==2) - { - PyObject *o0=PyTuple_GetItem(elt0,0); - PyObject *o1=PyTuple_GetItem(elt0,1); - if(PyInt_Check(o0) && PyInt_Check(o1)) - {//fmts(1,-1) - int iter=PyInt_AS_LONG(o0); - int order=PyInt_AS_LONG(o1); - return self->getPosOfTimeStep(iter,order); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); - } - else if(elt0 && PyFloat_Check(elt0)) - { - double val=PyFloat_AS_DOUBLE(elt0); - return self->getPosGivenTime(val); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int], or fmts[double] to request one time step ! To request a series of time steps invoke fmts[slice], fmts[list of int], fmts[list of double], or fmts[list of int,int] !"); -} - -/*! - * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a obj is neither a list nor a slice. - * In this case a MEDFileAnyTypeField1TS object is returned. - */ -int MEDFileFieldsgetitemSingleTS__(const MEDFileFields *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - if(PyInt_Check(obj)) - { - return InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfFields()); - } - else if(PyString_Check(obj)) - { - return self->getPosFromFieldName(PyString_AsString(obj)); - } - else - throw INTERP_KERNEL::Exception("MEDFileFields::__getitem__ : only integer or string with fieldname supported !"); -} diff --git a/medtool/src/MEDLoader/Swig/SauvLoaderTest.py b/medtool/src/MEDLoader/Swig/SauvLoaderTest.py deleted file mode 100644 index cab156183..000000000 --- a/medtool/src/MEDLoader/Swig/SauvLoaderTest.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Edward AGAPOV (eap) - -from MEDLoader import * -import unittest, os -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class SauvLoaderTest(unittest.TestCase): - - def __getResourcesDirectory(self): - med_root_dir=os.getenv("MEDCOUPLING_ROOT_DIR") - if med_root_dir: - return os.path.join( os.getenv("MEDCOUPLING_ROOT_DIR"), "share","resources","med") - else: - current_dir = os.path.dirname(os.path.realpath(__file__)) - return os.path.join(current_dir, "..", "..", "..", "resources") - pass - - def testSauv2Med(self): - # get a file containing all types of readable piles - sauvFile = os.path.join( self.__getResourcesDirectory(),"allPillesTest.sauv") - self.assertTrue( os.access( sauvFile, os.F_OK)) - - # read SAUV and write MED - medFile = "SauvLoaderTest.med" - sr=SauvReader(sauvFile); - d2=sr.loadInMEDFileDS(); - d2.write(medFile,0); - - # check - self.assertEqual(1,d2.getNumberOfMeshes()) - self.assertEqual(8+97,d2.getNumberOfFields()) - mm = d2.getMeshes() - m = mm.getMeshAtPos(0) - self.assertEqual(17,len(m.getGroupsNames())) - - os.remove( medFile ) - pass - - def testMed2Sauv(self): - # read pointe.med - medFile = os.path.join(self.__getResourcesDirectory(),"pointe.med") - self.assertTrue( os.access( medFile, os.F_OK)) - pointeMed = MEDFileData.New( medFile ) - - # add 3 faces to pointeMed - pointeMedMesh = pointeMed.getMeshes().getMeshAtPos(0) - pointeM1D = MEDCouplingUMesh.New() - pointeM1D.setCoords( pointeMedMesh.getCoords() ) - pointeM1D.setMeshDimension( 2 ) - pointeM1D.allocateCells( 3 ) - pointeM1D.insertNextCell( NORM_TRI3, 3, [0,1,2]) - pointeM1D.insertNextCell( NORM_TRI3, 3, [0,1,3]) - pointeM1D.insertNextCell( NORM_QUAD4, 4, [10,11,12,13]) - pointeM1D.finishInsertingCells() - pointeMedMesh.setMeshAtLevel( -1, pointeM1D ) - pointeMed.getMeshes().setMeshAtPos( 0, pointeMedMesh ) - - # add a field on 2 faces to pointeMed - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) - #f1.setMesh( pointeM1D ) - f1.setName("Field on 2 faces") - d=DataArrayDouble.New() - d.alloc(3+4,2) - d.setInfoOnComponent(0,"sigX [MPa]") - d.setInfoOnComponent(1,"sigY [GPa]") - d.setValues([311,312,321,322,331,332,411,412,421,422,431,432,441,442],3+4,2) - f1.setArray(d) - da=DataArrayInt.New() - da.setValues([0,2],2,1) - da.setName("sup2") - ff1.appendFieldProfile(f1,pointeMedMesh,-1,da) - pointeMed.getFields().pushField( ff1 ) - - #remove fieldnodeint - pointeFields = pointeMed.getFields() - for i in range( pointeFields.getNumberOfFields() ): - if pointeFields.getFieldAtPos(i).getName() == "fieldnodeint": - pointeFields.destroyFieldAtPos( i ) - break - - # write pointeMed to SAUV - sauvFile = "SauvLoaderTest.sauv" - sw=SauvWriter(); - sw.setMEDFileDS(pointeMed); - sw.write(sauvFile); - - # read SAUV and check - sr=SauvReader.New(sauvFile); - d2=sr.loadInMEDFileDS(); - self.assertEqual(1,d2.getNumberOfMeshes()) - self.assertEqual(4,d2.getNumberOfFields()) - m = d2.getMeshes().getMeshAtPos(0) - self.assertEqual("maa1",m.getName()) - self.assertEqual(6,len(m.getGroupsNames())) - self.assertEqual(3,m.getMeshDimension()) - groups = m.getGroupsNames() - self.assertTrue( "groupe1" in groups ) - self.assertTrue( "groupe2" in groups ) - self.assertTrue( "groupe3" in groups ) - self.assertTrue( "groupe4" in groups ) - self.assertTrue( "groupe5" in groups ) - self.assertTrue( "maa1" in groups ) - self.assertEqual(16,m.getSizeAtLevel(0)) - um0 = m.getGenMeshAtLevel(0) - self.assertEqual(12, um0.getNumberOfCellsWithType( NORM_TETRA4 )) - self.assertEqual(2, um0.getNumberOfCellsWithType( NORM_PYRA5 )) - self.assertEqual(2, um0.getNumberOfCellsWithType( NORM_HEXA8 )) - um1 = m.getGenMeshAtLevel(-1) - self.assertEqual(2, um1.getNumberOfCellsWithType( NORM_TRI3 )) - pointeUM0 = pointeMedMesh.getGenMeshAtLevel(0) - self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(pointeMedMesh.getCoords(),1e-12)) - self.assertEqual( um0.getMeasureField(0).accumulate(0), - pointeUM0.getMeasureField(0).accumulate(0),1e-12) - # check fields - # fieldnodedouble - fieldnodedoubleTS1 = pointeMed.getFields().getFieldWithName("fieldnodedouble") - fieldnodedoubleTS2 = d2.getFields().getFieldWithName("fieldnodedouble") - self.assertEqual( fieldnodedoubleTS1.getInfo(), fieldnodedoubleTS2.getInfo()) - self.assertEqual( fieldnodedoubleTS1.getNumberOfTS(), fieldnodedoubleTS2.getNumberOfTS()) - io1 = fieldnodedoubleTS1.getIterations() - io2 = fieldnodedoubleTS2.getIterations() - for i in range(fieldnodedoubleTS1.getNumberOfTS() ): - fnd1 = fieldnodedoubleTS1.getFieldOnMeshAtLevel(ON_NODES, io1[i][0],io1[i][1],pointeUM0) - fnd2 = fieldnodedoubleTS2.getFieldOnMeshAtLevel(ON_NODES, io2[i][0],io2[i][1],um0) - self.assertTrue( fnd1.getArray().isEqual( fnd2.getArray(), 1e-12 )) - # fieldcelldoublevector - fieldnodedoubleTS1 = pointeMed.getFields().getFieldWithName("fieldcelldoublevector") - fieldnodedoubleTS2 = d2.getFields().getFieldWithName("fieldcelldoublevector") - self.assertEqual( fieldnodedoubleTS1.getInfo(), fieldnodedoubleTS2.getInfo()) - self.assertEqual( fieldnodedoubleTS1.getNumberOfTS(), fieldnodedoubleTS2.getNumberOfTS()) - io1 = fieldnodedoubleTS1.getIterations() - io2 = fieldnodedoubleTS2.getIterations() - for i in range(fieldnodedoubleTS1.getNumberOfTS() ): - fnd1 = fieldnodedoubleTS1.getFieldOnMeshAtLevel(ON_CELLS, io1[i][0],io1[i][1],pointeUM0) - fnd2 = fieldnodedoubleTS2.getFieldOnMeshAtLevel(ON_CELLS, io2[i][0],io2[i][1],um0) - self.assertAlmostEqual( fnd1.accumulate(0), fnd2.accumulate(0) ) - self.assertAlmostEqual( fnd1.accumulate(1), fnd2.accumulate(1) ) - self.assertAlmostEqual( fnd1.accumulate(2), fnd2.accumulate(2) ) - # Field on 2 faces - fieldOnFaces = d2.getFields().getFieldWithName(f1.getName()) - io1 = fieldOnFaces.getIterations() - fof = fieldOnFaces.getFieldOnMeshAtLevel(f1.getTypeOfField(),io1[i][0],io1[i][1],um1) - self.assertTrue( d.isEqual( fof.getArray(), 1e-12 )) - pass - del sr - os.remove( sauvFile ) - pass - - def testSauv2MedWONodeFamilyNum(self): - """test for issue 0021673: [CEA 566] Bug in SauvWriter when writing meshes - having no family ids on nodes.""" - - myCoords=DataArrayDouble.New([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2) - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - targetMesh=MEDCouplingUMesh.New("BugInSauvWriter",2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - targetMesh.setCoords(myCoords); - # - m=MEDFileUMesh.New() - m.setMeshAtLevel(0,targetMesh) - # start of bug - fam=DataArrayInt.New(targetMesh.getNumberOfNodes()) - fam[:]=0 - #m.setFamilyFieldArr(1,fam) - #end of bug - - ms=MEDFileMeshes.New() - ms.setMeshAtPos(0,m) - meddata=MEDFileData.New() - meddata.setMeshes(ms) - - medFile = "BugInSauvWriter.sauv" - sw=SauvWriter.New(); - sw.setMEDFileDS(meddata); - sw.write(medFile); - - os.remove( medFile ) - pass - - def testSauv2MedOnPipe1D(self): - """test for issue 0021745: [CEA 600] Some missing groups in mesh after reading a SAUV file with SauvReader.""" - sauvFile="Test_sauve_1D.sauv" - # Make a sauve file with a qudratic 1D mesh - m=MEDCouplingUMesh.New("pipe1D",1) - m.allocateCells(2); - targetConn=[0,2,1, 2,4,3] - m.insertNextCell(NORM_SEG3,3,targetConn[0:3]) - m.insertNextCell(NORM_SEG3,3,targetConn[3:6]) - m.finishInsertingCells(); - # coords - coords=[ 0.,1.,2.,4.,5. ]; - c=DataArrayDouble.New() - c.setValues(coords,5,1) - m.setCoords(c) - # MEDFileUMesh - mm=MEDFileUMesh.New() - mm.setName(m.getName()) - mm.setDescription("1D mesh") - mm.setCoords(c) - mm.setMeshAtLevel(0,m); - # MEDFileData - mfd1 = MEDFileData.New() - ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm) - mfd1.setMeshes(ms) - # write - sw=SauvWriter.New() - sw.setMEDFileDS(mfd1) - sw.write(sauvFile) - # Check connectivity read from the sauv file - sr = SauvReader.New(sauvFile) - mfd2 = sr.loadInMEDFileDS() - mfMesh = mfd2.getMeshes()[0] - mesh = mfMesh.getMeshAtLevel(0) - self.assertTrue(mesh.getNodalConnectivity().isEqual(m.getNodalConnectivity())) - # - del sr - os.remove(sauvFile) - pass - - @unittest.skipUnless(MEDLoader.HasXDR(),"requires XDR") - def testMissingGroups(self): - """test for issue 0021749: [CEA 601] Some missing groups in mesh after reading a SAUV file with SauvReader.""" - sauvFile = os.path.join(self.__getResourcesDirectory(),"BDC-714.sauv") - self.assertTrue( os.access( sauvFile, os.F_OK)) - name_of_group_on_cells='Slice10:ABSORBER' - name_of_group_on_cells2='Slice10:00LR' - sr=SauvReader.New(sauvFile) - mfd2=sr.loadInMEDFileDS() - mfMesh=mfd2.getMeshes()[0] - # - self.assertTrue(name_of_group_on_cells in mfMesh.getGroupsNames()) - self.assertTrue(name_of_group_on_cells2 in mfMesh.getGroupsNames()) - self.assertEqual(270,len(mfMesh.getGroupsNames())) - # - ids1=mfMesh.getGroupArr(0,name_of_group_on_cells) - ids2=mfMesh.getGroupArr(0,name_of_group_on_cells2) - ids1.setName("") - ids2.setName("") - self.assertTrue(ids1.isEqual(ids2)) - pass - - def testGaussPt(self): - """issue 22321: [CEA 933] Bug when reading a sauve file containing field on Gauss Pt. - The problem was that a field ON_GAUSS_PT was created but no Gauss Localization - was defined""" - - # create a MEDFileData with a field ON_GAUSS_PT: 9 Gauss points, on 4 QUAD8 elements - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - m=MEDCouplingUMesh("mesh",2) ; m.allocateCells() - m.insertNextCell(NORM_QUAD8,[0,2,4,6,1,3,5,7]) - m.insertNextCell(NORM_QUAD8,[2,9,11,4,8,10,12,3]) - m.insertNextCell(NORM_QUAD8,[6,4,14,16,5,13,15,17]) - m.insertNextCell(NORM_QUAD8,[4,11,19,14,12,18,20,13]) - m.setCoords(DataArrayDouble([(0,0),(0,0.25),(0,0.5),(0.25,0.5),(0.5,0.5),(0.5,0.25),(0.5,0),(0.25,0),(0,0.75),(0,1),(0.25,1),(0.5,1),(0.5,0.75),(0.75,0.5),(1,0.5),(1,0.25),(1,0),(0.75,0),(0.75,1),(1,1),(1,0.75)],21,2)) - f.setMesh(m) - arr=DataArrayDouble(4*9*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["YOUN []","NU []"]) - f.setArray(arr) - refCoo=[-1,-1,1,-1,1,1,-1,1,0,-1,1,0,0,1,-1,0] - gpCoo=[-0.7,-0.7,0.7,-0.7,0.7,0.7,-0.7,0.7,0,-0.7,0.7,0,0,0.7,-0.7,0,0,0] - wgt=[0.3,0.3,0.3,0.3,0.4,0.4,0.4,0.4,0.7] - f.setGaussLocalizationOnType(NORM_QUAD8,refCoo,gpCoo,wgt) - f.setName("SIGT") - f.checkCoherency() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mfm = MEDFileMeshes() - mfm.pushMesh( mm ) - ff=MEDFileField1TS() - ff.setFieldNoProfileSBT(f) - mfmts = MEDFileFieldMultiTS() - mfmts.pushBackTimeStep(ff) - mff = MEDFileFields() - mff.pushField( mfmts ) - mfd = MEDFileData.New() - mfd.setFields( mff ) - mfd.setMeshes( mfm ) - - # convert the MED file to a SAUV file - sauvFile = "SauvLoaderTest_testGaussPt.sauv" - sw=SauvWriter.New(); - sw.setMEDFileDS(mfd); - sw.write(sauvFile); - - # convert the SAUV file back to MED - sr=SauvReader.New(sauvFile); - d2=sr.loadInMEDFileDS(); - - self.assertEqual( 1, d2.getNumberOfFields() ) - self.assertEqual( 1, d2.getNumberOfMeshes() ) - mfm2 = d2.getMeshes()[0] - mff2 = d2.getFields()[0] - m2 = mfm2.getMeshAtLevel(0) - f2 = mff2.getTimeStepAtPos(0).getFieldOnMeshAtLevel(f.getTypeOfField(),0,mfm2) - f2.setGaussLocalizationOnType(NORM_QUAD8,refCoo,gpCoo,wgt) # not stored in SAUV - #f2.setOrder( f.getTime()[2] ) # not stored in SAUV - self.assertTrue( m2.isEqual( m, 1e-12 )) - self.assertTrue( f2.isEqual( f, 1e-12, 1e-12 )) - del sr - os.remove( sauvFile ) - pass - - def testSauvWriterGroupWithOneFamily(self): - """ - This test checks an option for sauv writing. It is requested here to copy a group from a family if a group is lying on a single family. - """ - import re - mfd=MEDLoaderDataForTest.buildAMEDFileDataWithGroupOnOneFamilyForSauv() - sauvFile = "mesh.sauv" - sw=SauvWriter.New() - sw.setMEDFileDS(mfd) - self.assertTrue(not sw.getCpyGrpIfOnASingleFamilyStatus()) - sw.setCpyGrpIfOnASingleFamilyStatus(True) - self.assertTrue(sw.getCpyGrpIfOnASingleFamilyStatus()) - sw.write(sauvFile) - - f = open(sauvFile) - # String pattern for the header of the sub meshes record ("PILE" number, number of named objects, number of objects) - pattern_pile= re.compile(r'\sPILE\sNUMERO\s+(?P<number>[0-9]+)NBRE\sOBJETS\sNOMMES\s+(?P<nbnamed>[0-9]+)NBRE\sOBJETS\s+(?P<nbobjects>[0-9]+)') - # String pattern for a sub mesh header (cell type, number of components and three numbers) - pattern_header=re.compile(r'\s+(?P<type>[0-9]+)\s+(?P<nbsubs>[0-9]+)\s+[0-9]+\s+[0-9]+\s+[0-9]+') - - nbobjects=0 - line = f.readline() - while(line): - match_pile = pattern_pile.match(line) - if match_pile: - number=int(match_pile.group("number")) - if number == 1: - nbnamed=int(match_pile.group("nbnamed")) - nbobjects=int(match_pile.group("nbobjects")) - break - pass - line=f.readline() - pass - - # Skipping the objects names - f.readline() - # Skipping the objects ids - f.readline() - - # Looking for each sub-mesh header - line = f.readline() - cur_object=0 - while(line and cur_object < nbobjects): - match_header=pattern_header.match(line) - if match_header: - cell_type=int(match_header.group("type")) - nb_subs=int(match_header.group("nbsubs")) - # Looking for a compound object - if cell_type == 0: - # Testing if there is only one component - self.assertTrue(nb_subs > 1) - else: - f.readline() - f.readline() - cur_object = cur_object + 1 - pass - pass - line=f.readline() - pass - f.close() - os.remove(sauvFile) - pass - - pass - -unittest.main() diff --git a/medtool/src/MEDLoader/Swig/VTKReader.py b/medtool/src/MEDLoader/Swig/VTKReader.py deleted file mode 100644 index b54174459..000000000 --- a/medtool/src/MEDLoader/Swig/VTKReader.py +++ /dev/null @@ -1,306 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF) - -from MEDLoader import * - -class PVDReader: - @classmethod - def New(cls,fileName): - """ Static constructor. """ - return PVDReader(fileName) - pass - - def __init__(self,fileName): - self._fileName=fileName - pass - - def loadTopInfo(self): - fd=open(self._fileName,"r") - return self.__parseXML(fd) - - def __parseXML(self,fd): - import xml.sax - class PVD_SAX_Reader(xml.sax.ContentHandler): - def __init__(self): - self._tsteps=[] - pass - def startElement(self,name,attrs): - if name=="VTKFile": - if attrs["type"]!="Collection": - raise Exception("Mismatch between reader (PVD) type and file content !") - return - if name=="DataSet": - self._tsteps.append((float(attrs["timestep"]),str(attrs["file"]))) - return - pass - pass - rd=PVD_SAX_Reader() - parser=xml.sax.make_parser() - parser.setContentHandler(rd) - parser.parse(fd) - return rd - pass - -class PVTUReader: - @classmethod - def New(cls,fileName): - """ Static constructor. """ - return PVTUReader(fileName) - pass - - def __init__(self,fileName): - self._fileName=fileName - pass - - def loadParaInfo(self): - fd=open(self._fileName,"r") - return self.__parseXML(fd) - - def __parseXML(self,fd): - import xml.sax - class PVTU_SAX_Reader(xml.sax.ContentHandler): - def __init__(self): - self._data_array={2:self.DAPointData,3:self.DACellData} - self._node_fields=[] - self._cell_fields=[] - self._pfiles=[] - self._tmp=None - pass - def DAPointData(self,attrs): - self._node_fields.append((str(attrs["Name"]),int(attrs["NumberOfComponents"]))) - pass - def DACellData(self,attrs): - self._cell_fields.append((str(attrs["Name"]),int(attrs["NumberOfComponents"]))) - pass - def startElement(self,name,attrs): - if name=="VTKFile": - if attrs["type"]!="PUnstructuredGrid": - raise Exception("Mismatch between reader (PVTU) type and file content !") - return - if name=="Piece": - self._pfiles.append(str(attrs["Source"])) - return - if name=="PPointData": - self._tmp=2 - return - if name=="PCellData": - self._tmp=3 - return - if name=="PDataArray": - if self._tmp in self._data_array.keys(): - self._data_array[self._tmp](attrs) - pass - return - pass - pass - rd=PVTU_SAX_Reader() - parser=xml.sax.make_parser() - parser.setContentHandler(rd) - parser.parse(fd) - return rd - pass - -class VTURawReader: - """ Converting a VTU file in raw mode into the MED format. - """ - VTKTypes_2_MC=[-1,0,-1,1,33,3,-1,5,-1,4,14,-1,NORM_HEXA8,16,15,-1,22,-1,-1,-1,-1,2,6,8,20,30,25,23,9,27,-1,-1,-1,-1,7,-1,-1,-1,-1,-1,-1,-1,31] - - class NormalException(Exception): - def __init__(self,lineNb): - Exception.__init__(self) - self._line_nb=lineNb - def getLineNb(self): - return self._line_nb - pass - - class NotRawVTUException(Exception): - pass - - def loadInMEDFileDS(self): - import numpy as np - fd=open(self._fileName,"r") - ref,rd=self.__parseXML(fd) - # - ret=MEDFileData() - ms=MEDFileMeshes() ; ret.setMeshes(ms) - fs=MEDFileFields() ; ret.setFields(fs) - # - types=np.memmap(fd,dtype=rd._type_types,mode='r',offset=ref+rd._off_types,shape=(rd._nb_cells,)) - types=self.__swapIfNecessary(rd._bo,types) - # mesh dimension detection - types2=types.copy() ; types2.sort() ; types2=np.unique(types2) - meshDim=MEDCouplingMesh.GetDimensionOfGeometricType(self.VTKTypes_2_MC[types2[0]]) - for typ in types2[1:]: - md=MEDCouplingMesh.GetDimensionOfGeometricType(self.VTKTypes_2_MC[typ]) - if md!=meshDim: - raise Exception("MultiLevel umeshes not managed yet !") - pass - m=MEDCouplingUMesh("mesh",meshDim) - # coordinates - coo=np.memmap(fd,dtype=rd._type_coords,mode='r',offset=ref+rd._off_coords,shape=(rd._nb_nodes*rd._space_dim,)) - coo=self.__swapIfNecessary(rd._bo,coo) ; coo=DataArrayDouble(np.array(coo,dtype='float64')) ; coo.rearrange(rd._space_dim) - m.setCoords(coo) - # connectivity - offsets=np.memmap(fd,dtype=rd._type_off,mode='r',offset=ref+rd._off_off,shape=(rd._nb_cells,)) - offsets=self.__swapIfNecessary(rd._bo,offsets) ; connLgth=offsets[-1] ; offsets2=DataArrayInt(rd._nb_cells+1) ; offsets2.setIJ(0,0,0) - offsets2[1:]=DataArrayInt(offsets) - offsets3=offsets2.deltaShiftIndex() ; offsets2=offsets3.deepCpy() ; offsets3+=1 ; offsets3.computeOffsets2() - offsets=offsets3 - tmp1=DataArrayInt(len(offsets2),2) ; tmp1[:,0]=1 ; tmp1[:,1]=offsets2 ; tmp1.rearrange(1) ; tmp1.computeOffsets2() - tmp1=DataArrayInt.Range(1,2*len(offsets2),2).buildExplicitArrByRanges(tmp1) - conn=np.memmap(fd,dtype=rd._type_conn,mode='r',offset=ref+rd._off_conn,shape=(connLgth,)) - conn=self.__swapIfNecessary(rd._bo,conn) - types=np.array(types,dtype='int32') ; types=DataArrayInt(types) ; types.transformWithIndArr(self.VTKTypes_2_MC) - conn2=DataArrayInt(offsets.back()) - conn2[offsets[0:-1]]=types - conn2[tmp1]=DataArrayInt(conn) - m.setConnectivity(conn2,offsets,True) - m.checkCoherency() ; mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; ms.pushMesh(mm) - # Fields on nodes and on cells - for spatialDisc,nbEnt,fields in [(ON_NODES,rd._nb_nodes,rd._node_fields),(ON_CELLS,rd._nb_cells,rd._cell_fields)]: - for name,typ,nbCompo,off in fields: - ff=MEDFileFieldMultiTS() - f=MEDCouplingFieldDouble(spatialDisc,ONE_TIME) - f.setName(name) ; f.setMesh(m) - vals=np.memmap(fd,dtype=typ,mode='r',offset=ref+off,shape=(nbEnt*nbCompo)) - vals=self.__swapIfNecessary(rd._bo,vals) - arr=DataArrayDouble(np.array(vals,dtype='float64')) ; arr.rearrange(nbCompo) - f.setArray(arr) ; f.checkCoherency() - f.setTime(self._time[0],self._time[1],0) - ff.appendFieldNoProfileSBT(f) - fs.pushField(ff) - pass - pass - return ret - - def __parseXML(self,fd): - import xml.sax - class VTU_SAX_Reader(xml.sax.ContentHandler): - def __init__(self): - self._loc=None - self._data_array={0:self.DAPoints,1:self.DACells,2:self.DAPointData,3:self.DACellData} - self._node_fields=[] - self._cell_fields=[] - pass - def setLocator(self,loc): - self._loc=loc - def DAPoints(self,attrs): - self._space_dim=int(attrs["NumberOfComponents"]) - self._type_coords=str(attrs["type"]).lower() - self._off_coords=int(attrs["offset"]) - pass - def DACells(self,attrs): - if attrs["Name"]=="connectivity": - self._type_conn=str(attrs["type"]).lower() - self._off_conn=int(attrs["offset"]) - pass - if attrs["Name"]=="offsets": - self._type_off=str(attrs["type"]).lower() - self._off_off=int(attrs["offset"]) - pass - if attrs["Name"]=="types": - self._type_types=str(attrs["type"]).lower() - self._off_types=int(attrs["offset"]) - pass - pass - def DAPointData(self,attrs): - self._node_fields.append((str(attrs["Name"]),str(attrs["type"]).lower(),int(attrs["NumberOfComponents"]),int(attrs["offset"]))) - pass - def DACellData(self,attrs): - self._cell_fields.append((str(attrs["Name"]),str(attrs["type"]).lower(),int(attrs["NumberOfComponents"]),int(attrs["offset"]))) - pass - def startElement(self,name,attrs): - if name=="VTKFile": - if attrs["type"]!="UnstructuredGrid": - raise Exception("Mismatch between reader (VTU) type and file content !") - self._bo=bool(["LittleEndian","BigEndian"].index(attrs["byte_order"])) - pass - if name=="Piece": - self._nb_cells=int(attrs["NumberOfCells"]) - self._nb_nodes=int(attrs["NumberOfPoints"]) - return - if name=="Points": - self._tmp=0 - return - if name=="Cells": - self._tmp=1 - return - if name=="PointData": - self._tmp=2 - return - if name=="CellData": - self._tmp=3 - return - if name=="DataArray": - self._data_array[self._tmp](attrs) - return - if name=="AppendedData": - if str(attrs["encoding"])=="raw": - raise VTURawReader.NormalException(self._loc.getLineNumber()) - else: - raise VTURawReader.NotRawVTUException("The file is not a raw VTU ! Change reader !") - pass - pass - rd=VTU_SAX_Reader() - parser=xml.sax.make_parser() - parser.setContentHandler(rd) - locator=xml.sax.expatreader.ExpatLocator(parser) - rd.setLocator(locator) - isOK=False - try: - parser.parse(fd) - except self.NormalException as e: - isOK=True - fd.seek(0) - for i in xrange(e.getLineNb()): fd.readline() - ref=fd.tell()+5 - pass - if not isOK: - raise Exception("Error in VTURawReader : not a raw format ?") - return ref,rd - - @classmethod - def New(cls,fileName,tim=(0.,0)): - """ Static constructor. """ - return VTURawReader(fileName,tim) - pass - - def __init__(self,fileName,tim=(0.,0)): - msg="The time specified in constructor as 2nd arg should be a tuple containing 2 values 1 float and 1 int !" - if type(tim)!=tuple: - raise Exception(msg) - if len(tim)!=2: - raise Exception(msg) - if type(tim[0])!=float or type(tim[1])!=int: - raise Exception(msg) - self._fileName=fileName - self._time=tim - pass - - def __swapIfNecessary(self,b,arr): - if b: - ret=arr.copy() - ret.byteswap(True) - return ret - else: - return arr - pass - pass diff --git a/medtool/src/MEDLoader/Swig/case2med b/medtool/src/MEDLoader/Swig/case2med deleted file mode 100755 index ef2e15286..000000000 --- a/medtool/src/MEDLoader/Swig/case2med +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from CaseReader import CaseReader -from optparse import OptionParser -import os - -parser = OptionParser() -parser.set_usage("Convert a Case file to a MED file.\n %prog [options] case_file") -parser.add_option("-c", "--currentdir", action="store_true", dest="here", default=False, - help="Are generated MED file generated in current directory. By default not, MED file is generated in directory containing the input file (default False)") -(opts, args) = parser.parse_args() - -if len(args) != 1: - parser.print_usage() - exit(1) - pass - -fname=args[0] #"cas_test_simple.case" -if opts.here: - fOut=os.path.splitext(os.path.basename(fname))[0]+".med" - pass -else: - fOut=os.path.splitext(fname)[0]+".med" - pass -### -cr=CaseReader(fname) -try: - medfd=cr.loadInMEDFileDS() -except: - print "An error occured during the conversion!" - print "#######################################" - raise -medfd.write(fOut,2) -print "#########\nFile \"%s\" written !\n#########"%(fOut) - diff --git a/medtool/src/MEDLoader/Swig/med2case b/medtool/src/MEDLoader/Swig/med2case deleted file mode 100755 index bec9f4f30..000000000 --- a/medtool/src/MEDLoader/Swig/med2case +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony GEAY (CEA/DEN/DM2S/STMF/LGLS) - -from MEDLoader import MEDFileData,InterpKernelException -from CaseWriter import CaseWriter -from optparse import OptionParser -import os - -parser = OptionParser() -parser.set_usage("Convert a MED file to a Case file.\n %prog [options] med_file") -parser.add_option("-g", "--groups", action="store_true", dest="groups", default=False, - help="Are groups in meshes stored in MEDFile exported in output case as subparts (default False)") -parser.add_option("-c", "--currentdir", action="store_true", dest="here", default=False, - help="Are generated case,geo files generated in current directory. By default not, files are generated in directory containing the input file (default False)") -(opts, args) = parser.parse_args() - -if len(args) != 1: - parser.print_usage() - exit(1) - pass - -fname=os.path.abspath(args[0]) #"cas_test_simple.case" -if opts.here: - fOut=os.path.splitext(os.path.basename(fname))[0]+".case" - pass -else: - fOut=os.path.splitext(fname)[0]+".case" - pass -### -try: - cw=CaseWriter.New() - cw.setExportingGroups(opts.groups) - mfd=MEDFileData(fname) - cw.setMEDFileDS(mfd) - listOfWrittenFileNames=cw.write(fOut) -except InterpKernelException as e: - print "An error occurred during the conversion!" - print "#######################################" - raise e -print "#########" -for l in listOfWrittenFileNames: - print "File \"%s\" successfully written !"%(l) - pass -print "#########" diff --git a/medtool/src/MEDLoader/Swig/med2sauv b/medtool/src/MEDLoader/Swig/med2sauv deleted file mode 100755 index 8ba498033..000000000 --- a/medtool/src/MEDLoader/Swig/med2sauv +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -# -- -# Copyright (C) 2009-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Erwan ADAM (CEA) -# -- - -from sys import argv,path -from os.path import dirname,abspath,sep -from medutilities import med2sauv - -d = argv[0] -d = dirname(d) -d = abspath(d+sep+".."+sep+"lib") -if d not in path: - path.insert(0,d) - pass - -med2sauv(*argv[1:]) diff --git a/medtool/src/MEDLoader/Swig/medutilities.py b/medtool/src/MEDLoader/Swig/medutilities.py deleted file mode 100644 index 64c541868..000000000 --- a/medtool/src/MEDLoader/Swig/medutilities.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# -- -# Copyright (C) 2009-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Erwan ADAM (CEA), Anthony GEAY (CEA) -# -- - -from MEDLoader import * - -def my_remove(f): - from os import remove - try: - remove(f) - except OSError: - pass - return - -def convert(file_in, driver_in, driver_out, format=1, file_out=None): - # - print file_in - # - if file_out is None: - file_out = file_in - if driver_out == "GIBI": - file_out += ".sauv" - elif driver_out == "MED": - file_out += ".med" - else: - msg = "Driver out %s is unknown"%(driver_out) - raise NotImplementedError(msg) - pass - print file_out - # - if driver_in == "GIBI": - sr = SauvReader.New(file_in) - mfd= sr.loadInMEDFileDS() - pass - elif driver_in == "MED": - mfd = MEDFileData(file_in) - pass - else: - raise NotImplementedError("Driver in %s is unknown"%(driver_in)) - # - my_remove(file_out) - # - if driver_out == "GIBI": - sw=SauvWriter.New() - sw.setMEDFileDS(mfd,0);#0 ? - sw.write(file_out) - # - mesh = mfd.getMeshes()[0] - mesh_dim = mesh.getSpaceDimension() - if mesh_dim >= 3: - from sys import platform - if platform in ["win32"]: - f = open(file_out) - content = f.read() - f.close() - content = content.replace("IFOUR -1", "IFOUR 2") - content = content.replace("IFOMOD -1", "IFOMOD 2") - f = open(file_out, "w") - f.write(content) - f.close() - else: - cmd = "sed" - cmd += ' -e "s/IFOUR -1/IFOUR 2/g"' - cmd += ' -e "s/IFOMOD -1/IFOMOD 2/g"' - # cmd += ' -e "s/IECHO 1/IECHO 0/g"' - cmd += ' %s > .dummy'%(file_out) - cmd += ' && ' - cmd += ' mv -f .dummy %s'%(file_out) - from os import system - system(cmd) - pass - pass - # - if format == 0: - from castemlauncher import CastemLauncher - dgibi_stream = "\n" - dgibi_stream += "OPTI REST FORMAT '%s' ;\n"%(file_out) - dgibi_stream += "REST FORMAT;\n" - file_out = file_out.replace('__format__', '') - dgibi_stream += "OPTI SAUV '%s' ;\n"%(file_out) - dgibi_stream += "SAUV ;\n" - cl = CastemLauncher(dgibi_stream) - cl.addTmpFiles(file_out+'__format__', "UTILNOTI", "UTILPROC") - cl.run() - pass - return - elif driver_out == "MED": - mfd.write(file_out,2) - return - else: - raise NotImplementedError("Driver in %s is unknown"%(driver_in)) - -def sauv2med(*argv): - argv = list(argv) - for arg in argv: - convert(arg, "GIBI", "MED") - pass - return - -def med2sauv(*argv): - argv = list(argv) - format = 1 - for arg in argv[:]: - if arg.find('--format') == 0: - argv.remove(arg) - try: - value = arg.split("=")[1] - except IndexError: - usage(1) - pass - try: - value = int(value) - except ValueError: - usage(1) - pass - format = value - pass - pass - for arg in argv: - convert(arg, "MED", "GIBI", format) - pass - return diff --git a/medtool/src/MEDLoader/Swig/sauv2med b/medtool/src/MEDLoader/Swig/sauv2med deleted file mode 100755 index d4f9cf693..000000000 --- a/medtool/src/MEDLoader/Swig/sauv2med +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -# -- -# Copyright (C) 2009-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Erwan ADAM (CEA) -# -- - -from sys import argv,path -from os.path import dirname,abspath,sep -from medutilities import sauv2med - -d = argv[0] -d = dirname(d) -d = abspath(d+sep+".."+sep+"lib") -if d not in path: - path.insert(0,d) - pass - -sauv2med(*argv[1:]) diff --git a/medtool/src/MEDLoader/Test/CMakeLists.txt b/medtool/src/MEDLoader/Test/CMakeLists.txt deleted file mode 100644 index 27603494e..000000000 --- a/medtool/src/MEDLoader/Test/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest # For common CppUnitTest.hxx file - ) - -SET(TestMEDLoader_SOURCES - TestMEDLoader.cxx - MEDLoaderTest.cxx - ) - -SET(TestSauvLoader_SOURCES - TestSauvLoader.cxx - SauvLoaderTest.cxx - ) - -ADD_EXECUTABLE(TestMEDLoader ${TestMEDLoader_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDLoader medloader ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDLoader TestMEDLoader) - -ADD_EXECUTABLE(TestSauvLoader ${TestSauvLoader_SOURCES}) - -TARGET_LINK_LIBRARIES(TestSauvLoader medloader ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestSauvLoader TestSauvLoader) - -INSTALL(TARGETS TestMEDLoader TestSauvLoader DESTINATION ${MEDCOUPLING_INSTALL_BINS}) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDLoader) -INSTALL(TARGETS TestMEDLoader TestSauvLoader DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/MEDLoader/Test/CTestTestfileInstall.cmake b/medtool/src/MEDLoader/Test/CTestTestfileInstall.cmake deleted file mode 100644 index 4cf399650..000000000 --- a/medtool/src/MEDLoader/Test/CTestTestfileInstall.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(TestMEDLoader TestMEDLoader) -SET_TESTS_PROPERTIES(TestMEDLoader PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(TestSauvLoader TestSauvLoader) -SET_TESTS_PROPERTIES(TestSauvLoader PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/MEDLoader/Test/MEDLoaderTest.cxx b/medtool/src/MEDLoader/Test/MEDLoaderTest.cxx deleted file mode 100644 index 5807aca3e..000000000 --- a/medtool/src/MEDLoader/Test/MEDLoaderTest.cxx +++ /dev/null @@ -1,1494 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "MEDLoaderTest.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" - -#include <cmath> -#include <numeric> - -using namespace ParaMEDMEM; - -void MEDLoaderTest::testMesh1DRW() -{ - MEDCouplingUMesh *mesh=build1DMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file1.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file1.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh2DCurveRW() -{ - MEDCouplingUMesh *mesh=build2DCurveMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file2.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file2.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh2DRW() -{ - MEDCouplingUMesh *mesh=build2DMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file3.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file3.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh3DSurfRW() -{ - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file4.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file4.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh3DRW() -{ - MEDCouplingUMesh *mesh=build3DMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file5.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file5.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -/*! - * Most basic test : one and only one MEDCoupling field in a new file. - */ -void MEDLoaderTest::testFieldRW1() -{ - MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - MEDLoader::WriteField("file6.med",f1,true); - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell("file6.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f1->decrRef(); - f2->decrRef(); - // - f1=buildVecFieldOnNodes_1(); - MEDLoader::WriteField("file7.med",f1,true); - f2=MEDLoader::ReadFieldNode("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - // testing kind message on error of field type. - CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3),INTERP_KERNEL::Exception); - // - f1->decrRef(); - f2->decrRef(); -} - -/*! - * Multi field writing in a same file. - */ -void MEDLoaderTest::testFieldRW2() -{ - const char fileName[]="file8.med"; - static const double VAL1=12345.67890314; - static const double VAL2=-1111111111111.; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - MEDLoader::WriteField(fileName,f1,true); - f1->setTime(10.,8,9); - double *tmp=f1->getArray()->getPointer(); - tmp[0]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.14,18,19); - tmp[0]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - //retrieving time steps... - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),8,9); - f1->setTime(10.,8,9); - tmp[0]=VAL1; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - MEDCouplingFieldDouble *f3=buildVecFieldOnCells_1(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f2->decrRef(); - f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),18,19); - f1->setTime(10.14,18,19); - tmp[0]=VAL2; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - //test of throw on invalid (dt,it) - CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),28,19),INTERP_KERNEL::Exception); - f2->decrRef(); - f1->decrRef(); - //ON NODES - f1=buildVecFieldOnNodes_1(); - const char fileName2[]="file9.med"; - MEDLoader::WriteField(fileName2,f1,true); - f1->setTime(110.,108,109); - tmp=f1->getArray()->getPointer(); - tmp[3]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f1->setTime(210.,208,209); - tmp[3]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),108,109); - f1->setTime(110.,108,109); - tmp[3]=VAL1; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3); - f3=buildVecFieldOnNodes_1(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f2->decrRef(); - f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),208,209); - f1->setTime(210.,208,209); - tmp[3]=VAL2; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f1->decrRef(); -} - -/*! - * Multi field in a same file, but this field has several - */ -void MEDLoaderTest::testFieldRW3() -{ - const char fileName[]="file11.med"; - static const double VAL1=12345.67890314; - static const double VAL2=-1111111111111.; - const char name1[]="AField"; - const char name3[]="AMesh1"; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3); - f1->setName(name1); - f1->setTime(10.,8,9); - double *tmp=f1->getArray()->getPointer(); - tmp[0]=VAL1; - MEDLoader::WriteField(fileName,f1,true); - f1->setTime(10.14,18,19); - tmp[0]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.55,28,29); - tmp[0]=3*VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.66,38,39); - tmp[0]=3*VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.77,48,49); - tmp[0]=4*VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - //ON NODES - f1->decrRef(); - f1=buildVecFieldOnNodes_1(); - f1->setName(name1); - (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3); - f1->setTime(110.,8,9); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(110.,108,109); - tmp=f1->getArray()->getPointer(); - tmp[3]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(210.,208,209); - tmp[3]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - // - std::vector< std::pair<int,int> > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1); - CPPUNIT_ASSERT_EQUAL(5,(int)it1.size()); - CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second); - CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second); - CPPUNIT_ASSERT_EQUAL(28,it1[2].first); CPPUNIT_ASSERT_EQUAL(29,it1[2].second); - CPPUNIT_ASSERT_EQUAL(38,it1[3].first); CPPUNIT_ASSERT_EQUAL(39,it1[3].second); - CPPUNIT_ASSERT_EQUAL(48,it1[4].first); CPPUNIT_ASSERT_EQUAL(49,it1[4].second); - std::vector< std::pair<int,int> > it3=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); - CPPUNIT_ASSERT_EQUAL(3,(int)it3.size()); - CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second); - CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second); - CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second); - // - f1->decrRef(); - // - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,8,9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,18,19); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,28,29); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,38,39); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,48,49); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - // - f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,8,9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,108,109); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,208,209); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13); - f1->decrRef(); -} - -void MEDLoaderTest::testMultiMeshRW1() -{ - const char fileName[]="file10.med"; - MEDCouplingUMesh *mesh1=build3DMesh_1(); - const int part1[5]={1,2,4,13,15}; - MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); - mesh2->setName("mesh2"); - const int part2[4]={3,4,13,14}; - MEDCouplingUMesh *mesh3=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part2,part2+4,true); - mesh3->setName("mesh3"); - MEDCouplingUMesh *mesh4=MEDCouplingUMesh::New(); - mesh4->setName("mesh4"); - mesh4->setMeshDimension(3); - mesh4->allocateCells(1); - int conn[4]={0,11,1,3}; - mesh4->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - mesh4->finishInsertingCells(); - mesh4->setCoords(mesh1->getCoords()); - std::vector<const MEDCouplingUMesh *> meshes; - meshes.push_back(mesh1); - meshes.push_back(mesh2); - meshes.push_back(mesh3); - meshes.push_back(mesh4); - const char mnane[]="3DToto"; - MEDLoader::WriteUMeshesPartition(fileName,mnane,meshes,true); - // - MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane); - mesh1->setName(mnane); - const int part3[18]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; - MEDCouplingUMesh *mesh6=(MEDCouplingUMesh *)mesh5->buildPartOfMySelf(part3,part3+18,true); - mesh6->setName(mnane); - mesh5->decrRef(); - CPPUNIT_ASSERT(mesh6->isEqual(mesh1,1e-12)); - mesh6->decrRef(); - std::vector<std::string> grps=MEDLoader::GetMeshGroupsNames(fileName,mnane); - CPPUNIT_ASSERT_EQUAL(4,(int)grps.size()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh2"))!=grps.end()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh3"))!=grps.end()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh4"))!=grps.end()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("3DMesh_1"))!=grps.end()); - // - std::vector<std::string> vec; - vec.push_back(std::string("mesh2")); - MEDCouplingUMesh *mesh2_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); - mesh2_2->decrRef(); - vec.clear(); vec.push_back(std::string("mesh3")); - MEDCouplingUMesh *mesh3_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - CPPUNIT_ASSERT(mesh3_2->isEqual(mesh3,1e-12)); - mesh3_2->decrRef(); - vec.clear(); vec.push_back(std::string("mesh4")); - MEDCouplingUMesh *mesh4_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - CPPUNIT_ASSERT(mesh4_2->isEqual(mesh4,1e-12)); - mesh4_2->decrRef(); - vec.clear(); vec.push_back(std::string("3DMesh_1")); - MEDCouplingUMesh *mesh1_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - mesh1->setName("3DMesh_1"); - CPPUNIT_ASSERT(mesh1_2->isEqual(mesh1,1e-12)); - mesh1_2->decrRef(); - // - vec.clear(); vec.push_back(std::string("Family_-3")); vec.push_back(std::string("Family_-5")); - mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec); - mesh2_2->setName("mesh2"); - CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); - mesh2_2->decrRef(); - // - std::vector<std::string> ret=MEDLoader::GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1"); - CPPUNIT_ASSERT_EQUAL(4,(int)ret.size()); - CPPUNIT_ASSERT(ret[0]=="Family_-2"); - CPPUNIT_ASSERT(ret[1]=="Family_-3"); - CPPUNIT_ASSERT(ret[2]=="Family_-4"); - CPPUNIT_ASSERT(ret[3]=="Family_-5"); - // - std::vector<std::string> ret1=MEDLoader::GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3"); - CPPUNIT_ASSERT_EQUAL(2,(int)ret1.size()); - CPPUNIT_ASSERT(ret1[0]=="3DMesh_1"); - CPPUNIT_ASSERT(ret1[1]=="mesh2"); - // - mesh4->decrRef(); - mesh3->decrRef(); - mesh2->decrRef(); - mesh1->decrRef(); -} - -void MEDLoaderTest::testFieldProfilRW1() -{ - const char fileName[]="file12.med"; - MEDCouplingUMesh *mesh1=build3DMesh_1(); - bool b; - int newNbOfNodes; - DataArrayInt *da=mesh1->mergeNodes(1e-12,b,newNbOfNodes); - da->decrRef(); - MEDLoader::WriteUMesh(fileName,mesh1,true); - const int part1[5]={1,2,4,13,15}; - MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); - mesh2->setName(mesh1->getName().c_str());//<- important for the test - // - int nbOfCells=mesh2->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(5,nbOfCells); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("VectorFieldOnCells"); - f1->setMesh(mesh2); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,2); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; - std::copy(arr1,arr1+10,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - // - MEDLoader::WriteField(fileName,f1,false);//<- false important for the test - // - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - std::vector<ParaMEDMEM::TypeOfField> types=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); - CPPUNIT_ASSERT(types[0]==ON_CELLS); - f2->checkCoherency(); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - // - f2->decrRef(); - f1->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); -} - -/*! - * Test MED file profiles. - */ -void MEDLoaderTest::testFieldNodeProfilRW1() -{ - const char fileName[]="file19.med"; - const char fileName2[]="file20.med"; - MEDCouplingUMesh *m=build2DMesh_1(); - int nbOfNodes=m->getNumberOfNodes(); - MEDLoader::WriteUMesh(fileName,m,true); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("VFieldOnNodes"); - f1->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - const double arr1[24]={1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.}; - array->alloc(nbOfNodes,2); - std::copy(arr1,arr1+24,array->getPointer()); - f1->setArray(array); - array->setInfoOnComponent(0,"tyty [mm]"); - array->setInfoOnComponent(1,"uiop [MW]"); - array->decrRef(); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - const int arr2[2]={1,4};//node ids are 2,4,5,3,6,7 - MEDCouplingFieldDouble *f2=f1->buildSubPart(arr2,arr2+2); - (const_cast<MEDCouplingMesh *>(f2->getMesh()))->setName(f1->getMesh()->getName().c_str()); - MEDLoader::WriteField(fileName,f2,false);//<- false important for the test - // - MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),2,7); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - // - const int arr3[6]={1,3,0,5,2,4}; - f2->renumberNodes(arr3); - MEDLoader::WriteUMesh(fileName2,m,true); - MEDLoader::WriteField(fileName2,f2,false);//<- false important for the test - f3=MEDLoader::ReadFieldNode(fileName2,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),2,7); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f2->decrRef(); - // - f1->decrRef(); - m->decrRef(); -} - -void MEDLoaderTest::testFieldNodeProfilRW2() -{ - const char fileName[]="file23.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - MEDLoader::WriteUMesh(fileName,mesh,true); - // - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("FieldMix"); - f1->setMesh(mesh); - const double arr2[24]={ - 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. - }; - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(12,2); - f1->setArray(array); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - array->decrRef(); - double *tmp=array->getPointer(); - std::copy(arr2,arr2+24,tmp); - f1->setTime(3.17,2,7); - // - const int renumArr[12]={3,7,2,1,5,11,10,0,9,6,8,4}; - f1->renumberNodes(renumArr); - f1->checkCoherency(); - MEDLoader::WriteField(fileName,f1,false);//<- false important for the test - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); - // - f2->decrRef(); - mesh->decrRef(); - f1->decrRef(); -} - -void MEDLoaderTest::testFieldGaussRW1() -{ - const char fileName[]="file13.med"; - MEDCouplingFieldDouble *f1=buildVecFieldOnGauss_1(); - MEDLoader::WriteField(fileName,f1,true); - MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_PT,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),1,5); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f1->decrRef(); -} - -void MEDLoaderTest::testFieldGaussNERW1() -{ - const char fileName[]="file14.med"; - MEDCouplingFieldDouble *f1=buildVecFieldOnGaussNE_1(); - MEDLoader::WriteField(fileName,f1,true); - std::vector<ParaMEDMEM::TypeOfField> tof(MEDLoader::GetTypesOfField(fileName,"2DMesh_2","MyFieldOnGaussNE")); - CPPUNIT_ASSERT_EQUAL(1,(int)tof.size()); - CPPUNIT_ASSERT(ON_GAUSS_NE==tof[0]); - MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_NE,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),1,5); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f1->decrRef(); -} - -void MEDLoaderTest::testLittleStrings1() -{ - std::string s("azeeeerrrtty"); - MEDLoaderBase::zipEqualConsChar(s,3); - CPPUNIT_ASSERT(s=="azertty"); -} - -void MEDLoaderTest::testSplitIntoNameAndUnit1() -{ - std::string s(" []"); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(s,c,u); - CPPUNIT_ASSERT(c.empty()); - CPPUNIT_ASSERT(u.empty()); - s=" lmmm kki jjj "; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s=="lmmm kki jjj"); - s=" "; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s.empty()); - s=""; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s.empty()); - s=" "; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s.empty()); - s=" pp"; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s=="pp"); -} - -void MEDLoaderTest::testMesh3DSurfShuffleRW() -{ - const char fileName[]="file15.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - const int renumber1[6]={2,5,1,0,3,4}; - mesh->renumberCells(renumber1,false); - mesh->checkCoherency(); - MEDLoader::WriteUMesh(fileName,mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(fileName,mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testFieldShuffleRW1() -{ - const char fileName[]="file16.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("FieldOnCellsShuffle"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(6,2); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; - std::copy(arr1,arr1+12,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - // - const int renumber1[6]={2,1,5,0,3,4}; - f1->renumberCells(renumber1,false); - MEDLoader::WriteField(fileName,f1,true); - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,mesh->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); - f2->decrRef(); - // - mesh->decrRef(); - f1->decrRef(); -} - -/*! - * Shuffle de cells but no profile. Like pointe.med - */ -void MEDLoaderTest::testMultiFieldShuffleRW1() -{ - const char fileName[]="file17.med"; - MEDCouplingUMesh *m=build3DMesh_2(); - CPPUNIT_ASSERT_EQUAL(20,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(45,m->getNumberOfNodes()); - const int polys[3]={1,4,6}; - std::vector<int> poly2(polys,polys+3); - m->convertToPolyTypes(&poly2[0],&poly2[0]+poly2.size()); - const int renum[20]={1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11}; - m->renumberCells(renum,false); - m->orientCorrectlyPolyhedrons(); - // Writing - MEDLoader::WriteUMesh(fileName,m,true); - MEDCouplingFieldDouble *f1Tmp=m->getMeasureField(false); - MEDCouplingFieldDouble *f1=f1Tmp->buildNewTimeReprFromThis(ONE_TIME,false); - f1Tmp->decrRef(); - f1->setTime(0.,1,2); - MEDCouplingFieldDouble *f_1=f1->cloneWithMesh(true); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->applyFunc("2*x"); - f1->setTime(0.01,3,4); - MEDCouplingFieldDouble *f_2=f1->cloneWithMesh(true); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->applyFunc("2*x/3"); - f1->setTime(0.02,5,6); - MEDCouplingFieldDouble *f_3=f1->cloneWithMesh(true); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->decrRef(); - // Reading - std::vector<std::pair<int,int> > its; - its.push_back(std::pair<int,int>(1,2)); - its.push_back(std::pair<int,int>(3,4)); - its.push_back(std::pair<int,int>(5,6)); - std::vector<MEDCouplingFieldDouble *> fs=MEDLoader::ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1->getMesh()->getName().c_str(),0,f_1->getName().c_str(),its); - CPPUNIT_ASSERT_EQUAL(3,(int)fs.size()); - const MEDCouplingMesh *mm=fs[0]->getMesh(); - CPPUNIT_ASSERT(fs[0]->isEqual(f_1,1e-12,1e-12)); - CPPUNIT_ASSERT(fs[1]->isEqual(f_2,1e-12,1e-12)); - CPPUNIT_ASSERT(fs[2]->isEqual(f_3,1e-12,1e-12)); - CPPUNIT_ASSERT(mm==fs[1]->getMesh());// <- important for the test - CPPUNIT_ASSERT(mm==fs[2]->getMesh());// <- important for the test - for(std::vector<MEDCouplingFieldDouble *>::iterator iter=fs.begin();iter!=fs.end();iter++) - (*iter)->decrRef(); - // - f_1->decrRef(); - f_2->decrRef(); - f_3->decrRef(); - // - m->decrRef(); -} - -void MEDLoaderTest::testWriteUMeshesRW1() -{ - const char fileName[]="file18.med"; - MEDCouplingUMesh *m3d=build3DMesh_2(); - const double pt[3]={0.,0.,-0.3}; - const double vec[3]={0.,0.,1.}; - std::vector<int> nodes; - m3d->findNodesOnPlane(pt,vec,1e-12,nodes); - MEDCouplingUMesh *m2d=(MEDCouplingUMesh *)m3d->buildFacePartOfMySelfNode(&nodes[0],&nodes[0]+nodes.size(),true); - const int renumber[5]={1,2,0,4,3}; - m2d->renumberCells(renumber,false); - m2d->setName("ExampleOfMultiDimW"); - std::vector<const MEDCouplingUMesh *> meshes; - meshes.push_back(m2d); - meshes.push_back(m3d); - MEDLoader::WriteUMeshes(fileName,meshes,true); - MEDCouplingUMesh *m3d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),0); - CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12)); - m3d_bis->setName(m3d->getName().c_str()); - CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12)); - MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),-1);//-1 for faces - CPPUNIT_ASSERT(m2d_bis->isEqual(m2d,1e-12)); - // Creation of a field on faces. - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("FieldOnFacesShuffle"); - f1->setMesh(m2d); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(m2d->getNumberOfCells(),2); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; - std::copy(arr1,arr1+10,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),-1,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); - f1->decrRef(); - f2->decrRef(); - // - m2d_bis->decrRef(); - m3d_bis->decrRef(); - m2d->decrRef(); - m3d->decrRef(); -} - -void MEDLoaderTest::testMixCellAndNodesFieldRW1() -{ - const char fileName[]="file21.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("FieldMix"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(6,2); - f1->setArray(array); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; - std::copy(arr1,arr1+12,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f2->setName("FieldMix"); - f2->setMesh(mesh); - array=DataArrayDouble::New(); - array->alloc(12,2); - f2->setArray(array); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - array->decrRef(); - tmp=array->getPointer(); - const double arr2[24]={ - 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. - }; - std::copy(arr2,arr2+24,tmp); - f2->setTime(3.14,2,7); - f2->checkCoherency(); - // - MEDLoader::WriteField(fileName,f1,true); - std::vector<ParaMEDMEM::TypeOfField> ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)ts.size()); - CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[0]); - std::vector<std::string> fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); - CPPUNIT_ASSERT(fs[0]=="FieldMix"); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f2); - fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); - CPPUNIT_ASSERT(fs[0]=="FieldMix"); - // - ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(2,(int)ts.size()); - CPPUNIT_ASSERT_EQUAL(ON_NODES,ts[0]); - CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[1]); - // - MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f3=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f3->isEqual(f1,1e-12,1e-12)); - f3->decrRef(); - // - f1->decrRef(); - f2->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testGetAllFieldNamesRW1() -{ - const char fileName[]="file22.med"; - MEDCouplingUMesh *mesh=build2DMesh_2(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("Field1"); - f1->setTime(3.44,5,6); - f1->setMesh(mesh); - f1->fillFromAnalytic(2,"x+y"); - MEDLoader::WriteField(fileName,f1,true); - f1->setTime(1002.3,7,8); - f1->fillFromAnalytic(2,"x+77.*y"); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setName("Field2"); - MEDLoader::WriteField(fileName,f1,false); - f1->setName("Field3"); - mesh->setName("2DMesh_2Bis"); - MEDLoader::WriteField(fileName,f1,false); - f1->decrRef(); - f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("Field8"); - f1->setTime(8.99,7,9); - f1->setMesh(mesh); - f1->fillFromAnalytic(3,"3*x+y"); - MEDLoader::WriteField(fileName,f1,false); - f1->decrRef(); - std::vector<std::string> fs=MEDLoader::GetAllFieldNames(fileName); - CPPUNIT_ASSERT_EQUAL(4,(int)fs.size()); - CPPUNIT_ASSERT(fs[0]=="Field1"); - CPPUNIT_ASSERT(fs[1]=="Field2"); - CPPUNIT_ASSERT(fs[2]=="Field3"); - CPPUNIT_ASSERT(fs[3]=="Field8"); - mesh->decrRef(); -} - - -void MEDLoaderTest::testMEDLoaderRead1() -{ - using namespace std; - using namespace INTERP_KERNEL; - - string fileName=getResourceFile("pointe.med"); - vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size()); - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(16,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllGeoTypes().size()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(12)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(13)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(14)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(15)); - CPPUNIT_ASSERT_EQUAL((std::size_t)90,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(701,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(705,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+17,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); - mesh->decrRef(); - // - vector<string> families=MEDLoader::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str()); - CPPUNIT_ASSERT_EQUAL(8,(int)families.size()); - CPPUNIT_ASSERT(families[2]=="FAMILLE_ELEMENT_3"); - // - vector<string> families2; - families2.push_back(families[2]); - mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),0,families2); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL((std::size_t)11,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(132,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+11,0)); - CPPUNIT_ASSERT_EQUAL(16,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+3,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); - mesh->decrRef(); - // - vector<string> groups=MEDLoader::GetMeshGroupsNames(fileName.c_str(),meshNames[0].c_str()); - CPPUNIT_ASSERT_EQUAL(5,(int)groups.size()); - CPPUNIT_ASSERT(groups[0]=="groupe1"); - CPPUNIT_ASSERT(groups[1]=="groupe2"); - CPPUNIT_ASSERT(groups[2]=="groupe3"); - CPPUNIT_ASSERT(groups[3]=="groupe4"); - CPPUNIT_ASSERT(groups[4]=="groupe5"); - vector<string> groups2; - groups2.push_back(groups[0]); - mesh=MEDLoader::ReadUMeshFromGroups(fileName.c_str(),meshNames[0].c_str(),0,groups2); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(7,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(6)); - CPPUNIT_ASSERT_EQUAL((std::size_t)36,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(254,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+36,0)); - CPPUNIT_ASSERT_EQUAL(141,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+8,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); - mesh->decrRef(); - // - std::vector<std::string> fieldsName=MEDLoader::GetCellFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str()); - CPPUNIT_ASSERT_EQUAL(2,(int)fieldsName.size()); - CPPUNIT_ASSERT(fieldsName[0]=="fieldcelldoublescalar"); - CPPUNIT_ASSERT(fieldsName[1]=="fieldcelldoublevector"); - std::vector<std::pair<int,int> > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[0].c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)its0.size()); - CPPUNIT_ASSERT_EQUAL(-1,its0[0].first); - CPPUNIT_ASSERT_EQUAL(-1,its0[0].second); - std::vector<std::pair<int,int> > its1=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[1].c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)its1.size()); - CPPUNIT_ASSERT_EQUAL(-1,its1[0].first); - CPPUNIT_ASSERT_EQUAL(-1,its1[0].second); - // - MEDCouplingFieldDouble *field0=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second); - field0->checkCoherency(); - CPPUNIT_ASSERT(field0->getName()==fieldsName[0]); - CPPUNIT_ASSERT_EQUAL(1,field0->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(16,field0->getNumberOfTuples()); - const double expectedValues[16]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,2.,3.,3.,2.}; - double diffValue[16]; - std::transform(field0->getArray()->getPointer(),field0->getArray()->getPointer()+16,expectedValues,diffValue,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue,diffValue+16),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue,diffValue+16),1e-12); - const MEDCouplingUMesh *constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0->getMesh()); - CPPUNIT_ASSERT(constMesh); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); - CPPUNIT_ASSERT_EQUAL((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12); - field0->decrRef(); - // - MEDCouplingFieldDouble *field1=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[1].c_str(),its1[0].first,its1[0].second); - field1->checkCoherency(); - CPPUNIT_ASSERT(field1->getName()==fieldsName[1]); - CPPUNIT_ASSERT_EQUAL(3,field1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(16,field1->getNumberOfTuples()); - const double expectedValues2[48]={1.,0.,1.,1.,0.,1.,1.,0.,1.,2.,1.,0.,2.,1.,0.,2.,1.,0.,3.,0.,1.,3.,0.,1.,3.,0.,1.,4.,1.,0.,4.,1.,0.,4.,1.,0.,5.,0.,0.,6.,1.,1.,6.,0.,0.,5.,1.,1.}; - double diffValue2[48]; - std::transform(field1->getArray()->getPointer(),field1->getArray()->getPointer()+48,expectedValues2,diffValue2,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue2,diffValue2+48),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue2,diffValue2+48),1e-12); - constMesh=dynamic_cast<const MEDCouplingUMesh *>(field1->getMesh()); - CPPUNIT_ASSERT(constMesh); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); - CPPUNIT_ASSERT_EQUAL((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12); - field1->decrRef(); - //fields on nodes - std::vector<std::string> fieldsNameNode=MEDLoader::GetNodeFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str()); - CPPUNIT_ASSERT_EQUAL(2,(int)fieldsNameNode.size()); - CPPUNIT_ASSERT(fieldsNameNode[0]=="fieldnodedouble"); - CPPUNIT_ASSERT(fieldsNameNode[1]=="fieldnodeint"); - std::vector<std::pair<int,int> > its0Node=MEDLoader::GetNodeFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsNameNode[0].c_str()); - CPPUNIT_ASSERT_EQUAL(3,(int)its0Node.size()); - CPPUNIT_ASSERT_EQUAL(-1,its0Node[0].first); - CPPUNIT_ASSERT_EQUAL(-1,its0Node[0].second); - CPPUNIT_ASSERT_EQUAL(1,its0Node[1].first); - CPPUNIT_ASSERT_EQUAL(-1,its0Node[1].second); - CPPUNIT_ASSERT_EQUAL(2,its0Node[2].first); - CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].second); - MEDCouplingFieldDouble *field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second); - field0Nodes->checkCoherency(); - CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); - CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples()); - const double expectedValues3[19]={1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.}; - double diffValue3[19]; - std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues3,diffValue3,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12); - constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh()); - CPPUNIT_ASSERT(constMesh); - field0Nodes->decrRef(); - // - field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second); - field0Nodes->checkCoherency(); - CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); - CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples()); - const double expectedValues4[19]={1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.,7.,7.}; - std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues4,diffValue3,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12); - constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh()); - CPPUNIT_ASSERT(constMesh); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); - CPPUNIT_ASSERT_EQUAL((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12); - field0Nodes->decrRef(); - // - field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second); - field0Nodes->checkCoherency(); - CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); - CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(19,field0Nodes->getNumberOfTuples()); - const double expectedValues5[19]={1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.}; - std::transform(field0Nodes->getArray()->getPointer(),field0Nodes->getArray()->getPointer()+19,expectedValues5,diffValue3,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue3,diffValue3+19),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue3,diffValue3+19),1e-12); - constMesh=dynamic_cast<const MEDCouplingUMesh *>(field0Nodes->getMesh()); - CPPUNIT_ASSERT(constMesh); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(16,constMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,constMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllGeoTypes().size()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); - CPPUNIT_ASSERT_EQUAL((std::size_t)90,constMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+17,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+57,0),1e-12); - field0Nodes->decrRef(); -} - -void MEDLoaderTest::testMEDLoaderPolygonRead() -{ - using namespace std; - using namespace INTERP_KERNEL; - - string fileName=getResourceFile("polygones.med"); - vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size()); - CPPUNIT_ASSERT(meshNames[0]=="Bord"); - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(538,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(579,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - for(int i=0;i<514;i++) - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(i)); - for(int i=514;i<538;i++) - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+1737,0),1e-12); - const double expectedVals1[12]={1.4851585216522212,-0.5,0.,1.4851585216522212,-0.4,0.,1.4851585216522212,-0.3,0., 1.5741585216522211, -0.5, 0. }; - double diffValue1[12]; - std::transform(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+12,expectedVals1,diffValue1,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue1,diffValue1+12),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue1,diffValue1+12),1e-12); - CPPUNIT_ASSERT_EQUAL((std::size_t)2768,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(651050,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+2768,0)); - CPPUNIT_ASSERT_EQUAL(725943,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+539,0)); - mesh->decrRef(); - // - std::vector<std::string> fieldsName=MEDLoader::GetCellFieldNamesOnMesh(fileName.c_str(),meshNames[0].c_str()); - CPPUNIT_ASSERT_EQUAL(3,(int)fieldsName.size()); - CPPUNIT_ASSERT(fieldsName[0]=="bord_:_distorsion"); - CPPUNIT_ASSERT(fieldsName[1]=="bord_:_familles"); - CPPUNIT_ASSERT(fieldsName[2]=="bord_:_non-ortho"); - std::vector<std::pair<int,int> > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[0].c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)its0.size()); - MEDCouplingFieldDouble *field=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second); - field->checkCoherency(); - CPPUNIT_ASSERT(field->getName()==fieldsName[0]); - CPPUNIT_ASSERT_EQUAL(1,field->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(538,field->getNumberOfTuples()); - const MEDCouplingUMesh *constMesh=dynamic_cast<const MEDCouplingUMesh *>(field->getMesh()); - CPPUNIT_ASSERT(constMesh); - CPPUNIT_ASSERT_EQUAL(3,constMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,constMesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(538,constMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(579,constMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,(int)constMesh->getAllGeoTypes().size()); - for(int i=0;i<514;i++) - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,constMesh->getTypeOfCell(i)); - for(int i=514;i<538;i++) - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,constMesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,std::accumulate(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+1737,0),1e-12); - std::transform(constMesh->getCoords()->getConstPointer(),constMesh->getCoords()->getConstPointer()+12,expectedVals1,diffValue1,std::minus<double>()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue1,diffValue1+12),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::min_element(diffValue1,diffValue1+12),1e-12); - CPPUNIT_ASSERT_EQUAL((std::size_t)2768,constMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(651050,std::accumulate(constMesh->getNodalConnectivity()->getConstPointer(),constMesh->getNodalConnectivity()->getConstPointer()+2768,0)); - CPPUNIT_ASSERT_EQUAL(725943,std::accumulate(constMesh->getNodalConnectivityIndex()->getConstPointer(),constMesh->getNodalConnectivityIndex()->getConstPointer()+539,0)); - const double *values=field->getArray()->getPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.87214203182918,std::accumulate(values,values+538,0.),1e-12); - field->decrRef(); -} - -void MEDLoaderTest::testMEDLoaderPolyhedronRead() -{ - using namespace std; - using namespace INTERP_KERNEL; - - string fileName=getResourceFile("poly3D.med"); - vector<string> meshNames=MEDLoader::GetMeshNames(fileName.c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size()); - CPPUNIT_ASSERT(meshNames[0]=="poly3D"); - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(NORM_POLYHED,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(NORM_POLYHED,mesh->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL((std::size_t)98,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(725,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+98,0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(110.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); - CPPUNIT_ASSERT_EQUAL(155,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+4,0)); - mesh->decrRef(); - // - mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),-1); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(17,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(4)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(5)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(6)); - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(7)); - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(8)); - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(9)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(10)); - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(11)); - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(12)); - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(13)); - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(14)); - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(15)); - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(16)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(110.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); - CPPUNIT_ASSERT_EQUAL((std::size_t)83,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(619,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+83,0)); - mesh->decrRef(); - // - vector<string> families=MEDLoader::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str()); - CPPUNIT_ASSERT_EQUAL(4,(int)families.size()); - CPPUNIT_ASSERT(families[0]=="FAMILLE_FACE_POLYGONS3"); - CPPUNIT_ASSERT(families[1]=="FAMILLE_FACE_QUAD41"); - CPPUNIT_ASSERT(families[2]=="FAMILLE_FACE_TRIA32"); - CPPUNIT_ASSERT(families[3]=="FAMILLE_ZERO"); - vector<string> families2; - families2.push_back(families[0]); - mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),-1,families2); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(1,(int)mesh->getAllGeoTypes().size()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i)); - CPPUNIT_ASSERT_EQUAL((std::size_t)19,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(117,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+19,0)); - mesh->decrRef(); - // - mesh=MEDLoader::ReadUMeshFromFamilies(fileName.c_str(),meshNames[0].c_str(),0,families2); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(0,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(0,(int)mesh->getAllGeoTypes().size()); - mesh->decrRef(); -} - -std::string MEDLoaderTest::getResourceFile( const std::string& filename ) const -{ - std::string resourceFile = ""; - - if ( getenv("MEDCOUPLING_ROOT_DIR") ) { - // use MEDCOUPLING_ROOT_DIR env.var - resourceFile = getenv("MEDCOUPLING_ROOT_DIR"); - resourceFile += "/share/resources/med/"; - } - else { - resourceFile = get_current_dir_name(); - resourceFile += "/../../../resources/"; - } - - resourceFile += filename; - return resourceFile; -} - - -MEDCouplingUMesh *MEDLoaderTest::build1DMesh_1() -{ - double coords[6]={ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 }; - int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setName("1DMesh_1"); - mesh->setMeshDimension(1); - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(6,1); - myCoords->setInfoOnComponent(0,"tototototototot [m*m*m*m*m*m*m*m]"); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build2DCurveMesh_1() -{ - double coords[12]={ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 }; - int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setName("2DCurveMesh_1"); - mesh->setMeshDimension(1); - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(6,2); - std::copy(coords,coords+12,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build2DMesh_1() -{ - double targetCoords[24]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, -0.05,0.95, 0.2,1.2, 0.45,0.95 }; - int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(6); - targetMesh->setName("2DMesh_1"); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,2); - myCoords->setInfoOnComponent(0,"tototototototot [m]"); - myCoords->setInfoOnComponent(1,"energie [kW]"); - std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build2DMesh_2() -{ - double targetCoords[24]={ - -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95 - }; - int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->setName("2DMesh_2"); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,2); - myCoords->setInfoOnComponent(0,"toto [m]"); - myCoords->setInfoOnComponent(1,"energie [kW]"); - std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build3DSurfMesh_1() -{ - double targetCoords[36]={ - -0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 - ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3 - }; - int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(6); - targetMesh->setName("3DSurfMesh_1"); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,3); - myCoords->setInfoOnComponent(0,"toto [m]"); - myCoords->setInfoOnComponent(2,"ff [km]");//component 1 is not set for test - std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build3DMesh_1() -{ - double coords[180]={ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; - - int conn[354]={ - // 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - // 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - // 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58 - }; - // - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName("3DMesh_1"); - ret->setMeshDimension(3); - ret->allocateCells(18); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); - // - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); - // - ret->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(60,3); - myCoords->setInfoOnComponent(0,"titi [m]"); - myCoords->setInfoOnComponent(1,"density power [MW/m^3]"); - myCoords->setInfoOnComponent(2,"t [kW]"); - std::copy(coords,coords+180,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDLoaderTest::build3DMesh_2() -{ - MEDCouplingUMesh *m3dsurfBase=build3DSurfMesh_1(); - int numbers[5]={0,1,2,3,5}; - MEDCouplingUMesh *m3dsurf=(MEDCouplingUMesh *)m3dsurfBase->buildPartOfMySelf(numbers,numbers+5,false); - m3dsurfBase->decrRef(); - MEDCouplingUMesh *m1dBase=build1DMesh_1(); - int numbers2[4]={0,1,2,3}; - MEDCouplingUMesh *m1d=(MEDCouplingUMesh *)m1dBase->buildPartOfMySelf(numbers2,numbers2+4,false); - m1dBase->decrRef(); - m1d->changeSpaceDimension(3); - const double vec[3]={0.,1.,0.}; - const double pt[3]={0.,0.,0.}; - m1d->rotate(pt,vec,-M_PI/2.); - MEDCouplingUMesh *ret=m3dsurf->buildExtrudedMesh(m1d,0); - m1d->decrRef(); - m3dsurf->decrRef(); - return ret; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnCells_1() -{ - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - int nbOfCells=mesh->getNumberOfCells(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("VectorFieldOnCells"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,3); - array->setInfoOnComponent(0,"power [MW/m^3]"); - array->setInfoOnComponent(1,"density [g/cm^3]"); - array->setInfoOnComponent(2,"temperature [K]"); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[18]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; - std::copy(arr1,arr1+18,tmp); - f1->setTime(2.,0,1); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnNodes_1() -{ - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - int nbOfNodes=mesh->getNumberOfNodes(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("VectorFieldOnNodes"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfNodes,3); - f1->setArray(array); - array->setInfoOnComponent(0,"power [MW/m^3]"); - array->setInfoOnComponent(1,"density [g/cm^3]"); - array->setInfoOnComponent(2,"temperature [K]"); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[36]={ - 70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., - 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025., - }; - std::copy(arr1,arr1+36,tmp); - f1->setTime(2.12,2,3); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGauss_1() -{ - const double _a=0.446948490915965; - const double _b=0.091576213509771; - const double _p1=0.11169079483905; - const double _p2=0.0549758718227661; - const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; - const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - std::vector<double> _refCoo1(refCoo1,refCoo1+6); - std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12); - std::vector<double> _wg1(wg1,wg1+6); - MEDCouplingUMesh *m=build2DMesh_2(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setTime(3.14,1,5); - f->setMesh(m); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - const double refCoo2[12]={-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 }; - std::vector<double> _refCoo2(refCoo2,refCoo2+12); - std::vector<double> _gsCoo2(_gsCoo1); - std::vector<double> _wg2(_wg1); - _gsCoo2.resize(6); _wg2.resize(3); - const double refCoo3[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; - std::vector<double> _refCoo3(refCoo3,refCoo3+8); - _gsCoo1.resize(4); _wg1.resize(2); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(19,2); - double *ptr=array->getPointer(); - for(int i=0;i<19*2;i++) - ptr[i]=(double)(i+7); - f->setArray(array); - f->setName("MyFirstFieldOnGaussPoint"); - array->setInfoOnComponent(0,"power [MW/m^3]"); - array->setInfoOnComponent(1,"density"); - array->decrRef(); - f->checkCoherency(); - m->decrRef(); - return f; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGaussNE_1() -{ - MEDCouplingUMesh *m=build2DMesh_2(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); - f->setTime(3.14,1,5); - f->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(20,2); - double *ptr=array->getPointer(); - for(int i=0;i<20*2;i++) - ptr[i]=(double)(i+8); - f->setArray(array); - array->setInfoOnComponent(0,"power [W]"); - array->setInfoOnComponent(1,"temperature"); - f->setName("MyFieldOnGaussNE"); - array->decrRef(); - f->checkCoherency(); - m->decrRef(); - return f; -} - - - diff --git a/medtool/src/MEDLoader/Test/MEDLoaderTest.hxx b/medtool/src/MEDLoader/Test/MEDLoaderTest.hxx deleted file mode 100644 index b42b3b3db..000000000 --- a/medtool/src/MEDLoader/Test/MEDLoaderTest.hxx +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __MEDLOADERTEST_HXX__ -#define __MEDLOADERTEST_HXX__ - -#include <cppunit/extensions/HelperMacros.h> - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - class MEDLoaderTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE(MEDLoaderTest); - CPPUNIT_TEST( testMesh1DRW ); - CPPUNIT_TEST( testMesh2DCurveRW ); - CPPUNIT_TEST( testMesh2DRW ); - CPPUNIT_TEST( testMesh3DSurfRW ); - CPPUNIT_TEST( testMesh3DRW ); - CPPUNIT_TEST( testFieldRW1 ); - CPPUNIT_TEST( testFieldRW2 ); - CPPUNIT_TEST( testFieldRW3 ); - CPPUNIT_TEST( testMultiMeshRW1 ); - CPPUNIT_TEST( testFieldProfilRW1 ); - CPPUNIT_TEST( testFieldNodeProfilRW1 ); - CPPUNIT_TEST( testFieldNodeProfilRW2 ); - CPPUNIT_TEST( testFieldGaussRW1 ); - CPPUNIT_TEST( testFieldGaussNERW1 ); - CPPUNIT_TEST( testLittleStrings1 ); - CPPUNIT_TEST( testSplitIntoNameAndUnit1 ); - CPPUNIT_TEST( testMesh3DSurfShuffleRW ); - CPPUNIT_TEST( testFieldShuffleRW1 ); - CPPUNIT_TEST( testMultiFieldShuffleRW1 ); - CPPUNIT_TEST( testWriteUMeshesRW1 ); - CPPUNIT_TEST( testMixCellAndNodesFieldRW1 ); - CPPUNIT_TEST( testGetAllFieldNamesRW1 ); - - // Previously in ParaMEDMEM: - CPPUNIT_TEST(testMEDLoaderRead1); - CPPUNIT_TEST(testMEDLoaderPolygonRead); - CPPUNIT_TEST(testMEDLoaderPolyhedronRead); - - CPPUNIT_TEST_SUITE_END(); - public: - void testMesh1DRW(); - void testMesh2DCurveRW(); - void testMesh2DRW(); - void testMesh3DSurfRW(); - void testMesh3DRW(); - void testFieldRW1(); - void testFieldRW2(); - void testFieldRW3(); - void testMultiMeshRW1(); - void testFieldProfilRW1(); - void testFieldNodeProfilRW1(); - void testFieldNodeProfilRW2(); - void testFieldGaussRW1(); - void testFieldGaussNERW1(); - void testLittleStrings1(); - void testSplitIntoNameAndUnit1(); - void testMesh3DSurfShuffleRW(); - void testFieldShuffleRW1(); - void testMultiFieldShuffleRW1(); - void testWriteUMeshesRW1(); - void testMixCellAndNodesFieldRW1(); - void testGetAllFieldNamesRW1(); - - void testMEDLoaderRead1(); - void testMEDLoaderPolygonRead(); - void testMEDLoaderPolyhedronRead(); - private: - MEDCouplingUMesh *build1DMesh_1(); - MEDCouplingUMesh *build2DCurveMesh_1(); - MEDCouplingUMesh *build2DMesh_1(); - MEDCouplingUMesh *build2DMesh_2(); - MEDCouplingUMesh *build3DSurfMesh_1(); - MEDCouplingUMesh *build3DMesh_1(); - MEDCouplingUMesh *build3DMesh_2(); - MEDCouplingFieldDouble *buildVecFieldOnCells_1(); - MEDCouplingFieldDouble *buildVecFieldOnNodes_1(); - MEDCouplingFieldDouble *buildVecFieldOnGauss_1(); - MEDCouplingFieldDouble *buildVecFieldOnGaussNE_1(); - - std::string getResourceFile( const std::string& filename ) const; - }; -} - -#endif diff --git a/medtool/src/MEDLoader/Test/SauvLoaderTest.cxx b/medtool/src/MEDLoader/Test/SauvLoaderTest.cxx deleted file mode 100644 index 6ac13e4fe..000000000 --- a/medtool/src/MEDLoader/Test/SauvLoaderTest.cxx +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "SauvLoaderTest.hxx" - -#include "SauvReader.hxx" -#include "SauvWriter.hxx" -#include "MEDFileData.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" - -#ifdef WIN32 -# include <windows.h> -#else -# include <unistd.h> -#endif - -#include <vector> -#include <string> - -using namespace ParaMEDMEM; - -void SauvLoaderTest::testSauv2Med() -{ - // read a file containing all types of readable piles - std::string file = getResourceFile("allPillesTest.sauv"); - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(file.c_str()); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - // write MED - d2->write("allPillesTest.med",0); - // check - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes()); - CPPUNIT_ASSERT_EQUAL(8+97,d2->getNumberOfFields()); - MEDFileMesh * m = d2->getMeshes()->getMeshAtPos(0); - CPPUNIT_ASSERT_EQUAL(17,int(m->getGroupsNames().size())); -} - -void SauvLoaderTest::testMed2SauvOnAMeshWithVoidFamily() -{ - // Create a mesh with 2 quads. - const int spaceDim = 2; - const int nbOfNodes = 6; - double coords[nbOfNodes*spaceDim] = {0,0, 1,0, 1,1, 0,1, 2,0, 2,1}; - int conn[8]={0,1,2,3, 1,4,5,2}; - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2d=MEDCouplingUMesh::New("Mesh",spaceDim); - mesh2d->allocateCells(2); - mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - mesh2d->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> myCoords=DataArrayDouble::New(); - myCoords->alloc(nbOfNodes,spaceDim); - std::copy(coords,coords+nbOfNodes*spaceDim,myCoords->getPointer()); - mesh2d->setCoords(myCoords); - - // create a MedFileUMesh - MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m= MEDFileUMesh::New(); - m->setMeshAtLevel(0,mesh2d); - - // Create families and groups - - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam = DataArrayInt::New(); - fam->alloc(2,1); - int elemsFams[2] = {-2,-3}; - std::copy(elemsFams,elemsFams+2,fam->getPointer()); - - m->setFamilyFieldArr(0,fam); - - std::map<std::string,int> theFamilies; - theFamilies["FAM_-1"]=-1; - theFamilies["FAM_-2"]=-2; - theFamilies["FAM_-3"]=-3; - - std::map<std::string, std::vector<std::string> > theGroups; - theGroups["Group1"].push_back("FAM_-2"); - theGroups["Group2"].push_back("FAM_-3"); - theGroups["Grouptot"].push_back("FAM_-1"); - theGroups["Grouptot"].push_back("FAM_-2"); - theGroups["Grouptot"].push_back("FAM_-3"); - m->setFamilyInfo(theFamilies); - m->setGroupInfo(theGroups); - - // write to MED for visual check - //const char* medFile = "mesh_with_void_family.med"; - //m->write(medFile, 2); - - // write to SAUV - const char* sauvFile = "mesh_with_void_family.sauv"; - MEDCouplingAutoRefCountObjectPtr<MEDFileData> medData = MEDFileData::New(); - MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> medMeshes = MEDFileMeshes::New(); - MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New(); - medMeshes->setMeshAtPos(0, m); - medData->setMeshes(medMeshes); - sw->setMEDFileDS(medData); - sw->write(sauvFile); - - // read SAUV and check groups - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) ); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> group1 = m2->getGroup(0, "Group1"); - CPPUNIT_ASSERT_EQUAL(1,(int)group1->getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> group2 = m2->getGroup(0, "Group2"); - CPPUNIT_ASSERT_EQUAL(1,(int)group2->getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> grptot = m2->getGroup(0, "Grouptot"); - CPPUNIT_ASSERT_EQUAL(2,(int)grptot->getNumberOfCells()); -} - -void SauvLoaderTest::testSauv2MedOnA3SubsField() -{ - // read SAUV - std::string sauvFile = getResourceFile("portico_3subs.sauv"); - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile.c_str()); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - // check mesh - MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>(d2->getMeshes()->getMeshAtPos(0)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1d = m2->getMeshAtLevel(0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> length1dField = mesh1d->getMeasureField(0); - std::cout << "Length of 1d elements: " << length1dField->accumulate(0) << std::endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL(3, length1dField->accumulate(0), 1e-12); - // check field - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> field = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("CHAM1D")); - std::cout << "Number of components in field: " << field->getInfo().size() << std::endl; - CPPUNIT_ASSERT_EQUAL(6,(int)field->getInfo().size()); - std::vector< std::pair<int,int> > timesteps = field->getIterations(); - - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1d = - field->getFieldOnMeshAtLevel(ON_GAUSS_NE, timesteps[0].first, timesteps[0].second, 0, m2); - - // Check first component of the field - // 2 gauss points per element => 12 values - double values[12] = { - -7.687500000000e-03, - -7.687500000000e-03, - -4.562500000000e-03, - -4.562500000000e-03, - -8.208333333333e-03, - -8.208333333333e-03, - -6.125000000000e-03, - -6.125000000000e-03, - -4.041666666666e-03, - -4.041666666666e-03, - -6.111413346910e-07, - -6.111413346910e-07}; - - for (int i=0; i < field1d->getNumberOfTuples(); i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL( values[i], field1d->getIJ(i, 0), 1e-12 ); - } -} - -void SauvLoaderTest::testMed2Sauv() -{ - // read pointe.med - std::string file = getResourceFile("pointe.med"); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> pointeMed=MEDFileData::New(file.c_str()); - - // add 3 faces to pointeMed - MEDFileUMesh* pointeMedMesh = static_cast<MEDFileUMesh*>(pointeMed->getMeshes()->getMeshAtPos(0)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeM1D = MEDCouplingUMesh::New(); - DataArrayDouble *coords = pointeMedMesh->getCoords(); - pointeM1D->setCoords( coords ); - pointeM1D->setMeshDimension( 2 ); - pointeM1D->allocateCells( 3 ); - int conn[]= - { - 0,1,2, 0,1,3, 10,11,12,13 - }; - pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn); - pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn+3); - pointeM1D->insertNextCell( INTERP_KERNEL::NORM_QUAD4, 4, conn+6); - pointeM1D->finishInsertingCells(); - pointeMedMesh->setMeshAtLevel( -1, pointeM1D ); - pointeMed->getMeshes()->setMeshAtPos( 0, pointeMedMesh ); - - // add a field on 2 faces to pointeMed - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ff1=MEDFileFieldMultiTS::New(); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); - f1->setMesh( pointeM1D ); - f1->setName("Field on 2 faces"); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> d=DataArrayDouble::New(); - d->alloc(3+4,2); - d->setInfoOnComponent(0,"sigX [MPa]"); - d->setInfoOnComponent(1,"sigY [GPa]"); - double vals[2*(3+4)] = - { - 311,312,321,322,331,332,411,412,421,422,431,432,441,442 - }; - std::copy(vals,vals+d->getNbOfElems(),d->getPointer()); - f1->setArray(d); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); - int ids[] = - { - 0,2 - }; - da->alloc(2,1); - std::copy(ids,ids+da->getNbOfElems(),da->getPointer()); - da->setName("sup2"); - ff1->appendFieldProfile(f1,pointeMedMesh,-1,da); - pointeMed->getFields()->pushField( ff1 ); - - // remove "fieldnodeint" - MEDFileFields* pointeFields = pointeMed->getFields(); - for ( int i = 0; i < pointeFields->getNumberOfFields(); ++i ) - { - MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ts = pointeFields->getFieldAtPos(i); - if ( std::string("fieldnodeint") == ts->getName()) - { - pointeFields->destroyFieldAtPos( i ); - break; - } - } - // write pointeMed to SAUV - const char* sauvFile = "pointe.sauv"; - MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New(); - sw->setMEDFileDS(pointeMed); - sw->write(sauvFile); - - // read SAUV and check - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes()); - CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfFields()); - MEDFileUMesh * m = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) ); - CPPUNIT_ASSERT_EQUAL(std::string("maa1"),std::string(m->getName() )); - CPPUNIT_ASSERT_EQUAL(3,m->getMeshDimension()); - std::vector<std::string > groups = m->getGroupsNames(); - CPPUNIT_ASSERT_EQUAL(6,(int)groups.size()); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe1") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe2") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe3") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe4") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe5") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"maa1") != groups.end() ); - CPPUNIT_ASSERT_EQUAL(16,m->getSizeAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um0 = m->getGenMeshAtLevel(0); - CPPUNIT_ASSERT_EQUAL(12, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TETRA4 )); - CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_PYRA5 )); - CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_HEXA8 )); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um1 = m->getGenMeshAtLevel(-1); - CPPUNIT_ASSERT_EQUAL(2, um1->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TRI3 )); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeUM0 = - static_cast<MEDCouplingUMesh*>( pointeMedMesh->getGenMeshAtLevel(0)); - DataArrayDouble *coo = m->getCoords(); - DataArrayDouble *pointeCoo = pointeMedMesh->getCoords(); - CPPUNIT_ASSERT(coo->isEqualWithoutConsideringStr(*pointeCoo,1e-12)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol = um0->getMeasureField(0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> pointeVol = pointeUM0->getMeasureField(0); - CPPUNIT_ASSERT_DOUBLES_EQUAL( vol->accumulate(0), pointeVol->accumulate(0),1e-12); - // check fields - // fieldnodedouble - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS1 = - dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldnodedouble")); - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS2 = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldnodedouble")); - CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo().size(), fieldnodedoubleTS2->getInfo().size()); - for ( size_t i = 0; i < fieldnodedoubleTS1->getInfo().size(); ++i ) - CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo()[i], fieldnodedoubleTS2->getInfo()[i]); - CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getNumberOfTS(), fieldnodedoubleTS2->getNumberOfTS()); - std::vector< std::pair<int,int> > io1 = fieldnodedoubleTS1->getIterations(); - std::vector< std::pair<int,int> > io2 = fieldnodedoubleTS2->getIterations(); - for ( int i =0; i < fieldnodedoubleTS1->getNumberOfTS(); ++i ) - { - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 = - fieldnodedoubleTS1->getFieldOnMeshAtLevel(ON_NODES, io1[i].first,io1[i].second,pointeUM0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 = - fieldnodedoubleTS2->getFieldOnMeshAtLevel(ON_NODES, io2[i].first,io2[i].second,um0); - CPPUNIT_ASSERT( fnd1->getArray()->isEqual( *fnd2->getArray(), 1e-12 )); - } - // fieldcelldoublevector - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS1 = - dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldcelldoublevector")); - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS2 = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldcelldoublevector")); - CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo().size(), fieldcelldoublevectorTS2->getInfo().size()); - for ( size_t i = 0; i < fieldcelldoublevectorTS1->getInfo().size(); ++i ) - CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo()[i], fieldcelldoublevectorTS2->getInfo()[i]); - CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getNumberOfTS(), fieldcelldoublevectorTS2->getNumberOfTS()); - io1 = fieldcelldoublevectorTS1->getIterations(); - io2 = fieldcelldoublevectorTS2->getIterations(); - for ( int i =0; i < fieldcelldoublevectorTS1->getNumberOfTS(); ++i ) - { - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 = - fieldcelldoublevectorTS1->getFieldOnMeshAtLevel(ON_CELLS, io1[i].first,io1[i].second,pointeUM0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 = - fieldcelldoublevectorTS2->getFieldOnMeshAtLevel(ON_CELLS, io2[i].first,io2[i].second,um0); - CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(0), fnd2->accumulate(0), 1e-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(1), fnd2->accumulate(1), 1e-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(2), fnd2->accumulate(2), 1e-12 ); - } - // "Field on 2 faces" - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldOnFaces = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName(f1->getName().c_str())); - io1 = fieldOnFaces->getIterations(); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fof = - fieldOnFaces->getFieldOnMeshAtLevel(f1->getTypeOfField(),io1[0].first,io1[0].second,um1); - CPPUNIT_ASSERT( d->isEqual( *fof->getArray(), 1e-12 )); -} - -void SauvLoaderTest::tearDown() -{ - const int nbFilesToRemove = 3; - const char* fileToRemove[nbFilesToRemove] = { "allPillesTest.med", "pointe.sauv", "mesh_with_void_family.sauv" }; - for ( int i = 0; i < nbFilesToRemove; ++i ) - { -#ifdef WIN32 - if (GetFileAttributes(fileToRemove[i]) != INVALID_FILE_ATTRIBUTES) -#else - if (access(fileToRemove[i], F_OK) == 0) -#endif - remove(fileToRemove[i]); - } -} - -std::string SauvLoaderTest::getResourceFile( const std::string& filename ) -{ - std::string resourceFile = ""; - - if ( getenv("MEDCOUPLING_ROOT_DIR") ) { - // use MEDCOUPLING_ROOT_DIR env.var - resourceFile = getenv("MEDCOUPLING_ROOT_DIR"); - resourceFile += "/share/resources/med/"; - } - else { - resourceFile = get_current_dir_name(); - resourceFile += "/../../../resources/"; - } - - resourceFile += filename; -#ifdef WIN32 - std::string fixedpath = resourceFile; - for ( int i=0; i < fixedpath.length(); ++i ) - if (fixedpath[i] == '/') - fixedpath[i] = '\\'; - return fixedpath; -#endif - return resourceFile; -} diff --git a/medtool/src/MEDLoader/Test/SauvLoaderTest.hxx b/medtool/src/MEDLoader/Test/SauvLoaderTest.hxx deleted file mode 100644 index 586285cad..000000000 --- a/medtool/src/MEDLoader/Test/SauvLoaderTest.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __SauvLoaderTest_HXX__ -#define __SauvLoaderTest_HXX__ - -#include <cppunit/extensions/HelperMacros.h> - -#include "MEDLoaderTest.hxx" - -namespace ParaMEDMEM -{ - class SauvLoaderTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE(SauvLoaderTest); - CPPUNIT_TEST( testSauv2Med ); - CPPUNIT_TEST( testMed2Sauv ); - CPPUNIT_TEST( testMed2SauvOnAMeshWithVoidFamily ); - CPPUNIT_TEST( testSauv2MedOnA3SubsField ); - CPPUNIT_TEST_SUITE_END(); - public: - void testSauv2Med(); - void testMed2Sauv(); - void testMed2SauvOnAMeshWithVoidFamily(); - void testSauv2MedOnA3SubsField(); - - public: - void tearDown(); - static std::string getResourceFile( const std::string& filename ); - }; -} - -#endif diff --git a/medtool/src/MEDLoader/Test/TestMEDLoader.cxx b/medtool/src/MEDLoader/Test/TestMEDLoader.cxx deleted file mode 100644 index 8800a0405..000000000 --- a/medtool/src/MEDLoader/Test/TestMEDLoader.cxx +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "CppUnitTest.hxx" -#include "MEDLoaderTest.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDLoaderTest ); - -#include "BasicMainTest.hxx" diff --git a/medtool/src/MEDLoader/Test/TestSauvLoader.cxx b/medtool/src/MEDLoader/Test/TestSauvLoader.cxx deleted file mode 100644 index 4fdbcdbce..000000000 --- a/medtool/src/MEDLoader/Test/TestSauvLoader.cxx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CppUnitTest.hxx" -#include "SauvLoaderTest.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::SauvLoaderTest ); - -#include "BasicMainTest.hxx" diff --git a/medtool/src/MEDPartitioner/CMakeLists.txt b/medtool/src/MEDPartitioner/CMakeLists.txt deleted file mode 100644 index 2cfe13a79..000000000 --- a/medtool/src/MEDPartitioner/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${LIBXML2_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${LIBXML2_INCLUDE_DIR} - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -IF(MEDCOUPLING_MED_PARTITIONER_METIS) - ADD_DEFINITIONS(${METIS_DEFINITIONS}) - IF(MEDCOUPLING_METIS_V5) - ADD_DEFINITIONS("-DMED_ENABLE_METIS_V5") - ENDIF(MEDCOUPLING_METIS_V5) - INCLUDE_DIRECTORIES(${METIS_INCLUDE_DIRS}) -ENDIF(MEDCOUPLING_MED_PARTITIONER_METIS) - - -######## -# VERY IMPORTANT PUT METIS BEFORE SCOTCH because -# metis.h is also in SCOTCH install dir !!! -######## -IF(MEDCOUPLING_MED_PARTITIONER_SCOTCH) - ADD_DEFINITIONS(${SCOTCH_DEFINITIONS}) - INCLUDE_DIRECTORIES(${SCOTCH_INCLUDE_DIRS}) -ENDIF(MEDCOUPLING_MED_PARTITIONER_SCOTCH) - -IF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) - ADD_DEFINITIONS(${PARMETIS_DEFINITIONS}) - INCLUDE_DIRECTORIES(${PARMETIS_INCLUDE_DIRS}) -ENDIF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) - -IF(MEDCOUPLING_USE_MPI) - ADD_DEFINITIONS(${MPI_DEFINITIONS}) - INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) -ENDIF(MEDCOUPLING_USE_MPI) - -IF(MEDCOUPLING_BUILD_TESTS) - ADD_SUBDIRECTORY(Test) -ENDIF(MEDCOUPLING_BUILD_TESTS) - -SET(medpartitionercpp_HEADERS_HXX - MEDPARTITIONER_MeshCollection.hxx - MEDPARTITIONER_MeshCollectionDriver.hxx - MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx - MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx - MEDPARTITIONER_ParallelTopology.hxx - MEDPARTITIONER_JointFinder.hxx - MEDPARTITIONER_Graph.hxx - MEDPARTITIONER_UserGraph.hxx - MEDPARTITIONER_Utils.hxx - MEDPARTITIONER.hxx - MEDPARTITIONER_ParaDomainSelector.hxx - MEDPARTITIONER_ConnectZone.hxx - MEDPARTITIONER_Topology.hxx - MEDPARTITIONER_MEDPartitioner.hxx - ) - -SET(medpartitionercpp_SOURCES - MEDPARTITIONER_MeshCollection.cxx - MEDPARTITIONER_MeshCollectionDriver.cxx - MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx - MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx - MEDPARTITIONER_ParallelTopology.cxx - MEDPARTITIONER_Graph.cxx - MEDPARTITIONER_UserGraph.cxx - MEDPARTITIONER_Utils.cxx - MEDPARTITIONER_ParaDomainSelector.cxx - MEDPARTITIONER_ConnectZone.cxx - MEDPARTITIONER_metis.c - MEDPARTITIONER_MEDPartitioner.cxx - ) - -SET(medpartitionercpp_LDFLAGS - ${MEDFILE_C_LIBRARIES} - ${HDF5_LIBRARIES} - ${STDLIB} - ${LIBXML2_LIBRARIES} - interpkernel - medcoupling - medloader -) -IF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ParMetisGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ParMetisGraph.cxx MEDPARTITIONER_MetisGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${PARMETIS_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${PARMETIS_LIBRARIES}) -ENDIF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) -IF(MEDCOUPLING_MED_PARTITIONER_METIS) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBRARIES}) -ENDIF(MEDCOUPLING_MED_PARTITIONER_METIS) -IF(MEDCOUPLING_MED_PARTITIONER_SCOTCH) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBRARIES}) -ENDIF(MEDCOUPLING_MED_PARTITIONER_SCOTCH) - -IF(${MEDCOUPLING_USE_MPI}) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_UtilsPara.cxx MEDPARTITIONER_JointFinder.cxx) - ADD_EXECUTABLE(medpartitioner_para medpartitioner_para.cxx) - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${MPI_LIBRARIES}) - SET_TARGET_PROPERTIES(medpartitioner_para PROPERTIES COMPILE_FLAGS "${medpartitionercpp_DEFINITIONS}") - TARGET_LINK_LIBRARIES(medpartitioner_para medpartitionercpp ${medpartitionercpp_LDFLAGS}) - INSTALL(TARGETS medpartitioner_para DESTINATION ${MEDCOUPLING_INSTALL_BINS}) -ENDIF(${MEDCOUPLING_USE_MPI}) - -ADD_DEFINITIONS(${medpartitionercpp_DEFINITIONS}) - -ADD_LIBRARY(medpartitionercpp SHARED ${medpartitionercpp_SOURCES}) -TARGET_LINK_LIBRARIES(medpartitionercpp ${medpartitionercpp_LDFLAGS} ${PLATFORM_LIBS} ${PTHREAD_LIBS}) -INSTALL(TARGETS medpartitionercpp DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -ADD_EXECUTABLE(medpartitioner medpartitioner.cxx) -TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS}) -INSTALL(TARGETS medpartitioner DESTINATION ${MEDCOUPLING_INSTALL_BINS}) - -INSTALL(FILES ${medpartitionercpp_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER.hxx deleted file mode 100755 index 0996534cc..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_HXX__ -#define __MEDPARTITIONER_HXX__ - -#ifdef WIN32 -# if defined MEDPARTITIONERCPP_EXPORTS || defined medpartitionercpp_EXPORTS -# define MEDPARTITIONER_EXPORT __declspec( dllexport ) -# else -# define MEDPARTITIONER_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDPARTITIONER_EXPORT -#endif - -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx deleted file mode 100644 index 402d66249..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx +++ /dev/null @@ -1,339 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ConnectZone.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <map> - -using namespace ParaMEDMEM; - -MEDPARTITIONER::ConnectZone::ConnectZone(): - _name("") - ,_description("") - ,_local_domain_number(0) - ,_distant_domain_number(0) - ,_node_corresp(0) - ,_face_corresp(0) -{ -} - -MEDPARTITIONER::ConnectZone::~ConnectZone() -{ - delete _node_corresp; - delete _face_corresp; - for(std::map < std::pair <int, int>,MEDCouplingSkyLineArray * >::iterator iter=_entity_corresp.begin(); iter!=_entity_corresp.end();iter++) - { - delete iter->second; - } -} - -MEDPARTITIONER::ConnectZone::ConnectZone(const ConnectZone & myConnectZone): - _name(myConnectZone._name) - ,_description(myConnectZone._description) - ,_local_domain_number(myConnectZone._local_domain_number) - ,_distant_domain_number(myConnectZone._distant_domain_number) - ,_node_corresp(myConnectZone._node_corresp) - ,_face_corresp(myConnectZone._face_corresp) - ,_entity_corresp(myConnectZone._entity_corresp) -{ -} - -std::string MEDPARTITIONER::ConnectZone::getName() const -{ - return _name; -} - -std::string MEDPARTITIONER::ConnectZone::getDescription() const -{ - return _description; -} - -int MEDPARTITIONER::ConnectZone::getDistantDomainNumber() const -{ - return _distant_domain_number; -} - -int MEDPARTITIONER::ConnectZone::getLocalDomainNumber() const -{ - return _local_domain_number; -} - -ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getLocalMesh() const -{ - return _local_mesh; -} - -ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getDistantMesh() const -{ - return _distant_mesh; -} - -bool MEDPARTITIONER::ConnectZone::isEntityCorrespPresent(int localEntity, int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - for(map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return true; - } - return false; -} - -const int *MEDPARTITIONER::ConnectZone::getNodeCorrespIndex() const -{ - return _node_corresp->getIndex(); -} - -const int *MEDPARTITIONER::ConnectZone::getNodeCorrespValue() const -{ - return _node_corresp->getValue(); -} - -int MEDPARTITIONER::ConnectZone::getNodeNumber() const -{ - return _node_corresp->getNumberOf(); -} - -const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getNodeCorresp() const -{ - return _node_corresp; -} - -const int *MEDPARTITIONER::ConnectZone::getFaceCorrespIndex() const -{ - return _face_corresp->getIndex(); -} - -const int *MEDPARTITIONER::ConnectZone::getFaceCorrespValue() const -{ - return _face_corresp->getValue(); -} - -int MEDPARTITIONER::ConnectZone::getFaceNumber() const -{ - return _face_corresp->getNumberOf(); -} - -const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getFaceCorresp() const -{ - return _face_corresp; -} - -const int *MEDPARTITIONER::ConnectZone::getEntityCorrespIndex(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getIndex(); - } - return 0; -} - -const int *MEDPARTITIONER::ConnectZone::getEntityCorrespValue(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for (map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getValue(); - } - return 0; -} - -int MEDPARTITIONER::ConnectZone::getEntityCorrespNumber(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) - { - if((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getNumberOf(); - } - return 0; -} - -int MEDPARTITIONER::ConnectZone::getEntityCorrespLength(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getLength(); - } - return 0; -} - -const ParaMEDMEM::MEDCouplingSkyLineArray * -MEDPARTITIONER::ConnectZone::getEntityCorresp(int localEntity, int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second; - } - return 0; -} - -std::vector< std::pair< int,int > > MEDPARTITIONER::ConnectZone::getEntities() const -{ - std::vector< std::pair< int,int > > types; - - std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator - iter = _entity_corresp.begin(); - for ( ; iter != _entity_corresp.end(); iter++) - { - types.push_back( iter->first ); - } - - return types; -} - -void MEDPARTITIONER::ConnectZone::setName(const std::string& name) -{ - _name=name; -} - -void MEDPARTITIONER::ConnectZone::setDescription(const std::string& description) -{ - _description=description; -} - -void MEDPARTITIONER::ConnectZone::setDistantDomainNumber(int distantDomainNumber) -{ - _distant_domain_number=distantDomainNumber; -} - -void MEDPARTITIONER::ConnectZone::setLocalDomainNumber(int localDomainNumber) -{ - _local_domain_number=localDomainNumber; -} - -void MEDPARTITIONER::ConnectZone::setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) -{ - _local_mesh=localMesh; -} - -void MEDPARTITIONER::ConnectZone::setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) -{ - _distant_mesh=distantMesh; -} - -/*! transforms an int array containing - * the node-node connections - * to a MEDCouplingSkyLineArray - */ -void MEDPARTITIONER::ConnectZone::setNodeCorresp(const int * nodeCorresp, int nbnode) -{ - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); - indexArr->alloc( nbnode+1 ); - valueArr->alloc( 2*nbnode ); - int * index = indexArr->getPointer(); - int * value = valueArr->getPointer(); - for (int i=0; i<nbnode; i++) - { - index[i]=2*i; - value[2*i ]=nodeCorresp[2*i]; - value[2*i+1]=nodeCorresp[2*i+1]; - } - index[nbnode]=2*nbnode; - setNodeCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr )); -} - -void MEDPARTITIONER::ConnectZone::setNodeCorresp(MEDCouplingSkyLineArray* array) -{ - if ( _node_corresp ) delete _node_corresp; - _node_corresp = array; -} - -/*! transforms an int array containing - * the face-face connections - * to a MEDCouplingSkyLineArray - */ -void MEDPARTITIONER::ConnectZone::setFaceCorresp(const int * faceCorresp, int nbface) -{ - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); - indexArr->alloc( nbface+1 ); - valueArr->alloc( 2*nbface ); - int * index = indexArr->getPointer(); - int * value = valueArr->getPointer(); - for (int i=0; i<nbface; i++) - { - index[i]=2*i; - value[2*i]=faceCorresp[2*i]; - value[2*i+1]=faceCorresp[2*i+1]; - } - index[nbface]=2*nbface; - setFaceCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr )); -} - -void MEDPARTITIONER::ConnectZone::setFaceCorresp(MEDCouplingSkyLineArray* array) -{ - if ( _face_corresp ) delete _face_corresp; - _face_corresp = array; -} - -/*! transforms an int array containing - * the entity-entity connections - * to a MEDCouplingSkyLineArray - * - * the resulting MEDCouplingSkyLineArray is put in the map - */ -void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity, - const int *entityCorresp, int nbentity) -{ - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); - indexArr->alloc( nbentity+1 ); - valueArr->alloc( 2*nbentity ); - int * index = indexArr->getPointer(); - int * value = valueArr->getPointer(); - for (int i=0; i<nbentity; i++) - { - index[i]=2*i; - value[2*i ]=entityCorresp[2*i]; - value[2*i+1]=entityCorresp[2*i+1]; - } - index[nbentity]=2*nbentity; - setEntityCorresp( localEntity, distantEntity, new MEDCouplingSkyLineArray(indexArr,valueArr)); -} - -void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity, - MEDCouplingSkyLineArray *array) -{ - ParaMEDMEM::MEDCouplingSkyLineArray * nullArray = 0; - std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * >::iterator it; - it = _entity_corresp.insert - ( std::make_pair( std::make_pair(localEntity,distantEntity), nullArray )).first; - if ( it->second != nullArray ) delete it->second; - it->second = array; -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx deleted file mode 100644 index 9572db1c8..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_CONNECTZONE_HXX__ -#define __MEDPARTITIONER_CONNECTZONE_HXX__ - -#include "MEDPARTITIONER.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class MEDCouplingSkyLineArray; -} - -#include <map> -#include <vector> -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT ConnectZone - { - public : - ConnectZone(); - ~ConnectZone(); - ConnectZone(const ConnectZone & myConnectZone); - - std::string getName() const ; - std::string getDescription() const ; - int getDistantDomainNumber() const ; - int getLocalDomainNumber() const ; - ParaMEDMEM::MEDCouplingUMesh *getLocalMesh() const ; - ParaMEDMEM::MEDCouplingUMesh *getDistantMesh() const ; - - bool isEntityCorrespPresent(int localEntity,int distantEntity) const; - const int *getNodeCorrespIndex() const; - const int *getNodeCorrespValue() const; - int getNodeNumber() const; - const ParaMEDMEM::MEDCouplingSkyLineArray * getNodeCorresp() const; - const int *getFaceCorrespIndex() const; - const int *getFaceCorrespValue() const; - int getFaceNumber() const; - const ParaMEDMEM::MEDCouplingSkyLineArray * getFaceCorresp() const; - const int *getEntityCorrespIndex(int localEntity, - int distantEntity) const; - const int *getEntityCorrespValue(int localEntity, - int distantEntity) const; - int getEntityCorrespNumber(int localEntity, - int distantEntity) const; - int getEntityCorrespLength(int localEntity, - int distantEntity) const; - const ParaMEDMEM::MEDCouplingSkyLineArray * getEntityCorresp(int localEntity, - int distantEntity) const; - std::vector< std::pair< int,int > > getEntities() const; - - void setName(const std::string& name) ; - void setDescription(const std::string& description) ; - void setDistantDomainNumber(int distantDomainNumber) ; - void setLocalDomainNumber(int distantDomainNumber) ; - void setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) ; - void setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) ; - - void setNodeCorresp(const int * nodeCorresp, int nbnode); - void setNodeCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array); - void setFaceCorresp(const int * faceCorresp, int nbface); - void setFaceCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array); - void setEntityCorresp(int localEntity, int distantEntity, - const int * entityCorresp, int nbentity); - void setEntityCorresp(int localEntity, int distantEntity, - ParaMEDMEM::MEDCouplingSkyLineArray *array); - private : - std::string _name; - std::string _description; - int _local_domain_number; - int _distant_domain_number; - - ParaMEDMEM::MEDCouplingUMesh * _local_mesh; - ParaMEDMEM::MEDCouplingUMesh * _distant_mesh; - - ParaMEDMEM::MEDCouplingSkyLineArray * _node_corresp; - ParaMEDMEM::MEDCouplingSkyLineArray * _face_corresp; - - std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * > _entity_corresp; - }; -} -# endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx deleted file mode 100644 index 1904ae4f5..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Graph.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <set> - -MEDPARTITIONER::Graph::Graph(ParaMEDMEM::MEDCouplingSkyLineArray *array, int *edgeweight):_graph(array),_partition(0),_edge_weight(edgeweight),_cell_weight(0) -{ -} - -MEDPARTITIONER::Graph::~Graph() -{ - delete _partition; - delete _graph; -} - -int MEDPARTITIONER::Graph::nbDomains() const -{ - std::set<int> domains; - if ( _partition ) - if ( ParaMEDMEM::DataArrayInt* array = _partition->getValueArray() ) - { - for ( const int * dom = array->begin(); dom != array->end(); ++dom ) - domains.insert( *dom ); - } - return domains.size(); -} - -const int *MEDPARTITIONER::Graph::getPart() const -{ - return _partition->getValue(); -} - -int MEDPARTITIONER::Graph::nbVertices() const -{ - return _graph->getNumberOf(); -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx deleted file mode 100644 index 12227bdb0..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_GRAPH_HXX__ -#define __MEDPARTITIONER_GRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <string> - -namespace ParaMEDMEM -{ - class MEDCouplingSkyLineArray; -} - -namespace MEDPARTITIONER -{ - class ParaDomainSelector; - class MEDPARTITIONER_EXPORT Graph - { - public: - typedef enum {METIS,SCOTCH} splitter_type; - - Graph(){}; - //creates a graph from a SKYLINEARRAY - Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight=0); - virtual ~Graph(); - - void setEdgesWeights(int *edgeweight) { _edge_weight=edgeweight; } - void setVerticesWeights(int *cellweight) { _cell_weight=cellweight; } - - //computes partitioning of the graph - virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) = 0; - - //returns the partitioning - const int *getPart() const; - - //returns the number of graph vertices (which can correspond to the cells in the mesh!) - int nbVertices() const; - - // returns nb of domains in _partition - int nbDomains() const; - - const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const { return _graph; } - const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const { return _partition; } - - protected: - ParaMEDMEM::MEDCouplingSkyLineArray* _graph; - ParaMEDMEM::MEDCouplingSkyLineArray* _partition; - int* _edge_weight; - int* _cell_weight; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx deleted file mode 100644 index 1e826eac7..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_JointFinder.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "BBTree.txx" - -/*! - * Method contributing to the distant cell graph - */ -MEDPARTITIONER::JointFinder::JointFinder(const MeshCollection& mc):_mesh_collection(mc),_domain_selector(mc.getParaDomainSelector()),_topology(mc.getTopology()) -{ -} - -MEDPARTITIONER::JointFinder::~JointFinder() -{ -} - -void MEDPARTITIONER::JointFinder::findCommonDistantNodes() -{ - int nbdomain=_topology->nbDomain(); - _distant_node_cell.resize(nbdomain); - _node_node.resize(nbdomain); - for (int i=0; i<nbdomain; i++) - { - _distant_node_cell[i].resize(nbdomain); - _node_node[i].resize(nbdomain); - } - int nbproc=_domain_selector->nbProcs(); - std::vector<BBTreeOfDim* > bbtree(nbdomain,(BBTreeOfDim*) 0); - std::vector<double* > bbxi(nbdomain,(double*) 0); - std::vector<ParaMEDMEM::DataArrayInt*> rev(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); - std::vector<ParaMEDMEM::DataArrayInt*> revIndx(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); - int meshDim=-1; - int spaceDim=-1; - - //init rev and revIndx and bbtree for my domain (of me:proc n) - for (int mydomain=0; mydomain<nbdomain; mydomain++) - { - if(!_domain_selector->isMyDomain(mydomain)) - continue; - const ParaMEDMEM::MEDCouplingUMesh* myMesh=_mesh_collection.getMesh(mydomain); - meshDim = myMesh->getMeshDimension(); - spaceDim= myMesh->getSpaceDimension(); - rev[mydomain] = ParaMEDMEM::DataArrayInt::New(); - revIndx[mydomain] = ParaMEDMEM::DataArrayInt::New(); - myMesh->getReverseNodalConnectivity(rev[mydomain],revIndx[mydomain]); - double* bbx=new double[2*spaceDim*myMesh->getNumberOfNodes()]; - for (int i=0; i<myMesh->getNumberOfNodes()*spaceDim; i++) - { - const double* coords=myMesh->getCoords()->getConstPointer(); - bbx[2*i]=(coords[i])-1e-12; - bbx[2*i+1]=bbx[2*i]+2e-12; - } - bbtree[mydomain]=new BBTreeOfDim( spaceDim, bbx,0,0,myMesh->getNumberOfNodes(),-1e-12); - //keep bbx because need it in getIntersectingElems - //no delete [] bbx yet - bbxi[mydomain]=bbx; - } - - //send my domains to other proc an receive other domains from other proc - for (int isource=0; isource<nbdomain; isource++) - { - for (int itarget=0; itarget<nbdomain; itarget++) - { - const ParaMEDMEM::MEDCouplingUMesh* sourceMesh=_mesh_collection.getMesh(isource); - if (_domain_selector->isMyDomain(isource)&&_domain_selector->isMyDomain(itarget)) - continue; - if (_domain_selector->isMyDomain(isource)) - { - //preparing data for treatment on target proc - int targetProc = _domain_selector->getProcessorID(itarget); - - std::vector<double> vec(spaceDim*sourceMesh->getNumberOfNodes()); - std::copy(sourceMesh->getCoords()->getConstPointer(),sourceMesh->getCoords()->getConstPointer()+sourceMesh->getNumberOfNodes()*spaceDim,&vec[0]); - SendDoubleVec(vec,targetProc); - - //retrieving target data for storage in commonDistantNodes array - std::vector<int> localCorrespondency; - RecvIntVec(localCorrespondency, targetProc); - for (std::size_t i=0; i<localCorrespondency.size()/2; i++) - { - _distant_node_cell[isource][itarget].insert(std::make_pair(localCorrespondency[2*i],localCorrespondency[2*i+1])); - } - - } - - if (_domain_selector->isMyDomain(itarget)) - { - //receiving data from source proc - int sourceProc = isource%nbproc; - std::vector<double> recvVec; - RecvDoubleVec(recvVec,sourceProc); - std::map<int,int> commonNodes; // (local nodes, distant nodes) list - for (int inode=0; inode<(recvVec.size()/spaceDim); inode++) - { - double* bbox=new double[2*spaceDim]; - for (int i=0; i<spaceDim; i++) - { - bbox[2*i]=recvVec[inode*spaceDim+i]-1e-12; - bbox[2*i+1]=bbox[2*i]+2e-12; - } - std::vector<int> inodes; - bbtree[itarget]->getIntersectingElems(bbox,inodes); - delete [] bbox; - - if (inodes.size()>0) - { - commonNodes.insert(std::make_pair(inodes[0],inode)); - } - - } - std::vector<int> nodeCellCorrespondency; - for (std::map<int,int>::iterator iter=commonNodes.begin(); iter!=commonNodes.end(); iter++) - { - _node_node[itarget][isource].push_back(std::make_pair(iter->first, iter->second));//storing node pairs in a vector - const int* revIndxPtr=revIndx[itarget]->getConstPointer(); - const int* revPtr=rev[itarget]->getConstPointer(); - for (int icell=revIndxPtr[iter->first]; icell<revIndxPtr[iter->first+1]; icell++) - { - nodeCellCorrespondency.push_back(iter->second); // - int globalCell=_topology->convertCellToGlobal(itarget,revPtr[icell]); - nodeCellCorrespondency.push_back(globalCell); - } - } - SendIntVec(nodeCellCorrespondency, sourceProc); //itarget proc send to other (otherLocalNode-itargetGlobalCell) - } - } - } - - //free rev(nbdomain) revIndx(nbdomain) bbtree(nbdomain) bbxi(nbdomain) - for (int i=0; i<nbdomain; i++) - { - if (rev[i]!=0) - rev[i]->decrRef(); - if (revIndx[i]!=0) - revIndx[i]->decrRef(); - if (bbtree[i]!=0) - delete bbtree[i]; - if (bbxi[i]!=0) - delete [] bbxi[i]; - } - - if (MyGlobals::_Verbose>100) - std::cout << "proc " << _domain_selector->rank() << " : end JointFinder::findCommonDistantNodes" << std::endl; -} - -std::vector<std::vector<std::multimap<int,int> > >& MEDPARTITIONER::JointFinder::getDistantNodeCell() -{ - return _distant_node_cell; -} - -std::vector<std::vector<std::vector<std::pair<int,int> > > >& MEDPARTITIONER::JointFinder::getNodeNode() -{ - return _node_node; -} - -void MEDPARTITIONER::JointFinder::print() -//it is for debug on small arrays under mpi 2,3 cpus -{ - int nbdomain=_topology->nbDomain(); - //MPI_Barrier(MPI_COMM_WORLD); - if (MyGlobals::_Is0verbose>0) - std::cout << "\nJointFinder print node-node (nn)iproc|itarget|isource|i|inodefirst-inodesecond\n\n" << - "JointFinder print distantNode=cell (nc)iproc|itarget|isource|inode=icell\n\n"; - for (int isource=0; isource<nbdomain; isource++) - { - for (int itarget=0; itarget<nbdomain; itarget++) - { - for (std::size_t i=0; i<_node_node[itarget][isource].size(); i++) - std::cout << " nn" << _domain_selector->rank() << itarget << "|" << isource << "|" << i << "|" << - _node_node[itarget][isource][i].first << "-" << - _node_node[itarget][isource][i].second; - } - } - std::cout<<std::endl; - //MPI_Barrier(MPI_COMM_WORLD); - for (int isource=0; isource<nbdomain; isource++) - { - for (int itarget=0; itarget<nbdomain; itarget++) - { - std::multimap<int,int>::iterator it; - for (it=_distant_node_cell[isource][itarget].begin() ; it!=_distant_node_cell[isource][itarget].end(); it++) - { - std::cout << " nc" << _domain_selector->rank() << "|" << itarget << "|" << isource << "|" << (*it).first << "=" << (*it).second; - } - } - } - std::cout << std::endl; - //MPI_Barrier(MPI_COMM_WORLD); -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx deleted file mode 100644 index 4fcc9ace6..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_JOINTFINDER_HXX__ -#define __MEDPARTITIONER_JOINTFINDER_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <map> -#include <vector> - -namespace MEDPARTITIONER -{ - class Topology; - class MeshCollection; - class ParaDomainSelector; - - class MEDPARTITIONER_EXPORT JointFinder - { - public: - JointFinder(const MeshCollection& mc); - ~JointFinder(); - void findCommonDistantNodes(); - void print(); - std::vector<std::vector<std::multimap<int,int> > >& getDistantNodeCell(); - std::vector<std::vector<std::vector<std::pair<int,int> > > >& getNodeNode(); - private: - const MeshCollection& _mesh_collection; - const ParaDomainSelector *_domain_selector; - const Topology *_topology; - std::vector<std::vector<std::multimap<int,int> > > _distant_node_cell; - std::vector<std::vector<std::vector<std::pair<int,int> > > > _node_node; - - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx deleted file mode 100644 index 57e9ae919..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MEDPartitioner.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_Utils.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_MetisGraph.hxx" -#include "MEDPARTITIONER_ScotchGraph.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingSkyLineArray.hxx" - -#include <iostream> -#include <vector> - -MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const std::string& filename, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory): - _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) -{ - MyGlobals::_World_Size = 1; - MyGlobals::_Rank = 0; - MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; - MyGlobals::_Create_Joints = create_joints; - - ParaDomainSelector parallelizer(mesure_memory); - _input_collection=new MeshCollection(filename,parallelizer); - _input_collection->setParaDomainSelector( ¶llelizer ); - - MEDPARTITIONER::ParallelTopology* aPT = - (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); - aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); - _input_collection->prepareFieldDescriptions(); - createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory); - - parallelizer.evaluateMemory(); -} - -MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory): - _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) -{ - MyGlobals::_World_Size = 1; - MyGlobals::_Rank = 0; - MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; - MyGlobals::_Create_Joints = create_joints; - - ParaDomainSelector parallelizer(mesure_memory); - _input_collection=new MeshCollection(); - _input_collection->setParaDomainSelector( ¶llelizer ); - _input_collection->retrieveDriver()->readMEDFileData(filedata); - - MEDPARTITIONER::ParallelTopology* aPT = - (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); - aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); - _input_collection->prepareFieldDescriptions(); - createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory); - - parallelizer.evaluateMemory(); -} - -MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, MEDPARTITIONER ::Graph* graph, bool creates_boundary_faces, bool create_joints, bool mesure_memory): - _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) -{ - MyGlobals::_World_Size = 1; - MyGlobals::_Rank = 0; - MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; - MyGlobals::_Create_Joints = create_joints; - - ParaDomainSelector parallelizer(mesure_memory); - _input_collection=new MeshCollection(); - _input_collection->setParaDomainSelector( ¶llelizer ); - _input_collection->retrieveDriver()->readMEDFileData(filedata); - - MEDPARTITIONER::ParallelTopology* aPT = - (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); - aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); - _input_collection->prepareFieldDescriptions(); - - _new_topology = new MEDPARTITIONER::ParallelTopology( graph, aPT, graph->nbDomains(), _input_collection->getMeshDimension() ); - _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false); - _output_collection->filterFaceOnCell(); - - parallelizer.evaluateMemory(); -} - -MEDPARTITIONER::MEDPartitioner::~MEDPartitioner() -{ - delete _input_collection; _input_collection = 0; - delete _output_collection; _output_collection = 0; - delete _new_topology; _new_topology = 0; -} - -void MEDPARTITIONER::MEDPartitioner::createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory) -{ - //ParallelTopology* aPT = (ParallelTopology*) _input_collection->getTopology(); - if (library == "metis") - _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::METIS); - else - _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH); - _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false); - _output_collection->filterFaceOnCell(); -} - -void MEDPARTITIONER::MEDPartitioner::write(const std::string& filename) -{ - ParaDomainSelector parallelizer(false); - _output_collection->setParaDomainSelector( ¶llelizer ); - _output_collection->write(filename); - parallelizer.evaluateMemory(); -} - -ParaMEDMEM::MEDFileData* MEDPARTITIONER::MEDPartitioner::getMEDFileData() -{ - return _output_collection->retrieveDriver()->getMEDFileData(); -} - -MEDPARTITIONER::Graph* MEDPARTITIONER::MEDPartitioner::Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split, int* edgeweight) -{ - MEDPARTITIONER::Graph* cellGraph=0; - ParaMEDMEM::MEDCouplingSkyLineArray* arr = new ParaMEDMEM::MEDCouplingSkyLineArray(graph->getIndexArray(), graph->getValueArray()); - switch (split) - { - case Graph::METIS: - if ( !cellGraph ) - { -#ifdef MED_ENABLE_METIS - cellGraph=new METISGraph(arr,edgeweight); -#endif - } - if ( !cellGraph ) - throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PARMETIS/METIS is not available. Check your products, please."); - break; - case Graph::SCOTCH: -#ifdef MED_ENABLE_SCOTCH - cellGraph=new SCOTCHGraph(arr,edgeweight); -#else - throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : SCOTCH is not available. Check your products, please."); -#endif - break; - } - return cellGraph; -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx deleted file mode 100644 index fecaf0cc9..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MEDPARTITIONER_HXX__ -#define __MEDPARTITIONER_MEDPARTITIONER_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <map> -#include <vector> - -namespace ParaMEDMEM -{ - class MEDFileData; -} - -namespace MEDPARTITIONER -{ - class Topology; - class MeshCollection; - - class MEDPARTITIONER_EXPORT MEDPartitioner - { - public: - MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); - static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0); - void write(const std::string& filename); - ParaMEDMEM::MEDFileData* getMEDFileData(); - ~MEDPartitioner(); - - ParaMEDMEM::MEDFileData *convertToMEDFileData(MeshCollection* meshcollection); - void createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory); - - private: - MeshCollection* _input_collection; - MeshCollection* _output_collection; - Topology* _new_topology; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx deleted file mode 100644 index d0ad9d4cb..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx +++ /dev/null @@ -1,2459 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MeshCollection.hxx" - -#include "MEDPARTITIONER_ConnectZone.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" -#include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" -#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_UserGraph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#ifdef HAVE_MPI -#include "MEDPARTITIONER_JointFinder.hxx" -#endif - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -#ifdef MED_ENABLE_PARMETIS -#include "MEDPARTITIONER_ParMetisGraph.hxx" -#endif -#ifdef MED_ENABLE_METIS -#include "MEDPARTITIONER_MetisGraph.hxx" -#endif -#ifdef MED_ENABLE_SCOTCH -#include "MEDPARTITIONER_ScotchGraph.hxx" -#endif - -#include <set> -#include <vector> -#include <string> -#include <limits> -#include <iostream> -#include <fstream> - -MEDPARTITIONER::MeshCollection::MeshCollection() - : _topology(0), - _owns_topology(false), - _driver(0), - _domain_selector( 0 ), - _i_non_empty_mesh(-1), - _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates( MyGlobals::_Creates_Boundary_Faces ), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ -} - -/*!constructor creating a new mesh collection (mesh series + topology) - *from an old collection and a new topology - * - * On output, the constructor has built the meshes corresponding to the new mesh collection. - * The new topology has been updated so that face and node mappings are included. - * The families have been cast to their projections in the new topology. - * - * \param initial_collection collection from which the data (coordinates, connectivity) are taken - * \param topology topology containing the cell mappings - */ - -MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection, - Topology* topology, - bool family_splitting, - bool create_empty_groups) - : _topology(topology), - _owns_topology(false), - _driver(0), - _domain_selector( initialCollection._domain_selector ), - _i_non_empty_mesh(-1), - _name(initialCollection._name), - _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(family_splitting), - _create_empty_groups(create_empty_groups), - _joint_finder(0) -{ - std::vector<std::vector<std::vector<int> > > new2oldIds(initialCollection.getTopology()->nbDomain()); - std::vector<ParaMEDMEM::DataArrayInt*> o2nRenumber; - - castCellMeshes(initialCollection, new2oldIds, o2nRenumber ); - - //defining the name for the collection and the underlying meshes - setName(initialCollection.getName()); - - ///////////////// - //treating faces - ///////////////// - -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - std::cout<<"treating faces"<<std::endl; - NodeMapping nodeMapping; - //nodeMapping contains the mapping between old nodes and new nodes - // (iolddomain,ioldnode)->(inewdomain,inewnode) - createNodeMapping(initialCollection, nodeMapping); - std::vector<std::vector<std::vector<int> > > new2oldFaceIds; - castFaceMeshes(initialCollection, nodeMapping, new2oldFaceIds); - - //////////////////// - //treating families - //////////////////// -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - { - if (isParallelMode()) - std::cout << "ParallelMode on " << topology->nbDomain() << " Domains" << std::endl; - else - std::cout << "NOT ParallelMode on " << topology->nbDomain() << " Domains" << std::endl; - } - if (MyGlobals::_Is0verbose>10) - std::cout<<"treating cell and face families"<<std::endl; - - castIntField(initialCollection.getMesh(), - this->getMesh(), - initialCollection.getCellFamilyIds(), - "cellFamily"); - castIntField(initialCollection.getFaceMesh(), - this->getFaceMesh(), - initialCollection.getFaceFamilyIds(), - "faceFamily"); - - //treating groups -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - std::cout << "treating groups" << std::endl; - _family_info=initialCollection.getFamilyInfo(); - _group_info=initialCollection.getGroupInfo(); - -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - std::cout << "treating fields" << std::endl; - castAllFields(initialCollection,"cellFieldDouble"); - if (_i_non_empty_mesh<0) - { - for (size_t i=0; i<_mesh.size(); i++) - { - if (_mesh[i]) - { - _i_non_empty_mesh=i; //first existing one local - break; - } - } - } - - // find faces common with neighbor domains and put them in groups - buildBoundaryFaces(); - - //building the connect zones necessary for writing joints - buildConnectZones( nodeMapping, o2nRenumber, initialCollection.getTopology()->nbDomain() ); - - // delete o2nRenumber - for ( size_t i = 0; i < o2nRenumber.size(); ++i ) - if ( o2nRenumber[i] ) - o2nRenumber[i]->decrRef(); -} - -/*! - Creates the meshes using the topology underlying he mesh collection and the mesh data - coming from the ancient collection - \param initialCollection collection from which the data is extracted to create the new meshes - \param [out] o2nRenumber returns for each new domain a permutation array returned by sortCellsInMEDFileFrmt() -*/ - -void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialCollection, - std::vector<std::vector<std::vector<int> > >& new2oldIds, - std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber) -{ - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : castCellMeshes" << std::endl; - if (_topology==0) - throw INTERP_KERNEL::Exception("Topology has not been defined on call to castCellMeshes"); - - int nbNewDomain=_topology->nbDomain(); - int nbOldDomain=initialCollection.getTopology()->nbDomain(); - - _mesh.resize(nbNewDomain); - o2nRenumber.resize(nbNewDomain,0); - int rank=MyGlobals::_Rank; - //splitting the initial domains into smaller bits - std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes; - splitMeshes.resize(nbNewDomain); - for (int inew=0; inew<nbNewDomain; inew++) - { - splitMeshes[inew].resize(nbOldDomain, (ParaMEDMEM::MEDCouplingUMesh*)0); - } - - for (int iold=0; iold<nbOldDomain; iold++) - { - if (!isParallelMode() || initialCollection._domain_selector->isMyDomain(iold)) - { - int size=(initialCollection._mesh)[iold]->getNumberOfCells(); - std::vector<int> globalids(size); - initialCollection.getTopology()->getCellList(iold, &globalids[0]); - std::vector<int> ilocalnew(size); //local - std::vector<int> ipnew(size); //idomain old - _topology->convertGlobalCellList(&globalids[0],size,&ilocalnew[0],&ipnew[0]); - - new2oldIds[iold].resize(nbNewDomain); - for (int i=0; i<(int)ilocalnew.size(); i++) - { - new2oldIds[iold][ipnew[i]].push_back(i); - } - for (int inew=0; inew<nbNewDomain; inew++) - { - splitMeshes[inew][iold]=(ParaMEDMEM::MEDCouplingUMesh*) - (initialCollection.getMesh())[iold]->buildPartOfMySelf(&new2oldIds[iold][inew][0], - &new2oldIds[iold][inew][0]+new2oldIds[iold][inew].size(), - true); - if (MyGlobals::_Verbose>400) - std::cout<< "proc " << rank << " : a splitMesh iold inew NbCells " << iold << " " << inew << " " - << splitMeshes[inew][iold]->getNumberOfCells() << std::endl; - } - } - } -#ifdef HAVE_MPI - if (isParallelMode()) - { - //if (MyGlobals::_Verbose>300) std::cout<<"proc "<<rank<<" : castCellMeshes send/receive"<<std::endl; - for (int iold=0; iold<nbOldDomain; iold++) - for(int inew=0; inew<nbNewDomain; inew++) - { - if (initialCollection._domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - continue; - - if(initialCollection._domain_selector->isMyDomain(iold)) - _domain_selector->sendMesh(*(splitMeshes[inew][iold]),_domain_selector->getProcessorID(inew)); - - if (_domain_selector->isMyDomain(inew)) - _domain_selector->recvMesh(splitMeshes[inew][iold],_domain_selector->getProcessorID(iold)); - - } - } -#endif - - //fusing the split meshes - if (MyGlobals::_Verbose>200) - std::cout << "proc " << rank << " : castCellMeshes fusing" << std::endl; - for (int inew=0; inew<nbNewDomain ;inew++) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes; - - for (int i=0; i<(int)splitMeshes[inew].size(); i++) - if (splitMeshes[inew][i]!=0) - if (splitMeshes[inew][i]->getNumberOfCells()>0) - meshes.push_back(splitMeshes[inew][i]); - - if (!isParallelMode()||_domain_selector->isMyDomain(inew)) - { - if (meshes.size()==0) - { - _mesh[inew]=CreateEmptyMEDCouplingUMesh(); - std::cout << "WARNING : castCellMeshes fusing : no meshes try another number of processors" << std::endl; - } - else - { - _mesh[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(meshes); - o2nRenumber[inew]=_mesh[inew]->sortCellsInMEDFileFrmt(); - bool areNodesMerged; - int nbNodesMerged; - if (meshes.size()>1) - { - ParaMEDMEM::DataArrayInt* array=_mesh[inew]->mergeNodes(1e-12,areNodesMerged,nbNodesMerged); - array->decrRef(); // array is not used in this case - } - _mesh[inew]->zipCoords(); - } - } - for (int i=0;i<(int)splitMeshes[inew].size();i++) - if (splitMeshes[inew][i]!=0) - splitMeshes[inew][i]->decrRef(); - } - if (MyGlobals::_Verbose>300) - std::cout << "proc " << rank << " : castCellMeshes end fusing" << std::endl; -} - -/*! - \param initialCollection source mesh collection - \param nodeMapping structure containing the correspondency between nodes in the initial collection and the node(s) in the new collection -*/ -void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialCollection, NodeMapping& nodeMapping) -{ - using std::vector; - using std::make_pair; - // NodeMapping reverseNodeMapping; - for (int iold=0; iold<initialCollection.getTopology()->nbDomain();iold++) - { - - double* bbox; - BBTreeOfDim* tree = 0; - int dim = 3; - if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) - { - // std::map<pair<double,pair<double, double> >, int > nodeClassifier; - ParaMEDMEM::DataArrayDouble* coords = initialCollection.getMesh(iold)->getCoords(); - double* coordsPtr=coords->getPointer(); - dim = coords->getNumberOfComponents(); - int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes(); - bbox=new double[nvertices*2*dim]; - - for (int i=0; i<nvertices*dim;i++) - { - bbox[i*2]=coordsPtr[i]-1e-8; - bbox[i*2+1]=coordsPtr[i]+1e-8; - } - tree=new BBTreeOfDim( dim, bbox,0,0,nvertices,1e-9); - } - - for (int inew=0; inew<_topology->nbDomain(); inew++) - { -#ifdef HAVE_MPI - //sending meshes for parallel computation - if (isParallelMode() && _domain_selector->isMyDomain(inew) && !_domain_selector->isMyDomain(iold)) - _domain_selector->sendMesh(*(getMesh(inew)), _domain_selector->getProcessorID(iold)); - else if (isParallelMode() && !_domain_selector->isMyDomain(inew)&& _domain_selector->isMyDomain(iold)) - { - ParaMEDMEM::MEDCouplingUMesh* mesh; - _domain_selector->recvMesh(mesh, _domain_selector->getProcessorID(inew)); - ParaMEDMEM::DataArrayDouble* coords = mesh->getCoords(); - for (int inode=0; inode<mesh->getNumberOfNodes();inode++) - { - double* coordsPtr=coords->getPointer()+inode*dim; - vector<int> elems; - tree->getElementsAroundPoint(coordsPtr,elems); - if (elems.size()==0) continue; - nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); - } - mesh->decrRef(); - } - else if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) -#else - if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) -#endif - { - ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords(); - for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++) - { - double* coordsPtr=coords->getPointer()+inode*dim; - vector<int> elems; - tree->getElementsAroundPoint(coordsPtr,elems); - if (elems.size()==0) continue; - nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); - } - } - } - if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) - { - delete tree; - delete[] bbox; - } - } - -} - -void getNodeIds(ParaMEDMEM::MEDCouplingUMesh& meshOne, ParaMEDMEM::MEDCouplingUMesh& meshTwo, std::vector<int>& nodeIds) -{ - using std::vector; - using MEDPARTITIONER::BBTreeOfDim; - if (!&meshOne || !&meshTwo) return; //empty or not existing - double* bbox; - BBTreeOfDim* tree = 0; - int nv1=meshOne.getNumberOfNodes(); - ParaMEDMEM::DataArrayDouble* coords=meshOne.getCoords(); - int dim = coords->getNumberOfComponents(); - - bbox=new double[nv1*2*dim]; - double* coordsPtr=coords->getPointer(); - for (int i=0; i<nv1*dim; i++) - { - bbox[i*2]=coordsPtr[i]-1e-8; - bbox[i*2+1]=coordsPtr[i]+1e-8; - } - tree=new BBTreeOfDim( dim, bbox,0,0,nv1,1e-9); - - int nv2=meshTwo.getNumberOfNodes(); - nodeIds.resize(nv2,-1); - coords=meshTwo.getCoords(); - for (int inode=0; inode<nv2; inode++) - { - double* coordsPtr2=coords->getPointer()+inode*dim; - vector<int> elems; - tree->getElementsAroundPoint(coordsPtr2,elems); - if (elems.size()==0) continue; - nodeIds[inode]=elems[0]; - } - delete tree; - delete[] bbox; -} - -/*! - creates the face meshes on the new domains from the faces on the old domain and the node mapping - faces at the interface are duplicated -*/ -void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialCollection, - const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping, - std::vector<std::vector<std::vector<int> > >& new2oldIds) -{ - //splitMeshes structure will contain the partition of - //the old faces on the new ones - //splitMeshes[4][2] contains the faces from old domain 2 - //that have to be added to domain 4 - - using std::vector; - using std::map; - using std::multimap; - using std::pair; - using std::make_pair; - - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes" << std::endl; - if (_topology==0) - throw INTERP_KERNEL::Exception("Topology has not been defined on call to castFaceMeshes"); - - int nbNewDomain=_topology->nbDomain(); - int nbOldDomain=initialCollection.getTopology()->nbDomain(); - - vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom=initialCollection.getFaceMesh(); - vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo=this->getFaceMesh(); - - vector< vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes; - - splitMeshes.resize(nbNewDomain); - for (int inew=0; inew<nbNewDomain; inew++) - { - splitMeshes[inew].resize(nbOldDomain, (ParaMEDMEM::MEDCouplingUMesh*)0); - } - new2oldIds.resize(nbOldDomain); - for (int iold=0; iold<nbOldDomain; iold++) new2oldIds[iold].resize(nbNewDomain); - - //init null pointer for empty meshes - for (int inew=0; inew<nbNewDomain; inew++) - { - for (int iold=0; iold<nbOldDomain; iold++) - { - splitMeshes[inew][iold]=0; //null for empty meshes - new2oldIds[iold][inew].clear(); - } - } - - //loop over the old domains to analyse the faces and decide - //on which new domain they belong - for (int iold=0; iold<nbOldDomain; iold++) - { - if (isParallelMode() && !initialCollection._domain_selector->isMyDomain(iold)) continue; - if (MyGlobals::_Verbose>400) - std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes iodDomain "<<iold<<std::endl; - //initial face mesh known : in my domain - if (meshesCastFrom[iold] != 0) - { - for (int ielem=0; ielem<meshesCastFrom[iold]->getNumberOfCells(); ielem++) - { - vector<int> nodes; - meshesCastFrom[iold]->getNodeIdsOfCell(ielem,nodes); - - map <int,int> faces; - - //analysis of element ielem - //counters are set for the element - //for each source node, the mapping is interrogated and the domain counters - //are incremented for each target node - //the face is considered as going to target domains if the counter of the domain - //is equal to the number of nodes - for (int inode=0; inode<(int)nodes.size(); inode++) - { - typedef multimap<pair<int,int>,pair<int,int> >::const_iterator MI; - int mynode=nodes[inode]; - - pair <MI,MI> myRange = nodeMapping.equal_range(make_pair(iold,mynode)); - for (MI iter=myRange.first; iter!=myRange.second; iter++) - { - int inew=iter->second.first; - if (faces.find(inew)==faces.end()) - faces[inew]=1; - else - faces[inew]++; - } - } - - for (map<int,int>::iterator iter=faces.begin(); iter!=faces.end(); iter++) - { - if (iter->second==(int)nodes.size()) - //cvw eligible but may be have to be face of a cell of this->getMesh()[inew]? - //it is not sure here... - //done before writeMedfile on option?... see filterFaceOnCell() - new2oldIds[iold][iter->first].push_back(ielem); - } - } - - //creating the splitMeshes from the face ids - for (int inew=0; inew<nbNewDomain; inew++) - { - if (meshesCastFrom[iold]->getNumberOfCells() > 0) - { - splitMeshes[inew][iold]= - (ParaMEDMEM::MEDCouplingUMesh*) - ( meshesCastFrom[iold]->buildPartOfMySelf(&new2oldIds[iold][inew][0], - &new2oldIds[iold][inew][0]+new2oldIds[iold][inew].size(), - true) - ); - splitMeshes[inew][iold]->zipCoords(); - } - else - { - splitMeshes[inew][iold]=CreateEmptyMEDCouplingUMesh(); - } - } - } - else - { - std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes empty mesh from iodDomain "<<iold<<std::endl; - } - } - -#ifdef HAVE_MPI - //send/receive stuff - if (isParallelMode()) - { - ParaMEDMEM::MEDCouplingUMesh *empty=CreateEmptyMEDCouplingUMesh(); - for (int iold=0; iold<nbOldDomain; iold++) - for (int inew=0; inew<nbNewDomain; inew++) - { - if (initialCollection._domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) - { - if (splitMeshes[inew][iold] != 0) - { - _domain_selector->sendMesh(*(splitMeshes[inew][iold]), _domain_selector->getProcessorID(inew)); - //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes send " <<inew<<" "<<iold<<" "<<splitMeshes[inew][iold]->getNumberOfCells()<<std::endl; - } - else - { - _domain_selector->sendMesh(*(empty), _domain_selector->getProcessorID(inew)); - //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes sen0 " <<inew<<" "<<iold<<std::endl; - } - } - if (!initialCollection._domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - _domain_selector->recvMesh(splitMeshes[inew][iold], _domain_selector->getProcessorID(iold)); - //int nb=0; - //if (splitMeshes[inew][iold]) - // nb=splitMeshes[inew][iold]->getNumberOfCells(); - //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes recv "<<inew<<" "<<iold<<" "<<nb<<std::endl;//" "<<splitMeshes[inew][iold]->getNumberOfCells()<<std::endl; - } - empty->decrRef(); - } -#endif - - //fusing the split meshes - if (MyGlobals::_Verbose>200) - std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes fusing" << std::endl; - meshesCastTo.resize(nbNewDomain); - for (int inew=0; inew<nbNewDomain; inew++) - { - vector<const ParaMEDMEM::MEDCouplingUMesh*> myMeshes; - for (int iold=0; iold<nbOldDomain; iold++) - { - ParaMEDMEM::MEDCouplingUMesh *umesh=splitMeshes[inew][iold]; - if (umesh!=0) - if (umesh->getNumberOfCells()>0) - myMeshes.push_back(umesh); - } - - ParaMEDMEM::MEDCouplingUMesh *bndMesh = 0; - if ( _subdomain_boundary_creates && - _mesh[inew] && - _mesh[inew]->getNumberOfCells()>0 ) - { - bndMesh = - ((ParaMEDMEM::MEDCouplingUMesh *)_mesh[inew]->buildBoundaryMesh(/*keepCoords=*/true)); - if (bndMesh->getNumberOfCells()>0) - myMeshes.push_back( bndMesh ); - } - - if (myMeshes.size()>0) - { - meshesCastTo[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(myMeshes); - meshesCastTo[inew]->sortCellsInMEDFileFrmt()->decrRef(); - } - else - { - ParaMEDMEM::MEDCouplingUMesh *empty=CreateEmptyMEDCouplingUMesh(); - meshesCastTo[inew]=empty; - } - for (int iold=0; iold<nbOldDomain; iold++) - if (splitMeshes[inew][iold]!=0) - splitMeshes[inew][iold]->decrRef(); - if ( bndMesh ) - bndMesh->decrRef(); - } - if (MyGlobals::_Verbose>300) - std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes end fusing" << std::endl; -} - - - -void MEDPARTITIONER::MeshCollection::castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom, - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, - std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom, - std::string nameArrayTo) -{ - using std::vector; - - int ioldMax=meshesCastFrom.size(); - int inewMax=meshesCastTo.size(); - - - //preparing bounding box trees for accelerating source-target node identifications - if (MyGlobals::_Verbose>99) - std::cout<<"making accelerating structures"<<std::endl; - std::vector<BBTreeOfDim* > acceleratingStructures(ioldMax); - std::vector<ParaMEDMEM::DataArrayDouble*>bbox(ioldMax); - for (int iold =0; iold< ioldMax; iold++) - if (isParallelMode() && _domain_selector->isMyDomain(iold)) - { - ParaMEDMEM::DataArrayDouble* sourceCoords=meshesCastFrom[iold]->getBarycenterAndOwner(); - bbox[iold]=sourceCoords->computeBBoxPerTuple(1.e-6); - acceleratingStructures[iold]=new BBTreeOfDim( sourceCoords->getNumberOfComponents(), bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples()); - sourceCoords->decrRef(); - } - // send-recv operations -#ifdef HAVE_MPI - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - { - //sending arrays for distant domains - if (isParallelMode() && _domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) - { - //send mesh - _domain_selector->sendMesh(*meshesCastFrom[iold],_domain_selector->getProcessorID(inew)); - //send vector - int size=arrayFrom[iold]->getNumberOfTuples(); //cvw may be -1! - vector<int>sendIds; - if (MyGlobals::_Verbose>400) std::cout<<"proc "<<_domain_selector->rank()<<" : castIntField SendIntVec size "<<size<<std::endl; - if (size>0) //no empty - { - sendIds.resize(size); - std::copy(arrayFrom[iold]->getPointer(),arrayFrom[iold]->getPointer()+size,&sendIds[0]); - } - else //empty - { - size=0; - sendIds.resize(size); - } - SendIntVec(sendIds, _domain_selector->getProcessorID(inew)); - } - //receiving arrays from distant domains - if (isParallelMode() && !_domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - { - //receive mesh - vector<int> recvIds; - ParaMEDMEM::MEDCouplingUMesh* recvMesh; - _domain_selector->recvMesh(recvMesh,_domain_selector->getProcessorID(iold)); - //receive vector - if (MyGlobals::_Verbose>400) std::cout<<"proc "<<_domain_selector->rank()<<" : castIntField recIntVec "<<std::endl; - RecvIntVec(recvIds, _domain_selector->getProcessorID(iold)); - remapIntField(inew,iold,*recvMesh,*meshesCastTo[inew],&recvIds[0],nameArrayTo,0); - recvMesh->decrRef(); //cww is it correct? - } - } - } -#endif - - //local contributions and aggregation - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - if (!isParallelMode() || ( _domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew))) - { - remapIntField(inew,iold,*meshesCastFrom[iold],*meshesCastTo[inew],arrayFrom[iold]->getConstPointer(),nameArrayTo,acceleratingStructures[iold]); - } - } - for (int iold=0; iold<ioldMax;iold++) - if (isParallelMode() && _domain_selector->isMyDomain(iold)) - { - bbox[iold]->decrRef(); - delete acceleratingStructures[iold]; - } -} - -void MEDPARTITIONER::MeshCollection::remapIntField(int inew, int iold, - const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, - const ParaMEDMEM::MEDCouplingUMesh& targetMesh, - const int* fromArray, - std::string nameArrayTo, - const BBTreeOfDim* myTree) -{ - - if (sourceMesh.getNumberOfCells()<=0) return; //empty mesh could exist - ParaMEDMEM::DataArrayDouble* targetCoords=targetMesh.getBarycenterAndOwner(); - const double* tc=targetCoords->getConstPointer(); - int targetSize=targetMesh.getNumberOfCells(); - int sourceSize=sourceMesh.getNumberOfCells(); - if (MyGlobals::_Verbose>200) - std::cout<<"remap vers target de taille "<<targetSize<<std::endl; - std::vector<int> ccI; - std::string str,cle; - str=nameArrayTo+"_toArray"; - cle=Cle1ToStr(str,inew); - int* toArray; - - const BBTreeOfDim* tree; - bool cleantree=false; - ParaMEDMEM::DataArrayDouble* sourceBBox=0; - int dim = targetCoords->getNumberOfComponents(); - if (myTree==0) - { - sourceBBox=sourceMesh.getBarycenterAndOwner()->computeBBoxPerTuple(1e-8); - tree=new BBTreeOfDim( dim, sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10); - cleantree=true; - } - else tree=myTree; - //first time iold : create and initiate - if (_map_dataarray_int.find(cle)==_map_dataarray_int.end()) - { - if (MyGlobals::_Is0verbose>100) - std::cout << "create " << cle << " size " << targetSize << std::endl; - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - p->alloc(targetSize,1); - p->fillWithZero(); - toArray=p->getPointer(); - _map_dataarray_int[cle]=p; - } - else //other times iold: refind and complete - { - toArray=_map_dataarray_int.find(cle)->second->getPointer(); - } - - std::map< int, int > isource2nb; // count coincident elements - std::map<int,int>::iterator i2nb; - - for (int itargetnode=0; itargetnode<targetSize; itargetnode++) - { - std::vector<int> intersectingElems; - tree->getElementsAroundPoint(tc+itargetnode*dim,intersectingElems); - if (intersectingElems.size()!=0) - { - int isourcenode=intersectingElems[0]; - if ( intersectingElems.size() > 1 ) - { - i2nb = isource2nb.insert( std::make_pair( isourcenode, 0 )).first; - isourcenode = intersectingElems[ i2nb->second++ ]; - } - if ( isourcenode < sourceSize ) // protection from invalid elements - { - toArray[itargetnode]=fromArray[isourcenode]; - ccI.push_back(itargetnode); - ccI.push_back(isourcenode); - } - } - } - if (MyGlobals::_Verbose>200) - std::cout<<"nb points trouves"<<ccI.size()/2<<std::endl; - //memories intersection for future same job on fields (if no existing cle=no intersection) - str=Cle2ToStr(nameArrayTo+"_ccI",inew,iold); - if (MyGlobals::_Verbose>700) - std::cout << "proc " << MyGlobals::_Rank << " : map memorize '" << str << "'\n"; - - _map_dataarray_int[str]=CreateDataArrayIntFromVector(ccI, 2); - - targetCoords->decrRef(); - if (cleantree) delete tree; - if (sourceBBox !=0) sourceBBox->decrRef(); -} - -void MEDPARTITIONER::MeshCollection::castAllFields(MeshCollection& initialCollection, std::string nameArrayTo) -{ - if (nameArrayTo!="cellFieldDouble") - throw INTERP_KERNEL::Exception("Error castAllField only on cellFieldDouble"); - - std::string nameTo="typeData=6"; //resume the type of field casted - // send-recv operations - int ioldMax=initialCollection.getMesh().size(); - int inewMax=this->getMesh().size(); - int iFieldMax=initialCollection.getFieldDescriptions().size(); - if (MyGlobals::_Verbose>10) - std::cout << "castAllFields with:\n" << ReprVectorOfString(initialCollection.getFieldDescriptions()) << std::endl; - //see collection.prepareFieldDescriptions() - for (int ifield=0; ifield<iFieldMax; ifield++) - { - std::string descriptionField=initialCollection.getFieldDescriptions()[ifield]; - if (descriptionField.find(nameTo)==std::string::npos) - continue; //only nameTo accepted in Fields name description -#ifdef HAVE_MPI - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - { - //sending arrays for distant domains - if (isParallelMode() && _domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) - { - int target=_domain_selector->getProcessorID(inew); - ParaMEDMEM::DataArrayDouble* field=initialCollection.getField(descriptionField,iold); - if (MyGlobals::_Verbose>10) - std::cout << "proc " << _domain_selector->rank() << " : castAllFields sendDouble" << std::endl; - SendDataArrayDouble(field, target); - } - //receiving arrays from distant domains - if (isParallelMode() && !_domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - { - int source=_domain_selector->getProcessorID(iold); - //receive vector - if (MyGlobals::_Verbose>10) - std::cout << "proc " << _domain_selector->rank() << " : castAllFields recvDouble" << std::endl; - ParaMEDMEM::DataArrayDouble* field=RecvDataArrayDouble(source); - remapDoubleField(inew,iold,field,nameArrayTo,descriptionField); - } - } - } -#endif - //local contributions and aggregation - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - if (!isParallelMode() || ( _domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew))) - { - ParaMEDMEM::DataArrayDouble* field=initialCollection.getField(descriptionField,iold); - remapDoubleField(inew,iold,field,nameArrayTo,descriptionField); - } - } - } -} - -void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold, - ParaMEDMEM::DataArrayDouble* fromArray, - std::string nameArrayTo, - std::string descriptionField) -//here we use 'cellFamily_ccI inew iold' set in remapIntField -{ - if (nameArrayTo!="cellFieldDouble") - throw INTERP_KERNEL::Exception("Error remapDoubleField only on cellFieldDouble"); - std::string key=Cle2ToStr("cellFamily_ccI",inew,iold); - - std::map<std::string,ParaMEDMEM::DataArrayInt*>::iterator it1; - it1=_map_dataarray_int.find(key); - if (it1==_map_dataarray_int.end()) - { - std::cerr << "proc " << MyGlobals::_Rank << " : remapDoubleField key '" << key << "' not found" << std::endl; - std::cerr << " trying remap of field double on cells : " << descriptionField << std::endl; - return; - } - //create ccI in remapIntField - ParaMEDMEM::DataArrayInt *ccI=it1->second; - if (MyGlobals::_Verbose>300) - std::cout << "proc " << MyGlobals::_Rank << " : remapDoubleField " << key << " size " << ccI->getNbOfElems() << std::endl; - - int nbcell=this->getMesh()[inew]->getNumberOfCells(); - int nbcomp=fromArray->getNumberOfComponents(); - int nbPtGauss=StrToInt(ExtractFromDescription(descriptionField, "nbPtGauss=")); - - std::string tag="inewFieldDouble="+IntToStr(inew); - key=descriptionField+SerializeFromString(tag); - int fromArrayNbOfElem=fromArray->getNbOfElems(); - int fromArrayNbOfComp=fromArray->getNumberOfComponents(); - int fromArrayNbOfCell=fromArrayNbOfElem/fromArrayNbOfComp/nbPtGauss; - - if (MyGlobals::_Verbose>1000) - { - std::cout<<"proc " << MyGlobals::_Rank << " nbcell " << nbcell << " nbcomp " << nbcomp << " nbPtGauss " << nbPtGauss << - " fromArray nbOfElems " << fromArrayNbOfElem << - " nbTuples " << fromArray->getNumberOfTuples() << - " nbcells " << fromArrayNbOfCell << - " nbComponents " << fromArray->getNumberOfComponents() << std::endl; - } - - ParaMEDMEM::DataArrayDouble* field=0; - std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it2; - it2=_map_dataarray_double.find(key); - if (it2==_map_dataarray_double.end()) - { - if (MyGlobals::_Verbose>300) - std::cout << "proc "<< MyGlobals::_Rank << " : remapDoubleField key '" << key << "' not found and create it" << std::endl; - field=ParaMEDMEM::DataArrayDouble::New(); - _map_dataarray_double[key]=field; - field->alloc(nbcell*nbPtGauss,nbcomp); - field->fillWithZero(); - } - else - { - field=it2->second; - if (field->getNumberOfTuples()!=nbcell*nbPtGauss || field->getNumberOfComponents()!=nbcomp) - { - std::cerr << "proc " << MyGlobals::_Rank << " : remapDoubleField3 pb of size " << - " trying remap of field double on cells : \n" << descriptionField << std::endl; - return; - } - } - - if (nbPtGauss==1) - { - field->setPartOfValuesAdv(fromArray,ccI); - } - else - { - //replaced by setPartOfValuesAdv if nbPtGauss==1 - int iMax=ccI->getNbOfElems(); - int* pccI=ccI->getPointer(); - double* pField=field->getPointer(); - double* pFrom=fromArray->getPointer(); - int itarget, isource, delta=nbPtGauss*nbcomp; - for (int i=0; i<iMax; i=i+2) //cell - { - itarget=pccI[i]; - isource=pccI[i+1]; - if ((itarget<0) || (itarget>=nbcell) || (isource<0) || (isource>=fromArrayNbOfCell)) - throw INTERP_KERNEL::Exception("Error field override"); - int ita=itarget*delta; - int iso=isource*delta; - for (int k=0; k<delta; k++) pField[ita+k]=pFrom[iso+k]; //components and gausspoints - } - } -} - -namespace -{ - using namespace ParaMEDMEM; - //================================================================================ - /*! - * \brief Sort correspondence ids of one domain and permute ids of the other accordingly - * \param [in,out] ids1 - ids of one domain - * \param [in,out] ids2 - ids of another domain - * \param [in] delta - a delta to change all ids - * \param [in] removeEqual - to remove equal ids - * \return DataArrayInt* - array of ids joined back - */ - //================================================================================ - - DataArrayInt* sortCorrespondences( DataArrayInt* ids1, - DataArrayInt* ids2, - int delta, - bool removeEqual = false) - { - // sort - MEDCouplingAutoRefCountObjectPtr< DataArrayInt > renumN2O = ids1->buildPermArrPerLevel(); - ids1->renumberInPlaceR( renumN2O->begin() ); - ids2->renumberInPlaceR( renumN2O->begin() ); - - if ( removeEqual ) - { - ids1 = ids1->buildUnique(); - ids2 = ids2->buildUnique(); - } - if ( delta != 0 ) - { - int * id = ids1->getPointer(); - for ( ; id < ids1->end(); ++id ) - ++(*id); - id = ids2->getPointer(); - for ( ; id < ids2->end(); ++id ) - ++(*id); - } - - // join - DataArrayInt* ids12 = DataArrayInt::Meld( ids1, ids2 ); // two components - ids12->rearrange( 1 ); // make one component - return ids12; - } - - //================================================================================ - /*! - * \brief Renumber ids according to mesh->sortCellsInMEDFileFrmt() - * \param [in,out] ids - cell ids to renumber - * \param [in] o2nRenumber - renumbering array in "Old to New" mode - */ - //================================================================================ - - void renumber( DataArrayInt* ids, const DataArrayInt* o2nRenumber ) - { - if ( !ids || !o2nRenumber ) - return; - int * id = ids->getPointer(); - const int * o2n = o2nRenumber->getConstPointer(); - for ( ; id < ids->end(); ++id ) - { - *id = o2n[ *id ]; - } - } -} - -//================================================================================ -/*! - * \brief Fill up ConnectZone's stored in _topology with nodal correspondences - * \param [in] nodeMapping - mapping between old nodes and new nodes - * (iolddomain,ioldnode)->(inewdomain,inewnode) - * \param [in] o2nRenumber - renumbering array returned by mesh->sortCellsInMEDFileFrmt() - * per a new domain - * \param [in] nbInitialDomains - nb of old domains - */ -//================================================================================ - -void MEDPARTITIONER::MeshCollection::buildConnectZones( const NodeMapping& nodeMapping, - const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber, - int nbInitialDomains) -{ - if ( !MyGlobals::_Create_Joints || _topology->nbDomain() < 2 ) - return; - - if ( MyGlobals::_World_Size > 1 ) - { - _topology->getCZ().clear(); - return; // not implemented for parallel mode - } - - // at construction, _topology creates cell correspondences basing on Graph information, - // and here we - // 1) add node correspondences, - // 2) split cell correspondences by cell geometry types - // 3) sort ids to be in ascending order - - const int nb_domains = _topology->nbDomain(); - - // ================================== - // 1) add node correspondences - // ================================== - - std::vector< std::vector< std::vector< int > > > nodeCorresp( nb_domains ); - for ( int idomain = 0; idomain < nb_domains; ++idomain ) - { - nodeCorresp[ idomain ].resize( nb_domains ); - } - - NodeMapping::const_iterator nmIt1, nmIt2 = nodeMapping.begin(); - for ( nmIt1 = nmIt2; nmIt1 != nodeMapping.end(); nmIt1 = nmIt2 ) - { - // look for an "old" node mapped into several "new" nodes in different domains - int nbSameOld = 0; - while ( ++nmIt2 != nodeMapping.end() && nmIt2->first == nmIt1->first ) - nbSameOld += ( nmIt2->second != nmIt1->second ); - - if ( nbSameOld > 0 ) - { - NodeMapping::const_iterator nmEnd = nmIt2; - for ( ; true; ++nmIt1 ) - { - nmIt2 = nmIt1; - if ( ++nmIt2 == nmEnd ) - break; - int dom1 = nmIt1->second.first; - int node1 = nmIt1->second.second; - for ( ; nmIt2 != nmEnd; ++nmIt2 ) - { - int dom2 = nmIt2->second.first; - int node2 = nmIt2->second.second; - if ( dom1 != dom2 ) - { - nodeCorresp[ dom1 ][ dom2 ].push_back( node1 ); - nodeCorresp[ dom1 ][ dom2 ].push_back( node2 ); - nodeCorresp[ dom2 ][ dom1 ].push_back( node2 ); - nodeCorresp[ dom2 ][ dom1 ].push_back( node1 ); - } - } - } - } - } - - // add nodeCorresp to czVec - - std::vector<MEDPARTITIONER::ConnectZone*>& czVec = _topology->getCZ(); - - for ( int idomain = 0; idomain < nb_domains; ++idomain ) - { - for ( int idomainNear = 0; idomainNear < nb_domains; ++idomainNear ) - { - std::vector< int > & corresp = nodeCorresp[ idomain ][ idomainNear ]; - if ( corresp.empty() ) - continue; - - MEDPARTITIONER::ConnectZone* cz = 0; - for ( size_t i = 0; i < czVec.size() && !cz; ++i ) - if ( czVec[i] && - czVec[i]->getLocalDomainNumber () == idomain && - czVec[i]->getDistantDomainNumber() == idomainNear ) - cz = czVec[i]; - - if ( !cz ) - { - cz = new MEDPARTITIONER::ConnectZone(); - cz->setName( "Nodal Connect Zone defined by MEDPARTITIONER" ); - cz->setLocalDomainNumber ( idomain ); - cz->setDistantDomainNumber( idomainNear ); - czVec.push_back(cz); - } - - cz->setNodeCorresp( &corresp[0], corresp.size()/2 ); - } - } - - // ========================================================== - // 2) split cell correspondences by cell geometry types - // ========================================================== - - for ( size_t i = 0; i < czVec.size(); ++i ) - { - MEDPARTITIONER::ConnectZone* cz = czVec[i]; - if ( !cz || - cz->getEntityCorrespNumber( 0,0 ) == 0 || - cz->getLocalDomainNumber () > (int)_mesh.size() || - cz->getDistantDomainNumber() > (int)_mesh.size() ) - continue; - ParaMEDMEM::MEDCouplingUMesh* mesh1 = _mesh[ cz->getLocalDomainNumber () ]; - ParaMEDMEM::MEDCouplingUMesh* mesh2 = _mesh[ cz->getDistantDomainNumber() ]; - - // separate ids of two domains - const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getEntityCorresp( 0, 0 ); - const DataArrayInt* ids12 = corrArray->getValueArray(); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted; - ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 ); - ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 ); - - // renumber cells according to mesh->sortCellsInMEDFileFrmt() - renumber( ids1, o2nRenumber[ cz->getLocalDomainNumber() ]); - renumber( ids2, o2nRenumber[ cz->getDistantDomainNumber() ]); - - // check nb cell types - std::set<INTERP_KERNEL::NormalizedCellType> types1, types2; - types1 = mesh1->getTypesOfPart( ids1->begin(), ids1->end() ); - types2 = mesh2->getTypesOfPart( ids2->begin(), ids2->end() ); - if ( types1.size() < 1 || types2.size() < 1 ) - continue; // parallel mode? - - MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1 - for ( size_t j = 0; j < czVec.size() && !cz21; ++j ) - if ( czVec[j] && - czVec[j]->getLocalDomainNumber () == cz->getDistantDomainNumber() && - czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() ) - cz21 = czVec[j]; - - if ( types1.size() == 1 && types2.size() == 1 ) // split not needed, only sort - { - ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 ); - cz->setEntityCorresp( *types1.begin(), *types2.begin(), - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - - if ( cz21 )// set 2->1 correspondence - { - ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 ); - cz21->setEntityCorresp( *types2.begin(), *types1.begin(), - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - } - } - else // split and sort - { - typedef std::pair< std::vector< int >, std::vector< int > > T2Vecs; - T2Vecs idsByType[ INTERP_KERNEL::NORM_MAXTYPE ][ INTERP_KERNEL::NORM_MAXTYPE ]; - int t1, t2; - - const int nbIds = ids1->getNbOfElems(); - const int * p1 = ids1->begin(), * p2 = ids2->begin(); - for ( int i = 0; i < nbIds; ++i ) - { - t1 = mesh1->getTypeOfCell( p1[ i ]); - t2 = mesh2->getTypeOfCell( p2[ i ]); - T2Vecs & ids = idsByType[ t1 ][ t2 ]; - ids.first .push_back( p1[ i ]); - ids.second.push_back( p1[ i ]); - } - - const int maxType = int( INTERP_KERNEL::NORM_MAXTYPE ); - for ( t1 = 0; t1 < maxType; ++t1 ) - for ( t2 = 0; t2 < maxType; ++t2 ) - { - T2Vecs & ids = idsByType[ t1 ][ t2 ]; - if ( ids.first.empty() ) continue; - p1 = & ids.first[0]; - p2 = & ids.second[0]; - ids1->desallocate(); - ids1->pushBackValsSilent( p1, p1+ids.first.size() ); - ids2->desallocate(); - ids2->pushBackValsSilent( p2, p2+ids.first.size() ); - ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 ); - - cz->setEntityCorresp( t1, t2, - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - - if ( cz21 )// set 2->1 correspondence - { - ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 ); - cz21->setEntityCorresp( t2, t1, - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - break; - } - } - }// split and sort - - cz->setEntityCorresp( 0, 0, 0, 0 ); // erase ids computed by _topology - if ( cz21 ) - cz21->setEntityCorresp( 0, 0, 0, 0 ); - - } // loop on czVec - - - // ========================================== - // 3) sort node ids to be in ascending order - // ========================================== - - const bool removeEqual = ( nbInitialDomains > 1 ); - - for ( size_t i = 0; i < czVec.size(); ++i ) - { - MEDPARTITIONER::ConnectZone* cz = czVec[i]; - if ( !cz || cz->getNodeNumber() < 1 ) - continue; - if ( cz->getDistantDomainNumber() < cz->getLocalDomainNumber() ) - continue; // treat a pair of domains once - - MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1 - for ( size_t j = 0; j < czVec.size() && !cz21; ++j ) - if ( czVec[j] && - czVec[j]->getLocalDomainNumber () == cz->getDistantDomainNumber() && - czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() ) - cz21 = czVec[j]; - - // separate ids of two domains - const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getNodeCorresp(); - const DataArrayInt *ids12 = corrArray->getValueArray(); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted; - ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 ); - ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 ); - - ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/0, removeEqual ); - cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - - if ( cz21 )// set 2->1 correspondence - { - ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0, false ); - cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - } - } -} - -//================================================================================ -/*! - * \brief Find faces common with neighbor domains and put them in "JOINT_n_p_Faces" - * group (where "n" and "p" are domain IDs) - */ -//================================================================================ - -void MEDPARTITIONER::MeshCollection::buildBoundaryFaces() -{ - if (_topology->nbDomain() < 2 || !_subdomain_boundary_creates ) - return; - - if ( getMeshDimension() < 2 ) - return; - - using ParaMEDMEM::MEDCouplingUMesh; - using ParaMEDMEM::DataArrayDouble; - using ParaMEDMEM::DataArrayInt; - - std::vector<MEDCouplingUMesh*>& faceMeshes = getFaceMesh(); - int nbMeshes = faceMeshes.size(); - - //preparing bounding box trees for accelerating search of coincident faces - std::vector<BBTreeOfDim* > bbTrees(nbMeshes); - std::vector<DataArrayDouble*>bbox (nbMeshes); - for (int inew = 0; inew < nbMeshes-1; inew++) - if ( !isParallelMode() || _domain_selector->isMyDomain(inew) ) - { - DataArrayDouble* bcCoords = faceMeshes[inew]->getBarycenterAndOwner(); - bbox [inew] = bcCoords->computeBBoxPerTuple(1.e-6); - bbTrees[inew] = new BBTreeOfDim( bcCoords->getNumberOfComponents(), - bbox[inew]->getConstPointer(),0,0, - bbox[inew]->getNumberOfTuples()); - bcCoords->decrRef(); - } - - // loop on domains to find joint faces between them - for (int inew1 = 0; inew1 < nbMeshes; inew1++ ) - { - for (int inew2 = inew1+1; inew2 < nbMeshes; inew2++ ) - { - MEDCouplingUMesh* mesh1 = 0; - MEDCouplingUMesh* mesh2 = 0; - //MEDCouplingUMesh* recvMesh = 0; - bool mesh1Here = true, mesh2Here = true; - if (isParallelMode()) - { -#ifdef HAVE_MPI - mesh1Here = _domain_selector->isMyDomain(inew1); - mesh2Here = _domain_selector->isMyDomain(inew2); - if ( !mesh1Here && mesh2Here ) - { - //send mesh2 to domain of mesh1 - _domain_selector->sendMesh(*faceMeshes[inew2], - _domain_selector->getProcessorID(inew1)); - } - else if ( mesh1Here && !mesh2Here ) - { - //receiving mesh2 from a distant domain - _domain_selector->recvMesh(mesh2,_domain_selector->getProcessorID(inew2)); - if ( faceMeshes[ inew2 ] ) - faceMeshes[ inew2 ]->decrRef(); - faceMeshes[ inew2 ] = mesh2; - } -#endif - } - if ( mesh1Here && !mesh1 ) mesh1 = faceMeshes[ inew1 ]; - if ( mesh2Here && !mesh2 ) mesh2 = faceMeshes[ inew2 ]; - - // find coincident faces - std::vector< int > faces1, faces2; - if ( mesh1 && mesh2 ) - { - const DataArrayDouble* coords2 = mesh2->getBarycenterAndOwner(); - const double* c2 = coords2->getConstPointer(); - const int dim = coords2->getNumberOfComponents(); - const int nbFaces2 = mesh2->getNumberOfCells(); - const int nbFaces1 = mesh1->getNumberOfCells(); - - for (int i2 = 0; i2 < nbFaces2; i2++) - { - std::vector<int> coincFaces; - bbTrees[inew1]->getElementsAroundPoint( c2+i2*dim, coincFaces ); - if (coincFaces.size()!=0) - { - int i1 = coincFaces[0]; - // if ( coincFaces.size() > 1 ) - // { - // i2nb = isource2nb.insert( std::make_pair( i1 , 0 )).first; - // i1 = coincFaces[ i2nb->second++ ]; - // } - if ( i1 < nbFaces1 ) // protection from invalid elements - { - faces1.push_back( i1 ); - faces2.push_back( i2 ); - } - } - } - coords2->decrRef(); - } - - if ( isParallelMode()) - { -#ifdef HAVE_MPI - if ( mesh1Here && !mesh2Here ) - { - //send faces2 to domain of recvMesh - SendIntVec(faces2, _domain_selector->getProcessorID(inew2)); - } - else if ( !mesh1Here && mesh2Here ) - { - //receiving ids of faces from a domain of mesh1 - RecvIntVec(faces2, _domain_selector->getProcessorID(inew1)); - } -#endif - } - // if ( recvMesh ) - // recvMesh->decrRef(); - - // Create group "JOINT_inew1_inew2_Faces" and corresponding families - for ( int is2nd = 0; is2nd < 2; ++is2nd ) - { - createJointGroup( is2nd ? faces2 : faces1, - inew1 , inew2, is2nd ); - } - - } // loop on the 2nd domains (inew2) - } // loop on the 1st domains (inew1) - - - // delete bounding box trees - for (int inew = 0; inew < nbMeshes-1; inew++) - if (isParallelMode() && _domain_selector->isMyDomain(inew)) - { - bbox[inew]->decrRef(); - delete bbTrees[inew]; - } -} - -//================================================================================ -/*! - * \brief Create group "JOINT_inew1_inew2_Faces" and corresponding families - * \param faces - face ids to include into the group - * \param inew1 - index of the 1st domain - * \param inew2 - index of the 2nd domain - * \param is2nd - in which (1st or 2nd) domain to create the group - */ -//================================================================================ - -void MEDPARTITIONER::MeshCollection::createJointGroup( const std::vector< int >& faces, - const int inew1, - const int inew2, - const bool is2nd ) -{ - // get the name of JOINT group - std::string groupName; - { - std::ostringstream oss; - oss << "JOINT_" - << (is2nd ? inew2 : inew1 ) << "_" - << (is2nd ? inew1 : inew2 ) << "_" - << ( getMeshDimension()==2 ? "Edge" : "Face" ); - groupName = oss.str(); - } - - // remove existing "JOINT_*" group - _group_info.erase( groupName ); - - // get family IDs array - int* famIDs = 0; - int inew = (is2nd ? inew2 : inew1 ); - int totalNbFaces = _face_mesh[ inew ] ? _face_mesh[ inew ]->getNumberOfCells() : 0; - std::string cle = Cle1ToStr( "faceFamily_toArray", inew ); - if ( !_map_dataarray_int.count(cle) ) - { - if ( totalNbFaces > 0 ) - { - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - p->alloc( totalNbFaces, 1 ); - p->fillWithZero(); - famIDs = p->getPointer(); - _map_dataarray_int[cle]=p; - } - } - else - { - famIDs = _map_dataarray_int.find(cle)->second->getPointer(); - } - // find a family ID of an existing JOINT group - int familyID = 0; - std::map<std::string, int>::iterator name2id = _family_info.find( groupName ); - if ( name2id != _family_info.end() ) - familyID = name2id->second; - - // remove faces from the familyID-the family - if ( familyID != 0 && famIDs ) - for ( int i = 0; i < totalNbFaces; ++i ) - if ( famIDs[i] == familyID ) - famIDs[i] = 0; - - if ( faces.empty() ) - return; - - if ( familyID == 0 ) // generate a family ID for JOINT group - { - std::set< int > familyIDs; - for ( name2id = _family_info.begin(); name2id != _family_info.end(); ++name2id ) - familyIDs.insert( name2id->second ); - // find the next free family ID - int freeIdCount = inew1 * getNbOfGlobalMeshes() + inew2 + is2nd; - do - { - if ( !familyIDs.count( ++familyID )) - --freeIdCount; - } - while ( freeIdCount > 0 ); - } - - // push faces to familyID-th group - if ( faces.back() >= totalNbFaces ) - throw INTERP_KERNEL::Exception("MeshCollection::createJointGroup(): to high face ID"); - for ( size_t i = 0; i < faces.size(); ++i ) - famIDs[ faces[i] ] = familyID; - - // register JOINT group and family - _family_info[ groupName ] = familyID; // name of the group and family is same - _group_info [ groupName ].push_back( groupName ); -} - -/*! constructing the MESH collection from a distributed file - * - * \param filename name of the master file containing the list of all the MED files - */ -MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename) - : _topology(0), - _owns_topology(true), - _driver(0), - _domain_selector( 0 ), - _i_non_empty_mesh(-1), - _driver_type(MEDPARTITIONER::Undefined), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ - try - { - _driver=new MeshCollectionMedXmlDriver(this); - _driver->read (filename.c_str()); - _driver_type = MedXml; - } - catch(...) - { // Handle all exceptions - if ( _driver ) delete _driver; _driver=0; - try - { - _driver=new MeshCollectionMedAsciiDriver(this); - _driver->read (filename.c_str()); - _driver_type=MedAscii; - } - catch(...) - { - delete _driver; - _driver=0; - throw INTERP_KERNEL::Exception("file does not comply with any recognized format"); - } - } - for ( int idomain = 0; idomain < (int)_mesh.size(); ++idomain ) - if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 ) - _i_non_empty_mesh = idomain; -} - -/*! Constructing the MESH collection from selected domains of a distributed file - * - * \param filename - name of the master file containing the list of all the MED files - * \param domainSelector - selector of domains to load - */ -MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, ParaDomainSelector& domainSelector) - : _topology(0), - _owns_topology(true), - _driver(0), - _domain_selector( &domainSelector ), - _i_non_empty_mesh(-1), - _driver_type(MEDPARTITIONER::Undefined), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ - std::string myfile=filename; - std::size_t found=myfile.find(".xml"); - if (found!=std::string::npos) //file .xml - { - try - { - _driver=new MeshCollectionMedXmlDriver(this); - _driver->read ( filename.c_str(), _domain_selector ); - _driver_type = MedXml; - } - catch(...) - { // Handle all exceptions - delete _driver; - throw INTERP_KERNEL::Exception("file .xml does not comply with any recognized format"); - } - } - else - { - found=myfile.find(".med"); - if (found!=std::string::npos) //file .med single - { - //make a temporary file .xml and retry MedXmlDriver - std::string xml="\ -<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \ -<root>\n \ - <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \ - <description what=\"\" when=\"\"/>\n \ - <content>\n \ - <mesh name=\"$meshName\"/>\n \ - </content>\n \ - <splitting>\n \ - <subdomain number=\"1\"/>\n \ - <global_numbering present=\"no\"/>\n \ - </splitting>\n \ - <files>\n \ - <subfile id=\"1\">\n \ - <name>$fileName</name>\n \ - <machine>localhost</machine>\n \ - </subfile>\n \ - </files>\n \ - <mapping>\n \ - <mesh name=\"$meshName\">\n \ - <chunk subdomain=\"1\">\n \ - <name>$meshName</name>\n \ - </chunk>\n \ - </mesh>\n \ - </mapping>\n \ -</root>\n"; - std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile); - xml.replace(xml.find("$fileName"),9,myfile); - xml.replace(xml.find("$meshName"),9,meshNames[0]); - xml.replace(xml.find("$meshName"),9,meshNames[0]); - xml.replace(xml.find("$meshName"),9,meshNames[0]); - std::string nameFileXml(myfile); - nameFileXml.replace(nameFileXml.find(".med"),4,".xml"); - std::string nameFileXmlDN,nameFileXmlBN; - MEDLoaderBase::getDirAndBaseName(nameFileXml,nameFileXmlDN,nameFileXmlBN); - nameFileXml=MEDLoaderBase::joinPath(nameFileXmlDN,"medpartitioner_"+nameFileXmlBN); - if (_domain_selector->rank()==0) //only on to write it - { - std::ofstream f(nameFileXml.c_str()); - f<<xml; - f.close(); - } -#ifdef HAVE_MPI - if (MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //wait for creation of nameFileXml -#endif - try - { - _driver=new MeshCollectionMedXmlDriver(this); - _driver->read ( nameFileXml.c_str(), _domain_selector ); - _driver_type = MedXml; - } - catch(...) - { // Handle all exceptions - delete _driver; _driver=0; - throw INTERP_KERNEL::Exception("file medpartitioner_xxx.xml does not comply with any recognized format"); - } - } - else //no extension - { - try - { - _driver=new MeshCollectionMedAsciiDriver(this); - _driver->read ( filename.c_str(), _domain_selector ); - _driver_type=MedAscii; - } - catch(...) - { - delete _driver; - _driver=0; - throw INTERP_KERNEL::Exception("file name with no extension does not comply with any recognized format"); - } - } - } - // find non-empty domain mesh - for ( int idomain = 0; idomain < (int)_mesh.size(); ++idomain ) - if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 ) - _i_non_empty_mesh = idomain; - - try - { - //check for all proc/file compatibility of _field_descriptions -#ifdef HAVE_MPI - _field_descriptions=AllgathervVectorOfString(MyGlobals::_Field_Descriptions); -#else - _field_descriptions=MyGlobals::_Field_Descriptions; -#endif - } - catch(INTERP_KERNEL::Exception& e) - { - std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; - throw INTERP_KERNEL::Exception("Something wrong verifying coherency of files med ands fields"); - } -#ifdef HAVE_MPI - try - { - //check for all proc/file compatibility of _family_info - std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringInt(_family_info)); - _family_info=DevectorizeToMapOfStringInt(v2); - } - catch(INTERP_KERNEL::Exception& e) - { - std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; - throw INTERP_KERNEL::Exception("Something wrong merging all familyInfo"); - } - - try - { - //check for all proc/file compatibility of _group_info - std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringVectorOfString(_group_info)); - _group_info=DeleteDuplicatesInMapOfStringVectorOfString(DevectorizeToMapOfStringVectorOfString(v2)); - } - catch(INTERP_KERNEL::Exception& e) - { - std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; - throw INTERP_KERNEL::Exception("Something wrong merging all groupInfo"); - } -#endif -} - -/*! constructing the MESH collection from a sequential MED-file - * - * \param filename MED file - * \param meshname name of the mesh that is to be read - */ -MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, const std::string& meshname) - : _topology(0), - _owns_topology(true), - _driver(0), - _domain_selector( 0 ), - _i_non_empty_mesh(-1), - _name(meshname), - _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ - try // avoid memory leak in case of inexistent filename - { - retrieveDriver()->readSeq (filename.c_str(),meshname.c_str()); - } - catch (...) - { - delete _driver; - _driver=0; - throw INTERP_KERNEL::Exception("problem reading .med files"); - } - if ( _mesh[0] && _mesh[0]->getNumberOfNodes() > 0 ) - _i_non_empty_mesh = 0; -} - -MEDPARTITIONER::MeshCollection::~MeshCollection() -{ - for (int i=0; i<(int)_mesh.size();i++) - if (_mesh[i]!=0) _mesh[i]->decrRef(); - - for (int i=0; i<(int)_cell_family_ids.size();i++) - if (_cell_family_ids[i]!=0) - _cell_family_ids[i]->decrRef(); - - for (int i=0; i<(int)_face_mesh.size();i++) - if (_face_mesh[i]!=0) - _face_mesh[i]->decrRef(); - - for (int i=0; i<(int)_face_family_ids.size();i++) - if (_face_family_ids[i]!=0) - _face_family_ids[i]->decrRef(); - - for (std::map<std::string, ParaMEDMEM::DataArrayInt*>::iterator it=_map_dataarray_int.begin() ; it!=_map_dataarray_int.end(); it++ ) - if ((*it).second!=0) - (*it).second->decrRef(); - - for (std::map<std::string, ParaMEDMEM::DataArrayDouble*>::iterator it=_map_dataarray_double.begin() ; it!=_map_dataarray_double.end(); it++ ) - if ((*it).second!=0) - (*it).second->decrRef(); - - delete _driver; - if (_topology!=0 && _owns_topology) - delete _topology; -#ifdef HAVE_MPI - delete _joint_finder; -#endif -} - -/*! constructing the MESH collection from a file - * - * The method creates as many MED-files as there are domains in the - * collection. It also creates a master file that lists all the MED files. - * The MED files created in ths manner contain joints that describe the - * connectivity between subdomains. - * - * \param filename name of the master file that will contain the list of the MED files - * - */ -void MEDPARTITIONER::MeshCollection::write(const std::string& filename) -{ - //suppresses link with driver so that it can be changed for writing - delete _driver; - _driver=0; - retrieveDriver()->write (filename.c_str(), _domain_selector); -} - -/*! creates or gets the link to the collection driver - */ -MEDPARTITIONER::MeshCollectionDriver* MEDPARTITIONER::MeshCollection::retrieveDriver() -{ - if (_driver==0) - { - switch(_driver_type) - { - case MedXml: - _driver=new MeshCollectionMedXmlDriver(this); - break; - case MedAscii: - _driver=new MeshCollectionMedAsciiDriver(this); - break; - default: - throw INTERP_KERNEL::Exception("Unrecognized driver"); - } - } - return _driver; -} - - -/*! gets an existing driver - * - */ -MEDPARTITIONER::MeshCollectionDriver* MEDPARTITIONER::MeshCollection::getDriver() const -{ - return _driver; -} - -/*! - * retrieves the mesh dimension -*/ -int MEDPARTITIONER::MeshCollection::getMeshDimension() const -{ - return _i_non_empty_mesh < 0 ? -1 : _mesh[_i_non_empty_mesh]->getMeshDimension(); -} - -int MEDPARTITIONER::MeshCollection::getNbOfLocalMeshes() const -{ - int nb=0; - for (size_t i=0; i<_mesh.size(); i++) - { - if (_mesh[i]) nb++; - } - return nb; -} - -int MEDPARTITIONER::MeshCollection::getNbOfLocalCells() const -{ - int nb=0; - for (size_t i=0; i<_mesh.size(); i++) - { - if (_mesh[i]) nb=nb+_mesh[i]->getNumberOfCells(); - } - return nb; -} - -int MEDPARTITIONER::MeshCollection::getNbOfLocalFaces() const -{ - int nb=0; - for (size_t i=0; i<_face_mesh.size(); i++) - { - if (_face_mesh[i]) nb=nb+_face_mesh[i]->getNumberOfCells(); - } - return nb; -} - -std::vector<ParaMEDMEM::MEDCouplingUMesh*>& MEDPARTITIONER::MeshCollection::getMesh() -{ - return _mesh; -} - -std::vector<ParaMEDMEM::MEDCouplingUMesh*>& MEDPARTITIONER::MeshCollection::getFaceMesh() -{ - return _face_mesh; -} - -ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getMesh(int idomain) const -{ - return _mesh[idomain]; -} - -ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getFaceMesh(int idomain) -{ - return _face_mesh[idomain]; -} - -std::vector<MEDPARTITIONER::ConnectZone*>& MEDPARTITIONER::MeshCollection::getCZ() -{ - if ( _topology ) - return _topology->getCZ(); - - static std::vector<MEDPARTITIONER::ConnectZone*> noCZ; - return noCZ; -} - -MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::getTopology() const -{ - return _topology; -} - -void MEDPARTITIONER::MeshCollection::setTopology(Topology* topo, bool takeOwneship) -{ - if (_topology!=0) - { - throw INTERP_KERNEL::Exception("topology is already set"); - } - else - { - _topology = topo; - _owns_topology = takeOwneship; - } -} - -/*! Method creating the cell graph in serial mode - * - * \param array returns the pointer to the structure that contains the graph - * \param edgeweight returns the pointer to the table that contains the edgeweights - * (only used if indivisible regions are required) - */ -void MEDPARTITIONER::MeshCollection::buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights ) -{ - - using std::map; - using std::vector; - using std::make_pair; - using std::pair; - - if (_topology->nbDomain()>1) throw INTERP_KERNEL::Exception("buildCellGraph should be used for one domain only"); - const ParaMEDMEM::MEDCouplingUMesh* mesh=_mesh[0]; - if (MyGlobals::_Verbose>50) - std::cout<<"getting nodal connectivity"<<std::endl; - - //looking for reverse nodal connectivity i global numbering - if (isParallelMode() && !_domain_selector->isMyDomain(0)) - { - vector<int> value; - vector<int> index(1,0); - - array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); - return; - } - array=mesh->generateGraph(); -} -/*! Method creating the cell graph in multidomain mode - * - * \param array returns the pointer to the structure that contains the graph - * \param edgeweight returns the pointer to the table that contains the edgeweights - * (only used if indivisible regions are required) - */ -void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights ) -{ - using std::multimap; - using std::vector; - using std::make_pair; - using std::pair; - - std::multimap< int, int > node2cell; - std::map< pair<int,int>, int > cell2cellcounter; - std::multimap<int,int> cell2cell; - - std::vector<std::vector<std::multimap<int,int> > > commonDistantNodes; - int nbdomain=_topology->nbDomain(); -#ifdef HAVE_MPI - if (isParallelMode()) - { - _joint_finder=new JointFinder(*this); - _joint_finder->findCommonDistantNodes(); - commonDistantNodes=_joint_finder->getDistantNodeCell(); - } - - if (MyGlobals::_Verbose>500) - _joint_finder->print(); -#endif - - if (MyGlobals::_Verbose>50) - std::cout<<"getting nodal connectivity"<<std::endl; - //looking for reverse nodal connectivity i global numbering - int meshDim = 3; - for (int idomain=0; idomain<nbdomain; idomain++) - { - if (isParallelMode() && !_domain_selector->isMyDomain(idomain)) - continue; - meshDim = _mesh[idomain]->getMeshDimension(); - - ParaMEDMEM::DataArrayInt* index=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); - int nbNodes=_mesh[idomain]->getNumberOfNodes(); - _mesh[idomain]->getReverseNodalConnectivity(revConn,index); - //problem saturation over 1 000 000 nodes for 1 proc - if (MyGlobals::_Verbose>100) - std::cout << "proc " << MyGlobals::_Rank << " : getReverseNodalConnectivity done on " << nbNodes << " nodes" << std::endl; - int* index_ptr=index->getPointer(); - int* revConnPtr=revConn->getPointer(); - for (int i=0; i<nbNodes; i++) - { - for (int icell=index_ptr[i]; icell<index_ptr[i+1]; icell++) - { - int globalNode=_topology->convertNodeToGlobal(idomain,i); - int globalCell=_topology->convertCellToGlobal(idomain,revConnPtr[icell]); - node2cell.insert(make_pair(globalNode, globalCell)); - } - } - revConn->decrRef(); - index->decrRef(); -#ifdef HAVE_MPI - for (int iother=0; iother<nbdomain; iother++) - { - std::multimap<int,int>::iterator it; - int isource=idomain; - int itarget=iother; - for (it=_joint_finder->getDistantNodeCell()[isource][itarget].begin(); - it!=_joint_finder->getDistantNodeCell()[isource][itarget].end(); it++) - { - int globalNode=_topology->convertNodeToGlobal(idomain,(*it).first); - int globalCell=(*it).second; - node2cell.insert(make_pair(globalNode, globalCell)); - } - } -#endif - } //endfor idomain - - //creating graph arcs (cell to cell relations) - //arcs are stored in terms of (index,value) notation - // 0 3 5 6 6 - // 1 2 3 2 3 3 - // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) - // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell - - //warning here one node have less than or equal effective number of cell with it - //but cell could have more than effective nodes - //because other equals nodes in other domain (with other global inode) - if (MyGlobals::_Verbose>50) - std::cout<< "proc " << MyGlobals::_Rank << " : creating graph arcs on nbNodes " << _topology->nbNodes() << std::endl; - - for (int inode=0;inode<_topology->nbNodes();inode++) - { - typedef multimap<int,int>::const_iterator MI; - std::pair <MI,MI> nodeRange=node2cell.equal_range(inode); - for (MI cell1=nodeRange.first;cell1!=nodeRange.second;cell1++) - for (MI cell2=nodeRange.first;cell2!=cell1;cell2++) - { - int icell1=cell1->second; - int icell2=cell2->second; - if (icell1>icell2) {int tmp=icell1; icell1=icell2; icell2=tmp;} - std::map<pair<int,int>,int>::iterator it=cell2cellcounter.find(make_pair(icell1,icell2)); - if (it==cell2cellcounter.end()) cell2cellcounter.insert(make_pair(make_pair(icell1,icell2),1)); - else (it->second)++; - } - } - // for (int icell1=0; icell1<_topology->nbCells(); icell1++) //on all nodes - // { - // typedef multimap<int,int>::const_iterator MI; - // std::pair <MI,MI> nodeRange=cell2node.equal_range(icell1); - // for (MI node1=nodeRange.first; node1!=nodeRange.second; node1++) //on nodes with icell - // { - // std::pair<MI,MI> cellRange=node2cell.equal_range(node1->second); - // for (MI cell2=cellRange.first; cell2!=cellRange.second; cell2++) //on one of these cell - // { - // int icell2=cell2->second; - // std::map<pair<int,int>,int>::iterator it=cell2cellcounter.find(make_pair(icell1,icell2)); - // if (it==cell2cellcounter.end()) cell2cellcounter.insert(make_pair(make_pair(icell1,icell2),1)); - // else (it->second)++; - // } - // } - // } - - - //converting the counter to a multimap structure - for (std::map<pair<int,int>,int>::const_iterator it=cell2cellcounter.begin(); - it!=cell2cellcounter.end(); - it++) - if (it->second>=meshDim) - { - cell2cell.insert(std::make_pair(it->first.first,it->first.second)); - cell2cell.insert(std::make_pair(it->first.second, it->first.first)); - } - - - if (MyGlobals::_Verbose>50) - std::cout << "proc " << MyGlobals::_Rank << " : create skylinearray" << std::endl; - //filling up index and value to create skylinearray structure - std::vector <int> index,value; - index.push_back(0); - int idep=0; - - for (int idomain=0; idomain<nbdomain; idomain++) - { - if (isParallelMode() && !_domain_selector->isMyDomain(idomain)) continue; - int nbCells=_mesh[idomain]->getNumberOfCells(); - for (int icell=0; icell<nbCells; icell++) - { - int size=0; - int globalCell=_topology->convertCellToGlobal(idomain,icell); - multimap<int,int>::iterator it; - pair<multimap<int,int>::iterator,multimap<int,int>::iterator> ret; - ret=cell2cell.equal_range(globalCell); - for (it=ret.first; it!=ret.second; ++it) - { - int ival=(*it).second; //no adding one existing yet - for (int i=idep ; i<idep+size ; i++) - { - if (value[i]==ival) - { - ival= -1; break; - } - } - if (ival!= -1) - { - value.push_back(ival); - size++; - } - } - idep=index[index.size()-1]+size; - index.push_back(idep); - } - } - - array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); - - if (MyGlobals::_Verbose>100) - { - std::cout << "\nproc " << _domain_selector->rank() << " : end MeshCollection::buildCellGraph " << - index.size()-1 << " " << value.size() << std::endl; - int max=index.size()>15?15:index.size(); - if (index.size()>1) - { - for (int i=0; i<max; ++i) - std::cout<<index[i]<<" "; - std::cout << "... " << index[index.size()-1] << std::endl; - for (int i=0; i<max; ++i) - std::cout<< value[i] << " "; - int ll=index[index.size()-1]-1; - std::cout << "... (" << ll << ") " << value[ll-1] << " " << value[ll] << std::endl; - } - } - -} - - -/*! Creates the partition corresponding to the cell graph and the partition number - * - * \param nbdomain number of subdomains for the newly created graph - * - * returns a topology based on the new graph - */ -MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nbdomain, - Graph::splitter_type split, - const std::string& options_string, - int *user_edge_weights, - int *user_vertices_weights) -{ - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : MeshCollection::createPartition : Building cell graph" << std::endl; - - if (nbdomain <1) - throw INTERP_KERNEL::Exception("Number of subdomains must be > 0"); - ParaMEDMEM::MEDCouplingSkyLineArray* array=0; - int* edgeweights=0; - - if (_topology->nbDomain()>1 || isParallelMode()) - buildParallelCellGraph(array,edgeweights); - else - buildCellGraph(array,edgeweights); - - Graph* cellGraph = 0; - switch (split) - { - case Graph::METIS: - if ( isParallelMode() && MyGlobals::_World_Size > 1 ) - { -#ifdef MED_ENABLE_PARMETIS - if (MyGlobals::_Verbose>10) - std::cout << "ParMETISGraph" << std::endl; - cellGraph=new ParMETISGraph(array,edgeweights); -#endif - } - if ( !cellGraph ) - { -#ifdef MED_ENABLE_METIS - if (MyGlobals::_Verbose>10) - std::cout << "METISGraph" << std::endl; - cellGraph=new METISGraph(array,edgeweights); -#endif - } - if ( !cellGraph ) - throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please."); - break; - - case Graph::SCOTCH: -#ifdef MED_ENABLE_SCOTCH - if (MyGlobals::_Verbose>10) - std::cout << "SCOTCHGraph" << std::endl; - cellGraph=new SCOTCHGraph(array,edgeweights); -#else - throw INTERP_KERNEL::Exception("MeshCollection::createPartition : SCOTCH is not available. Check your products, please."); -#endif - break; - } - - //!user-defined weights - if (user_edge_weights!=0) - cellGraph->setEdgesWeights(user_edge_weights); - if (user_vertices_weights!=0) - cellGraph->setVerticesWeights(user_vertices_weights); - - if (MyGlobals::_Is0verbose>10) - std::cout << "partitioning graph on " << nbdomain << " domains" << std::endl; - cellGraph->partGraph(nbdomain, options_string, _domain_selector); - - if (MyGlobals::_Is0verbose>10) - std::cout << "building new topology" << std::endl; - //cellGraph is a shared pointer - Topology *topology=0; - topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); - //cleaning - delete [] edgeweights; - delete cellGraph; - if (MyGlobals::_Verbose>11) - std::cout << "proc " << MyGlobals::_Rank << " : end MeshCollection::createPartition" << std::endl; - return topology; -} - -/*! Creates a topology for a partition specified by the user - * - * \param table user-specified partition (for each cell contains the domain number from 0 to n-1) - * - * returns a topology based on the new partition - */ -MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(const int* partition) -{ - ParaMEDMEM::MEDCouplingSkyLineArray* array=0; - int* edgeweights=0; - - if ( _topology->nbDomain()>1) - buildParallelCellGraph(array,edgeweights); - else - buildCellGraph(array,edgeweights); - - Graph* cellGraph; - std::set<int> domains; - for (int i=0; i<_topology->nbCells(); i++) - { - domains.insert(partition[i]); - } - cellGraph=new UserGraph(array, partition, _topology->nbCells()); - - //cellGraph is a shared pointer - Topology *topology=0; - int nbdomain=domains.size(); - topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); - // if (array!=0) delete array; - delete cellGraph; - return topology; -} - -void MEDPARTITIONER::MeshCollection::setDomainNames(const std::string& name) -{ - for (int i=0; i<_topology->nbDomain(); i++) - { - std::ostringstream oss; - oss<<name<<"_"<<i; - if (!isParallelMode() || _domain_selector->isMyDomain(i)) - _mesh[i]->setName(oss.str()); - } -} - -ParaMEDMEM::DataArrayDouble *MEDPARTITIONER::MeshCollection::getField(std::string descriptionField, int iold) -//getField look for and read it if not done, and assume decrRef() in ~MeshCollection; -//something like MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name,f1->getMesh()->getName(),0,f1->getName(),0,1); -{ - int rank=MyGlobals::_Rank; - std::string tag="ioldFieldDouble="+IntToStr(iold); - std::string descriptionIold=descriptionField+SerializeFromString(tag); - if (_map_dataarray_double.find(descriptionIold)!=_map_dataarray_double.end()) - { - if (MyGlobals::_Verbose>300) - std::cout << "proc " << rank << " : YET READ getField : " << descriptionIold << std::endl; - ParaMEDMEM::DataArrayDouble* res=_map_dataarray_double[descriptionIold]; - return res; - } - if (MyGlobals::_Verbose>200) - std::cout << "proc " << rank << " : TO BE READ getField : " << descriptionIold << std::endl; - std::string description, fileName, meshName, fieldName; - int typeField, DT, IT, entity; - fileName=MyGlobals::_File_Names[iold]; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : in " << fileName << " " << iold << " " << descriptionIold << std::endl; - FieldShortDescriptionToData(descriptionIold, fieldName, typeField, entity, DT, IT); - meshName=MyGlobals::_Mesh_Names[iold]; - - ParaMEDMEM::MEDCouplingFieldDouble* f2=MEDLoader::ReadField((ParaMEDMEM::TypeOfField) typeField, - fileName, meshName, 0, fieldName, DT, IT); - - ParaMEDMEM::DataArrayDouble* res=f2->getArray(); - //to know names of components - std::vector<std::string> browse=BrowseFieldDouble(f2); - std::string localFieldInformation=descriptionIold+SerializeFromVectorOfString(browse); - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : localFieldInformation : " << localFieldInformation << std::endl; - MyGlobals::_General_Informations.push_back(localFieldInformation); - res->incrRef(); - f2->decrRef(); - _map_dataarray_double[descriptionIold]=res; - return res; -} - -void MEDPARTITIONER::MeshCollection::prepareFieldDescriptions() -//to have unique valid fields names/pointers/descriptions for partitionning -//filter _field_descriptions to be in all procs compliant and equal -{ - int nbfiles=MyGlobals::_File_Names.size(); //nb domains - if (nbfiles==0) - { - nbfiles=_topology->nbDomain(); - } - std::vector<std::string> r2; - //from allgatherv then vector(procs) of serialised vector(fields) of vector(description) data - for (int i=0; i<(int)_field_descriptions.size(); i++) - { - std::vector<std::string> r1=DeserializeToVectorOfString(_field_descriptions[i]); - for (int ii=0; ii<(int)r1.size(); ii++) - r2.push_back(r1[ii]); - } - //here vector(procs*fields) of serialised vector(description) data - _field_descriptions=r2; - int nbfields=_field_descriptions.size(); //on all domains - if ((nbfields%nbfiles)!=0) - { - if (MyGlobals::_Rank==0) - { - std::cerr<< "\nERROR : incoherent number of fields references in all files .med\n" << std::endl - << "fileMedNames :" << std::endl - << ReprVectorOfString(MyGlobals::_File_Names) - << "field_descriptions :" << std::endl - << ReprVectorOfString(MyGlobals::_Field_Descriptions); - } - throw INTERP_KERNEL::Exception("incoherent number of fields references in all files .med\n"); - } - _field_descriptions.resize(nbfields/nbfiles); - for (int i=0; i<(int)_field_descriptions.size(); i++) - { - std::string str=_field_descriptions[i]; - str=EraseTagSerialized(str,"idomain="); - str=EraseTagSerialized(str,"fileName="); - _field_descriptions[i]=str; - } -} - -//returns true if inodes of a face are in inodes of a cell -bool isFaceOncell(std::vector< int >& inodesFace, std::vector< int >& inodesCell) -{ - int ires=0; - int nbok=inodesFace.size(); - for (int i=0; i<nbok; i++) - { - int ii=inodesFace[i]; - if (ii<0) - std::cout << "isFaceOncell problem inodeface<0" << std::endl; - for (int j=0; j<(int)inodesCell.size(); j++) - { - if (ii==inodesCell[j]) - { - ires=ires+1; - break; //inode of face found - } - } - if (ires<i+1) - break; //inode of face not found do not continue... - } - return (ires==nbok); -} - -void MEDPARTITIONER::MeshCollection::filterFaceOnCell() -{ - for (int inew=0; inew<_topology->nbDomain(); inew++) - { - if (!isParallelMode() || _domain_selector->isMyDomain(inew)) - { - if (MyGlobals::_Verbose>200) - std::cout << "proc " << MyGlobals::_Rank << " : filterFaceOnCell on inewDomain " << inew << " nbOfFaces " << _face_mesh[inew]->getNumberOfCells() << std::endl; - ParaMEDMEM::MEDCouplingUMesh* mcel=_mesh[inew]; - ParaMEDMEM::MEDCouplingUMesh* mfac=_face_mesh[inew]; - - //to have cellnode=f(facenode)... inodeCell=nodeIds[inodeFace] - std::vector<int> nodeIds; - getNodeIds(*mcel, *mfac, nodeIds); - if (nodeIds.size()==0) - continue; //one empty mesh nothing to do - - ParaMEDMEM::DataArrayInt *revNodalCel=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt *revNodalIndxCel=ParaMEDMEM::DataArrayInt::New(); - mcel->getReverseNodalConnectivity(revNodalCel,revNodalIndxCel); - int *revC=revNodalCel->getPointer(); - int *revIndxC=revNodalIndxCel->getPointer(); - - std::vector< int > faceOnCell; - std::vector< int > faceNotOnCell; - int nbface=mfac->getNumberOfCells(); - for (int iface=0; iface<nbface; iface++) - { - bool ok; - std::vector< int > inodesFace; - mfac->getNodeIdsOfCell(iface, inodesFace); - int nbnodFace=inodesFace.size(); - if ( nbnodFace != mfac->getNumberOfNodesInCell( iface )) - continue; // invalid node ids - //set inodesFace in mcel - int nbok = 0; - for (int i=0; i<nbnodFace; i++) - nbok += (( inodesFace[i]=nodeIds[inodesFace[i]] ) >= 0 ); - if ( nbok != nbnodFace ) - continue; - int inod=inodesFace[0]; - if (inod<0) - { - std::cout << "filterFaceOnCell problem 1" << std::endl; - continue; - } - int nbcell=revIndxC[inod+1]-revIndxC[inod]; - for (int j=0; j<nbcell; j++) //look for each cell with inod - { - int icel=revC[revIndxC[inod]+j]; - std::vector< int > inodesCell; - mcel->getNodeIdsOfCell(icel, inodesCell); - ok=isFaceOncell(inodesFace, inodesCell); - if (ok) break; - } - if (ok) - { - faceOnCell.push_back(iface); - } - else - { - faceNotOnCell.push_back(iface); - if (MyGlobals::_Is0verbose>300) - std::cout << "face NOT on cell " << iface << " " << faceOnCell.size()-1 << std::endl; - } - } - - revNodalCel->decrRef(); - revNodalIndxCel->decrRef(); - - // std::string keyy; - // keyy=Cle1ToStr("filterFaceOnCell",inew); - // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell); - // keyy=Cle1ToStr("filterNotFaceOnCell",inew); - // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell); - - // filter the face mesh - if ( faceOnCell.empty() ) - _face_mesh[inew] = CreateEmptyMEDCouplingUMesh(); - else - _face_mesh[inew] = (ParaMEDMEM::MEDCouplingUMesh *) - mfac->buildPartOfMySelf( &faceOnCell[0], &faceOnCell[0] + faceOnCell.size(),true); - mfac->decrRef(); - - // filter the face families - std::string key = Cle1ToStr("faceFamily_toArray",inew); - if ( getMapDataArrayInt().count( key )) - { - ParaMEDMEM::DataArrayInt * & fam = getMapDataArrayInt()[ key ]; - ParaMEDMEM::DataArrayInt * famFilter = ParaMEDMEM::DataArrayInt::New(); - famFilter->alloc(faceOnCell.size(),1); - int* pfamFilter = famFilter->getPointer(); - int* pfam = fam->getPointer(); - for ( size_t i=0; i<faceOnCell.size(); i++ ) - pfamFilter[i]=pfam[faceOnCell[i]]; - fam->decrRef(); - fam = famFilter; - } - } - } -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx deleted file mode 100644 index 7f7ad1316..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTION_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTION_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include <map> -#include <vector> -#include <string> - -#include "BBTree.txx" - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class DataArrayInt; - class MEDCouplingSkyLineArray; -} - -namespace MEDPARTITIONER -{ - class Topology; - class MeshCollectionDriver; - class ParaDomainSelector; - class ConnectZone; - class JointFinder; - - typedef enum{MedAscii, MedXml, Undefined} DriverType; - typedef std::multimap<std::pair<int,int>, std::pair<int,int> > NodeMapping ; - typedef std::vector<std::pair<int,int> > NodeList; - - class MEDPARTITIONER_EXPORT MeshCollection - { - public: - MeshCollection(); - //Constructing from an existing mesh and a new topology - MeshCollection(MeshCollection&, Topology*, bool family_splitting=false, bool create_empty_groups=false); - //Constructing the mesh collection from a file - MeshCollection(const std::string& filename); - //Constructing the mesh collection from a file - MeshCollection(const std::string& filename, ParaDomainSelector& domainSelector); - //Constructing the mesh collection from a file - MeshCollection(const std::string& filename, const std::string& meshname); - ~MeshCollection(); - bool isParallelMode() const { return _domain_selector; } - - //writing to a distributed file - void write(const std::string& filename); - - //getting the driver - MeshCollectionDriver *retrieveDriver(); - MeshCollectionDriver *getDriver() const; - void setDriverType(MEDPARTITIONER::DriverType type) { _driver_type=type; } - - //creation of the cell graph - void buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights ); - //creation of the cell graph - void buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights ); - - //creation and partition of the associated graph - Topology* createPartition(int nbdomain, Graph::splitter_type type = Graph::METIS, - const std::string& ="", int* edgeweights=0, int* verticesweights=0); - - //creation of a user specified partition - Topology* createPartition(const int* partition); - - //getting mesh dimension - int getMeshDimension() const; - int getNbOfLocalMeshes() const; - int getNbOfGlobalMeshes() const { return _mesh.size(); } - int getNbOfLocalCells() const; - int getNbOfLocalFaces() const; - - //getting a reference to mesh vector - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getMesh(); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getFaceMesh(); - std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> >& getGroupMeshes(); - - ParaMEDMEM::MEDCouplingUMesh* getMesh(int idomain) const; - ParaMEDMEM::MEDCouplingUMesh* getFaceMesh(int idomain); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getGroupMeshes(int idomain); - - std::vector<ParaMEDMEM::DataArrayInt*>& getCellFamilyIds() { return _cell_family_ids; } - std::vector<ParaMEDMEM::DataArrayInt*>& getFaceFamilyIds() { return _face_family_ids; } - - std::map<std::string, ParaMEDMEM::DataArrayInt*>& getMapDataArrayInt() { return _map_dataarray_int; } - std::map<std::string, ParaMEDMEM::DataArrayDouble*>& getMapDataArrayDouble() { return _map_dataarray_double; } - - std::map<std::string,int>& getFamilyInfo() { return _family_info; } - std::map<std::string, std::vector<std::string> >& getGroupInfo() { return _group_info; } - - ParaMEDMEM::DataArrayDouble* getField(std::string descriptionField, int iold); - std::vector<std::string>& getFieldDescriptions() { return _field_descriptions; } - void prepareFieldDescriptions(); - void filterFaceOnCell(); - - //getting a reference to connect zones vector - std::vector<MEDPARTITIONER::ConnectZone*>& getCZ(); - - //getting a pointer to topology - Topology* getTopology() const ; - ParaDomainSelector* getParaDomainSelector() const { return _domain_selector; } - void setParaDomainSelector(ParaDomainSelector* pds) { _domain_selector = pds; } - //setting a new topology - void setTopology(Topology* topology, bool takeOwneship); - - //getting/setting the name of the global mesh (as opposed - //to the name of a subdomain \a nn, which is name_nn) - std::string getName() const { return _name; } - void setName(const std::string& name) { _name=name; } - void setDomainNames(const std::string& name); - - void setNonEmptyMesh(int number) { _i_non_empty_mesh=number;} - - //getting/setting the description of the global mesh - std::string getDescription() const { return _description; } - void setDescription(const std::string& name) { _description=name; } - - //creates the node mapping between an old collection and the present one - void createNodeMapping(MeshCollection& initialCollection, - std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping); - - void castCellMeshes(MeshCollection& initialCollection, - std::vector<std::vector<std::vector<int> > >& new2oldIds, - std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber); - - //creates faces on the new collection - void castFaceMeshes(MeshCollection& initialCollection, - const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping, - std::vector<std::vector<std::vector<int> > >& new2oldIds); - - //constructing connect zones - void buildConnectZones( const NodeMapping& nodeMapping, - const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber, - int nbInitialDomains ); - - // Find faces common with neighbor domains and put them in groups - void buildBoundaryFaces(); - - private: - void castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom, - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, - std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom, - std::string nameArrayTo); - - void castAllFields(MeshCollection& initialCollection, - std::string nameArrayTo); - - void findCommonDistantNodes(std::vector<std::vector<std::multimap<int,int> > >& commonDistantNodes); - - - void remapIntField(int inew, int iold, - const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, - const ParaMEDMEM::MEDCouplingUMesh& targetMesh, - const int* fromArray, - std::string nameArrayTo, - const BBTreeOfDim* tree); - - void remapDoubleField(int inew, int iold, - ParaMEDMEM::DataArrayDouble* fromArray, - std::string nameArrayTo, - std::string descriptionField); - - void createJointGroup( const std::vector< int >& faces, - const int inew1, - const int inew2, - const bool is2nd ); - private: - - //link to mesh_collection topology - Topology* _topology; - - //control over topology - bool _owns_topology; - - //Driver for read/write operations - MeshCollectionDriver* _driver; - - //Parallelizer - mark of parallel execution mode - ParaDomainSelector* _domain_selector; - - //links to meshes - std::vector<ParaMEDMEM::MEDCouplingUMesh*> _mesh; - std::vector<ParaMEDMEM::MEDCouplingUMesh*> _face_mesh; - - //index of a non empty mesh within _mesh (in parallel mode all of meshes can be empty) - int _i_non_empty_mesh; - - //family ids storages - std::vector<ParaMEDMEM::DataArrayInt*> _cell_family_ids; - std::vector<ParaMEDMEM::DataArrayInt*> _face_family_ids; - - //DataArrayInt* storages - std::map<std::string, ParaMEDMEM::DataArrayInt*> _map_dataarray_int; - //DataArrayDouble* storages - std::map<std::string, ParaMEDMEM::DataArrayDouble*> _map_dataarray_double; - - //fields to be partitioned - std::vector<std::string> _field_descriptions; - - //group family conversion - std::map<std::string, int> _family_info; - std::map<std::string, std::vector<std::string> > _group_info; - - //list of groups that are not to be splitted - std::vector<std::string> _indivisible_regions; - - //name of global mesh - std::string _name; - - //description of global mesh - std::string _description; - - //specifies the driver associated to the collection - DriverType _driver_type; - - //flag specifying that the splitter should create boundary constituent entity - //so that they are written in joints - bool _subdomain_boundary_creates; - - //flag specifying that families must be preserved by the splitting - bool _family_splitting; - - //flag specifying that groups must be created on all domains, even if they are empty - bool _create_empty_groups; - - JointFinder* _joint_finder; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx deleted file mode 100644 index 68f12e7a5..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx +++ /dev/null @@ -1,462 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -#include "MEDPARTITIONER_ConnectZone.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDFileData.hxx" -#include "MEDFileField.hxx" -#include "MEDFileJoint.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoader.hxx" - -#include <map> -#include <set> -#include <vector> -#include <string> -#include <fstream> -#include <iostream> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -#include "med.h" - -using namespace MEDPARTITIONER; - -MeshCollectionDriver::MeshCollectionDriver(MeshCollection* collection):_collection(collection) -{ -} - -/*!reads a unique MED File v>=2.1 - * and mounts the corresponding mesh in memory - *\param filename binary file - *\param meshname mesh name in the MED file - * */ -int MeshCollectionDriver::readSeq(const char* filename, const char* meshname) -{ - std::cout << "readSeq" << std::endl; - MyGlobals::_File_Names.resize(1); - MyGlobals::_File_Names[0]=std::string(filename); - - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(filename,meshname); - //puts the only mesh in the mesh vector - (_collection->getMesh()).push_back(mfm->getLevel0Mesh(false)); - (_collection->getFaceMesh()).push_back(mfm->getLevelM1Mesh(false)); - - //reading family ids - ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy()); - ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy()); - (_collection->getCellFamilyIds()).push_back(cellIds); - (_collection->getFaceFamilyIds()).push_back(faceIds); - - //reading groups - (_collection->getFamilyInfo())=mfm->getFamilyInfo(); - (_collection->getGroupInfo())=mfm->getGroupInfo(); - - (_collection->getCZ()).clear(); - - ParallelTopology* aPT = new ParallelTopology((_collection->getMesh())); - _collection->setTopology(aPT, true); - _collection->setName(meshname); - _collection->setDomainNames(meshname); - return 0; -} - - -void MeshCollectionDriver::readMEDFileData(const ParaMEDMEM::MEDFileData* filedata) -{ - const int nbDomains = filedata->getMeshes()->getNumberOfMeshes(); - _collection->getMesh() .resize( nbDomains, 0 ); - _collection->getFaceMesh() .resize( nbDomains, 0 ); - _collection->getCellFamilyIds().resize( nbDomains, 0 ); - _collection->getFaceFamilyIds().resize( nbDomains, 0 ); - - for (int i=0; i<nbDomains; i++) - { - ParaMEDMEM::MEDFileUMesh *mfm = dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(filedata->getMeshes()->getMeshAtPos(i)); - readData(mfm,i); - if ( mfm && mfm->getMeshDimension() > 0 ) - _collection->setNonEmptyMesh( i ); - } - - ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); - _collection->setTopology(aPT, true); - if ( nbDomains > 0 ) - { - _collection->setName( filedata->getMeshes()->getMeshAtPos(0)->getName() ); - _collection->setDomainNames( _collection->getName() ); - } - if ( ParaDomainSelector* domainSelector = _collection->getParaDomainSelector() ) - if ( _collection->isParallelMode() ) - { - //to know nb of cells on each proc to compute global cell ids from locally global - domainSelector->gatherNbOf(_collection->getMesh()); - } -} - -void MeshCollectionDriver::readFileData(std::string file,std::string meshname,int idomain) const -{ - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(file,meshname); - readData(mfm,idomain); - mfm->decrRef(); -} - -void MeshCollectionDriver::readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const -{ - std::vector<int> nonEmpty=mfm->getNonEmptyLevels(); - try - { - (_collection->getMesh())[idomain]=mfm->getLevel0Mesh(false); - //reading families groups - ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy()); - (_collection->getCellFamilyIds())[idomain]=cellIds; - } - catch(...) - { - (_collection->getMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want tests; - ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New(); - empty->alloc(0,1); - (_collection->getCellFamilyIds())[idomain]=empty; - std::cout<<"\nNO Level0Mesh (Cells)\n"; - } - try - { - if (nonEmpty.size()>1 && nonEmpty[1]==-1) - { - (_collection->getFaceMesh())[idomain]=mfm->getLevelM1Mesh(false); - //reading families groups - ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy()); - (_collection->getFaceFamilyIds())[idomain]=faceIds; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : WITH Faces\n"; - } - else - { - throw INTERP_KERNEL::Exception("no faces"); - } - } - catch(...) - { - (_collection->getFaceMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want test; - ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New(); - (_collection->getFaceFamilyIds())[idomain]=empty; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : WITHOUT Faces\n"; - } - //reading groups - _collection->getFamilyInfo()=mfm->getFamilyInfo(); - _collection->getGroupInfo()=mfm->getGroupInfo(); -} - -void MeshCollectionDriver::readSubdomain(int idomain) -{ - std::string meshname=MyGlobals::_Mesh_Names[idomain]; - std::string file=MyGlobals::_File_Names[idomain]; - readFileData(file,meshname,idomain); - - std::vector<std::string> localInformation; - std::string str; - localInformation.push_back(str+"ioldDomain="+IntToStr(idomain)); - localInformation.push_back(str+"meshName="+meshname); - MyGlobals::_General_Informations.push_back(SerializeFromVectorOfString(localInformation)); - std::vector<std::string> localFields=BrowseAllFieldsOnMesh(file, meshname, idomain); - if (localFields.size()>0) - MyGlobals::_Field_Descriptions.push_back(SerializeFromVectorOfString(localFields)); -} - -ParaMEDMEM::MEDFileMesh* MeshCollectionDriver::getMesh(int idomain) const -{ - ParaMEDMEM::MEDFileUMesh* mfm = ParaMEDMEM::MEDFileUMesh::New(); - - ParaMEDMEM::MEDCouplingUMesh* cellMesh=_collection->getMesh(idomain); - ParaMEDMEM::MEDCouplingUMesh* faceMesh=_collection->getFaceMesh(idomain); - // std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain); - // ParaMEDMEM::DataArrayInt* filter=0; - // if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end()) - // { - // filter=_collection->getMapDataArrayInt().find(cleFilter)->second; - // int* index=filter->getPointer(); - // faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true); - // faceMesh=faceMeshFilter; - // } - // if (faceMeshFilter!=0) - // faceMeshFilter->decrRef(); - std::string finalMeshName=""; - if (MyGlobals::_General_Informations.size()!=0) - { - std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName="); - if ((found!=std::string::npos) && (found>0)) - { - finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); - } - } - if (finalMeshName.empty()) - { - finalMeshName=_collection->getName(); - } - cellMesh->setName(finalMeshName); - mfm->setMeshAtLevel( 0, cellMesh ); - - faceMesh->checkCoherency(); - if (faceMesh->getNumberOfCells()>0) - { - faceMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-10); - faceMesh->setName(finalMeshName); - mfm->setMeshAtLevel( -1, faceMesh ); - } - - // ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0; - // if (MyGlobals::_Creates_Boundary_Faces>0) - // { - // //try to write Boundary meshes - // bool keepCoords=false; //TODO or true - // boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords); - // boundaryMesh->setName("boundaryMesh"); - // if (boundaryMesh!=0) - // { - // //doing that testMesh becomes second mesh sorted by alphabetical order of name - // MEDLoader::WriteUMesh(distfilename, boundaryMesh, false); - // boundaryMesh->decrRef(); - // } - - mfm->setFamilyInfo(_collection->getFamilyInfo()); - mfm->setGroupInfo(_collection->getGroupInfo()); - std::string key=Cle1ToStr("faceFamily_toArray",idomain); - if ( faceMesh->getNumberOfCells()>0 && _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) - mfm->setFamilyFieldArr(-1,_collection->getMapDataArrayInt().find(key)->second); - key=Cle1ToStr("cellFamily_toArray",idomain); - if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) - mfm->setFamilyFieldArr(0,_collection->getMapDataArrayInt().find(key)->second); - - // add joints - - using ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr; - using ParaMEDMEM::MEDCouplingSkyLineArray; - using ParaMEDMEM::MEDFileJoint; - using ParaMEDMEM::MEDFileJointCorrespondence; - using ParaMEDMEM::MEDFileJointOneStep; - using ParaMEDMEM::MEDFileJoints; - using ParaMEDMEM::MEDFileJoints; - - if ( _collection->getCZ().size() > 0 ) - { - MEDCouplingAutoRefCountObjectPtr< MEDFileJoints > joints = MEDFileJoints::New(); - - for ( size_t i = 0; i < _collection->getCZ().size(); ++i ) - { - ConnectZone* cz = _collection->getCZ()[i]; - if ( !cz || - cz->getLocalDomainNumber() != idomain ) - continue; - { - std::ostringstream oss; - oss << "joint_" << cz->getDistantDomainNumber(); - cz->setName( oss.str() ); - } - { - std::ostringstream oss; - oss << "connect_zone_" << i; - cz->setDescription( oss.str() ); - } - - MEDCouplingAutoRefCountObjectPtr< MEDFileJoint> - joint = MEDFileJoint::New( cz->getName(), finalMeshName, - finalMeshName, cz->getDistantDomainNumber() ); - joint->setDescription( cz->getDescription() ); - joints->pushJoint( joint ); - - MEDCouplingAutoRefCountObjectPtr< MEDFileJointOneStep> j1st = MEDFileJointOneStep::New(); - joint->pushStep( j1st ); - - const MEDCouplingSkyLineArray * nodeCorr = cz->getNodeCorresp(); - if ( nodeCorr ) - { - MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence > - corr = MEDFileJointCorrespondence::New( nodeCorr->getValueArray() ); - j1st->pushCorrespondence( corr ); - } - - std::vector< std::pair< int,int > > types = cz->getEntities(); - INTERP_KERNEL::NormalizedCellType t1, t2; - for ( size_t it = 0; it < types.size(); ++it ) - { - const MEDCouplingSkyLineArray * cellCorr = - cz->getEntityCorresp( types[it].first, types[it].second ); - if ( cellCorr && cellCorr->getNumberOf() > 0 ) - { - t1 = INTERP_KERNEL::NormalizedCellType( types[it].first ); - t2 = INTERP_KERNEL::NormalizedCellType( types[it].second ); - MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence> - corr = MEDFileJointCorrespondence::New( cellCorr->getValueArray(), t1, t2 ); - j1st->pushCorrespondence( corr ); - } - } - } - mfm->setJoints( joints ); - } - - return mfm; -} - -ParaMEDMEM::MEDCouplingFieldDouble* MeshCollectionDriver::getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const -{ - std::string desc=description; - if (MyGlobals::_Verbose>20) - std::cout << "proc " << MyGlobals::_Rank << " : write field " << desc << std::endl; - std::string meshName, fieldName; - int typeField, DT, IT, entity; - FieldShortDescriptionToData(desc, fieldName, typeField, entity, DT, IT); - double time=StrToDouble(ExtractFromDescription(desc, "time=")); - int typeData=StrToInt(ExtractFromDescription(desc, "typeData=")); - std::string entityName=ExtractFromDescription(desc, "entityName="); - ParaMEDMEM::MEDCouplingFieldDouble* field=0; - if (typeData!=6) - { - std::cout << "WARNING : writeMedFile : typeData " << typeData << " not implemented for fields\n"; - } - if (entityName=="MED_CELL") - { - //there is a field of idomain to write - field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - } - if (entityName=="MED_NODE_ELEMENT") - { - //there is a field of idomain to write - field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_GAUSS_NE,ParaMEDMEM::ONE_TIME); - } - if (!field) - { - std::cout << "WARNING : writeMedFile : entityName " << entityName << " not implemented for fields\n"; - } - if (field && typeData==6) - { - field->setName(fieldName); - field->setMesh(mfm->getGenMeshAtLevel(0)); - ParaMEDMEM::DataArrayDouble *da=data; - //get information for components etc.. - std::vector<std::string> r1; - r1=SelectTagsInVectorOfString(MyGlobals::_General_Informations,"fieldName="+fieldName); - r1=SelectTagsInVectorOfString(r1,"typeField="+IntToStr(typeField)); - r1=SelectTagsInVectorOfString(r1,"DT="+IntToStr(DT)); - r1=SelectTagsInVectorOfString(r1,"IT="+IntToStr(IT)); - //not saved in file? field->setDescription(ExtractFromDescription(r1[0], "fieldDescription=")); - int nbc=StrToInt(ExtractFromDescription(r1[0], "nbComponents=")); - if (nbc==da->getNumberOfComponents()) - { - for (int i=0; i<nbc; i++) - da->setInfoOnComponent(i,ExtractFromDescription(r1[0], "componentInfo"+IntToStr(i)+"=")); - } - else - { - std::cerr << "Problem On field " << fieldName << " : number of components unexpected " << da->getNumberOfComponents() << std::endl; - } - field->setArray(da); - field->setTime(time,DT,IT); - field->checkCoherency(); - } - return field; -} - -void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfilename) const -{ - ParaMEDMEM::MEDFileMesh* mfm = getMesh( idomain ); - mfm->write(distfilename,2); - - std::string key="/inewFieldDouble="+IntToStr(idomain)+"/"; - std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it; - int nbfFieldFound=0; - for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) - { - size_t found=(*it).first.find(key); - if (found==std::string::npos) - continue; - ParaMEDMEM::MEDCouplingFieldDouble* field=0; - field = getField(key, (*it).first, (*it).second, mfm, idomain); - nbfFieldFound++; - try - { - MEDLoader::WriteField(distfilename,field,false); - } - catch(INTERP_KERNEL::Exception& e) - { - //cout trying rewrite all data, only one field defined - std::string tmp,newName=distfilename; - std::string fieldName; - fieldName=field->getName(); - tmp+="_"+fieldName+"_"+IntToStr(nbfFieldFound)+".med"; - newName.replace(newName.find(".med"),4,tmp); - std::cout << "WARNING : writeMedFile : create a new file name with only one field because MEDLoader::WriteField throw:" << newName << std::endl; - MEDLoader::WriteField(newName,field,true); - } - } - mfm->decrRef(); -} - -ParaMEDMEM::MEDFileData* MeshCollectionDriver::getMEDFileData() -{ - ParaMEDMEM::MEDFileData* newdata = ParaMEDMEM::MEDFileData::New(); - - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileMeshes> meshes; - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileFields> fields; - meshes = ParaMEDMEM::MEDFileMeshes::New(); - fields = ParaMEDMEM::MEDFileFields::New(); - - for (size_t i=0; i<_collection->getMesh().size(); i++) - { - ParaMEDMEM::MEDFileMesh* mfm = getMesh( i ); - meshes->pushMesh(mfm); - - std::string key="/inewFieldDouble="+IntToStr(i)+"/"; - std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it; - ParaMEDMEM::MEDFileFieldMultiTS* fieldsMTS = ParaMEDMEM::MEDFileFieldMultiTS::New(); - for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) - { - size_t found=(*it).first.find(key); - if (found==std::string::npos) - continue; - ParaMEDMEM::MEDCouplingFieldDouble* field=0; - field=getField(key, (*it).first, (*it).second, mfm, i); - ParaMEDMEM::MEDFileField1TS* f1ts = ParaMEDMEM::MEDFileField1TS::New(); - f1ts->setFieldNoProfileSBT(field); - fieldsMTS->pushBackTimeStep(f1ts); - - field->decrRef(); - f1ts->decrRef(); - } - fields->pushField(fieldsMTS); - - fieldsMTS->decrRef(); - mfm->decrRef(); - } - newdata->setMeshes(meshes); - newdata->setFields(fields); - return newdata; -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx deleted file mode 100644 index c378a3408..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <vector> -#include <string> - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingFieldDouble; - class MEDFileData; - class MEDFileMesh; - class MEDFileUMesh; -} - -namespace MEDPARTITIONER -{ - class MeshCollection; - class ParaDomainSelector; - - class MEDPARTITIONER_EXPORT MeshCollectionDriver - { - public: - MeshCollectionDriver(MeshCollection*); - virtual ~MeshCollectionDriver() { } - virtual int read(const char*, ParaDomainSelector* sel=0) = 0; - int readSeq(const char*,const char*); - ParaMEDMEM::MEDFileData *getMEDFileData(); - virtual void write(const char*, ParaDomainSelector* sel=0) const = 0; - void readMEDFileData(const ParaMEDMEM::MEDFileData* filedata); - protected: - void readSubdomain(int idomain); - void readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const; - void readFileData(std::string file,std::string meshname,int idomain) const; - ParaMEDMEM::MEDFileMesh* getMesh(int idomain) const; - ParaMEDMEM::MEDCouplingFieldDouble* getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const; - void writeMedFile(int idomain, const std::string& distfilename) const; - protected: - MeshCollection* _collection; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx deleted file mode 100644 index 4eb8360cb..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDLoader.hxx" - -#include <map> -#include <set> -#include <vector> -#include <string> -#include <fstream> -#include <iostream> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -using namespace MEDPARTITIONER; - -MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* collection):MeshCollectionDriver(collection) -{ -} - -/*!reads a MED File v>=2.3 - * and mounts the corresponding meshes in memory - * the connect zones are created from the joints - * - *\param filename ascii file containing the list of MED v2.3 files - * */ - -int MeshCollectionMedAsciiDriver::read(ParaMEDMEM::MEDFileData* filedata) -{ - readMEDFileData(filedata); - - std::vector<MEDPARTITIONER::ConnectZone*> cz; // to fill from filedata - std::vector<int*> cellglobal; - std::vector<int*> nodeglobal; - std::vector<int*> faceglobal; - int size = (_collection->getMesh()).size(); - cellglobal.resize(size); - nodeglobal.resize(size); - faceglobal.resize(size); - for ( int idomain = 0; idomain < size; ++idomain ) - { - cellglobal[idomain]=0; - faceglobal[idomain]=0; - nodeglobal[idomain]=0; - if ( (_collection->getMesh())[idomain] && (_collection->getMesh())[idomain]->getNumberOfNodes() > 0 ) - _collection->setNonEmptyMesh(idomain); - } - //creation of topology from mesh and connect zones - ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), cz, cellglobal, nodeglobal, faceglobal); - _collection->setTopology(aPT,true); - - return 0; -} - -/*!reads a MED File v>=2.3 - * and mounts the corresponding meshes in memory - * the connect zones are created from the joints - * - *\param filename ascii file containing the list of MED v2.3 files - * */ - -int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector) -{ - //distributed meshes - std::vector<int*> cellglobal; - std::vector<int*> nodeglobal; - std::vector<int*> faceglobal; - int nbdomain; - - //reading ascii master file - try - { - std::ifstream asciiinput(filename); - if (!asciiinput) - throw INTERP_KERNEL::Exception("Master ASCII File does not exist"); - char charbuffer[512]; - asciiinput.getline(charbuffer,512); - - while (charbuffer[0]=='#') - { - asciiinput.getline(charbuffer,512); - } - - //reading number of domains - nbdomain=atoi(charbuffer); - MyGlobals::_File_Names.resize(nbdomain); - MyGlobals::_Mesh_Names.resize(nbdomain); - (_collection->getMesh()).resize(nbdomain); - cellglobal.resize(nbdomain); - nodeglobal.resize(nbdomain); - faceglobal.resize(nbdomain); - - if (nbdomain == 0) - throw INTERP_KERNEL::Exception("Empty ASCII master file"); - for (int i=0; i<nbdomain;i++) - { - //reading information about the domain - std::string mesh,host; - int idomain; - cellglobal[i]=0; - faceglobal[i]=0; - nodeglobal[i]=0; - - asciiinput >> mesh >> idomain >> MyGlobals::_Mesh_Names[i] >> host >> MyGlobals::_File_Names[i]; - - //Setting the name of the global mesh (which should be is the same for all the subdomains) - if (i==0) - _collection->setName(mesh); - - if (idomain!=i+1) - { - throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor"); - } - if ( !domainSelector || domainSelector->isMyDomain(i)) - readSubdomain(i); - - } //loop on domains - } //of try - catch(...) - { - throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); - } - - //creation of topology from mesh and connect zones - ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal); - _collection->setTopology(aPT, true); - - for (int i=0; i<nbdomain; i++) - { - delete [] cellglobal[i]; - delete [] nodeglobal[i]; - delete [] faceglobal[i]; - } - return 0; -} - -/*! writes the collection of meshes in a MED v2.3 file - * with the connect zones being written as joints - * \param filename name of the ascii file containing the meshes description - */ -void MeshCollectionMedAsciiDriver::write(const char* filename, ParaDomainSelector* domainSelector) const -{ - int nbdomains=_collection->getMesh().size(); - std::vector<std::string> filenames; - filenames.resize(nbdomains); - - //loop on the domains - for (int idomain=0; idomain<nbdomains; idomain++) - { - std::string distfilename; - std::ostringstream suffix; - suffix << filename << idomain+1 << ".med"; - distfilename=suffix.str(); - filenames[idomain]=distfilename; - - if ( !domainSelector || domainSelector->isMyDomain( idomain ) ) - { - if ( !_collection->getMesh()[idomain]->getNumberOfCells()==0 ) continue;//empty domain - MEDLoader::WriteUMesh(distfilename.c_str(),(_collection->getMesh())[idomain],true); - //writeSubdomain(idomain, nbdomains, distfilename.c_str(), domainSelector); - } - } - - //write master file - if ( !domainSelector || domainSelector->rank() == 0 ) - { - std::ofstream file(filename); - file << "#MED Fichier V 2.3"<<" " << std::endl; - file << "#" << " " << std::endl; - file << _collection->getMesh().size() << " " << std::endl; - - for (int idomain=0; idomain<nbdomains; idomain++) - file << _collection->getName() <<" "<< idomain+1 << " " - << (_collection->getMesh())[idomain]->getName() << " localhost " - << filenames[idomain] << " "<< std::endl; - } - -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx deleted file mode 100644 index 2a22d9446..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTIONMEDASCIIDRIVER_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTIONMEDASCIIDRIVER_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -namespace MEDPARTITIONER -{ - class MeshCollection; - class MEDPARTITIONER_EXPORT MeshCollectionMedAsciiDriver : public MeshCollectionDriver - { - public: - MeshCollectionMedAsciiDriver(MeshCollection*); - virtual ~MeshCollectionMedAsciiDriver() { } - int read(const char*, ParaDomainSelector* sel=0); - int read(ParaMEDMEM::MEDFileData*); - void write(const char*, ParaDomainSelector* sel=0) const; - private: - std::string _master_filename; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx deleted file mode 100644 index 0fcb460be..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDFileMesh.hxx" - -#include <map> -#include <set> -#include <vector> -#include <string> -#include <cstring> -#include <fstream> -#include <sstream> -#include <iostream> -#ifdef WIN32 -#include <time.h> -#include <windows.h> -#endif - - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -using namespace MEDPARTITIONER; - -/*!\class MeshCollectionMedXmlDriver - * - *\brief Driver for MED 3.2 files having Xml master files - * - * Driver for reading and writing distributed files - * for which the master file is written in an Xml format compliant with - * the MED 3.2 specification. - * The reading and writing of the meshes and fields are apart : - * the meshes must always be written/read before the fields. Reading/Writing fields - * is optional and is done field after field. API for reading/writing fields - * is written with a template so that FIELD<int> and FIELD<double> - * can be conveniently handled. - */ - -MeshCollectionMedXmlDriver::MeshCollectionMedXmlDriver(MeshCollection* collection):MeshCollectionDriver(collection) -{ -} - -/*!reads a MED File Xml Master File v>=2.3 - * and mounts the corresponding meshes in memory - * the connect zones are created from the joints - * - *\param filename Xml file containing the list of MED v2.3 files - * */ - -int MeshCollectionMedXmlDriver::read(const char* filename, ParaDomainSelector* domainSelector) -{ - //distributed meshes - int nbdomain; - _master_filename=filename; - - //reading ascii master file - try - { - //Setting up the Xml tree corresponding to filename - xmlDocPtr master_doc=xmlParseFile(filename); - - if (!master_doc) - throw INTERP_KERNEL::Exception("Xml Master File does not exist or is not compliant with Xml scheme"); - - //number of domains - xmlXPathContextPtr xpathCtx = xmlXPathNewContext(master_doc); - xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "//splitting/subdomain", xpathCtx); - if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) - throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/splitting/subdomain node"); - - //as subdomain has only one property which is "number" - //it suffices to take the content of its first child - const char* mystring = (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content; - sscanf(mystring, "%d", &nbdomain); - - //mesh name - xmlXPathFreeObject(xpathObj); - xpathObj = xmlXPathEvalExpression(BAD_CAST "//content/mesh", xpathCtx); - if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) - throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/content/mesh node"); - _collection->setName( (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content); - - //cout << "nb domain " << nbdomain << endl; - MyGlobals::_File_Names.resize(nbdomain); - MyGlobals::_Mesh_Names.resize(nbdomain); - (_collection->getMesh()).resize(nbdomain); - (_collection->getFaceMesh()).resize(nbdomain); - (_collection->getCellFamilyIds()).resize(nbdomain); - (_collection->getFaceFamilyIds()).resize(nbdomain); - - //retrieving the node which contains the file names - const char filechar[]="//files/subfile"; - xmlXPathFreeObject(xpathObj); - xpathObj = xmlXPathEvalExpression(BAD_CAST filechar, xpathCtx); - if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) - throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/files/subfile nodes"); - int nbfiles = xpathObj->nodesetval ->nodeNr; - - for (int i=0; i<nbfiles;i++) - { - //reading information about the domain - std::string host; - //reading file names - std::ostringstream name_search_string; - name_search_string<<"//files/subfile[@id=\""<<i+1<<"\"]/name"; - xmlXPathObjectPtr xpathObjfilename = - xmlXPathEvalExpression(BAD_CAST name_search_string.str().c_str(),xpathCtx); - if (xpathObjfilename->nodesetval ==0) - throw INTERP_KERNEL::Exception("Error retrieving a file name from subfile of Xml Master File"); - MyGlobals::_File_Names[i]=(const char*)xpathObjfilename->nodesetval->nodeTab[0]->children->content; - - //reading the local mesh names - std::ostringstream mesh_search_string; - mesh_search_string<<"//mapping/mesh/chunk[@subdomain=\""<<i+1<<"\"]/name"; - - xmlXPathObjectPtr xpathMeshObj = xmlXPathEvalExpression(BAD_CAST mesh_search_string.str().c_str(),xpathCtx); - if (xpathMeshObj->nodesetval ==0) - throw INTERP_KERNEL::Exception("Error retrieving mesh name from chunk of Xml Master File"); - MyGlobals::_Mesh_Names[i]=(const char*)xpathMeshObj->nodesetval->nodeTab[0]->children->content; - - if ( !domainSelector || domainSelector->isMyDomain(i)) - readSubdomain(i); - xmlXPathFreeObject(xpathObjfilename); - xmlXPathFreeObject(xpathMeshObj); - } //loop on domains - - //LIBXML cleanup - xmlXPathFreeObject(xpathObj); - xmlXPathFreeContext(xpathCtx); - xmlFreeDoc(master_doc); - - } //of try - catch(...) - { - throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); - } - - ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); - //creation of topology from mesh and connect zones - if ( _collection->isParallelMode() ) - { - //to know nb of cells on each proc to compute global cell ids from locally global - domainSelector->gatherNbOf(_collection->getMesh()); - } - _collection->setTopology(aPT, true); - _collection->setDomainNames(_collection->getName()); - return 0; -} - - -/*! writes the collection of meshes in a - * MED v2.3 Xml file - * with the connect zones being written as joints - * \param filename name of the Xml file containing the meshes description - */ -void MeshCollectionMedXmlDriver::write(const char* filename, ParaDomainSelector* domainSelector) const -{ - xmlDocPtr master_doc = 0; - xmlNodePtr root_node = 0, node, node2; - char buff[256]; - - //Creating the Xml document - master_doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(0, BAD_CAST "root"); - xmlDocSetRootElement(master_doc,root_node); - - //Creating child nodes - // Version tag - node = xmlNewChild(root_node, 0, BAD_CAST "version",0); - xmlNewProp(node, BAD_CAST "maj", BAD_CAST "2"); - xmlNewProp(node, BAD_CAST "min", BAD_CAST "3"); - xmlNewProp(node, BAD_CAST "ver", BAD_CAST "1"); - - //Description tag - time_t present; - char date[20]; -#ifndef WIN32 - time( &present); - struct tm *time_asc = localtime(&present); - sprintf(date,"%02d%02d%02d",time_asc->tm_year - ,time_asc->tm_mon+1 - ,time_asc->tm_mday); -#else - SYSTEMTIME st; - GetLocalTime ( &st ); - sprintf(date,"%02d%02d%02d", - st.wYear - ,st.wMonth - ,st.wDay); -#endif - - node = xmlNewChild(root_node,0, BAD_CAST "description",0); - - xmlNewProp(node, BAD_CAST "what", BAD_CAST _collection->getDescription().c_str()); - xmlNewProp(node, BAD_CAST "when", BAD_CAST date); - - //Content tag - node =xmlNewChild(root_node,0, BAD_CAST "content",0); - node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0); - xmlNewProp(node2, BAD_CAST "name", BAD_CAST _collection->getName().c_str()); - - //Splitting tag - node=xmlNewChild(root_node,0,BAD_CAST "splitting",0); - node2=xmlNewChild(node,0,BAD_CAST "subdomain",0); - sprintf(buff, "%d", (int)_collection->getMesh().size()); - xmlNewProp(node2, BAD_CAST "number", BAD_CAST buff); - node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0); - xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes"); - - //Files tag - xmlNodePtr file_node=xmlNewChild(root_node,0,BAD_CAST "files",0); - - //Mapping tag - node = xmlNewChild(root_node,0,BAD_CAST "mapping",0); - xmlNodePtr mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0); - xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST _collection->getName().c_str()); - - int nbdomains= _collection->getMesh().size(); - - //loop on the domains - std::string finalMeshName=""; - if (MyGlobals::_General_Informations.size()!=0) - { - std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName="); - if ((found!=std::string::npos) && (found>0)) - { - finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); - } - } - if (finalMeshName.empty()) - { - finalMeshName=_collection->getName(); - } - for (int idomain=nbdomains-1; idomain>=0;idomain--) - { - std::string distfilename; - std::ostringstream suffix; - suffix<<filename<<idomain+1<<".med"; - distfilename=suffix.str(); - - if ( !domainSelector || domainSelector->isMyDomain( idomain ) ) - { - if ( (_collection->getMesh())[idomain]->getNumberOfCells()==0 ) - continue; //empty domain - if (MyGlobals::_Verbose>1) - std::cout << "proc "<< domainSelector->rank() << " : writeMedFile " << distfilename - << " "<< (_collection->getMesh())[idomain]->getNumberOfCells() << " cells" - << " " << (_collection->getFaceMesh())[idomain]->getNumberOfCells() << " faces" - << " " << (_collection->getMesh())[idomain]->getNumberOfNodes()<<" nodes" << std::endl; - writeMedFile(idomain,distfilename); - } - - if (domainSelector->rank()==0) - { - //updating the ascii description file - node = xmlNewChild(file_node, 0, BAD_CAST "subfile",0); - sprintf (buff,"%d",idomain+1); - xmlNewProp(node, BAD_CAST "id", BAD_CAST buff); - xmlNewChild(node,0,BAD_CAST "name",BAD_CAST distfilename.c_str()); - xmlNewChild(node,0,BAD_CAST "machine",BAD_CAST "localhost"); - - node = xmlNewChild(mesh_node,0, BAD_CAST "chunk",0); - xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST buff); - xmlNewChild(node,0,BAD_CAST "name", BAD_CAST finalMeshName.c_str()); - //xmlNewChild(node,0,BAD_CAST "name", BAD_CAST ((_collection->getMesh())[idomain]->getName()).c_str()); - } - } - - //create the ascii description file - if (domainSelector->rank()==0) - { - std::string myfile(filename); - myfile.append(".xml"); - if ( !domainSelector || domainSelector->rank() == 0 ) - xmlSaveFormatFileEnc(myfile.c_str(), master_doc, "UTF-8", 1); - } - xmlFreeDoc(master_doc); - xmlCleanupParser(); -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx deleted file mode 100644 index 5e2049b4d..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTIONMEDXMLDRIVER_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTIONMEDXMLDRIVER_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -namespace MEDPARTITIONER -{ - class MeshCollection; - class MEDPARTITIONER_EXPORT MeshCollectionMedXmlDriver : public MeshCollectionDriver - { - public: - MeshCollectionMedXmlDriver(MeshCollection*); - virtual ~MeshCollectionMedXmlDriver() { } - int read(const char*, ParaDomainSelector* sel=0); - void write(const char*, ParaDomainSelector* sel=0) const; - private : - std::string _master_filename; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx deleted file mode 100644 index 7e3533815..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MetisGraph.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" -#include "InterpKernelException.hxx" - -#include <iostream> - -extern "C" -{ -#include "MEDPARTITIONER_metis.h" -} - -using namespace MEDPARTITIONER; - -METISGraph::METISGraph():Graph() -{ -} - -METISGraph::METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight) - :Graph(graph,edgeweight) -{ -} - -METISGraph::~METISGraph() -{ -} - -void METISGraph::partGraph(int ndomain, - const std::string& options_string, - ParaDomainSelector *parallelizer) -{ - using std::vector; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl; - - //number of graph vertices - int n=_graph->getNumberOf(); - //graph - int * xadj=const_cast<int*>(_graph->getIndex()); - int * adjncy=const_cast<int*>(_graph->getValue()); - //constraints - int * vwgt=_cell_weight; - int * adjwgt=_edge_weight; - int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0; - //base 0 or 1 - int base=0; - //ndomain - int nparts=ndomain; - //options - /* - (0=default_option,option,random_seed) see defs.h - #define PMV3_OPTION_DBGLVL 1 - #define PMV3_OPTION_SEED 2 - #define PMV3_OPTION_IPART 3 - #define PMV3_OPTION_PSR 3 - seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33 - */ - int options[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -#if !defined(MED_ENABLE_METIS) - throw INTERP_KERNEL::Exception("METISGraph::partGraph : METIS is not available. Check your products, please."); -#else - //output parameters - int edgecut; - int* partition=new int[n]; - - if(nparts >1) - { - if (MyGlobals::_Verbose>10) - std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl; - if (options_string != "k") - MEDPARTITIONER_METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, - &base, &nparts, options, &edgecut, partition); - else - MEDPARTITIONER_METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, - &base, &nparts, options, &edgecut, partition); - } - else //force this case because METIS send all 1 in value - { - for (int i=0; i<n; i++) - partition[i]=0; - } - vector<int> index(n+1); - vector<int> value(n); - index[0]=0; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - delete [] partition; - - //creating a skylinearray with no copy of the index and partition array - //the fifth argument true specifies that only the pointers are passed - //to the object - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); -#endif -} - diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx deleted file mode 100644 index 5954f9e4d..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_METISGRAPH_HXX__ -#define __MEDPARTITIONER_METISGRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT METISGraph : public Graph - { - public: - METISGraph(); - METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0); - virtual ~METISGraph(); - void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); - }; -} - -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx deleted file mode 100644 index 4c424f09f..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParMetisGraph.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" -#include "InterpKernelException.hxx" - -#include <iostream> - -#ifdef MED_ENABLE_PARMETIS -#include <parmetis.h> -// #if PARMETIS_MAJOR_VERSION == 4 -// #define ParMETIS_PartKway ParMETIS_V3_PartKway -// #endif -#endif - -using namespace MEDPARTITIONER; - -ParMETISGraph::ParMETISGraph():Graph() -{ -} - -ParMETISGraph::ParMETISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight) - :Graph(graph,edgeweight) -{ -} - -ParMETISGraph::~ParMETISGraph() -{ -} - -void ParMETISGraph::partGraph(int ndomain, - const std::string& options_string, - ParaDomainSelector *parallelizer) -{ - using std::vector; - vector<int> ran,vx,va; //for randomize - - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph" << std::endl; - - // number of graph vertices - int n=_graph->getNumberOf(); - //graph - int * xadj=const_cast<int*>(_graph->getIndex()); - int * adjncy=const_cast<int*>(_graph->getValue()); - //constraints - int * vwgt=_cell_weight; - int * adjwgt=_edge_weight; - int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0; - //base 0 or 1 - int base=0; - //ndomain - int nparts=ndomain; - //options - /* - (0=default_option,option,random_seed) see defs.h - #define PMV3_OPTION_DBGLVL 1 - #define PMV3_OPTION_SEED 2 - #define PMV3_OPTION_IPART 3 - #define PMV3_OPTION_PSR 3 - seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33 - */ - int options[4]={0,0,0,0}; - // output parameters - int edgecut; -#if !defined(MED_ENABLE_PARMETIS) - throw INTERP_KERNEL::Exception("ParMETISGraph::partGraph : PARMETIS is not available. Check your products, please."); -#else - int* partition=new int[n]; - - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph ParMETIS_PartKway new" << std::endl; - int * vtxdist=parallelizer->getProcVtxdist(); - MPI_Comm comm=MPI_COMM_WORLD; - ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, - adjwgt, &wgtflag, &base, &nparts, options, - &edgecut, partition, &comm ); - - - /*doc from parmetis.h - void __cdecl ParMETIS_PartKway( - idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, - int *edgecut, idxtype *part, MPI_Comm *comm); - - void __cdecl ParMETIS_V3_PartKway( - idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, - float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, - MPI_Comm *comm); - */ - - vector<int> index(n+1); - vector<int> value(n); - index[0]=0; - if (ran.size()>0 && MyGlobals::_Atomize==0) //there is randomize - { - if (MyGlobals::_Is0verbose>100) - std::cout << "randomize" << std::endl; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[ran[i]]=partition[i]; - } - } - else - { - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - } - delete [] partition; - - //creating a skylinearray with no copy of the index and partition array - //the fifth argument true specifies that only the pointers are passed - //to the object - - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); -#endif -} - diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx deleted file mode 100644 index 2d61cec26..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_ParMETISGraph_HXX__ -#define __MEDPARTITIONER_ParMETISGraph_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT ParMETISGraph : public Graph - { - public: - ParMETISGraph(); - ParMETISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0); - virtual ~ParMETISGraph(); - void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); - }; -} - -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx deleted file mode 100644 index 7658b72f7..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx +++ /dev/null @@ -1,674 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_UserGraph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingSkyLineArray.hxx" - -#include <iostream> -#include <numeric> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -/*! - * \brief Constructor. Find out my rank and world size - */ -MEDPARTITIONER::ParaDomainSelector::ParaDomainSelector(bool mesure_memory) - :_rank(0),_world_size(1), _nb_result_domains(-1), _init_time(0.0), - _mesure_memory(mesure_memory), _init_memory(0), _max_memory(0) -{ -#ifdef HAVE_MPI - if (MyGlobals::_Rank==-1) - { - MPI_Init(0,0); //do once only - MPI_Comm_size(MPI_COMM_WORLD,&_world_size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&_rank) ; - } - else - { - _world_size=MyGlobals::_World_Size; - _rank=MyGlobals::_Rank; - } - _init_time = MPI_Wtime(); -#else - //sequential : no MPI - _world_size=1; - _rank=0; - if (MyGlobals::_Verbose>10) - std::cout << "WARNING : ParaDomainSelector contructor without parallel_mode World_Size=1 by default" << std::endl; -#endif - MyGlobals::_World_Size=_world_size; - MyGlobals::_Rank=_rank; - - if (MyGlobals::_Verbose>200) std::cout << "proc " << MyGlobals::_Rank << " of " << MyGlobals::_World_Size << std::endl; - evaluateMemory(); -} - -MEDPARTITIONER::ParaDomainSelector::~ParaDomainSelector() -{ -} - -/*! - * \brief Return true if is running on different hosts - */ -bool MEDPARTITIONER::ParaDomainSelector::isOnDifferentHosts() const -{ - evaluateMemory(); - if ( _world_size < 2 ) return false; - -#ifdef HAVE_MPI - char name_here[ MPI_MAX_PROCESSOR_NAME+1 ], name_there[ MPI_MAX_PROCESSOR_NAME+1 ]; - int size; - MPI_Get_processor_name( name_here, &size); - - int next_proc = (rank() + 1) % nbProcs(); - int prev_proc = (rank() - 1 + nbProcs()) % nbProcs(); - int tag = 1111111; - - MPI_Status status; - MPI_Sendrecv((void*)&name_here[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, next_proc, tag, - (void*)&name_there[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, prev_proc, tag, - MPI_COMM_WORLD, &status); - - //bug: (isOnDifferentHosts here and there) is not (isOnDifferentHosts somewhere) - //return string(name_here) != string(name_there); - - int sum_same = -1; - int same = 1; - if (std::string(name_here) != std::string(name_there)) - same=0; - MPI_Allreduce( &same, &sum_same, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); - return (sum_same != nbProcs()); -#endif - return false; -} - -/*! - * \brief Return true if the domain with domainIndex is to be loaded on this proc - * \param domainIndex - index of mesh domain - * \retval bool - to load or not - */ -bool MEDPARTITIONER::ParaDomainSelector::isMyDomain(int domainIndex) const -{ - evaluateMemory(); - return (_rank == getProcessorID( domainIndex )); -} - -/*! - * \brief Return processor id where the domain with domainIndex resides - * \param domainIndex - index of mesh domain - * \retval int - processor id - */ -int MEDPARTITIONER::ParaDomainSelector::getProcessorID(int domainIndex) const -{ - evaluateMemory(); - return ( domainIndex % _world_size ); -} - -/*! - * \brief Gather info on nb of cell entities on each processor and return total nb. - * - * Is called - * 1) for MED_CELL to know global id shift for domains at graph construction; - * 2) for sub-entity to know total nb of sub-entities before creating those of joints - */ -void MEDPARTITIONER::ParaDomainSelector::gatherNbOf(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes) -{ - evaluateMemory(); - // get nb of elems of each domain mesh - int nb_domains=domain_meshes.size(); - std::vector<int> nb_elems(nb_domains*2, 0); //NumberOfCells & NumberOfNodes - for (int i=0; i<nb_domains; ++i) - if ( domain_meshes[i] ) - { - nb_elems[i*2] = domain_meshes[i]->getNumberOfCells(); - nb_elems[i*2+1] = domain_meshes[i]->getNumberOfNodes(); - } - // receive nb of elems from other procs - std::vector<int> all_nb_elems; - if (MyGlobals::_World_Size==1) - { - all_nb_elems=nb_elems; - } - else - { -#ifdef HAVE_MPI - all_nb_elems.resize( nb_domains*2 ); - MPI_Allreduce((void*)&nb_elems[0], (void*)&all_nb_elems[0], nb_domains*2, MPI_INT, MPI_SUM, MPI_COMM_WORLD); -#else - throw INTERP_KERNEL::Exception("not(HAVE_MPI) incompatible with MPI_World_Size>1"); -#endif - } - int total_nb_cells=0, total_nb_nodes=0; - for (int i=0; i<nb_domains; ++i) - { - total_nb_cells+=all_nb_elems[i*2]; - total_nb_nodes+=all_nb_elems[i*2+1]; - } - - if (MyGlobals::_Is0verbose>10) - std::cout << "totalNbCells " << total_nb_cells << " totalNbNodes " << total_nb_nodes << std::endl; - - std::vector<int>& cell_shift_by_domain=_cell_shift_by_domain; - std::vector<int>& node_shift_by_domain=_node_shift_by_domain; - std::vector<int>& face_shift_by_domain=_face_shift_by_domain; - - std::vector< int > ordered_nbs_cell, ordered_nbs_node, domain_order(nb_domains); - ordered_nbs_cell.push_back(0); - ordered_nbs_node.push_back(0); - for (int iproc=0; iproc<nbProcs(); ++iproc) - for (int idomain=0; idomain<nb_domains; ++idomain) - if (getProcessorID( idomain )==iproc) - { - domain_order[idomain] = ordered_nbs_cell.size() - 1; - ordered_nbs_cell.push_back( ordered_nbs_cell.back() + all_nb_elems[idomain*2] ); - ordered_nbs_node.push_back( ordered_nbs_node.back() + all_nb_elems[idomain*2+1] ); - } - cell_shift_by_domain.resize( nb_domains+1, 0 ); - node_shift_by_domain.resize( nb_domains+1, 0 ); - face_shift_by_domain.resize( nb_domains+1, 0 ); - for (int idomain=0; idomain<nb_domains; ++idomain) - { - cell_shift_by_domain[ idomain ] = ordered_nbs_cell[ domain_order[ idomain ]]; - node_shift_by_domain[ idomain ] = ordered_nbs_node[ domain_order[ idomain ]]; - } - cell_shift_by_domain.back() = ordered_nbs_cell.back(); // to know total nb of elements - node_shift_by_domain.back() = ordered_nbs_node.back(); // to know total nb of elements - - if (MyGlobals::_Is0verbose>300) - { - std::cout << "proc " << MyGlobals::_Rank << " : cellShiftByDomain "; - for (int i=0; i<=nb_domains; ++i) - std::cout << cell_shift_by_domain[i] << "|"; - std::cout << std::endl; - std::cout << "proc " << MyGlobals::_Rank << " : nodeShiftBy_domain "; - for (int i=0; i<=nb_domains; ++i) - std::cout << node_shift_by_domain[i] << "|"; - std::cout << std::endl; - } - // fill _nb_vert_of_procs (is Vtxdist) - _nb_vert_of_procs.resize(_world_size+1); - _nb_vert_of_procs[0] = 0; // base = 0 - for (int i=0; i<nb_domains; ++i) - { - int rankk = getProcessorID(i); - _nb_vert_of_procs[rankk+1] += all_nb_elems[i*2]; - } - for (std::size_t i=1; i<_nb_vert_of_procs.size(); ++i) - _nb_vert_of_procs[i] += _nb_vert_of_procs[i-1]; // to CSR format : cumulated - - if (MyGlobals::_Is0verbose>200) - { - std::cout << "proc " << MyGlobals::_Rank << " : gatherNbOf : vtxdist is "; - for (int i = 0; i <= _world_size; ++i) - std::cout << _nb_vert_of_procs[i] << " "; - std::cout << std::endl; - } - - evaluateMemory(); - return; -} - -/*! - * \brief Return distribution of the graph vertices among the processors - * \retval int* - array containing nb of vertices (=cells) on all processors - * - * gatherNbOf() must be called before. - * The result array is to be used as the first arg of ParMETIS_V3_PartKway() and - * is freed by ParaDomainSelector. - */ -int *MEDPARTITIONER::ParaDomainSelector::getProcVtxdist() const -{ - evaluateMemory(); - if (_nb_vert_of_procs.empty()) - throw INTERP_KERNEL::Exception("_nb_vert_of_procs not set"); - return const_cast<int*>(& _nb_vert_of_procs[0]); -} - -/*! - * \brief Return nb of cells in domains with lower index. - * - * gatherNbOf() must be called before. - * Result added to local id on given domain gives id in the whole distributed mesh - */ -int MEDPARTITIONER::ParaDomainSelector::getDomainCellShift(int domainIndex) const -{ - evaluateMemory(); - if (_cell_shift_by_domain.empty()) - throw INTERP_KERNEL::Exception("_cell_shift_by_domain not set"); - return _cell_shift_by_domain[domainIndex]; -} - -int MEDPARTITIONER::ParaDomainSelector::getDomainNodeShift(int domainIndex) const -{ - evaluateMemory(); - if (_node_shift_by_domain.empty()) - throw INTERP_KERNEL::Exception("_node_shift_by_domain not set"); - return _node_shift_by_domain[domainIndex]; -} - -/*! - * \brief Return nb of nodes on processors with lower rank. - * - * gatherNbOf() must be called before. - * Result added to global id on this processor gives id in the whole distributed mesh - */ -int MEDPARTITIONER::ParaDomainSelector::getProcNodeShift() const -{ - evaluateMemory(); - if (_nb_vert_of_procs.empty()) - throw INTERP_KERNEL::Exception("_nb_vert_of_procs not set"); - return _nb_vert_of_procs[_rank]; -} - -/*! - * \brief Gather graphs from all processors into one - */ -std::auto_ptr<MEDPARTITIONER::Graph> MEDPARTITIONER::ParaDomainSelector::gatherGraph(const Graph* graph) const -{ - Graph* glob_graph = 0; - - evaluateMemory(); -#ifdef HAVE_MPI - - // --------------- - // Gather indices - // --------------- - - std::vector<int> index_size_of_proc( nbProcs() ); // index sizes - 1 - for ( std::size_t i = 1; i < _nb_vert_of_procs.size(); ++i ) - index_size_of_proc[i-1] = _nb_vert_of_procs[ i ] - _nb_vert_of_procs[ i-1 ]; - - int index_size = 1 + _cell_shift_by_domain.back(); - int *graph_index = new int[ index_size ]; - const int *index = graph->getGraph()->getIndex(); - int *proc_index_displacement = const_cast<int*>( & _nb_vert_of_procs[0] ); - - MPI_Allgatherv((void*) (index+1), // send local index except first 0 (or 1) - index_size_of_proc[_rank], // index size on this proc - MPI_INT, - (void*) graph_index, // receive indices - & index_size_of_proc[0], // index size on each proc - proc_index_displacement, // displacement of each proc index - MPI_INT, - MPI_COMM_WORLD); - graph_index[0] = index[0]; // it is not overwritten thanks to proc_index_displacement[0]==1 - - // get sizes of graph values on each proc by the got indices of graphs - std::vector< int > value_size_of_proc( nbProcs() ), proc_value_displacement(1,0); - for ( int i = 0; i < nbProcs(); ++i ) - { - if ( index_size_of_proc[i] > 0 ) - value_size_of_proc[i] = graph_index[ proc_index_displacement[ i+1 ]-1 ] - graph_index[0]; - else - value_size_of_proc[i] = 0; - proc_value_displacement.push_back( proc_value_displacement.back() + value_size_of_proc[i] ); - } - - // update graph_index - for ( int i = 1; i < nbProcs(); ++i ) - { - int shift = graph_index[ proc_index_displacement[i]-1 ]-graph_index[0]; - for ( int j = proc_index_displacement[i]; j < proc_index_displacement[i+1]; ++j ) - graph_index[ j ] += shift; - } - - // -------------- - // Gather values - // -------------- - - int value_size = graph_index[ index_size-1 ] - graph_index[ 0 ]; - int *graph_value = new int[ value_size ]; - const int *value = graph->getGraph()->getValue(); - - MPI_Allgatherv((void*) value, // send local value - value_size_of_proc[_rank], // value size on this proc - MPI_INT, - (void*) graph_value, // receive values - & value_size_of_proc[0], // value size on each proc - & proc_value_displacement[0], // displacement of each proc value - MPI_INT, - MPI_COMM_WORLD); - - // ----------------- - // Gather partition - // ----------------- - - int * partition = new int[ _cell_shift_by_domain.back() ]; - const int* part = graph->getPart(); - - MPI_Allgatherv((void*) part, // send local partition - index_size_of_proc[_rank], // index size on this proc - MPI_INT, - (void*)(partition-1), // -1 compensates proc_index_displacement[0]==1 - & index_size_of_proc[0], // index size on each proc - proc_index_displacement, // displacement of each proc index - MPI_INT, - MPI_COMM_WORLD); - - // ----------- - // Make graph - // ----------- - - // MEDCouplingSkyLineArray* array = - // new MEDCouplingSkyLineArray( index_size-1, value_size, graph_index, graph_value, true ); - - // glob_graph = new UserGraph( array, partition, index_size-1 ); - - evaluateMemory(); - - delete [] partition; - -#endif // HAVE_MPI - - return std::auto_ptr<Graph>( glob_graph ); -} - - -/*! - * \brief Set nb of cell/cell pairs in a joint between domains - */ -void MEDPARTITIONER::ParaDomainSelector::setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain ) -{ - // This method is needed for further computing global numbers of faces in joint. - // Store if both domains are on this proc else on one of procs only - if ( isMyDomain( dist_domain ) || dist_domain < loc_domain ) - { - if ( _nb_cell_pairs_by_joint.empty() ) - _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0); - - int joint_id = jointId( loc_domain, dist_domain ); - _nb_cell_pairs_by_joint[ joint_id ] = nb_cell_pairs; - } - evaluateMemory(); -} - -//================================================================================ -/*! - * \brief Return nb of cell/cell pairs in a joint between domains on different procs - */ -//================================================================================ - -int MEDPARTITIONER::ParaDomainSelector::getNbCellPairs( int dist_domain, int loc_domain ) const -{ - evaluateMemory(); - - int joint_id = jointId( loc_domain, dist_domain ); - return _nb_cell_pairs_by_joint[ joint_id ]; -} - -//================================================================================ -/*! - * \brief Gather size of each joint - */ -//================================================================================ - -void MEDPARTITIONER::ParaDomainSelector::gatherNbCellPairs() -{ - if ( _nb_cell_pairs_by_joint.empty() ) - _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0); - evaluateMemory(); - - std::vector< int > send_buf = _nb_cell_pairs_by_joint; -#ifdef HAVE_MPI - MPI_Allreduce((void*)&send_buf[0], - (void*)&_nb_cell_pairs_by_joint[0], - _nb_cell_pairs_by_joint.size(), - MPI_INT, MPI_SUM, MPI_COMM_WORLD); -#endif - // check that the set nbs of cell pairs are correct, - // namely that each joint is treated on one proc only - for ( std::size_t j = 0; j < _nb_cell_pairs_by_joint.size(); ++j ) - if ( _nb_cell_pairs_by_joint[j] != send_buf[j] && send_buf[j]>0 ) - throw INTERP_KERNEL::Exception("invalid nb of cell pairs"); -} - -//================================================================================ -/*! - * \brief Return the first global id of sub-entity for the joint - */ -//================================================================================ - -int MEDPARTITIONER::ParaDomainSelector::getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const -{ - // total_nb_faces includes faces existing before creation of joint faces - // (got in gatherNbOf( MED_FACE )). - evaluateMemory(); - - int total_nb_faces = _face_shift_by_domain.empty() ? 0 : _face_shift_by_domain.back(); - int id = total_nb_faces + 1; - - if ( _nb_cell_pairs_by_joint.empty() ) - throw INTERP_KERNEL::Exception("gatherNbCellPairs() must be called before"); - int joint_id = jointId( loc_domain, dist_domain ); - for ( int j = 0; j < joint_id; ++j ) - id += _nb_cell_pairs_by_joint[ j ]; - - return id; -} - -//================================================================================ -/*! - * \brief Send-receive local ids of joint faces - */ -//================================================================================ - -int *MEDPARTITIONER::ParaDomainSelector::exchangeSubentityIds( int loc_domain, int dist_domain, - const std::vector<int>& loc_ids_here ) const -{ - int* loc_ids_dist = new int[ loc_ids_here.size()]; -#ifdef HAVE_MPI - int dest = getProcessorID( dist_domain ); - int tag = 2002 + jointId( loc_domain, dist_domain ); - MPI_Status status; - MPI_Sendrecv((void*)&loc_ids_here[0], loc_ids_here.size(), MPI_INT, dest, tag, - (void*) loc_ids_dist, loc_ids_here.size(), MPI_INT, dest, tag, - MPI_COMM_WORLD, &status); -#endif - evaluateMemory(); - - return loc_ids_dist; -} - -//================================================================================ -/*! - * \brief Return identifier for a joint - */ -//================================================================================ - -int MEDPARTITIONER::ParaDomainSelector::jointId( int local_domain, int distant_domain ) const -{ - evaluateMemory(); - if (_nb_result_domains < 0) - throw INTERP_KERNEL::Exception("setNbDomains() must be called before"); - - if ( local_domain < distant_domain ) - std::swap( local_domain, distant_domain ); - return local_domain * _nb_result_domains + distant_domain; -} - - -//================================================================================ -/*! - * \brief Return time passed from construction in seconds - */ -//================================================================================ - -double MEDPARTITIONER::ParaDomainSelector::getPassedTime() const -{ -#ifdef HAVE_MPI - return MPI_Wtime() - _init_time; -#else - return 0.0; -#endif -} - -/*! - Sends content of \a mesh to processor \a target. To be used with \a recvMesh method. - \param mesh mesh to be sent - \param target processor id of the target -*/ - -void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const -{ -#ifndef HAVE_MPI - throw INTERP_KERNEL::Exception("ParaDomainSelector::sendMesh : incoherent call in non_MPI mode"); -#else - if (MyGlobals::_Verbose>600) - std::cout << "proc " << _rank << " : sendMesh '" << mesh.getName() << "' size " << mesh.getNumberOfCells() << " to " << target << std::endl; - // First stage : sending sizes - // ------------------------------ - std::vector<int> tinyInfoLocal; - std::vector<std::string> tinyInfoLocalS; - std::vector<double> tinyInfoLocalD; - //Getting tiny info of local mesh to allow the distant proc to initialize and allocate - //the transmitted mesh. - mesh.getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS); - tinyInfoLocal.push_back(mesh.getNumberOfCells()); - int tinySize=tinyInfoLocal.size(); - MPI_Send(&tinySize, 1, MPI_INT, target, 1113, MPI_COMM_WORLD); - MPI_Send(&tinyInfoLocal[0], tinyInfoLocal.size(), MPI_INT, target, 1112, MPI_COMM_WORLD); - - if (mesh.getNumberOfCells()>0) //no sends if empty - { - ParaMEDMEM::DataArrayInt *v1Local=0; - ParaMEDMEM::DataArrayDouble *v2Local=0; - //serialization of local mesh to send data to distant proc. - mesh.serialize(v1Local,v2Local); - int nbLocalElems=0; - int* ptLocal=0; - if(v1Local) //if empty getNbOfElems() is 1! - { - nbLocalElems=v1Local->getNbOfElems(); // if empty be 1! - ptLocal=v1Local->getPointer(); - } - MPI_Send(ptLocal, nbLocalElems, MPI_INT, target, 1111, MPI_COMM_WORLD); - int nbLocalElems2=0; - double *ptLocal2=0; - if(v2Local) //if empty be 0! - { - nbLocalElems2=v2Local->getNbOfElems(); - ptLocal2=v2Local->getPointer(); - } - MPI_Send(ptLocal2, nbLocalElems2, MPI_DOUBLE, target, 1110, MPI_COMM_WORLD); - if(v1Local) v1Local->decrRef(); - if(v2Local) v2Local->decrRef(); - } -#endif -} - -/*! Receives messages from proc \a source to fill mesh \a mesh. - To be used with \a sendMesh method. - \param mesh pointer to mesh that is filled - \param source processor id of the incoming messages -*/ -void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source)const -{ -#ifndef HAVE_MPI - throw INTERP_KERNEL::Exception("ParaDomainSelector::recvMesh : incoherent call in non_MPI mode"); -#else - // First stage : exchanging sizes - // ------------------------------ - std::vector<int> tinyInfoDistant; - std::vector<std::string> tinyInfoLocalS; - std::vector<double> tinyInfoDistantD(1); - //Getting tiny info of local mesh to allow the distant proc to initialize and allocate - //the transmitted mesh. - MPI_Status status; - int tinyVecSize; - MPI_Recv(&tinyVecSize, 1, MPI_INT, source, 1113, MPI_COMM_WORLD, &status); - tinyInfoDistant.resize(tinyVecSize); - std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0); - - MPI_Recv(&tinyInfoDistant[0], tinyVecSize, MPI_INT,source,1112,MPI_COMM_WORLD, &status); - //there was tinyInfoLocal.push_back(mesh.getNumberOfCells()); - int NumberOfCells=tinyInfoDistant[tinyVecSize-1]; - if (NumberOfCells>0) - { - ParaMEDMEM::DataArrayInt *v1Distant=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayDouble *v2Distant=ParaMEDMEM::DataArrayDouble::New(); - //Building the right instance of copy of distant mesh. - ParaMEDMEM::MEDCouplingPointSet *distant_mesh_tmp= - ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType( - (ParaMEDMEM::MEDCouplingMeshType) tinyInfoDistant[0]); - std::vector<std::string> unusedTinyDistantSts; - mesh=dynamic_cast<ParaMEDMEM::MEDCouplingUMesh*> (distant_mesh_tmp); - - mesh->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - int nbDistElem=0; - int *ptDist=0; - if(v1Distant) - { - nbDistElem=v1Distant->getNbOfElems(); - ptDist=v1Distant->getPointer(); - } - MPI_Recv(ptDist, nbDistElem, MPI_INT, source,1111, MPI_COMM_WORLD, &status); - double *ptDist2=0; - nbDistElem=0; - if(v2Distant) - { - nbDistElem=v2Distant->getNbOfElems(); - ptDist2=v2Distant->getPointer(); - } - MPI_Recv(ptDist2, nbDistElem, MPI_DOUBLE,source, 1110, MPI_COMM_WORLD, &status); - //finish unserialization - mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - if(v1Distant) v1Distant->decrRef(); - if(v2Distant) v2Distant->decrRef(); - } - else - { - mesh=CreateEmptyMEDCouplingUMesh(); - } - if (MyGlobals::_Verbose>600) - std::cout << "proc " << _rank << " : recvMesh '" << mesh->getName() << "' size " << mesh->getNumberOfCells() << " from " << source << std::endl; -#endif -} - -#ifndef WIN32 -#include <sys/sysinfo.h> -#endif - -/*! - * \brief Evaluate current memory usage and return the maximal one in KB - */ -int MEDPARTITIONER::ParaDomainSelector::evaluateMemory() const -{ - if ( _mesure_memory ) - { - int used_memory = 0; -#ifndef WIN32 - struct sysinfo si; - int err = sysinfo( &si ); - if ( !err ) - used_memory = (( si.totalram - si.freeram + si.totalswap - si.freeswap ) * si.mem_unit ) / 1024; -#endif - if ( used_memory > _max_memory ) - _max_memory = used_memory; - - if ( !_init_memory ) - _init_memory = used_memory; - } - return _max_memory - _init_memory; -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx deleted file mode 100644 index 7db3c6082..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_PARADOMAINSELECTOR_HXX__ -#define __MEDPARTITIONER_PARADOMAINSELECTOR_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <memory> -#include <vector> - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; -} - -namespace MEDPARTITIONER -{ - class Graph; - class JointExchangeData; - - /*! - * \brief Communication helper in parallel mode - */ - class MEDPARTITIONER_EXPORT ParaDomainSelector - { - public: - ParaDomainSelector(bool mesure_memory=false); - ~ParaDomainSelector(); - - //processor rank - int rank() const { return _rank; } - //number of processors - int nbProcs() const { return _world_size; } - //true if is running on different hosts - bool isOnDifferentHosts() const; - //true if the domain with domainIndex is to be loaded on this proc - bool isMyDomain(int domainIndex) const; - //processor id where the domain with domainIndex resides - int getProcessorID(int domainIndex) const; - //Set nb of required domains. (Used to sort joints via jointId()) - void setNbDomains(int nb) { _nb_result_domains = nb; } - //identifier for a joint - int jointId( int local_domain, int distant_domain ) const; - - int getNbTotalCells() { return _cell_shift_by_domain.back(); } - int getNbTotalNodes() { return _node_shift_by_domain.back(); }; - int getNbTotalFaces() { return _face_shift_by_domain.back(); }; - - //Collect nb of entities on procs - void gatherNbOf(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes); - - //distribution of the graph vertices among the processors - int* getProcVtxdist() const; - - //nb of nodes on processors with lower rank - int getProcNodeShift() const; - //nb of cells in domains with lower index - int getDomainCellShift(int domainIndex) const; - //nb of nodes in domains with lower index - int getDomainNodeShift(int domainIndex) const; - - //Gather graphs from all processors into one - std::auto_ptr<Graph> gatherGraph(const Graph* graph) const; - - //Set nb of cell/cell pairs in a joint between domains - void setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain ); - //Gather size of each proc/proc joint - void gatherNbCellPairs(); - //nb of cell/cell pairs in a joint between domains on different procs - int getNbCellPairs( int dist_domain, int loc_domain ) const; - - //get the first global id of sub-entity for the joint - int getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const; - //Send-receive local ids of joint faces - int* exchangeSubentityIds( int loc_domain, int dist_domain, - const std::vector<int>& loc_ids_here ) const; - //time passed from construction in seconds - double getPassedTime() const; - - //Evaluate current memory usage and return the maximal one in KB - int evaluateMemory() const; - - void sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const; - void recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source) const; - private: - int _rank; //my rank - int _world_size; //nb of processors - int _nb_result_domains; //required nb of domains - - std::vector< int > _nb_cell_pairs_by_joint; - std::vector< int > _nb_vert_of_procs; //graph vertices - std::vector< int > _cell_shift_by_domain; - std::vector< int > _node_shift_by_domain; - std::vector< int > _face_shift_by_domain; - - double _init_time; - bool _mesure_memory; - mutable int _init_memory; - mutable int _max_memory; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx deleted file mode 100644 index b65d3fdd1..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx +++ /dev/null @@ -1,674 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ConnectZone.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "InterpKernelHashMap.hxx" - -#include <set> -#include <map> -#include <vector> -#include <iostream> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace MEDPARTITIONER; - -ParallelTopology::ParallelTopology():_nb_domain(0),_mesh_dimension(0) -{ -} - -//constructing topology according to mesh collection without global numerotation (use setGlobalNumerotation later) -ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes) -{ - _nb_domain=meshes.size(); - _nb_cells.resize(_nb_domain); - _nb_nodes.resize(_nb_domain); - // _nb_faces.resize(_nb_domain); - - if (MyGlobals::_Is0verbose>100) - std::cout << "new ParallelTopology\n"; - _loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation() - _node_loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation() - //_face_loc_to_glob.resize(_nb_domain); - _mesh_dimension = -1; - bool parallel_mode = false; - for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++) - parallel_mode = (!meshes[idomain]); - - if (MyGlobals::_Is0verbose>20 && !parallel_mode) - std::cout << "WARNING : ParallelTopology contructor without parallel_mode" << std::endl; - for (int idomain=0; idomain<_nb_domain; idomain++) - { - if ( !meshes[idomain] ) continue; - if (_mesh_dimension==-1) - { - _mesh_dimension = meshes[idomain]->getMeshDimension(); - } - else - { - if (_mesh_dimension!=meshes[idomain]->getMeshDimension()) - throw INTERP_KERNEL::Exception("meshes dimensions incompatible"); - } - _nb_cells[idomain]=meshes[idomain]->getNumberOfCells(); - _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes(); - //note: in parallel mode _nb_cells and _nb_nodes are not complete now, needs gatherNbOf() - } -} - -//constructing _loc_to_glob etc by default, needs gatherNbOf() done -void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSelector) -{ - if (MyGlobals::_Is0verbose>100) - std::cout<< "setGlobalNumerotationDefault on " << _nb_domain << " domains\n"; - if (_loc_to_glob.size()!=0) throw INTERP_KERNEL::Exception("a global numerotation is done yet"); - _loc_to_glob.resize(_nb_domain); - _node_loc_to_glob.resize(_nb_domain); - - //warning because _nb_cells[idomain] is 0 if not my domain(s) - //we set loc_to_glob etc.. only for my domain(s) - if (MyGlobals::_Is0verbose>500) - std::cout << "(c)idomain|ilocalCell|iglobalCell" << std::endl; - for (int idomain=0; idomain<_nb_domain; idomain++) - { - _loc_to_glob[idomain].resize(_nb_cells[idomain]); - int domainCellShift=domainSelector->getDomainCellShift(idomain); - for (int i=0; i<_nb_cells[idomain]; i++) - { - int global=domainCellShift+i ; - _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - _loc_to_glob[idomain][i]=global; - if (MyGlobals::_Verbose>500) - std::cout << "c" << idomain << "|" << i << "|" << global << " "; - } - } -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace -#endif - if (MyGlobals::_Is0verbose>500) std::cout << std::endl; - - if (MyGlobals::_Is0verbose>500) std::cout << "(n)idomain|ilocalNode|iglobalNode" << std::endl; - for (int idomain=0; idomain<_nb_domain; idomain++) - { - _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); - int domainNodeShift=domainSelector->getDomainNodeShift(idomain); - for (int i=0; i<_nb_nodes[idomain]; i++) - { - int global=domainNodeShift+i ; - _node_glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - _node_loc_to_glob[idomain][i]=global; - if (MyGlobals::_Verbose>500) - std::cout << "n" << idomain << "|" << i << "|" << global << " "; - } - } -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace -#endif - if (MyGlobals::_Is0verbose>500) std::cout << std::endl; - - _nb_total_cells=domainSelector->getNbTotalCells(); - _nb_total_nodes=domainSelector->getNbTotalNodes(); - _nb_total_faces=domainSelector->getNbTotalFaces(); - if (MyGlobals::_Is0verbose>200) - std::cout << "globalNumerotation default done meshDimension " << _mesh_dimension << " nbTotalCells " << _nb_total_cells << " nbTotalNodes " << _nb_total_nodes << std::endl; -} - -//constructing topology according to mesh collection -ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes, - const std::vector<MEDPARTITIONER::ConnectZone*>& cz, - std::vector<int*>& cellglobal, - std::vector<int*>& nodeglobal, - std::vector<int*>& faceglobal) -{ - _nb_domain=meshes.size(); - int index_global=0; - int index_node_global=0; - int index_face_global=0; - - _nb_cells.resize(_nb_domain); - _nb_nodes.resize(_nb_domain); - // _nb_faces.resize(_nb_domain); - - _loc_to_glob.resize(_nb_domain); - _node_loc_to_glob.resize(_nb_domain); - // _face_loc_to_glob.resize(_nb_domain); - - bool parallel_mode = false; - for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++) - parallel_mode = (!meshes[idomain]); - - for (int idomain=0; idomain<_nb_domain; idomain++) - { - if ( !meshes[idomain] ) continue; - _mesh_dimension = meshes[idomain]->getMeshDimension(); - - //creating cell maps - _nb_cells[idomain]=meshes[idomain]->getNumberOfCells(); - // cout << "Nb cells (domain "<<idomain<<") = "<<_nb_cells[idomain]; - _loc_to_glob[idomain].resize(_nb_cells[idomain]); - - if (cellglobal[idomain]==0 || parallel_mode) - { - //int cellDomainShift=_cell_shift_by_domain[idomain]; - //creating global numbering from scratch - for (int i=0; i<_nb_cells[idomain]; i++) - { - int global=i ;//cellDomainShift+i; - _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - _loc_to_glob[idomain][i]=global; - index_global++; - } - } - //using global numbering coming from a previous numbering - else - { - for (int i=0; i<_nb_cells[idomain]; i++) - { - int global=cellglobal[idomain][i]; - _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - //_loc_to_glob[make_pair(idomain,i+1)]=global; - _loc_to_glob[idomain][i]=global; - index_global++; - } - } - - //cas sequentiel - if (_nb_domain==1) - { - _nb_total_cells=index_global; - _nb_cells[0]=index_global; - _node_loc_to_glob[idomain].resize(meshes[idomain]->getNumberOfNodes()); - for (int i=0; i<meshes[idomain]->getNumberOfNodes(); i++) - { - _node_glob_to_loc.insert(std::make_pair(i,std::make_pair(0,i))); - _node_loc_to_glob[0][i]=i; - } - _nb_total_nodes=meshes[idomain]->getNumberOfNodes(); - _nb_nodes[0]=_nb_total_nodes; - return; - } - - //creating node maps - _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes(); - INTERP_KERNEL::HashMap <int,std::pair<int,int> > local2distant; - _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); - for (std::size_t icz=0; icz<cz.size(); icz++) - { - if (cz[icz]->getLocalDomainNumber() == idomain && - cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber()) - { - int nb_node= cz[icz]->getNodeNumber(); - const int* node_corresp=cz[icz]->getNodeCorrespValue(); - int distant_ip = cz[icz]->getDistantDomainNumber(); - for (int i=0; i< nb_node; i++) - { - int local= node_corresp[i*2]; - int distant = node_corresp[i*2+1]; - local2distant.insert(std::make_pair(local, std::make_pair(distant_ip,distant))); - } - } - } - // setting mappings for all nodes - if (nodeglobal[idomain]==0) - { - for (int inode=0; inode<_nb_nodes[idomain]; inode++) - { - if (local2distant.find(inode)==local2distant.end()) - { - index_node_global++; - _node_glob_to_loc.insert(std::make_pair(index_node_global,std::make_pair(idomain,inode))); - //_node_loc_to_glob[make_pair(idomain,inode+1)]=index_node_global; - _node_loc_to_glob[idomain][inode]=index_node_global; - } - else - { - int ip = (local2distant.find(inode)->second).first; - int distant = (local2distant.find(inode)->second).second; - int global_number=_loc_to_glob[ip][distant]; - _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); - _node_loc_to_glob[idomain][inode]=global_number; - } - } - } - //using former node numbering - else - { - for (int inode=0; inode<_nb_nodes[idomain]; inode++) - { - int global_number=nodeglobal[idomain][inode]; - _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); - _node_loc_to_glob[idomain][inode]=global_number; - } - } - } - - _nb_total_cells=index_global; - _nb_total_nodes=index_node_global; - _nb_total_faces=index_face_global; -} - - -//constructing ParallelTopology from an old topology and a graph -ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_domain, int mesh_dimension) -{ - - _nb_domain=nb_domain; - _mesh_dimension=mesh_dimension; - - if (MyGlobals::_Verbose>200) - std::cout << "proc " << MyGlobals::_Rank << " : new topology oldNbDomain " << - oldTopology->nbDomain() << " newNbDomain " << _nb_domain << std::endl; - _nb_cells.resize(_nb_domain,0); - _nb_nodes.resize(_nb_domain,0); - _nb_faces.resize(_nb_domain,0); - - _loc_to_glob.resize(_nb_domain); - _node_loc_to_glob.resize(_nb_domain); - _face_loc_to_glob.resize(_nb_domain); - - const int* part=graph->getPart(); //all cells for this proc (may be more domains) - _nb_total_cells=graph->nbVertices(); //all cells for this proc (may be more domains) - if (MyGlobals::_Verbose>300) - std::cout << "proc " << MyGlobals::_Rank << " : topology from partition, nbTotalCells " << _nb_total_cells << std::endl; - - int icellProc=0; //all cells of my domains are concatenated in part - for (int iold=0; iold<oldTopology->nbDomain(); iold++) - { - int ioldNbCell=oldTopology->getCellNumber(iold); - //std::cout<<"proc "<<MyGlobals::_Rank<<" : cell number old domain "<<iold<<" : "<<ioldNbCell<<std::endl; - //if not my old domains getCellNumber is 0 - std::vector<int> globalids(ioldNbCell); - oldTopology->getCellList(iold, &globalids[0]); //unique global numerotation - for (int icell=0; icell<ioldNbCell; icell++) - { - int idomain=part[icellProc]; - _nb_cells[idomain]++; - icellProc++; - int iGlobalCell=globalids[icell]; - _loc_to_glob[idomain].push_back(iGlobalCell); - _glob_to_loc.insert(std::make_pair(iGlobalCell, std::make_pair(idomain, _nb_cells[idomain]))); - } - } - - if (MyGlobals::_Verbose>300) - for (int idomain=0; idomain<_nb_domain; idomain++) - std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; - - // JOINTs - - if ( MyGlobals::_Create_Joints && nb_domain > 1 ) - { - std::vector< std::vector< std::vector< int > > > cellCorresp( nb_domain ); - for ( int idomain = 0; idomain < nb_domain; ++idomain ) - { - cellCorresp[ idomain ].resize( nb_domain ); - } - const ParaMEDMEM::MEDCouplingSkyLineArray* skylinegraph = graph->getGraph(); - const int* index = skylinegraph->getIndex(); - const int* value = skylinegraph->getValue(); - const int nbCells = skylinegraph->getNumberOf(); - - for ( int iGlob = 0; iGlob < nbCells; ++iGlob ) - { - int iGlobDom = part[ iGlob ]; - for ( int i = index[ iGlob ]; i < index[ iGlob+1 ]; i++ ) - { - int iGlobNear = value[ i ]; - if ( iGlob > iGlobNear ) - continue; // treat ( iGlob, iGlobNear ) pair once - int iGlobNearDom = part[ iGlobNear ]; - if ( iGlobDom != iGlobNearDom ) - { - int iLoc = convertGlobalCell( iGlob ).second - 1; // to MEDCoupling fmt - int iLocNear = convertGlobalCell( iGlobNear ).second - 1; - cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLoc ); - cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLocNear ); - cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLocNear ); - cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLoc ); - } - } - } - for ( int idomain = 0; idomain < nb_domain; ++idomain ) - { - for ( int idomainNear = 0; idomainNear < nb_domain; ++idomainNear ) - { - std::vector< int > & corresp = cellCorresp[ idomain ][ idomainNear ]; - if ( corresp.empty() ) - continue; - MEDPARTITIONER::ConnectZone* cz = new MEDPARTITIONER::ConnectZone(); - cz->setName( "Connect Zone defined by MEDPARTITIONER" ); - cz->setDistantDomainNumber( idomainNear ); - cz->setLocalDomainNumber ( idomain ); - cz->setEntityCorresp( 0,0, &corresp[0], corresp.size()/2 ); - _connect_zones.push_back( cz ); - } - } - } -} - -ParallelTopology::~ParallelTopology() -{ - for ( size_t i = 0; i < _connect_zones.size(); ++i ) - { - delete _connect_zones[i]; - _connect_zones[i] = 0; - } - _connect_zones.clear(); -} - -/*!Converts a list of global node numbers - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * only the first value is returned - * */ -void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int* ip) -{ - if (_node_glob_to_loc.empty()) - throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - for (int i=0; i< nbnode; i++) - { - std::pair<int,int> local_node = _node_glob_to_loc.find(node_list[i])->second; - ip[i]=local_node.first; - local[i]=local_node.second; - } -} - -/*!Converts a list of global node numbers on domain ip - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * only the value with domain ip is returned - * - * */ -void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int ip) -{ - if (_node_glob_to_loc.empty()) - throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - - for (int i=0; i< nbnode; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - int ipfound=(it->second).first; - if (ipfound==ip) - local[i]=(it->second).second; - } - } -} - -/*!Converts a list of global node numbers - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * all the values are put in the array - * */ -void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int nbnode, int*& local, int*& ip,int*& full_array, int& size) -{ - if (_node_glob_to_loc.empty()) - throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - - size=0; - for (int i=0; i< nbnode; i++) - { - int count= _node_glob_to_loc.count(node_list[i]); - size+=count; - } - int index=0; - ip=new int[size]; - local=new int[size]; - full_array=new int[size]; - for (int i=0; i< nbnode; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - ip[index]=(it->second).first; - local[index]=(it->second).second; - full_array [index]=node_list[i]; - index++; - } - - } -} - -/*!Converts a list of global face numbers - * to a distributed array with local face numbers. - * - * If a face in the list is represented on several domains, - * all the values are put in the array - * */ -void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size) -{ - size=0; - for (int i=0; i< nbface; i++) - { - //int count = _face_glob_to_loc.count(face_list[i]); - //if (count >1) MESSAGE_MED("face en doublon "<<face_list[i]); - size+= _face_glob_to_loc.count(face_list[i]); - } - int index=0; - ip=new int[size]; - local=new int[size]; - full_array=new int[size]; - for (int i=0; i< nbface; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - ip[index]=(it->second).first; - local[index]=(it->second).second; - full_array[index]=face_list[i]; - index++; - } - - } -} - -//!converts a list of global cell numbers -//!to a distributed array with local cell numbers -void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, int* local, int* ip) -{ - for (int i=0; i<nbcell; i++) - { - INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _glob_to_loc.find(cell_list[i]); - if (iter == _glob_to_loc.end()) - { - std::cerr << "proc " << MyGlobals::_Rank << " : KO cell_list[" << i << "] : " << cell_list[i] << std::endl; - throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalCellList : Cell not found"); - } - else - { - ip[i]=(iter->second).first; //no domain - local[i]=(iter->second).second; //no local cell - } - } -} - -/*!Converts a list of global face numbers - * to a distributed array with local face numbers - */ -void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int* ip) -{ - for (int i=0; i< nbface; i++) - { - INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _face_glob_to_loc.find(face_list[i]); - if (iter == _face_glob_to_loc.end()) - { - throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalFaceList : Face not found"); - } - ip[i]=(iter->second).first; - local[i]=(iter->second).second; - } -} - -/*!Converts a list of global node numbers on domain ip - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * only the value with domain ip is returned - * - */ -void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int ip) -{ - for (int i=0; i< nbface; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - int ipfound=(it->second).first; - if (ipfound==ip) - local[i]=(it->second).second; - - } - } -} - -//replacing a table of global numbering with a table with local numberings -// type_connectivity contains global connectivity for each type in input -// type_connectivity contains local connectivity for each type in output -void ParallelTopology::convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain) -{ - for (int inode=0; inode<nbnodes; inode++) - { - // cout <<" inode :"<<inode<< " global = "<<type_connectivity[type][inode]; - int global = nodes[inode]; - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(global); - for (mmiter it=range.first; it !=range.second; it++) - { - if ((it->second).first==idomain) - nodes[inode]=(it->second).second; - } - } -} - -/*! - * \brief Return max global face number - */ -int ParallelTopology::getMaxGlobalFace() const -{ - int max = 0; - TGlob2LocsMap::const_iterator g_l_l = _face_glob_to_loc.begin(); - for ( ; g_l_l != _face_glob_to_loc.end(); ++g_l_l ) - if ( g_l_l->first > max ) - max = g_l_l->first; - return max; -} - -int ParallelTopology::getNodeNumber() const -{ - if (_node_glob_to_loc.empty()) return 0; - std::set <int> keys; - for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _node_glob_to_loc.begin(); iter!=_node_glob_to_loc.end(); iter++) - { - keys.insert(iter->first); - } - return keys.size(); -} - -/*! - * retrieving list of nodes in global numbers - */ -void ParallelTopology::getNodeList(int idomain, int *list) const -{ - for (int i=0; i<_nb_nodes[idomain]; i++) - list[i]=_node_loc_to_glob[idomain][i]; -} - -/*! - * retrieving list of nodes in global numbers - */ -void ParallelTopology::getCellList(int idomain, int *list) const -{ - for (int i=0; i<_nb_cells[idomain];i++) - list[i]=_loc_to_glob[idomain][i]; -} - -int ParallelTopology::getFaceNumber() const -{ - if (_face_glob_to_loc.empty()) - return 0; - std::set <int> keys; - for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _face_glob_to_loc.begin(); iter!=_face_glob_to_loc.end(); iter++) - { - keys.insert(iter->first); - } - return keys.size(); -} - -/*! - * retrieving list of faces in global numbers - */ -void ParallelTopology::getFaceList(int idomain, int *list) const -{ - for (int i=0; i<_nb_faces[idomain];i++) - list[i]=_face_loc_to_glob[idomain][i]; -} - -int ParallelTopology::convertGlobalFace(int iglobal, int idomain) -{ - typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter; - std::pair<MMiter,MMiter> eq = _face_glob_to_loc.equal_range(iglobal); - for (MMiter it=eq.first; it != eq.second; it++) - if (it->second.first == idomain) - return it->second.second; - return -1; -} - -int ParallelTopology::convertGlobalNode(int iglobal, int idomain) -{ - typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter; - std::pair<MMiter,MMiter> eq = _node_glob_to_loc.equal_range(iglobal); - for (MMiter it=eq.first; it != eq.second; it++) - { - if (it->second.first == idomain) - return it->second.second; - } - return -1; -} - -std::vector<MEDPARTITIONER::ConnectZone*>& ParallelTopology::getCZ() -{ - return _connect_zones; -} - -/*! - * adding a face to the topology - */ -void ParallelTopology::appendFace(int idomain, int ilocal, int iglobal) -{ - _face_loc_to_glob[idomain].push_back(iglobal); - _face_glob_to_loc.insert(std::make_pair(iglobal,std::make_pair(idomain,ilocal))); -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx deleted file mode 100644 index f18723fb2..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_PARALLELTOPOLOGY_HXX__ -#define __MEDPARTITIONER_PARALLELTOPOLOGY_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Topology.hxx" - -#include "InterpKernelHashMap.hxx" - -#include <set> -#include <vector> - -namespace MEDPARTITIONER -{ - class Graph; - class MeshCollection; - class ParaDomainSelector; - - class MEDPARTITIONER_EXPORT ParallelTopology : public Topology - { - - public: - - ParallelTopology(); - ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&); - ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&, - const std::vector<MEDPARTITIONER::ConnectZone*>&, - std::vector<int*>&, - std::vector<int*>&, - std::vector<int*>&); - ParallelTopology(Graph* graph, Topology* oldTopology, int nbdomain, int mesh_dimension); - ~ParallelTopology(); - - void setGlobalNumerotationDefault(ParaDomainSelector* domainSelector); - - /*! converts a list of global cell numbers - * to a distributed array with local cell numbers - */ - void convertGlobalNodeList(const int*, int,int*,int*); - void convertGlobalNodeList(const int*, int,int*,int); - void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size); - - /*! converts a list of global node numbers - * to a distributed array with local cell numbers - */ - void convertGlobalCellList(const int*, int , int*, int *); - - /*! converts a list of global face numbers - * to a distributed array with local face numbers - */ - void convertGlobalFaceList(const int*, int , int*, int *); - void convertGlobalFaceList(const int*, int , int*, int); - void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size); - - /*! converting node global numberings to local numberings */ - void convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain); - - /*! converting node local numbering to global */ - int convertNodeToGlobal(int ip, int icell) const { return _node_loc_to_glob[ip][icell]; } - - /*! converting face local numbering to global */ - int convertFaceToGlobal(int ip, int iface) const { return _face_loc_to_glob[ip][iface]; } - - /*! converting cell global numbering to local */ - int convertCellToGlobal(int ip, int icell) const { return _loc_to_glob[ip][icell]; } - - void convertNodeToGlobal(int ip, const int* local, int n, int *global) const - { - for (int i=0; i<n; i++) - global[i]=_node_loc_to_glob[ip][local[i]]; - } - - void convertCellToGlobal(int ip, const int* local, int n, int *global) const - { - for (int i=0; i<n; i++) - global[i]=_loc_to_glob[ip][local[i]]; - } - - void convertFaceToGlobal(int ip, const int* local, int n, int *global) const - { - for (int i=0; i<n; i++) - global[i]=_face_loc_to_glob[ip][local[i]]; - } - - int nbDomain() const { return _nb_domain; } - - int nbCells() const { return _nb_total_cells; } - - int nbNodes() const { return _nb_total_nodes; } - - int nbCells( int idomain) const { return _nb_cells[idomain]; } - - /*! retrieving number of nodes */ - int getNodeNumber(int idomain) const { return _nb_nodes[idomain]; } - - int getNodeNumber() const; - - void getNodeList(int idomain, int* list) const; - - /*! retrieving cell numbers after merging in parallel mode */ - std::vector<int> & getFusedCellNumbers(int idomain) { return _cell_loc_to_glob_fuse[idomain]; } - - const std::vector<int>& getFusedCellNumbers(int idomain) const { return _cell_loc_to_glob_fuse[idomain]; } - - /*! retrieving face numbers after merging in parallel mode */ - std::vector<int> & getFusedFaceNumbers(int idomain) { return _face_loc_to_glob_fuse[idomain]; } - - const std::vector<int>& getFusedFaceNumbers(int idomain) const { return _face_loc_to_glob_fuse[idomain]; } - - /*! retrieving number of nodes */ - int getCellNumber(int idomain) const { return _nb_cells[idomain]; } - - int getCellDomainNumber(int global) const { return (_glob_to_loc.find(global)->second).first; } - - void getCellList(int idomain, int* list) const; - - int getFaceNumber(int idomain) const { return _nb_faces[idomain]; } - - int getFaceNumber() const; - - void getFaceList(int idomain, int* list) const; - - /*! converting a global cell number to a local representation (domain + local number) */ - std::pair<int,int> convertGlobalCell(int iglobal) const { return _glob_to_loc.find(iglobal)->second; } - - int convertGlobalFace(int iglobal, int idomain); - - int convertGlobalNode(int iglobal, int idomain); - - std::vector<MEDPARTITIONER::ConnectZone*>& getCZ(); - - //adding a face to the topology - void appendFace(int idomain, int ilocal, int iglobal); - - //return max global face number - int getMaxGlobalFace() const; - - private: - bool hasCellWithNodes( const MeshCollection&, int dom, const std::set<int>& nodes ); - - private: - //mapping global -> local - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2DomainLoc; - - TGlob2DomainLoc _glob_to_loc; - TGlob2DomainLoc _node_glob_to_loc; - - //mapping local -> global - std::vector<std::vector<int> > _loc_to_glob; - std::vector<std::vector <int> > _node_loc_to_glob; - - // global numbers in parallel mode - std::vector<std::vector <int> > _cell_loc_to_glob_fuse; // glob nums after merging - std::vector<std::vector <int> > _face_loc_to_glob_fuse; // glob nums after merging - - //mapping global -> local - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2LocsMap; - TGlob2LocsMap _face_glob_to_loc; - - //mapping local -> global - std::vector<std::vector <int> > _face_loc_to_glob; - std::vector<int> _nb_cells; - std::vector<int> _nb_nodes; - std::vector<int> _nb_faces; - int _nb_total_cells; - int _nb_total_nodes; - int _nb_total_faces; - int _nb_domain; - int _mesh_dimension; - - //links to connectzones - std::vector<MEDPARTITIONER::ConnectZone*> _connect_zones; - - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx deleted file mode 100644 index 1289291e1..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_ScotchGraph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <cstdio> - -#ifdef MED_ENABLE_SCOTCH -extern "C" -{ -#define restrict -#include "scotch.h" -} -#endif - -using namespace MEDPARTITIONER; - -SCOTCHGraph::SCOTCHGraph():Graph() -{ -} - -SCOTCHGraph::SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight):Graph(graph,edgeweight) -{ -} - -SCOTCHGraph::~SCOTCHGraph() -{ -} - -void SCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel) -{ - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : SCOTCHGraph::partGraph" << std::endl; - - //number of graph vertices - int n = _graph->getNumberOf(); - //graph - int * xadj=const_cast<int*>(_graph->getIndex()); - int * adjncy=const_cast<int*>(_graph->getValue()); - //ndomain - int nparts=ndomain; - -#if !defined(MED_ENABLE_SCOTCH) - throw INTERP_KERNEL::Exception("SCOTCHGraph::partGraph : SCOTCH is not available. Check your products, please."); -#else - //output parameters - int* partition = new int[n+1]; - - SCOTCH_Graph scotch_graph; - SCOTCH_graphInit(&scotch_graph); - SCOTCH_graphBuild(&scotch_graph, - 0, //base first indice 0 - n, //nb of graph nodes - xadj, - 0, - _cell_weight, //graph vertices loads - 0, - xadj[n], //number of edges - adjncy, - _edge_weight); - SCOTCH_Strat scotch_strategy; - SCOTCH_stratInit(&scotch_strategy); - - //!user-defined options for the strategy - if (options_string!="") - SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str()); - - if (nparts>1) - { - if (MyGlobals::_Verbose>10) std::cout << "SCOTCHGraph::graphPart SCOTCH_graphPart" << std::endl; - SCOTCH_graphPart(&scotch_graph,nparts,&scotch_strategy,partition); - } - else //partition for 1 subdomain - { - for (int i=0; i<n+1; i++) - partition[i]=0; - } - - SCOTCH_stratExit(&scotch_strategy); - SCOTCH_graphExit(&scotch_graph); - - std::vector<int> index(n+1); - std::vector<int> value(n); - index[0]=0; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - delete [] partition; - - //creating a skylinearray with no copy of the index and partition array - //the fifth argument true specifies that only the pointers are passed - //to the object - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); -#endif -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx deleted file mode 100644 index 96f5854b0..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_SCOTCHGRAPH_HXX__ -#define __MEDPARTITIONER_SCOTCHGRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT SCOTCHGraph : public Graph - { - public: - SCOTCHGraph(); - SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int* edgeweight=0); - virtual ~SCOTCHGraph(); - void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector* sel=0); - }; -} - -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx deleted file mode 100644 index 018388c62..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_TOPOLOGY_HXX__ -#define __MEDPARTITIONER_TOPOLOGY_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <map> -#include <vector> - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; -} - -namespace MEDPARTITIONER -{ - class Graph; - class ConnectZone; - class MeshCollection; - class MEDPARTITIONER_FaceModel; - - class MEDPARTITIONER_EXPORT Topology - { - public: - Topology() { } - Topology(std::vector<ParaMEDMEM::MEDCouplingUMesh*>, std::vector<MEDPARTITIONER::ConnectZone*>) { } - virtual ~Topology() { } - - /*! converts a list of global cell numbers - * to a distributed array with local cell numbers - */ - virtual void convertGlobalNodeList(const int *list, int nb, int *local, int*ip) = 0; - virtual void convertGlobalNodeList(const int *list, int nb, int *local, int ip) = 0; - //converts a list of global node numbers - /*! to a distributed array with local cell numbers */ - virtual void convertGlobalCellList(const int*list , int nb, int *local, int*ip) = 0; - - /*! converts a list of global face numbers - * to a distributed array with local face numbers - */ - virtual void convertGlobalFaceList(const int*list , int nb, int* local, int*ip) = 0; - virtual void convertGlobalFaceList(const int*list , int nb, int* local, int ip) = 0; - virtual void convertGlobalFaceListWithTwins(const int *face_list, int nbface, int*& local, int*& ip, int*& full_array, int& size) = 0; - virtual void convertGlobalNodeListWithTwins(const int *face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size) = 0; - /*! number of doamins */ - virtual int nbDomain() const = 0; - /*! number of cells */ - virtual int nbCells() const = 0; - /*! number of nodes */ - virtual int nbNodes() const = 0; - /*! number of cells on a specific domain */ - virtual int nbCells(int idomain) const = 0; - /*! converting node global numberings to local numberings */ - virtual void convertToLocal2ndVersion(int*,int,int) = 0; - virtual int convertNodeToGlobal(int ip,int icell) const = 0; - virtual int convertFaceToGlobal(int ip,int icell) const = 0; - virtual int convertCellToGlobal(int ip,int icell) const = 0; - virtual void convertNodeToGlobal(int ip,const int *local, int n, int *global) const = 0; - virtual void convertCellToGlobal(int ip,const int *local, int n, int *global) const = 0; - virtual void convertFaceToGlobal(int ip,const int *local, int n, int *global) const = 0; - /*! retrieving number of nodes */ - virtual int getNodeNumber(int idomain) const = 0; - virtual int getNodeNumber() const = 0; - /*! retrieving list of nodes */ - virtual void getNodeList(int idomain, int *list) const = 0; - virtual std::vector<int> & getFusedCellNumbers(int idomain) = 0; - virtual const std::vector<int> & getFusedCellNumbers(int idomain) const = 0; - virtual std::vector<int> & getFusedFaceNumbers(int idomain) = 0; - virtual const std::vector<int> & getFusedFaceNumbers(int idomain) const = 0; - /*! retrieving number of nodes */ - virtual int getCellNumber(int idomain) const = 0; - /*! retrieving list of nodes */ - virtual void getCellList(int idomain, int *list) const = 0; - /*! retrieving number of faces */ - virtual int getFaceNumber(int idomain) const = 0; - virtual int getFaceNumber() const = 0; - /*! retrieving list of nodes */ - virtual void getFaceList(int idomain, int *list) const = 0; - /*! adding a face to the mapping */ - virtual void appendFace(int idomain, int ilocal, int iglobal) = 0; - /*! returns max global face number */ - virtual int getMaxGlobalFace() const = 0; - /*! converting a global cell number to a local representation */ - virtual std::pair<int,int> convertGlobalCell(int iglobal) const = 0; - /*! converting a global face number to a local representation */ - virtual int convertGlobalFace(int iglobal, int idomain) = 0; - /*! converting a global node number to a local representation */ - virtual int convertGlobalNode(int iglobal, int idomain) = 0; - /*! getting a reference to connect zones vector */ - virtual std::vector<MEDPARTITIONER::ConnectZone*>& getCZ() = 0; - }; -} - -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx deleted file mode 100644 index 1d0808471..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_UserGraph.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <iostream> -#include <vector> - -using namespace MEDPARTITIONER; - -/*! constructor that allows to specify the desired partition - * \param partition as table giving the domain number for each cell - * (domain numbers range from 0 to ndomain-1 - * \param n number of cells in the mesh - */ -UserGraph::UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray *array, const int *partition, int n):Graph(array,0) -{ - - std::vector<int> index(n+1),value(n); - - index[0]=0; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); - -} - -UserGraph::~UserGraph() -{ -} - -void UserGraph::partGraph(int ndomain, const std::string& options, ParaDomainSelector* sel) -{ - std::cerr << "MEDPARTITIONER::UserGraph::partGraph() should not have to be used" << std::endl; -} - diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx deleted file mode 100644 index d6c5f6b5b..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_USERGRAPH_HXX__ -#define __MEDPARTITIONER_USERGRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT UserGraph : public Graph - { - public: - UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, const int*, int); - virtual ~UserGraph(); - void partGraph(int, const std::string& options=std::string(""), ParaDomainSelector *sel=0); - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx deleted file mode 100644 index 861da009d..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx +++ /dev/null @@ -1,880 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "CellModel.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "InterpKernelException.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> -#include <cstring> - -using namespace MEDPARTITIONER; - -int MEDPARTITIONER::MyGlobals::_Verbose=0; -int MEDPARTITIONER::MyGlobals::_Is0verbose=0; -int MEDPARTITIONER::MyGlobals::_Rank=-1; -int MEDPARTITIONER::MyGlobals::_World_Size=-1; -int MEDPARTITIONER::MyGlobals::_Randomize=0; -int MEDPARTITIONER::MyGlobals::_Atomize=0; -int MEDPARTITIONER::MyGlobals::_Creates_Boundary_Faces=0; -int MEDPARTITIONER::MyGlobals::_Create_Joints=0; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_File_Names; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_Mesh_Names; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_Field_Descriptions; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_General_Informations; - -std::string MEDPARTITIONER::Trim(const std::string& s,const std::string& drop) -{ - std::string r(s); - r.erase(r.find_last_not_of(drop)+1); - return r.erase(0,r.find_first_not_of(drop)); -} - -std::string MEDPARTITIONER::IntToStr(const int i) -{ - std::ostringstream oss; - oss << i; - return oss.str(); -} - -std::string MEDPARTITIONER::DoubleToStr(const double i) -{ - std::ostringstream oss; - oss << i; - return oss.str(); -} - -int MEDPARTITIONER::StrToInt(const std::string& s) -{ - int res; - std::istringstream iss(s); - iss >> res; - return res; -} - -double MEDPARTITIONER::StrToDouble(const std::string& s) -{ - double res; - std::istringstream iss(s); - iss >> res; - return res; -} - -bool MEDPARTITIONER::TestArg(const char *arg, const char *argExpected, std::string& argValue) -{ - argValue=""; - std::size_t i; - for (i=0; i<strlen(arg); i++) - { - if (arg[i]=='=') - break; - if (arg[i]!=argExpected[i]) - return false; - } - for (std::size_t j=i+1; j<strlen(arg); j++) - argValue+=arg[j]; - return true; -} - -std::vector<int> MEDPARTITIONER::CreateRandomSize(const int size) -{ - std::vector<int> res(size); - for (int i=0; i<size; i++) - res[i]=i; - //cvw TODO or not? srand( (unsigned)time( NULL ) ); - srand( MyGlobals::_Randomize ); - for (int i=0; i<size; i++) - { - int ii=rand()%size; - int tmp=res[ii]; - res[ii]=res[i]; - res[i]=tmp; - } - return res; -} - -/*! - * randomize a xadj and adjncy, renumbering vertices belong rand. Works only on one processor!!!! - */ -void MEDPARTITIONER::RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va) -{ - if (MyGlobals::_World_Size>1) - { - std::cerr << "MEDPARTITIONER::RandomizeAdj only works on one proc!" << std::endl; - return; - } - int size=ran.size(); - std::vector<int> invran(size); - for (int i=0; i<size; i++) - invran[ran[i]]=i; - vx.resize(size+1); - int lga=xadj[size]; - va.resize(lga); - int jj=0; - vx[0]=0; - for (int i=0; i<size; i++) - { - int ir=ran[i]; - int ii=xadj[ir]; - int lgj=xadj[ir+1]-ii; - for (int j=0; j<lgj; j++) - { - va[jj]=invran[adjncy[ii]]; - jj=jj+1; - ii=ii+1; - } - vx[i+1]=jj; - } -} - -void MEDPARTITIONER::TestRandomize() -{ - //int xadj[6]={0,2,5,9,12,13}; //for first debug only - //int adjncy[13]={1,4,0,2,4,1,3,4,2,4,4,3,4}; - int xadj[6]={0,2,5,9,12,13}; - int adjncy[13]={0,0,1,1,1,2,2,2,2,3,3,3,4}; - int size=5; - std::vector<int> r=CreateRandomSize(size); - std::vector<int> vx,va; - RandomizeAdj(&xadj[0],&adjncy[0],r,vx,va); -} - -std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec) -{ - if (vec.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - oss << " -> '" << *i << "'" << std::endl; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator) -{ - if (vec.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - oss << separator << *i; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprMapOfStringInt(const std::map<std::string,int>& mymap) -{ - if (mymap.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - oss << " -> [" << (*i).first << "]=" << (*i).second << std::endl; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) -{ - if (mymap.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - oss << " -> [" << (*i).first << "]=" << std::endl << ReprVectorOfString((*i).second) << std::endl; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprFieldDescriptions(const std::vector<std::string>& vec, const std::string separator) -{ - if (vec.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - oss << " ->"; - oss << ReprVectorOfString(DeserializeToVectorOfString(*i), separator) << std::endl; - } - return oss.str(); -} - -/*! - * a string "hello" gives a string " 5/hello/" - * serialized_FromVectorOfString_string+SerializeFromString("toto") is - * equivalent to vector<string>.push_back("toto") on serialized_FromVectorOfString_string - */ -std::string MEDPARTITIONER::SerializeFromString(const std::string& s) -{ - std::ostringstream oss; - oss << std::setw(5) << s.size() << "/" << s << "/"; - return oss.str(); -} - -/*! - * a vector of string gives a string - */ -std::string MEDPARTITIONER::SerializeFromVectorOfString(const std::vector<std::string>& vec) -{ - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - oss<< std::setw(5) << (*i).size() << "/" << *i << "/"; - return oss.str(); -} - -/*! - * a string gives a vector of string - */ -std::vector<std::string> MEDPARTITIONER::DeserializeToVectorOfString(const std::string& str) -{ - std::vector<std::string> res; - std::size_t pos=0; - std::size_t posmax=str.size(); - if (posmax==0) - return res; //empty vector - std::size_t length; - while (pos < posmax-6) //setw(5)+" " - { - std::istringstream iss(str.substr(pos,5)); - iss >> length; - if ((str[pos+5]!='/') || (str[pos+6+length]!='/')) - { - std::cerr << "Error on string '" << str << "'" << std::endl;; - throw INTERP_KERNEL::Exception("Error on string"); - } - res.push_back(str.substr(pos+6,length)); - pos=pos+6+length+1; - } - return res; -} - -std::string MEDPARTITIONER::EraseTagSerialized(const std::string& fromStr, const std::string& tag) -{ - std::vector<std::string> vec=DeserializeToVectorOfString(fromStr); - std::vector<std::string> res; - for (std::size_t i=0; i<vec.size(); i++) - { - if (vec[i].find(tag)==std::string::npos) - res.push_back(vec[i]); - } - return MEDPARTITIONER::SerializeFromVectorOfString(res); -} - -/*! - * elements first and second of map give one elements in result vector of string - * converting formatted the int second as firsts characters ending at first slash - */ -std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap) -{ - std::vector<std::string> res; - for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - { - std::ostringstream oss; - oss << (*i).second << "/" << (*i).first; - res.push_back(oss.str()); - } - return res; -} - -/* - * if existing identicals (first,second) in vector no problem, else Exception - */ -std::map<std::string,int> MEDPARTITIONER::DevectorizeToMapOfStringInt(const std::vector<std::string>& vec) -{ - std::map<std::string,int> res; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - std::size_t pos=0; - std::size_t posmax=(*i).size(); - std::size_t found=(*i).find('/'); //first slash - if ((found==std::string::npos) || (found<1)) - throw INTERP_KERNEL::Exception("Error aIntNumber/anyString is expected"); - int second; - std::istringstream iss((*i).substr(pos,found)); - iss >> second; - std::string first=(*i).substr(pos+found+1,posmax-found); - std::map<std::string,int>::iterator it=res.find(first); - if (it!=res.end()) - if ((*it).second!=second) - throw INTERP_KERNEL::Exception("Error not the same map value"); - res[first]=second; - } - return res; -} - -/*! - * elements first and second of map give one elements in result vector of string - * adding key map and length of second vector as first string in each serialized vector - * one serialized vector per key map - */ -std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) -{ - std::vector<std::string> res; - for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - { - std::vector<std::string> vs=(*i).second; //a vector of string; - std::ostringstream oss; - oss << "Keymap/" << (*i).first << "/" << (*i).second.size(); - vs.insert(vs.begin(), oss.str()); - res.push_back(SerializeFromVectorOfString(vs)); - } - return res; -} - -/*! - * if existing identicals keymap in vector no problem - * duplicates in second vector - */ -std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec) -{ - std::map< std::string,std::vector<std::string> > res; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - std::vector<std::string> vs=DeserializeToVectorOfString(*i); - - std::string enTete=vs[0]; - std::size_t posmax=enTete.size(); - std::size_t foundKey=enTete.find("Keymap/"); - std::size_t foundSizeVector=enTete.find_last_of('/'); - if ((foundKey==std::string::npos) || (foundKey!=0) || ((foundKey+7)>=foundSizeVector)) - throw INTERP_KERNEL::Exception("Error Keymap/anyString/aIntNumber is expected"); - int sizeVector; - std::istringstream iss(enTete.substr(foundSizeVector+1,posmax-foundSizeVector)); - iss >> sizeVector; - std::string keymap=enTete.substr(foundKey+7,foundSizeVector-foundKey-7); - for (int ii=1; ii<=sizeVector; ii++) - res[keymap].push_back(vs[ii]); //add unconditionnaly,so merge duplicates in second vector - } - return res; -} - -/*! - * shit for unique and unique_copy for the duplicate CONSECUTIVE elements - * I do not want to sort - */ -std::vector<std::string> MEDPARTITIONER::SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag) -{ - std::vector<std::string> res; - if (vec.size()==0) - return res; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - if ((*i).find(tag)!=std::string::npos) res.push_back(*i); - } - return res; -} - -/*! - * - */ -std::vector<std::string> MEDPARTITIONER::DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec) -{ - std::vector<std::string> res; - if (vec.size()==0) return res; - //shit for unique and unique_copy for the duplicate CONSECUTIVE elements - //I do not want to sort - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - bool found=false; - for (std::vector<std::string>::const_iterator j=res.begin(); j!=res.end(); ++j) - { - if ((*i).compare(*j)==0) - { - found=true; - break; - } - } - if (!found) res.push_back(*i); - } - return res; -} - -std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) -{ - std::map< std::string,std::vector<std::string> > res; - for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - res[(*i).first]=DeleteDuplicatesInVectorOfString((*i).second); - return res; -} - -//void MEDPARTITIONER::sendRecvVectorOfString(const std::vector<string>& vec, const int source, const int target) -//TODO -std::string MEDPARTITIONER::Cle1ToStr(const std::string& s, const int inew) -{ - std::ostringstream oss; - oss << s << " " << inew; - return oss.str(); -} - -void MEDPARTITIONER::Cle1ToData(const std::string& key, std::string& s, int& inew) -{ - std::size_t posmax=key.size(); - std::size_t found=key.find(' '); - if ((found==std::string::npos) || (found<1)) - throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt' is expected"); - s=key.substr(0,found); - std::istringstream iss(key.substr(found,posmax-found)); - iss >> inew; -} - -std::string MEDPARTITIONER::Cle2ToStr(const std::string& s, const int inew, const int iold) -{ - std::ostringstream oss; - oss << s << " " << inew << " " << iold; - return oss.str(); -} - -void MEDPARTITIONER::Cle2ToData(const std::string& key, std::string& s, int& inew, int& iold) -{ - std::size_t posmax=key.size(); - std::size_t found=key.find(' '); - if ((found==std::string::npos) || (found<1)) - throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt aInt' is expected"); - s=key.substr(0,found); - std::istringstream iss(key.substr(found,posmax-found)); - iss >> inew >> iold; -} - -std::string MEDPARTITIONER::ExtractFromDescription(const std::string& description,const std::string& tag) -{ - std::size_t found=description.find(tag); - if ((found==std::string::npos) || (found<1)) - { - std::cerr << "ERROR : not found '" << tag << "' in '"<< description << "'\n"; - throw INTERP_KERNEL::Exception("Error ExtractFromDescription"); - } - std::size_t beg=found; - std::size_t end=beg; - if (description[found-1]!='/') - { - //find without '/'... and pray looking for first whitespace - //something like 'idomain=0 fileName=tmp.med meshName=...' - end=description.size(); - beg+=tag.length(); - std::string res=description.substr(beg,end-beg); - found=res.find(' '); - if (found==std::string::npos) - found=res.length(); - res=res.substr(0,found); - return res; - } - std::size_t lg=StrToInt(description.substr(found-6,found)); - beg+=tag.length(); - return description.substr(beg,lg-tag.length()); -} - -void MEDPARTITIONER::FieldDescriptionToData(const std::string& description, - int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, int& typeField, int& DT, int& IT) -{ - idomain=StrToInt(ExtractFromDescription(description,"idomain=")); - fileName=ExtractFromDescription(description,"fileName="); - meshName=ExtractFromDescription(description,"meshName="); - fieldName=ExtractFromDescription(description,"fieldName="); - typeField=StrToInt(ExtractFromDescription(description,"typeField=")); - DT=StrToInt(ExtractFromDescription(description,"DT=")); - IT=StrToInt(ExtractFromDescription(description,"IT=")); -} - -void MEDPARTITIONER::FieldShortDescriptionToData(const std::string& description, - std::string& fieldName, int& typeField, int& entity, int& DT, int& IT) -{ - fieldName=ExtractFromDescription(description,"fieldName="); - typeField=StrToInt(ExtractFromDescription(description,"typeField=")); - entity=StrToInt(ExtractFromDescription(description,"entity=")); - DT=StrToInt(ExtractFromDescription(description,"DT=")); - IT=StrToInt(ExtractFromDescription(description,"IT=")); -} - -ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v) -{ - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - p->alloc(v.size(),1); - std::copy(v.begin(),v.end(),p->getPointer()); - return p; -} - -ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v,const int nbComponents) -{ - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - if (v.size()%nbComponents!=0) - throw INTERP_KERNEL::Exception("Problem size modulo nbComponents != 0"); - p->alloc(v.size()/nbComponents,nbComponents); - std::copy(v.begin(),v.end(),p->getPointer()); - return p; -} - -ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::CreateDataArrayDoubleFromVector(const std::vector<double>& v) -{ - ParaMEDMEM::DataArrayDouble* p=ParaMEDMEM::DataArrayDouble::New(); - p->alloc(v.size(),1); - std::copy(v.begin(),v.end(),p->getPointer()); - return p; -} - -/*! - */ -std::vector<std::string> MEDPARTITIONER::BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd) -{ - std::vector<std::string> res; - if (fd->getArray()) - { - int nb=fd->getArray()->getNumberOfComponents(); - res.push_back("nbComponents="); res.back()+=IntToStr(nb); - for (int i=0; i<nb; i++) - { - res.push_back("componentInfo"); - res.back()+=IntToStr(i)+"="+fd->getArray()->getInfoOnComponent(i); - } - } - else - { - res.push_back("nbComponents=0"); //unknown - } - return res; -} - -/*! - * quick almost human readable information on all fields in a .med file - */ -std::vector<std::string> MEDPARTITIONER::BrowseAllFields(const std::string& myfile) -{ - std::vector<std::string> res; - std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile); - - for (std::size_t i=0; i<meshNames.size(); i++) - { - std::vector<std::string> fieldNames= - MEDLoader::GetAllFieldNamesOnMesh(myfile,meshNames[i]); - for (std::size_t j = 0; j < fieldNames.size(); j++) - { - std::vector< ParaMEDMEM::TypeOfField > typeFields= - MEDLoader::GetTypesOfField(myfile, meshNames[i], fieldNames[j]); - for (std::size_t k = 0; k < typeFields.size(); k++) - { - std::vector< std::pair< int, int > > its= - MEDLoader::GetFieldIterations(typeFields[k], myfile, meshNames[i], fieldNames[j]); - if (MyGlobals::_Is0verbose>100) - std::cout<< "fieldName " << fieldNames[j] << " typeField " << typeFields[k] << " its.size() " << its.size() << std::endl; - for (std::size_t m = 0; m < its.size(); m++) - { - std::vector<std::string> resi; - resi.push_back("fileName="); resi.back()+=myfile; - resi.push_back("meshName="); resi.back()+=meshNames[i]; - resi.push_back("fieldName="); resi.back()+=fieldNames[j]; - resi.push_back("typeField="); resi.back()+=IntToStr((int)typeFields[k]); - resi.push_back("DT="); resi.back()+=IntToStr((int)its[m].first); - resi.push_back("IT="); resi.back()+=IntToStr((int)its[m].second); - res.push_back(SerializeFromVectorOfString(resi)); - } - } - } - } - return res; -} - -std::vector<std::string> MEDPARTITIONER::GetInfosOfField(const char *fileName, const char *meshName, const int idomain) -{ - const int lggeom=10; - const med_geometry_type GEOMTYPE[lggeom]={ //MED_N_CELL_FIXED_GEO] = { - //MED_POINT1, - //MED_SEG2, - //MED_SEG3, - //MED_SEG4, - //MED_TRIA3, - //MED_QUAD4, - //MED_TRIA6, - //MED_TRIA7, - //MED_QUAD8, - //MED_QUAD9, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_OCTA12, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_HEXA27, - //MED_POLYGON, - //MED_POLYHEDRON - }; - - const char * const GEOMTYPENAME[lggeom]={ - //"MED_POINT1", - //"MED_SEG2", - //"MED_SEG3", - //"MED_SEG4", - //"MED_TRIA3", - //"MED_QUAD4", - //"MED_TRIA6", - //"MED_TRIA7", - //"MED_QUAD8", - //"MED_QUAD9", - "MED_TETRA4", - "MED_PYRA5", - "MED_PENTA6", - "MED_HEXA8", - "MED_OCTA12", - "MED_TETRA10", - "MED_PYRA13", - "MED_PENTA15", - "MED_HEXA20", - "MED_HEXA27", - //"MED_POLYGONE", - //"MED_POLYEDRE", - }; - - - const int lgentity=3; - const med_entity_type ENTITYTYPE[lgentity]={ //MED_N_ENTITY_TYPES+2]={ - //MED_UNDEF_ENTITY_TYPE, - MED_CELL, - //MED_DESCENDING_FACE, - //MED_DESCENDING_EDGE, - MED_NODE, - MED_NODE_ELEMENT, - //MED_STRUCT_ELEMENT, - //MED_UNDEF_ENTITY_TYPE - }; - - const char * const ENTITYTYPENAME[lgentity]={ //MED_N_ENTITY_TYPES+2]={ - //"MED_UNDEF_ENTITY_TYPE", - "MED_CELL", - //"MED_FACE", - //"MED_ARETE", - "MED_NODE", - "MED_NODE_ELEMENT", - //"MED_STRUCT_ELEMENT", - //"MED_UNDEF_ENTITY_TYPE" - }; - - std::vector<std::string> res; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - if (MyGlobals::_Verbose>20) - std::cout << "on filename " << fileName << " nbOfField " << nbFields << std::endl; - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - for(int i=1; i<=nbFields; i++) - { - med_int ncomp=MEDfieldnComponent(fid,i); - INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - MEDfieldInfo(fid,i,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - for (int k=1; k<=nbPdt; k++) - { - MEDfieldComputingStepInfo(fid,nomcha,k,&numdt,&numo,&dt); - if (MyGlobals::_Verbose>20) - std::cout<< "on filename " << fileName << " field " << i << " fieldName " << curFieldName << " meshName " << curMeshName << - " typ " << typcha << " nbComponent " << ncomp << " nbPdt " << nbPdt << " noPdt " << k << - " ndt " << numdt << " nor " << numo << " dt " << dt << std::endl; - for (int ie=0; ie<lgentity; ie++) - { - for (int j=0; j<lggeom; j++) - { - int profilesize=0,nbi=0; - med_entity_type enttype=ENTITYTYPE[ie]; - //enttype=MED_NODE;enttype=MED_CELL;enttype=MED_NODE_ELEMENT; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - med_int nbofprofile=MEDfieldnProfile(fid,nomcha,numdt,numo,enttype,GEOMTYPE[j],pflname,locname); - int profileit=1; - if (enttype==MED_NODE) - { - med_geometry_type mygeomtype=MED_UNDEF_ENTITY_TYPE; - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit, - MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi); - if (nbOfVal>0) - { - if (MyGlobals::_Verbose>20) - std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " << - nbofprofile << " profile(s) for geomType (AUCUN) nbOfVal " << - nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl; - std::vector<std::string> resi; - resi.push_back("idomain="); resi.back()+=IntToStr(idomain); - resi.push_back("fileName="); resi.back()+=fileName; - resi.push_back("meshName="); resi.back()+=curMeshName; - resi.push_back("fieldName="); resi.back()+=curFieldName; - resi.push_back("typeField="); resi.back()+=IntToStr((int)ParaMEDMEM::ON_NODES); - resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha); //6 for double? - resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp); - resi.push_back("DT="); resi.back()+=IntToStr((int)numdt); - resi.push_back("IT="); resi.back()+=IntToStr((int)numo); - resi.push_back("time="); resi.back()+=DoubleToStr(dt); - resi.push_back("entity="); resi.back()+=IntToStr((int)enttype); - resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie]; - resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal); - resi.push_back("profilName="); resi.back()+=pflname; - resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize); - resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi); - res.push_back(SerializeFromVectorOfString(resi)); - } - break; //on nodes no need to scute all geomtype - } - else - { - med_geometry_type mygeomtype=GEOMTYPE[j]; - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit, - MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi); - if (nbOfVal>0) - { - if (MyGlobals::_Verbose>20) - std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " << - nbofprofile << " profile(s) for geomType " << - GEOMTYPE[j] << " " << GEOMTYPENAME[j] << " nbOfVal " << - nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl; - int typeField=-1; //unknown - if (enttype==MED_CELL) - typeField=ParaMEDMEM::ON_CELLS; - if (enttype==MED_NODE_ELEMENT) - typeField=ParaMEDMEM::ON_GAUSS_NE; - //if (enttype==??) typeField=ON_GAUSS_PT; - std::vector<std::string> resi; - resi.push_back("idomain="); resi.back()+=IntToStr(idomain); - resi.push_back("fileName="); resi.back()+=fileName; - resi.push_back("meshName="); resi.back()+=curMeshName; - resi.push_back("fieldName="); resi.back()+=curFieldName; - resi.push_back("typeField="); resi.back()+=IntToStr((int)typeField); - resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha); //6 for double? - resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp); - resi.push_back("DT="); resi.back()+=IntToStr((int)numdt); - resi.push_back("IT="); resi.back()+=IntToStr((int)numo); - resi.push_back("time="); resi.back()+=DoubleToStr(dt); - resi.push_back("entity="); resi.back()+=IntToStr((int)enttype); - resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie]; - resi.push_back("geomType="); resi.back()+=IntToStr((int)GEOMTYPE[j]); - resi.push_back("geomTypeName="); resi.back()+=GEOMTYPENAME[j]; - resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal); - resi.push_back("profilName="); resi.back()+=pflname; - resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize); - resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi); - if (typeField==(-1)) - { - std::cout << "WARNING : unknown typeField for entity type " << enttype << std::endl << - SerializeFromVectorOfString(resi) << std::endl; - continue; //do not register push_back - } - res.push_back(SerializeFromVectorOfString(resi)); - } - } - } - } - } - } - delete [] maa_ass; - delete [] nomcha; - MEDfileClose(fid); - if (MyGlobals::_Verbose>10) - std::cout << "detected fields:\n" << ReprVectorOfString(res) << std::endl; - return res; -} - -/*! - * quick almost human readable information on all fields on a mesh in a .med file - */ -std::vector<std::string> MEDPARTITIONER::BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain) -{ - std::vector<std::string> res=GetInfosOfField(myfile.c_str(),mymesh.c_str(),idomain); - return res; -} - -/*! - * create empty MEDCouplingUMesh* dim 3 - */ -ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::CreateEmptyMEDCouplingUMesh() -{ - ParaMEDMEM::MEDCouplingUMesh* umesh=ParaMEDMEM::MEDCouplingUMesh::New(); - umesh->setMeshDimension(3); - umesh->allocateCells(0); - umesh->finishInsertingCells(); - ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New(); - myCoords->alloc(0,3); - umesh->setCoords(myCoords); - umesh->setName("EMPTY"); - myCoords->decrRef(); - umesh->checkCoherency(); - return umesh; -} - -namespace MEDPARTITIONER -{ - BBTreeOfDim::BBTreeOfDim( int dim, - const double* bbs, - int* elems, - int level, - int nbelems, - double epsilon) - { - switch ( dim ) - { - case 3: - _tree=new BBTree<3> (bbs,elems,level,nbelems,epsilon); - _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 3 >; - _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 3 >; - break; - case 2: - _tree=new BBTree<2> (bbs,elems,level,nbelems,epsilon); - _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 2 >; - _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 2 >; - break; - case 1: - _tree=new BBTree<1> (bbs,elems,level,nbelems,epsilon); - _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 1 >; - _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 1 >; - break; - default: - _tree=0; - throw INTERP_KERNEL::Exception("BBTreeOfDim(): wrong space dimension"); - } - } - - BBTreeOfDim::~BBTreeOfDim() - { - delete (BBTree<3>*)_tree; - } - - void BBTreeOfDim::getElementsAroundPoint( const double* coordsPtr, - std::vector<int>& elems ) const - { - BBTreeOfDim* me = (BBTreeOfDim*) this; - (me->*_PgetElementsAroundPoint) ( coordsPtr, elems ); - } - void BBTreeOfDim::getIntersectingElems(const double* bb, - std::vector<int>& elems) const - { - BBTreeOfDim* me = (BBTreeOfDim*) this; - (me->*_PgetIntersectingElems) ( bb, elems ); - } -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx deleted file mode 100644 index 64fc0c2b9..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_UTILS_HXX__ -#define __MEDPARTITIONER_UTILS_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "BBTree.txx" - -#include <string> -#include <vector> -#include <map> - -//# define LOCALIZED(message) #message , __FILE__ , __FUNCTION__ , __LINE__ - -namespace MEDPARTITIONER -{ - MEDPARTITIONER_EXPORT std::string Trim(const std::string& s,const std::string& drop); - MEDPARTITIONER_EXPORT std::string IntToStr(const int i); - MEDPARTITIONER_EXPORT std::string DoubleToStr(const double i); - MEDPARTITIONER_EXPORT int StrToInt(const std::string& s); - MEDPARTITIONER_EXPORT double StrToDouble(const std::string& s); - MEDPARTITIONER_EXPORT bool TestArg(const char *arg, const char *argExpected, std::string& argValue); - MEDPARTITIONER_EXPORT std::vector<int> CreateRandomSize(const int size); - MEDPARTITIONER_EXPORT void RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va); - MEDPARTITIONER_EXPORT void TestRandomize(); - - MEDPARTITIONER_EXPORT std::string ReprVectorOfString(const std::vector<std::string>& vec); - MEDPARTITIONER_EXPORT std::string ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator); - MEDPARTITIONER_EXPORT std::string ReprMapOfStringInt(const std::map<std::string,int>& mymap); - MEDPARTITIONER_EXPORT std::string ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); - MEDPARTITIONER_EXPORT std::string ReprFieldDescriptions(const std::vector<std::string>& vec,const std::string separator); - - MEDPARTITIONER_EXPORT std::string SerializeFromString(const std::string& s); - MEDPARTITIONER_EXPORT std::string SerializeFromVectorOfString(const std::vector<std::string>& vec); - MEDPARTITIONER_EXPORT std::vector<std::string> DeserializeToVectorOfString(const std::string& str); - MEDPARTITIONER_EXPORT std::string EraseTagSerialized(const std::string& fromStr, const std::string& tag); - - MEDPARTITIONER_EXPORT std::vector<std::string> VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap); - MEDPARTITIONER_EXPORT std::map<std::string,int> DevectorizeToMapOfStringInt(const std::vector<std::string>& vec); - - MEDPARTITIONER_EXPORT std::vector<std::string> VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); - MEDPARTITIONER_EXPORT std::map< std::string,std::vector<std::string> > DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec); - - MEDPARTITIONER_EXPORT std::vector<std::string> SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag); - MEDPARTITIONER_EXPORT std::vector<std::string> DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec); - MEDPARTITIONER_EXPORT std::map< std::string,std::vector<std::string> > DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); - - MEDPARTITIONER_EXPORT std::string Cle1ToStr(const std::string& s, const int inew); - MEDPARTITIONER_EXPORT void Cle1ToData(const std::string& cle, std::string& s, int& inew); - - MEDPARTITIONER_EXPORT std::string Cle2ToStr(const std::string& s,const int inew,const int iold); - MEDPARTITIONER_EXPORT void Cle2ToData(const std::string& cle, std::string& s, int& inew, int& iold); - - MEDPARTITIONER_EXPORT std::string ExtractFromDescription(const std::string& description,const std::string& tag); - MEDPARTITIONER_EXPORT void FieldDescriptionToData(const std::string& description, - int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, - int& typeField, int& DT, int& IT); - MEDPARTITIONER_EXPORT void FieldShortDescriptionToData(const std::string& description, - std::string& fieldName, int& typeField, int& entity, int& DT, int& IT); - - ParaMEDMEM::DataArrayInt *CreateDataArrayIntFromVector(const std::vector<int>& v); - ParaMEDMEM::DataArrayInt *CreateDataArrayIntFromVector(const std::vector<int>& v, const int nbComponents); - ParaMEDMEM::DataArrayDouble *CreateDataArrayDoubleFromVector(const std::vector<double>& v); - - ParaMEDMEM::MEDCouplingUMesh *CreateEmptyMEDCouplingUMesh(); - - std::vector<std::string> BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd); - std::vector<std::string> BrowseAllFields(const std::string& myfile); - std::vector<std::string> BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain); - std::vector<std::string> GetInfosOfField(const char *fileName, const char *meshName, const int idomain ); - -#ifdef HAVE_MPI - //not adviced, interblocking, use sendAndReceive - //void SendVectorOfString(const std::vector<std::string>& vec, const int target); - //std::vector<std::string> RecvVectorOfString(const int source); - //TODO void sendRecvVectorOfString(const std::vector<std::string>& vec, const int source, const int target); - MEDPARTITIONER_EXPORT std::vector<std::string> SendAndReceiveVectorOfString(const std::vector<std::string>& vec, const int source, const int target); - MEDPARTITIONER_EXPORT std::vector<std::string> AllgathervVectorOfString(const std::vector<std::string>& vec); - - void SendDoubleVec(const std::vector<double>& vec, const int target); - std::vector<double> *RecvDoubleVec(const int source); - void RecvDoubleVec(std::vector<double>& vec, const int source); - - void SendIntVec(const std::vector<int>& vec, const int target); - std::vector<int>* RecvIntVec(int source); - void RecvIntVec(std::vector<int>& vec, const int source); - - void SendDataArrayInt(const ParaMEDMEM::DataArrayInt* da, const int target); - ParaMEDMEM::DataArrayInt *RecvDataArrayInt(const int source); - void SendDataArrayDouble(const ParaMEDMEM::DataArrayDouble* da, const int target); - ParaMEDMEM::DataArrayDouble *RecvDataArrayDouble(const int source); - - void TestVectorOfStringMpi(); - void TestMapOfStringIntMpi(); - void TestMapOfStringVectorOfStringMpi(); - void TestDataArrayMpi(); - void TestPersistantMpi0To1(int taille, int nb); - void TestPersistantMpiRing(int taille, int nb); - void TestPersistantMpiRingOnCommSplit(int taille, int nb); -#endif - - class MEDPARTITIONER_EXPORT MyGlobals - { - public : - static int _Verbose; //0 to 1000 over 200 is debug - static int _Rank; - static int _World_Size; - static int _Randomize; - static int _Atomize; - static int _Creates_Boundary_Faces; - static int _Create_Joints; - static int _Is0verbose; //trace cout if rank 0 and verbose - static std::vector<std::string> _File_Names; //on [iold] - static std::vector<std::string> _Mesh_Names; //on [iold] - static std::vector<std::string> _Field_Descriptions; - /*! used for descriptions of components of fields for example...*/ - static std::vector<std::string> _General_Informations; - }; - - - - /*! - * \brief Class encapsulating BBTree of dimension given at construction and - * providing all features of BBTree - */ - class BBTreeOfDim - { - void * _tree; - void (BBTreeOfDim::*_PgetElementsAroundPoint)( const double* coordsPtr, - std::vector<int>& elems ) const; - void (BBTreeOfDim::*_PgetIntersectingElems)( const double* bb, - std::vector<int>& elems ) const; - - template< int dim> - void _getElementsAroundPoint( const double* coordsPtr, - std::vector<int>& elems ) const - { - ((BBTree<dim,int>*)_tree)->getElementsAroundPoint( coordsPtr, elems ); - } - template< int dim> - void _getIntersectingElems(const double* bb, - std::vector<int>& elems) const - { - ((BBTree<dim,int>*)_tree)->getIntersectingElems( bb, elems ); - } - public: - - BBTreeOfDim( int dim, - const double* bbs, - int* elems, - int level, - int nbelems, - double epsilon=1e-12); - ~BBTreeOfDim(); - void getElementsAroundPoint(const double* coordsPtr, std::vector<int>& elems ) const; - void getIntersectingElems (const double* bb, std::vector<int>& elems) const; - }; -} -#endif diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx b/medtool/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx deleted file mode 100644 index 12b5d6cf5..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx +++ /dev/null @@ -1,732 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "CellModel.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "InterpKernelException.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace MEDPARTITIONER; - -/*! - * not optimized but suffisant - * return empty vector if i am not target - */ -std::vector<std::string> MEDPARTITIONER::SendAndReceiveVectorOfString(const std::vector<std::string>& vec, const int source, const int target) -{ - int rank=MyGlobals::_Rank; - - MPI_Status status; - int tag = 111001; - if (rank == source) - { - std::string str=SerializeFromVectorOfString(vec); - int size=str.length(); - MPI_Send( &size, 1, MPI_INT, target, tag, MPI_COMM_WORLD ); - MPI_Send( (void*)str.data(), str.length(), MPI_CHAR, target, tag+100, MPI_COMM_WORLD ); - } - - int recSize=0; - if (rank == target) - { - MPI_Recv(&recSize, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - std::string recData(recSize,'x'); - MPI_Recv((void*)recData.data(), recSize, MPI_CHAR, source, tag+100, MPI_COMM_WORLD, &status); - return DeserializeToVectorOfString(recData); //not empty one for target proc - } - std::vector<std::string> res; - return res; //empty one for other proc -} - -/*! - * strings NO need all same size!!!! - */ -std::vector<std::string> MEDPARTITIONER::AllgathervVectorOfString(const std::vector<std::string>& vec) -{ - if (MyGlobals::_World_Size==1) //nothing to do - return vec; - - int world_size=MyGlobals::_World_Size; - std::string str=SerializeFromVectorOfString(vec); - - std::vector<int> indexes(world_size); - int size=str.length(); - MPI_Allgather(&size, 1, MPI_INT, - &indexes[0], 1, MPI_INT, MPI_COMM_WORLD); - - //calcul of displacement - std::vector< int > disp(1,0); - for (int i=0; i<world_size; i++) disp.push_back( disp.back() + indexes[i] ); - - std::string recData(disp.back(),'x'); - MPI_Allgatherv((void*)str.data(), str.length(), MPI_CHAR, - (void*)recData.data(), &indexes[0], &disp[0], MPI_CHAR, - MPI_COMM_WORLD); - - //really extraordinary verbose for debug - std::vector<std::string> deserial=DeserializeToVectorOfString(recData); - if (MyGlobals::_Verbose>1000) - { - std::cout << "proc "<<MyGlobals::_Rank<<" : receive '" << recData << "'" << std::endl; - std::cout << "deserialize is : a vector of size " << deserial.size() << std::endl; - std::cout << ReprVectorOfString(deserial) << std::endl; - } - return deserial; -} - -/*! - Sends content of \a vec to processor \a target. To be used with \a RecvDoubleVec method. - \param vec vector to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendDoubleVec(const std::vector<double>& vec, const int target) -{ - int tag = 111002; - int size=vec.size(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendDoubleVec " << size << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 1, MPI_INT, target, tag, MPI_COMM_WORLD); - MPI_Send(const_cast<double*>(&vec[0]), size, MPI_DOUBLE, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill vector<int> vec. - To be used with \a SendDoubleVec method. - - \param vec vector that is filled - \param source processor id of the incoming messages -*/ -std::vector<double>* MEDPARTITIONER::RecvDoubleVec(const int source) -{ - int tag = 111002; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDoubleVec " << size << std::endl; - std::vector<double>* vec=new std::vector<double>; - vec->resize(size); - MPI_Recv(&vec[0], size, MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return vec; -} - -void MEDPARTITIONER::RecvDoubleVec(std::vector<double>& vec, const int source) -{ - int tag = 111002; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout<< "proc " << MyGlobals::_Rank << " : <-- RecvDoubleVec " << size << std::endl;; - vec.resize(size); - MPI_Recv(&vec[0], size, MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); -#endif -} -/*! - Sends content of \a vec to processor \a target. To be used with \a RecvIntVec method. - \param vec vector to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendIntVec(const std::vector<int>& vec, const int target) -{ - int tag = 111003; - int size=vec.size(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendIntVec " << size << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 1, MPI_INT, target, tag, MPI_COMM_WORLD); - MPI_Send(const_cast<int*>(&vec[0]), size,MPI_INT, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill vector<int> vec. - To be used with \a SendIntVec method. - \param vec vector that is filled - \param source processor id of the incoming messages -*/ -std::vector<int> *MEDPARTITIONER::RecvIntVec(const int source) -{ - int tag = 111003; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvIntVec " << size << std::endl; - std::vector<int> *vec=new std::vector<int>; - vec->resize(size); - MPI_Recv(&vec[0], size, MPI_INT, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return vec; -} - -void MEDPARTITIONER::RecvIntVec(std::vector<int>& vec, const int source) -{ - int tag = 111003; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvIntVec " << size << std::endl; - vec.resize(size); - MPI_Recv(&vec[0], size, MPI_INT, source, tag+100, MPI_COMM_WORLD,&status); -#endif -} - -/*! - Sends content of \a dataArrayInt to processor \a target. - To be used with \a RecvDataArrayInt method. - \param da dataArray to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendDataArrayInt(const ParaMEDMEM::DataArrayInt *da, const int target) -{ - if (da==0) - throw INTERP_KERNEL::Exception("Problem send DataArrayInt* NULL"); - int tag = 111004; - int size[3]; - size[0]=da->getNbOfElems(); - size[1]=da->getNumberOfTuples(); - size[2]=da->getNumberOfComponents(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendDataArrayInt " << size[0] << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 3, MPI_INT, target, tag, MPI_COMM_WORLD); - const int *p=da->getConstPointer(); - MPI_Send(const_cast<int*>(&p[0]), size[0] ,MPI_INT, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill dataArrayInt da. - To be used with \a SendIntVec method. - \param da dataArrayInt that is filled - \param source processor id of the incoming messages -*/ -ParaMEDMEM::DataArrayInt *MEDPARTITIONER::RecvDataArrayInt(const int source) -{ - int tag = 111004; - int size[3]; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(size, 3, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDataArrayInt " << size[0] << std::endl; - if (size[0]!=(size[1]*size[2])) - throw INTERP_KERNEL::Exception("Problem in RecvDataArrayInt incoherent sizes"); - ParaMEDMEM::DataArrayInt* da=ParaMEDMEM::DataArrayInt::New(); - da->alloc(size[1],size[2]); - int *p=da->getPointer(); - MPI_Recv(const_cast<int*>(&p[0]), size[0], MPI_INT, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return da; -} - -/*! - Sends content of \a dataArrayInt to processor \a target. - To be used with \a RecvDataArrayDouble method. - \param da dataArray to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendDataArrayDouble(const ParaMEDMEM::DataArrayDouble *da, const int target) -{ - if (da==0) - throw INTERP_KERNEL::Exception("Problem send DataArrayDouble* NULL"); - int tag = 111005; - int size[3]; - size[0]=da->getNbOfElems(); - size[1]=da->getNumberOfTuples(); - size[2]=da->getNumberOfComponents(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendDataArrayDouble " << size[0] << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 3, MPI_INT, target, tag, MPI_COMM_WORLD); - const double *p=da->getConstPointer(); - MPI_Send(const_cast<double*>(&p[0]), size[0] ,MPI_DOUBLE, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill dataArrayDouble da. - To be used with \a SendDoubleVec method. - \param da dataArrayDouble that is filled - \param source processor id of the incoming messages -*/ -ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::RecvDataArrayDouble(const int source) -{ - int tag = 111005; - int size[3]; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(size, 3, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDataArrayDouble " << size[0] << std::endl; - if (size[0]!=(size[1]*size[2])) - throw INTERP_KERNEL::Exception("Problem in RecvDataArrayDouble incoherent sizes"); - ParaMEDMEM::DataArrayDouble* da=ParaMEDMEM::DataArrayDouble::New(); - da->alloc(size[1],size[2]); - double *p=da->getPointer(); - MPI_Recv(const_cast<double*>(&p[0]), size[0], MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return da; -} - -void MEDPARTITIONER::TestVectorOfStringMpi() -{ - int rank=MyGlobals::_Rank; - int world_size=MyGlobals::_World_Size; - std::vector<std::string> myVector; - std::ostringstream oss; - oss << "hello from " << std::setw(5) << rank << " " << std::string(rank+1,'n') << - " next is an empty one"; - myVector.push_back(oss.str()); - myVector.push_back(""); - myVector.push_back("next is an singleton"); - myVector.push_back("1"); - - if (rank==0) - { - std::string s0=SerializeFromVectorOfString(myVector); - std::vector<std::string> res=DeserializeToVectorOfString(s0); - if (res.size()!=myVector.size()) - throw INTERP_KERNEL::Exception("Problem in (de)serialise VectorOfString incoherent sizes"); - for (std::size_t i=0; i<myVector.size(); i++) - if (res[i]!=myVector[i]) - throw INTERP_KERNEL::Exception("Problem in (de)serialise VectorOfString incoherent elements"); - } - - for (int i=0; i<world_size; i++) - { - for (int j=0; j<world_size; j++) - { - std::vector<std::string> res=SendAndReceiveVectorOfString(myVector, i, j); - if ((rank==j) && MyGlobals::_Verbose>20) - std::cout << "proc " << rank << " : receive \n" << ReprVectorOfString(res) << std::endl; - if (rank==j) - { - if (res.size()!=myVector.size()) - throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString incoherent sizes"); - for (std::size_t ii=1; ii<myVector.size(); ii++) //first is different - if (res[i]!=myVector[ii]) - throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString incoherent elements"); - } - else - { - if (res.size()!=0) - throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString size have to be 0"); - } - } - } - std::vector<std::string> res=AllgathervVectorOfString(myVector); - //sometimes for test - res=AllgathervVectorOfString(myVector); - res=AllgathervVectorOfString(myVector); - if (rank==0 && MyGlobals::_Verbose>20) - std::cout << "proc " << rank << " : receive \n" << ReprVectorOfString(res) << std::endl; - if (res.size()!=myVector.size()*world_size) - throw INTERP_KERNEL::Exception("Problem in AllgathervVectorOfString incoherent sizes"); - int jj=-1; - for (int j=0; j<world_size; j++) - { - for (int i=0; i<(int)myVector.size(); i++) - { - jj=jj+1; - if (i==0) - continue; //first is different - if (res[jj]!=myVector[i]) - throw INTERP_KERNEL::Exception("Problem in AllgathervVectorOfString incoherent elements"); - } - } - if (MyGlobals::_Verbose) - std::cout << "proc " << rank << " : OK TestVectorOfStringMpi END" << std::endl; -} - -void MEDPARTITIONER::TestMapOfStringIntMpi() -{ - int rank=MyGlobals::_Rank; - std::map<std::string,int> myMap; - myMap["one"]=1; - myMap["two"]=22; //a bug - myMap["three"]=3; - myMap["two"]=2; //last speaking override - - if (rank==0) - { - std::vector<std::string> v2=VectorizeFromMapOfStringInt(myMap); - std::map<std::string,int> m3=DevectorizeToMapOfStringInt(v2); - if (ReprMapOfStringInt(m3)!=ReprMapOfStringInt(myMap)) - throw INTERP_KERNEL::Exception("Problem in (de)vectorize MapOfStringInt"); - } - - std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringInt(myMap)); - if (rank==0 && MyGlobals::_Verbose>20) - { - std::cout << "v2 is : a vector of size " << v2.size() << std::endl; - std::cout << ReprVectorOfString(v2) << std::endl; - std::map<std::string,int> m2=DevectorizeToMapOfStringInt(v2); - std::cout << "m2 is : a map of size " << m2.size() << std::endl; - std::cout << ReprMapOfStringInt(m2) << std::endl; - } - if (MyGlobals::_Verbose) - std::cout << "proc " << rank << " : OK TestMapOfStringIntMpi END" << std::endl; -} - -void MEDPARTITIONER::TestMapOfStringVectorOfStringMpi() -{ - int rank=MyGlobals::_Rank; - std::vector<std::string> myVector; - std::ostringstream oss; - oss << "hello from " << std::setw(5) << MyGlobals::_Rank << " " << std::string(rank+1,'n') << " next is an empty one"; - myVector.push_back(oss.str()); - myVector.push_back(""); - myVector.push_back("next is an singleton"); - myVector.push_back("1"); - - if (rank==0) - { - std::map< std::string,std::vector<std::string> > m2; - m2["first key"]=myVector; - m2["second key"]=myVector; - std::vector<std::string> v2=VectorizeFromMapOfStringVectorOfString(m2); - std::map< std::string,std::vector<std::string> > m3=DevectorizeToMapOfStringVectorOfString(v2); - if (rank==0 && MyGlobals::_Verbose>20) - std::cout << "m2 is : a MapOfStringVectorOfString of size " << m2.size() << std::endl; - std::cout << ReprMapOfStringVectorOfString(m2) << std::endl; - std::cout << "v2 is : a vector of size " << v2.size() << std::endl; - std::cout << ReprVectorOfString(v2) << std::endl; - std::cout << "m3 is : a map of size "<<m3.size() << std::endl; - std::cout << ReprMapOfStringVectorOfString(m3) << std::endl; - if (ReprMapOfStringVectorOfString(m3)!=ReprMapOfStringVectorOfString(m2)) - throw INTERP_KERNEL::Exception("Problem in (de)vectorize MapOfStringVectorOfString"); - } - - std::map< std::string,std::vector<std::string> > m4; - m4["1rst key"]=myVector; - m4["2snd key"]=myVector; - std::vector<std::string> v4=AllgathervVectorOfString(VectorizeFromMapOfStringVectorOfString(m4)); - if (rank==0 && MyGlobals::_Verbose>20) - { - std::map< std::string,std::vector<std::string> > m5=DevectorizeToMapOfStringVectorOfString(v4); - std::map< std::string,std::vector<std::string> > m6=DeleteDuplicatesInMapOfStringVectorOfString(m5); - std::cout<< "m5 is : a map of size "<<m5.size() << std::endl; - std::cout<< ReprMapOfStringVectorOfString(m5) << std::endl; - std::cout<< "m6 is : a map from m5 with deleteDuplicates of size " << m6.size() << std::endl; - std::cout<< ReprMapOfStringVectorOfString(m6) << std::endl; - } - if (MyGlobals::_Verbose) - std::cout<<"proc " << rank << " : OK TestMapOfStringVectorOfStringMpi END" << std::endl; -} - -void MEDPARTITIONER::TestDataArrayMpi() -{ - int rank=MyGlobals::_Rank; - //int - { - ParaMEDMEM::DataArrayInt* send=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt* recv=0; - int nbOfTuples=5; - int numberOfComponents=3; - send->alloc(nbOfTuples,numberOfComponents); - std::vector<int> vals; - for (int j=0; j<nbOfTuples; j++) - for (int i=0; i<numberOfComponents; i++) vals.push_back((j+1)*10+i+1); - std::copy(vals.begin(),vals.end(),send->getPointer()); - if (rank==0) - SendDataArrayInt(send, 1); - if (rank==1) - recv=RecvDataArrayInt(0); - if (rank==1 && MyGlobals::_Verbose>20) - { - std::cout << send->repr() << std::endl; - std::cout << recv->repr() << std::endl; - } - if (rank==1) - { - if (send->repr()!=recv->repr()) - throw INTERP_KERNEL::Exception("Problem in send&recv DataArrayInt"); - } - send->decrRef(); - if (rank==1) - recv->decrRef(); - } - //double - { - ParaMEDMEM::DataArrayDouble* send=ParaMEDMEM::DataArrayDouble::New(); - ParaMEDMEM::DataArrayDouble* recv=0; - int nbOfTuples=5; - int numberOfComponents=3; - send->alloc(nbOfTuples,numberOfComponents); - std::vector<double> vals; - for (int j=0; j<nbOfTuples; j++) - for (int i=0; i<numberOfComponents; i++) vals.push_back(double(j+1)+double(i+1)/10); - std::copy(vals.begin(),vals.end(),send->getPointer()); - if (rank==0) SendDataArrayDouble(send, 1); - if (rank==1) recv=RecvDataArrayDouble(0); - if (rank==1 && MyGlobals::_Verbose>20) - { - std::cout << send->repr() << std::endl; - std::cout << recv->repr() << std::endl; - } - if (rank==1) - { - if (send->repr()!=recv->repr()) - throw INTERP_KERNEL::Exception("Problem in send&recv DataArrayDouble"); - } - send->decrRef(); - if (rank==1) recv->decrRef(); - } - - if (MyGlobals::_Verbose) - std::cout << "proc " << rank << " : OK TestDataArrayMpi END" << std::endl; -} - -void MEDPARTITIONER::TestPersistantMpi0To1(int taille, int nb) -{ - double temps_debut=MPI_Wtime(); - int rank=MyGlobals::_Rank; - std::vector<int> x, y; - int tag=111111; - MPI_Request requete0, requete1; - MPI_Status statut; - int ok=0; - std::string res; - if (rank==0) - { - x.resize(taille); - MPI_Ssend_init(&x[0], taille, MPI_INT, 1, tag, MPI_COMM_WORLD , &requete0); - for(int k=0; k<nb; k++) - { - for (int i=0; i<taille; ++i) x[i]=k; - //Envoi d’un gros message --> cela peut prendre du temps - MPI_Start(&requete0); - //Traitement sequentiel independant de "x" - //... - MPI_Wait(&requete0, &statut); - //Traitement sequentiel impliquant une modification de "x" en memoire - //x=... - } - MPI_Request_free(&requete0); - } - else if (rank == 1) - { - y.resize(taille); - MPI_Recv_init(&y[0], taille, MPI_INT, 0, tag, MPI_COMM_WORLD , &requete1); - for(int k=0; k<nb; k++) - { - //Pre-traitement sequentiel - //... - for (int i=0; i<taille; ++i) y[i]=(-1); - //Reception du gros message --> cela peut prendre du temps - MPI_Start(&requete1); - //Traitement sequentiel independant de "y" - //... - MPI_Wait(&requete1, &statut); - //Traitement sequentiel dependant de "y" - //...=f(y) - int nbb=0; - for (int i=0; i<taille; ++i) - if (y[i]==k) - nbb++; - if (nbb==taille) - ok++; - if (MyGlobals::_Verbose>9) - { - res="0K"; - if (nbb!=taille) - res="KO"; - std::cout << res << k << " "; - } - } - res="0K"; - if (ok!=nb) - res="BAD"; - if (MyGlobals::_Verbose>1) - std::cout << "result " << res << " time(sec) " << MPI_Wtime()-temps_debut << std::endl; - MPI_Request_free(&requete1); - } - //end_time=(MPI_WTIME()-start_time); -} - -void MEDPARTITIONER::TestPersistantMpiRing(int taille, int nb) -{ - double temps_debut=MPI_Wtime(); - int befo, next, rank, wsize, tagbefo, tagnext; - rank=MyGlobals::_Rank; - wsize=MyGlobals::_World_Size; - befo=rank-1; if (befo<0) befo=wsize-1; - next=rank+1; if (next>=wsize) next=0; - std::vector<int> x, y; - tagbefo=111111+befo; - tagnext=111111+rank; - MPI_Request requete0, requete1; - MPI_Status statut1, statut2; - int ok=0; - std::string res; - //cout<<"ini|"<<rank<<'|'<<befo<<'|'<<next<<' '; - { - x.resize(taille); - y.resize(taille); - MPI_Ssend_init(&x[0], taille, MPI_INT, next, tagnext, MPI_COMM_WORLD , &requete0); - MPI_Recv_init(&y[0], taille, MPI_INT, befo, tagbefo, MPI_COMM_WORLD , &requete1); - for(int k=0; k<nb; k++) - { - for (int i=0; i<taille; ++i) x[i]=k+rank; - //Envoi d’un gros message --> cela peut prendre du temps - MPI_Start(&requete0); - //Reception du gros message --> cela peut prendre du temps - for (int i=0; i<taille; ++i) y[i]=(-1); - MPI_Start(&requete1); - //Traitement sequentiel independant de "x" - //... - //Traitement sequentiel independant de "y" - //... - MPI_Wait(&requete1, &statut1); - //Traitement sequentiel dependant de "y" - //...=f(y) - int nbb=0; - for (int i=0; i<taille; ++i) - if (y[i]==k+befo) - nbb++; - if (nbb==taille) - ok++; - if (MyGlobals::_Verbose>9) - { - res="0K"+IntToStr(rank); - if (nbb!=taille) - res="KO"+IntToStr(rank); - std::cout << res << k << " "; - } - MPI_Wait(&requete0, &statut2); - //Traitement sequentiel impliquant une modification de "x" en memoire - //x=... - } - res="0K"; if (ok!=nb) res="MAUVAIS"; - temps_debut=MPI_Wtime()-temps_debut; - MPI_Request_free(&requete1); - MPI_Request_free(&requete0); - } - //end_time=(MPI_WTIME()-start_time); - if (MyGlobals::_Verbose>1) - std::cout << "result on proc " << rank << " " << res << " time(sec) " << temps_debut << std::endl; -} - -void MEDPARTITIONER::TestPersistantMpiRingOnCommSplit(int size, int nb) -{ - double temps_debut=MPI_Wtime(); - int rank=MyGlobals::_Rank; - MPI_Comm newcomm; - int color=1; - int rankMax=4; - if (rank>=rankMax) - color=MPI_UNDEFINED; - //MPI_Comm_dup (MPI_COMM_WORLD, &newcomm) ; - MPI_Comm_split(MPI_COMM_WORLD, color, rank, &newcomm); - - int befo, next, wsize, tagbefo, tagnext; - wsize=rankMax; - if (wsize>MyGlobals::_World_Size) - wsize=MyGlobals::_World_Size; - befo=rank-1; - if (befo<0) - befo=wsize-1; - next=rank+1; - if (next>=wsize) - next=0; - std::vector<int> x, y; - tagbefo=111111+befo; - tagnext=111111+rank; - MPI_Request requete0, requete1; - MPI_Status statut1, statut2; - int ok=0; - std::string res; - - if (color==1) - { - x.resize(size); - y.resize(size); - MPI_Ssend_init(&x[0], size, MPI_INT, next, tagnext, newcomm , &requete0); - MPI_Recv_init(&y[0], size, MPI_INT, befo, tagbefo, newcomm , &requete1); - for(int k=0; k<nb; k++) - { - for (int i=0; i<size; ++i) - x[i]=k+rank; - //Send of big message --> time consuming - MPI_Start(&requete0); - //Reception of big message --> time consuming - for (int i=0; i<size; ++i) - y[i]=-1; - MPI_Start(&requete1); - //Traitement sequentiel independant de "x" - //... - //Traitement sequentiel independant de "y" - //... - //cout<<"dsr|"<<rank<<' '; - MPI_Wait(&requete1, &statut1); - //Traitement sequentiel dependant de "y" - //...=f(y) - int nbb=0; - for (int i=0; i<size; ++i) - if (y[i]==k+befo) - nbb++; - if (nbb==size) - ok++; - if (MyGlobals::_Verbose>9) - { - res="0K"+IntToStr(rank); - if (nbb!=size) - res="KO"+IntToStr(rank); - std::cout << res << k << " "; - } - MPI_Wait(&requete0, &statut2); - //Traitement sequentiel impliquant une modification de "x" en memoire - //x=... - } - res="0K"; - if (ok!=nb) - res="MAUVAIS"; - temps_debut=MPI_Wtime()-temps_debut; - MPI_Request_free(&requete1); - MPI_Request_free(&requete0); - } - //MPI_Barrier(MPI_COMM_WORLD); - if (color==1) - MPI_Comm_free(&newcomm); - if (MyGlobals::_Verbose>1) - std::cout << "resultat proc " << rank <<" " << res << " time(sec) " << temps_debut << std::endl; -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.c b/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.c deleted file mode 100644 index 7967cab1c..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.c +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// Creation of this C code is forced by the following. -// -// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes -// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h -// that breaks compilation. To workaround this problem we create a wrapping C -// function, inclusion of whose declaration causes no problem. - -#include "MEDPARTITIONER_metis.h" - -#if defined(MED_ENABLE_METIS) & !defined(MED_ENABLE_PARMETIS) - #ifndef MED_ENABLE_METIS_V5 - #include "defs.h" - #endif // MED_ENABLE_METIS_V5 - #include "metis.h" - #ifdef MED_ENABLE_METIS_V5 - #define idxtype idx_t - #endif // MED_ENABLE_METIS_V5 -#else - typedef int idxtype; -#endif // defined(MED_ENABLE_METIS) & !defined(MED_ENABLE_PARMETIS) - -void MEDPARTITIONER_METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ -#if defined(MED_ENABLE_METIS) - #ifndef MED_ENABLE_METIS_V5 - METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, - adjwgt, wgtflag, numflag, nparts, - options, edgecut, part); - #else - int ncon=1; - options[METIS_OPTION_NCUTS]=1; - options[METIS_OPTION_NITER]=1; - options[METIS_OPTION_UFACTOR]=1; - METIS_PartGraphRecursive(nvtxs, &ncon, xadj, adjncy, vwgt, 0 /* vsize*/, - adjwgt, nparts,/* tpwgts*/ 0,/* ubvec */ 0, - options, edgecut, part); - #endif -#endif -} - -void MEDPARTITIONER_METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ -#if defined(MED_ENABLE_METIS) - #ifndef MED_ENABLE_METIS_V5 - METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, - adjwgt, wgtflag, numflag, nparts, - options, edgecut, part); - #else - int ncon=1; - options[METIS_OPTION_NCUTS]=1; - options[METIS_OPTION_NITER]=1; - options[METIS_OPTION_UFACTOR]=1; - METIS_PartGraphKway(nvtxs, &ncon, xadj, adjncy, vwgt, 0 /* vsize*/, - adjwgt, nparts, 0 , 0 /* ubvec */, - options, edgecut, part); - #endif -#endif -} diff --git a/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.h b/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.h deleted file mode 100644 index eadfd7d50..000000000 --- a/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// Creation of this C code is forced by the following. -// -// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes -// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h -// that breaks compilation. To workaround this problem we create a wrapping C -// function, inclusion of whose declaration causes no problem. - - -void MEDPARTITIONER_METIS_PartGraphRecursive(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); - -void MEDPARTITIONER_METIS_PartGraphKway(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); diff --git a/medtool/src/MEDPartitioner/Test/CMakeLists.txt b/medtool/src/MEDPartitioner/Test/CMakeLists.txt deleted file mode 100644 index 4a9aded6f..000000000 --- a/medtool/src/MEDPartitioner/Test/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_DEFINITIONS(${BOOST_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest # for BasicMainTest.hxx - ) - -SET(MEDPARTITIONERTest_HEADERS_HXX - MEDPARTITIONERTest.hxx - ) - -SET(MEDPARTITIONERTest_SOURCES - MEDPARTITIONERTest.cxx - ) - -SET(MEDPARTITIONERTest_LDFLAGS medpartitionercpp ${CPPUNIT_LIBRARIES}) - -IF(MEDCOUPLING_USE_MPI) - IF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) - SET(MEDPARTITIONERTest_SOURCES ${MEDPARTITIONERTest_SOURCES} MEDPARTITIONERTestPara.cxx) - ENDIF(MEDCOUPLING_MED_PARTITIONER_PARMETIS) -ENDIF(MEDCOUPLING_USE_MPI) - -ADD_LIBRARY(MEDPARTITIONERTest SHARED ${MEDPARTITIONERTest_SOURCES}) -TARGET_LINK_LIBRARIES(MEDPARTITIONERTest ${MEDPARTITIONERTest_LDFLAGS}) -INSTALL(TARGETS MEDPARTITIONERTest DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -ADD_EXECUTABLE(TestMEDPARTITIONER TestMEDPARTITIONER.cxx) -TARGET_LINK_LIBRARIES(TestMEDPARTITIONER MEDPARTITIONERTest) -INSTALL(TARGETS TestMEDPARTITIONER DESTINATION ${MEDCOUPLING_INSTALL_BINS}) - -INSTALL(FILES ${MEDPARTITIONERTest_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -ADD_TEST(TestMEDPARTITIONER TestMEDPARTITIONER) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner) -INSTALL(TARGETS MEDPARTITIONERTest TestMEDPARTITIONER DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/MEDPartitioner/Test/CTestTestfileInstall.cmake b/medtool/src/MEDPartitioner/Test/CTestTestfileInstall.cmake deleted file mode 100644 index 4605fa005..000000000 --- a/medtool/src/MEDPartitioner/Test/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(TestMEDPARTITIONER TestMEDPARTITIONER) -SET_TESTS_PROPERTIES(TestMEDPARTITIONER PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx b/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx deleted file mode 100644 index 242de7f99..000000000 --- a/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx +++ /dev/null @@ -1,1506 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONERTest.hxx" - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "CellModel.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <fstream> -#include <cmath> -#include <list> -#include <stdexcept> -#include <cstdlib> -#include <vector> -#include <unistd.h> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace std; -using namespace ParaMEDMEM; -using namespace MEDPARTITIONER; - -void MEDPARTITIONERTest::setSize(int ni, int nj, int nk) -{ - this->_ni=ni; //nb of hexa9 - this->_nj=nj; - this->_nk=nk; - this->_ntot=_ni*_nj*_nk; - string ijk=IntToStr(ni)+"x"+IntToStr(nj)+"x"+IntToStr(nk); - this->_file_name="tmp_testMesh_"+ijk+".med"; - this->_file_name_with_faces="tmp_testMeshWithFaces_"+ijk+".med"; - string ij=IntToStr(ni)+"x"+IntToStr(nj); - this->_file_name2="tmp_testMesh_"+ij+".med"; - this->_mesh_name="testMesh"; -} - -void MEDPARTITIONERTest::setSmallSize() -{ - setSize(2,3,5); //nb of hexa9 -} - -void MEDPARTITIONERTest::setMedianSize() -{ - setSize(20,30,50); //nb of hexa9 -} - -void MEDPARTITIONERTest::setbigSize() -{ - setSize(200,300,500); //nb of hexa9 -} - -std::string MEDPARTITIONERTest::getPartitionerExe() const -{ - std::string execName; - if ( getenv("MEDCOUPLING_ROOT_DIR") ) - { - execName=getenv("MEDCOUPLING_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/medpartitioner"; - } - else - { - execName = get_current_dir_name(); - execName += "/../../MEDPartitioner/medpartitioner"; - if (! std::ifstream(execName.c_str())) - CPPUNIT_FAIL("Can't find medpartitioner, please set MEDCOUPLING_ROOT_DIR"); - } - return execName; -} - -// ============================================================================ -/*! - * Set up the environment called at every CPPUNIT_TEST () - */ -// ============================================================================ -void MEDPARTITIONERTest::setUp() -{ - this->_verbose=0; -#if defined(HAVE_MPI) - if (MyGlobals::_Rank==-1) //do once only - { - MPI_Init(0,0); - MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size); - MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank); - } -#else - //sequential : no MPI - MyGlobals::_World_Size=1; - MyGlobals::_Rank=0; -#endif - - if (_verbose>10) - { -#if defined(HAVE_MPI) - cout<<"\ndefined(HAVE_MPI)"<<endl; -#else - cout<<"\nNOT defined(HAVE_MPI)"<<endl; -#endif -#if defined(MED_ENABLE_PARMETIS) - cout<<"defined(MED_ENABLE_PARMETIS)"<<endl; -#else - cout<<"NOT defined(MED_ENABLE_PARMETIS)"<<endl; -#endif -#if defined(MED_ENABLE_METIS) - cout<<"defined(MED_ENABLE_METIS)"<<endl; -#else - cout<<"NOT defined(MED_ENABLE_METIS)"<<endl; -#endif -#if defined(MED_ENABLE_SCOTCH) - cout<<"defined(MED_ENABLE_SCOTCH)"<<endl; -#else - cout<<"NOT defined(MED_ENABLE_SCOTCH)"<<endl; -#endif - } -} - -// ============================================================================ -/*! - * - delete - */ -// ============================================================================ -void MEDPARTITIONERTest::tearDown() -{ -} - -ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh() -//only hexa8 -{ - vector<int> conn; - vector<double> coor; - for (int k=0; k<=_nk; k++) - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - coor.push_back(i+.1); - coor.push_back(j+.2); - coor.push_back(k+.3); - } - int ii; - for (int k=0; k<_nk; k++) - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - - ii=i + j*(_ni+1) + (k+1)*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - - /* - if (_verbose) //only for debug - { - cout<< "\nnb coor " << (_ni+1)*(_nj+1)*(_nk+1)*3 << " " << coor.size() << endl; - for (int i=0; i<(int)coor.size(); i++) - cout << coor[i] << " "; - cout << endl; - cout << "\nnb conn " << (_ni)*(_nj)*(_nk)*8 << " " << conn.size() << endl; - for (int i=0; i<(int)conn.size(); i=i+8) - { - for (int j=0; j<8; j++) - cout << conn[i+j] << " "; - cout << endl; - } - cout << endl; - } - */ - - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(3); - int nbc=conn.size()/8; //nb of cells - int nbv=coor.size()/3; //nb of vertices - mesh->allocateCells(nbc); - for(int i=0; i<nbc; i++) - { - int onehexa[8]; - std::copy(conn.begin()+i*8,conn.begin()+(i+1)*8,onehexa); - if (false) //(_verbose) - { - for (int j=0; j<8; j++) cout<<onehexa[j]<<" "; - cout<<endl; - } - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,onehexa); - } - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbv,3); - std::copy(coor.begin(),coor.end(),myCoords->getPointer()); - mesh->setCoords(myCoords); - mesh->setName(_mesh_name.c_str()); - myCoords->decrRef(); - mesh->checkCoherency(); - return mesh; -} - -ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCARRE3DMesh() -//only quad4 in oblique (k=j) -{ - vector<int> conn; - vector<double> coor; - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - int k=j; - coor.push_back(i+.1); - coor.push_back(j+.2); - coor.push_back(k+.3); - } - int ii; - int k=0; - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - - if (false) //(_verbose) - { - cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl; - for (int i=0; i<(int)coor.size(); i++) - cout << coor[i] << " "; - cout<<endl; - cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl; - for (int i=0; i<(int)conn.size(); i=i+4) - { - for (int j=0; j<4; j++) cout<<conn[i+j]<<" "; - cout<<endl; - } - cout<<endl; - } - - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - int nbc=conn.size()/4; //nb of cells - int nbv=coor.size()/3; //nb of vertices - mesh->allocateCells(nbc); - for(int i=0; i<nbc; i++) - { - int onequa[4]; - std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa); - if (false) //(_verbose) - { - for (int j=0; j<4; j++) cout<<onequa[j]<<" "; - cout<<endl; - } - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa); - } - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbv,3); - std::copy(coor.begin(),coor.end(),myCoords->getPointer()); - mesh->setCoords(myCoords); - mesh->setName(_mesh_name.c_str()); - myCoords->decrRef(); - mesh->checkCoherency(); - return mesh; -} - -ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildFACE3DMesh() -//only quad4 on a global face of the CUBE3D (k=0) -{ - vector<int> conn; - vector<double> coor; - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - int k=0; - coor.push_back(i+.1); - coor.push_back(j+.2); - coor.push_back(k+.3); - } - int ii; - int k=0; - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - - if (false) //(_verbose) - { - cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl; - for (int i=0; i<(int)coor.size(); i++) - cout << coor[i] << " "; - cout<<endl; - cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl; - for (int i=0; i<(int)conn.size(); i=i+4) - { - for (int j=0; j<4; j++) - cout << conn[i+j] << " "; - cout << endl; - } - cout << endl; - } - - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - int nbc=conn.size()/4; //nb of cells - int nbv=coor.size()/3; //nb of vertices - mesh->allocateCells(nbc); - for(int i=0; i<nbc; i++) - { - int onequa[4]; - std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa); - if (false) //(_verbose) - { - for (int j=0; j<4; j++) cout<<onequa[j]<<" "; - cout<<endl; - } - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa); - } - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbv,3); - std::copy(coor.begin(),coor.end(),myCoords->getPointer()); - mesh->setCoords(myCoords); - mesh->setName(_mesh_name.c_str()); - myCoords->decrRef(); - mesh->checkCoherency(); - return mesh; -} - -MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnCells(string myfileName) -{ - //int ni=2,nj=3,nk=5; //nb of hexa9 - vector<double> field; - for (int k=0; k<_nk; k++) - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - field.push_back(i+.1); - field.push_back(j+.2); - field.push_back(k+.3); - } - - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(myfileName.c_str(),_mesh_name.c_str(),0); - int nbOfCells=mesh->getNumberOfCells(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("VectorFieldOnCells"); - f1->setDescription("DescriptionOfFieldOnCells"); //not saved in file? - f1->setMesh(mesh); - DataArrayDouble *myField=DataArrayDouble::New(); - myField->alloc(nbOfCells,3); - std::copy(field.begin(),field.end(),myField->getPointer()); - f1->setArray(myField); - myField->setInfoOnComponent(0,"vx"); - myField->setInfoOnComponent(1,"vy"); - myField->setInfoOnComponent(2,"vz"); - myField->decrRef(); - f1->setTime(2.,0,1); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - -MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnNodes() -{ - //int ni=2,nj=3,nk=5; //nb of hexa9 - vector<double> field; - for (int k=0; k<=_nk; k++) - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - field.push_back(i+.1); - field.push_back(j+.2); - field.push_back(k+.3); - } - - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),_mesh_name.c_str(),0); - int nbOfNodes=mesh->getNumberOfNodes(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("VectorFieldOnNodes"); - f1->setDescription("DescriptionOfFieldOnNodes"); //not saved in file? - f1->setMesh(mesh); - DataArrayDouble *myField=DataArrayDouble::New(); - myField->alloc(nbOfNodes,3); - std::copy(field.begin(),field.end(),myField->getPointer()); - f1->setArray(myField); - myField->setInfoOnComponent(0,"vx"); - myField->setInfoOnComponent(1,"vy"); - myField->setInfoOnComponent(2,"vz"); - myField->decrRef(); - f1->setTime(2.,0,1); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - - -void MEDPARTITIONERTest::createTestMeshWithoutField() -{ - { - MEDCouplingUMesh * mesh = buildCUBE3DMesh(); - MEDLoader::WriteUMesh(_file_name.c_str(),mesh,true); - if (_verbose) cout<<endl<<_file_name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),mesh->getName().c_str(),0); - if (_verbose) cout<<_file_name<<" reread"<<endl; - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - } - mesh->decrRef(); - } - - { - vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes; - MEDCouplingUMesh * mesh1 = buildCUBE3DMesh(); - MEDCouplingUMesh * mesh2 = buildFACE3DMesh(); - mesh1->setName("testMesh"); - mesh2->setName("theFaces"); - mesh2->tryToShareSameCoordsPermute(*mesh1, 1e-9); - mesh2->checkCoherency(); - mesh1->checkCoherency(); - meshes.push_back(mesh1); - meshes.push_back(mesh2); - MEDLoader::WriteUMeshes(_file_name_with_faces.c_str(), meshes, true); - - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName().c_str()); - DataArrayInt* FacesFam=DataArrayInt::New(); - FacesFam->alloc(mfm->getSizeAtLevel(-1),1); - FacesFam->fillWithValue(-1); - DataArrayInt* CellsFam=DataArrayInt::New(); - CellsFam->alloc(mfm->getSizeAtLevel(0),1); - CellsFam->fillWithValue(1); - mfm->setFamilyFieldArr(-1,FacesFam); - mfm->setFamilyFieldArr(0,CellsFam); - map<string,int> theFamilies; - theFamilies["FAMILLE_ZERO"]=0; - theFamilies["FamilyFaces"]=-1; - theFamilies["FamilyCells"]=1; - map<string, vector<string> > theGroups; - theGroups["GroupFaces"].push_back("FamilyFaces"); - theGroups["GroupCells"].push_back("FamilyCells"); - mfm->setFamilyInfo(theFamilies); - mfm->setGroupInfo(theGroups); - mfm->write(_file_name_with_faces.c_str(),0); - FacesFam->decrRef(); - CellsFam->decrRef(); - - /*ce truc marche pas! - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName()); - vector<const ParaMEDMEM::MEDCouplingUMesh*> ms; - ms.push_back(mesh2); - mfm->setGroupsFromScratch(-1, ms); - mfm->write(_file_name_with_faces.c_str(),0); - */ - - if (_verbose) cout<<endl<<_file_name_with_faces<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name_with_faces.c_str(),mesh1->getName().c_str(),0); - if (_verbose) cout<<_file_name_with_faces<<" reread"<<endl; - CPPUNIT_ASSERT(mesh1->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - } - mesh1->decrRef(); - mesh2->decrRef(); - mfm->decrRef(); - } - - { - MEDCouplingUMesh * mesh = buildCARRE3DMesh(); - MEDLoader::WriteUMesh(_file_name2.c_str(),mesh,true); - if (_verbose) cout<<endl<<_file_name2<<" created"<<endl; - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name2.c_str(),mesh->getName().c_str(),0); - if (_verbose) cout<<_file_name2<<" reread"<<endl; - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); - } -} - -/* -create a set of nbx*nby*nbz files mesh of ni*ny*nz cells -*/ -void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget) -{ - setSize(ni,nj,nk); - _nb_target_huge=nbTarget; - MEDCouplingUMesh * mesh = buildCUBE3DMesh(); - //int nbx=1, nby=1, nbz=2; - std::vector< double > cooDep,cooFin; - mesh->getCoordinatesOfNode(0, cooDep); - mesh->getCoordinatesOfNode(mesh->getNumberOfNodes()-1, cooFin); - //cout<<endl<<cooDep[0]<<" "<<cooDep[1]<<" "<<cooDep[2]<<endl; - //cout<<cooFin[0]<<" "<<cooFin[1]<<" "<<cooFin[2]<<endl; - - string tagXml="\ -<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \ -<root>\n \ - <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \ - <description what=\"\" when=\"YYMMDDHHmm\"/>\n \ - <content>\n \ - <mesh name=\"testMesh\"/>\n \ - </content>\n \ - <splitting>\n \ - <subdomain number=\"$subdomainNumber\"/>\n \ - <global_numbering present=\"no\"/>\n \ - </splitting>\n \ - <files>\n$tagSubfile \ - </files>\n \ - <mapping>\n$tagMesh \ - </mapping>\n \ -</root>\n"; - - string tagSubfiles, tagSubfile="\ - <subfile id=\"$xyz\">\n \ - <name>$fileName</name>\n \ - <machine>localhost</machine>\n \ - </subfile>\n"; - string tagMeshes, tagMesh="\ - <mesh name=\"testMesh\">\n \ - <chunk subdomain=\"$xyz\">\n \ - <name>testMesh</name>\n \ - </chunk>\n \ - </mesh>\n"; - - int xyz=1; - string sxyz; - DataArrayDouble* coordsInit=mesh->getCoords()->deepCpy(); - double* ptrInit=coordsInit->getPointer(); - double deltax=cooFin[0]-cooDep[0]; - double deltay=cooFin[1]-cooDep[1]; - double deltaz=cooFin[2]-cooDep[2]; - - double dz=0.; - for (int z=0; z<nbz; z++) - { - double dy=0.; - for (int y=0; y<nby; y++) - { - double dx=0.; - for (int x=0; x<nbx; x++) - { - string fileName; - sxyz=IntToStr(xyz); - fileName="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".med"; - - DataArrayDouble* coords=mesh->getCoords(); - //int nbOfComp=coords->getNumberOfComponents(); //be 3D - int nbOfTuple=coords->getNumberOfTuples(); - double* ptr=coords->getPointer(); - double* ptrini=ptrInit; - for (int i=0; i<nbOfTuple; i++) - { - *ptr=(*ptrini)+dx; ptr++; ptrini++; //be 3D - *ptr=(*ptrini)+dy; ptr++; ptrini++; - *ptr=(*ptrini)+dz; ptr++; ptrini++; - } - - MEDLoader::WriteUMesh(fileName.c_str(),mesh,true); - - tagSubfiles+=tagSubfile; - tagSubfiles.replace(tagSubfiles.find("$xyz"),4,sxyz); - tagSubfiles.replace(tagSubfiles.find("$fileName"),9,fileName); - - tagMeshes+=tagMesh; - tagMeshes.replace(tagMeshes.find("$xyz"),4,sxyz); - xyz++; - dx+=deltax; - } - dy+=deltay; - } - dz+=deltaz; - } - coordsInit->decrRef(); - - tagXml.replace(tagXml.find("$subdomainNumber"),16,sxyz); - tagXml.replace(tagXml.find("$tagSubfile"),11,tagSubfiles); - tagXml.replace(tagXml.find("$tagMesh"),8,tagMeshes); - - string nameFileXml; - _file_name_huge_xml="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".xml"; - std::ofstream f(_file_name_huge_xml.c_str()); - f<<tagXml; - f.close(); - //cout<<"\n"<<tagXml<<endl; - if (_verbose) - cout<<endl<<nameFileXml<<" created"<<endl; - mesh->decrRef(); -} - -void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells() -{ - { - string name=_file_name; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); - name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med"); - MEDLoader::WriteField(name.c_str(),f1,true); - f1->setTime(3.,1,1); //time,it,order - f1->applyFunc("x/2."); - MEDLoader::WriteField(name.c_str(),f1,false); - if (_verbose) cout<<endl<<name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - //DataArrayDouble *res=f2->getArray(); - if (_verbose) cout<<name<<" reread"<<endl; - //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - } - f1->decrRef(); - } - { - string name=_file_name; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); - name.replace(name.find(".med"),4,"_WithVecFieldOnGaussNe.med"); - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); - f3->setMesh(f1->getMesh()); - //cout<<"\nNumberOfMeshPlacesExpected "<<f3->getNumberOfMeshPlacesExpected()<<" " - // /*<<getNumberOfTuples(f1->getMesh())<<" "*/ - // <<f3->getMesh()->getNumberOfNodes()<<" " - // <<f3->getMesh()->getNumberOfCells()<<endl; - f3->setName("MyFieldOnGaussNE"); - f3->setDescription("MyDescriptionNE"); - DataArrayDouble *array=DataArrayDouble::New(); - //int nb=f1->getMesh()->getNumberOfNodes(); - - /*8 pt de gauss by cell - int nb=f3->getMesh()->getNumberOfCells()*8; - array->alloc(nb,2); - double *ptr=array->getPointer(); - for (int i=0; i<nb*2; i=i+2) {ptr[i]=(double)(i/8) ; ptr[i]=2.*(double)(i/8);} - */ - - //more nbptgauss=8 by default needs set MEDCouplingFieldDiscretizationPerCell - //theory: (may be) http://www.code-aster.org/V2/doc/v9/fr/man_r/r3/r3.06.03.pdf - int nbptgauss=8; //nb pt de gauss by cell - int nbcell=f3->getMesh()->getNumberOfCells(); - int nb=nbcell*nbptgauss; - int nbcomp=2; - array->alloc(nb,nbcomp); - double *ptr=array->getPointer(); - int ii=0; - for (int i=0; i<nbcell; i++) - for (int j=0; j<nbptgauss; j++) - for (int k=0; k<nbcomp; k++) - { - //123.4 for 12th cell,3rd component, 4th gausspoint - ptr[ii]=(double)((i+1)*10+(k+1))+((double)(j+1))/10.; - ii++; - } - array->setInfoOnComponent(0,"vGx"); - array->setInfoOnComponent(1,"vGy"); - f3->setTime(4.,5,6); - f3->setArray(array); - array->decrRef(); - MEDLoader::WriteField(name.c_str(),f3,true); - if (_verbose) cout<<endl<<name<<" created"<<endl; - f3->checkCoherency(); - f1->decrRef(); - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble* f4=MEDLoader::ReadField(ON_GAUSS_NE, - name.c_str(), f3->getMesh()->getName().c_str(), 0, "MyFieldOnGaussNE", 5, 6); - if (_verbose) cout<<"MyFieldOnGaussNE reread"<<endl; - f4->decrRef(); - } - f3->decrRef(); - } - { - string name=_file_name_with_faces; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); - name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med"); - MEDLoader::WriteField(name.c_str(),f1,true); - if (_verbose) cout<<endl<<name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - if (_verbose) cout<<name<<" reread"<<endl; - //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!! - f2->decrRef(); - } - f1->decrRef(); - } -} - -void MEDPARTITIONERTest::createTestMeshWithVecFieldOnNodes() -{ - MEDCouplingFieldDouble *f1=buildVecFieldOnNodes(); - string name=_file_name; - name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med"); - MEDLoader::WriteField(name.c_str(),f1,true); - if (_verbose) cout<<endl<<name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - if (_verbose) cout<<name<<" reread"<<endl; - //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!! - f2->decrRef(); - } - f1->decrRef(); -} - -void MEDPARTITIONERTest::verifyTestMeshWithVecFieldOnNodes() -{ - string name=_file_name; - name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med"); - MEDCouplingUMesh * m=MEDLoader::ReadUMeshFromFile(name.c_str(),_mesh_name.c_str(),0); - std::set<INTERP_KERNEL::NormalizedCellType> types(m->getAllGeoTypes()); - if (_verbose) - { - cout<<"\n types in "<<name<<" : "; - //for (std::set<INTERP_KERNEL::NormalizedCellType>::iterator t=types.begin(); t!=types.end(); ++t) cout<<" "<<*t; - for (std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator t=types.begin(); t!=types.end(); ++t) - { - //INTERP_KERNEL::CellModel essai=INTERP_KERNEL::CellModel::GetCellModel(*t); - cout<<" "<<(INTERP_KERNEL::CellModel::GetCellModel(*t)).getRepr(); - } - cout<<endl; - } - m->decrRef(); - - MEDFileUMesh * mf = MEDFileUMesh::New(_file_name.c_str(),_mesh_name.c_str(),-1,-1); - vector<int> lev; - lev=mf->getNonEmptyLevels(); - if (_verbose) - { - cout<<" levels in "<<name<<" : "; - for (vector<int>::iterator l=lev.begin(); l!=lev.end(); ++l) cout<<" "<<*l; - cout<<endl; - } - mf->decrRef(); -} - -void MEDPARTITIONERTest::createTestMeshes() -{ - createTestMeshWithoutField(); - createTestMeshWithVecFieldOnCells(); - createTestMeshWithVecFieldOnNodes(); -} - -void MEDPARTITIONERTest::deleteTestMeshes() -{ - string cmd="rm *tmp_testMesh*"; - if (_verbose) cout<<endl<<cmd<<endl; - system(cmd.c_str()); //may be not if debug -} - -void MEDPARTITIONERTest::testMeshCollectionSingle() -{ - setSmallSize(); - createTestMeshes(); - MyGlobals::_World_Size=1; - MyGlobals::_Rank=0; - string fileName=_file_name_with_faces; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - CPPUNIT_ASSERT(collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - CPPUNIT_ASSERT(collection.getName()=="testMesh"); - CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk,collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(_ni*_nj,collection.getNbOfLocalFaces()); -} - -void MEDPARTITIONERTest::testMeshCollectionXml() -{ - setSmallSize(); - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml but not so huge - string fileName=_file_name_huge_xml; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - CPPUNIT_ASSERT(collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - CPPUNIT_ASSERT(collection.getName()=="testMesh"); - CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk*8,collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); -} - - -//#################for metis - - - -#if defined(MED_ENABLE_METIS) -void MEDPARTITIONERTest::testMeshCollectionSinglePartitionMetis() -{ - setSmallSize(); - createTestMeshes(); - //MyGlobals::_Verbose=500; - string fileName=_file_name_with_faces; - int ndomains=2; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - //example to create files - //MyGlobals::_General_Informations.clear(); - //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge")); - //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations); - //new_collection.write("ttmp") - - CPPUNIT_ASSERT(new_collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension()); - CPPUNIT_ASSERT(new_collection.getName()==collection.getName()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); -} - -void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis() -{ - setSmallSize(); - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge - string fileName=_file_name_huge_xml; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - - for (int ndomains=2 ; ndomains<=16 ; ndomains++) - { - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); - } -} - -void MEDPARTITIONERTest::testMetisSmallSize() -{ - //#if !defined(HAVE_MPI) - setSmallSize(); - createTestMeshes(); - std::string MetisOrScotch("metis"); - launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); - //#endif -} -#endif - - -//#################for scotch - - -#if defined(MED_ENABLE_SCOTCH) -void MEDPARTITIONERTest::testMeshCollectionSinglePartitionScotch() -{ - setSmallSize(); - createTestMeshes(); - //MyGlobals::_Verbose=500; - string fileName=_file_name_with_faces; - int ndomains=2; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - //example to create files - //MyGlobals::_General_Informations.clear(); - //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge")); - //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations); - //new_collection.write("ttmp") - - CPPUNIT_ASSERT(new_collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension()); - CPPUNIT_ASSERT(new_collection.getName()==collection.getName()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); -} - -void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch() -{ - setSmallSize(); - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge - string fileName=_file_name_huge_xml; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - - for (int ndomains=2 ; ndomains<=16 ; ndomains++) - { - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); - } -} - -void MEDPARTITIONERTest::testScotchSmallSize() -{ - //#if !defined(HAVE_MPI) - setSmallSize(); - createTestMeshes(); - std::string MetisOrScotch("scotch"); - launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); - //#endif -} -#endif - -void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch) -{ - int res; - string cmd,execName,sourceName,targetName; - - execName=getPartitionerExe(); - - cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(execName + " - INVALID PATH TO medpartitioner", 0, res); - - cmd=execName+" --ndomains=2 --split-method="+MetisOrScotch; //on same proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo2_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on less proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on 1 proc - sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on more proc - //sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); -} - -void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch) -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerExe(); - fileName=_file_name_with_faces; - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size()); - int nbcells=0; - for (std::size_t i = 0; i < cellMeshes.size(); i++) - nbcells+=cellMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - - std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size()); - int nbfaces=0; - for (std::size_t i=0; i < faceMeshes.size(); i++) - nbfaces+=faceMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces); - - //merge split meshes and test equality - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells()); - - /*not the good job - ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells()); - - ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells()); - - CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12)); - */ - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - meshes.resize(0); - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - corr.resize(0); - meshes.push_back(faceMesh); - refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9); - meshes.push_back(refusedFaceMesh); - MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells()); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - fusedFace->decrRef(); - refusedFaceMesh->decrRef(); - faceMesh->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - refusedMesh->decrRef(); - cellMesh->decrRef(); - initialMesh->decrRef(); - //done in ~collection - //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); - //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); -} - -void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch) -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerExe(); - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout<<"\nf1 : "<<f1->reprZip(); - cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp; - int i2=i*nbcomp; - for (int j = 0; j < nbcomp; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedMesh->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); - initialMesh->decrRef(); -} - -void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch) -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerExe(); - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint - cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbptgauss=8; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp*nbptgauss; - int i2=i*nbcomp*nbptgauss; - for (int j = 0; j < nbcomp*nbptgauss; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedMesh->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); - initialMesh->decrRef(); -} - -//================================================================================ -/*! - * \brief Test for 0021756: [CEA 602] MEDPartitioner improvements - */ -//================================================================================ - -void MEDPARTITIONERTest::testCreateBoundaryFaces2D() -{ - // Fixed complains are: - // - 2D is not available - // - groups and family handling is bugged (probably due to bug in the handling - // of arrayTo in castIntField()) - // - creates boundary faces option is not handled - - // Create a 2D mesh in a file - - const char fileName[] = "tmp_testCreateBoundaryFaces2D.med"; - - const int idFam1 = 3, idFam2 = 2; - int nbFam1, nbFam2, nbc; - { - const int nbX = 20, nbY = 15; - vector<int> conn; - vector<double> coor; - for (int j=0; j<=nbY; j++) - for (int i=0; i<=nbX; i++) - { - coor.push_back(i+.1); - coor.push_back(j+.2); - } - int ii; - for (int j=0; j<nbY; j++) - for (int i=0; i<nbX; i++) - { - ii=i + j*(nbX+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + nbX + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - - nbc=conn.size()/4; //nb of cells - mesh->allocateCells(nbc); - int* pConn = &conn[0]; - for(int i=0; i<nbc; i++, pConn+=4) - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,pConn); - mesh->finishInsertingCells(); - - int nbv=coor.size()/2; //nb of vertices - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->useArray( &coor[0], /*ownership=*/false, CPP_DEALLOC, nbv, 2 ); - mesh->setCoords(myCoords); - mesh->setName("FacesIn2D"); - myCoords->decrRef(); - mesh->checkCoherency(); - - // groups of cells - DataArrayInt* cellsFam=DataArrayInt::New(); - cellsFam->alloc(nbc,1); - nbFam1 = nbc/3, nbFam2 = nbc/2; - int iE = 0; - for ( int i = 0; i < nbFam1; ++i ) cellsFam->getPointer()[ iE++ ] = idFam1; - for ( int i = 0; i < nbFam2; ++i ) cellsFam->getPointer()[ iE++ ] = idFam2; - for ( ; iE < nbc; ) cellsFam->getPointer()[ iE++ ] = 0; - map<string,int> theFamilies; - theFamilies["FAMILLE_ZERO"]=0; - theFamilies["Family1" ]=idFam1; - theFamilies["Family2" ]=idFam2; - map<string, vector<string> > theGroups; - theGroups["Group1"].push_back("Family1"); - theGroups["Group2"].push_back("Family2"); - - // write mesh - MEDFileUMesh * fileMesh = MEDFileUMesh::New(); - fileMesh->setMeshAtLevel(0, mesh); - fileMesh->setFamilyInfo(theFamilies); - fileMesh->setGroupInfo(theGroups); - fileMesh->setFamilyFieldArr(0, cellsFam); - fileMesh->write(fileName,2); - - cellsFam->decrRef(); - mesh ->decrRef(); - fileMesh->decrRef(); - - } // mesh creation - - // Partition the mesh into 4 parts - - const int ndomains = 4; - ParaDomainSelector parallelizer(false); - MeshCollection collection(fileName,parallelizer); - ParallelTopology* aPT = (ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - - std::auto_ptr< Topology > new_topo; -#if defined(MED_ENABLE_METIS) || defined(MED_ENABLE_PARMETIS) - new_topo.reset( collection.createPartition(ndomains,Graph::METIS) ); -#endif -#if defined(MED_ENABLE_SCOTCH) - if ( !new_topo.get() ) - new_topo.reset( collection.createPartition(ndomains,Graph::SCOTCH) ); -#endif - if ( !new_topo.get() ) - return; - - // Check that "2D is available" - - const char xmlName[] = "tmp_testCreateBoundaryFaces2D"; - { - MyGlobals::_Creates_Boundary_Faces = true; - MeshCollection new_collection(collection,new_topo.get()); - - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); - CPPUNIT_ASSERT (new_collection.getNbOfLocalFaces() > 0 ); - - MyGlobals::_General_Informations.clear(); - MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=2D")); - new_collection.write( xmlName ); - } - - // Check that "groups and family handling is NOT bugged" - - MeshCollection new_collection(std::string(xmlName)+".xml"); - std::map< int, int > famId2nb; // count total nb of cells in divided families - std::map< int, int >::iterator id2nn; - { - const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getCellFamilyIds(); - for ( size_t i = 0; i < famIdsVec.size(); ++i ) - { - ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; - for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) - { - id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; - id2nn->second++; - } - } - } - CPPUNIT_ASSERT_EQUAL( 3, (int) famId2nb.size() ); // 3 fams/groups in all - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( 0 )); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam1 )); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam2 )); - CPPUNIT_ASSERT_EQUAL( nbFam1, famId2nb[ idFam1 ]); - CPPUNIT_ASSERT_EQUAL( nbFam2, famId2nb[ idFam2 ]); - CPPUNIT_ASSERT_EQUAL( nbc - nbFam1 - nbFam2, famId2nb[ 0 ]); - - // Check that "creates boundary faces option is handled" - - famId2nb.clear(); - const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getFaceFamilyIds(); - for ( size_t i = 0; i < famIdsVec.size(); ++i ) - { - ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; - for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) - { - id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; - id2nn->second++; - } - } - - CPPUNIT_ASSERT( !famId2nb.empty() ); - - // for each "JOINT_n_p_..." group there must be "JOINT_p_n_..." group - // of the same size - std::map<std::string,int>& famName2id = new_collection.getFamilyInfo(); - std::map<std::string,int>::iterator na2id = famName2id.begin(), na2id2; - std::set< int > okFamIds; - okFamIds.insert(0); - for ( ; na2id != famName2id.end(); ++na2id ) - { - if ( okFamIds.count( na2id->second ) || na2id->first[0] != 'J') - continue; - na2id2 = na2id; - bool groupOK = false; - while ( !groupOK && ++na2id2 != famName2id.end() ) - groupOK = ( na2id2->first.find_first_not_of( na2id->first ) == std::string::npos ); - - CPPUNIT_ASSERT( groupOK ); - CPPUNIT_ASSERT( na2id->second != na2id2->second); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id2->second )); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id->second )); - CPPUNIT_ASSERT_EQUAL( (int) famId2nb[ na2id2->second ], - (int) famId2nb[ na2id->second ]); - okFamIds.insert( na2id2->second ); - } -} diff --git a/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx b/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx deleted file mode 100644 index f6cd5a13b..000000000 --- a/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONERTEST_HXX__ -#define __MEDPARTITIONERTEST_HXX__ - -#ifdef WIN32 -# if defined MEDPARTITIONERTEST_EXPORTS || defined MEDPARTITIONERTest_EXPORTS -# define MEDPARTITIONERTEST_EXPORT __declspec( dllexport ) -# else -# define MEDPARTITIONERTEST_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDPARTITIONERTEST_EXPORT -#endif - - -#include <cppunit/extensions/HelperMacros.h> - -#include <set> -#include <string> -#include <iostream> - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -class MEDPARTITIONERTEST_EXPORT MEDPARTITIONERTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MEDPARTITIONERTest ); - CPPUNIT_TEST( testMeshCollectionSingle ); - CPPUNIT_TEST( testMeshCollectionXml ); -#if defined(MED_ENABLE_METIS) - CPPUNIT_TEST( testMeshCollectionSinglePartitionMetis ); - CPPUNIT_TEST( testMeshCollectionComplexPartitionMetis ); - CPPUNIT_TEST( testMetisSmallSize ); -#endif -#if defined(MED_ENABLE_SCOTCH) - CPPUNIT_TEST( testMeshCollectionSinglePartitionScotch ); - CPPUNIT_TEST( testMeshCollectionComplexPartitionScotch ); - CPPUNIT_TEST( testScotchSmallSize ); -#endif - -#if defined(HAVE_MPI) -#if defined(MED_ENABLE_PARMETIS) - //test with mpi on system - CPPUNIT_TEST( testMpirunSmallSize ); - CPPUNIT_TEST( testMpirunMedianSize ); - CPPUNIT_TEST( testMpirunHugeSize ); -#endif -#endif - - CPPUNIT_TEST( testCreateBoundaryFaces2D ); // imp 0021756 - - //CPPUNIT_TEST( deleteTestMeshes ); - CPPUNIT_TEST_SUITE_END(); - -public: - - //global use - int _ni; //nb of hexa9 - int _nj; - int _nk; - int _ntot; - std::string _file_name; //initial test mesh file med CUBE3D - std::string _file_name_with_faces; //initial test mesh file med CUBE3D plus a set of faces - std::string _file_name2; //initial test mesh file med CARRE3D - std::string _file_name_huge_xml; - int _nb_target_huge; - std::string _mesh_name; //initial test mesh file med - int _verbose; - - //for utils - void setSize(int ni, int nj, int nk); - void setSmallSize(); - void setMedianSize(); - void setbigSize(); - std::string getPartitionerExe() const; - std::string getPartitionerParaExe() const; - ParaMEDMEM::MEDCouplingUMesh * buildCUBE3DMesh(); - ParaMEDMEM::MEDCouplingUMesh * buildFACE3DMesh(); - ParaMEDMEM::MEDCouplingUMesh * buildCARRE3DMesh(); - ParaMEDMEM::MEDCouplingFieldDouble * buildVecFieldOnCells(std::string myfileName); - ParaMEDMEM::MEDCouplingFieldDouble * buildVecFieldOnNodes(); - void createTestMeshWithoutField(); - void createTestMeshWithVecFieldOnCells(); - void createTestMeshWithVecFieldOnNodes(); - void verifyTestMeshWithVecFieldOnNodes(); - void verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch); - void verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch); - void verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch); - void verifyMedpartitionerOnSmallSizeForMesh(); - void verifyMedpartitionerOnSmallSizeForFieldOnCells(); - void verifyMedpartitionerOnSmallSizeForFieldOnGaussNe(); - void createTestMeshes(); - void createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget); - void launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch); - void launchMedpartitionerOnTestMeshes(); - void launchMedpartitionerOnHugeTestMeshes(); - void deleteTestMeshes(); - - //for CPPUNIT_TEST - void setUp(); - void tearDown(); - void testMeshCollectionSingle(); - void testMeshCollectionXml(); -#if defined(MED_ENABLE_METIS) - void testMeshCollectionSinglePartitionMetis(); - void testMeshCollectionComplexPartitionMetis(); - void testMetisSmallSize(); -#endif -#if defined(MED_ENABLE_SCOTCH) - void testMeshCollectionSinglePartitionScotch(); - void testMeshCollectionComplexPartitionScotch(); - void testScotchSmallSize(); -#endif - -#if defined(HAVE_MPI) - void testMpirunSmallSize(); - void testMpirunMedianSize(); - void testMpirunHugeSize(); -#endif - - void testCreateBoundaryFaces2D(); -}; - -#endif diff --git a/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx b/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx deleted file mode 100644 index 866409f0e..000000000 --- a/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx +++ /dev/null @@ -1,448 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONERTest.hxx" - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "CellModel.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> -#include <list> -#include <stdexcept> -#include <cstdlib> -#include <vector> - -#include <mpi.h> - -using namespace std; -using namespace ParaMEDMEM; -using namespace MEDPARTITIONER; - -#if defined(HAVE_MPI) -std::string MEDPARTITIONERTest::getPartitionerParaExe() const -{ - std::string execName; - if ( getenv("MEDCOUPLING_ROOT_DIR") ) - { - execName=getenv("MEDCOUPLING_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/medpartitioner_para"; - } - else - { - execName = get_current_dir_name(); - execName += "/../../MEDPartitioner/medpartitioner_para"; - if (! std::ifstream(execName.c_str())) - CPPUNIT_FAIL("Can't find medpartitioner_para, please set MEDCOUPLING_ROOT_DIR"); - } - return execName; -} - -void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForMesh() -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerParaExe(); - fileName=_file_name_with_faces; - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false); - - cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size()); - int nbcells=0; - for (std::size_t i = 0; i < cellMeshes.size(); i++) - nbcells+=cellMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - - std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size()); - int nbfaces=0; - for (std::size_t i=0; i < faceMeshes.size(); i++) - nbfaces+=faceMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces); - - //merge split meshes and test equality - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells()); - - /*not the good job - ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells()); - - ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells()); - - CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12)); - */ - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - meshes.resize(0); - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - corr.resize(0); - meshes.push_back(faceMesh); - refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9); - meshes.push_back(refusedFaceMesh); - MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells()); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - fusedFace->decrRef(); - refusedFaceMesh->decrRef(); - faceMesh->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); - //done in ~collection - //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); - //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); -} - -void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnCells() -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerParaExe(); - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout<<"\nf1 : "<<f1->reprZip(); - cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp; - int i2=i*nbcomp; - for (int j = 0; j < nbcomp; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); -} - -void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnGaussNe() -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerParaExe(); - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint - cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbptgauss=8; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp*nbptgauss; - int i2=i*nbcomp*nbptgauss; - for (int j = 0; j < nbcomp*nbptgauss; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); -} - -void MEDPARTITIONERTest::launchMedpartitionerOnTestMeshes() -{ - - /* examples - export INFI=/home/vb144235/resources/blade.med - //no need export MESH=Fuse_1 - export INFI=tmp_testMeshxxx.med - //no need export MESH=testMesh - mpirun -np 2 medpartitioner_para --input-file=$INFI --output-file=ttmp1_ --ndomains=4 - mpirun -np 5 medpartitioner_para --input-file=ttmp1_.xml --output-file=ttmp2_ --ndomains=5 - mpirun -np 2 valgrind medpartitioner_para --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp1petit_ --ndomains=4 --dump-cpu-memory --verbose=111 - */ - int res; - string cmd,execName,sourceName,targetName; - - res=system("which mpirun 2>/dev/null 1>/dev/null"); //no trace - CPPUNIT_ASSERT_EQUAL(0, res); - - execName=getPartitionerParaExe(); - - cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 2 "+execName+" --ndomains=2 --split-method=metis"; //on same proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo2_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 3 "+execName+" --ndomains=5 --split-method=metis"; //on less proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on 1 proc - sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 8 "+execName+" --ndomains=1 --split-method=metis"; //on more proc - //sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); -} - -void MEDPARTITIONERTest::launchMedpartitionerOnHugeTestMeshes() -{ - int res=0; - string cmd,execName,sourceName,targetName; - execName=getPartitionerParaExe(); - - string snbTarget=IntToStr(_nb_target_huge); - cmd="mpirun -np "+snbTarget+" "+execName+" --ndomains="+snbTarget+" --split-method=metis"; //on same proc - sourceName=_file_name_huge_xml; - targetName=_file_name_huge_xml; - string tmp="_partitionedTo"+snbTarget+"_"; - targetName.replace(targetName.find(".xml"),4,tmp); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); -} - -void MEDPARTITIONERTest::testMpirunSmallSize() -{ - setSmallSize(); - createTestMeshes(); - launchMedpartitionerOnTestMeshes(); - verifyMedpartitionerOnSmallSizeForMesh(); - verifyMedpartitionerOnSmallSizeForFieldOnCells(); - verifyMedpartitionerOnSmallSizeForFieldOnGaussNe(); -} - -void MEDPARTITIONERTest::testMpirunMedianSize() -{ - setMedianSize(); - createTestMeshes(); - launchMedpartitionerOnTestMeshes(); -} - -void MEDPARTITIONERTest::testMpirunHugeSize() -{ - //setBigSize(); //may be a lot for now - setMedianSize(); - //create a set of nbx*nby*nbz files mesh of ni*ny*nz cells - //_verbose=1; - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //it is now to know how far we are going to test - launchMedpartitionerOnHugeTestMeshes(); -} -#endif diff --git a/medtool/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx b/medtool/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx deleted file mode 100644 index a46dd0a4a..000000000 --- a/medtool/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -//include all MEDPARTITIONER Test -#include "MEDPARTITIONERTest.hxx" - -//Registers the fixture into the 'registry' -CPPUNIT_TEST_SUITE_REGISTRATION( MEDPARTITIONERTest ); - -//generic Main program from KERNEL_SRC/src/Basics/Test -#include "BasicMainTest.hxx" diff --git a/medtool/src/MEDPartitioner/medpartitioner.cxx b/medtool/src/MEDPartitioner/medpartitioner.cxx deleted file mode 100644 index 48b90a7d4..000000000 --- a/medtool/src/MEDPartitioner/medpartitioner.cxx +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -/* - examples of launch - export verb=1 - medpartitioner --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - medpartitioner --input-file=medpartitioner_blade.xml --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - medpartitioner --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --dump-cpu-memory --verbose=$verb -*/ - -/* -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Utils.hxx" -*/ - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include <string> -#include <fstream> -#include <cstring> -#include <cstdlib> -#include <iostream> - -using namespace std; -using namespace MEDPARTITIONER; - -int main(int argc, char** argv) -{ -#if !defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) - std::cout << "Sorry, no one split method is available. Please, compile with METIS or SCOTCH." << std::endl; - return 1; -#else - - // Defining options - // by parsing the command line - - bool split_family=false; - bool empty_groups=false; - bool mesure_memory=false; - bool filter_face=true; - - string input; - string output; - string meshname; - string library="metis"; //default - int ndomains; - int help=0; - - //sequential : no MPI - MyGlobals::_World_Size=1; - MyGlobals::_Rank=0; - MyGlobals::_Creates_Boundary_Faces=0; - MyGlobals::_Create_Joints=0; - - // Primitive parsing of command-line options - string desc ("Available options of medpartitioner V1.0:\n" - "\t--help : produces this help message\n" - "\t--verbose : echoes arguments\n" - "\t--input-file=<string> : name of the input .med file or .xml master file\n" - "\t--output-file=<string> : name of the resulting file (without extension)\n" - "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n" -#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) - //user can choose! - "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n" -#endif - "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" - "\t--creates-joints : creates joints in the output files\n" - "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" - ); - - if (argc<=1) help=1; - string value; - for (int i = 1; i < argc; i++) - { - if (strlen(argv[i]) < 3) - { - cerr << "bad argument : "<< argv[i] << endl; - return 1; - } - - if (TestArg(argv[i],"--verbose",value)) - { - MyGlobals::_Verbose=1; - if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); - } - else if (TestArg(argv[i],"--help",value)) help=1; -// else if (TestArg(argv[i],"--test",value)) test=1; - else if (TestArg(argv[i],"--input-file",value)) input=value; - else if (TestArg(argv[i],"--output-file",value)) output=value; - else if (TestArg(argv[i],"--split-method",value)) library=value; - else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); - else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; - else if (TestArg(argv[i],"--create-joints",value)) MyGlobals::_Create_Joints=1; - else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; - else - { - cerr << "unknown argument : "<< argv[i] << endl; - return 1; - } - } - - MyGlobals::_Is0verbose=MyGlobals::_Verbose; - -//no choice -#if defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) - library = "metis"; -#endif -#if !defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) - library = "scotch"; -#endif -//user choice -#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) - if ((library!="metis") && (library!="scotch")) - { - cerr << "split-method only available : metis, scotch" << endl; - return 1; - } -#endif - - if (help==1) - { - cout<<desc<<"\n"; - return 0; - } - - if (MyGlobals::_Is0verbose) - { - cout << "medpartitioner V1.0 :" << endl; - cout << " input-file = " << input << endl; - cout << " output-file = " << output << endl; - cout << " split-method = " << library << endl; - cout << " ndomains = " << ndomains << endl; - cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; - cout << " create-joints = " << MyGlobals::_Create_Joints<< endl; - cout << " dump-cpu-memory = " << mesure_memory<< endl; - cout << " verbose = " << MyGlobals::_Verbose << endl; - } - //testing whether it is possible to write a file at the specified location - if (MyGlobals::_Rank==0) - { - string outputtest = output + ".testioms."; - ofstream testfile (outputtest.c_str()); - if (testfile.fail()) - { - cerr << "output-file directory does not exist or is in read-only access" << endl; - return 1; - } - //deletes test file - remove(outputtest.c_str()); - } - - // Beginning of the computation - - // Loading the mesh collection - if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl; - - try - { - /*MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains - //to have unique valid fields names/pointers/descriptions for partitionning - collection.prepareFieldDescriptions(); - //int nbfields=collection.getFieldDescriptions().size(); //on all domains - //cout<<ReprVectorOfString(collection.getFieldDescriptions()); - - if (MyGlobals::_Is0verbose) - { - cout<<"fileNames :"<<endl - <<ReprVectorOfString(MyGlobals::_File_Names); - cout<<"fieldDescriptions :"<<endl - <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); //cvwat07 - cout<<"familyInfo :\n" - <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl; - cout<<"groupInfo :\n" - <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl; - }*/ - MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //to have unique valid fields names/pointers/descriptions for partitionning - collection.prepareFieldDescriptions(); - - //MEDPARTITIONER::MeshCollection collection(input); - - //Creating the graph and partitioning it - if (MyGlobals::_Is0verbose) cout << "Computing partition with " << library << endl; - - auto_ptr< MEDPARTITIONER::Topology > new_topo; - if (library == "metis") - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); - else - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); - parallelizer.evaluateMemory(); - - //Creating a new mesh collection from the partitioning - if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - if (filter_face) new_collection.filterFaceOnCell(); - - //to get infos on all procs - - //see meshName - vector<string> finalInformations; - vector<string> r1,r2; - //r1=AllgathervVectorOfString(MyGlobals::_General_Informations); - r1=MyGlobals::_General_Informations; - //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1); - r2=SelectTagsInVectorOfString(r1,"ioldDomain="); - r2=SelectTagsInVectorOfString(r2,"meshName="); - if (r2.size()==(collection.getMesh()).size()) - { - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldDomain="); - r2=DeleteDuplicatesInVectorOfString(r2); - if (r2.size()==1) - { - string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName="); - finalInformations.push_back(SerializeFromString(finalMesh)); - } - } - if (finalInformations.size()==0) - { - if (MyGlobals::_Rank==0) - cerr<<"Problem on final meshName : set at 'Merge'"<<endl; - finalInformations.push_back(SerializeFromString("finalMeshName=Merge")); - } - - //see field info nbComponents & componentInfo (if fields present) - r2=SelectTagsInVectorOfString(r1,"fieldName="); - r2=SelectTagsInVectorOfString(r2,"nbComponents="); - //may be yes? or not? - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble="); - r2=DeleteDuplicatesInVectorOfString(r2); - for (std::size_t i=0; i<r2.size(); i++) - finalInformations.push_back(r2[i]); - - MyGlobals::_General_Informations=finalInformations; - if (MyGlobals::_Is0verbose) - cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations); - - //new_collection.setSubdomainBoundaryCreates(creates_boundary_faces); - if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl; - new_collection.write(output); - - /*if ( mesure_memory ) - if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 ) - { - cout << "Elapsed time = " << parallelizer.getPassedTime() - << ", max memory usage = " << parallelizer.evaluateMemory() << " KB" - << endl; - }*/ - - if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl; - return 0; - } - catch(const char *mess) - { - cerr<<mess<<endl; - fflush(stderr); - return 1; - } - catch(INTERP_KERNEL::Exception& e) - { - cerr<<"INTERP_KERNEL_Exception : "<<e.what()<<endl; - fflush(stderr); - return 1; - } - catch(std::exception& e) - { - cerr<<"std_Exception : "<<e.what()<<endl; - fflush(stderr); - return 1; - } - catch(...) - { - cerr<<"an unknown type exception error was occured"<<endl; - fflush(stderr); - return 1; - } -#endif -} diff --git a/medtool/src/MEDPartitioner/medpartitioner_para.cxx b/medtool/src/MEDPartitioner/medpartitioner_para.cxx deleted file mode 100644 index 60c3295d2..000000000 --- a/medtool/src/MEDPartitioner/medpartitioner_para.cxx +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -/* - examples of launch - rm ttmp* tttmp* - export verb=11 - mpirun -np 2 medpartitioner_para --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - mpirun -np 5 medpartitioner_para --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - mpirun -np 4 medpartitioner_para --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --verbose=$verb - - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb - - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMeshWithFaces_20x30x50.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb - - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50_WithVecFieldOnCells.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50_WithVecFieldOnNodes.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb - - mpirun -np 4 medpartitioner_para --ndomains=4 --input-file=tmp_testMeshHuge_20x30x50_6.xml --output-file=ttmp3_ --verbose=1 -*/ - - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDLoader.hxx" - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> -#include <cstring> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace std; -using namespace MEDPARTITIONER; - -int main(int argc, char** argv) -{ -#if !defined(MED_ENABLE_PARMETIS) - cout << "Sorry, no one split method is available. Please, compile with ParMETIS."<<endl; - return 1; -#else - - // Defining options - // by parsing the command line - - bool split_family=false; - bool empty_groups=false; - bool mesure_memory=false; - bool filter_face=true; - - string input; - string output; - string meshname; - string library="metis"; //default - int ndomains; - int help=0; - int test=0; - MPI_Init(&argc,&argv); - MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size); - MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank); - - //cout<<"proc "<<MyGlobals::_Rank<<" of "<<MyGlobals::_World_Size<<endl; //for debug - //TestVectorOfStringMpi(); //cvw - //TestRandomize(); - - //Primitive parsing of command-line options - string desc ("Available options of medpartitioner_para V1.0.3:\n" - "\t--help : produces this help message\n" - "\t--verbose : echoes arguments\n" - "\t--input-file=<string> : name of the input .med file or .xml master file\n" - "\t--output-file=<string> : name of the resulting file (without extension)\n" - "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n" -#if defined(MED_ENABLE_PARMETIS) -// || defined(MED_ENABLE_PTSCOTCH) -//user can choose! (not yet) - "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n" -#endif - "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" - "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" - //"\t--randomize=<number> : random seed for other partitionning (only on one proc)\n" - //"\t--atomize : do the opposite of a good partitionner (only on one proc)\n" - ); - - if (argc<=1) help=1; - string value; - for (int i = 1; i < argc; i++) - { - if (strlen(argv[i]) < 3) - { - if (MyGlobals::_Rank==0) cerr << "bad argument : "<< argv[i] << endl; - MPI_Finalize(); return 1; - } - - if (TestArg(argv[i],"--verbose",value)) - { - MyGlobals::_Verbose=1; - if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); - } - else if (TestArg(argv[i],"--help",value)) help=1; - else if (TestArg(argv[i],"--test",value)) test=1; - else if (TestArg(argv[i],"--input-file",value)) input=value; - else if (TestArg(argv[i],"--output-file",value)) output=value; - else if (TestArg(argv[i],"--split-method",value)) library=value; - else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); - else if (TestArg(argv[i],"--randomize",value)) MyGlobals::_Randomize=atoi(value.c_str()); - else if (TestArg(argv[i],"--atomize",value)) MyGlobals::_Atomize=atoi(value.c_str()); - else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; - else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; - else - { - if (MyGlobals::_Rank==0) cerr << "unknown argument : "<< argv[i] << endl; - MPI_Finalize(); return 1; - } - } - - - if (MyGlobals::_Randomize!=0 && MyGlobals::_World_Size!=1) - { - if (MyGlobals::_Rank==0) cerr << "randomize only available on 1 proc (mpirun -np 1)" << endl; - MyGlobals::_Randomize=0; - } - -//no choice -#if defined(MED_ENABLE_PARMETIS) && !defined(MED_ENABLE_SCOTCH) - library = "metis"; -#endif -#if !defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) - library = "scotch"; -#endif -//user choice -#if defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) - if ((library!="metis") && (library!="scotch")) - { - if (MyGlobals::_Rank==0) cerr << "split-method only available : metis, scotch" << endl; - MPI_Finalize(); return 1; - } -#endif - - if (help==1) - { - if (MyGlobals::_Rank==0) cout<<desc<<"\n"; - MPI_Finalize(); return 0; - } - - MyGlobals::_Is0verbose=0; - if (MyGlobals::_Rank==0) MyGlobals::_Is0verbose=MyGlobals::_Verbose; - //MyGlobals::_Is0verbose=((MyGlobals::_Rank==0) && MyGlobals::_Verbose); - if (test==1) //only for debugger - { - if (MyGlobals::_Is0verbose>0) cout<<"tests on "<<MyGlobals::_Atomize<<" "<<ndomains<<endl; - //TestPersistantMpi0To1(MyGlobals::_Atomize, ndomains); - //TestPersistantMpiRing(MyGlobals::_Atomize, ndomains); - TestPersistantMpiRingOnCommSplit(MyGlobals::_Atomize, ndomains); - //MPI_Barrier(MPI_COMM_WORLD); - MPI_Finalize(); - return 0; - TestVectorOfStringMpi(); - TestMapOfStringIntMpi(); - TestMapOfStringVectorOfStringMpi(); - TestDataArrayMpi(); - MPI_Finalize(); - return 1; - } - - if (MyGlobals::_Is0verbose) - { - cout << "medpartitioner_para V1.0 :" << endl; - cout << " input-file = " << input << endl; - cout << " output-file = " << output << endl; - cout << " split-method = " << library << endl; - cout << " ndomains = " << ndomains << endl; - cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; - cout << " dump-cpu-memory = " << mesure_memory<< endl; - cout << " verbose = " << MyGlobals::_Verbose << endl; - } - //testing whether it is possible to write a file at the specified location - if (MyGlobals::_Rank==0) - { - string outputtest = output + ".testioms."; - ofstream testfile (outputtest.c_str()); - if (testfile.fail()) - { - cerr << "output-file directory does not exist or is in read-only access" << endl; - MPI_Finalize(); return 1; - } - //deletes test file - remove(outputtest.c_str()); - } - - // Beginning of the computation - - // Loading the mesh collection - if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl; - - try - { - MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains - //to have unique valid fields names/pointers/descriptions for partitionning - collection.prepareFieldDescriptions(); - //int nbfields=collection.getFieldDescriptions().size(); //on all domains - //cout<<ReprVectorOfString(collection.getFieldDescriptions()); - - if (MyGlobals::_Is0verbose) - { - cout<<"fileNames :"<<endl - <<ReprVectorOfString(MyGlobals::_File_Names); - cout<<"fieldDescriptions :"<<endl - <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); - cout<<"familyInfo :\n" - <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl; - cout<<"groupInfo :\n" - <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl; - } - - //Creating the graph and partitioning it - if (MyGlobals::_Is0verbose) cout << "Computing partition "<< endl; - - auto_ptr< MEDPARTITIONER::Topology > new_topo; - if (library == "metis") - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); - else - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); - parallelizer.evaluateMemory(); - - //Creating a new mesh collection from the partitioning - if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - //cout<<"proc "<<MyGlobals::_Rank<<" : new_collection done"<<endl; - parallelizer.evaluateMemory(); - - //if (!xml_output_master) new_collection.setDriverType(MEDPARTITIONER::MedAscii); - if (filter_face) new_collection.filterFaceOnCell(); - - //to get infos on all procs - - //see meshName - vector<string> finalInformations; - vector<string> r1,r2; - r1=AllgathervVectorOfString(MyGlobals::_General_Informations); - //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1); - r2=SelectTagsInVectorOfString(r1,"ioldDomain="); - r2=SelectTagsInVectorOfString(r2,"meshName="); - if (r2.size()==(collection.getMesh()).size()) - { - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldDomain="); - r2=DeleteDuplicatesInVectorOfString(r2); - if (r2.size()==1) - { - string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName="); - finalInformations.push_back(SerializeFromString(finalMesh)); - } - } - if (finalInformations.size()==0) - { - if (MyGlobals::_Rank==0) - cerr<<"Problem on final meshName : set at 'Merge'"<<endl; - finalInformations.push_back(SerializeFromString("finalMeshName=Merge")); - } - - //see field info nbComponents & componentInfo (if fields present) - r2=SelectTagsInVectorOfString(r1,"fieldName="); - r2=SelectTagsInVectorOfString(r2,"nbComponents="); - //may be yes? or not? - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble="); - r2=DeleteDuplicatesInVectorOfString(r2); - for (std::size_t i=0; i<r2.size(); i++) - finalInformations.push_back(r2[i]); - - MyGlobals::_General_Informations=finalInformations; - if (MyGlobals::_Is0verbose) - cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations); - - //new_collection.setSubdomainBoundaryCreates(creates_boundary_faces); - if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl; - new_collection.write(output); - - if ( mesure_memory ) - if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 ) - { - cout << "Elapsed time = " << parallelizer.getPassedTime() - << ", max memory usage = " << parallelizer.evaluateMemory() << " KB" - << endl; - } - if(MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); - if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl; - MPI_Finalize(); - return 0; - } - catch(const char *mess) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : "<<mess<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } - catch(INTERP_KERNEL::Exception& e) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : INTERP_KERNEL_Exception : "<<e.what()<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } - catch(std::exception& e) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : std_Exception : "<<e.what()<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } - catch(...) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : an unknown type exception error was occured"<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } -#endif -} - diff --git a/medtool/src/MEDPartitioner_Swig/CMakeLists.txt b/medtool/src/MEDPartitioner_Swig/CMakeLists.txt deleted file mode 100644 index 36d142a6e..000000000 --- a/medtool/src/MEDPartitioner_Swig/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS} ${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ) - -SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDPartitioner_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD") - -SET (MEDPartitioner_SWIG_DPYS_FILES - MEDPartitionerCommon.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${HDF5_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDPartitioner - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader/Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SWIG_ADD_MODULE(MEDPartitioner python MEDPartitioner.i) -SWIG_LINK_LIBRARIES(MEDPartitioner ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medpartitionercpp) - -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDPartitioner PROPERTIES DEBUG_OUTPUT_NAME _MEDPartitioner_d) -ENDIF(WIN32) -INSTALL(TARGETS ${SWIG_MODULE_MEDPartitioner_REAL_NAME} DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) - -SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDPartitioner.py) -INSTALL(FILES "${PYFILES_TO_INSTALL}" DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) - -INSTALL(FILES MEDPartitioner.i MEDPartitionerCommon.i DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) -INSTALL(FILES MEDPartitionerTest.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) - -ADD_TEST(MEDPartitionerTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDPartitionerTest.py) -SET(MEDPartitionerTest_PYTHONPATH "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/../MEDLoader/Swig") -SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES ENVIRONMENT "${MEDPartitionerTest_PYTHONPATH}") - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner_Swig) -INSTALL(FILES MEDPartitionerTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake b/medtool/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake deleted file mode 100644 index 2100e6bf0..000000000 --- a/medtool/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(MEDPartitionerTest python MEDPartitionerTest.py) -SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/MEDPartitioner_Swig/MEDPartitioner.i b/medtool/src/MEDPartitioner_Swig/MEDPartitioner.i deleted file mode 100644 index 13f6d9ca9..000000000 --- a/medtool/src/MEDPartitioner_Swig/MEDPartitioner.i +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include "MEDPartitionerCommon.i" - - -// %pythoncode %{ -// def ParaMEDMEMDataArrayDoublenew(cls,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____new___(cls,args) -// def ParaMEDMEMDataArrayDoubleIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____isub___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____imul___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleIpow(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____ipow___(self, self, *args) -// def ParaMEDMEMDataArrayIntnew(cls,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____new___(cls,args) -// def ParaMEDMEMDataArrayIntIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayIntIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____isub___(self, self, *args) -// def ParaMEDMEMDataArrayIntImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____imul___(self, self, *args) -// def ParaMEDMEMDataArrayIntIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayIntImod(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____imod___(self, self, *args) -// def ParaMEDMEMDataArrayIntIpow(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____ipow___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____isub___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____imul___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____isub___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____imul___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleImod(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____imod___(self, self, *args) -// %} - - -// %pythoncode %{ -// DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) -// DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd -// DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub -// DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul -// DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv -// DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow - -// DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) -// DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd -// DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub -// DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul -// DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv -// DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod -// DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow - -// DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd -// DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub -// DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul -// DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv - -// DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd -// DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub -// DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul -// DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv -// DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod - -// del ParaMEDMEMDataArrayDoublenew -// del ParaMEDMEMDataArrayDoubleIadd -// del ParaMEDMEMDataArrayDoubleIsub -// del ParaMEDMEMDataArrayDoubleImul -// del ParaMEDMEMDataArrayDoubleIdiv -// del ParaMEDMEMDataArrayIntnew -// del ParaMEDMEMDataArrayIntIadd -// del ParaMEDMEMDataArrayIntIsub -// del ParaMEDMEMDataArrayIntImul -// del ParaMEDMEMDataArrayIntIdiv -// del ParaMEDMEMDataArrayIntImod -// del ParaMEDMEMDataArrayDoubleTupleIadd -// del ParaMEDMEMDataArrayDoubleTupleIsub -// del ParaMEDMEMDataArrayDoubleTupleImul -// del ParaMEDMEMDataArrayDoubleTupleIdiv -// del ParaMEDMEMDataArrayIntTupleIadd -// del ParaMEDMEMDataArrayIntTupleIsub -// del ParaMEDMEMDataArrayIntTupleImul -// del ParaMEDMEMDataArrayIntTupleIdiv -// del ParaMEDMEMDataArrayIntTupleImod -// %} diff --git a/medtool/src/MEDPartitioner_Swig/MEDPartitionerCommon.i b/medtool/src/MEDPartitioner_Swig/MEDPartitionerCommon.i deleted file mode 100644 index 93a390a81..000000000 --- a/medtool/src/MEDPartitioner_Swig/MEDPartitionerCommon.i +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%module MEDPartitioner - -%include std_string.i - -%{ -#include "MEDFileData.hxx" - -#include "MEDPARTITIONER_MEDPartitioner.hxx" -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; -using namespace MEDPARTITIONER; -%} - -%feature("autodoc", "1"); -%feature("docstring"); - -%newobject MEDPARTITIONER::MEDPartitioner::New; -%newobject MEDPARTITIONER::MEDPartitioner::Graph; -%newobject MEDPARTITIONER::MEDPartitioner::getMEDFileData; -%feature("unref") ParaMEDMEM::MEDFileData "$this->decrRef();" - -%nodefaultctor; - -%rename (InterpKernelException) INTERP_KERNEL::Exception; - -namespace MEDPARTITIONER -{ - class Graph - { - public: - virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) throw(INTERP_KERNEL::Exception); - const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const; - const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const; - int nbVertices() const; - }; - - class MEDPartitioner - { - public: - MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); - static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileData* getMEDFileData() throw(INTERP_KERNEL::Exception); - void write(const std::string& filename) throw(INTERP_KERNEL::Exception); - }; -} - diff --git a/medtool/src/MEDPartitioner_Swig/MEDPartitionerTest.py b/medtool/src/MEDPartitioner_Swig/MEDPartitionerTest.py deleted file mode 100644 index 9985d1986..000000000 --- a/medtool/src/MEDPartitioner_Swig/MEDPartitionerTest.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDPartitioner import * -from MEDLoader import * -import unittest -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDPartitionerTest(unittest.TestCase): - def testPartition(self): - fname="PyPartitionTest.med" - data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - data.write(fname,2) - part_file=MEDPartitioner(fname,2) - part_data=MEDPartitioner(data,2) - part_file.write("splitted_PyPartitionTest_1") - part_data.write("splitted_PyPartitionTest_2") - part_file_xml=MEDPartitioner("splitted_PyPartitionTest_1.xml") - part_data_xml=MEDPartitioner("splitted_PyPartitionTest_2.xml") - data1=part_file_xml.getMEDFileData() - data2=part_data_xml.getMEDFileData() - m1d=data1.getMeshes().getMeshAtPos(0) - m2d=data2.getMeshes().getMeshAtPos(0) - self.assertTrue(m1d.isEqual(m2d,1e-12)) - pass - def testPartitionGraph(self): - data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - m=data.getMeshes().getMeshAtPos(0) - graph=MEDPartitioner.Graph(m.getLevel0Mesh().generateGraph()) - graph.partGraph(2) - tool=MEDPartitioner(data,graph) - data2=tool.getMEDFileData() - self.assertEqual( 2, data2.getMeshes().getNumberOfMeshes() ) - pass - def testPartitionWithJoints(self): - # cartesian mesh 4x4 - arr=DataArrayDouble(5) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - m.setName("mesh") - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - ms=MEDFileMeshes() ; ms.pushMesh(mm) - data=MEDFileData() - data.setMeshes(ms) - part_file=MEDPartitioner(data,4,"metis",True,True,True) - data_file=part_file.getMEDFileData() - meshes=data_file.getMeshes() - self.assertEqual( 4, meshes.getNumberOfMeshes()) - self.assertEqual( 3, meshes.getMeshAtPos(0).getJoints().getNumberOfJoints()) - self.assertEqual( 3, meshes.getMeshAtPos(1).getJoints().getNumberOfJoints()) - self.assertEqual( 3, meshes.getMeshAtPos(2).getJoints().getNumberOfJoints()) - self.assertEqual( 3, meshes.getMeshAtPos(3).getJoints().getNumberOfJoints()) - joints=meshes.getMeshAtPos(0).getJoints() - self.assertEqual( 1, joints.getJointAtPos(0).getDomainNumber(), 1) - self.assertEqual( 2, joints.getJointAtPos(1).getDomainNumber(), 2) - self.assertEqual( 3, joints.getJointAtPos(2).getDomainNumber(), 3) - self.assertEqual( 2, joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()) - self.assertEqual( 2, joints.getJointAtPos(1).getStepAtPos(0).getNumberOfCorrespondences()) - self.assertEqual( 1, joints.getJointAtPos(2).getStepAtPos(0).getNumberOfCorrespondences()) - found=0 - for ii in xrange(joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()): - correspond=joints.getJointAtPos(0).getStepAtPos(0).getCorrespondenceAtPos(ii) - if correspond.getCorrespondence().isEqual(DataArrayInt([1,3,2,4])): - found+=1 - self.assertEqual(NORM_QUAD4, correspond.getLocalGeometryType()) - self.assertEqual(NORM_QUAD4, correspond.getRemoteGeometryType()) - pass - pass - self.assertEqual(1,found) - pass - def testPartitionPartGraph(self): - arr=DataArrayDouble(5) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - part=MEDPartitioner.Graph(m.generateGraph()) - part.partGraph(2) - a=part.getGraph() - p=part.getPartition() - self.assertTrue(isinstance(a,MEDCouplingSkyLineArray)) - self.assertTrue(isinstance(p,MEDCouplingSkyLineArray)) - self.assertTrue(part.nbVertices() > 0 ) - pass -unittest.main() diff --git a/medtool/src/ParaMEDLoader/CMakeLists.txt b/medtool/src/ParaMEDLoader/CMakeLists.txt deleted file mode 100644 index 2edf2a29d..000000000 --- a/medtool/src/ParaMEDLoader/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${MPI_DEFINITIONS}) - -IF(HDF5_ENABLE_PARALLEL OR HDF5_IS_PARALLEL) - ADD_DEFINITIONS("-DHDF5_IS_PARALLEL") -ENDIF(HDF5_ENABLE_PARALLEL OR HDF5_IS_PARALLEL) - -INCLUDE_DIRECTORIES( - ${MPI_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ) - -SET(paramedloader_SOURCES - ParaMEDLoader.cxx - ParaMEDFileMesh.cxx - ) - -ADD_LIBRARY(paramedloader SHARED ${paramedloader_SOURCES}) -TARGET_LINK_LIBRARIES(paramedloader paramedmem medloader ${PLATFORM_LIBS}) -INSTALL(TARGETS paramedloader EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -FILE(GLOB paramedloader_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") -INSTALL(FILES ${paramedloader_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) diff --git a/medtool/src/ParaMEDLoader/ParaMEDFileMesh.cxx b/medtool/src/ParaMEDLoader/ParaMEDFileMesh.cxx deleted file mode 100644 index 043f62df0..000000000 --- a/medtool/src/ParaMEDLoader/ParaMEDFileMesh.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#include "ParaMEDFileMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileMeshLL.hxx" -#include "MEDLoader.hxx" - -using namespace ParaMEDMEM; - -MEDFileMesh *ParaMEDFileMesh::New(int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - int dummy0,dummy1; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); - switch(meshType) - { - case UNSTRUCTURED: - { - return ParaMEDFileUMesh::New(iPart,nbOfParts,fileName,mName,dt,it,mrs); - } - default: - throw INTERP_KERNEL::Exception("ParaMEDFileMesh::New : only unstructured mesh supported for the moment !"); - } -} - -MEDFileMesh *ParaMEDFileMesh::ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - int dummy0,dummy1; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); - switch(meshType) - { - case UNSTRUCTURED: - { - return ParaMEDFileUMesh::ParaNew(iPart,nbOfParts,com,nfo,fileName,mName,dt,it,mrs); - } - default: - throw INTERP_KERNEL::Exception("ParaMEDFileMesh::ParaNew : only unstructured mesh supported for the moment !"); - } -} - -MEDFileUMesh *ParaMEDFileUMesh::New(int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - return ParaMEDFileUMesh::NewPrivate(fid,iPart,nbOfParts,fileName,mName,dt,it,mrs); -} - -// MPI_COMM_WORLD, MPI_INFO_NULL -MEDFileUMesh *ParaMEDFileUMesh::ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); -#ifdef HDF5_IS_PARALLEL - MEDFileUtilities::AutoFid fid(MEDparFileOpen(fileName.c_str(),MED_ACC_RDONLY,com,nfo)); -#else - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); -#endif - return ParaMEDFileUMesh::NewPrivate(fid,iPart,nbOfParts,fileName,mName,dt,it,mrs); -} - -MEDFileUMesh *ParaMEDFileUMesh::NewPrivate(med_idt fid, int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret; - int meshDim, spaceDim, numberOfNodes; - std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > typesDistrib(MEDLoader::GetUMeshGlobalInfo(fileName,mName,meshDim,spaceDim,numberOfNodes)); - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector<int> distrib; - for(std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > >::const_iterator it0=typesDistrib.begin();it0!=typesDistrib.end();it0++) - for(std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - { - types.push_back((*it1).first); - int tmp[3]; - DataArray::GetSlice(0,(*it1).second,1,iPart,nbOfParts,tmp[0],tmp[1]); - tmp[2]=1; - distrib.insert(distrib.end(),tmp,tmp+3); - } - ret=MEDFileUMesh::LoadPartOf(fid,mName,types,distrib,dt,it,mrs); - return ret.retn(); -} - -MEDFileMeshes *ParaMEDFileMeshes::New(int iPart, int nbOfParts, const std::string& fileName) -{ - std::vector<std::string> ms(MEDLoader::GetMeshNames(fileName)); - MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret(MEDFileMeshes::New()); - for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++) - { - MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mesh(ParaMEDFileMesh::New(iPart,nbOfParts,fileName,(*it))); - ret->pushMesh(mesh); - } - return ret.retn(); -} - -MEDFileMeshes *ParaMEDFileMeshes::ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName) -{ - std::vector<std::string> ms(MEDLoader::GetMeshNames(fileName)); - MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret(MEDFileMeshes::New()); - for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++) - { - MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mesh(ParaMEDFileMesh::ParaNew(iPart,nbOfParts,com,nfo,fileName,(*it))); - ret->pushMesh(mesh); - } - return ret.retn(); -} diff --git a/medtool/src/ParaMEDLoader/ParaMEDFileMesh.hxx b/medtool/src/ParaMEDLoader/ParaMEDFileMesh.hxx deleted file mode 100644 index f034c471d..000000000 --- a/medtool/src/ParaMEDLoader/ParaMEDFileMesh.hxx +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (EDF R&D) - -#ifndef __PARAMEDFILEMESH_HXX__ -#define __PARAMEDFILEMESH_HXX__ - -#include "med.h" - -#include "mpi.h" - -#include <string> - -namespace ParaMEDMEM -{ - class MEDFileMesh; - class MEDFileUMesh; - class MEDFileMeshes; - class MEDFileMeshReadSelector; - - class ParaMEDFileMesh - { - public: - static MEDFileMesh *New(int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - static MEDFileMesh *ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - }; - - class ParaMEDFileUMesh - { - public: - static MEDFileUMesh *New(int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - static MEDFileUMesh *ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - private: - static MEDFileUMesh *NewPrivate(med_idt fid, int iPart, int nbOfParts, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - }; - - class ParaMEDFileMeshes - { - public: - static MEDFileMeshes *New(int iPart, int nbOfParts, const std::string& fileName); - static MEDFileMeshes *ParaNew(int iPart, int nbOfParts, const MPI_Comm& com, const MPI_Info& nfo, const std::string& fileName); - }; -} - -#endif diff --git a/medtool/src/ParaMEDLoader/ParaMEDLoader.cxx b/medtool/src/ParaMEDLoader/ParaMEDLoader.cxx deleted file mode 100644 index 43a4eec9d..000000000 --- a/medtool/src/ParaMEDLoader/ParaMEDLoader.cxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "ParaMEDLoader.hxx" -#include "MEDLoader.hxx" -#include "ParaMESH.hxx" -#include "BlockTopology.hxx" -#include "MEDCouplingUMesh.hxx" - -#include <fstream> - -using namespace ParaMEDMEM; - -ParaMEDLoader::ParaMEDLoader() -{ -} - -void ParaMEDLoader::WriteParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh) -{ - if(!mesh->getBlockTopology()->getProcGroup()->containsMyRank()) - return ; - int myRank=mesh->getBlockTopology()->getProcGroup()->myRank(); - int nbDomains=mesh->getBlockTopology()->getProcGroup()->size(); - std::vector<std::string> fileNames(nbDomains); - for(int i=0;i<nbDomains;i++) - { - std::ostringstream sstr; - sstr << fileName << i+1 << ".med"; - fileNames[i]=sstr.str(); - } - if(myRank==0) - WriteMasterFile(fileName,fileNames,mesh->getCellMesh()->getName().c_str()); - MEDLoader::WriteUMesh(fileNames[myRank].c_str(),dynamic_cast<MEDCouplingUMesh *>(mesh->getCellMesh()),true); -} - -/*! - * This method builds the master file 'fileName' of a parallel MED file defined in 'fileNames'. - */ -void ParaMEDLoader::WriteMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName) -{ - int nbOfDom=fileNames.size(); - std::ofstream fs(fileName); - fs << "#MED Fichier V 2.3" << " " << std::endl; - fs << "#"<<" " << std::endl; - fs << nbOfDom <<" " << std::endl; - for(int i=0;i<nbOfDom;i++) - fs << meshName << " " << i+1 << " " << meshName << "_" << i+1 << " localhost " << fileNames[i] << " " << std::endl; -} diff --git a/medtool/src/ParaMEDLoader/ParaMEDLoader.hxx b/medtool/src/ParaMEDLoader/ParaMEDLoader.hxx deleted file mode 100644 index 6a49a470d..000000000 --- a/medtool/src/ParaMEDLoader/ParaMEDLoader.hxx +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __PARAMEDLOADER_HXX__ -#define __PARAMEDLOADER_HXX__ - -#include <string> -#include <vector> - -namespace ParaMEDMEM -{ - class ParaMESH; - class ParaFIELD; -} - -class ParaMEDLoader -{ -public: - static void WriteParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh); - static void WriteMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName); -private: - ParaMEDLoader(); -}; - -#endif diff --git a/medtool/src/ParaMEDMEM/BASICS_JR b/medtool/src/ParaMEDMEM/BASICS_JR deleted file mode 100644 index 61a724d45..000000000 --- a/medtool/src/ParaMEDMEM/BASICS_JR +++ /dev/null @@ -1,339 +0,0 @@ - -Le document de specification : -============================== - -Globalement le document de specification correspond a -l'implementation qui a ete faite avec : - -. Transport-ParaMEDMEM qui a ete enrichi avec la classe MPI_Access - -. Presentation-ParaMEDMEM qui a ete enrichi avec la classe - MPI_AccessDEC - - -La conception correspondant a cette specification est restee -la meme : - -. MPI_Access gere pour un ProcessorGroup (IntraCommunicator) : - - Les structures MPI_Request et MPI_Status - - La valeur des "tags" MPI - - Les requetes d'ecritures et de lectures asynchrones - - Les communications en "Point a Point" [I]Send, [I]Recv ainsi - que [I]SendRecv. - - A la difference de l'API MPI [I]SendRecv ne concerne qu'un - seul et meme "target". - - Les controles de communications asynchrones Wait, Test, - WaitAll, TestAll, [I]Probe, Cancel et CancelAll. - - Comme c'etait demande seules les methodes "utiles" ont ete - implementees. - - Les appels a [I]Send ou a [I]Recv avec des sendbuff/recvbuff - de valeur NULL ou avec des sendcount/recvcount de valeur - nulle sont ignores. - - Les methodes de communications collectives ne sont pas - implementees dans MPI_Access. - - Les deux methodes "Cancel" concernent soit un IRecv deja - soumis soit un message en attente (sans IRecv deja soumis). - Elles regroupent les differents appels de l'API MPI - necessaires (IProbe, IRecv, Wait, Test_Canceled ...). - -. MPI_AccessDEC utilise les services de MPI_Access pour un - ProcessorGroup (IntraCommunicator) et gere : - - Les communications collectives en "Point a Point". - (AllToAll[v] synchrone ou asynchrone). - - Les temps et l'interpolation - - Les [I]Send avec leurs buffers (delete []) - - Les [I]Recv - - La finalisation des envois et receptions de messages dans - le destructeur afin qu'il n'y ait plus de message en attente - et afin de liberer les buffers - - -MPI_Access et "tags" (ou "MPITags") : -===================================== - -. Le constructeur permet optionnellement de fixer une plage de tags - a utiliser : [BaseTag , MaxTag]. - Par defaut c'est [ 0 , MPI_TAG_UB], MPI_TAG_UB etant la valeur - maximum d'une implementation de MPI (valeur minimum 32767 - soit 2**15-1). Sur awa avec l'implementation lam MPI_TAG_UB - vaut 7353944. La norme MPI specifie que cette valeur doit - etre la meme dans les process demarres avec mpirun. - Dans le cas de l'usage simultane du meme IntraCommunicator - dans un meme process (ou de plusieurs IntraCommunicator - d'intersection non nulle) cela peut eviter toute ambiguite - et aider au debug. - -. Dans MPI_Access les tags sont constitues de deux parties - (#define ModuloTag 10) : - + Le dernier digit decimal correspond au MPI_DataType ( 1 pour - les messages "temps", 2 pour MPI_INT et 3 pour MPI_DOUBLE) - + La valeur des autres digits correspond a une numerotation - circulaire des messages. - + Un message "temps" et le message de donnees associe ont le - meme numero de message (mais des types et donc des tags - differents). - -. Pour un envoi de message d'un process "source" vers un process - "target", on dispose de _SendMPITag[target] dans le process - source (il contient le dernier "tag" utilise pour l'envoi de - messages vers le process target). - Et dans le process "target" qui recoit ce message, on dispose - de _RecvMPITag[source] (il contient le dernier "tag" utilise - pour la reception de messages du process source). - Naturellement d'apres la norme MPI les valeurs de ces tags sont - les memes. - - -MPI_Access et "RequestIds" : -============================ - -. ATTENTION : Dans le document de specification, la distinction - n'est pas faite clairement entre les "MPITags" (voir ci-dessus) - qui sont un argument des appels a MPI et les "RequestIds" qui - ne concernent pas les appels MPI. Ces "RequestIds" figurent - en effet sous le nom de tag comme argument d'entree/sortie dans l'API - de MPI_Access decrite dans le document de specification. Mais - dans l'implementation on a bien le nom RequestId (ou bien - RecvRequestId/SendRequestId). - -. Lors de la soumission d'une requete d'ecriture ou de lecture MPI - via MPI_Access, on obtient un identifieur "RequestId". - Cet identifieur "RequestId" correspond a une structure RequestStruct - de MPI_Access a laquelle on accede avec la map - "_MapOfRequestStruct". - Cette structure RequestStruct permet de gerer MPI_Request et - MPI_Status * de MPI et permet d'obtenir des informations sur - la requete : target, send/recv, tag, [a]synchrone, type, outcount. - -. C'est cet identifieur qui peut etre utilise pour controler une - requete asynchrone via MPI_Access : Wait, Test, Probe, etc... - -. En pratique "RequestId" est simplement un entier de l'intervalle - [0 , 2**32-1]. Il y a uniquement un compteur cyclique global - aussi bien pour les [I]Send que pour les [I]Recv. - -. Ces "RequestIds" et leur structures associees facilitent les - communications asynchrones. - Par exemple on a mpi_access->Wait( int RequestId ) - au lieu de MPI_Wait(MPI_Request *request, MPI_Status *status) - avec gestion de status. - -. L'API de MPI_Access peut fournir les "SendRequestIds" d'un "target", - les "RecvRequestIds" d'un "source" ou bien les "SendRequestIds" de - tous les "targets" ou les "RecvRequestIds" de tous les "sources". - Cela permet d'eviter leur gestion au niveau de Presentation-ParaMEDMEM. - - -MPI_AccessDEC : -=============== - -. Comme la classe DEC, il est base sur local_group et distant_group - ce qui forme un MPI_union_group et donc un IntraCommunicator. - -. Il permet de choisir le mode synchrone ou asynchrone (par defaut). - Le meme programme peut fonctionner en synchrone ou en asynchrone - sans devoir etre modifie. - -. Il permet de choisir un mode d'interpolation (actuellement - uniquement une interpolation lineaire) ou bien un mode sans - interpolation (par defaut). Ceci pour les communications collectives. - Avec interpolation les communications collectives transmettent et - recoivent un message "temps" en plus des donnees. - -. Il implemente AllToAll[v] en "Point a Point" avec ou sans interpolation. - -. Il gere les buffers d'envoi de messages. Il les detruit donc - lorsqu'ils sont disponibles. - -. Il cree et utilise MPI_Access. - - -MPI_AccessDEC et la gestion des SendBuffers : -============================================= - -. Comme dans les communications collectives on n'envoie que des - parties du meme buffer à chaque process "target", il faut s'assurer - en asynchrone que toutes ces parties sont disponibles pour - pouvoir liberer le buffer. - -. On suppose que ces buffers ont ete alloues avec un new double[] - -. La structure SendBuffStruct permet de conserver l'adresse du buffer - et de gerer un compteur de references de ce buffer. Elle comporte - aussi MPI_Datatype pour pouvoir faire un delete [] (double *) ... - lorsque le compteur est null. - -. La map _MapOfSendBuffers etablit la correspondance entre chaque - RequestId obtenu de MPI_Access->ISend(...) et un SendBuffStruct - pour chaque "target" d'une partie du buffer. - -. Tout cela ne concerne que les envois asynchrones. En synchrone, - on detruit senbuf juste apres l'avoir transmis. - - -MPI_AccessDEC et la gestion des RecvBuffers : -============================================= - -S'il n'y a pas d'interpolation, rien de particulier n'est fait. - -Avec interpolation pour chaque target : ---------------------------------------- -. On a _TimeMessages[target] qui est un vecteur de TimesMessages. - On en a 2 dans notre cas avec une interpolation lineaire qui - contiennent le time(t0)/deltatime precedent et le dernier - time(t1)/deltatime. - -. On a _DataMessages[target] qui est un vecteur de DatasMessages - On en a 2 dans notre cas avec une interpolation lineaire qui - contiennent les donnees obtenues par Recv au time(t0)/deltatime - precedent et au dernier time(t1)/deltatime. - -. Au temps _t(t*) du processus courrant on effectue l'interpolation - entre les valeurs des 2 DatasMessages que l'on rend dans la - partie de recvbuf correspondant au target pourvu que t0 < t* <= t1. - -. Par suite de la difference des "deltatimes" entre process, on - peut avoir t0 < t1 < t* auquel cas on aura une extrapolation. - -. Les vecteurs _OutOfTime, _DataMessagesRecvCount et _DataMessagesType - contiennent pour chaque target true si t* > dernier t1, recvcount et - MPI_Datatype pour finaliser la gestion des messages a la fin. - - -Etapes des communications collectives de MPI_AccessDEC : -======================================================== - -AllToAll[v] : Les arguments sont les memes que dans MPI sauf MPI_Comm -------------- inutile (deja connu de MPI_AccessDEC et MPI_Access). - - Si on a un TimeInterpolator, appel de AllToAll[v]Time. - - Sinon, on appelle CheckSent pour les echanges - asynchrones (voir ci-apres) et on appelle SendRecv - pour chaque "target". - -AllToAll[v]Time : ------------------ - -. CheckSent() : - + appelle SendRequestIds de MPI_Access afin d'obtenir tous les - RequestIds d'envoi de messages a tous les "targets". - + Pour chaque RequestId, appelle Test de MPI_Access pour savoir - si le buffer est libre (flag = true). Lorsqu'il s'agit du - FinalCheckSent, on appelle Wait au lieu de Test. - + Si le buffer est libre, on decremente le compteur de la - structure SendBuffStruct obtenue avec _MapOfSendBuffers. - (voir MPI_AccessDEC et la gestion des SendBuffers ci-dessus) - + Si le compteur est nul on detruit le TimeMessage ou le - SendBuffer en fonction du DataType. - + Puis on detruit la structure SendBuffStruct avant de supprimer - (erase) cet item de _MapOfSendBuffers - -. DoSend : - + On cree un TimeMessage (voir cette structure dans MPI_Access). - + Si l'on est en asynchrone on cree deux structures SendBuffStruct - aSendTimeStruct et aSendDataStruct que l'on remplit. - + On remplit la structure aSendTimeMessage avec time/deltatime du - process courant. "deltatime" doit etre nul s'il s'agit du dernier - pas de temps. - + Puis pour chaque "target", on envoie le TimeMessage et la partie - de sendbuf concernee par ce target. - + Si l'on est en asynchrone, on incremente le compteur et on ajoute - a _MapOfSendBuffers aSendTimeStruct et aSendDataStruct avec les - identifieurs SendTimeRequestId et SendDataRequestId recus de - MPI_Access->Send(...). - + Et enfin si l'on est en synchrone, on detruit les SendMessages. - -. CheckTime(recvcount , recvtype , target , UntilEnd) - + Au depart, on lit le premier "Message-temps" dans - &(*_TimeMessages)[target][1] et le premier message de donnees - dans le buffer alloue (*_DataMessages)[target][1]. - + Par convention deltatime des messages temps est nul si c'est le - dernier. - + Boucle while : _t(t*) est le temps courant du processus. - "tant que _t(t*) est superieur au temps du "target" - (*_TimeMessages)[target][1].time et que - (*_TimeMessages)[target][1].deltatime n'est pas nul", - ainsi en fin de boucle on aura : - _t(t*) <= (*_TimeMessages)[target][1].time avec - _t(t*) > (*_TimeMessages)[target][0].time - ou bien on aura le dernier message temps du "target". - + S'il s'agit de la finalisation des receptions des messages - temps et donnees (UntilEnd vaut true), on effectue la - boucle jusqu'a ce que l'on trouve - (*_TimeMessages)[target][1].deltatime nul. - + Dans la boucle : - On recopie le dernier message temps dans le message temps - precedent et on lit le message temps suivant. - On detruit le buffer de donnees du temps precedent. - On recopie le pointeur du dernier buffer de donnees dans - le precedent. - On alloue un nouveau dernier buffer de donnees - (*_DataMessages)[target][1] et on lit les donnees - correspondantes dans ce buffer. - + Si le temps courant du process est plus grand que le dernier - temps (*_TimeMessages)[target][1].time du target, on donne - la valeur true a (*_OutOfTime)[target]. - (*_TimeMessages)[target][1].deltatime est alors nul. - -. CheckTime + DoRecv + DoInterp - + Pour chaque target on appelle CheckTime - + Si on a un TimeInterpolator et si le message temps du target - n'est pas le premier, on appelle l'interpolateur qui stocke - ses resultats dans la partie du buffer de reception qui - correspond au "target". - + Sinon, on recopie les donnees recues pour ce premier pas de - temps dans la partie du buffer de reception qui correspond au - "target". - - -Presentation-ParaMEDMEM : -========================= - -. Des modifications mineures ont ete effectuees dans Presentation-ParaMEDMEM - afin de pouvoir utiliser ces nouvelles fonctionnalites. Il n'y - a surtout pas eu de bouleversement destabilisateur. L'ancien - mode de fonctionnement reste naturellement disponible. - -. Cela repose sur trois nouvelles options creees avec registerOption - dans le constructeur de InterpKernelDEC : - + Asynchronous : true ou false (par defaut) - + TimeInterpolation : WithoutTimeInterp (par defaut) ou LinearTimeInterp - typedef enum{WithoutTimeInterp,LinearTimeInterp} TimeInterpolationMethod; - dans MPI_AccessDEC.hxx - + AllToAllMethod : Native (par defaut) ou PointToPoint - typedef enum{Native,PointToPoint} AllToAllMethod; - dans MxN_Mapping.hxx - -. Le choix des options se fait avec le Data Exchange Channel : - + ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); - + dec.setOption("Asynchronous",true); - + dec.setOption("TimeInterpolation",LinearTimeInterp); - + dec.setOption("AllToAllMethod",PointToPoint); - -. Dans dec.synchronize(), - + on cree un objet InterpolationMatrix - qui lui-meme cree un objet MxN_Mapping - qui lui-meme cree maintenant un objet MPI_AccessDEC - + on transmet a MxN_Mapping via l'InterpolationMatrix l'option - choisie de AllToAllMethod - + on transmet a MPI_AccessDEC les valeurs des options Asynchronous - et TimeInterpolation : methodes Asynchronous et - SetTimeInterpolator de MPI_AccessDEC. - -. ParaMEDMEM::InterpKernelDEC comporte maintenant une surcharge des - methodes recvData() et sendData() : - + void InterpKernelDEC::recvData( double time ) qui appelle - SetTime(time) de MPI_AccessDEC et - recvData() - + void InterpKernelDEC::sendData( double time , double deltatime ) - qui appelle - SetTime(time,deltatime) de MPI_AccessDEC et - sendData() - -. recvData() et sendData() de ParaMEDMEM::InterpKernelDEC - appellent multiply et transposeMultiply de l'InterpolationMatrix - qui appellent sendRecv et reverseSendRecv de MxN_Mapping - qui appellent comm_interface.allToAllV en mode "Native" - ou bien MPI_AccessDEC::AllToAllv en mode "PointToPoint" - diff --git a/medtool/src/ParaMEDMEM/BlockTopology.cxx b/medtool/src/ParaMEDMEM/BlockTopology.cxx deleted file mode 100644 index 7297be21c..000000000 --- a/medtool/src/ParaMEDMEM/BlockTopology.cxx +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "BlockTopology.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingCMesh.hxx" -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "ComponentTopology.hxx" -#include "InterpKernelUtilities.hxx" - -#include <vector> -#include <algorithm> -#include <utility> -#include <iostream> - -using namespace std; - -namespace ParaMEDMEM -{ - /*! - * Default ctor. - */ - BlockTopology::BlockTopology() : - _dimension(0), _nb_procs_per_dim(0), - _local_array_indices(0), _cycle_type(0), - _proc_group(NULL),_nb_elems(0), - _owns_processor_group(false) - {} - - /*! - * Constructor of a block topology from a grid. - * This preliminary version simply splits along the first axis - * instead of making the best choice with respect to the - * values of the different axes. - */ - BlockTopology::BlockTopology(const ProcessorGroup& group, MEDCouplingCMesh *grid): - _dimension(grid->getSpaceDimension()), _proc_group(&group), _owns_processor_group(false) - { - vector <int> axis_length(_dimension); - _nb_elems=1; - for (int idim=0; idim <_dimension; idim++) - { - DataArrayDouble *arr=grid->getCoordsAt(idim); - axis_length[idim]=arr->getNbOfElems(); - _nb_elems*=axis_length[idim]; - } - //default splitting along 1st dimension - _local_array_indices.resize(_dimension); - _nb_procs_per_dim.resize(_dimension); - - _local_array_indices[0].resize(_proc_group->size()+1); - _local_array_indices[0][0]=0; - _nb_procs_per_dim[0]=_proc_group->size(); - - for (int i=1; i<=_proc_group->size(); i++) - { - _local_array_indices[0][i]=_local_array_indices[0][i-1]+ - axis_length[0]/_proc_group->size(); - if (i<= axis_length[0]%_proc_group->size()) - _local_array_indices[0][i]+=1; - } - for (int i=1; i<_dimension; i++) - { - _local_array_indices[i].resize(2); - _local_array_indices[i][0]=0; - _local_array_indices[i][1]=axis_length[i]; - _nb_procs_per_dim[i]=1; - } - _cycle_type.resize(_dimension); - for (int i=0; i<_dimension; i++) - _cycle_type[i]=ParaMEDMEM::Block; - } - - /*! - * Creation of a block topology by composing - * a geometrical topology and a component topology. - * This constructor is intended for creating fields - * for which the parallel distribution is made on the - * components of the field rather than on the geometrical - * partitioning of the underlying mesh. - * - */ - BlockTopology::BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo):_owns_processor_group(false) - { - // so far, the block topology can only be created if the proc group - // is either on geom_topo or on comp_topo - if (geom_topo.getProcGroup()->size()>1 && comp_topo.nbBlocks()>1) - throw INTERP_KERNEL::Exception(LOCALIZED("BlockTopology cannot yet be constructed with both complex geo and components topology")); - - if (comp_topo.nbComponents()==1) - { - *this=geom_topo; - return; - } - else - { - _dimension = geom_topo.getDimension()+1; - if (comp_topo.nbBlocks()>1) - _proc_group=comp_topo.getProcGroup(); - else - _proc_group=geom_topo.getProcGroup(); - _local_array_indices=geom_topo._local_array_indices; - vector<int> comp_indices = *(comp_topo.getBlockIndices()); - _local_array_indices.push_back(comp_indices); - _nb_procs_per_dim=geom_topo._nb_procs_per_dim; - _nb_procs_per_dim.push_back(comp_topo.nbBlocks()); - _cycle_type=geom_topo._cycle_type; - _cycle_type.push_back(Block); - _nb_elems=geom_topo.getNbElements()*comp_topo.nbComponents(); - } - } - - /*! Constructor for creating a one-dimensional - * topology from a processor group and a local - * number of elements on each processor - * - * The function must be called only by the processors belonging - * to group \a group. Calling it from a processor not belonging - * to \a group will cause an MPI error, while calling from a subset - * of \a group will result in a deadlock. - */ - BlockTopology::BlockTopology(const ProcessorGroup& group, int nb_elem):_dimension(1),_proc_group(&group),_owns_processor_group(false) - { - int* nbelems_per_proc = new int[group.size()]; - const MPIProcessorGroup* mpi_group=dynamic_cast<const MPIProcessorGroup*>(_proc_group); - const MPI_Comm* comm=mpi_group->getComm(); - int nbtemp=nb_elem; - mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_INT, - nbelems_per_proc, 1, MPI_INT, - *comm); - _nb_elems=0; - - //splitting along only dimension - _local_array_indices.resize(1); - _nb_procs_per_dim.resize(1); - - _local_array_indices[0].resize(_proc_group->size()+1); - _local_array_indices[0][0]=0; - _nb_procs_per_dim[0]=_proc_group->size(); - - for (int i=1; i<=_proc_group->size(); i++) - { - _local_array_indices[0][i]=_local_array_indices[0][i-1]+ - nbelems_per_proc[i-1]; - _nb_elems+=nbelems_per_proc[i-1]; - } - _cycle_type.resize(1); - _cycle_type[0]=ParaMEDMEM::Block; - delete[] nbelems_per_proc; - } - - BlockTopology::~BlockTopology() - { - if (_owns_processor_group) - delete _proc_group; - } - - //!converts a pair <subdomainid,local> to a global number - std::pair<int,int> BlockTopology::globalToLocal(const int global) const - { - int subdomain_id=0; - int position=global; - int size=_nb_elems; - int size_procs=_proc_group->size(); - int increment=size; - vector<int>axis_position(_dimension); - vector<int>axis_offset(_dimension); - for (int idim=0; idim<_dimension; idim++) - { - int axis_size=_local_array_indices[idim].size()-1; - int axis_nb_elem=_local_array_indices[idim][axis_size]; - increment=increment/axis_nb_elem; - int proc_increment = size_procs/(axis_size); - int axis_pos=position/increment; - position=position%increment; - int iaxis=1; - while (_local_array_indices[idim][iaxis]<=axis_pos) - { - subdomain_id+=proc_increment; - iaxis++; - } - axis_position[idim]=axis_pos-_local_array_indices[idim][iaxis-1]; - axis_offset[idim]=iaxis; - } - int local=0; - int local_increment=1; - for (int idim=_dimension-1; idim>=0; idim--) - { - local+=axis_position[idim]*local_increment; - local_increment*=_local_array_indices[idim][axis_offset[idim]]-_local_array_indices[idim][axis_offset[idim]-1]; - } - return make_pair(subdomain_id,local); - } - - //!converts local number to a global number - int BlockTopology::localToGlobal(const pair<int,int> local) const - { - - int subdomain_id=local.first; - int global=0; - int loc=local.second; - int increment=_nb_elems; - int proc_increment=_proc_group->size(); - int local_increment=getNbLocalElements(); - for (int idim=0; idim < _dimension; idim++) - { - int axis_size=_local_array_indices[idim].size()-1; - int axis_nb_elem=_local_array_indices[idim][axis_size]; - increment=axis_nb_elem==0?0:increment/axis_nb_elem; - proc_increment = proc_increment/(axis_size); - int proc_axis=subdomain_id/proc_increment; - subdomain_id=subdomain_id%proc_increment; - int local_axis_nb_elem=_local_array_indices[idim][proc_axis+1]-_local_array_indices[idim][proc_axis]; - local_increment = (local_axis_nb_elem==0)?0:(local_increment/local_axis_nb_elem); - int iaxis=((local_increment==0)?0:(loc/local_increment))+_local_array_indices[idim][proc_axis]; - global+=increment*iaxis; - loc = (local_increment==0)?0:(loc%local_increment); - } - return global; - } - - //Retrieves the local number of elements - int BlockTopology::getNbLocalElements()const - { - int position=_proc_group->myRank(); - int nb_elem = 1; - int increment=1; - for (int i=_dimension-1; i>=0; i--) - { - increment *=_nb_procs_per_dim[i]; - int idim=position%increment; - position=position/increment; - int imin=_local_array_indices[i][idim]; - int imax=_local_array_indices[i][idim+1]; - nb_elem*=(imax-imin); - } - return nb_elem; - } - - /*! Retrieves the min and max indices of the domain stored locally - * for each dimension. The output vector has the topology dimension - * as a size and each pair <int,int> contains min and max. Indices - * range from min to max-1. - */ - std::vector<std::pair<int,int> > BlockTopology::getLocalArrayMinMax() const - { - vector<pair<int,int> > local_indices (_dimension); - int myrank=_proc_group->myRank(); - int increment=1; - for (int i=_dimension-1; i>=0; i--) - { - increment *=_nb_procs_per_dim[i]; - int idim=myrank%increment; - local_indices[i].first=_local_array_indices[i][idim]; - local_indices[i].second=_local_array_indices[i][idim+1]; - cout << local_indices[i].first << " "<< local_indices[i].second<<endl; - } - return local_indices; - } - - /*! Serializes the data contained in the Block Topology - * for communication purposes*/ - void BlockTopology::serialize(int* & serializer, int& size) const - { - vector<int> buffer; - - buffer.push_back(_dimension); - buffer.push_back(_nb_elems); - for (int i=0; i<_dimension; i++) - { - buffer.push_back(_nb_procs_per_dim[i]); - buffer.push_back(_cycle_type[i]); - buffer.push_back(_local_array_indices[i].size()); - for (int j=0; j<(int)_local_array_indices[i].size(); j++) - buffer.push_back(_local_array_indices[i][j]); - } - - //serializing the comm group - int size_comm=_proc_group->size(); - buffer.push_back(size_comm); - MPIProcessorGroup world_group(_proc_group->getCommInterface()); - for (int i=0; i<size_comm;i++) - { - int world_rank=world_group.translateRank(_proc_group, i); - buffer.push_back(world_rank); - } - - serializer=new int[buffer.size()]; - size=buffer.size(); - copy(buffer.begin(), buffer.end(), serializer); - } - - /*! - * - * Unserializes the data contained in the Block Topology - * after communication. Uses the same structure as the one used for serialize() - * - */ - void BlockTopology::unserialize(const int* serializer,const CommInterface& comm_interface) - { - const int* ptr_serializer=serializer; - cout << "unserialize..."<<endl; - _dimension=*(ptr_serializer++); - cout << "dimension "<<_dimension<<endl; - _nb_elems=*(ptr_serializer++); - cout << "nbelems "<<_nb_elems<<endl; - _nb_procs_per_dim.resize(_dimension); - _cycle_type.resize(_dimension); - _local_array_indices.resize(_dimension); - for (int i=0; i<_dimension; i++) - { - _nb_procs_per_dim[i]=*(ptr_serializer++); - _cycle_type[i]=(CYCLE_TYPE)*(ptr_serializer++); - _local_array_indices[i].resize(*(ptr_serializer++)); - for (int j=0; j<(int)_local_array_indices[i].size(); j++) - _local_array_indices[i][j]=*(ptr_serializer++); - } - set<int> procs; - int size_comm=*(ptr_serializer++); - for (int i=0; i<size_comm; i++) - procs.insert(*(ptr_serializer++)); - cout << "unserialize..."<<procs.size()<<endl; - _proc_group=new MPIProcessorGroup(comm_interface,procs); - _owns_processor_group=true; - //TODO manage memory ownership of _proc_group - } -} diff --git a/medtool/src/ParaMEDMEM/BlockTopology.hxx b/medtool/src/ParaMEDMEM/BlockTopology.hxx deleted file mode 100644 index 37466731d..000000000 --- a/medtool/src/ParaMEDMEM/BlockTopology.hxx +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __BLOCKTOPOLOGY_HXX__ -#define __BLOCKTOPOLOGY_HXX__ - -#include "Topology.hxx" -#include "ProcessorGroup.hxx" - -#include <vector> - -namespace ParaMEDMEM -{ - class ComponentTopology; - class MEDCouplingCMesh; - - typedef enum{Block,Cycle} CYCLE_TYPE; - - /*! - * \anchor BlockTopology-det - * - * A BlockTopology typically represents the split of a *structured* mesh among the processors of - * a common ProcessorGroup. Each processor gets a contiguous part of the cells in the mesh (a block). - * - * A BlockTopology can also be used to split a structured domain among the various components of a field. - * - * \sa ExplicitTopology - */ - class BlockTopology : public Topology - { - public: - BlockTopology(); - BlockTopology(const ProcessorGroup& group, MEDCouplingCMesh *grid); - BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo); - BlockTopology(const ProcessorGroup& group, int nb_elem); - virtual ~BlockTopology(); - //!Retrieves the number of elements for a given topology - int getNbElements()const { return _nb_elems; } - int getNbLocalElements() const; - const ProcessorGroup* getProcGroup()const { return _proc_group; } - std::pair<int,int> globalToLocal (const int) const ; - int localToGlobal (const std::pair<int,int>) const; - std::vector<std::pair<int,int> > getLocalArrayMinMax() const ; - int getDimension() const { return _dimension; } - void serialize(int* & serializer, int& size) const ; - void unserialize(const int* serializer, const CommInterface& comm_interface); - private: - //dimension : 2 or 3 - int _dimension; - //proc array - std::vector<int> _nb_procs_per_dim; - //stores the offsets vector - std::vector<std::vector<int> > _local_array_indices; - //stores the cycle type (block or cyclic) - std::vector<CYCLE_TYPE> _cycle_type; - //Processor group - const ProcessorGroup* _proc_group; - //nb of elements - int _nb_elems; - bool _owns_processor_group; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/CMakeLists.txt b/medtool/src/ParaMEDMEM/CMakeLists.txt deleted file mode 100644 index cede08235..000000000 --- a/medtool/src/ParaMEDMEM/CMakeLists.txt +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author : Anthony Geay (CEA/DEN) - -ADD_DEFINITIONS(${MPI_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${MPI_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SET(paramedmem_SOURCES - ProcessorGroup.cxx - MPIProcessorGroup.cxx - ParaMESH.cxx - ComponentTopology.cxx - MPIAccess.cxx - InterpolationMatrix.cxx - OverlapInterpolationMatrix.cxx - StructuredCoincidentDEC.cxx - ExplicitCoincidentDEC.cxx - InterpKernelDEC.cxx - ElementLocator.cxx - OverlapElementLocator.cxx - MPIAccessDEC.cxx - TimeInterpolator.cxx - LinearTimeInterpolator.cxx - DEC.cxx - DisjointDEC.cxx - OverlapDEC.cxx - ExplicitTopology.cxx - MxN_Mapping.cxx - OverlapMapping.cxx - ICoCoMEDField.cxx - ICoCoField.cxx - ParaFIELD.cxx - ParaGRID.cxx - BlockTopology.cxx - ExplicitMapping.cxx - ) - -ADD_LIBRARY(paramedmem SHARED ${paramedmem_SOURCES}) -TARGET_LINK_LIBRARIES(paramedmem medcoupling ${MPI_LIBRARIES}) -INSTALL(TARGETS paramedmem EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -FILE(GLOB paramedmem_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") -INSTALL(FILES ${paramedmem_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) - -# To allow usage as SWIG dependencies: -SET(paramedmem_HEADERS_HXX PARENT_SCOPE) diff --git a/medtool/src/ParaMEDMEM/CommInterface.cxx b/medtool/src/ParaMEDMEM/CommInterface.cxx deleted file mode 100644 index 54e06e6fc..000000000 --- a/medtool/src/ParaMEDMEM/CommInterface.cxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CommInterface.hxx" - -namespace ParaMEDMEM -{ - /*! \anchor CommInterface-det - \class CommInterface - - The class \a CommInterface is the gateway to the MPI library. - It is a wrapper around all MPI calls, thus trying to abstract the rest of the code from using the direct MPI API - (but this is not strictly respected overall in practice ...). It is used in all - the \ref parallel "DEC related classes". - - It is typically instanciated after the MPI_Init() call in a program and is afterwards passed as a - parameter to the constructors of various \ref parallel "parallel objects" so that they access the - MPI library via this common interface. - - As an example, the following code excerpt initializes a processor group made of the zero processor. - - \verbatim - #include "CommInterface.hxx" - #include "ProcessorGroup.hxx" - - int main(int argc, char** argv) - { - //initialization - MPI_Init(&argc, &argv); - ParaMEDMEM::CommInterface comm_interface; - - //setting up a processor group with proc 0 - set<int> procs; - procs.insert(0); - ParaMEDMEM::ProcessorGroup group(procs, comm_interface); - - //cleanup - MPI_Finalize(); - } - \endverbatim - */ - - CommInterface::CommInterface() - { - } - - CommInterface::~CommInterface() - { - } -} diff --git a/medtool/src/ParaMEDMEM/CommInterface.hxx b/medtool/src/ParaMEDMEM/CommInterface.hxx deleted file mode 100644 index ae430eddd..000000000 --- a/medtool/src/ParaMEDMEM/CommInterface.hxx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __COMMINTERFACE_HXX__ -#define __COMMINTERFACE_HXX__ - -#include <mpi.h> -namespace ParaMEDMEM -{ - - class CommInterface - { - public: - CommInterface(){} - virtual ~CommInterface(){} - int worldSize() const { - int size; - MPI_Comm_size(MPI_COMM_WORLD, &size); - return size;} - int commSize(MPI_Comm comm, int* size) const { return MPI_Comm_size(comm,size); } - int commRank(MPI_Comm comm, int* rank) const { return MPI_Comm_rank(comm,rank); } - int commGroup(MPI_Comm comm, MPI_Group* group) const { return MPI_Comm_group(comm, group); } - int groupIncl(MPI_Group group, int size, int* ranks, MPI_Group* group_output) const { return MPI_Group_incl(group, size, ranks, group_output); } - int commCreate(MPI_Comm comm, MPI_Group group, MPI_Comm* comm_output) const { return MPI_Comm_create(comm,group,comm_output); } - int groupFree(MPI_Group* group) const { return MPI_Group_free(group); } - int commFree(MPI_Comm* comm) const { return MPI_Comm_free(comm); } - - int send(void* buffer, int count, MPI_Datatype datatype, int target, int tag, MPI_Comm comm) const { return MPI_Send(buffer,count, datatype, target, tag, comm); } - int recv(void* buffer, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status* status) const { return MPI_Recv(buffer,count, datatype, source, tag, comm, status); } - int sendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, - int dest, int sendtag, void* recvbuf, int recvcount, - MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, - MPI_Status* status) { return MPI_Sendrecv(sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, recvcount, recvtype, source, recvtag, comm,status); } - - int Isend(void* buffer, int count, MPI_Datatype datatype, int target, - int tag, MPI_Comm comm, MPI_Request *request) const { return MPI_Isend(buffer,count, datatype, target, tag, comm, request); } - int Irecv(void* buffer, int count, MPI_Datatype datatype, int source, - int tag, MPI_Comm comm, MPI_Request* request) const { return MPI_Irecv(buffer,count, datatype, source, tag, comm, request); } - - int wait(MPI_Request *request, MPI_Status *status) const { return MPI_Wait(request, status); } - int test(MPI_Request *request, int *flag, MPI_Status *status) const { return MPI_Test(request, flag, status); } - int requestFree(MPI_Request *request) const { return MPI_Request_free(request); } - int waitany(int count, MPI_Request *array_of_requests, int *index, MPI_Status *status) const { return MPI_Waitany(count, array_of_requests, index, status); } - int testany(int count, MPI_Request *array_of_requests, int *index, int *flag, MPI_Status *status) const { return MPI_Testany(count, array_of_requests, index, flag, status); } - int waitall(int count, MPI_Request *array_of_requests, MPI_Status *array_of_status) const { return MPI_Waitall(count, array_of_requests, array_of_status); } - int testall(int count, MPI_Request *array_of_requests, int *flag, MPI_Status *array_of_status) const { return MPI_Testall(count, array_of_requests, flag, array_of_status); } - int waitsome(int incount, MPI_Request *array_of_requests,int *outcount, int *array_of_indices, MPI_Status *array_of_status) const { return MPI_Waitsome(incount, array_of_requests, outcount, array_of_indices, array_of_status); } - int testsome(int incount, MPI_Request *array_of_requests, int *outcount, - int *array_of_indices, MPI_Status *array_of_status) const { return MPI_Testsome(incount, array_of_requests, outcount, array_of_indices, array_of_status); } - int probe(int source, int tag, MPI_Comm comm, MPI_Status *status) const { return MPI_Probe(source, tag, comm, status) ; } - int Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status) const { return MPI_Iprobe(source, tag, comm, flag, status) ; } - int cancel(MPI_Request *request) const { return MPI_Cancel(request); } - int testCancelled(MPI_Status *status, int *flag) const { return MPI_Test_cancelled(status, flag); } - int barrier(MPI_Comm comm) const { return MPI_Barrier(comm); } - int errorString(int errorcode, char *string, int *resultlen) const { return MPI_Error_string(errorcode, string, resultlen); } - int getCount(MPI_Status *status, MPI_Datatype datatype, int *count) const { return MPI_Get_count(status, datatype, count); } - - int broadcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) const { return MPI_Bcast(buffer, count, datatype, root, comm); } - int allGather(void* sendbuf, int sendcount, MPI_Datatype sendtype, - void* recvbuf, int recvcount, MPI_Datatype recvtype, - MPI_Comm comm) const { return MPI_Allgather(sendbuf,sendcount, sendtype, recvbuf, recvcount, recvtype, comm); } - int allToAll(void* sendbuf, int sendcount, MPI_Datatype sendtype, - void* recvbuf, int recvcount, MPI_Datatype recvtype, - MPI_Comm comm) const { return MPI_Alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm); } - int allToAllV(void* sendbuf, int* sendcounts, int* senddispls, - MPI_Datatype sendtype, void* recvbuf, int* recvcounts, - int* recvdispls, MPI_Datatype recvtype, - MPI_Comm comm) const { return MPI_Alltoallv(sendbuf, sendcounts, senddispls, sendtype, recvbuf, recvcounts, recvdispls, recvtype, comm); } - - int reduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, - MPI_Op op, int root, MPI_Comm comm) const { return MPI_Reduce(sendbuf, recvbuf, count, datatype, op, root, comm); } - int allReduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) const { return MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm); } - }; -} - -#endif /*COMMINTERFACE_HXX_*/ diff --git a/medtool/src/ParaMEDMEM/ComponentTopology.cxx b/medtool/src/ParaMEDMEM/ComponentTopology.cxx deleted file mode 100644 index 8af706e59..000000000 --- a/medtool/src/ParaMEDMEM/ComponentTopology.cxx +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ComponentTopology.hxx" -#include "ProcessorGroup.hxx" -#include "InterpolationUtils.hxx" - -namespace ParaMEDMEM -{ - /* Generic constructor for \a nb_comp components equally parted - * in \a nb_blocks blocks - */ - ComponentTopology::ComponentTopology(int nb_comp, ProcessorGroup* group):_proc_group(group) - { - int nb_blocks=group->size(); - - if (nb_blocks>nb_comp) - throw INTERP_KERNEL::Exception("ComponentTopology Number of components must be larger than number of blocks"); - - _component_array.resize(nb_blocks+1); - _component_array[0]=0; - for (int i=1; i<=nb_blocks; i++) - { - _component_array[i]=_component_array[i-1]+nb_comp/nb_blocks; - if (i<=nb_comp%nb_blocks) - _component_array[i]++; - } - } - - /* Generic constructor for \a nb_comp components equally parted - * in \a nb_blocks blocks - */ - ComponentTopology::ComponentTopology(int nb_comp, int nb_blocks):_proc_group(0) - { - if (nb_blocks>nb_comp) - throw INTERP_KERNEL::Exception("ComponentTopology Number of components must be larger than number of blocks"); - - _component_array.resize(nb_blocks+1); - _component_array[0]=0; - for (int i=1; i<=nb_blocks; i++) - { - _component_array[i]=_component_array[i-1]+nb_comp/nb_blocks; - if (i<=nb_comp%nb_blocks) - _component_array[i]++; - } - - } - - //!Constructor for one block of \a nb_comp components - ComponentTopology::ComponentTopology(int nb_comp):_proc_group(0) - { - - _component_array.resize(2); - _component_array[0]=0; - _component_array[1]=nb_comp; - - } - - //! Constructor for one component - ComponentTopology::ComponentTopology():_proc_group(0) - { - _component_array.resize(2); - _component_array[0]=0; - _component_array[1]=1; - - } - - ComponentTopology::~ComponentTopology() - { - } - - int ComponentTopology::nbLocalComponents() const - { - if (_proc_group==0) - return nbComponents(); - - int nbcomp; - int myrank = _proc_group->myRank(); - if (myrank!=-1) - nbcomp = _component_array[myrank+1]-_component_array[myrank]; - else - nbcomp=0; - return nbcomp; - } - - int ComponentTopology::firstLocalComponent() const - { - if (_proc_group==0) - return 0; - - int icomp; - int myrank = _proc_group->myRank(); - if (myrank!=-1) - icomp = _component_array[myrank]; - else - icomp=-1; - return icomp; - } -} diff --git a/medtool/src/ParaMEDMEM/ComponentTopology.hxx b/medtool/src/ParaMEDMEM/ComponentTopology.hxx deleted file mode 100644 index 9b84607a3..000000000 --- a/medtool/src/ParaMEDMEM/ComponentTopology.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __COMPONENTTOPOLOGY_HXX__ -#define __COMPONENTTOPOLOGY_HXX__ - -#include "Topology.hxx" - -#include <vector> - -namespace ParaMEDMEM -{ - class ProcessorGroup; - - /*! - * \anchor ComponentTopology-det - * - * The ComponentTopology can be used when building a ParaFIELD. It allows the splitting of the components - * of the field among different processors within a single processor group. - * - * \sa ParaFIELD::ParaFIELD(TypeOfField , TypeOfTimeDiscretization , ParaMESH* , const ComponentTopology& ) - */ - class ComponentTopology - { - public: - ComponentTopology(int nb_comp, ProcessorGroup* group); - ComponentTopology(int nb_comp, int nb_blocks); - ComponentTopology(int nb_comp); - ComponentTopology(); - virtual ~ComponentTopology(); - //!returns the number of MED components in the topology - int nbComponents() const { return _component_array.back(); } - //!returns the number of MED components on local processor - int nbLocalComponents() const ; - //!returns the number of the first MED component on local processor - int firstLocalComponent() const ; - //!returns the number of blocks in the topology - int nbBlocks()const {return _component_array.size()-1;} - //!returns the block structure - const std::vector<int>* getBlockIndices() const { return &_component_array; } - const ProcessorGroup* getProcGroup()const { return _proc_group; } - private: - std::vector<int> _component_array; - ProcessorGroup* _proc_group; - }; -} - -#endif /*COMPONENTTOPOLOGY_HXX_*/ diff --git a/medtool/src/ParaMEDMEM/DEC.cxx b/medtool/src/ParaMEDMEM/DEC.cxx deleted file mode 100644 index cbd0ea45d..000000000 --- a/medtool/src/ParaMEDMEM/DEC.cxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "ParaMESH.hxx" -#include "DEC.hxx" -#include "ICoCoField.hxx" -#include "ICoCoMEDField.hxx" -#include "MPIProcessorGroup.hxx" - -#include <cmath> - -namespace ParaMEDMEM -{ - DEC::DEC():_comm_interface(0) - { - } - - void DEC::copyFrom(const DEC& other) - { - _comm_interface=other._comm_interface; - } - - DEC::~DEC() - { - } -} diff --git a/medtool/src/ParaMEDMEM/DEC.hxx b/medtool/src/ParaMEDMEM/DEC.hxx deleted file mode 100644 index 6df677bbc..000000000 --- a/medtool/src/ParaMEDMEM/DEC.hxx +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __DEC_HXX__ -#define __DEC_HXX__ - -#include "MEDCouplingFieldDouble.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "DECOptions.hxx" - -namespace ParaMEDMEM -{ - class CommInterface; - - /*! - * DEC stands for Data Exchange Channel. See the page \ref para-dec for more on this. - * - * This class is purely abstract. See the derivations: - * - \ref DisjointDEC-det "DisjointDEC" - * - \ref NonCoincidentDEC "NonCoincidentDEC" - * - \ref OverlapDEC "OverlapDEC" - */ - class DEC : public DECOptions - { - public: - DEC(); - void copyFrom(const DEC& other); - virtual void synchronize() = 0; - virtual void sendRecvData(bool way=true) = 0; - virtual ~DEC(); - protected: - const CommInterface* _comm_interface; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/DECOptions.hxx b/medtool/src/ParaMEDMEM/DECOptions.hxx deleted file mode 100644 index eb9271237..000000000 --- a/medtool/src/ParaMEDMEM/DECOptions.hxx +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __DECOPTIONS_HXX__ -#define __DECOPTIONS_HXX__ - -#include <string> - -namespace ParaMEDMEM -{ - //! Enum describing the allToAll method used in the communication pattern - typedef enum { Native, PointToPoint } AllToAllMethod; - //! Enum describing the time interpolation method - typedef enum { WithoutTimeInterp, LinearTimeInterp } TimeInterpolationMethod; - - /*! - This class groups the various options accepted by all \ref para-dec "DECs" (which all inherit from %DECOptions). - - The following code excerpt shows how to set options on a %DEC : - - \code - InterpKernelDEC dec(source_group,target_group); - dec.setForcedRenormalization(true); - dec.attachLocalField(field); - dec.synchronize(); - if (source_group.containsMyRank()) - dec.sendData(); - else - dec.recvData(); - \endcode - * - * - */ - class DECOptions - { - protected: - std::string _method; - bool _asynchronous; - TimeInterpolationMethod _timeInterpolationMethod; - AllToAllMethod _allToAllMethod; - bool _forcedRenormalization; - public: - DECOptions():_method("P0"), - _asynchronous(false), - _timeInterpolationMethod(WithoutTimeInterp), - _allToAllMethod(Native), - _forcedRenormalization(false) - { - } - - DECOptions(const DECOptions& deco) - { - _method=deco._method; - _timeInterpolationMethod=deco._timeInterpolationMethod; - _asynchronous=deco._asynchronous; - _forcedRenormalization=deco._forcedRenormalization; - _allToAllMethod=deco._allToAllMethod; - } - - - /*! - * \sa setMethod() - */ - const std::string& getMethod() const { return _method; } - /*! - * Set interpolation method. Defaults to "P0". - */ - void setMethod(const char *m) { _method=m; } - - /*! - * \sa setTimeInterpolationMethod() - */ - TimeInterpolationMethod getTimeInterpolationMethod() const { return DECOptions::_timeInterpolationMethod; } - /*! - * Set time interpolation method. Default to WithoutTimeInterp. - */ - void setTimeInterpolationMethod(TimeInterpolationMethod it) { DECOptions::_timeInterpolationMethod=it; } - - /*! - * \sa setForcedRenormalization() - */ - bool getForcedRenormalization() const { return DECOptions::_forcedRenormalization; } - - /*! - * Force renormalization of the field after it has been received so that the total sum - * of the field values are the same on both the sending and the receiving side. Defaults to - * false. - */ - void setForcedRenormalization( bool dr) { DECOptions::_forcedRenormalization = dr; } - - - /*! - * \sa setAsynchronous() - */ - bool getAsynchronous() const { return DECOptions::_asynchronous; } - - /*! - * Switch to asynchronous data transfer mode. Default is false. - */ - void setAsynchronous( bool dr) { DECOptions::_asynchronous = dr; } - - /*! - * \sa setAllToAllMethod() - */ - AllToAllMethod getAllToAllMethod() const { return _allToAllMethod; } - /*! - * Set the broadcast method for synchronisation processes. Default to Native. - */ - void setAllToAllMethod(AllToAllMethod sp) { _allToAllMethod=sp; } - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/DisjointDEC.cxx b/medtool/src/ParaMEDMEM/DisjointDEC.cxx deleted file mode 100644 index b2ba8f795..000000000 --- a/medtool/src/ParaMEDMEM/DisjointDEC.cxx +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "DisjointDEC.hxx" -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "ParaMESH.hxx" -#include "ICoCoField.hxx" -#include "ICoCoMEDField.hxx" -#include "MPIProcessorGroup.hxx" - -#include <cmath> -#include <iostream> - - -namespace ParaMEDMEM -{ - - /*! - * \anchor DisjointDEC-det - * \class DisjointDEC - * - * \section DisjointDEC-over Overview - * - * Abstract interface class representing a link between two - * processor groups for exchanging mesh or field data. The two processor groups must - * have a void intersection (\ref ParaMEDMEM::OverlapDEC "OverlapDEC" is to be considered otherwise). - * The %DEC is initialized by attaching a field on the receiving or on the - * sending side. - * - * The data is sent or received through calls to the (abstract) methods recvData() and sendData(). - * - * One can attach either a \c ParaMEDMEM::ParaFIELD, or a - * \c ICoCo::Field, or directly a \c ParaMEDMEM::MEDCouplingFieldDouble instance. - * See the various signatures of the method DisjointDEC::attachLocalField() - * - * The derivations of this class should be considered for practical instanciation: - * - \ref InterpKernelDEC-det "InterpKernelDEC" - * - \ref ExplicitCoincidentDEC-det "ExplicitCoincidentDEC" - * - \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC" - * - * \section DisjointDEC-options DisjointDEC options - * The options supported by %DisjointDEC objects are the same that the ones supported for all - * DECs in general and are all inherited from the class \ref ParaMEDMEM::DECOptions "DECOptions" - * - */ - - DisjointDEC::DisjointDEC(ProcessorGroup& source_group, ProcessorGroup& target_group): - _local_field(0), - _source_group(&source_group), - _target_group(&target_group), - _comm_interface(0), - _owns_field(false), - _owns_groups(false), - _union_comm(MPI_COMM_NULL) - { - _union_group = source_group.fuse(target_group); - } - - DisjointDEC::DisjointDEC(const DisjointDEC& s): - DEC(s), - _local_field(0), - _union_group(0), - _source_group(0), - _target_group(0), - _comm_interface(0), - _owns_field(false), - _owns_groups(false), - _union_comm(MPI_COMM_NULL) - { - copyInstance(s); - } - - DisjointDEC & DisjointDEC::operator=(const DisjointDEC& s) - { - cleanInstance(); - copyInstance(s); - return *this; - - } - - void DisjointDEC::copyInstance(const DisjointDEC& other) - { - DEC::copyFrom(other); - if(other._target_group) - { - _target_group=other._target_group->deepCpy(); - _owns_groups=true; - } - if(other._source_group) - { - _source_group=other._source_group->deepCpy(); - _owns_groups=true; - } - if (_source_group && _target_group) - _union_group = _source_group->fuse(*_target_group); - } - - DisjointDEC::DisjointDEC(const std::set<int>& source_ids, - const std::set<int>& target_ids, - const MPI_Comm& world_comm): - _local_field(0), - _owns_field(false), - _owns_groups(true), - _comm_interface(0), - _union_comm(MPI_COMM_NULL) - { - ParaMEDMEM::CommInterface comm; - // Create the list of procs including source and target - std::set<int> union_ids; // source and target ids in world_comm - union_ids.insert(source_ids.begin(),source_ids.end()); - union_ids.insert(target_ids.begin(),target_ids.end()); - if(union_ids.size()!=(source_ids.size()+target_ids.size())) - throw INTERP_KERNEL::Exception("DisjointDEC constructor : source_ids and target_ids overlap partially or fully. This type of DEC does not support it! OverlapDEC class could be the solution!"); - int* union_ranks_world=new int[union_ids.size()]; // ranks of sources and targets in world_comm - std::copy(union_ids.begin(), union_ids.end(), union_ranks_world); - - // Create a communicator on these procs - MPI_Group union_group,world_group; - comm.commGroup(world_comm,&world_group); - comm.groupIncl(world_group,union_ids.size(),union_ranks_world,&union_group); - comm.commCreate(world_comm,union_group,&_union_comm); - delete[] union_ranks_world; - if (_union_comm==MPI_COMM_NULL) - { // This process is not in union - _source_group=0; - _target_group=0; - _union_group=0; - comm.groupFree(&union_group); - comm.groupFree(&world_group); - return; - } - - // Translate source_ids and target_ids from world_comm to union_comm - int* source_ranks_world=new int[source_ids.size()]; // ranks of sources in world_comm - std::copy(source_ids.begin(), source_ids.end(),source_ranks_world); - int* source_ranks_union=new int[source_ids.size()]; // ranks of sources in union_comm - int* target_ranks_world=new int[target_ids.size()]; // ranks of targets in world_comm - std::copy(target_ids.begin(), target_ids.end(),target_ranks_world); - int* target_ranks_union=new int[target_ids.size()]; // ranks of targets in union_comm - MPI_Group_translate_ranks(world_group,source_ids.size(),source_ranks_world,union_group,source_ranks_union); - MPI_Group_translate_ranks(world_group,target_ids.size(),target_ranks_world,union_group,target_ranks_union); - std::set<int> source_ids_union; - for (int i=0;i<(int)source_ids.size();i++) - source_ids_union.insert(source_ranks_union[i]); - std::set<int> target_ids_union; - for (int i=0;i<(int)target_ids.size();i++) - target_ids_union.insert(target_ranks_union[i]); - delete [] source_ranks_world; - delete [] source_ranks_union; - delete [] target_ranks_world; - delete [] target_ranks_union; - - // Create the MPIProcessorGroups - _source_group = new MPIProcessorGroup(comm,source_ids_union,_union_comm); - _target_group = new MPIProcessorGroup(comm,target_ids_union,_union_comm); - _union_group = _source_group->fuse(*_target_group); - comm.groupFree(&union_group); - comm.groupFree(&world_group); - } - - DisjointDEC::~DisjointDEC() - { - cleanInstance(); - } - - void DisjointDEC::cleanInstance() - { - if(_owns_field) - { - delete _local_field; - } - _local_field=0; - _owns_field=false; - if(_owns_groups) - { - delete _source_group; - delete _target_group; - } - _owns_groups=false; - _source_group=0; - _target_group=0; - delete _union_group; - _union_group=0; - if (_union_comm != MPI_COMM_NULL) - _comm_interface->commFree(&_union_comm); - } - - void DisjointDEC::setNature(NatureOfField nature) - { - if(_local_field) - _local_field->getField()->setNature(nature); - } - - /*! Attaches a local field to a DEC. - If the processor is on the receiving end of the DEC, the field - will be updated by a recvData() call. - Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side. - */ - void DisjointDEC::attachLocalField(const ParaFIELD *field, bool ownPt) - { - if(!isInUnion()) - return ; - if(_owns_field) - delete _local_field; - _local_field=field; - _owns_field=ownPt; - _comm_interface=&(field->getTopology()->getProcGroup()->getCommInterface()); - compareFieldAndMethod(); - } - - /*! Attaches a local field to a DEC. The method will test whether the processor - is on the source or the target side and will associate the mesh underlying the - field to the local side. - - If the processor is on the receiving end of the DEC, the field - will be updated by a recvData() call. - Reversely, if the processor is on the sending end, the field will be read, possibly transformed, - and sent appropriately to the other side. - */ - - void DisjointDEC::attachLocalField(MEDCouplingFieldDouble *field) - { - if(!isInUnion()) - return ; - ProcessorGroup* local_group; - if (_source_group->containsMyRank()) - local_group=_source_group; - else if (_target_group->containsMyRank()) - local_group=_target_group; - else - throw INTERP_KERNEL::Exception("Invalid procgroup for field attachment to DEC"); - ParaMESH *paramesh=new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())),*local_group,field->getMesh()->getName()); - ParaFIELD *tmp=new ParaFIELD(field, paramesh, *local_group); - tmp->setOwnSupport(true); - attachLocalField(tmp,true); - //_comm_interface=&(local_group->getCommInterface()); - } - - /*! - Attaches a local field to a DEC. - If the processor is on the receiving end of the DEC, the field - will be updated by a recvData() call. - Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side. - The field type is a generic ICoCo Field, so that the DEC can couple a number of different fields : - - a ICoCo::MEDField, that is created from a MEDCoupling structure - - */ - void DisjointDEC::attachLocalField(const ICoCo::MEDField *field) - { - if(!isInUnion()) - return ; - if(!field) - throw INTERP_KERNEL::Exception("DisjointDEC::attachLocalField : ICoCo::MEDField pointer is NULL !"); - attachLocalField(field->getField()); - } - - /*! - Computes the field norm over its support - on the source side and renormalizes the field on the target side - so that the norms match. - - \f[ - I_{source}=\sum_{i=1}^{n_{source}}V_{i}.|\Phi^{source}_{i}|^2, - \f] - - \f[ - I_{target}=\sum_{i=1}^{n_{target}}V_{i}.|\Phi^{target}_{i}|^2, - \f] - - \f[ - \Phi^{target}:=\Phi^{target}.\sqrt{I_{source}/I_{target}}. - \f] - - */ - void DisjointDEC::renormalizeTargetField(bool isWAbs) - { - if (_source_group->containsMyRank()) - for (int icomp=0; icomp<_local_field->getField()->getArray()->getNumberOfComponents(); icomp++) - { - double total_norm = _local_field->getVolumeIntegral(icomp+1,isWAbs); - double source_norm = total_norm; - _comm_interface->broadcast(&source_norm, 1, MPI_DOUBLE, 0,* dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); - - } - if (_target_group->containsMyRank()) - { - for (int icomp=0; icomp<_local_field->getField()->getArray()->getNumberOfComponents(); icomp++) - { - double total_norm = _local_field->getVolumeIntegral(icomp+1,isWAbs); - double source_norm=total_norm; - _comm_interface->broadcast(&source_norm, 1, MPI_DOUBLE, 0,* dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); - - if (fabs(total_norm)>1e-100) - _local_field->getField()->applyLin(source_norm/total_norm,0.0,icomp+1); - } - } - } - - bool DisjointDEC::isInSourceSide() const - { - if(!_source_group) - return false; - return _source_group->containsMyRank(); - } - - bool DisjointDEC::isInTargetSide() const - { - if(!_target_group) - return false; - return _target_group->containsMyRank(); - } - - bool DisjointDEC::isInUnion() const - { - if(!_union_group) - return false; - return _union_group->containsMyRank(); - } - - void DisjointDEC::compareFieldAndMethod() const throw(INTERP_KERNEL::Exception) - { - if (_local_field) - { - TypeOfField entity = _local_field->getField()->getTypeOfField(); - if ( getMethod() == "P0" ) - { - if ( entity != ON_CELLS ) - throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch." - " For P0 interpolation, field must be on MED_CELL's"); - } - else if ( getMethod() == "P1" ) - { - if ( entity != ON_NODES ) - throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch." - " For P1 interpolation, field must be on MED_NODE's"); - } - else if ( getMethod() == "P1d" ) - { - if ( entity != ON_CELLS ) - throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch." - " For P1d interpolation, field must be on MED_CELL's"); - if ( _target_group->containsMyRank() ) - throw INTERP_KERNEL::Exception("Projection to P1d field not supported"); - } - else - { - throw INTERP_KERNEL::Exception("Unknown interpolation method. Possible methods: P0, P1, P1d"); - } - } - } - - /*! - If way==true, source procs call sendData() and target procs call recvData(). - if way==false, it's the other way round. - */ - void DisjointDEC::sendRecvData(bool way) - { - if(!isInUnion()) - return; - if(isInSourceSide()) - { - if(way) - sendData(); - else - recvData(); - } - else if(isInTargetSide()) - { - if(way) - recvData(); - else - sendData(); - } - } -} diff --git a/medtool/src/ParaMEDMEM/DisjointDEC.hxx b/medtool/src/ParaMEDMEM/DisjointDEC.hxx deleted file mode 100644 index a4073a292..000000000 --- a/medtool/src/ParaMEDMEM/DisjointDEC.hxx +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __DISJOINTDEC_HXX__ -#define __DISJOINTDEC_HXX__ - -#include "MEDCouplingFieldDouble.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "DEC.hxx" - -#include <mpi.h> -#include <set> - -namespace ICoCo -{ - class MEDField; -} - -namespace ParaMEDMEM -{ - class ProcessorGroup; - class ParaFIELD; - - class DisjointDEC : public DEC - { - public: - DisjointDEC():_local_field(0),_union_group(0),_source_group(0),_target_group(0), - _comm_interface(0), - _owns_field(false),_owns_groups(false), - _union_comm(MPI_COMM_NULL) - { } - DisjointDEC(ProcessorGroup& source_group, ProcessorGroup& target_group); - DisjointDEC(const DisjointDEC&); - DisjointDEC &operator=(const DisjointDEC& s); - DisjointDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids, - const MPI_Comm& world_comm=MPI_COMM_WORLD); - void setNature(NatureOfField nature); - void attachLocalField( MEDCouplingFieldDouble *field); - void attachLocalField(const ParaFIELD *field, bool ownPt=false); - void attachLocalField(const ICoCo::MEDField *field); - - virtual void prepareSourceDE() = 0; - virtual void prepareTargetDE() = 0; - virtual void recvData() = 0; - virtual void sendData() = 0; - void sendRecvData(bool way=true); - virtual void synchronize() = 0; - virtual ~DisjointDEC(); - virtual void computeProcGroup() { } - void renormalizeTargetField(bool isWAbs); - // - ProcessorGroup *getSourceGrp() const { return _source_group; } - ProcessorGroup *getTargetGrp() const { return _target_group; } - bool isInSourceSide() const; - bool isInTargetSide() const; - bool isInUnion() const; - protected: - void compareFieldAndMethod() const throw(INTERP_KERNEL::Exception); - void cleanInstance(); - void copyInstance(const DisjointDEC& other); - protected: - const ParaFIELD* _local_field; - //! Processor group representing the union of target and source processors - ProcessorGroup* _union_group; - ProcessorGroup* _source_group; - ProcessorGroup* _target_group; - - const CommInterface* _comm_interface; - bool _owns_field; - bool _owns_groups; - MPI_Comm _union_comm; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ElementLocator.cxx b/medtool/src/ParaMEDMEM/ElementLocator.cxx deleted file mode 100644 index 1374387ee..000000000 --- a/medtool/src/ParaMEDMEM/ElementLocator.cxx +++ /dev/null @@ -1,720 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <mpi.h> -#include "CommInterface.hxx" -#include "ElementLocator.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ParaFIELD.hxx" -#include "ParaMESH.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "DirectedBoundingBox.hxx" - -#include <map> -#include <set> -#include <limits> - -using namespace std; - -//#define USE_DIRECTED_BB - -namespace ParaMEDMEM -{ - ElementLocator::ElementLocator(const ParaFIELD& sourceField, - const ProcessorGroup& distant_group, - const ProcessorGroup& local_group) - : _local_para_field(sourceField), - _local_cell_mesh(sourceField.getSupport()->getCellMesh()), - _local_face_mesh(sourceField.getSupport()->getFaceMesh()), - _distant_group(distant_group), - _local_group(local_group) - { - _union_group = _local_group.fuse(distant_group); - _computeBoundingBoxes(); - _comm=getCommunicator(); - } - - ElementLocator::~ElementLocator() - { - delete _union_group; - delete [] _domain_bounding_boxes; - } - - const MPI_Comm *ElementLocator::getCommunicator() const - { - MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); - return group->getComm(); - } - - NatureOfField ElementLocator::getLocalNature() const - { - return _local_para_field.getField()->getNature(); - } - - - /*! Procedure for exchanging a mesh between a distant proc and a local processor - \param idistantrank proc id on distant group - \param distant_mesh on return , points to a local reconstruction of - the distant mesh - \param distant_ids on return, contains a vector defining a correspondence - between the distant ids and the ids of the local reconstruction - */ - void ElementLocator::exchangeMesh(int idistantrank, - MEDCouplingPointSet*& distant_mesh, - int*& distant_ids) - { - int rank = _union_group->translateRank(&_distant_group,idistantrank); - - if (find(_distant_proc_ids.begin(), _distant_proc_ids.end(),rank)==_distant_proc_ids.end()) - return; - - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems; -#ifdef USE_DIRECTED_BB - INTERP_KERNEL::DirectedBoundingBox dbb; - double* distant_bb = _domain_bounding_boxes+rank*dbb.dataSize(_local_cell_mesh_space_dim); - dbb.setData(distant_bb); - elems=_local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment()); -#else - double* distant_bb = _domain_bounding_boxes+rank*2*_local_cell_mesh_space_dim; - elems=_local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment()); -#endif - - DataArrayInt *distant_ids_send; - MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(elems->begin(),elems->end(),distant_ids_send); - _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids); - distant_ids_send->decrRef(); - - if(send_mesh) - send_mesh->decrRef(); - } - - void ElementLocator::exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth) - { - CommInterface comm_interface=_union_group->getCommInterface(); - MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); - const MPI_Comm* comm=(group->getComm()); - MPI_Status status; - // it must be converted to union numbering before communication - int idistRankInUnion = group->translateRank(&_distant_group,idistantrank); - char *recv_buffer=new char[4]; - std::vector<char> send_buffer(4); - std::copy(sourceMeth.begin(),sourceMeth.end(),send_buffer.begin()); - comm_interface.sendRecv(&send_buffer[0], 4, MPI_CHAR,idistRankInUnion, 1112, - recv_buffer, 4, MPI_CHAR,idistRankInUnion, 1112, - *comm, &status); - targetMeth=recv_buffer; - delete [] recv_buffer; - } - - - - /*! - Compute bounding boxes - */ - void ElementLocator::_computeBoundingBoxes() - { - CommInterface comm_interface =_union_group->getCommInterface(); - MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); - const MPI_Comm* comm = group->getComm(); - _local_cell_mesh_space_dim = -1; - if(_local_cell_mesh->getMeshDimension() != -1) - _local_cell_mesh_space_dim=_local_cell_mesh->getSpaceDimension(); - int *spaceDimForAll=new int[_union_group->size()]; - comm_interface.allGather(&_local_cell_mesh_space_dim, 1, MPI_INT, - spaceDimForAll,1, MPI_INT, - *comm); - _local_cell_mesh_space_dim=*std::max_element(spaceDimForAll,spaceDimForAll+_union_group->size()); - _is_m1d_corr=((*std::min_element(spaceDimForAll,spaceDimForAll+_union_group->size()))==-1); - for(int i=0;i<_union_group->size();i++) - if(spaceDimForAll[i]!=_local_cell_mesh_space_dim && spaceDimForAll[i]!=-1) - throw INTERP_KERNEL::Exception("Spacedim not matches !"); - delete [] spaceDimForAll; -#ifdef USE_DIRECTED_BB - INTERP_KERNEL::DirectedBoundingBox dbb; - int bbSize = dbb.dataSize(_local_cell_mesh_space_dim); - _domain_bounding_boxes = new double[bbSize*_union_group->size()]; - if(_local_cell_mesh->getMeshDimension() != -1) - dbb = INTERP_KERNEL::DirectedBoundingBox(_local_cell_mesh->getCoords()->getPointer(), - _local_cell_mesh->getNumberOfNodes(), - _local_cell_mesh_space_dim); - std::vector<double> dbbData = dbb.getData(); - if ( dbbData.size() < bbSize ) dbbData.resize(bbSize,0); - double * minmax= &dbbData[0]; -#else - int bbSize = 2*_local_cell_mesh_space_dim; - _domain_bounding_boxes = new double[bbSize*_union_group->size()]; - double * minmax=new double [bbSize]; - if(_local_cell_mesh->getMeshDimension() != -1) - _local_cell_mesh->getBoundingBox(minmax); - else - for(int i=0;i<_local_cell_mesh_space_dim;i++) - { - minmax[i*2]=-std::numeric_limits<double>::max(); - minmax[i*2+1]=std::numeric_limits<double>::max(); - } -#endif - - comm_interface.allGather(minmax, bbSize, MPI_DOUBLE, - _domain_bounding_boxes,bbSize, MPI_DOUBLE, - *comm); - - for (int i=0; i< _distant_group.size(); i++) - { - int rank=_union_group->translateRank(&_distant_group,i); - - if (_intersectsBoundingBox(rank)) - { - _distant_proc_ids.push_back(rank); - } - } -#ifdef USE_DIRECTED_BB -#else - delete [] minmax; -#endif - } - - - - /*! - * Intersect local bounding box with a given distant bounding box on "irank" - */ - bool ElementLocator::_intersectsBoundingBox(int irank) - { -#ifdef USE_DIRECTED_BB - INTERP_KERNEL::DirectedBoundingBox local_dbb, distant_dbb; - local_dbb.setData( _domain_bounding_boxes+_union_group->myRank()*local_dbb.dataSize( _local_cell_mesh_space_dim )); - distant_dbb.setData( _domain_bounding_boxes+irank*distant_dbb.dataSize( _local_cell_mesh_space_dim )); - return !local_dbb.isDisjointWith( distant_dbb ); -#else - double* local_bb = _domain_bounding_boxes+_union_group->myRank()*2*_local_cell_mesh_space_dim; - double* distant_bb = _domain_bounding_boxes+irank*2*_local_cell_mesh_space_dim; - - const double eps = 1e-12; - for (int idim=0; idim < _local_cell_mesh_space_dim; idim++) - { - bool intersects = (distant_bb[idim*2]<local_bb[idim*2+1]+eps) - && (local_bb[idim*2]<distant_bb[idim*2+1]+eps); - if (!intersects) return false; - } - return true; -#endif - } - - - /*! - * Exchange mesh data - */ - void ElementLocator::_exchangeMesh( MEDCouplingPointSet* local_mesh, - MEDCouplingPointSet*& distant_mesh, - int iproc_distant, - const DataArrayInt* distant_ids_send, - int*& distant_ids_recv) - { - CommInterface comm_interface=_union_group->getCommInterface(); - - // First stage : exchanging sizes - // ------------------------------ - vector<double> tinyInfoLocalD,tinyInfoDistantD(1);//not used for the moment - vector<int> tinyInfoLocal,tinyInfoDistant; - vector<string> tinyInfoLocalS; - //Getting tiny info of local mesh to allow the distant proc to initialize and allocate - //the transmitted mesh. - local_mesh->getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS); - tinyInfoLocal.push_back(distant_ids_send->getNumberOfTuples()); - tinyInfoDistant.resize(tinyInfoLocal.size()); - std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0); - MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); - const MPI_Comm* comm=group->getComm(); - MPI_Status status; - - // iproc_distant is the number of proc in distant group - // it must be converted to union numbering before communication - int iprocdistant_in_union = group->translateRank(&_distant_group, - iproc_distant); - - comm_interface.sendRecv(&tinyInfoLocal[0], tinyInfoLocal.size(), MPI_INT, iprocdistant_in_union, 1112, - &tinyInfoDistant[0], tinyInfoDistant.size(), MPI_INT,iprocdistant_in_union,1112, - *comm, &status); - DataArrayInt *v1Local=0; - DataArrayDouble *v2Local=0; - DataArrayInt *v1Distant=DataArrayInt::New(); - DataArrayDouble *v2Distant=DataArrayDouble::New(); - //serialization of local mesh to send data to distant proc. - local_mesh->serialize(v1Local,v2Local); - //Building the right instance of copy of distant mesh. - MEDCouplingPointSet *distant_mesh_tmp=MEDCouplingPointSet::BuildInstanceFromMeshType((MEDCouplingMeshType)tinyInfoDistant[0]); - std::vector<std::string> unusedTinyDistantSts; - distant_mesh_tmp->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - int nbLocalElems=0; - int nbDistElem=0; - int *ptLocal=0; - int *ptDist=0; - if(v1Local) - { - nbLocalElems=v1Local->getNbOfElems(); - ptLocal=v1Local->getPointer(); - } - if(v1Distant) - { - nbDistElem=v1Distant->getNbOfElems(); - ptDist=v1Distant->getPointer(); - } - comm_interface.sendRecv(ptLocal, nbLocalElems, MPI_INT, - iprocdistant_in_union, 1111, - ptDist, nbDistElem, MPI_INT, - iprocdistant_in_union,1111, - *comm, &status); - nbLocalElems=0; - double *ptLocal2=0; - double *ptDist2=0; - if(v2Local) - { - nbLocalElems=v2Local->getNbOfElems(); - ptLocal2=v2Local->getPointer(); - } - nbDistElem=0; - if(v2Distant) - { - nbDistElem=v2Distant->getNbOfElems(); - ptDist2=v2Distant->getPointer(); - } - comm_interface.sendRecv(ptLocal2, nbLocalElems, MPI_DOUBLE, - iprocdistant_in_union, 1112, - ptDist2, nbDistElem, MPI_DOUBLE, - iprocdistant_in_union, 1112, - *comm, &status); - // - distant_mesh=distant_mesh_tmp; - //finish unserialization - distant_mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - // - distant_ids_recv=new int[tinyInfoDistant.back()]; - comm_interface.sendRecv(const_cast<void *>(reinterpret_cast<const void *>(distant_ids_send->getConstPointer())),tinyInfoLocal.back(), MPI_INT, - iprocdistant_in_union, 1113, - distant_ids_recv,tinyInfoDistant.back(), MPI_INT, - iprocdistant_in_union,1113, - *comm, &status); - if(v1Local) - v1Local->decrRef(); - if(v2Local) - v2Local->decrRef(); - if(v1Distant) - v1Distant->decrRef(); - if(v2Distant) - v2Distant->decrRef(); - } - - /*! - * connected with ElementLocator::sendPolicyToWorkingSideL - */ - void ElementLocator::recvPolicyFromLazySideW(std::vector<int>& policy) - { - policy.resize(_distant_proc_ids.size()); - int procId=0; - CommInterface comm; - MPI_Status status; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - int toRecv; - comm.recv((void *)&toRecv,1,MPI_INT,*iter,1120,*_comm,&status); - policy[procId]=toRecv; - } - } - - /*! - * connected with ElementLocator::recvFromWorkingSideL - */ - void ElementLocator::sendSumToLazySideW(const std::vector< std::vector<int> >& distantLocEltIds, const std::vector< std::vector<double> >& partialSumRelToDistantIds) - { - int procId=0; - CommInterface comm; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const vector<int>& eltIds=distantLocEltIds[procId]; - const vector<double>& valued=partialSumRelToDistantIds[procId]; - int lgth=eltIds.size(); - comm.send(&lgth,1,MPI_INT,*iter,1114,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&eltIds[0])),lgth,MPI_INT,*iter,1115,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&valued[0])),lgth,MPI_DOUBLE,*iter,1116,*_comm); - } - } - - /*! - * connected with ElementLocator::sendToWorkingSideL - */ - void ElementLocator::recvSumFromLazySideW(std::vector< std::vector<double> >& globalSumRelToDistantIds) - { - int procId=0; - CommInterface comm; - MPI_Status status; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - std::vector<double>& vec=globalSumRelToDistantIds[procId]; - comm.recv(&vec[0],vec.size(),MPI_DOUBLE,*iter,1117,*_comm,&status); - } - } - - /*! - * connected with ElementLocator::recvLocalIdsFromWorkingSideL - */ - void ElementLocator::sendLocalIdsToLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds) - { - int procId=0; - CommInterface comm; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const vector<int>& eltIds=distantLocEltIds[procId]; - int lgth=eltIds.size(); - comm.send(&lgth,1,MPI_INT,*iter,1121,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&eltIds[0])),lgth,MPI_INT,*iter,1122,*_comm); - } - } - - /*! - * connected with ElementLocator::sendGlobalIdsToWorkingSideL - */ - void ElementLocator::recvGlobalIdsFromLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds, std::vector< std::vector<int> >& globalIds) - { - int procId=0; - CommInterface comm; - MPI_Status status; - globalIds.resize(_distant_proc_ids.size()); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const std::vector<int>& vec=distantLocEltIds[procId]; - std::vector<int>& global=globalIds[procId]; - global.resize(vec.size()); - comm.recv(&global[0],vec.size(),MPI_INT,*iter,1123,*_comm,&status); - } - } - - /*! - * connected with ElementLocator::sendCandidatesGlobalIdsToWorkingSideL - */ - void ElementLocator::recvCandidatesGlobalIdsFromLazyProcsW(std::vector< std::vector<int> >& globalIds) - { - int procId=0; - CommInterface comm; - MPI_Status status; - globalIds.resize(_distant_proc_ids.size()); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - std::vector<int>& global=globalIds[procId]; - int lgth; - comm.recv(&lgth,1,MPI_INT,*iter,1132,*_comm,&status); - global.resize(lgth); - comm.recv(&global[0],lgth,MPI_INT,*iter,1133,*_comm,&status); - } - } - - /*! - * connected with ElementLocator::recvSumFromWorkingSideL - */ - void ElementLocator::sendPartialSumToLazyProcsW(const std::vector<int>& distantGlobIds, const std::vector<double>& sum) - { - int procId=0; - CommInterface comm; - int lgth=distantGlobIds.size(); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - comm.send(&lgth,1,MPI_INT,*iter,1124,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&distantGlobIds[0])),lgth,MPI_INT,*iter,1125,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&sum[0])),lgth,MPI_DOUBLE,*iter,1126,*_comm); - } - } - - /*! - * connected with ElementLocator::recvCandidatesForAddElementsL - */ - void ElementLocator::sendCandidatesForAddElementsW(const std::vector<int>& distantGlobIds) - { - int procId=0; - CommInterface comm; - int lgth=distantGlobIds.size(); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&lgth)),1,MPI_INT,*iter,1128,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&distantGlobIds[0])),lgth,MPI_INT,*iter,1129,*_comm); - } - } - - /*! - * connected with ElementLocator::sendAddElementsToWorkingSideL - */ - void ElementLocator::recvAddElementsFromLazyProcsW(std::vector<std::vector<int> >& elementsToAdd) - { - int procId=0; - CommInterface comm; - MPI_Status status; - int lgth=_distant_proc_ids.size(); - elementsToAdd.resize(lgth); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - int locLgth; - std::vector<int>& eltToFeed=elementsToAdd[procId]; - comm.recv(&locLgth,1,MPI_INT,*iter,1130,*_comm,&status); - eltToFeed.resize(locLgth); - comm.recv(&eltToFeed[0],locLgth,MPI_INT,*iter,1131,*_comm,&status); - } - } - - /*! - * connected with ElementLocator::recvPolicyFromLazySideW - */ - int ElementLocator::sendPolicyToWorkingSideL() - { - CommInterface comm; - int toSend; - DataArrayInt *isCumulative=_local_para_field.returnCumulativeGlobalNumbering(); - if(isCumulative) - { - toSend=CUMULATIVE_POLICY; - isCumulative->decrRef(); - } - else - toSend=NO_POST_TREATMENT_POLICY; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++) - comm.send(&toSend,1,MPI_INT,*iter,1120,*_comm); - return toSend; - } - - /*! - * connected with ElementLocator::sendSumToLazySideW - */ - void ElementLocator::recvFromWorkingSideL() - { - _values_added.resize(_local_para_field.getField()->getNumberOfTuples()); - int procId=0; - CommInterface comm; - _ids_per_working_proc.resize(_distant_proc_ids.size()); - MPI_Status status; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - int lgth; - comm.recv(&lgth,1,MPI_INT,*iter,1114,*_comm,&status); - vector<int>& ids=_ids_per_working_proc[procId]; - ids.resize(lgth); - vector<double> values(lgth); - comm.recv(&ids[0],lgth,MPI_INT,*iter,1115,*_comm,&status); - comm.recv(&values[0],lgth,MPI_DOUBLE,*iter,1116,*_comm,&status); - for(int i=0;i<lgth;i++) - _values_added[ids[i]]+=values[i]; - } - } - - /*! - * connected with ElementLocator::recvSumFromLazySideW - */ - void ElementLocator::sendToWorkingSideL() - { - int procId=0; - CommInterface comm; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - vector<int>& ids=_ids_per_working_proc[procId]; - vector<double> valsToSend(ids.size()); - vector<double>::iterator iter3=valsToSend.begin(); - for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter3++) - *iter3=_values_added[*iter2]; - comm.send(&valsToSend[0],ids.size(),MPI_DOUBLE,*iter,1117,*_comm); - //ids.clear(); - } - //_ids_per_working_proc.clear(); - } - - /*! - * connected with ElementLocator::sendLocalIdsToLazyProcsW - */ - void ElementLocator::recvLocalIdsFromWorkingSideL() - { - int procId=0; - CommInterface comm; - _ids_per_working_proc.resize(_distant_proc_ids.size()); - MPI_Status status; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - int lgth; - vector<int>& ids=_ids_per_working_proc[procId]; - comm.recv(&lgth,1,MPI_INT,*iter,1121,*_comm,&status); - ids.resize(lgth); - comm.recv(&ids[0],lgth,MPI_INT,*iter,1122,*_comm,&status); - } - } - - /*! - * connected with ElementLocator::recvGlobalIdsFromLazyProcsW - */ - void ElementLocator::sendGlobalIdsToWorkingSideL() - { - int procId=0; - CommInterface comm; - DataArrayInt *globalIds=_local_para_field.returnGlobalNumbering(); - const int *globalIdsC=globalIds->getConstPointer(); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const vector<int>& ids=_ids_per_working_proc[procId]; - vector<int> valsToSend(ids.size()); - vector<int>::iterator iter1=valsToSend.begin(); - for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter1++) - *iter1=globalIdsC[*iter2]; - comm.send(&valsToSend[0],ids.size(),MPI_INT,*iter,1123,*_comm); - } - if(globalIds) - globalIds->decrRef(); - } - - /*! - * connected with ElementLocator::sendPartialSumToLazyProcsW - */ - void ElementLocator::recvSumFromWorkingSideL() - { - int procId=0; - int wProcSize=_distant_proc_ids.size(); - CommInterface comm; - _ids_per_working_proc.resize(wProcSize); - _values_per_working_proc.resize(wProcSize); - MPI_Status status; - std::map<int,double> sums; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - int lgth; - comm.recv(&lgth,1,MPI_INT,*iter,1124,*_comm,&status); - vector<int>& ids=_ids_per_working_proc[procId]; - vector<double>& vals=_values_per_working_proc[procId]; - ids.resize(lgth); - vals.resize(lgth); - comm.recv(&ids[0],lgth,MPI_INT,*iter,1125,*_comm,&status); - comm.recv(&vals[0],lgth,MPI_DOUBLE,*iter,1126,*_comm,&status); - vector<int>::const_iterator iter1=ids.begin(); - vector<double>::const_iterator iter2=vals.begin(); - for(;iter1!=ids.end();iter1++,iter2++) - sums[*iter1]+=*iter2; - } - //assign sum to prepare sending to working side - for(procId=0;procId<wProcSize;procId++) - { - vector<int>& ids=_ids_per_working_proc[procId]; - vector<double>& vals=_values_per_working_proc[procId]; - vector<int>::const_iterator iter1=ids.begin(); - vector<double>::iterator iter2=vals.begin(); - for(;iter1!=ids.end();iter1++,iter2++) - *iter2=sums[*iter1]; - ids.clear(); - } - } - - /*! - * Foreach working procs Wi compute and push it in _ids_per_working_proc3, - * if it exist, local id of nodes that are in interaction with an another lazy proc than this - * and that exists in this \b but with no interaction with this. - * The computation is performed here. sendAddElementsToWorkingSideL is only in charge to send - * precomputed _ids_per_working_proc3 attribute. - * connected with ElementLocator::sendCandidatesForAddElementsW - */ - void ElementLocator::recvCandidatesForAddElementsL() - { - int procId=0; - int wProcSize=_distant_proc_ids.size(); - CommInterface comm; - _ids_per_working_proc3.resize(wProcSize); - MPI_Status status; - std::map<int,double> sums; - DataArrayInt *globalIds=_local_para_field.returnGlobalNumbering(); - const int *globalIdsC=globalIds->getConstPointer(); - int nbElts=globalIds->getNumberOfTuples(); - std::set<int> globalIdsS(globalIdsC,globalIdsC+nbElts); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const std::vector<int>& ids0=_ids_per_working_proc[procId]; - int lgth0=ids0.size(); - std::set<int> elts0; - for(int i=0;i<lgth0;i++) - elts0.insert(globalIdsC[ids0[i]]); - int lgth; - comm.recv(&lgth,1,MPI_INT,*iter,1128,*_comm,&status); - vector<int> ids(lgth); - comm.recv(&ids[0],lgth,MPI_INT,*iter,1129,*_comm,&status); - set<int> ids1(ids.begin(),ids.end()); - ids.clear(); - set<int> tmp5,tmp6; - set_intersection(globalIdsS.begin(),globalIdsS.end(),ids1.begin(),ids1.end(),inserter(tmp5,tmp5.begin())); - set_difference(tmp5.begin(),tmp5.end(),elts0.begin(),elts0.end(),inserter(tmp6,tmp6.begin())); - std::vector<int>& ids2=_ids_per_working_proc3[procId]; - ids2.resize(tmp6.size()); - std::copy(tmp6.begin(),tmp6.end(),ids2.begin()); - //global->local - for(std::vector<int>::iterator iter2=ids2.begin();iter2!=ids2.end();iter2++) - *iter2=std::find(globalIdsC,globalIdsC+nbElts,*iter2)-globalIdsC; - } - if(globalIds) - globalIds->decrRef(); - } - - /*! - * connected with ElementLocator::recvAddElementsFromLazyProcsW - */ - void ElementLocator::sendAddElementsToWorkingSideL() - { - int procId=0; - CommInterface comm; - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const std::vector<int>& vals=_ids_per_working_proc3[procId]; - int size=vals.size(); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&size)),1,MPI_INT,*iter,1130,*_comm); - comm.send(const_cast<void *>(reinterpret_cast<const void *>(&vals[0])),size,MPI_INT,*iter,1131,*_comm); - } - } - - /*! - * This method sends to working side Wi only nodes in interaction with Wi \b and located on boundary, to reduce number. - * connected with ElementLocator::recvCandidatesGlobalIdsFromLazyProcsW - */ - void ElementLocator::sendCandidatesGlobalIdsToWorkingSideL() - { - int procId=0; - CommInterface comm; - DataArrayInt *globalIds=_local_para_field.returnGlobalNumbering(); - const int *globalIdsC=globalIds->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=_local_para_field.getSupport()->getCellMesh()->findBoundaryNodes(); - for(int *iter1=candidates->getPointer();iter1!=candidates->getPointer()+candidates->getNumberOfTuples();iter1++) - (*iter1)=globalIdsC[*iter1]; - std::set<int> candidatesS(candidates->begin(),candidates->end()); - for(vector<int>::const_iterator iter=_distant_proc_ids.begin();iter!=_distant_proc_ids.end();iter++,procId++) - { - const vector<int>& ids=_ids_per_working_proc[procId]; - vector<int> valsToSend(ids.size()); - vector<int>::iterator iter1=valsToSend.begin(); - for(vector<int>::const_iterator iter2=ids.begin();iter2!=ids.end();iter2++,iter1++) - *iter1=globalIdsC[*iter2]; - std::set<int> tmp2(valsToSend.begin(),valsToSend.end()); - std::vector<int> tmp3; - set_intersection(candidatesS.begin(),candidatesS.end(),tmp2.begin(),tmp2.end(),std::back_insert_iterator< std::vector<int> >(tmp3)); - int lgth=tmp3.size(); - comm.send(&lgth,1,MPI_INT,*iter,1132,*_comm); - comm.send(&tmp3[0],lgth,MPI_INT,*iter,1133,*_comm); - } - if(globalIds) - globalIds->decrRef(); - } -} diff --git a/medtool/src/ParaMEDMEM/ElementLocator.hxx b/medtool/src/ParaMEDMEM/ElementLocator.hxx deleted file mode 100644 index 4edd27de6..000000000 --- a/medtool/src/ParaMEDMEM/ElementLocator.hxx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __ELEMENTLOCATOR_HXX__ -#define __ELEMENTLOCATOR_HXX__ - -#include "InterpolationOptions.hxx" -#include "MEDCouplingNatureOfField.hxx" - -#include <mpi.h> -#include <vector> -#include <set> - -namespace ParaMEDMEM -{ - class ParaFIELD; - class ProcessorGroup; - class InterpolationMatrix; - class MEDCouplingPointSet; - class DataArrayInt; - - /*! Internal class, not part of the public API. Used in InterpolationMatrix. - * - */ - class ElementLocator : public INTERP_KERNEL::InterpolationOptions - { - public: - ElementLocator(const ParaFIELD& sourceField, const ProcessorGroup& distant_group, const ProcessorGroup& local_group); - - virtual ~ElementLocator(); - void exchangeMesh(int idistantrank, - MEDCouplingPointSet*& target_mesh, - int*& distant_ids); - void exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth); - const std::vector<int>& getDistantProcIds() const { return _distant_proc_ids; } - const MPI_Comm *getCommunicator() const; - NatureOfField getLocalNature() const; - //! This method is used to informed if there is -1D mesh on distant_group side or on local_group side. - bool isM1DCorr() const { return _is_m1d_corr; } - //Working side methods - void recvPolicyFromLazySideW(std::vector<int>& policy); - void sendSumToLazySideW(const std::vector< std::vector<int> >& distantLocEltIds, const std::vector< std::vector<double> >& partialSumRelToDistantIds); - void recvSumFromLazySideW(std::vector< std::vector<double> >& globalSumRelToDistantIds); - void sendCandidatesForAddElementsW(const std::vector<int>& distantGlobIds); - void recvAddElementsFromLazyProcsW(std::vector<std::vector<int> >& elementsToAdd); - // - void sendLocalIdsToLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds); - void recvGlobalIdsFromLazyProcsW(const std::vector< std::vector<int> >& distantLocEltIds, std::vector< std::vector<int> >& globalIds); - void recvCandidatesGlobalIdsFromLazyProcsW(std::vector< std::vector<int> >& globalIds); - void sendPartialSumToLazyProcsW(const std::vector<int>& distantGlobIds, const std::vector<double>& sum); - //Lazy side methods - int sendPolicyToWorkingSideL(); - void recvFromWorkingSideL(); - void sendToWorkingSideL(); - // - void recvLocalIdsFromWorkingSideL(); - void sendGlobalIdsToWorkingSideL(); - void sendCandidatesGlobalIdsToWorkingSideL(); - // - void recvSumFromWorkingSideL(); - void recvCandidatesForAddElementsL(); - void sendAddElementsToWorkingSideL(); - private: - void _computeBoundingBoxes(); - bool _intersectsBoundingBox(int irank); - void _exchangeMesh(MEDCouplingPointSet* local_mesh, MEDCouplingPointSet*& distant_mesh, - int iproc_distant, const DataArrayInt* distant_ids_send, - int*& distant_ids_recv); - private: - const ParaFIELD& _local_para_field ; - MEDCouplingPointSet* _local_cell_mesh; - int _local_cell_mesh_space_dim; - bool _is_m1d_corr; - MEDCouplingPointSet* _local_face_mesh; - std::vector<MEDCouplingPointSet*> _distant_cell_meshes; - std::vector<MEDCouplingPointSet*> _distant_face_meshes; - double* _domain_bounding_boxes; - const ProcessorGroup& _distant_group; - const ProcessorGroup& _local_group; - ProcessorGroup* _union_group; - std::vector<int> _distant_proc_ids; - const MPI_Comm *_comm; - //Attributes only used by lazy side - std::vector<double> _values_added; - std::vector< std::vector<int> > _ids_per_working_proc; - std::vector< std::vector<int> > _ids_per_working_proc3; - std::vector< std::vector<double> > _values_per_working_proc; - public: - static const int CUMULATIVE_POLICY=3; - static const int NO_POST_TREATMENT_POLICY=7; - }; - -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx b/medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx deleted file mode 100644 index db0396725..000000000 --- a/medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <mpi.h> -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "MPIProcessorGroup.hxx" -#include "ExplicitCoincidentDEC.hxx" -#include "ExplicitMapping.hxx" -#include "InterpKernelUtilities.hxx" - -using namespace std; - -namespace ParaMEDMEM -{ - - /*! - \anchor ExplicitCoincidentDEC-det - \class ExplicitCoincidentDEC - - - This class aims at \ref interpolation "remapping fields" that have identical - supports (=the same underlying mesh) but different parallel topologies - (=different sub-domains in the mesh). It can be used to couple - together multi-physics codes that operate on the same domain - with different partitioning. - - It is very similar to what the \ref StructuredCoincidentDEC-det "StructuredCoincidentDEC" - does, except that it works with an arbitrary user-defined topology. - - The remapping between the two supports is based on identity of global - ids, instead of geometrical considerations (as it is the case for - \ref InterpKernelDEC-det "InterpKernelDEC"). - Therefore, beware that this \ref para-dec "DEC" can not be used - for coincident meshes if they do *not* have the exact same numbering. - - With this \ref para-dec "DEC" no projection, and no interpolation of the field data is done, contrary - to what happens in \ref InterpKernelDEC-det "InterpKernelDEC". It is just - a matter of allocating the values from one side to the other, using directly the cell - identifiers. - - As all the other DECs, its usage requires two phases : - - a setup phase during which the topologies are exchanged so that - the target side knows from which processors it should expect - the data. - - a send/recv phase during which the field data is actually transferred. - - This example illustrates the sending of a field with - the \c ExplicitCoincidentDEC : - \code - ... - ExplicitCoincidentDEC dec(groupA, groupB); - dec.attachLocalField(field); - dec.synchronize(); - if (groupA.containsMyRank()) - dec.recvData(); - else if (groupB.containsMyRank()) - dec.sendData(); - ... - \endcode - - Creating a ParaFIELD to be attached to the %DEC is done in exactly the same way as for - the other DECs, if only the partitioning of the support mesh differs. - In the case where the - fields have also different *component* topologies, creating the ParaFIELD - requires some more effort. See the \ref para-over "parallelism" section for more details. - */ - - - /*! Constructor - */ - ExplicitCoincidentDEC::ExplicitCoincidentDEC(): - _toposource(0),_topotarget(0), - _targetgroup(0), _sourcegroup(0), - _sendcounts(0), _recvcounts(0), - _senddispls(0), _recvdispls(0), - _recvbuffer(0), _sendbuffer(0), - _distant_elems(), _explicit_mapping() - { - } - - ExplicitCoincidentDEC::~ExplicitCoincidentDEC() - { - } - - /*! Synchronization process for exchanging topologies - */ - void ExplicitCoincidentDEC::synchronize() - { - if (_source_group->containsMyRank()) - { - _toposource = dynamic_cast<ExplicitTopology*>(_local_field->getTopology()); - _sourcegroup= _toposource->getProcGroup()->createProcGroup(); - _targetgroup=_toposource->getProcGroup()->createComplementProcGroup(); - } - if (_target_group->containsMyRank()) - { - _topotarget = dynamic_cast<ExplicitTopology*>(_local_field->getTopology()); - _sourcegroup= _topotarget->getProcGroup()->createComplementProcGroup(); - _targetgroup=_topotarget->getProcGroup()->createProcGroup(); - } - - // Exchanging - - // Transmitting source topology to target code - broadcastTopology(_toposource,_topotarget,1000); - transferMappingToSource(); - } - - /*! Creates the arrays necessary for the data transfer - * and fills the send array with the values of the - * source field - * */ - void ExplicitCoincidentDEC::prepareSourceDE() - { - //////////////////////////////////// - //Step 1 : buffer array creation - - if (!_toposource->getProcGroup()->containsMyRank()) - return; - MPIProcessorGroup* group=new MPIProcessorGroup(_sourcegroup->getCommInterface()); - - // Warning : the size of the target side is implicitly deduced - //from the size of MPI_COMM_WORLD - int target_size = _toposource->getProcGroup()->getCommInterface().worldSize()- _toposource->getProcGroup()->size() ; - - vector<int>* target_arrays=new vector<int>[target_size]; - - int nb_local = _toposource-> getNbLocalElements(); - - int union_size=group->size(); - - _sendcounts=new int[union_size]; - _senddispls=new int[union_size]; - _recvcounts=new int[union_size]; - _recvdispls=new int[union_size]; - - for (int i=0; i< union_size; i++) - { - _sendcounts[i]=0; - _recvcounts[i]=0; - _recvdispls[i]=0; - } - _senddispls[0]=0; - - int* counts=_explicit_mapping.getCounts(); - for (int i=0; i<group->size(); i++) - _sendcounts[i]=counts[i]; - - for (int iproc=1; iproc<group->size();iproc++) - _senddispls[iproc]=_senddispls[iproc-1]+_sendcounts[iproc-1]; - - _sendbuffer = new double [nb_local * _toposource->getNbComponents()]; - - ///////////////////////////////////////////////////////////// - //Step 2 : filling the buffers with the source field values - - int* counter=new int [target_size]; - counter[0]=0; - for (int i=1; i<target_size; i++) - counter[i]=counter[i-1]+target_arrays[i-1].size(); - - - const double* value = _local_field->getField()->getArray()->getPointer(); - - int* bufferindex= _explicit_mapping.getBufferIndex(); - - for (int ielem=0; ielem<nb_local; ielem++) - { - int ncomp = _toposource->getNbComponents(); - for (int icomp=0; icomp<ncomp; icomp++) - { - _sendbuffer[ielem*ncomp+icomp]=value[bufferindex[ielem]*ncomp+icomp]; - } - } - delete[] target_arrays; - delete[] counter; - } - - /*! - * Creates the buffers for receiving the fields on the target side - */ - void ExplicitCoincidentDEC::prepareTargetDE() - { - if (!_topotarget->getProcGroup()->containsMyRank()) - return; - MPIProcessorGroup* group=new MPIProcessorGroup(_topotarget->getProcGroup()->getCommInterface()); - - vector < vector <int> > source_arrays(_sourcegroup->size()); - int nb_local = _topotarget-> getNbLocalElements(); - for (int ielem=0; ielem< nb_local ; ielem++) - { - //pair<int,int> source_local =_distant_elems[ielem]; - pair <int,int> source_local=_explicit_mapping.getDistantNumbering(ielem); - source_arrays[source_local.first].push_back(source_local.second); - } - int union_size=group->size(); - _recvcounts=new int[union_size]; - _recvdispls=new int[union_size]; - _sendcounts=new int[union_size]; - _senddispls=new int[union_size]; - - for (int i=0; i< union_size; i++) - { - _sendcounts[i]=0; - _recvcounts[i]=0; - _recvdispls[i]=0; - } - for (int iproc=0; iproc < _sourcegroup->size(); iproc++) - { - //converts the rank in target to the rank in union communicator - int unionrank=group->translateRank(_sourcegroup,iproc); - _recvcounts[unionrank]=source_arrays[iproc].size()*_topotarget->getNbComponents(); - } - for (int i=1; i<union_size; i++) - _recvdispls[i]=_recvdispls[i-1]+_recvcounts[i-1]; - _recvbuffer=new double[nb_local*_topotarget->getNbComponents()]; - - } - - - /*! - * Synchronizing a topology so that all the groups get it. - * - * \param toposend Topology that is transmitted. It is read on processes where it already exists, and it is created and filled on others. - * \param toporecv Topology which is received. - * \param tag Communication tag associated with this operation. - */ - void ExplicitCoincidentDEC::broadcastTopology(const ExplicitTopology* toposend, ExplicitTopology* toporecv, int tag) - { - MPI_Status status; - - int* serializer=0; - int size; - - MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); - - // The send processors serialize the send topology - // and send the buffers to the recv procs - if (toposend !=0 && toposend->getProcGroup()->containsMyRank()) - { - toposend->serialize(serializer, size); - for (int iproc=0; iproc< group->size(); iproc++) - { - int itarget=iproc; - if (!toposend->getProcGroup()->contains(itarget)) - { - _comm_interface->send(&size,1,MPI_INT, itarget,tag+itarget,*(group->getComm())); - _comm_interface->send(serializer, size, MPI_INT, itarget, tag+itarget,*(group->getComm())); - } - } - } - else - { - vector <int> size2(group->size()); - int myworldrank=group->myRank(); - for (int iproc=0; iproc<group->size();iproc++) - { - int isource = iproc; - if (!toporecv->getProcGroup()->contains(isource)) - { - int nbelem; - _comm_interface->recv(&nbelem, 1, MPI_INT, isource, tag+myworldrank, *(group->getComm()), &status); - int* buffer = new int[nbelem]; - _comm_interface->recv(buffer, nbelem, MPI_INT, isource,tag+myworldrank, *(group->getComm()), &status); - - ExplicitTopology* topotemp=new ExplicitTopology(); - topotemp->unserialize(buffer, *_comm_interface); - delete[] buffer; - - for (int ielem=0; ielem<toporecv->getNbLocalElements(); ielem++) - { - int global = toporecv->localToGlobal(ielem); - int sendlocal=topotemp->globalToLocal(global); - if (sendlocal!=-1) - { - size2[iproc]++; - _explicit_mapping.pushBackElem(make_pair(iproc,sendlocal)); - } - } - delete topotemp; - } - } - } - MESSAGE (" rank "<<group->myRank()<< " broadcastTopology is over"); - } - - void ExplicitCoincidentDEC::transferMappingToSource() - { - - MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); - - // sending source->target mapping which is stored by target - //in _distant_elems from target to source - if (_topotarget!=0 && _topotarget->getProcGroup()->containsMyRank()) - { - int world_size = _topotarget->getProcGroup()->getCommInterface().worldSize() ; - int* nb_transfer_union=new int[world_size]; - int* dummy_recv=new int[world_size]; - for (int i=0; i<world_size; i++) - nb_transfer_union[i]=0; - //converts the rank in target to the rank in union communicator - - for (int i=0; i< _explicit_mapping.nbDistantDomains(); i++) - { - int unionrank=group->translateRank(_sourcegroup,_explicit_mapping.getDistantDomain(i)); - nb_transfer_union[unionrank]=_explicit_mapping.getNbDistantElems(i); - } - _comm_interface->allToAll(nb_transfer_union, 1, MPI_INT, dummy_recv, 1, MPI_INT, MPI_COMM_WORLD); - - int* sendbuffer= _explicit_mapping.serialize(_topotarget->getProcGroup()->myRank()); - - int* sendcounts= new int [world_size]; - int* senddispls = new int [world_size]; - for (int i=0; i< world_size; i++) - { - sendcounts[i]=2*nb_transfer_union[i]; - if (i==0) - senddispls[i]=0; - else - senddispls[i]=senddispls[i-1]+sendcounts[i-1]; - } - int* recvcounts=new int[world_size]; - int* recvdispls=new int[world_size]; - int *dummyrecv=0; - for (int i=0; i <world_size; i++) - { - recvcounts[i]=0; - recvdispls[i]=0; - } - _comm_interface->allToAllV(sendbuffer, sendcounts, senddispls, MPI_INT, dummyrecv, recvcounts, senddispls, MPI_INT, MPI_COMM_WORLD); - - } - //receiving in the source subdomains the mapping sent by targets - else - { - int world_size = _toposource->getProcGroup()->getCommInterface().worldSize() ; - int* nb_transfer_union=new int[world_size]; - int* dummy_send=new int[world_size]; - for (int i=0; i<world_size; i++) - dummy_send[i]=0; - _comm_interface->allToAll(dummy_send, 1, MPI_INT, nb_transfer_union, 1, MPI_INT, MPI_COMM_WORLD); - - int total_size=0; - for (int i=0; i< world_size; i++) - total_size+=nb_transfer_union[i]; - int nbtarget = _targetgroup->size(); - int* targetranks = new int[ nbtarget]; - for (int i=0; i<nbtarget; i++) - targetranks[i]=group->translateRank(_targetgroup,i); - int* mappingbuffer= new int [total_size*2]; - int* sendcounts= new int [world_size]; - int* senddispls = new int [world_size]; - int* recvcounts=new int[world_size]; - int* recvdispls=new int[world_size]; - for (int i=0; i< world_size; i++) - { - recvcounts[i]=2*nb_transfer_union[i]; - if (i==0) - recvdispls[i]=0; - else - recvdispls[i]=recvdispls[i-1]+recvcounts[i-1]; - } - - int *dummysend=0; - for (int i=0; i <world_size; i++) - { - sendcounts[i]=0; - senddispls[i]=0; - } - _comm_interface->allToAllV(dummysend, sendcounts, senddispls, MPI_INT, mappingbuffer, recvcounts, recvdispls, MPI_INT, MPI_COMM_WORLD); - _explicit_mapping.unserialize(world_size,nb_transfer_union,nbtarget, targetranks, mappingbuffer); - } - } - - void ExplicitCoincidentDEC::recvData() - { - //MPI_COMM_WORLD is used instead of group because there is no - //mechanism for creating the union group yet - MESSAGE("recvData"); - - cout<<"start AllToAll"<<endl; - _comm_interface->allToAllV(_sendbuffer, _sendcounts, _senddispls, MPI_DOUBLE, - _recvbuffer, _recvcounts, _recvdispls, MPI_DOUBLE,MPI_COMM_WORLD); - cout<<"end AllToAll"<<endl; - int nb_local = _topotarget->getNbLocalElements(); - double* value=new double[nb_local*_topotarget->getNbComponents()]; - - vector<int> counters(_sourcegroup->size()); - counters[0]=0; - for (int i=0; i<_sourcegroup->size()-1; i++) - { - MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); - int worldrank=group->translateRank(_sourcegroup,i); - counters[i+1]=counters[i]+_recvcounts[worldrank]; - } - - for (int ielem=0; ielem<nb_local ; ielem++) - { - pair<int,int> distant_numbering=_explicit_mapping.getDistantNumbering(ielem); - int iproc=distant_numbering.first; - int ncomp = _topotarget->getNbComponents(); - for (int icomp=0; icomp< ncomp; icomp++) - value[ielem*ncomp+icomp]=_recvbuffer[counters[iproc]*ncomp+icomp]; - counters[iproc]++; - } - _local_field->getField()->getArray()->useArray(value,true,CPP_DEALLOC,nb_local,_topotarget->getNbComponents()); - } - - void ExplicitCoincidentDEC::sendData() - { - MESSAGE ("sendData"); - for (int i=0; i< 4; i++) - cout << _sendcounts[i]<<" "; - cout <<endl; - for (int i=0; i< 4; i++) - cout << _senddispls[i]<<" "; - cout <<endl; - //MPI_COMM_WORLD is used instead of group because there is no - //mechanism for creating the union group yet - cout <<"start AllToAll"<<endl; - _comm_interface->allToAllV(_sendbuffer, _sendcounts, _senddispls, MPI_DOUBLE, - _recvbuffer, _recvcounts, _recvdispls, MPI_DOUBLE,MPI_COMM_WORLD); - } -} - diff --git a/medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.hxx b/medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.hxx deleted file mode 100644 index 6205e11ef..000000000 --- a/medtool/src/ParaMEDMEM/ExplicitCoincidentDEC.hxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __EXPLICITCOINCIDENTDEC_HXX__ -#define __EXPLICITCOINCIDENTDEC_HXX__ - -#include "DisjointDEC.hxx" -#include "ExplicitMapping.hxx" -#include "ExplicitTopology.hxx" - -#include <map> - -namespace ParaMEDMEM -{ - class BlockTopology; - - class ExplicitCoincidentDEC : public DisjointDEC - { - public: - ExplicitCoincidentDEC(); - virtual ~ExplicitCoincidentDEC(); - void synchronize(); - void broadcastTopology(BlockTopology*&, int tag); - void broadcastTopology(const ExplicitTopology* toposend, ExplicitTopology* toporecv, int tag); - void transferMappingToSource(); - void prepareSourceDE(); - void prepareTargetDE(); - void recvData(); - void sendData(); - private: - ExplicitTopology* _toposource; - ExplicitTopology* _topotarget; - ProcessorGroup* _targetgroup; - ProcessorGroup* _sourcegroup; - int* _sendcounts; - int* _recvcounts; - int* _senddispls; - int* _recvdispls; - double* _recvbuffer; - double* _sendbuffer; - std::map<int,std::pair<int,int> > _distant_elems; - ExplicitMapping _explicit_mapping; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ExplicitMapping.cxx b/medtool/src/ParaMEDMEM/ExplicitMapping.cxx deleted file mode 100644 index f4e754571..000000000 --- a/medtool/src/ParaMEDMEM/ExplicitMapping.cxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ExplicitMapping.hxx" - -namespace ParaMEDMEM -{ - - ExplicitMapping::ExplicitMapping(): - _mapping(), _distant_domains(), - _numbers(0), _domains(0), _comm_buffer(0), - _buffer_index(0), _send_counts(0) - { } - - ExplicitMapping::~ExplicitMapping() - { - if (_domains!=0) delete[] _domains; - if (_numbers!=0) delete[] _numbers; - if (_comm_buffer!=0) delete[] _comm_buffer; - } - - void ExplicitMapping::pushBackElem(std::pair<int,int> idistant) - { - _mapping.push_back(idistant); - } - - void ExplicitMapping::setDistantElem(int ilocal, std::pair<int,int> idistant) - { - _mapping[ilocal]=idistant; - } - - int ExplicitMapping::nbDistantDomains() - { - if (_distant_domains.empty()) - { - for (std::vector <std::pair<int,int> >::const_iterator iter= _mapping.begin(); - iter!=_mapping.end(); - iter++) - _distant_domains.insert(iter->first); - } - return _distant_domains.size(); - } - - std::pair <int,int> ExplicitMapping::getDistantNumbering(int ielem)const - { - return _mapping[ielem]; - } - - int ExplicitMapping::getDistantDomain(int i) - { - if (_domains==0) - computeNumbers(); - - return _domains[i]; - } - - int ExplicitMapping::getNbDistantElems(int i) - { - if (_numbers==0) - computeNumbers(); - return _numbers[i]; - } - - int* ExplicitMapping::serialize(int idproc) - { - _comm_buffer=new int[_mapping.size()*2]; - std::vector<int> offsets(_distant_domains.size()); - offsets[0]=0; - for (int i=1; i<(int)_distant_domains.size();i++) - offsets[i]=offsets[i-1]+_numbers[i-1]; - - for (int i=0; i<(int)_mapping.size(); i++) - { - int offset= offsets[_mapping[i].first]; - _comm_buffer[offset*2]=idproc; - _comm_buffer[offset*2+1]=_mapping[i].second; - offsets[_mapping[i].first]++; - } - return _comm_buffer; - } - - void ExplicitMapping::unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer) - { - int total_size=0; - for (int i=0; i< nbprocs; i++) - total_size+=sizes[i]; - - _mapping.resize(total_size); - _buffer_index=new int[total_size]; - int indmap=0; - for (int i=0; i<nbprocs; i++) - for (int ielem=0; ielem<sizes[i]; ielem++) - { - _mapping[indmap].first=i; - _mapping[indmap].second=commbuffer[indmap*2+1]; - _buffer_index[indmap]=commbuffer[indmap*2+1]; - indmap++; - } - _numbers=new int [nbtarget]; - _domains=new int [nbtarget]; - - int index=0; - for (int i=0; i<nbtarget; i++) - { - if (sizes[targetrank[i]]>0) - { - _numbers[index]=sizes[targetrank[i]]; - _domains[index]=i; - index++; - } - } - _send_counts=new int[nbprocs]; - for (int i=0; i<nbprocs; i++) - _send_counts[i]=sizes[i]; - } - - void ExplicitMapping::computeNumbers() - { - std::map <int,int> counts; - if (_numbers==0) - { - _numbers=new int[nbDistantDomains()]; - _domains=new int[nbDistantDomains()]; - for (int i=0; i<(int)_mapping.size(); i++) - { - if ( counts.find(_mapping[i].first) == counts.end()) - counts.insert(std::make_pair(_mapping[i].first,1)); - else - (counts[_mapping[i].first])++; - } - int counter=0; - for (std::map<int,int>::const_iterator iter=counts.begin(); - iter!=counts.end(); - iter++) - { - _numbers[counter]=iter->second; - _domains[counter]=iter->first; - counter++; - } - } - } - -} diff --git a/medtool/src/ParaMEDMEM/ExplicitMapping.hxx b/medtool/src/ParaMEDMEM/ExplicitMapping.hxx deleted file mode 100644 index 3098b706f..000000000 --- a/medtool/src/ParaMEDMEM/ExplicitMapping.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __EXPLICITMAPPING_HXX__ -#define __EXPLICITMAPPING_HXX__ - -#include <vector> -#include <map> -#include <set> - -namespace ParaMEDMEM -{ - /*! - * Internal class, not part of the public API. - * - * Used by the ExplicitCoincidentDEC. - */ - class ExplicitMapping - { - public: - ExplicitMapping(); - ~ExplicitMapping(); - - void pushBackElem(std::pair<int,int> idistant); - void setDistantElem(int ilocal, std::pair<int,int> idistant); - int nbDistantDomains(); - std::pair <int,int> getDistantNumbering(int ielem) const; - - int getDistantDomain(int i); - int getNbDistantElems(int i); - int* serialize(int idproc); - void unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer); - - int* getBufferIndex() const { return _buffer_index; } - int* getCounts() const { return _send_counts; } - private: - std::vector <std::pair<int,int> > _mapping; - std::set<int> _distant_domains; - int* _numbers; - int* _domains; - int* _comm_buffer; - int* _buffer_index; - int* _send_counts; - - void computeNumbers(); - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ExplicitTopology.cxx b/medtool/src/ParaMEDMEM/ExplicitTopology.cxx deleted file mode 100644 index 4facf53e0..000000000 --- a/medtool/src/ParaMEDMEM/ExplicitTopology.cxx +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "ParaMESH.hxx" -#include "Topology.hxx" -#include "ExplicitTopology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" - -#include <vector> -#include <algorithm> - -using namespace std; -namespace ParaMEDMEM -{ - -ExplicitTopology::ExplicitTopology(): - _proc_group(NULL), _nb_elems(0), _nb_components(0), - _loc2glob(NULL), _glob2loc() - {} - -ExplicitTopology::ExplicitTopology(const ParaMESH& paramesh ): -_proc_group(paramesh.getBlockTopology()->getProcGroup()), -_nb_components(1) -{ - _nb_elems=paramesh.getCellMesh()->getNumberOfCells(); - const int* global=paramesh.getGlobalNumberingCell(); - _loc2glob=new int[_nb_elems]; - - for (int i=0; i<_nb_elems; i++) - { - _loc2glob[i]=global[i]; - _glob2loc[global[i]]=i; - } -} - -ExplicitTopology::ExplicitTopology(const ExplicitTopology& topo, int nb_components) -{ - _proc_group = topo._proc_group; - _nb_elems = topo._nb_elems; - _nb_components = nb_components; - _loc2glob=new int[_nb_elems]; - for (int i=0; i<_nb_elems; i++) - { - _loc2glob[i]=topo._loc2glob[i]; - } - _glob2loc=topo._glob2loc; -} - - -ExplicitTopology::~ExplicitTopology() -{ - if (_loc2glob != 0) delete[] _loc2glob; -} - - -/*! Serializes the data contained in the Explicit Topology - * for communication purposes*/ -void ExplicitTopology::serialize(int* & serializer, int& size) const -{ - vector <int> buffer; - - buffer.push_back(_nb_elems); - for (int i=0; i<_nb_elems; i++) - { - buffer.push_back(_loc2glob[i]); - } - - serializer=new int[buffer.size()]; - size= buffer.size(); - copy(buffer.begin(), buffer.end(), serializer); - -} -/*! Unserializes the data contained in the Explicit Topology - * after communication. Uses the same structure as the one used for serialize() - * - * */ -void ExplicitTopology::unserialize(const int* serializer,const CommInterface& comm_interface) -{ - const int* ptr_serializer=serializer; - cout << "unserialize..."<<endl; - _nb_elems=*ptr_serializer++; - cout << "nbelems "<<_nb_elems<<endl; - _loc2glob=new int[_nb_elems]; - for (int i=0; i<_nb_elems; i++) - { - _loc2glob[i]=*ptr_serializer; - _glob2loc[*ptr_serializer]=i; - ptr_serializer++; - - } - -} - -} diff --git a/medtool/src/ParaMEDMEM/ExplicitTopology.hxx b/medtool/src/ParaMEDMEM/ExplicitTopology.hxx deleted file mode 100644 index d7d73f9be..000000000 --- a/medtool/src/ParaMEDMEM/ExplicitTopology.hxx +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __EXPLICITTOPOLOGY_HXX__ -#define __EXPLICITTOPOLOGY_HXX__ - -#include "ProcessorGroup.hxx" -#include "InterpKernelHashMap.hxx" - -#include <vector> -#include <utility> -#include <iostream> - -namespace ParaMEDMEM -{ - class ParaMESH; - class Topology; - class ComponentTopology; - - /*! - * \anchor ExplicitTopology-det - * - * An ExplicitTopology typically represents the split of a mesh among the processors of - * a common ProcessorGroup. Each processor gets a user-defined part of the cells in the mesh. - * \sa BlockTopology - */ - class ExplicitTopology : public Topology - { - public: - ExplicitTopology(); - ExplicitTopology( const ExplicitTopology& topo, int nbcomponents); - ExplicitTopology(const ParaMESH &mesh); - virtual ~ExplicitTopology(); - - inline int getNbElements()const; - inline int getNbLocalElements() const; - const ProcessorGroup* getProcGroup()const { return _proc_group; } - int localToGlobal (const std::pair<int,int> local) const { return localToGlobal(local.second); } - inline int localToGlobal(int) const; - inline int globalToLocal(int) const; - void serialize(int* & serializer, int& size) const ; - void unserialize(const int* serializer, const CommInterface& comm_interface); - int getNbComponents() const { return _nb_components; } - private: - //Processor group - const ProcessorGroup* _proc_group; - //nb of elements - int _nb_elems; - //nb of components - int _nb_components; - //mapping local to global - int* _loc2glob; - //mapping global to local - INTERP_KERNEL::HashMap<int,int> _glob2loc; - }; - - //!converts a pair <subdomainid,local> to a global number - inline int ExplicitTopology::globalToLocal(const int global) const - { - return (_glob2loc.find(global))->second;; - } - - //!converts local number to a global number - int ExplicitTopology::localToGlobal(int local) const - { - return _loc2glob[local]; - } - - //!Retrieves the number of elements for a given topology - inline int ExplicitTopology::getNbElements() const - { - return _nb_elems; - } - - //Retrieves the local number of elements - inline int ExplicitTopology::getNbLocalElements()const - { - return _glob2loc.size(); - } -} - - -#endif diff --git a/medtool/src/ParaMEDMEM/ICoCoField.cxx b/medtool/src/ParaMEDMEM/ICoCoField.cxx deleted file mode 100644 index 3925945b7..000000000 --- a/medtool/src/ParaMEDMEM/ICoCoField.cxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// ICoCo file common to several codes -// ICoCoField.cxx -// version 1.2 10/05/2010 - -#include <ICoCoField.hxx> -#include <string> - -using namespace ICoCo; -using std::string; - -Field::Field() { - _name=new string; -} - -Field::~Field() { - delete _name; -} - -void Field::setName(const string& name) { - *_name=name; -} - -const string& Field::getName() const { - return *_name; -} - -const char* Field::getCharName() const { - return _name->c_str(); -} diff --git a/medtool/src/ParaMEDMEM/ICoCoField.hxx b/medtool/src/ParaMEDMEM/ICoCoField.hxx deleted file mode 100644 index 509dc68f5..000000000 --- a/medtool/src/ParaMEDMEM/ICoCoField.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// ICoCo file common to several codes -// ICoCoField.h -// version 1.2 10/05/2010 - -#ifndef _ICoCoField_included_ -#define _ICoCoField_included_ -#include <string> - - -namespace ICoCo { - - class Field { - public: - Field(); - virtual ~Field(); - void setName(const std::string& name); - const std::string& getName() const; - const char* getCharName() const; - - private: - std::string* _name; - }; -} -#endif diff --git a/medtool/src/ParaMEDMEM/ICoCoMEDField.cxx b/medtool/src/ParaMEDMEM/ICoCoMEDField.cxx deleted file mode 100644 index 1bf60fc75..000000000 --- a/medtool/src/ParaMEDMEM/ICoCoMEDField.cxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ICoCoMEDField.hxx" -#include "ProcessorGroup.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace ICoCo -{ - - /*! Constructor directly attaching a MEDCouplingFieldDouble - the object does not take the control the objects pointed by - \a field. - */ - - MEDField::MEDField(ParaMEDMEM::MEDCouplingFieldDouble *field):_field(field) - { - if(_field) - _field->incrRef(); - } - MEDField::MEDField(const MEDField& field):_field(field.getField()) - { - if(_field) - _field->incrRef(); - } - - MEDField::~MEDField() - { - if(_field) - _field->decrRef(); - } - - - MEDField& MEDField::operator=(const MEDField& field) - { - if (_field) - _field->decrRef(); - - _field=field.getField(); - if(_field) - _field->incrRef(); - return *this; - } -} diff --git a/medtool/src/ParaMEDMEM/ICoCoMEDField.hxx b/medtool/src/ParaMEDMEM/ICoCoMEDField.hxx deleted file mode 100644 index c5dbdbb14..000000000 --- a/medtool/src/ParaMEDMEM/ICoCoMEDField.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __ICOCOMEDFIELD_HXX__ -#define __ICOCOMEDFIELD_HXX__ - -#include "ICoCoField.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include <vector> - -namespace ICoCo -{ - class MEDField : public ICoCo::Field - { - public: - MEDField():_field(0) { } - MEDField(ParaMEDMEM::MEDCouplingFieldDouble* field); - MEDField(const MEDField& field); - MEDField& operator=(const MEDField& field); - virtual ~MEDField(); - ParaMEDMEM::MEDCouplingFieldDouble *getField() const { return _field; } - const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _field->getMesh(); } - private: - ParaMEDMEM::MEDCouplingFieldDouble *_field; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/InterpKernelDEC.cxx b/medtool/src/ParaMEDMEM/InterpKernelDEC.cxx deleted file mode 100644 index 7f1be4b36..000000000 --- a/medtool/src/ParaMEDMEM/InterpKernelDEC.cxx +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <mpi.h> -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "MPIProcessorGroup.hxx" -#include "ParaMESH.hxx" -#include "DEC.hxx" -#include "InterpolationMatrix.hxx" -#include "InterpKernelDEC.hxx" -#include "ElementLocator.hxx" - -namespace ParaMEDMEM -{ - - /*! - \anchor InterpKernelDEC-det - \class InterpKernelDEC - - \section InterpKernelDEC-over Overview - - The InterpKernelDEC enables the \ref InterpKerRemapGlobal "remapping" (or interpolation) of fields between - two parallel codes. - - The projection - methodology is based on the algorithms of %INTERP_KERNEL, that is to say, they work in a similar fashion than - what the \ref remapper "sequential remapper" does. The following \ref discretization "projection methods" - are supported: P0->P0 (the most common case), P1->P0, P0->P1. - - The computation is possible for 3D meshes, 2D meshes, and 3D-surface - meshes. Dimensions must be identical for code A and code B (for instance, though it could be - desirable, it is not yet possible to couple 3D surfaces with 2D surfaces). - - The name "InterpKernelDEC" comes from the fact that this class uses exactly the same algorithms - as the sequential remapper. Both this class and the sequential - \ref ParaMEDMEM::MEDCouplingRemapper "MEDCouplingRemapper" are built on top of the %INTERP_KERNEL - algorithms (notably the computation of the intersection volumes). - - Among the important properties inherited from the parent abstract class \ref DisjointDEC-det "DisjointDEC", - the two \ref MPIProcessorGroup-det "processor groups" (source and target) must have a void intersection. - - \image html NonCoincident_small.png "Transfer of a field supported by a quadrangular mesh to a triangular mesh". - - \image latex NonCoincident_small.eps "Transfer of a field supported by a quadrangular mesh to a triangular mesh" - - In the figure above we see the transfer of a field based on a quadrangular mesh to a new field supported by - a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on the - quadrangles are weighted by their intersection area and summed. - - A typical use of InterpKernelDEC encompasses two distinct phases : - - A setup phase during which the intersection volumes are computed and the communication structures are - setup. This corresponds to calling the InterpKernelDEC::synchronize() method. - - A running phase during which the projections are actually performed. This corresponds to the calls to - sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous - in the current version of the library so that recvData() and sendData() calls must be synchronized - on code A and code B processor groups. - - The following code excerpt illustrates a typical use of the InterpKernelDEC class. - - \code - ... - InterpKernelDEC dec(groupA, groupB); - dec.attachLocalField(field); - dec.synchronize(); - if (groupA.containsMyRank()) - dec.recvData(); - else if (groupB.containsMyRank()) - dec.sendData(); - ... - \endcode - A \ref InterpKerRemapGlobal "remapping" of the field from the source mesh to the target mesh is performed by - the function synchronise(), which computes the interpolation matrix. - - Computing the field on the receiving side can be expressed in terms of a matrix-vector product : - \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t \f$ the field on the target side and \f$ \phi_s \f$ the field - on the source side. - When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements - from both sides. Care must be taken when defining this projection to obtain a - \ref InterpKerRemapGlobal "conservative remapping". - - In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the - intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix - is : - - \f[ - \begin{tabular}{|cccc|} - 0.72 & 0 & 0.2 & 0 \\ - 0.46 & 0 & 0.51 & 0.03\\ - 0.42 & 0.53 & 0 & 0.05\\ - 0 & 0 & 0.92 & 0.05 \\ - \end{tabular} - \f] - - \section InterpKernelDEC-options Options - On top of the usual \ref ParaMEDMEM::DECOptions "DEC options", the options supported by %InterpKernelDEC objects are - related to the underlying \ref InterpKerIntersectors "intersector class". - All the options available in the intersector objects are - available for the %InterpKernelDEC object. The various options available for intersectors can - be reviewed in \ref InterpKerIntersectors. - - For instance : - \verbatim - InterpKernelDEC dec(source_group, target_group); - dec.attachLocalField(field); - dec.setDoRotate(false); - dec.setPrecision(1e-12); - dec.synchronize(); - \endverbatim - - \warning{ Options must be set before calling the synchronize method. } - */ - - InterpKernelDEC::InterpKernelDEC(): - DisjointDEC(), - _nb_distant_points(0), _distant_coords(0), - _distant_locations(0), _interpolation_matrix(0) - { - } - - /*! - This constructor creates an InterpKernelDEC which has \a source_group as a working side - and \a target_group as an idle side. All the processors will actually participate, but intersection computations will be performed on the working side during the \a synchronize() phase. - The constructor must be called synchronously on all processors of both processor groups. - - \param source_group working side ProcessorGroup - \param target_group lazy side ProcessorGroup - - */ - InterpKernelDEC::InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group): - DisjointDEC(source_group, target_group), - _nb_distant_points(0), _distant_coords(0), - _distant_locations(0), _interpolation_matrix(0) - { - - } - - InterpKernelDEC::InterpKernelDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids, - const MPI_Comm& world_comm): - DisjointDEC(src_ids,trg_ids,world_comm), - _nb_distant_points(0), _distant_coords(0), - _distant_locations(0), _interpolation_matrix(0) - { - } - - InterpKernelDEC::~InterpKernelDEC() - { - if (_interpolation_matrix !=0) - delete _interpolation_matrix; - } - - /*! - \brief Synchronization process for exchanging topologies. - - This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh - underlying the fields that have been set with attachLocalField method. - It works in four steps : - -# Bounding boxes are computed for each sub-domain, - -# The lazy side mesh parts that are likely to intersect the working side local processor are sent to the working side, - -# The working side calls the interpolation kernel to compute the intersection between local and imported mesh. - -# The lazy side is updated so that it knows the structure of the data that will be sent by - the working side during a \a sendData() call. - - */ - void InterpKernelDEC::synchronize() - { - if(!isInUnion()) - return ; - delete _interpolation_matrix; - _interpolation_matrix = new InterpolationMatrix (_local_field, *_source_group,*_target_group,*this,*this); - - //setting up the communication DEC on both sides - if (_source_group->containsMyRank()) - { - //locate the distant meshes - ElementLocator locator(*_local_field, *_target_group, *_source_group); - //transfering option from InterpKernelDEC to ElementLocator - locator.copyOptions(*this); - MEDCouplingPointSet* distant_mesh=0; - int* distant_ids=0; - std::string distantMeth; - for (int i=0; i<_target_group->size(); i++) - { - // int idistant_proc = (i+_source_group->myRank())%_target_group->size(); - int idistant_proc=i; - - //gathers pieces of the target meshes that can intersect the local mesh - locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); - if (distant_mesh !=0) - { - locator.exchangeMethod(_method,idistant_proc,distantMeth); - //adds the contribution of the distant mesh on the local one - int idistant_proc_in_union=_union_group->translateRank(_target_group,idistant_proc); - //std::cout <<"add contribution from proc "<<idistant_proc_in_union<<" to proc "<<_union_group->myRank()<<std::endl; - _interpolation_matrix->addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth); - distant_mesh->decrRef(); - delete [] distant_ids; - distant_mesh=0; - distant_ids=0; - } - } - _interpolation_matrix->finishContributionW(locator); - } - - if (_target_group->containsMyRank()) - { - ElementLocator locator(*_local_field, *_source_group, *_target_group); - //transfering option from InterpKernelDEC to ElementLocator - locator.copyOptions(*this); - MEDCouplingPointSet* distant_mesh=0; - int* distant_ids=0; - for (int i=0; i<_source_group->size(); i++) - { - // int idistant_proc = (i+_target_group->myRank())%_source_group->size(); - int idistant_proc=i; - //gathers pieces of the target meshes that can intersect the local mesh - locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); - //std::cout << " Data sent from "<<_union_group->myRank()<<" to source proc "<< idistant_proc<<std::endl; - if (distant_mesh!=0) - { - std::string distantMeth; - locator.exchangeMethod(_method,idistant_proc,distantMeth); - distant_mesh->decrRef(); - delete [] distant_ids; - distant_mesh=0; - distant_ids=0; - } - } - _interpolation_matrix->finishContributionL(locator); - } - _interpolation_matrix->prepare(); - } - - - /*! - Receives the data whether the processor is on the working side or on the lazy side. It must match a \a sendData() call on the other side. - */ - void InterpKernelDEC::recvData() - { - if (_source_group->containsMyRank()) - _interpolation_matrix->transposeMultiply(*_local_field->getField()); - else if (_target_group->containsMyRank()) - { - _interpolation_matrix->multiply(*_local_field->getField()); - if (getForcedRenormalization()) - renormalizeTargetField(getMeasureAbsStatus()); - } - } - - - /*! - Receives the data at time \a time in asynchronous mode. The value of the field - will be time-interpolated from the field values received. - \param time time at which the value is desired - */ - void InterpKernelDEC::recvData( double time ) - { - _interpolation_matrix->getAccessDEC()->setTime(time); - recvData() ; - } - - /*! - Sends the data whether the processor is on the working side or on the lazy side. - It must match a recvData() call on the other side. - */ - void InterpKernelDEC::sendData() - { - if (_source_group->containsMyRank()) - { - - _interpolation_matrix->multiply(*_local_field->getField()); - if (getForcedRenormalization()) - renormalizeTargetField(getMeasureAbsStatus()); - - } - else if (_target_group->containsMyRank()) - _interpolation_matrix->transposeMultiply(*_local_field->getField()); - } - - /*! - Sends the data available at time \a time in asynchronous mode. - \param time time at which the value is available - \param deltatime time interval between the value presently sent and the next one. - */ - void InterpKernelDEC::sendData( double time , double deltatime ) - { - _interpolation_matrix->getAccessDEC()->setTime(time,deltatime); - sendData() ; - } - -} diff --git a/medtool/src/ParaMEDMEM/InterpKernelDEC.hxx b/medtool/src/ParaMEDMEM/InterpKernelDEC.hxx deleted file mode 100644 index 54b8819da..000000000 --- a/medtool/src/ParaMEDMEM/InterpKernelDEC.hxx +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPKERNELDEC_HXX__ -#define __INTERPKERNELDEC_HXX__ - -#include "DisjointDEC.hxx" -#include "MxN_Mapping.hxx" -#include "InterpolationOptions.hxx" - -namespace ParaMEDMEM -{ - class InterpolationMatrix; - - class InterpKernelDEC : public DisjointDEC, public INTERP_KERNEL::InterpolationOptions - { - public: - InterpKernelDEC(); - InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group); - InterpKernelDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids, - const MPI_Comm& world_comm=MPI_COMM_WORLD); - virtual ~InterpKernelDEC(); - void synchronize(); - void recvData(); - void recvData(double time); - void sendData(); - void sendData(double time , double deltatime); - void prepareSourceDE() { } - void prepareTargetDE() { } - private : - //Number of distant points to be located locally - int _nb_distant_points; - //coordinates of distant points - const double* _distant_coords; - //local element number containing the distant points - const int* _distant_locations; - InterpolationMatrix* _interpolation_matrix; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/InterpolationMatrix.cxx b/medtool/src/ParaMEDMEM/InterpolationMatrix.cxx deleted file mode 100644 index 8b8c50f61..000000000 --- a/medtool/src/ParaMEDMEM/InterpolationMatrix.cxx +++ /dev/null @@ -1,963 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ProcessorGroup.hxx" -#include "MxN_Mapping.hxx" -#include "InterpolationMatrix.hxx" -#include "TranslationRotationMatrix.hxx" -#include "Interpolation.hxx" -#include "Interpolation1D.txx" -#include "Interpolation2DCurve.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3DSurf.hxx" -#include "Interpolation3D.txx" -#include "Interpolation3D2D.txx" -#include "Interpolation2D1D.txx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "InterpolationOptions.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "ElementLocator.hxx" - -#include <algorithm> - -using namespace std; - -namespace ParaMEDMEM -{ - - /**! - Creates an empty matrix structure linking two distributed supports. - The method must be called by all processors belonging to source - and target groups. - \param source_support local support - \param source_group processor group containing the local processors - \param target_group processor group containing the distant processors - \param method interpolation method - */ - InterpolationMatrix::InterpolationMatrix(const ParaMEDMEM::ParaFIELD *source_field, - const ProcessorGroup& source_group, - const ProcessorGroup& target_group, - const DECOptions& dec_options, - const INTERP_KERNEL::InterpolationOptions& interp_options): - INTERP_KERNEL::InterpolationOptions(interp_options), - DECOptions(dec_options), - _source_field(source_field), - _source_support(source_field->getSupport()->getCellMesh()), - _mapping(source_group, target_group, dec_options), - _source_group(source_group), - _target_group(target_group) - { - int nbelems = source_field->getField()->getNumberOfTuples(); - _row_offsets.resize(nbelems+1); - _coeffs.resize(nbelems); - _target_volume.resize(nbelems); - } - - InterpolationMatrix::~InterpolationMatrix() - { - } - - - /*! - \brief Adds the contribution of a distant subdomain to the* - interpolation matrix. - The method adds contribution to the interpolation matrix. - For each row of the matrix, elements are addded as - a (column, coeff) pair in the _coeffs array. This column number refers - to an element on the target side via the _col_offsets array. - It is made of a series of (iproc, ielem) pairs. - The number of elements per row is stored in the row_offsets array. - - param distant_support local representation of the distant subdomain - param iproc_distant id of the distant subdomain (in the distant group) - param distant_elems mapping between the local representation of - the subdomain and the actual elem ids on the distant subdomain - */ - void InterpolationMatrix::addContribution ( MEDCouplingPointSet& distant_support, - int iproc_distant, - const int* distant_elems, - const std::string& srcMeth, - const std::string& targetMeth) - { - std::string interpMethod(targetMeth); - interpMethod+=srcMeth; - //creating the interpolator structure - vector<map<int,double> > surfaces; - //computation of the intersection volumes between source and target elements - MEDCouplingUMesh *distant_supportC=dynamic_cast<MEDCouplingUMesh *>(&distant_support); - MEDCouplingUMesh *source_supportC=dynamic_cast<MEDCouplingUMesh *>(_source_support); - if ( distant_support.getMeshDimension() == -1 ) - { - if(source_supportC->getMeshDimension()==2 && source_supportC->getSpaceDimension()==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(source_supportC); - INTERP_KERNEL::Interpolation2D interpolation(*this); - interpolation.fromIntegralUniform(source_mesh_wrapper,surfaces,srcMeth); - } - else if(source_supportC->getMeshDimension()==3 && source_supportC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(source_supportC); - INTERP_KERNEL::Interpolation3D interpolation(*this); - interpolation.fromIntegralUniform(source_mesh_wrapper,surfaces,srcMeth); - } - else if(source_supportC->getMeshDimension()==2 && source_supportC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(source_supportC); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - interpolation.fromIntegralUniform(source_mesh_wrapper,surfaces,srcMeth); - } - else - throw INTERP_KERNEL::Exception("No para interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); - } - else if ( source_supportC->getMeshDimension() == -1 ) - { - if(distant_supportC->getMeshDimension()==2 && distant_supportC->getSpaceDimension()==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> distant_mesh_wrapper(distant_supportC); - INTERP_KERNEL::Interpolation2D interpolation(*this); - interpolation.toIntegralUniform(distant_mesh_wrapper,surfaces,srcMeth); - } - else if(distant_supportC->getMeshDimension()==3 && distant_supportC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> distant_mesh_wrapper(distant_supportC); - INTERP_KERNEL::Interpolation3D interpolation(*this); - interpolation.toIntegralUniform(distant_mesh_wrapper,surfaces,srcMeth); - } - else if(distant_supportC->getMeshDimension()==2 && distant_supportC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> distant_mesh_wrapper(distant_supportC); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - interpolation.toIntegralUniform(distant_mesh_wrapper,surfaces,srcMeth); - } - else - throw INTERP_KERNEL::Exception("No para interpolation available for the given mesh and space dimension of distant mesh to -1D sourceMesh"); - } - else if ( distant_support.getMeshDimension() == 2 - && _source_support->getMeshDimension() == 3 - && distant_support.getSpaceDimension() == 3 && _source_support->getSpaceDimension() == 3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(source_supportC); - INTERP_KERNEL::Interpolation3D2D interpolator (*this); - interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if ( distant_support.getMeshDimension() == 1 - && _source_support->getMeshDimension() == 2 - && distant_support.getSpaceDimension() == 2 && _source_support->getSpaceDimension() == 2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(source_supportC); - INTERP_KERNEL::Interpolation2D1D interpolator (*this); - interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if ( distant_support.getMeshDimension() == 3 - && _source_support->getMeshDimension() == 1 - && distant_support.getSpaceDimension() == 3 && _source_support->getSpaceDimension() == 3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(source_supportC); - INTERP_KERNEL::Interpolation3D interpolator (*this); - interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if (distant_support.getMeshDimension() != _source_support->getMeshDimension()) - { - throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions"); - } - else if( distant_support.getMeshDimension() == 1 - && distant_support.getSpaceDimension() == 1 ) - { - MEDCouplingNormalizedUnstructuredMesh<1,1> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<1,1> source_wrapper(source_supportC); - - INTERP_KERNEL::Interpolation1D interpolation(*this); - interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if( distant_support.getMeshDimension() == 1 - && distant_support.getSpaceDimension() == 2 ) - { - MEDCouplingNormalizedUnstructuredMesh<2,1> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<2,1> source_wrapper(source_supportC); - - INTERP_KERNEL::Interpolation2DCurve interpolation(*this); - interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if ( distant_support.getMeshDimension() == 2 - && distant_support.getSpaceDimension() == 3 ) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<3,2> source_wrapper(source_supportC); - - INTERP_KERNEL::Interpolation3DSurf interpolator (*this); - interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if ( distant_support.getMeshDimension() == 2 - && distant_support.getSpaceDimension() == 2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(source_supportC); - - INTERP_KERNEL::Interpolation2D interpolator (*this); - interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else if ( distant_support.getMeshDimension() == 3 - && distant_support.getSpaceDimension() == 3 ) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(distant_supportC); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(source_supportC); - - INTERP_KERNEL::Interpolation3D interpolator (*this); - interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod); - target_wrapper.releaseTempArrays(); - source_wrapper.releaseTempArrays(); - } - else - { - throw INTERP_KERNEL::Exception("no interpolator exists for these mesh and space dimensions "); - } - bool needTargetSurf=isSurfaceComputationNeeded(targetMeth); - - MEDCouplingFieldDouble *target_triangle_surf=0; - if(needTargetSurf) - target_triangle_surf = distant_support.getMeasureField(getMeasureAbsStatus()); - fillDSFromVM(iproc_distant,distant_elems,surfaces,target_triangle_surf); - - if(needTargetSurf) - target_triangle_surf->decrRef(); - } - - void InterpolationMatrix::fillDSFromVM(int iproc_distant, const int* distant_elems, const std::vector< std::map<int,double> >& values, MEDCouplingFieldDouble *surf) - { - //loop over the elements to build the interpolation - //matrix structures - int source_size=values.size(); - for (int ielem=0; ielem < source_size; ielem++) - { - _row_offsets[ielem+1] += values[ielem].size(); - for(map<int,double>::const_iterator iter=values[ielem].begin();iter!=values[ielem].end();iter++) - { - int localId; - if(distant_elems) - localId=distant_elems[iter->first]; - else - localId=iter->first; - //locating the (iproc, itriangle) pair in the list of columns - map<pair<int,int>,int >::iterator iter2 = _col_offsets.find(make_pair(iproc_distant,localId)); - int col_id; - - if (iter2 == _col_offsets.end()) - { - //(iproc, itriangle) is not registered in the list - //of distant elements - col_id =_col_offsets.size(); - _col_offsets.insert(make_pair(make_pair(iproc_distant,localId),col_id)); - _mapping.addElementFromSource(iproc_distant,localId); - } - else - { - col_id = iter2->second; - } - //the non zero coefficient is stored - //ielem is the row, - //col_id is the number of the column - //iter->second is the value of the coefficient - if(surf) - { - double surface = surf->getIJ(iter->first,0); - _target_volume[ielem].push_back(surface); - } - _coeffs[ielem].push_back(make_pair(col_id,iter->second)); - } - } - } - - void InterpolationMatrix::serializeMe(std::vector< std::vector< std::map<int,double> > >& data1, std::vector<int>& data2) const - { - data1.clear(); - data2.clear(); - const std::vector<std::pair<int,int> >& sendingIds=_mapping.getSendingIds(); - std::set<int> procsS; - for(std::vector<std::pair<int,int> >::const_iterator iter1=sendingIds.begin();iter1!=sendingIds.end();iter1++) - procsS.insert((*iter1).first); - data1.resize(procsS.size()); - data2.resize(procsS.size()); - std::copy(procsS.begin(),procsS.end(),data2.begin()); - std::map<int,int> fastProcAcc; - int id=0; - for(std::set<int>::const_iterator iter2=procsS.begin();iter2!=procsS.end();iter2++,id++) - fastProcAcc[*iter2]=id; - int nbOfSrcElt=_coeffs.size(); - for(std::vector< std::vector< std::map<int,double> > >::iterator iter3=data1.begin();iter3!=data1.end();iter3++) - (*iter3).resize(nbOfSrcElt); - id=0; - for(std::vector< std::vector< std::pair<int,double> > >::const_iterator iter4=_coeffs.begin();iter4!=_coeffs.end();iter4++,id++) - { - for(std::vector< std::pair<int,double> >::const_iterator iter5=(*iter4).begin();iter5!=(*iter4).end();iter5++) - { - const std::pair<int,int>& elt=sendingIds[(*iter5).first]; - data1[fastProcAcc[elt.first]][id][elt.second]=(*iter5).second; - } - } - } - - void InterpolationMatrix::initialize() - { - int lgth=_coeffs.size(); - _row_offsets.clear(); _row_offsets.resize(lgth+1); - _coeffs.clear(); _coeffs.resize(lgth); - _target_volume.clear(); _target_volume.resize(lgth); - _col_offsets.clear(); - _mapping.initialize(); - } - - void InterpolationMatrix::finishContributionW(ElementLocator& elementLocator) - { - NatureOfField nature=elementLocator.getLocalNature(); - switch(nature) - { - case ConservativeVolumic: - computeConservVolDenoW(elementLocator); - break; - case Integral: - { - if(!elementLocator.isM1DCorr()) - computeIntegralDenoW(elementLocator); - else - computeGlobConstraintDenoW(elementLocator); - break; - } - case IntegralGlobConstraint: - computeGlobConstraintDenoW(elementLocator); - break; - case RevIntegral: - { - if(!elementLocator.isM1DCorr()) - computeRevIntegralDenoW(elementLocator); - else - computeConservVolDenoW(elementLocator); - break; - } - default: - throw INTERP_KERNEL::Exception("Not recognized nature of field. Change nature of Field."); - break; - } - } - - void InterpolationMatrix::finishContributionL(ElementLocator& elementLocator) - { - NatureOfField nature=elementLocator.getLocalNature(); - switch(nature) - { - case ConservativeVolumic: - computeConservVolDenoL(elementLocator); - break; - case Integral: - { - if(!elementLocator.isM1DCorr()) - computeIntegralDenoL(elementLocator); - else - computeConservVolDenoL(elementLocator); - break; - } - case IntegralGlobConstraint: - //this is not a bug doing like ConservativeVolumic - computeConservVolDenoL(elementLocator); - break; - case RevIntegral: - { - if(!elementLocator.isM1DCorr()) - computeRevIntegralDenoL(elementLocator); - else - computeConservVolDenoL(elementLocator); - break; - } - default: - throw INTERP_KERNEL::Exception("Not recognized nature of field. Change nature of Field."); - break; - } - } - - void InterpolationMatrix::computeConservVolDenoW(ElementLocator& elementLocator) - { - computeGlobalColSum(_deno_reverse_multiply); - computeGlobalRowSum(elementLocator,_deno_multiply,_deno_reverse_multiply); - } - - void InterpolationMatrix::computeConservVolDenoL(ElementLocator& elementLocator) - { - int pol1=elementLocator.sendPolicyToWorkingSideL(); - if(pol1==ElementLocator::NO_POST_TREATMENT_POLICY) - { - elementLocator.recvFromWorkingSideL(); - elementLocator.sendToWorkingSideL(); - } - else if(ElementLocator::CUMULATIVE_POLICY) - { - //ask for lazy side to deduce ids eventually missing on working side and to send it back. - elementLocator.recvLocalIdsFromWorkingSideL(); - elementLocator.sendCandidatesGlobalIdsToWorkingSideL(); - elementLocator.recvCandidatesForAddElementsL(); - elementLocator.sendAddElementsToWorkingSideL(); - //Working side has updated its eventually missing ids updates its global ids with lazy side procs contribution - elementLocator.recvLocalIdsFromWorkingSideL(); - elementLocator.sendGlobalIdsToWorkingSideL(); - //like no post treatment - elementLocator.recvFromWorkingSideL(); - elementLocator.sendToWorkingSideL(); - } - else - throw INTERP_KERNEL::Exception("Not managed policy detected on lazy side : not implemented !"); - } - - void InterpolationMatrix::computeIntegralDenoW(ElementLocator& elementLocator) - { - MEDCouplingFieldDouble *source_triangle_surf = _source_support->getMeasureField(getMeasureAbsStatus()); - _deno_multiply.resize(_coeffs.size()); - vector<vector<double> >::iterator iter6=_deno_multiply.begin(); - const double *values=source_triangle_surf->getArray()->getConstPointer(); - for(vector<vector<pair<int,double> > >::const_iterator iter4=_coeffs.begin();iter4!=_coeffs.end();iter4++,iter6++,values++) - { - (*iter6).resize((*iter4).size()); - std::fill((*iter6).begin(),(*iter6).end(),*values); - } - source_triangle_surf->decrRef(); - _deno_reverse_multiply=_target_volume; - } - - void InterpolationMatrix::computeRevIntegralDenoW(ElementLocator& elementLocator) - { - _deno_multiply=_target_volume; - MEDCouplingFieldDouble *source_triangle_surf = _source_support->getMeasureField(getMeasureAbsStatus()); - _deno_reverse_multiply.resize(_coeffs.size()); - vector<vector<double> >::iterator iter6=_deno_reverse_multiply.begin(); - const double *values=source_triangle_surf->getArray()->getConstPointer(); - for(vector<vector<pair<int,double> > >::const_iterator iter4=_coeffs.begin();iter4!=_coeffs.end();iter4++,iter6++,values++) - { - (*iter6).resize((*iter4).size()); - std::fill((*iter6).begin(),(*iter6).end(),*values); - } - source_triangle_surf->decrRef(); - } - - /*! - * Nothing to do because surface computation is on working side. - */ - void InterpolationMatrix::computeIntegralDenoL(ElementLocator& elementLocator) - { - } - - /*! - * Nothing to do because surface computation is on working side. - */ - void InterpolationMatrix::computeRevIntegralDenoL(ElementLocator& elementLocator) - { - } - - - void InterpolationMatrix::computeGlobConstraintDenoW(ElementLocator& elementLocator) - { - computeGlobalColSum(_deno_multiply); - computeGlobalRowSum(elementLocator,_deno_reverse_multiply,_deno_multiply); - } - - void InterpolationMatrix::computeGlobalRowSum(ElementLocator& elementLocator, std::vector<std::vector<double> >& denoStrorage, std::vector<std::vector<double> >& denoStrorageInv) - { - //stores id in distant procs sorted by lazy procs connected with - vector< vector<int> > rowsPartialSumI; - //stores for each lazy procs connected with, if global info is available and if it's the case the policy - vector<int> policyPartial; - //stores the corresponding values. - vector< vector<double> > rowsPartialSumD; - elementLocator.recvPolicyFromLazySideW(policyPartial); - int pol1=mergePolicies(policyPartial); - if(pol1==ElementLocator::NO_POST_TREATMENT_POLICY) - { - computeLocalRowSum(elementLocator.getDistantProcIds(),rowsPartialSumI,rowsPartialSumD); - elementLocator.sendSumToLazySideW(rowsPartialSumI,rowsPartialSumD); - elementLocator.recvSumFromLazySideW(rowsPartialSumD); - } - else if(pol1==ElementLocator::CUMULATIVE_POLICY) - { - //updateWithNewAdditionnalElements(addingElements); - //stores for each lazy procs connected with, the ids in global mode if it exists (regarding policyPartial). This array has exactly the size of rowsPartialSumI, - //if policyPartial has CUMALATIVE_POLICY in each. - vector< vector<int> > globalIdsPartial; - computeLocalRowSum(elementLocator.getDistantProcIds(),rowsPartialSumI,rowsPartialSumD); - elementLocator.sendLocalIdsToLazyProcsW(rowsPartialSumI); - elementLocator.recvCandidatesGlobalIdsFromLazyProcsW(globalIdsPartial); - std::vector< std::vector<int> > addingElements; - findAdditionnalElements(elementLocator,addingElements,rowsPartialSumI,globalIdsPartial); - addGhostElements(elementLocator.getDistantProcIds(),addingElements); - rowsPartialSumI.clear(); - globalIdsPartial.clear(); - computeLocalRowSum(elementLocator.getDistantProcIds(),rowsPartialSumI,rowsPartialSumD); - elementLocator.sendLocalIdsToLazyProcsW(rowsPartialSumI); - elementLocator.recvGlobalIdsFromLazyProcsW(rowsPartialSumI,globalIdsPartial); - // - elementLocator.sendSumToLazySideW(rowsPartialSumI,rowsPartialSumD); - elementLocator.recvSumFromLazySideW(rowsPartialSumD); - mergeRowSum3(globalIdsPartial,rowsPartialSumD); - mergeCoeffs(elementLocator.getDistantProcIds(),rowsPartialSumI,globalIdsPartial,denoStrorageInv); - } - else - throw INTERP_KERNEL::Exception("Not managed policy detected : not implemented !"); - divideByGlobalRowSum(elementLocator.getDistantProcIds(),rowsPartialSumI,rowsPartialSumD,denoStrorage); - } - - /*! - * @param distantProcs in parameter that indicates which lazy procs are concerned. - * @param resPerProcI out parameter that must be cleared before calling this method. The size of 1st dimension is equal to the size of 'distantProcs'. - * It contains the element ids (2nd dimension) of the corresponding lazy proc. - * @param resPerProcD out parameter with the same format than 'resPerProcI'. It contains corresponding sum values. - */ - void InterpolationMatrix::computeLocalRowSum(const std::vector<int>& distantProcs, std::vector<std::vector<int> >& resPerProcI, - std::vector<std::vector<double> >& resPerProcD) const - { - resPerProcI.resize(distantProcs.size()); - resPerProcD.resize(distantProcs.size()); - std::vector<double> res(_col_offsets.size()); - for(vector<vector<pair<int,double> > >::const_iterator iter=_coeffs.begin();iter!=_coeffs.end();iter++) - for(vector<pair<int,double> >::const_iterator iter3=(*iter).begin();iter3!=(*iter).end();iter3++) - res[(*iter3).first]+=(*iter3).second; - set<int> procsSet; - int id=-1; - const vector<std::pair<int,int> >& mapping=_mapping.getSendingIds(); - for(vector<std::pair<int,int> >::const_iterator iter2=mapping.begin();iter2!=mapping.end();iter2++) - { - std::pair<set<int>::iterator,bool> isIns=procsSet.insert((*iter2).first); - if(isIns.second) - id=std::find(distantProcs.begin(),distantProcs.end(),(*iter2).first)-distantProcs.begin(); - resPerProcI[id].push_back((*iter2).second); - resPerProcD[id].push_back(res[iter2-mapping.begin()]); - } - } - - /*! - * This method is only usable when CUMULATIVE_POLICY detected. This method finds elements ids (typically nodes) lazy side that - * are not present in columns of 'this' and that should regarding cumulative merge of elements regarding their global ids. - */ - void InterpolationMatrix::findAdditionnalElements(ElementLocator& elementLocator, std::vector<std::vector<int> >& elementsToAdd, - const std::vector<std::vector<int> >& resPerProcI, const std::vector<std::vector<int> >& globalIdsPartial) - { - std::set<int> globalIds; - int nbLazyProcs=globalIdsPartial.size(); - for(int i=0;i<nbLazyProcs;i++) - globalIds.insert(globalIdsPartial[i].begin(),globalIdsPartial[i].end()); - std::vector<int> tmp(globalIds.size()); - std::copy(globalIds.begin(),globalIds.end(),tmp.begin()); - globalIds.clear(); - elementLocator.sendCandidatesForAddElementsW(tmp); - elementLocator.recvAddElementsFromLazyProcsW(elementsToAdd); - } - - void InterpolationMatrix::addGhostElements(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& elementsToAdd) - { - std::vector< std::vector< std::map<int,double> > > data1; - std::vector<int> data2; - serializeMe(data1,data2); - initialize(); - int nbOfDistProcs=distantProcs.size(); - for(int i=0;i<nbOfDistProcs;i++) - { - int procId=distantProcs[i]; - const std::vector<int>& eltsForThisProc=elementsToAdd[i]; - if(!eltsForThisProc.empty()) - { - std::vector<int>::iterator iter1=std::find(data2.begin(),data2.end(),procId); - std::map<int,double> *toFeed=0; - if(iter1!=data2.end()) - {//to test - int rank=iter1-data2.begin(); - toFeed=&(data1[rank].back()); - } - else - { - iter1=std::lower_bound(data2.begin(),data2.end(),procId); - int rank=iter1-data2.begin(); - data2.insert(iter1,procId); - std::vector< std::map<int,double> > tmp(data1.front().size()); - data1.insert(data1.begin()+rank,tmp); - toFeed=&(data1[rank].back()); - } - for(std::vector<int>::const_iterator iter2=eltsForThisProc.begin();iter2!=eltsForThisProc.end();iter2++) - (*toFeed)[*iter2]=0.; - } - } - // - nbOfDistProcs=data2.size(); - for(int j=0;j<nbOfDistProcs;j++) - fillDSFromVM(data2[j],0,data1[j],0); - } - - int InterpolationMatrix::mergePolicies(const std::vector<int>& policyPartial) - { - if(policyPartial.empty()) - return ElementLocator::NO_POST_TREATMENT_POLICY; - int ref=policyPartial[0]; - std::vector<int>::const_iterator iter1=std::find_if(policyPartial.begin(),policyPartial.end(),std::bind2nd(std::not_equal_to<int>(),ref)); - if(iter1!=policyPartial.end()) - { - std::ostringstream msg; msg << "Incompatible policies between lazy procs each other : proc # " << iter1-policyPartial.begin(); - throw INTERP_KERNEL::Exception(msg.str().c_str()); - } - return ref; - } - - /*! - * This method introduce global ids aspects in computed 'rowsPartialSumD'. - * As precondition rowsPartialSumD.size()==policyPartial.size()==globalIdsPartial.size(). Foreach i in [0;rowsPartialSumD.size() ) rowsPartialSumD[i].size()==globalIdsPartial[i].size() - * @param rowsPartialSumD : in parameter, Partial row sum computed for each lazy procs connected with. - * @param rowsPartialSumI : in parameter, Corresponding local ids for each lazy procs connected with. - * @param globalIdsPartial : in parameter, the global numbering, of elements connected with. - * @param globalIdsLazySideInteraction : out parameter, constituted from all global ids of lazy procs connected with. - * @para sumCorresponding : out parameter, relative to 'globalIdsLazySideInteraction' - */ - void InterpolationMatrix::mergeRowSum(const std::vector< std::vector<double> >& rowsPartialSumD, const std::vector< std::vector<int> >& globalIdsPartial, - std::vector<int>& globalIdsLazySideInteraction, std::vector<double>& sumCorresponding) - { - std::map<int,double> sumToReturn; - int nbLazyProcs=rowsPartialSumD.size(); - for(int i=0;i<nbLazyProcs;i++) - { - const std::vector<double>& rowSumOfP=rowsPartialSumD[i]; - const std::vector<int>& globalIdsOfP=globalIdsPartial[i]; - std::vector<double>::const_iterator iter1=rowSumOfP.begin(); - std::vector<int>::const_iterator iter2=globalIdsOfP.begin(); - for(;iter1!=rowSumOfP.end();iter1++,iter2++) - sumToReturn[*iter2]+=*iter1; - } - // - int lgth=sumToReturn.size(); - globalIdsLazySideInteraction.resize(lgth); - sumCorresponding.resize(lgth); - std::vector<int>::iterator iter3=globalIdsLazySideInteraction.begin(); - std::vector<double>::iterator iter4=sumCorresponding.begin(); - for(std::map<int,double>::const_iterator iter5=sumToReturn.begin();iter5!=sumToReturn.end();iter5++,iter3++,iter4++) - { - *iter3=(*iter5).first; - *iter4=(*iter5).second; - } - } - - /*! - * This method simply reorganize the result contained in 'sumCorresponding' computed by lazy side into 'rowsPartialSumD' with help of 'globalIdsPartial' and 'globalIdsLazySideInteraction' - * - * @param globalIdsPartial : in parameter, global ids sorted by lazy procs - * @param rowsPartialSumD : in/out parameter, with exactly the same size as 'globalIdsPartial' - * @param globalIdsLazySideInteraction : in parameter that represents ALL the global ids of every lazy procs in interaction - * @param sumCorresponding : in parameter with same size as 'globalIdsLazySideInteraction' that stores the corresponding sum of 'globalIdsLazySideInteraction' - */ - void InterpolationMatrix::mergeRowSum2(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD, - const std::vector<int>& globalIdsLazySideInteraction, const std::vector<double>& sumCorresponding) - { - std::map<int,double> acc; - std::vector<int>::const_iterator iter1=globalIdsLazySideInteraction.begin(); - std::vector<double>::const_iterator iter2=sumCorresponding.begin(); - for(;iter1!=globalIdsLazySideInteraction.end();iter1++,iter2++) - acc[*iter1]=*iter2; - // - int nbLazyProcs=globalIdsPartial.size(); - for(int i=0;i<nbLazyProcs;i++) - { - const std::vector<int>& tmp1=globalIdsPartial[i]; - std::vector<double>& tmp2=rowsPartialSumD[i]; - std::vector<int>::const_iterator iter3=tmp1.begin(); - std::vector<double>::iterator iter4=tmp2.begin(); - for(;iter3!=tmp1.end();iter3++,iter4++) - *iter4=acc[*iter3]; - } - } - - void InterpolationMatrix::mergeRowSum3(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD) - { - std::map<int,double> sum; - std::vector< std::vector<int> >::const_iterator iter1=globalIdsPartial.begin(); - std::vector< std::vector<double> >::iterator iter2=rowsPartialSumD.begin(); - for(;iter1!=globalIdsPartial.end();iter1++,iter2++) - { - std::vector<int>::const_iterator iter3=(*iter1).begin(); - std::vector<double>::const_iterator iter4=(*iter2).begin(); - for(;iter3!=(*iter1).end();iter3++,iter4++) - sum[*iter3]+=*iter4; - } - iter2=rowsPartialSumD.begin(); - for(iter1=globalIdsPartial.begin();iter1!=globalIdsPartial.end();iter1++,iter2++) - { - std::vector<int>::const_iterator iter3=(*iter1).begin(); - std::vector<double>::iterator iter4=(*iter2).begin(); - for(;iter3!=(*iter1).end();iter3++,iter4++) - *iter4=sum[*iter3]; - } - } - - /*! - * This method updates this->_coeffs attribute in order to take into account hidden (because having the same global number) similar nodes in _coeffs array. - * If in this->_coeffs two distant element id have the same global id their values will be replaced for each by the sum of the two. - * @param procsInInteraction input parameter : specifies the procId in absolute of distant lazy procs in interaction with - * @param rowsPartialSumI input parameter : local ids of distant lazy procs elements in interaction with - * @param globalIdsPartial input parameter : global ids of distant lazy procs elements in interaction with - */ - void InterpolationMatrix::mergeCoeffs(const std::vector<int>& procsInInteraction, const std::vector< std::vector<int> >& rowsPartialSumI, - const std::vector<std::vector<int> >& globalIdsPartial, std::vector<std::vector<double> >& denoStrorageInv) - { - //preparing fast access structures - std::map<int,int> procT; - int localProcId=0; - for(std::vector<int>::const_iterator iter1=procsInInteraction.begin();iter1!=procsInInteraction.end();iter1++,localProcId++) - procT[*iter1]=localProcId; - int size=procsInInteraction.size(); - std::vector<std::map<int,int> > localToGlobal(size); - for(int i=0;i<size;i++) - { - std::map<int,int>& myLocalToGlobal=localToGlobal[i]; - const std::vector<int>& locals=rowsPartialSumI[i]; - const std::vector<int>& globals=globalIdsPartial[i]; - std::vector<int>::const_iterator iter3=locals.begin(); - std::vector<int>::const_iterator iter4=globals.begin(); - for(;iter3!=locals.end();iter3++,iter4++) - myLocalToGlobal[*iter3]=*iter4; - } - // - const vector<std::pair<int,int> >& mapping=_mapping.getSendingIds(); - std::map<int,double> globalIdVal; - //accumulate for same global id on lazy part. - for(vector<vector<pair<int,double> > >::iterator iter1=_coeffs.begin();iter1!=_coeffs.end();iter1++) - for(vector<pair<int,double> >::iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - const std::pair<int,int>& distantLocalLazyId=mapping[(*iter2).first]; - int localLazyProcId=procT[distantLocalLazyId.first]; - int globalDistantLazyId=localToGlobal[localLazyProcId][distantLocalLazyId.second]; - globalIdVal[globalDistantLazyId]+=(*iter2).second; - } - //perform merge - std::vector<std::vector<double> >::iterator iter3=denoStrorageInv.begin(); - for(vector<vector<pair<int,double> > >::iterator iter1=_coeffs.begin();iter1!=_coeffs.end();iter1++,iter3++) - { - double val=(*iter3).back(); - (*iter3).resize((*iter1).size()); - std::vector<double>::iterator iter4=(*iter3).begin(); - for(vector<pair<int,double> >::iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++,iter4++) - { - const std::pair<int,int>& distantLocalLazyId=mapping[(*iter2).first]; - int localLazyProcId=procT[distantLocalLazyId.first]; - int globalDistantLazyId=localToGlobal[localLazyProcId][distantLocalLazyId.second]; - double newVal=globalIdVal[globalDistantLazyId]; - if((*iter2).second!=0.) - (*iter4)=val*newVal/(*iter2).second; - else - (*iter4)=std::numeric_limits<double>::max(); - (*iter2).second=newVal; - } - } - } - - void InterpolationMatrix::divideByGlobalRowSum(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& resPerProcI, - const std::vector<std::vector<double> >& resPerProcD, std::vector<std::vector<double> >& deno) - { - map<int,double> fastSums; - int procId=0; - for(vector<int>::const_iterator iter1=distantProcs.begin();iter1!=distantProcs.end();iter1++,procId++) - { - const std::vector<int>& currentProcI=resPerProcI[procId]; - const std::vector<double>& currentProcD=resPerProcD[procId]; - vector<double>::const_iterator iter3=currentProcD.begin(); - for(vector<int>::const_iterator iter2=currentProcI.begin();iter2!=currentProcI.end();iter2++,iter3++) - fastSums[_col_offsets[std::make_pair(*iter1,*iter2)]]=*iter3; - } - deno.resize(_coeffs.size()); - vector<vector<double> >::iterator iter6=deno.begin(); - for(vector<vector<pair<int,double> > >::const_iterator iter4=_coeffs.begin();iter4!=_coeffs.end();iter4++,iter6++) - { - (*iter6).resize((*iter4).size()); - vector<double>::iterator iter7=(*iter6).begin(); - for(vector<pair<int,double> >::const_iterator iter5=(*iter4).begin();iter5!=(*iter4).end();iter5++,iter7++) - *iter7=fastSums[(*iter5).first]; - } - } - - void InterpolationMatrix::computeGlobalColSum(std::vector<std::vector<double> >& denoStrorage) - { - denoStrorage.resize(_coeffs.size()); - vector<vector<double> >::iterator iter2=denoStrorage.begin(); - for(vector<vector<pair<int,double> > >::const_iterator iter1=_coeffs.begin();iter1!=_coeffs.end();iter1++,iter2++) - { - (*iter2).resize((*iter1).size()); - double sumOfCurrentRow=0.; - for(vector<pair<int,double> >::const_iterator iter3=(*iter1).begin();iter3!=(*iter1).end();iter3++) - sumOfCurrentRow+=(*iter3).second; - std::fill((*iter2).begin(),(*iter2).end(),sumOfCurrentRow); - } - } - - void InterpolationMatrix::resizeGlobalColSum(std::vector<std::vector<double> >& denoStrorage) - { - vector<vector<double> >::iterator iter2=denoStrorage.begin(); - for(vector<vector<pair<int,double> > >::const_iterator iter1=_coeffs.begin();iter1!=_coeffs.end();iter1++,iter2++) - { - double val=(*iter2).back(); - (*iter2).resize((*iter1).size()); - std::fill((*iter2).begin(),(*iter2).end(),val); - } - } - - - /**! The call to this method updates the arrays on the target side - so that they know which amount of data from which processor they - should expect. - That call makes actual interpolations via multiply method - available. - */ - void InterpolationMatrix::prepare() - { - int nbelems = _source_field->getField()->getNumberOfTuples(); - for (int ielem=0; ielem < nbelems; ielem++) - { - _row_offsets[ielem+1]+=_row_offsets[ielem]; - } - _mapping.prepareSendRecv(); - } - - - - /*! - \brief performs t=Ws, where t is the target field, s is the source field - - The call to this method must be called both on the working side - and on the idle side. On the working side, the vector T=VT^(-1).(W.S) - is computed and sent. On the idle side, no computation is done, but the - result from the working side is received and the field is updated. - - \param field source field on processors involved on the source side, - target field on processors on the target side - */ - void InterpolationMatrix::multiply(MEDCouplingFieldDouble& field) const - { - int nbcomp = field.getArray()->getNumberOfComponents(); - vector<double> target_value(_col_offsets.size()* nbcomp,0.0); - - //computing the matrix multiply on source side - if (_source_group.containsMyRank()) - { - int nbrows = _coeffs.size(); - - // performing W.S - // W is the intersection matrix - // S is the source vector - - for (int irow=0; irow<nbrows; irow++) - { - for (int icomp=0; icomp< nbcomp; icomp++) - { - double coeff_row = field.getIJ(irow,icomp); - for (int icol=_row_offsets[irow]; icol< _row_offsets[irow+1];icol++) - { - int colid= _coeffs[irow][icol-_row_offsets[irow]].first; - double value = _coeffs[irow][icol-_row_offsets[irow]].second; - double deno = _deno_multiply[irow][icol-_row_offsets[irow]]; - target_value[colid*nbcomp+icomp]+=value*coeff_row/deno; - } - } - } - } - - if (_target_group.containsMyRank()) - { - int nbelems = field.getArray()->getNumberOfTuples() ; - double* value = const_cast<double*> (field.getArray()->getPointer()); - for (int i=0; i<nbelems*nbcomp; i++) - { - value[i]=0.0; - } - } - - //on source side : sending T=VT^(-1).(W.S) - //on target side :: receiving T and storing it in field - _mapping.sendRecv(&target_value[0],field); - } - - - /**! - \brief performs s=WTt, where t is the target field, s is the source field, - WT is the transpose matrix from W - - The call to this method must be called both on the working side - and on the idle side. On the working side, the target vector T is - received and the vector S=VS^(-1).(WT.T) is computed to update - the field. - On the idle side, no computation is done, but the field is sent. - - param field source field on processors involved on the source side, - target field on processors on the target side - */ - void InterpolationMatrix::transposeMultiply(MEDCouplingFieldDouble& field) const - { - int nbcomp = field.getArray()->getNumberOfComponents(); - vector<double> source_value(_col_offsets.size()* nbcomp,0.0); - _mapping.reverseSendRecv(&source_value[0],field); - - //treatment of the transpose matrix multiply on the source side - if (_source_group.containsMyRank()) - { - int nbrows = _coeffs.size(); - double *array = field.getArray()->getPointer() ; - - // Initialization - std::fill(array, array+nbrows*nbcomp, 0.0) ; - - //performing WT.T - //WT is W transpose - //T is the target vector - for (int irow = 0; irow < nbrows; irow++) - { - for (int icol = _row_offsets[irow]; icol < _row_offsets[irow+1]; icol++) - { - int colid = _coeffs[irow][icol-_row_offsets[irow]].first; - double value = _coeffs[irow][icol-_row_offsets[irow]].second; - double deno = _deno_reverse_multiply[irow][icol-_row_offsets[irow]]; - for (int icomp=0; icomp<nbcomp; icomp++) - { - double coeff_row = source_value[colid*nbcomp+icomp]; - array[irow*nbcomp+icomp] += value*coeff_row/deno; - } - } - } - } - } - - bool InterpolationMatrix::isSurfaceComputationNeeded(const std::string& method) const - { - return method=="P0"; - } -} diff --git a/medtool/src/ParaMEDMEM/InterpolationMatrix.hxx b/medtool/src/ParaMEDMEM/InterpolationMatrix.hxx deleted file mode 100644 index b60c9ee54..000000000 --- a/medtool/src/ParaMEDMEM/InterpolationMatrix.hxx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __INTERPOLATIONMATRIX_HXX__ -#define __INTERPOLATIONMATRIX_HXX__ - -#include "MPIAccessDEC.hxx" -#include "MxN_Mapping.hxx" -#include "InterpolationOptions.hxx" -#include "DECOptions.hxx" - -namespace ParaMEDMEM -{ - class ElementLocator; - - /*! - Internal class, not part of the public API. - - This class enables the storage of an interpolation matrix Wij mapping - a source field Sj to a target field Ti via Ti=Vi^(-1).Wij.Sj. - The matrix is built and stored on the processors belonging to the source - group. - */ - class InterpolationMatrix : public INTERP_KERNEL::InterpolationOptions, - public DECOptions - { - public: - - InterpolationMatrix(const ParaMEDMEM::ParaFIELD *source_field, - const ProcessorGroup& source_group, - const ProcessorGroup& target_group, - const DECOptions& dec_opt, - const InterpolationOptions& i_opt); - - - virtual ~InterpolationMatrix(); - void addContribution(MEDCouplingPointSet& distant_support, int iproc_distant, - const int* distant_elems, const std::string& srcMeth, const std::string& targetMeth); - void finishContributionW(ElementLocator& elementLocator); - void finishContributionL(ElementLocator& elementLocator); - void multiply(MEDCouplingFieldDouble& field) const; - void transposeMultiply(MEDCouplingFieldDouble& field)const; - void prepare(); - int getNbRows() const { return _row_offsets.size(); } - MPIAccessDEC* getAccessDEC() { return _mapping.getAccessDEC(); } - private: - void computeConservVolDenoW(ElementLocator& elementLocator); - void computeIntegralDenoW(ElementLocator& elementLocator); - void computeRevIntegralDenoW(ElementLocator& elementLocator); - void computeGlobConstraintDenoW(ElementLocator& elementLocator); - void computeConservVolDenoL(ElementLocator& elementLocator); - void computeIntegralDenoL(ElementLocator& elementLocator); - void computeRevIntegralDenoL(ElementLocator& elementLocator); - - void computeLocalColSum(std::vector<double>& res) const; - void computeLocalRowSum(const std::vector<int>& distantProcs, std::vector<std::vector<int> >& resPerProcI, - std::vector<std::vector<double> >& resPerProcD) const; - void computeGlobalRowSum(ElementLocator& elementLocator, std::vector<std::vector<double> >& denoStrorage, std::vector<std::vector<double> >& denoStrorageInv); - void computeGlobalColSum(std::vector<std::vector<double> >& denoStrorage); - void resizeGlobalColSum(std::vector<std::vector<double> >& denoStrorage); - void fillDSFromVM(int iproc_distant, const int* distant_elems, const std::vector< std::map<int,double> >& values, MEDCouplingFieldDouble *surf); - void serializeMe(std::vector< std::vector< std::map<int,double> > >& data1, std::vector<int>& data2) const; - void initialize(); - void findAdditionnalElements(ElementLocator& elementLocator, std::vector<std::vector<int> >& elementsToAdd, - const std::vector<std::vector<int> >& resPerProcI, const std::vector<std::vector<int> >& globalIdsPartial); - void addGhostElements(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& elementsToAdd); - int mergePolicies(const std::vector<int>& policyPartial); - void mergeRowSum(const std::vector< std::vector<double> >& rowsPartialSumD, const std::vector< std::vector<int> >& globalIdsPartial, - std::vector<int>& globalIdsLazySideInteraction, std::vector<double>& sumCorresponding); - void mergeRowSum2(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD, - const std::vector<int>& globalIdsLazySideInteraction, const std::vector<double>& sumCorresponding); - void mergeRowSum3(const std::vector< std::vector<int> >& globalIdsPartial, std::vector< std::vector<double> >& rowsPartialSumD); - void mergeCoeffs(const std::vector<int>& procsInInteraction, const std::vector< std::vector<int> >& rowsPartialSumI, - const std::vector<std::vector<int> >& globalIdsPartial, std::vector<std::vector<double> >& denoStrorageInv); - void divideByGlobalRowSum(const std::vector<int>& distantProcs, const std::vector<std::vector<int> >& resPerProcI, - const std::vector<std::vector<double> >& resPerProcD, std::vector<std::vector<double> >& deno); - private: - bool isSurfaceComputationNeeded(const std::string& method) const; - private: - const ParaMEDMEM::ParaFIELD *_source_field; - std::vector<int> _row_offsets; - std::map<std::pair<int,int>, int > _col_offsets; - MEDCouplingPointSet *_source_support; - MxN_Mapping _mapping; - - const ProcessorGroup& _source_group; - const ProcessorGroup& _target_group; - std::vector< std::vector<double> > _target_volume; - std::vector<std::vector<std::pair<int,double> > > _coeffs; - std::vector<std::vector<double> > _deno_multiply; - std::vector<std::vector<double> > _deno_reverse_multiply; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/LinearTimeInterpolator.cxx b/medtool/src/ParaMEDMEM/LinearTimeInterpolator.cxx deleted file mode 100644 index 79524983e..000000000 --- a/medtool/src/ParaMEDMEM/LinearTimeInterpolator.cxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "LinearTimeInterpolator.hxx" - -using namespace std; - -namespace ParaMEDMEM -{ - - LinearTimeInterpolator::LinearTimeInterpolator( double InterpPrecision, int nStepBefore, - int nStepAfter ): - TimeInterpolator( InterpPrecision, nStepBefore, nStepAfter ) - { - } - - LinearTimeInterpolator::~LinearTimeInterpolator() - { - } - - void LinearTimeInterpolator::doInterp( double time0, double time1, double time, - int recvcount , int nbuff0, int nbuff1, - int **recvbuff0, int **recvbuff1, int *result ) - { - for(int i = 0 ; i < recvcount ; i++ ) - result[i] = (int) ((recvbuff0[0][i]*(time1 - time) + recvbuff1[0][i]*(time - time0))/(time1 - time0) + _interp_precision); - } - - void LinearTimeInterpolator::doInterp( double time0, double time1, double time, - int recvcount , int nbuff0, int nbuff1, - double **recvbuff0, double **recvbuff1, - double *result ) - { - for(int i = 0 ; i < recvcount ; i++ ) - result[i] = (recvbuff0[0][i]*(time1 - time) + recvbuff1[0][i]*(time - time0))/(time1 - time0); - } - -} diff --git a/medtool/src/ParaMEDMEM/LinearTimeInterpolator.hxx b/medtool/src/ParaMEDMEM/LinearTimeInterpolator.hxx deleted file mode 100644 index 76eca3fc7..000000000 --- a/medtool/src/ParaMEDMEM/LinearTimeInterpolator.hxx +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __LINEARTIMEINTERPOLATOR_HXX__ -#define __LINEARTIMEINTERPOLATOR_HXX__ - -#include "TimeInterpolator.hxx" - -#include <map> -#include <iostream> - -namespace ParaMEDMEM -{ - class DEC; - - /*! - * Internal class, not part of the public API. - * - * Linear interpolation of a block of data between two given times. - */ - class LinearTimeInterpolator : public TimeInterpolator - { - public: - LinearTimeInterpolator( double InterpPrecision=0, int nStepBefore=1, - int nStepAfter=1 ) ; - virtual ~LinearTimeInterpolator(); - void doInterp( double time0, double time1, double time, int recvcount, - int nbuff0, int nbuff1, - int **recvbuff0, int **recvbuff1, int *result ); - void doInterp( double time0, double time1, double time, int recvcount, - int nbuff0, int nbuff1, - double **recvbuff0, double **recvbuff1, double *result ); - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/MPIAccess.cxx b/medtool/src/ParaMEDMEM/MPIAccess.cxx deleted file mode 100644 index b7fe80393..000000000 --- a/medtool/src/ParaMEDMEM/MPIAccess.cxx +++ /dev/null @@ -1,1091 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MPIAccess.hxx" -#include "InterpolationUtils.hxx" - -#include <iostream> - -using namespace std; - -namespace ParaMEDMEM -{ - /**! - \anchor MPIAccess-det - \class MPIAccess - - The class \a MPIAccess is the gateway to the MPI library. - It is a helper class that gathers the calls to the MPI - library that are made in the ParaMEDMEM library. This gathering - allows easier gathering of information about the communication - in the library. With MPIAccess, tags are managed automatically - and asynchronous operations are easier. - - It is typically called after the MPI_Init() call in a program. It is afterwards passed as a parameter to the constructors of ParaMEDMEM objects so that they access the MPI library via the MPIAccess. - - As an example, the following code initializes a processor group made of the zero processor. - - \verbatim - #include "MPIAccess.hxx" - #include "ProcessorGroup.hxx" - - int main(int argc, char** argv) - { - //initialization - MPI_Init(&argc, &argv); - ParaMEDMEM::CommInterface comm_interface; - - //setting up a processor group with proc 0 - set<int> procs; - procs.insert(0); - ParaMEDMEM::ProcessorGroup group(procs, comm_interface); - - ParaMEDMEM::MPIAccess mpi_access(group); - - //cleanup - MPI_Finalize(); - } - \endverbatim - */ - - - /*! Creates a MPIAccess that is based on the processors included in \a ProcessorGroup. - This class may be called for easier use of MPI API. - - \param ProcessorGroup MPIProcessorGroup object giving access to group management - \param BaseTag and MaxTag define the range of tags to be used. - Tags are managed by MPIAccess. They are cyclically incremented. - When there is a Send or a Receive operation there is a new RequestId tag returned - to the caller. That RequestId may be used to manage the operation Wait, Check of - status etc... The MPITag internally managed by MPIAccess is used as "tag" argument - in MPI call. - */ - - MPIAccess::MPIAccess(MPIProcessorGroup * ProcessorGroup, int BaseTag, int MaxTag) : - _comm_interface( ProcessorGroup->getCommInterface() ) , - _intra_communicator( ProcessorGroup->getComm() ) - { - void *v ; - int mpitagub ; - int flag ; - //MPI_Comm_get_attr does not run with _IntraCommunicator ??? - //MPI_Comm_get_attr(*_IntraCommunicator,MPID_TAG_UB,&mpitagub,&flag) ; - MPI_Comm_get_attr(MPI_COMM_WORLD,MPI_TAG_UB,&v,&flag) ; - mpitagub=*(reinterpret_cast<int*>(v)); - if ( BaseTag != 0 ) - BaseTag = (BaseTag/MODULO_TAG)*MODULO_TAG ; - if ( MaxTag == 0 ) - MaxTag = (mpitagub/MODULO_TAG-1)*MODULO_TAG ; - MPI_Comm_rank( *_intra_communicator, &_my_rank ) ; - if ( !flag | (BaseTag < 0) | (BaseTag >= MaxTag) | (MaxTag > mpitagub) ) - throw INTERP_KERNEL::Exception("wrong call to MPIAccess constructor"); - - _processor_group = ProcessorGroup ; - _processor_group_size = _processor_group->size() ; - _trace = false ; - - _base_request = -1 ; - _max_request = std::numeric_limits<int>::max() ; - _request = _base_request ; - - _base_MPI_tag = BaseTag ; - _max_MPI_tag = MaxTag ; - - _send_request = new int[ _processor_group_size ] ; - _recv_request = new int[ _processor_group_size ] ; - - _send_requests.resize( _processor_group_size ) ; - _recv_requests.resize( _processor_group_size ) ; - - _send_MPI_tag = new int[ _processor_group_size ] ; - _recv_MPI_Tag = new int[ _processor_group_size ] ; - int i ; - for (i = 0 ; i < _processor_group_size ; i++ ) - { - _send_request[ i ] = _max_request ; - _recv_request[ i ] = _max_request ; - _send_requests[ i ].resize(0) ; - _recv_requests[ i ].resize(0) ; - _send_MPI_tag[ i ] = _max_MPI_tag ; - _recv_MPI_Tag[ i ] = _max_MPI_tag ; - } - MPI_Datatype array_of_types[3] ; - array_of_types[0] = MPI_DOUBLE ; - array_of_types[1] = MPI_DOUBLE ; - array_of_types[2] = MPI_INT ; - int array_of_blocklengths[3] ; - array_of_blocklengths[0] = 1 ; - array_of_blocklengths[1] = 1 ; - array_of_blocklengths[2] = 1 ; - MPI_Aint array_of_displacements[3] ; - array_of_displacements[0] = 0 ; - array_of_displacements[1] = sizeof(double) ; - array_of_displacements[2] = 2*sizeof(double) ; - MPI_Type_struct(3, array_of_blocklengths, array_of_displacements, - array_of_types, &_MPI_TIME) ; - MPI_Type_commit(&_MPI_TIME) ; - } - - MPIAccess::~MPIAccess() - { - delete [] _send_request ; - delete [] _recv_request ; - delete [] _send_MPI_tag ; - delete [] _recv_MPI_Tag ; - MPI_Type_free(&_MPI_TIME) ; - } - - /* - MPIAccess and "RequestIds" : - ============================ - - . WARNING : In the specification document, the distinction - between "MPITags" and "RequestIds" is not clear. "MPITags" - are arguments of calls to MPI. "RequestIds" does not concern - calls to MPI. "RequestIds" are named "tag"as arguments in/out - in the MPIAccess API in the specification documentation. - But in the implementation we have the right name RequestId (or - RecvRequestId/SendRequestId). - - . When we have a MPI write/read request via MPIAccess, we get - an identifier "RequestId". - That identifier matches a structure RequestStruct of - MPIAccess. The access to that structure is done with the map - "_MapOfRequestStruct". - That structure RequestStruct give the possibility to manage - the structures MPI_Request and MPI_Status * of MPI. It give - also the possibility to get informations about that request : - target, send/recv, tag, [a]synchronous, type, outcount. - - . That identifier is used to control an asynchronous request - via MPIAccess : Wait, Test, Probe, etc... - - . In practise "RequestId" is simply an integer fo the interval - [0 , 2**32-1]. There is only one such a cyclic for - [I]Sends and [I]Recvs. - - . That "RequestIds" and their associated structures give an easy - way to manage asynchronous communications. - For example we have mpi_access->Wait( int RequestId ) instead of - MPI_Wait(MPI_Request *request, MPI_Status *status). - - . The API of MPIAccess may give the "SendRequestIds" of a "target", - the "RecvRequestIds" from a "source" or the "SendRequestIds" of - all "targets" or the "RecvRequestIds" of all "sources". - That avoid to manage them in Presentation-ParaMEDMEM. - */ - - int MPIAccess::newRequest( MPI_Datatype datatype, int tag , int destsourcerank , - bool fromsourcerank , bool asynchronous ) - { - RequestStruct *mpiaccessstruct = new RequestStruct; - mpiaccessstruct->MPITag = tag ; - mpiaccessstruct->MPIDatatype = datatype ; - mpiaccessstruct->MPITarget = destsourcerank ; - mpiaccessstruct->MPIIsRecv = fromsourcerank ; - MPI_Status *aStatus = new MPI_Status ; - mpiaccessstruct->MPIStatus = aStatus ; - mpiaccessstruct->MPIAsynchronous = asynchronous ; - mpiaccessstruct->MPICompleted = !asynchronous ; - mpiaccessstruct->MPIOutCount = -1 ; - if ( !asynchronous ) - { - mpiaccessstruct->MPIRequest = MPI_REQUEST_NULL ; - mpiaccessstruct->MPIStatus->MPI_SOURCE = destsourcerank ; - mpiaccessstruct->MPIStatus->MPI_TAG = tag ; - mpiaccessstruct->MPIStatus->MPI_ERROR = MPI_SUCCESS ; - } - if ( _request == _max_request ) - _request = _base_request ; - _request += 1 ; - _map_of_request_struct[_request] = mpiaccessstruct ; - if ( fromsourcerank ) - _recv_request[ destsourcerank ] = _request; - else - _send_request[ destsourcerank ] = _request; - if ( _trace ) - cout << "NewRequest" << _my_rank << "( " << _request << " ) " - << mpiaccessstruct << endl ; - return _request ; - } - - /* - MPIAccess and "tags" (or "MPITags") : - ===================================== - - . The constructor give the possibility to choose an interval of - tags to use : [BaseTag , MaxTag]. - The default is [ 0 , MPI_TAG_UB], MPI_TAG_UB being the maximum - value in an implementation of MPI (minimum 32767 = 2**15-1). - On awa with the implementation lam MPI_TAG_UB value is - 7353944. The norm MPI specify that value is the same in all - processes started by mpirun. - In the case of the use of the same IntraCommunicator in a process - for several distinct data flows (or for several IntraCommunicators - with common processes), that permits to avoid ambiguity - and may help debug. - - . In MPIAccess the tags have two parts (#define MODULO_TAG 10) : - + The last decimal digit decimal correspond to MPI_DataType ( 1 for - TimeMessages, 2 for MPI_INT and 3 for MPI_DOUBLE) - + The value of other digits correspond to a circular number for each - message. - + A TimeMessage and the associated DataMessage have the same number - (but the types are different and the tags also). - - . For a Send of a message from a process "source" to a process - "target", we have _send_MPI_tag[target] in the process - source (it contains the last "tag" used for the Send of a - message to the process target). - And in the process "target" which receive that message, we have - _recv_MPI_Tag[source] (it contains the last "tag" used for the Recv - of messages from the process source). - Naturally in the MPI norm the values of that tags must be the same. - */ - int MPIAccess::newSendTag( MPI_Datatype datatype, int destrank , int method , - bool asynchronous, int &RequestId ) - { - int tag ; - tag = incrTag( _send_MPI_tag[destrank] ) ; - tag = valTag( tag, method ) ; - _send_MPI_tag[ destrank ] = tag ; - RequestId = newRequest( datatype, tag, destrank , false , asynchronous ) ; - _send_request[ destrank ] = RequestId ; - _send_requests[ destrank ].push_back( RequestId ) ; - return tag ; - } - - int MPIAccess::newRecvTag( MPI_Datatype datatype, int sourcerank , int method , - bool asynchronous, int &RequestId ) - { - int tag ; - tag = incrTag( _recv_MPI_Tag[sourcerank] ) ; - tag = valTag( tag, method ) ; - _recv_MPI_Tag[ sourcerank ] = tag ; - RequestId = newRequest( datatype, tag , sourcerank , true , asynchronous ) ; - _recv_request[ sourcerank ] = RequestId ; - _recv_requests[ sourcerank ].push_back( RequestId ) ; - return tag ; - } - - // Returns the number of all SendRequestIds that may be used to allocate - // ArrayOfSendRequests for the call to SendRequestIds - int MPIAccess::sendRequestIdsSize() - { - int size = 0; - for (int i = 0 ; i < _processor_group_size ; i++ ) - size += _send_requests[ i ].size() ; - return size ; - } - - // Returns in ArrayOfSendRequests with the dimension "size" all the - // SendRequestIds - int MPIAccess::sendRequestIds(int size, int *ArrayOfSendRequests) - { - int destrank ; - int i = 0 ; - for ( destrank = 0 ; destrank < _processor_group_size ; destrank++ ) - { - list< int >::const_iterator iter ; - for (iter = _send_requests[ destrank ].begin() ; iter != _send_requests[destrank].end() ; iter++ ) - ArrayOfSendRequests[i++] = *iter ; - } - return i ; - } - - // Returns the number of all RecvRequestIds that may be used to allocate - // ArrayOfRecvRequests for the call to RecvRequestIds - int MPIAccess::recvRequestIdsSize() - { - int size = 0 ; - for (int i = 0 ; i < _processor_group_size ; i++ ) - size += _recv_requests[ i ].size() ; - return size ; - } - - // Returns in ArrayOfRecvRequests with the dimension "size" all the - // RecvRequestIds - int MPIAccess::recvRequestIds(int size, int *ArrayOfRecvRequests) - { - int sourcerank ; - int i = 0 ; - for ( sourcerank = 0 ; sourcerank < _processor_group_size ; sourcerank++ ) - { - list< int >::const_iterator iter ; - for (iter = _recv_requests[ sourcerank ].begin() ; iter != _recv_requests[sourcerank].end() ; iter++ ) - ArrayOfRecvRequests[i++] = *iter ; - } - return i ; - } - - // Returns in ArrayOfSendRequests with the dimension "size" all the - // SendRequestIds to a destination rank - int MPIAccess::sendRequestIds(int destrank, int size, int *ArrayOfSendRequests) - { - if (size < (int)_send_requests[destrank].size() ) - throw INTERP_KERNEL::Exception("wrong call to MPIAccess::SendRequestIds"); - int i = 0 ; - list< int >::const_iterator iter ; - for (iter = _send_requests[ destrank ].begin() ; iter != _send_requests[destrank].end() ; iter++ ) - ArrayOfSendRequests[i++] = *iter ; - return _send_requests[destrank].size() ; - } - - // Returns in ArrayOfRecvRequests with the dimension "size" all the - // RecvRequestIds from a sourcerank - int MPIAccess::recvRequestIds(int sourcerank, int size, int *ArrayOfRecvRequests) - { - if (size < (int)_recv_requests[sourcerank].size() ) - throw INTERP_KERNEL::Exception("wrong call to MPIAccess::RecvRequestIds"); - int i = 0 ; - list< int >::const_iterator iter ; - _recv_requests[ sourcerank ] ; - for (iter = _recv_requests[ sourcerank ].begin() ; iter != _recv_requests[sourcerank].end() ; iter++ ) - ArrayOfRecvRequests[i++] = *iter ; - return _recv_requests[sourcerank].size() ; - } - - // Send in synchronous mode count values of type datatype from buffer to target - // (returns RequestId identifier even if the corresponding structure is deleted : - // it is only in order to have the same signature as the asynchronous mode) - int MPIAccess::send(void* buffer, int count, MPI_Datatype datatype, int target, int &RequestId) - { - int sts = MPI_SUCCESS ; - RequestId = -1 ; - if ( count ) - { - _MessageIdent aMethodIdent = methodId( datatype ) ; - int MPItag = newSendTag( datatype, target , aMethodIdent , false , RequestId ) ; - if ( aMethodIdent == _message_time ) - { - TimeMessage *aTimeMsg = (TimeMessage *) buffer ; - aTimeMsg->tag = MPItag ; - } - deleteRequest( RequestId ) ; - sts = _comm_interface.send(buffer, count, datatype, target, MPItag, - *_intra_communicator ) ; - if ( _trace ) - cout << "MPIAccess::Send" << _my_rank << " SendRequestId " - << RequestId << " count " << count << " target " << target - << " MPItag " << MPItag << endl ; - } - return sts ; - } - - // Receive (read) in synchronous mode count values of type datatype in buffer from source - // (returns RequestId identifier even if the corresponding structure is deleted : - // it is only in order to have the same signature as the asynchronous mode) - // The output argument OutCount is optionnal : *OutCount <= count - int MPIAccess::recv(void* buffer, int count, MPI_Datatype datatype, int source, int &RequestId, int *OutCount) - { - int sts = MPI_SUCCESS ; - RequestId = -1 ; - if ( OutCount != NULL ) - *OutCount = -1 ; - if ( count ) - { - _MessageIdent aMethodIdent = methodId( datatype ) ; - int MPItag = newRecvTag( datatype, source , aMethodIdent , false , RequestId ) ; - sts = _comm_interface.recv(buffer, count, datatype, source, MPItag, - *_intra_communicator , MPIStatus( RequestId ) ) ; - int outcount = 0 ; - if ( sts == MPI_SUCCESS ) - { - MPI_Datatype datatype = MPIDatatype( RequestId ) ; - _comm_interface.getCount(MPIStatus( RequestId ), datatype, &outcount ) ; - setMPIOutCount( RequestId , outcount ) ; - setMPICompleted( RequestId , true ) ; - deleteStatus( RequestId ) ; - } - if ( OutCount != NULL ) - *OutCount = outcount ; - if ( _trace ) - cout << "MPIAccess::Recv" << _my_rank << " RecvRequestId " - << RequestId << " count " << count << " source " << source - << " MPItag " << MPItag << endl ; - deleteRequest( RequestId ) ; - } - return sts ; - } - - // Send in asynchronous mode count values of type datatype from buffer to target - // Returns RequestId identifier. - int MPIAccess::ISend(void* buffer, int count, MPI_Datatype datatype, int target, int &RequestId) - { - int sts = MPI_SUCCESS ; - RequestId = -1 ; - if ( count ) - { - _MessageIdent aMethodIdent = methodId( datatype ) ; - int MPItag = newSendTag( datatype, target , aMethodIdent , true , RequestId ) ; - if ( aMethodIdent == _message_time ) - { - TimeMessage *aTimeMsg = (TimeMessage *) buffer ; - aTimeMsg->tag = MPItag ; - } - MPI_Request *aSendRequest = MPIRequest( RequestId ) ; - if ( _trace ) - { - cout << "MPIAccess::ISend" << _my_rank << " ISendRequestId " - << RequestId << " count " << count << " target " << target - << " MPItag " << MPItag << endl ; - if ( MPItag == 1 ) - cout << "MPIAccess::ISend" << _my_rank << " time " - << ((TimeMessage *)buffer)->time << " " << ((TimeMessage *)buffer)->deltatime - << endl ; - } - sts = _comm_interface.Isend(buffer, count, datatype, target, MPItag, - *_intra_communicator , aSendRequest) ; - } - return sts ; - } - - // Receive (read) in asynchronous mode count values of type datatype in buffer from source - // returns RequestId identifier. - int MPIAccess::IRecv(void* buffer, int count, MPI_Datatype datatype, int source, int &RequestId) - { - int sts = MPI_SUCCESS ; - RequestId = -1 ; - if ( count ) - { - _MessageIdent aMethodIdent = methodId( datatype ) ; - int MPItag = newRecvTag( datatype, source , aMethodIdent , true , RequestId ) ; - MPI_Request *aRecvRequest = MPIRequest( RequestId ) ; - if ( _trace ) - { - cout << "MPIAccess::IRecv" << _my_rank << " IRecvRequestId " - << RequestId << " count " << count << " source " << source - << " MPItag " << MPItag << endl ; - if ( MPItag == 1 ) - cout << "MPIAccess::ISend" << _my_rank << " time " - << ((TimeMessage *)buffer)->time << " " << ((TimeMessage *)buffer)->deltatime - << endl ; - } - sts = _comm_interface.Irecv(buffer, count, datatype, source, MPItag, - *_intra_communicator , aRecvRequest) ; - } - return sts ; - } - - // Perform a Send and a Recv in synchronous mode - int MPIAccess::sendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, - int dest, int &SendRequestId, - void* recvbuf, int recvcount, MPI_Datatype recvtype, - int source, int &RecvRequestId, int *OutCount) - { - int sts = MPI_SUCCESS ; - SendRequestId = -1 ; - RecvRequestId = -1 ; - if ( recvcount ) - sts = IRecv(recvbuf, recvcount, recvtype, source, RecvRequestId) ; - int outcount = -1 ; - if ( _trace ) - cout << "MPIAccess::SendRecv" << _my_rank << " IRecv RecvRequestId " - << RecvRequestId << endl ; - if ( sts == MPI_SUCCESS ) - { - if ( sendcount ) - sts = send(sendbuf, sendcount, sendtype, dest, SendRequestId) ; - if ( _trace ) - cout << "MPIAccess::SendRecv" << _my_rank << " Send SendRequestId " - << SendRequestId << endl ; - if ( sts == MPI_SUCCESS && recvcount ) - { - sts = wait( RecvRequestId ) ; - outcount = MPIOutCount( RecvRequestId ) ; - if ( _trace ) - cout << "MPIAccess::SendRecv" << _my_rank << " IRecv RecvRequestId " - << RecvRequestId << " outcount " << outcount << endl ; - } - } - if ( OutCount != NULL ) - { - *OutCount = outcount ; - if ( _trace ) - cout << "MPIAccess::SendRecv" << _my_rank << " *OutCount = " << *OutCount - << endl ; - } - deleteRequest( RecvRequestId ) ; - return sts ; - } - - // Perform a Send and a Recv in asynchronous mode - int MPIAccess::ISendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, - int dest, int &SendRequestId, - void* recvbuf, int recvcount, MPI_Datatype recvtype, - int source, int &RecvRequestId) - { - int sts = MPI_SUCCESS ; - SendRequestId = -1 ; - RecvRequestId = -1 ; - if ( recvcount ) - sts = IRecv(recvbuf, recvcount, recvtype, source, RecvRequestId) ; - if ( sts == MPI_SUCCESS ) - if ( sendcount ) - sts = ISend(sendbuf, sendcount, sendtype, dest, SendRequestId) ; - return sts ; - } - - // Perform a wait of a Send or Recv asynchronous Request - // Do nothing for a synchronous Request - // Manage MPI_Request * and MPI_Status * structure - int MPIAccess::wait( int RequestId ) - { - int status = MPI_SUCCESS ; - if ( !MPICompleted( RequestId ) ) - { - if ( *MPIRequest( RequestId ) != MPI_REQUEST_NULL ) - { - if ( _trace ) - cout << "MPIAccess::Wait" << _my_rank << " -> wait( " << RequestId - << " ) MPIRequest " << MPIRequest( RequestId ) << " MPIStatus " - << MPIStatus( RequestId ) << " MPITag " << MPITag( RequestId ) - << " MPIIsRecv " << MPIIsRecv( RequestId ) << endl ; - status = _comm_interface.wait(MPIRequest( RequestId ), MPIStatus( RequestId )) ; - } - else - { - if ( _trace ) - cout << "MPIAccess::Wait" << _my_rank << " MPIRequest == MPI_REQUEST_NULL" - << endl ; - } - setMPICompleted( RequestId , true ) ; - if ( MPIIsRecv( RequestId ) && MPIStatus( RequestId ) ) - { - MPI_Datatype datatype = MPIDatatype( RequestId ) ; - int outcount ; - status = _comm_interface.getCount(MPIStatus( RequestId ), datatype, - &outcount ) ; - if ( status == MPI_SUCCESS ) - { - setMPIOutCount( RequestId , outcount ) ; - deleteStatus( RequestId ) ; - if ( _trace ) - cout << "MPIAccess::Wait" << _my_rank << " RequestId " << RequestId - << "MPIIsRecv " << MPIIsRecv( RequestId ) << " outcount " << outcount - << endl ; - } - else - { - if ( _trace ) - cout << "MPIAccess::Wait" << _my_rank << " MPIIsRecv " - << MPIIsRecv( RequestId ) << " outcount " << outcount << endl ; - } - } - else - { - if ( _trace ) - cout << "MPIAccess::Wait" << _my_rank << " MPIIsRecv " << MPIIsRecv( RequestId ) - << " MPIOutCount " << MPIOutCount( RequestId ) << endl ; - } - } - if ( _trace ) - cout << "MPIAccess::Wait" << _my_rank << " RequestId " << RequestId - << " Request " << MPIRequest( RequestId ) - << " Status " << MPIStatus( RequestId ) << " MPICompleted " - << MPICompleted( RequestId ) << " MPIOutCount " << MPIOutCount( RequestId ) - << endl ; - return status ; - } - - // Perform a "test" of a Send or Recv asynchronous Request - // If the request is done, returns true in the flag argument - // If the request is not finished, returns false in the flag argument - // Do nothing for a synchronous Request - // Manage MPI_request * and MPI_status * structure - int MPIAccess::test(int RequestId, int &flag) - { - int status = MPI_SUCCESS ; - flag = MPICompleted( RequestId ) ; - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " flag " << flag ; - if ( MPIIsRecv( RequestId ) ) - { - if ( _trace ) - cout << " Recv" ; - } - else - { - if ( _trace ) - cout << " Send" ; - } - if( _trace ) - cout << "Request" << RequestId << " " << MPIRequest( RequestId ) - << " Status " << MPIStatus( RequestId ) << endl ; - if ( !flag ) - { - if ( *MPIRequest( RequestId ) != MPI_REQUEST_NULL ) - { - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " -> test( " << RequestId - << " ) MPIRequest " << MPIRequest( RequestId ) - << " MPIStatus " << MPIStatus( RequestId ) - << " MPITag " << MPITag( RequestId ) - << " MPIIsRecv " << MPIIsRecv( RequestId ) << endl ; - status = _comm_interface.test(MPIRequest( RequestId ), &flag, - MPIStatus( RequestId )) ; - } - else - { - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " MPIRequest == MPI_REQUEST_NULL" - << endl ; - } - if ( flag ) - { - setMPICompleted( RequestId , true ) ; - if ( MPIIsRecv( RequestId ) && MPIStatus( RequestId ) ) - { - int outcount ; - MPI_Datatype datatype = MPIDatatype( RequestId ) ; - status = _comm_interface.getCount( MPIStatus( RequestId ), datatype, - &outcount ) ; - if ( status == MPI_SUCCESS ) - { - setMPIOutCount( RequestId , outcount ) ; - deleteStatus( RequestId ) ; - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " MPIIsRecv " - << MPIIsRecv( RequestId ) << " outcount " << outcount << endl ; - } - else - { - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " MPIIsRecv " - << MPIIsRecv( RequestId ) << " outcount " << outcount << endl ; - } - } - else - { - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " MPIIsRecv " - << MPIIsRecv( RequestId ) << " MPIOutCount " - << MPIOutCount( RequestId ) << endl ; - } - } - } - if ( _trace ) - cout << "MPIAccess::Test" << _my_rank << " RequestId " << RequestId - << " flag " << flag << " MPICompleted " << MPICompleted( RequestId ) - << " MPIOutCount " << MPIOutCount( RequestId ) << endl ; - return status ; - } - - int MPIAccess::waitAny(int count, int *array_of_RequestIds, int &RequestId) - { - int status = MPI_ERR_OTHER ; - RequestId = -1 ; - cout << "MPIAccess::WaitAny not yet implemented" << endl ; - return status ; - } - - int MPIAccess::testAny(int count, int *array_of_RequestIds, int &RequestId, int &flag) - { - int status = MPI_ERR_OTHER ; - RequestId = -1 ; - flag = 0 ; - cout << "MPIAccess::TestAny not yet implemented" << endl ; - return status ; - } - - // Perform a wait of each Send or Recv asynchronous Request of the array - // array_of_RequestIds of size "count". - // That array may be filled with a call to SendRequestIdsSize or RecvRequestIdsSize - // Do nothing for a synchronous Request - // Manage MPI_Request * and MPI_Status * structure - int MPIAccess::waitAll(int count, int *array_of_RequestIds) - { - if ( _trace ) - cout << "WaitAll" << _my_rank << " : count " << count << endl ; - int status ; - int retstatus = MPI_SUCCESS ; - int i ; - for ( i = 0 ; i < count ; i++ ) - { - if ( _trace ) - cout << "WaitAll" << _my_rank << " " << i << " -> Wait( " - << array_of_RequestIds[i] << " )" << endl ; - status = wait( array_of_RequestIds[i] ) ; - if ( status != MPI_SUCCESS ) - retstatus = status ; - } - if ( _trace ) - cout << "EndWaitAll" << _my_rank << endl ; - return retstatus ; - } - - // Perform a "test" of each Send or Recv asynchronous Request of the array - // array_of_RequestIds of size "count". - // That array may be filled with a call to SendRequestIdsSize or RecvRequestIdsSize - // If all requests are done, returns true in the flag argument - // If all requests are not finished, returns false in the flag argument - // Do nothing for a synchronous Request - // Manage MPI_Request * and MPI_Status * structure - int MPIAccess::testAll(int count, int *array_of_RequestIds, int &flag) - { - if ( _trace ) - cout << "TestAll" << _my_rank << " : count " << count << endl ; - int status ; - int retstatus = MPI_SUCCESS ; - bool retflag = true ; - int i ; - for ( i = 0 ; i < count ; i++ ) - { - status = test( array_of_RequestIds[i] , flag ) ; - retflag = retflag && (flag != 0) ; - if ( status != MPI_SUCCESS ) - retstatus = status ; - } - flag = retflag ; - if ( _trace ) - cout << "EndTestAll" << _my_rank << endl ; - return retstatus ; - } - - int MPIAccess::waitSome(int count, int *array_of_RequestIds, int outcount, - int *outarray_of_RequestIds) - { - int status = MPI_ERR_OTHER ; - cout << "MPIAccess::WaitSome not yet implemented" << endl ; - return status ; - } - - int MPIAccess::testSome(int count, int *array_of_RequestIds, int outcounts, - int *outarray_of_RequestIds) - { - int status = MPI_ERR_OTHER ; - cout << "MPIAccess::TestSome not yet implemented" << endl ; - return status ; - } - - // Probe checks if a message is available for read from FromSource rank. - // Returns the corresponding source, MPITag, datatype and outcount - // Probe is a blocking call which wait until a message is available - int MPIAccess::probe(int FromSource, int &source, int &MPITag, - MPI_Datatype &myDatatype, int &outcount) - { - MPI_Status aMPIStatus ; - int sts = _comm_interface.probe( FromSource, MPI_ANY_TAG, - *_intra_communicator , &aMPIStatus ) ; - if ( sts == MPI_SUCCESS ) - { - source = aMPIStatus.MPI_SOURCE ; - MPITag = aMPIStatus.MPI_TAG ; - int MethodId = (MPITag % MODULO_TAG) ; - myDatatype = datatype( (ParaMEDMEM::_MessageIdent) MethodId ) ; - _comm_interface.getCount(&aMPIStatus, myDatatype, &outcount ) ; - if ( _trace ) - cout << "MPIAccess::Probe" << _my_rank << " FromSource " << FromSource - << " source " << source << " MPITag " << MPITag << " MethodId " - << MethodId << " datatype " << myDatatype << " outcount " << outcount - << endl ; - } - else - { - source = -1 ; - MPITag = -1 ; - myDatatype = 0 ; - outcount = -1 ; - } - return sts ; - } - - // IProbe checks if a message is available for read from FromSource rank. - // If there is a message available, returns the corresponding source, - // MPITag, datatype and outcount with flag = true - // If not, returns flag = false - int MPIAccess::IProbe(int FromSource, int &source, int &MPITag, - MPI_Datatype &myDataType, int &outcount, int &flag) - { - MPI_Status aMPIStatus ; - int sts = _comm_interface.Iprobe( FromSource, MPI_ANY_TAG, - *_intra_communicator , &flag, - &aMPIStatus ) ; - if ( sts == MPI_SUCCESS && flag ) - { - source = aMPIStatus.MPI_SOURCE ; - MPITag = aMPIStatus.MPI_TAG ; - int MethodId = (MPITag % MODULO_TAG) ; - myDataType = datatype( (ParaMEDMEM::_MessageIdent) MethodId ) ; - _comm_interface.getCount(&aMPIStatus, myDataType, &outcount ) ; - if ( _trace ) - cout << "MPIAccess::IProbe" << _my_rank << " FromSource " << FromSource - << " source " << source << " MPITag " << MPITag << " MethodId " - << MethodId << " datatype " << myDataType << " outcount " << outcount - << " flag " << flag << endl ; - } - else - { - source = -1 ; - MPITag = -1 ; - myDataType = 0 ; - outcount = -1 ; - } - return sts ; - } - - // Cancel concerns a "posted" asynchronous IRecv - // Returns flag = true if the receiving request was successfully canceled - // Returns flag = false if the receiving request was finished but not canceled - // Use cancel, wait and test_cancelled of the MPI API - int MPIAccess::cancel( int RecvRequestId, int &flag ) - { - flag = 0 ; - int sts = _comm_interface.cancel( MPIRequest( RecvRequestId ) ) ; - if ( sts == MPI_SUCCESS ) - { - sts = _comm_interface.wait( MPIRequest( RecvRequestId ) , - MPIStatus( RecvRequestId ) ) ; - if ( sts == MPI_SUCCESS ) - sts = _comm_interface.testCancelled( MPIStatus( RecvRequestId ) , &flag ) ; - } - return sts ; - } - - // Cancel concerns a "pending" receiving message (without IRecv "posted") - // Returns flag = true if the message was successfully canceled - // Returns flag = false if the receiving request was finished but not canceled - // Use Irecv, cancel, wait and test_cancelled of the MPI API - int MPIAccess::cancel( int source, int theMPITag, MPI_Datatype datatype, int outcount, int &flag ) - { - int sts ; - MPI_Aint extent ; - flag = 0 ; - sts = MPI_Type_extent( datatype , &extent ) ; - if ( sts == MPI_SUCCESS ) - { - void * recvbuf = malloc( extent*outcount ) ; - MPI_Request aRecvRequest ; - if ( _trace ) - cout << "MPIAccess::Cancel" << _my_rank << " Irecv extent " << extent - << " datatype " << datatype << " source " << source << " theMPITag " - << theMPITag << endl ; - sts = _comm_interface.Irecv( recvbuf, outcount, datatype, source, theMPITag, - *_intra_communicator , &aRecvRequest ) ; - if ( sts == MPI_SUCCESS ) - { - sts = _comm_interface.cancel( &aRecvRequest ) ; - if ( _trace ) - cout << "MPIAccess::Cancel" << _my_rank << " theMPITag " << theMPITag - << " cancel done" << endl ; - if ( sts == MPI_SUCCESS ) - { - MPI_Status aStatus ; - if ( _trace ) - cout << "MPIAccess::Cancel" << _my_rank << " wait" << endl ; - sts = _comm_interface.wait( &aRecvRequest , &aStatus ) ; - if ( sts == MPI_SUCCESS ) - { - if ( _trace ) - cout << "MPIAccess::Cancel" << _my_rank << " test_cancelled" << endl ; - sts = _comm_interface.testCancelled( &aStatus , &flag ) ; - } - } - } - if ( _trace && datatype == timeType() ) - cout << "MPIAccess::Cancel" << _my_rank << " time " - << ((TimeMessage *) recvbuf)->time << " " - << ((TimeMessage *) recvbuf)->deltatime << endl ; - free( recvbuf ) ; - } - if ( _trace ) - cout << "MPIAccess::Cancel" << _my_rank << " flag " << flag << endl ; - return sts ; - } - - - // CancelAll concerns all "pending" receiving message (without IRecv "posted") - // CancelAll use IProbe and Cancel (see obove) - int MPIAccess::cancelAll() - { - int sts = MPI_SUCCESS ; - int target ; - int source ; - int MPITag ; - MPI_Datatype datatype ; - int outcount ; - int flag ; - for ( target = 0 ; target < _processor_group_size ; target++ ) - { - sts = IProbe(target, source, MPITag, datatype, outcount, flag) ; - if ( sts == MPI_SUCCESS && flag ) - { - sts = cancel(source, MPITag, datatype, outcount, flag) ; - if ( _trace ) - cout << "MPIAccess::CancelAll" << _my_rank << " source " << source - << " MPITag " << MPITag << " datatype " << datatype - << " outcount " << outcount << " Cancel flag " << flag << endl ; - if ( sts != MPI_SUCCESS ) - break ; - } - else if ( sts != MPI_SUCCESS ) - break ; - } - return sts ; - } - - // Same as barrier of MPI API - int MPIAccess::barrier() - { - int status = _comm_interface.barrier( *_intra_communicator ) ; - return status ; - } - - // Same as Error_string of MPI API - int MPIAccess::errorString(int errorcode, char *string, int *resultlen) const - { - return _comm_interface.errorString( errorcode, string, resultlen) ; - } - - // Returns source, tag, error and outcount corresponding to receiving RequestId - // By default the corresponding structure of RequestId is deleted - int MPIAccess::status(int RequestId, int &source, int &tag, int &error, - int &outcount, bool keepRequestStruct) - { - MPI_Status *myStatus = MPIStatus( RequestId ) ; - if ( _trace ) - cout << "MPIAccess::status" << _my_rank << " RequestId " << RequestId - << " status " << myStatus << endl ; - if ( myStatus != NULL && MPIAsynchronous( RequestId ) && - MPICompleted( RequestId ) ) - { - if ( MPIIsRecv( RequestId ) ) - { - source = myStatus->MPI_SOURCE ; - tag = myStatus->MPI_TAG ; - error = myStatus->MPI_ERROR ; - MPI_Datatype datatype = MPIDatatype( RequestId ) ; - _comm_interface.getCount(myStatus, datatype, &outcount ) ; - if ( _trace ) - cout << "MPIAccess::status" << _my_rank << " RequestId " << RequestId - << " status " << myStatus << " outcount " << outcount << endl ; - setMPIOutCount( RequestId , outcount ) ; - } - else - { - source = MPITarget( RequestId ) ; - tag = MPITag( RequestId ) ; - error = 0 ; - outcount = MPIOutCount( RequestId ) ; - } - if ( !keepRequestStruct ) - deleteRequest( RequestId ) ; - return MPI_SUCCESS ; - } - else - { - source = MPITarget( RequestId ) ; - tag = MPITag( RequestId ) ; - error = 0 ; - outcount = MPIOutCount( RequestId ) ; - } - return MPI_SUCCESS ; - } - - int MPIAccess::requestFree( MPI_Request *request ) - { - return _comm_interface.requestFree( request ) ; - } - - // Print all informations of all known requests for debugging purpose - void MPIAccess::check() const - { - int i = 0 ; - map< int , RequestStruct * >::const_iterator MapOfRequestStructiterator ; - cout << "MPIAccess::Check" << _my_rank << "_map_of_request_struct_size " - << _map_of_request_struct.size() << endl ; - for ( MapOfRequestStructiterator = _map_of_request_struct.begin() ; - MapOfRequestStructiterator != _map_of_request_struct.end() ; - MapOfRequestStructiterator++ ) - { - if ( MapOfRequestStructiterator->second != NULL ) - { - cout << " Check" << _my_rank << " " << i << ". Request" - << MapOfRequestStructiterator->first << "-->" ; - if ( (MapOfRequestStructiterator->second)->MPIAsynchronous ) - cout << "I" ; - if ( (MapOfRequestStructiterator->second)->MPIIsRecv ) - cout << "Recv from " ; - else - cout << "Send to " ; - cout << (MapOfRequestStructiterator->second)->MPITarget - << " MPITag " << (MapOfRequestStructiterator->second)->MPITag - << " DataType " << (MapOfRequestStructiterator->second)->MPIDatatype - << " Request " << (MapOfRequestStructiterator->second)->MPIRequest - << " Status " << (MapOfRequestStructiterator->second)->MPIStatus - << " Completed " << (MapOfRequestStructiterator->second)->MPICompleted - << endl ; - } - i++ ; - } - } - - // Returns the MPI size of a TimeMessage - MPI_Aint MPIAccess::timeExtent() const - { - MPI_Aint aextent ; - MPI_Type_extent( _MPI_TIME , &aextent ) ; - return aextent ; - } - - // Returns the MPI size of a MPI_INT - MPI_Aint MPIAccess::intExtent() const - { - MPI_Aint aextent ; - MPI_Type_extent( MPI_INT , &aextent ) ; - return aextent ; - } - - // Returns the MPI size of a MPI_DOUBLE - MPI_Aint MPIAccess::doubleExtent() const - { - MPI_Aint aextent ; - MPI_Type_extent( MPI_DOUBLE , &aextent ) ; - return aextent ; - } - - // Outputs fields of a TimeMessage structure - ostream & operator<< (ostream & f ,const TimeMessage & aTimeMsg ) - { - f << " time " << aTimeMsg.time << " deltatime " << aTimeMsg.deltatime - << " tag " << aTimeMsg.tag ; - return f; - } - - // Outputs the DataType coded in a Tag - ostream & operator<< (ostream & f ,const _MessageIdent & methodtype ) - { - switch (methodtype) - { - case _message_time : - f << " MethodTime "; - break; - case _message_int : - f << " MPI_INT "; - break; - case _message_double : - f << " MPI_DOUBLE "; - break; - default : - f << " UnknownMethodType "; - break; - } - return f; - } -} diff --git a/medtool/src/ParaMEDMEM/MPIAccess.hxx b/medtool/src/ParaMEDMEM/MPIAccess.hxx deleted file mode 100644 index d438c8cec..000000000 --- a/medtool/src/ParaMEDMEM/MPIAccess.hxx +++ /dev/null @@ -1,471 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MPIACCESS_HXX__ -#define __MPIACCESS_HXX__ - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" - -#include <map> -#include <list> -#include <vector> -#include <iostream> - -namespace ParaMEDMEM -{ - typedef struct - { - double time ; - double deltatime ; - int tag ; - } TimeMessage; - - static MPI_Request mpirequestnull = MPI_REQUEST_NULL ; - enum _MessageIdent { _message_unknown, _message_time, _message_int, _message_double } ; - - class MPIAccess - { - private: - struct RequestStruct - { - int MPITarget ; - bool MPIIsRecv ; - int MPITag ; - bool MPIAsynchronous ; - bool MPICompleted ; - MPI_Datatype MPIDatatype ; - MPI_Request MPIRequest ; - MPI_Status *MPIStatus ; - int MPIOutCount ; - }; - public: - MPIAccess(MPIProcessorGroup * ProcessorGroup, int BaseTag=0, int MaxTag=0) ; - virtual ~MPIAccess() ; - - void trace( bool trace = true ) ; - - void deleteRequest( int RequestId ) ; - void deleteRequests(int size , int *ArrayOfSendRequests ) ; - - int sendMPITag(int destrank) ; - int recvMPITag(int sourcerank) ; - - int sendRequestIdsSize() ; - int sendRequestIds(int size, int *ArrayOfSendRequests) ; - int recvRequestIdsSize() ; - int recvRequestIds(int size, int *ArrayOfRecvRequests) ; - - int sendRequestIdsSize(int destrank) ; - int sendRequestIds(int destrank, int size, int *ArrayOfSendRequests) ; - int recvRequestIdsSize(int sourcerank) ; - int recvRequestIds(int sourcerank, int size, int *ArrayOfRecvRequests) ; - - int send(void* buffer, int count, MPI_Datatype datatype, int target, - int &RequestId) ; - int ISend(void* buffer, int count, MPI_Datatype datatype, int target, - int &RequestId) ; - int recv(void* buffer, int count, MPI_Datatype datatype, int source, - int &RequestId, int *OutCount=NULL) ; - int IRecv(void* buffer, int count, MPI_Datatype datatype, int source, - int &RequestId) ; - int sendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dest, - int &SendRequestId, void* recvbuf, int recvcount, - MPI_Datatype recvtype, int source, - int &RecvRequestId, int *OutCount=NULL) ; - int ISendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dest, - int &SendRequestId, void* recvbuf, int recvcount, - MPI_Datatype recvtype, int source, int &RecvRequestId) ; - - int wait(int RequestId) ; - int test(int RequestId, int &flag) ; - int waitAny(int count, int *array_of_RequestIds, int &RequestId) ; - int testAny(int count, int *array_of_RequestIds, int &RequestId, int &flag) ; - int waitAll(int count, int *array_of_RequestIds) ; - int testAll(int count, int *array_of_RequestIds, int &flag) ; - int waitSome(int count, int *array_of_RequestIds, int outcount, - int *outarray_of_RequestIds) ; - int testSome(int count, int *array_of_RequestIds, int outcounts, - int *outarray_of_RequestIds) ; - int probe(int FromSource, int &source, int &MPITag, MPI_Datatype &datatype, - int &outcount) ; - int IProbe(int FromSource, int &source, int &MPITag, MPI_Datatype &datatype, - int &outcount, int &flag) ; - int cancel( int RecvRequestId, int &flag ) ; - int cancel( int source, int MPITag, MPI_Datatype datatype, int outcount, - int &flag ) ; - int cancelAll() ; - int barrier() ; - int errorString(int errorcode, char *string, int *resultlen) const ; - int status(int RequestId, int &source, int &tag, int &error, int &outcount, - bool keepRequestStruct=false) ; - int requestFree( MPI_Request *request ) ; - - void check() const ; - - MPI_Datatype timeType() const ; - bool isTimeMessage( int MPITag ) const ; - MPI_Aint timeExtent() const ; - MPI_Aint intExtent() const ; - MPI_Aint doubleExtent() const ; - MPI_Aint extent( MPI_Datatype datatype ) const ; - - int MPITag( int RequestId ) ; - int MPITarget( int RequestId ) ; - bool MPIIsRecv( int RequestId ) ; - bool MPIAsynchronous( int RequestId ) ; - bool MPICompleted( int RequestId ) ; - MPI_Datatype MPIDatatype( int RequestId ) ; - int MPIOutCount( int RequestId ) ; - - private: - int newRequest( MPI_Datatype datatype, int tag , int destsourcerank , - bool fromsourcerank , bool asynchronous ) ; - int newSendTag( MPI_Datatype datatype, int destrank , int method , - bool asynchronous, int &RequestId ) ; - int newRecvTag( MPI_Datatype datatype, int sourcerank , int method , - bool asynchronous, int &RequestId ) ; - int incrTag( int prevtag ) ; - int valTag( int tag, int method ) ; - - void deleteSendRecvRequest( int RequestId ) ; - - void deleteStatus( int RequestId ) ; - - MPI_Request *MPIRequest( int RequestId ) ; - MPI_Status *MPIStatus( int RequestId ) ; - void setMPICompleted( int RequestId , bool completed ) ; - void setMPIOutCount( int RequestId , int outcount ) ; - void clearMPIStatus( int RequestId ) ; - - _MessageIdent methodId( MPI_Datatype datatype ) const ; - MPI_Datatype datatype( _MessageIdent aMethodIdent ) const ; - private: - const CommInterface &_comm_interface ; - const MPI_Comm* _intra_communicator ; - MPIProcessorGroup * _processor_group ; - int _processor_group_size ; - int _my_rank ; - bool _trace ; - int _base_request ; - int _max_request ; - int _request ; - int * _send_request ; - int * _recv_request ; - std::vector< std::list< int > > _send_requests ; - std::vector< std::list< int > > _recv_requests ; - int _base_MPI_tag ; - int _max_MPI_tag ; - int * _send_MPI_tag ; - int * _recv_MPI_Tag ; - MPI_Datatype _MPI_TIME ; - static const int MODULO_TAG=10; - std::map< int , RequestStruct * > _map_of_request_struct ; - - }; - - inline void MPIAccess::trace( bool atrace ) - { - _trace = atrace ; - } - - // Delete the structure Request corresponding to RequestId identifier after - // the deletion of the structures MPI_Request * and MPI_Status * - // remove it from _MapOfRequestStruct (erase) - inline void MPIAccess::deleteRequest( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - { - if ( _trace ) - std::cout << "MPIAccess::DeleteRequest" << _my_rank << "( " << RequestId << " ) " - << aRequestStruct << " MPIRequest " << aRequestStruct->MPIRequest - << " MPIIsRecv " << aRequestStruct->MPIIsRecv << std::endl ; - if ( _map_of_request_struct[RequestId]->MPIRequest != MPI_REQUEST_NULL ) - requestFree( &_map_of_request_struct[RequestId]->MPIRequest ) ; - deleteSendRecvRequest( RequestId ) ; - deleteStatus( RequestId ) ; - _map_of_request_struct.erase( RequestId ) ; - delete aRequestStruct ; - } - else - { - if ( _trace ) - std::cout << "MPIAccess::DeleteRequest" << _my_rank << "( " << RequestId - << " ) Request not found" << std::endl ; - } - } - - // Delete all requests of the array ArrayOfSendRequests - inline void MPIAccess::deleteRequests(int size , int *ArrayOfSendRequests ) - { - for (int i = 0 ; i < size ; i++ ) - deleteRequest( ArrayOfSendRequests[i] ) ; - } - - // Returns the last MPITag of the destination rank destrank - inline int MPIAccess::sendMPITag(int destrank) - { - return _send_MPI_tag[destrank] ; - } - - // Returns the last MPITag of the source rank sourcerank - inline int MPIAccess::recvMPITag(int sourcerank) - { - return _recv_MPI_Tag[sourcerank] ; - } - - // Returns the number of all SendRequestIds matching a destination rank. It may be - // used to allocate ArrayOfSendRequests for the call to SendRequestIds - inline int MPIAccess::sendRequestIdsSize(int destrank) - { - return _send_requests[destrank].size() ; - } - - // Returns the number of all RecvRequestIds matching a source rank. It may be - // used to allocate ArrayOfRecvRequests for the call to RecvRequestIds - inline int MPIAccess::recvRequestIdsSize(int sourcerank) - { - return _recv_requests[sourcerank].size() ; - } - - // Returns the MPI_Datatype (registered in MPI in the constructor with - // MPI_Type_struct and MPI_Type_commit) for TimeMessages - inline MPI_Datatype MPIAccess::timeType() const - { - return _MPI_TIME ; - } - - // Returns true if the tag MPITag corresponds to a TimeMessage - inline bool MPIAccess::isTimeMessage( int aMPITag ) const - { - return ((aMPITag%MODULO_TAG) == _message_time) ; - } - - // Returns the MPI size of the MPI_Datatype datatype - inline MPI_Aint MPIAccess::extent( MPI_Datatype adatatype ) const - { - if ( adatatype == _MPI_TIME ) - return timeExtent() ; - if ( adatatype == MPI_INT ) - return intExtent() ; - if ( adatatype == MPI_DOUBLE ) - return doubleExtent() ; - return 0 ; - } - - // Returns the MPITag of the request corresponding to RequestId identifier - inline int MPIAccess::MPITag( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPITag ; - return -1 ; - } - - // Returns the MPITarget of the request corresponding to RequestId identifier - inline int MPIAccess::MPITarget( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPITarget ; - return -1 ; - } - - // Returns true if the request corresponding to RequestId identifier was [I]Recv - inline bool MPIAccess::MPIIsRecv( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPIIsRecv ; - return false ; - } - - // Returns true if the request corresponding to RequestId identifier was asynchronous - inline bool MPIAccess::MPIAsynchronous( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPIAsynchronous ; - return false ; - } - - // Returns true if the request corresponding to RequestId identifier was completed - inline bool MPIAccess::MPICompleted( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPICompleted; - return true ; - } - - // Returns the MPI_datatype of the request corresponding to RequestId identifier - inline MPI_Datatype MPIAccess::MPIDatatype( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPIDatatype; - return MPI_DATATYPE_NULL; - } - - // Returns the size of the receiving message of the request corresponding to - // RequestId identifier - inline int MPIAccess::MPIOutCount( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return aRequestStruct->MPIOutCount; - return 0 ; - } - - // Increments the previous tag value (cyclically) - // Look at MPIAccess::NewSendTag/NewRecvTag in MPIAccess.cxx - inline int MPIAccess::incrTag( int prevtag ) - { - int tag; - if ( (prevtag % MODULO_TAG) == _message_time ) - tag = ((prevtag/MODULO_TAG)*MODULO_TAG); - else - tag = ((prevtag/MODULO_TAG + 1)*MODULO_TAG); - if ( tag > _max_MPI_tag ) - tag = _base_MPI_tag ; - return tag ; - } - - // Returns the MPITag with the method-type field - // Look at MPIAccess::NewSendTag/NewRecvTag in MPIAccess.cxx - inline int MPIAccess::valTag( int tag, int method ) - { - return ((tag/MODULO_TAG)*MODULO_TAG) + method; - } - - // Remove a Request identifier from the list _RecvRequests/_SendRequests for - // the corresponding target. - inline void MPIAccess::deleteSendRecvRequest( int RequestId ) - { - if ( _trace ) - std::cout << "MPIAccess::DeleteSendRecvRequest" << _my_rank - << "( " << RequestId << " ) " << std::endl ; - if ( MPIIsRecv( RequestId ) ) - _recv_requests[ MPITarget( RequestId ) ].remove( RequestId ); - else - _send_requests[ MPITarget( RequestId ) ].remove( RequestId ); - } - - // Delete the MPI structure MPI_status * of a ReaquestId - inline void MPIAccess::deleteStatus( int RequestId ) - { - if ( _map_of_request_struct[RequestId]->MPIStatus != NULL ) - { - delete _map_of_request_struct[RequestId]->MPIStatus ; - clearMPIStatus( RequestId ) ; - } - } - - // Returns the MPI structure MPI_request * of a RequestId - inline MPI_Request * MPIAccess::MPIRequest( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - return &aRequestStruct->MPIRequest; - return &mpirequestnull ; - } - - // Returns the MPI structure MPI_status * of a RequestId - inline MPI_Status * MPIAccess::MPIStatus( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ]; - if ( aRequestStruct ) - return aRequestStruct->MPIStatus; - return NULL ; - } - - // Set the MPICompleted field of the structure Request corresponding to RequestId - // identifier with the value completed - inline void MPIAccess::setMPICompleted( int RequestId , bool completed ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - aRequestStruct->MPICompleted = completed; - } - - // Set the MPIOutCount field of the structure Request corresponding to RequestId - // identifier with the value outcount - inline void MPIAccess::setMPIOutCount( int RequestId , int outcount ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - aRequestStruct->MPIOutCount = outcount; - } - - // Nullify the MPIStatusfield of the structure Request corresponding to RequestId - // identifier - inline void MPIAccess::clearMPIStatus( int RequestId ) - { - struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; - if ( aRequestStruct ) - aRequestStruct->MPIStatus = NULL ; - } - - // Returns the _MessageIdent enum value corresponding to the MPI_Datatype datatype - // Look at MPIAccess::NewSendTag/NewRecvTag in MPIAccess.cxx - inline _MessageIdent MPIAccess::methodId( MPI_Datatype adatatype ) const - { - _MessageIdent aMethodIdent ; - if ( adatatype == _MPI_TIME ) - aMethodIdent = _message_time; - else if ( adatatype == MPI_INT ) - aMethodIdent = _message_int ; - else if ( adatatype == MPI_DOUBLE ) - aMethodIdent = _message_double ; - else - aMethodIdent = _message_unknown ; - return aMethodIdent ; - } - - // Returns the MPI_Datatype corresponding to the _MessageIdent enum aMethodIdent - inline MPI_Datatype MPIAccess::datatype( _MessageIdent aMethodIdent ) const - { - MPI_Datatype aDataType ; - switch( aMethodIdent ) - { - case _message_time : - aDataType = _MPI_TIME ; - break ; - case _message_int : - aDataType = MPI_INT ; - break ; - case _message_double : - aDataType = MPI_DOUBLE ; - break ; - default : - aDataType = (MPI_Datatype) -1 ; - break ; - } - return aDataType ; - } - - std::ostream & operator<< (std::ostream &,const _MessageIdent &); - - std::ostream & operator<< (std::ostream &,const TimeMessage &); - -} - -#endif diff --git a/medtool/src/ParaMEDMEM/MPIAccessDEC.cxx b/medtool/src/ParaMEDMEM/MPIAccessDEC.cxx deleted file mode 100644 index 18184dc27..000000000 --- a/medtool/src/ParaMEDMEM/MPIAccessDEC.cxx +++ /dev/null @@ -1,1057 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MPIAccessDEC.hxx" - -#include <cstring> - -using namespace std; - -namespace ParaMEDMEM -{ - - /*! - This constructor creates an MPIAccessDEC which has \a source_group as a working side - and \a target_group as an idle side. - The constructor must be called synchronously on all processors of both processor groups. - - \param source_group working side ProcessorGroup - \param target_group lazy side ProcessorGroup - \param Asynchronous Communication mode (default asynchronous) - \param nStepBefore Number of Time step needed for the interpolation before current time - \param nStepAfter Number of Time step needed for the interpolation after current time - - */ - - MPIAccessDEC::MPIAccessDEC( const ProcessorGroup& source_group, - const ProcessorGroup& target_group, - bool Asynchronous ) - { - - ProcessorGroup * union_group = source_group.fuse(target_group) ; - int i ; - std::set<int> procs; - for ( i = 0 ; i < union_group->size() ; i++ ) - { - procs.insert(i) ; - } - MPIProcessorGroup *mpilg = static_cast<MPIProcessorGroup *>(const_cast<ProcessorGroup *>(&source_group)); - _MPI_union_group = new ParaMEDMEM::MPIProcessorGroup( union_group->getCommInterface(),procs,mpilg->getWorldComm()); - delete union_group ; - _my_rank = _MPI_union_group->myRank() ; - _group_size = _MPI_union_group->size() ; - _MPI_access = new MPIAccess( _MPI_union_group ) ; - _asynchronous = Asynchronous ; - _time_messages = new vector< vector< TimeMessage > > ; - _time_messages->resize( _group_size ) ; - _out_of_time = new vector< bool > ; - _out_of_time->resize( _group_size ) ; - _data_messages_recv_count = new vector< int > ; - _data_messages_recv_count->resize( _group_size ) ; - for ( i = 0 ; i < _group_size ; i++ ) - { - (*_out_of_time)[i] = false ; - (*_data_messages_recv_count)[i] = 0 ; - } - _data_messages_type = new vector< MPI_Datatype > ; - _data_messages_type->resize( _group_size ) ; - _data_messages = new vector< vector< void * > > ; - _data_messages->resize( _group_size ) ; - _time_interpolator = NULL ; - _map_of_send_buffers = new map< int , SendBuffStruct * > ; - } - - MPIAccessDEC::~MPIAccessDEC() - { - checkFinalSent() ; - checkFinalRecv() ; - delete _MPI_union_group ; - delete _MPI_access ; - if ( _time_interpolator ) - delete _time_interpolator ; - if ( _time_messages ) - delete _time_messages ; - if ( _out_of_time ) - delete _out_of_time ; - if ( _data_messages_recv_count ) - delete _data_messages_recv_count ; - if ( _data_messages_type ) - delete _data_messages_type ; - if ( _data_messages ) - delete _data_messages ; - if ( _map_of_send_buffers ) - delete _map_of_send_buffers ; - } - - void MPIAccessDEC::setTimeInterpolator( TimeInterpolationMethod aTimeInterp , - double InterpPrecision, int nStepBefore, - int nStepAfter ) - { - if ( _time_interpolator ) - delete _time_interpolator ; - switch ( aTimeInterp ) - { - case WithoutTimeInterp : - _time_interpolator = NULL ; - _n_step_before = 0 ; - _n_step_after = 0 ; - break ; - case LinearTimeInterp : - _time_interpolator = new LinearTimeInterpolator( InterpPrecision , nStepBefore , - nStepAfter ) ; - _n_step_before = nStepBefore ; - _n_step_after = nStepAfter ; - int i ; - for ( i = 0 ; i < _group_size ; i++ ) - { - (*_time_messages)[ i ].resize( _n_step_before + _n_step_after ) ; - (*_data_messages)[ i ].resize( _n_step_before + _n_step_after ) ; - int j ; - for ( j = 0 ; j < _n_step_before + _n_step_after ; j++ ) - { - (*_time_messages)[ i ][ j ].time = -1 ; - (*_time_messages)[ i ][ j ].deltatime = -1 ; - (*_data_messages)[ i ][ j ] = NULL ; - } - } - break ; - } - } - - /*! - Send sendcount datas from sendbuf[offset] with type sendtype to target of IntraCommunicator - (Internal Protected method) - - Returns the request identifier SendRequestId - - */ - int MPIAccessDEC::send( void* sendbuf, int sendcount , int offset , - MPI_Datatype sendtype , int target , int &SendRequestId ) - { - int sts ; - if ( _asynchronous ) - { - if ( sendtype == MPI_INT ) - { - sts = _MPI_access->ISend( &((int *) sendbuf)[offset] , sendcount , sendtype , - target , SendRequestId ) ; - } - else - { - sts = _MPI_access->ISend( &((double *) sendbuf)[offset] , sendcount , sendtype , - target , SendRequestId ) ; - } - } - else - { - if ( sendtype == MPI_INT ) - { - sts = _MPI_access->send( &((int *) sendbuf)[offset] , sendcount , sendtype , - target , SendRequestId ) ; - } - else - { - sts = _MPI_access->send( &((double *) sendbuf)[offset] , sendcount , sendtype , - target , SendRequestId ) ; - } - } - return sts ; - } - - /*! - Receive recvcount datas to recvbuf[offset] with type recvtype from target of IntraCommunicator - (Internal Protected method) - - Returns the request identifier RecvRequestId - - */ - int MPIAccessDEC::recv( void* recvbuf, int recvcount , int offset , - MPI_Datatype recvtype , int target , int &RecvRequestId ) - { - int sts ; - if ( _asynchronous ) - { - if ( recvtype == MPI_INT ) - { - sts = _MPI_access->IRecv( &((int *) recvbuf)[offset] , recvcount , recvtype , - target , RecvRequestId ) ; - } - else - { - sts = _MPI_access->IRecv( &((double *) recvbuf)[offset] , recvcount , recvtype , - target , RecvRequestId ) ; - } - } - else - { - if ( recvtype == MPI_INT ) - { - sts = _MPI_access->recv( &((int *) recvbuf)[offset] , recvcount , recvtype , - target , RecvRequestId ) ; - } - else - { - sts = _MPI_access->recv( &((double *) recvbuf)[offset] , recvcount , recvtype , - target , RecvRequestId ) ; - } - } - return sts ; - } - - /*! - Send sendcount datas from sendbuf[offset] with type sendtype to target of IntraCommunicator - Receive recvcount datas to recvbuf[offset] with type recvtype from target of IntraCommunicator - (Internal Protected method) - - Returns the request identifier SendRequestId - Returns the request identifier RecvRequestId - - */ - int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , int sendoffset , - MPI_Datatype sendtype , - void* recvbuf, int recvcount , int recvoffset , - MPI_Datatype recvtype , int target , - int &SendRequestId , int &RecvRequestId ) - { - int sts ; - if ( _asynchronous ) - { - if ( sendtype == MPI_INT ) - { - if ( recvtype == MPI_INT ) - { - sts = _MPI_access->ISendRecv( &((int *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((int *) recvbuf)[recvoffset] , recvcount , - recvtype , target , RecvRequestId ) ; - } - else - { - sts = _MPI_access->ISendRecv( &((int *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((double *) recvbuf)[recvoffset] , - recvcount , recvtype , target , RecvRequestId ) ; - } - } - else - { - if ( recvtype == MPI_INT ) - { - sts = _MPI_access->ISendRecv( &((double *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((int *) recvbuf)[recvoffset] , - recvcount , recvtype , target , RecvRequestId ) ; - } - else - { - sts = _MPI_access->ISendRecv( &((double *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((double *) recvbuf)[recvoffset] , - recvcount , recvtype , target , RecvRequestId ) ; - } - } - } - else - { - if ( sendtype == MPI_INT ) - { - if ( recvtype == MPI_INT ) - { - sts = _MPI_access->sendRecv( &((int *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((int *) recvbuf)[recvoffset] , recvcount , - recvtype , target , RecvRequestId ) ; - } - else - { - sts = _MPI_access->sendRecv( &((int *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((double *) recvbuf)[recvoffset] , - recvcount , recvtype , target , RecvRequestId ) ; - } - } - else - { - if ( recvtype == MPI_INT ) - { - sts = _MPI_access->sendRecv( &((double *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((int *) recvbuf)[recvoffset] , - recvcount , recvtype , target , RecvRequestId ) ; - } - else - { - sts = _MPI_access->sendRecv( &((double *) sendbuf)[sendoffset] , sendcount , - sendtype , target , SendRequestId , - &((double *) recvbuf)[recvoffset] , - recvcount , recvtype , target , RecvRequestId ) ; - } - } - } - return sts ; - } - - /*! - Send sendcount datas from sendbuf[offset] with type sendtype to all targets of IntraCommunicator - Receive recvcount datas to recvbuf[offset] with type recvtype from all targets of IntraCommunicator - - */ - int MPIAccessDEC::allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype , - void* recvbuf, int recvcount, MPI_Datatype recvtype ) - { - if ( _time_interpolator ) - { - return allToAllTime( sendbuf, sendcount, sendtype , recvbuf, recvcount, recvtype ) ; - } - int sts ; - int target ; - int sendoffset = 0 ; - int recvoffset = 0 ; - int SendRequestId ; - int RecvRequestId ; - - //Free of SendBuffers - if ( _asynchronous ) - checkSent() ; - - //DoSend + DoRecv : SendRecv - SendBuffStruct * aSendDataStruct = NULL ; - if ( _asynchronous && sendbuf ) - { - aSendDataStruct = new SendBuffStruct ; - aSendDataStruct->SendBuffer = sendbuf ; - aSendDataStruct->Counter = 0 ; - aSendDataStruct->DataType = sendtype ; - } - for ( target = 0 ; target < _group_size ; target++ ) - { - sts = sendRecv( sendbuf , sendcount , sendoffset , sendtype , - recvbuf , recvcount , recvoffset , recvtype , - target , SendRequestId , RecvRequestId ) ; - if ( _asynchronous && sendbuf && sendcount ) - { - aSendDataStruct->Counter += 1 ; - (*_map_of_send_buffers)[ SendRequestId ] = aSendDataStruct ; - } - sendoffset += sendcount ; - recvoffset += recvcount ; - } - if ( !_asynchronous && sendbuf ) - { - if ( sendtype == MPI_INT ) - { - delete [] (int *) sendbuf ; - } - else - { - delete [] (double *) sendbuf ; - } - } - return sts ; - } - - /*! - Send sendcounts[target] datas from sendbuf[sdispls[target]] with type sendtype to all targets of IntraCommunicator - Receive recvcounts[target] datas to recvbuf[rdispls[target]] with type recvtype from all targets of IntraCommunicator - - */ - int MPIAccessDEC::allToAllv( void* sendbuf, int* sendcounts, int* sdispls, - MPI_Datatype sendtype , - void* recvbuf, int* recvcounts, int* rdispls, - MPI_Datatype recvtype ) - { - if ( _time_interpolator ) - { - return allToAllvTime( sendbuf, sendcounts, sdispls, sendtype , - recvbuf, recvcounts, rdispls, recvtype ) ; - } - int sts ; - int target ; - int SendRequestId ; - int RecvRequestId ; - - //Free of SendBuffers - if ( _asynchronous ) - { - checkSent() ; - } - - //DoSend + DoRecv : SendRecv - SendBuffStruct * aSendDataStruct = NULL ; - if ( _asynchronous && sendbuf ) - { - aSendDataStruct = new SendBuffStruct ; - aSendDataStruct->SendBuffer = sendbuf ; - aSendDataStruct->Counter = 0 ; - aSendDataStruct->DataType = sendtype ; - } - for ( target = 0 ; target < _group_size ; target++ ) - { - if ( sendcounts[target] || recvcounts[target] ) - { - sts = sendRecv( sendbuf , sendcounts[target] , sdispls[target] , sendtype , - recvbuf , recvcounts[target] , rdispls[target] , recvtype , - target , SendRequestId , RecvRequestId ) ; - if ( _asynchronous && sendbuf && sendcounts[target]) - { - aSendDataStruct->Counter += 1 ; - (*_map_of_send_buffers)[ SendRequestId ] = aSendDataStruct ; - } - } - } - if ( !_asynchronous && sendbuf ) - { - if ( sendtype == MPI_INT ) - { - delete [] (int *) sendbuf ; - } - else - { - delete [] (double *) sendbuf ; - } - } - return sts ; - } - - /* - MPIAccessDEC and the management of SendBuffers : - ================================================= - - . In the collective communications collectives we send only parts of - the same buffer to each "target". So in asynchronous mode it is - necessary that all parts are free before to delete/free the - buffer. - - . We assume that buffers are allocated with a new double[]. so a - delete [] is done. - - . The structure SendBuffStruct permit to keep the adress of the buffer - and to manage a reference counter of that buffer. It contains - also MPI_Datatype for the delete [] (double *) ... when the counter - is null. - - . The map _MapOfSendBuffers etablish the correspondance between each - RequestId given by a MPI_Access->ISend(...) and a SendBuffStruct - for each "target" of a part of the buffer. - - . All that concerns only asynchronous Send. In synchronous mode, - we delete senbuf just after the Send. - */ - - /* - MPIAccessDEC and the management of RecvBuffers : - ================================================= - - If there is no interpolation, no special action is done. - - With interpolation for each target : - ------------------------------------ - . We have _time_messages[target] which is a vector of TimesMessages. - We have 2 TimesMessages in our case with a linear interpolation. - They contain the previous time(t0)/deltatime and the last - time(t1)/deltatime. - - . We have _data_messages[target] which is a vector of DatasMessages. - We have 2 DatasMessages in our case with a linear interpolation. - They contain the previous datas at time(t0)/deltatime and at last - time(t1)/deltatime. - - . At time _t(t*) of current processus we do the interpolation of - the values of the 2 DatasMessages which are returned in the part of - recvbuf corresponding to the target with t0 < t* <= t1. - - . Because of the difference of "deltatimes" between processes, we - may have t0 < t1 < t* and there is an extrapolation. - - . The vectors _out_of_time, _DataMessagesRecvCount and _DataMessagesType - contain for each target true if t* > last t1, recvcount and - MPI_Datatype for the finalize of messages at the end. - */ - - /*! - Send a TimeMessage to all targets of IntraCommunicator - Receive the TimeMessages from targets of IntraCommunicator if necessary. - - Send sendcount datas from sendbuf[offset] with type sendtype to all targets of IntraCommunicator - Returns recvcount datas to recvbuf[offset] with type recvtype after an interpolation - with datas received from all targets of IntraCommunicator. - - */ - int MPIAccessDEC::allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype , - void* recvbuf, int recvcount , MPI_Datatype recvtype ) - { - int sts ; - int target ; - int sendoffset = 0 ; - int SendTimeRequestId ; - int SendDataRequestId ; - - if ( _time_interpolator == NULL ) - { - return MPI_ERR_OTHER ; - } - - //Free of SendBuffers - if ( _asynchronous ) - { - checkSent() ; - } - - //DoSend : Time + SendBuff - SendBuffStruct * aSendTimeStruct = NULL ; - SendBuffStruct * aSendDataStruct = NULL ; - if ( sendbuf && sendcount ) - { - TimeMessage * aSendTimeMessage = new TimeMessage ; - if ( _asynchronous ) - { - aSendTimeStruct = new SendBuffStruct ; - aSendTimeStruct->SendBuffer = aSendTimeMessage ; - aSendTimeStruct->Counter = 0 ; - aSendTimeStruct->DataType = _MPI_access->timeType() ; - aSendDataStruct = new SendBuffStruct ; - aSendDataStruct->SendBuffer = sendbuf ; - aSendDataStruct->Counter = 0 ; - aSendDataStruct->DataType = sendtype ; - } - aSendTimeMessage->time = _t ; - aSendTimeMessage->deltatime = _dt ; - for ( target = 0 ; target < _group_size ; target++ ) - { - sts = send( aSendTimeMessage , 1 , 0 , _MPI_access->timeType() , target , - SendTimeRequestId ) ; - sts = send( sendbuf , sendcount , sendoffset , sendtype , target , SendDataRequestId ) ; - if ( _asynchronous ) - { - aSendTimeStruct->Counter += 1 ; - (*_map_of_send_buffers)[ SendTimeRequestId ] = aSendTimeStruct ; - aSendDataStruct->Counter += 1 ; - (*_map_of_send_buffers)[ SendDataRequestId ] = aSendDataStruct ; - } - sendoffset += sendcount ; - } - if ( !_asynchronous ) - { - delete aSendTimeMessage ; - if ( sendtype == MPI_INT ) - { - delete [] (int *) sendbuf ; - } - else - { - delete [] (double *) sendbuf ; - } - } - } - - //CheckTime + DoRecv + DoInterp - if ( recvbuf && recvcount ) - { - for ( target = 0 ; target < _group_size ; target++ ) - { - int recvsize = recvcount*_MPI_access->extent( recvtype ) ; - checkTime( recvcount , recvtype , target , false ) ; - //=========================================================================== - //TODO : it is assumed actually that we have only 1 timestep before and after - //=========================================================================== - if ( _time_interpolator && (*_time_messages)[target][0].time != -1 ) - { - if ( (*_out_of_time)[target] ) - { - cout << " =====================================================" << endl - << "Recv" << _my_rank << " <-- target " << target << " t0 " - << (*_time_messages)[target][0].time << " < t1 " - << (*_time_messages)[target][1].time << " < t* " << _t << endl - << " =====================================================" << endl ; - } - if ( recvtype == MPI_INT ) - { - _time_interpolator->doInterp( (*_time_messages)[target][0].time, - (*_time_messages)[target][1].time, _t, recvcount , - _n_step_before, _n_step_after, - (int **) &(*_data_messages)[target][0], - (int **) &(*_data_messages)[target][1], - &((int *)recvbuf)[target*recvcount] ) ; - } - else - { - _time_interpolator->doInterp( (*_time_messages)[target][0].time, - (*_time_messages)[target][1].time, _t, recvcount , - _n_step_before, _n_step_after, - (double **) &(*_data_messages)[target][0], - (double **) &(*_data_messages)[target][1], - &((double *)recvbuf)[target*recvcount] ) ; - } - } - else - { - char * buffdest = (char *) recvbuf ; - char * buffsrc = (char *) (*_data_messages)[target][1] ; - memcpy( &buffdest[target*recvsize] , buffsrc , recvsize ) ; - } - } - } - - return sts ; - } - - int MPIAccessDEC::allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls, - MPI_Datatype sendtype , - void* recvbuf, int* recvcounts, int* rdispls, - MPI_Datatype recvtype ) - { - int sts ; - int target ; - int SendTimeRequestId ; - int SendDataRequestId ; - - if ( _time_interpolator == NULL ) - { - return MPI_ERR_OTHER ; - } - - //Free of SendBuffers - if ( _asynchronous ) - { - checkSent() ; - } - - /* - . DoSend : - + We create a TimeMessage (look at that structure in MPI_Access). - + If we are in asynchronous mode, we create two structures SendBuffStruct - aSendTimeStruct and aSendDataStruct that we fill. - + We fill the structure aSendTimeMessage with time/deltatime of - the current process. "deltatime" must be nul if it is the last step of - Time. - + After that for each "target", we Send the TimeMessage and the part - of sendbuf corresponding to that target. - + If we are in asynchronous mode, we increment the counter and we add - aSendTimeStruct and aSendDataStruct to _MapOfSendBuffers with the - identifiers SendTimeRequestId and SendDataRequestId returned by - MPI_Access->Send(...). - + And if we are in synchronous mode we delete the SendMessages. - */ - //DoSend : Time + SendBuff - SendBuffStruct * aSendTimeStruct = NULL ; - SendBuffStruct * aSendDataStruct = NULL ; - if ( sendbuf ) - { - TimeMessage * aSendTimeMessage = new TimeMessage ; - if ( _asynchronous ) - { - aSendTimeStruct = new SendBuffStruct ; - aSendTimeStruct->SendBuffer = aSendTimeMessage ; - aSendTimeStruct->Counter = 0 ; - aSendTimeStruct->DataType = _MPI_access->timeType() ; - aSendDataStruct = new SendBuffStruct ; - aSendDataStruct->SendBuffer = sendbuf ; - aSendDataStruct->Counter = 0 ; - aSendDataStruct->DataType = sendtype ; - } - aSendTimeMessage->time = _t ; - aSendTimeMessage->deltatime = _dt ; - for ( target = 0 ; target < _group_size ; target++ ) - { - if ( sendcounts[target] ) - { - sts = send( aSendTimeMessage , 1 , 0 , _MPI_access->timeType() , target , - SendTimeRequestId ) ; - sts = send( sendbuf , sendcounts[target] , sdispls[target] , sendtype , target , - SendDataRequestId ) ; - if ( _asynchronous ) - { - aSendTimeStruct->Counter += 1 ; - (*_map_of_send_buffers)[ SendTimeRequestId ] = aSendTimeStruct ; - aSendDataStruct->Counter += 1 ; - (*_map_of_send_buffers)[ SendDataRequestId ] = aSendDataStruct ; - } - } - } - if ( !_asynchronous ) - { - delete aSendTimeMessage ; - if ( sendtype == MPI_INT ) - { - delete [] (int *) sendbuf ; - } - else - { - delete [] (double *) sendbuf ; - } - } - } - - /* - . CheckTime + DoRecv + DoInterp - + For each target we call CheckTime - + If there is a TimeInterpolator and if the TimeMessage of the target - is not the first, we call the interpolator which return its - results in the part of the recv buffer corresponding to the "target". - + If not, there is a copy of received datas for that first step of time - in the part of the recv buffer corresponding to the "target". - */ - //CheckTime + DoRecv + DoInterp - if ( recvbuf ) - { - for ( target = 0 ; target < _group_size ; target++ ) - { - if ( recvcounts[target] ) - { - int recvsize = recvcounts[target]*_MPI_access->extent( recvtype ) ; - checkTime( recvcounts[target] , recvtype , target , false ) ; - //=========================================================================== - //TODO : it is assumed actually that we have only 1 timestep before nad after - //=========================================================================== - if ( _time_interpolator && (*_time_messages)[target][0].time != -1 ) - { - if ( (*_out_of_time)[target] ) - { - cout << " =====================================================" << endl - << "Recv" << _my_rank << " <-- target " << target << " t0 " - << (*_time_messages)[target][0].time << " < t1 " - << (*_time_messages)[target][1].time << " < t* " << _t << endl - << " =====================================================" << endl ; - } - if ( recvtype == MPI_INT ) - { - _time_interpolator->doInterp( (*_time_messages)[target][0].time, - (*_time_messages)[target][1].time, _t, - recvcounts[target] , _n_step_before, _n_step_after, - (int **) &(*_data_messages)[target][0], - (int **) &(*_data_messages)[target][1], - &((int *)recvbuf)[rdispls[target]] ) ; - } - else - { - _time_interpolator->doInterp( (*_time_messages)[target][0].time, - (*_time_messages)[target][1].time, _t, - recvcounts[target] , _n_step_before, _n_step_after, - (double **) &(*_data_messages)[target][0], - (double **) &(*_data_messages)[target][1], - &((double *)recvbuf)[rdispls[target]] ) ; - } - } - else - { - char * buffdest = (char *) recvbuf ; - char * buffsrc = (char *) (*_data_messages)[target][1] ; - memcpy( &buffdest[rdispls[target]*_MPI_access->extent( recvtype )] , buffsrc , - recvsize ) ; - } - } - } - } - - return sts ; - } - - /* - . CheckTime(recvcount , recvtype , target , UntilEnd) - + At the beginning, we read the first TimeMessage in - &(*_TimeMessages)[target][1] and the first DataMessage - in the allocated buffer (*_DataMessages)[target][1]. - + deltatime of TimesMessages must be nul if it is the last one. - + While : _t(t*) is the current time of the processus. - "while _t(t*) is greater than the time of the "target" - (*_TimeMessages)[target][1].time and - (*_TimeMessages)[target][1].deltatime is not nul", - So at the end of the while we have : - _t(t*) <= (*_TimeMessages)[target][1].time with - _t(t*) > (*_TimeMessages)[target][0].time - or we have the last TimeMessage of the "target". - + If it is the finalization of the recv of TimeMessages and - DataMessages (UntilEnd value is true), we execute the while - until (*_TimeMessages)[target][1].deltatime is nul. - + In the while : - We copy the last TimeMessage in the previoud TimeMessage and - we read a new TimeMessage - We delete the previous DataMessage. - We copy the last DataMessage pointer in the previous one. - We allocate a new last DataMessage buffer - (*_DataMessages)[target][1] and we read the corresponding - datas in that buffe. - + If the current time of the current process is greater than the - last time (*_TimeMessages)[target][1].time du target, we give - a true value to (*_OutOfTime)[target]. - (*_TimeMessages)[target][1].deltatime is nul. - */ - int MPIAccessDEC::checkTime( int recvcount , MPI_Datatype recvtype , int target , - bool UntilEnd ) - { - int sts = MPI_SUCCESS ; - int RecvTimeRequestId ; - int RecvDataRequestId ; - //Pour l'instant on cherche _time_messages[target][0] < _t <= _time_messages[target][1] - //=========================================================================== - //TODO : it is assumed actually that we have only 1 timestep before and after - // instead of _n_step_before and _n_step_after ... - //=========================================================================== - (*_data_messages_recv_count)[target] = recvcount ; - (*_data_messages_type)[target] = recvtype ; - if ( (*_time_messages)[target][1].time == -1 ) - { - (*_time_messages)[target][0] = (*_time_messages)[target][1] ; - sts = recv( &(*_time_messages)[target][1] , 1 , _MPI_access->timeType() , - target , RecvTimeRequestId ) ; - (*_data_messages)[target][0] = (*_data_messages)[target][1] ; - if ( recvtype == MPI_INT ) - { - (*_data_messages)[target][1] = new int[recvcount] ; - } - else - { - (*_data_messages)[target][1] = new double[recvcount] ; - } - sts = recv( (*_data_messages)[target][1] , recvcount , recvtype , target , - RecvDataRequestId ) ; - } - else - { - while ( ( _t > (*_time_messages)[target][1].time || UntilEnd ) && - (*_time_messages)[target][1].deltatime != 0 ) - { - (*_time_messages)[target][0] = (*_time_messages)[target][1] ; - sts = recv( &(*_time_messages)[target][1] , 1 , _MPI_access->timeType() , - target , RecvTimeRequestId ) ; - if ( UntilEnd ) - { - cout << "CheckTime" << _my_rank << " TimeMessage target " << target - << " RecvTimeRequestId " << RecvTimeRequestId << " MPITag " - << _MPI_access->recvMPITag(target) << endl ; - } - if ( recvtype == MPI_INT ) - { - delete [] (int *) (*_data_messages)[target][0] ; - } - else - { - delete [] (double *) (*_data_messages)[target][0] ; - } - (*_data_messages)[target][0] = (*_data_messages)[target][1] ; - if ( recvtype == MPI_INT ) - { - (*_data_messages)[target][1] = new int[recvcount] ; - } - else - { - (*_data_messages)[target][1] = new double[recvcount] ; - } - sts = recv( (*_data_messages)[target][1] , recvcount , recvtype , target , - RecvDataRequestId ) ; - if ( UntilEnd ) - { - cout << "CheckTime" << _my_rank << " DataMessage target " << target - << " RecvDataRequestId " << RecvDataRequestId << " MPITag " - << _MPI_access->recvMPITag(target) << endl ; - } - } - - if ( _t > (*_time_messages)[target][0].time && - _t <= (*_time_messages)[target][1].time ) - { - } - else - { - (*_out_of_time)[target] = true ; - } - } - return sts ; - } - - /* - . CheckSent() : - + call SendRequestIds of MPI_Access in order to get all - RequestIds of SendMessages of all "targets". - + For each RequestId, CheckSent call "Test" of MPI_Access in order - to know if the buffer is "free" (flag = true). If it is the - FinalCheckSent (WithWait = true), we call Wait instead of Test. - + If the buffer is "free", the counter of the structure SendBuffStruct - (from _MapOfSendBuffers) is decremented. - + If that counter is nul we delete the TimeMessage or the - SendBuffer according to the DataType. - + And we delete the structure SendBuffStruct before the suppression - (erase) of that item of _MapOfSendBuffers - */ - int MPIAccessDEC::checkSent(bool WithWait) - { - int sts = MPI_SUCCESS ; - int flag = WithWait ; - int size = _MPI_access->sendRequestIdsSize() ; - int * ArrayOfSendRequests = new int[ size ] ; - int nSendRequest = _MPI_access->sendRequestIds( size , ArrayOfSendRequests ) ; - bool SendTrace = false ; - int i ; - for ( i = 0 ; i < nSendRequest ; i++ ) - { - if ( WithWait ) - { - if (SendTrace) - { - cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest - << " SendRequestId " << ArrayOfSendRequests[i] << " MPITarget " - << _MPI_access->MPITarget(ArrayOfSendRequests[i]) << " MPITag " - << _MPI_access->MPITag(ArrayOfSendRequests[i]) << " Wait :" << endl ; - } - sts = _MPI_access->wait( ArrayOfSendRequests[i] ) ; - } - else - { - sts = _MPI_access->test( ArrayOfSendRequests[i] , flag ) ; - } - if ( flag ) - { - _MPI_access->deleteRequest( ArrayOfSendRequests[i] ) ; - if ( SendTrace ) - { - cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest - << " SendRequestId " << ArrayOfSendRequests[i] - << " flag " << flag - << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter - << " DataType " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType - << endl ; - } - (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter -= 1 ; - if ( SendTrace ) - { - if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == - _MPI_access->timeType() ) - { - cout << "CheckTimeSent" << _my_rank << " Request " ; - } - else - { - cout << "CheckDataSent" << _my_rank << " Request " ; - } - cout << ArrayOfSendRequests[i] - << " _map_of_send_buffers->SendBuffer " - << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer - << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter - << endl ; - } - if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter == 0 ) - { - if ( SendTrace ) - { - cout << "CheckSent" << _my_rank << " SendRequestId " << ArrayOfSendRequests[i] - << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter - << " flag " << flag << " SendBuffer " - << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer - << " deleted. Erase in _map_of_send_buffers :" << endl ; - } - if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == - _MPI_access->timeType() ) - { - delete (TimeMessage * ) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ; - } - else - { - if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == MPI_INT ) - { - delete [] (int *) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ; - } - else - { - delete [] (double *) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ; - } - } - delete (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ] ; - } - if ( SendTrace ) - { - cout << "CheckSent" << _my_rank << " Erase in _map_of_send_buffers SendRequestId " - << ArrayOfSendRequests[i] << endl ; - } - (*_map_of_send_buffers).erase( ArrayOfSendRequests[i] ) ; - } - else if ( SendTrace ) - { - cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest - << " SendRequestId " << ArrayOfSendRequests[i] - << " flag " << flag - << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter - << " DataType " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType - << endl ; - } - } - if ( SendTrace ) - { - _MPI_access->check() ; - } - delete [] ArrayOfSendRequests ; - return sts ; - } - - int MPIAccessDEC::checkFinalRecv() - { - int sts = MPI_SUCCESS ; - if ( _time_interpolator ) - { - int target ; - for ( target = 0 ; target < _group_size ; target++ ) - { - if ( (*_data_messages)[target][0] != NULL ) - { - sts = checkTime( (*_data_messages_recv_count)[target] , (*_data_messages_type)[target] , - target , true ) ; - if ( (*_data_messages_type)[target] == MPI_INT ) - { - delete [] (int *) (*_data_messages)[target][0] ; - } - else - { - delete [] (double *) (*_data_messages)[target][0] ; - } - (*_data_messages)[target][0] = NULL ; - if ( (*_data_messages)[target][1] != NULL ) - { - if ( (*_data_messages_type)[target] == MPI_INT ) - { - delete [] (int *) (*_data_messages)[target][1] ; - } - else - { - delete [] (double *) (*_data_messages)[target][1] ; - } - (*_data_messages)[target][1] = NULL ; - } - } - } - } - return sts ; - } - - ostream & operator<< (ostream & f ,const TimeInterpolationMethod & interpolationmethod ) - { - switch (interpolationmethod) - { - case WithoutTimeInterp : - f << " WithoutTimeInterpolation "; - break; - case LinearTimeInterp : - f << " LinearTimeInterpolation "; - break; - default : - f << " UnknownTimeInterpolation "; - break; - } - - return f; - } -} diff --git a/medtool/src/ParaMEDMEM/MPIAccessDEC.hxx b/medtool/src/ParaMEDMEM/MPIAccessDEC.hxx deleted file mode 100644 index aba86958f..000000000 --- a/medtool/src/ParaMEDMEM/MPIAccessDEC.hxx +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MPIACCESSDEC_HXX__ -#define __MPIACCESSDEC_HXX__ - -#include "MPIAccess.hxx" -#include "DEC.hxx" -#include "LinearTimeInterpolator.hxx" - -#include <map> -#include <iostream> - -namespace ParaMEDMEM -{ - /* - * Internal class, not part of the public API. - * - * Another gateway to the MPI library? - */ - class MPIAccessDEC - { - public: - MPIAccessDEC( const ProcessorGroup& local_group, const ProcessorGroup& distant_group, - bool Asynchronous = true ); - virtual ~MPIAccessDEC(); - MPIAccess * getMPIAccess() { return _MPI_access; } - const MPI_Comm* getComm() { return _MPI_union_group->getComm(); } - void asynchronous( bool Asynchronous = true ) { _asynchronous = Asynchronous; } - void setTimeInterpolator( TimeInterpolationMethod anInterp , double InterpPrecision=0 , - int n_step_before=1, int nStepAfter=1 ); - - void setTime( double t ) { _t = t; _dt = -1; } - void setTime( double t , double dt ) { _t = t; _dt = dt; } - bool outOfTime( int target ) { return (*_out_of_time)[target]; } - - int send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target ); - int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ); - int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target , - int &RecvRequestId , bool Asynchronous=false ); - int sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype , - void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ); - - int allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype , - void* recvbuf, int recvcount, MPI_Datatype recvtype ); - int allToAllv( void* sendbuf, int* sendcounts, int* sdispls, MPI_Datatype sendtype , - void* recvbuf, int* recvcounts, int* rdispls, MPI_Datatype recvtype ); - - int allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype , - void* recvbuf, int recvcount , MPI_Datatype recvtype ); - int allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls, - MPI_Datatype sendtype , - void* recvbuf, int* recvcounts, int* rdispls, - MPI_Datatype recvtype ); - int checkTime( int recvcount , MPI_Datatype recvtype , int target , bool UntilEnd ); - int checkSent(bool WithWait=false); - int checkFinalSent() { return checkSent( true ); } - int checkFinalRecv(); - protected: - int send( void* sendbuf, int sendcount , int sendoffset , MPI_Datatype sendtype , - int target, int &SendRequestId ); - int recv( void* recvbuf, int recvcount , int recvoffset , MPI_Datatype recvtype , - int target, int &RecvRequestId ); - int sendRecv( void* sendbuf, int sendcount , int sendoffset , - MPI_Datatype sendtype , - void* recvbuf, int recvcount , int recvoffset , - MPI_Datatype recvtype , int target , - int &SendRequestId ,int &RecvRequestId ); - private : - bool _asynchronous; - MPIProcessorGroup* _MPI_union_group; - - TimeInterpolator* _time_interpolator; - int _n_step_before; - int _n_step_after; - - int _my_rank; - int _group_size; - MPIAccess* _MPI_access; - - // Current time and deltatime of current process - double _t; - double _dt; - - // TimeMessages from each target _TimeMessages[target][Step] : TimeMessage - std::vector< std::vector< TimeMessage > > *_time_messages; - // Corresponding DataMessages from each target _DataMessages[target][~TimeStep] - std::vector< bool >* _out_of_time; - std::vector< int >* _data_messages_recv_count; - std::vector< MPI_Datatype >* _data_messages_type; - std::vector< std::vector< void * > >* _data_messages; - - typedef struct - { - void * SendBuffer; - int Counter; - MPI_Datatype DataType; } - SendBuffStruct; - std::map< int , SendBuffStruct * > *_map_of_send_buffers; - }; - - inline int MPIAccessDEC::send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target ) - { - int SendRequestId; - int sts; - if ( _asynchronous ) - { - sts = _MPI_access->ISend( sendbuf , sendcount , sendtype , target , - SendRequestId ); - } - else - { - sts = _MPI_access->send( sendbuf , sendcount , sendtype , target , - SendRequestId ); - if ( sts == MPI_SUCCESS ) - free( sendbuf ); - } - return sts; - } - - inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ) - { - int RecvRequestId; - int sts; - if ( _asynchronous ) - sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target , RecvRequestId ); - else - sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target , RecvRequestId ); - return sts; - } - - inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , - int target , int &RecvRequestId , bool Asynchronous ) - { - int sts; - if ( Asynchronous ) - sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target , - RecvRequestId ); - else - sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target , - RecvRequestId ); - return sts; - } - - inline int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype , - void* recvbuf, int recvcount , MPI_Datatype recvtype , - int target ) - { - int SendRequestId; - int RecvRequestId; - int sts; - if ( _asynchronous ) - sts = _MPI_access->ISendRecv( sendbuf , sendcount , sendtype , target , - SendRequestId , - recvbuf , recvcount , recvtype , target , - RecvRequestId ); - else - sts = _MPI_access->sendRecv( sendbuf , sendcount , sendtype , target , - SendRequestId , - recvbuf , recvcount , recvtype , target , - RecvRequestId ); - return sts; - } - - std::ostream & operator<< (std::ostream &,const TimeInterpolationMethod &); -} - -#endif diff --git a/medtool/src/ParaMEDMEM/MPIProcessorGroup.cxx b/medtool/src/ParaMEDMEM/MPIProcessorGroup.cxx deleted file mode 100644 index 3bf01b69d..000000000 --- a/medtool/src/ParaMEDMEM/MPIProcessorGroup.cxx +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "CommInterface.hxx" -#include "InterpolationUtils.hxx" - -#include <iostream> -#include <set> -#include <algorithm> -#include "mpi.h" - -using namespace std; - - -namespace ParaMEDMEM -{ - /*! - \anchor MPIProcessorGroup-det - \class MPIProcessorGroup - - The MPIProcessorGroup class represents a set of distinct "processors" (computation nodes) - in a MPI code. It is used to define the MPI topology of code couplings. - - Groups can be set up in various ways, the most common being - the use of the \c MPIProcessorGroup(Comminterface, int pfirst, int plast) - constructor. - - The following code excerpt creates two processor groups on respectively 3 and 2 processors. - \verbatim - int main() - { - MPI_Init(&argc,&argv); - CommInterface comm_interface; - MPIProcessorGroup codeA_group(comm_interface, 0, 2); // groups processors 0, 1 and 2 - MPIProcessorGroup codeB_group(comm_interface, 3, 4); // groups processors 3 and 4 - - ... - } - \endverbatim - */ - - - /*! - * Creates a processor group that is based on all the - processors of MPI_COMM_WORLD .This routine must be called by all processors in MPI_COMM_WORLD. - \param interface CommInterface object giving access to the MPI - communication layer - */ - MPIProcessorGroup::MPIProcessorGroup(const CommInterface& interface): - ProcessorGroup(interface),_world_comm(MPI_COMM_WORLD) - { - _comm=_world_comm; - _comm_interface.commGroup(_world_comm, &_group); - int size; - _comm_interface.commSize(_world_comm,&size); - for (int i=0; i<size; i++) - _proc_ids.insert(i); - - } - - /*! Creates a processor group that is based on the processors included in \a proc_ids. - This routine must be called by all processors in MPI_COMM_WORLD. - - \param interface CommInterface object giving access to the MPI - communication layer - \param proc_ids set of ids that are to be integrated in the group. The ids number are - to be understood in terms of MPI_COMM_WORLD ranks. - */ - - MPIProcessorGroup::MPIProcessorGroup(const CommInterface& interface, set<int> proc_ids, const MPI_Comm& world_comm): - ProcessorGroup(interface, proc_ids), _world_comm(world_comm) - { - updateMPISpecificAttributes(); - } - - - void MPIProcessorGroup::updateMPISpecificAttributes() - { - //Creation of a communicator - MPI_Group group_world; - - int size_world; - _comm_interface.commSize(_world_comm,&size_world); - int rank_world; - _comm_interface.commRank(_world_comm,&rank_world); - _comm_interface.commGroup(_world_comm, &group_world); - - int* ranks=new int[_proc_ids.size()]; - - // copying proc_ids in ranks - copy<set<int>::const_iterator,int*> (_proc_ids.begin(), _proc_ids.end(), ranks); - for (int i=0; i< (int)_proc_ids.size();i++) - if (ranks[i]>size_world-1) - { - delete[] ranks; - _comm_interface.groupFree(&group_world); // MPI_Group is a C structure and won't get de-allocated automatically? - throw INTERP_KERNEL::Exception("invalid rank in set<int> argument of MPIProcessorGroup constructor"); - } - - _comm_interface.groupIncl(group_world, _proc_ids.size(), ranks, &_group); - - _comm_interface.commCreate(_world_comm, _group, &_comm); - - // clean-up - delete[] ranks; - _comm_interface.groupFree(&group_world); // MPI_Group is a C structure and won't get de-allocated automatically? - } - - /*! Creates a processor group that is based on the processors between \a pstart and \a pend. - This routine must be called by all processors in MPI_COMM_WORLD. - - \param comm_interface CommInterface object giving access to the MPI - communication layer - \param pstart id in MPI_COMM_WORLD of the first processor in the group - \param pend id in MPI_COMM_WORLD of the last processor in the group - */ - MPIProcessorGroup::MPIProcessorGroup (const CommInterface& comm_interface, int pstart, int pend, const MPI_Comm& world_comm): ProcessorGroup(comm_interface,pstart,pend),_world_comm(world_comm) - { - //Creation of a communicator - MPI_Group group_world; - - int size_world; - _comm_interface.commSize(_world_comm,&size_world); - int rank_world; - _comm_interface.commRank(_world_comm,&rank_world); - _comm_interface.commGroup(_world_comm, &group_world); - - if (pend>size_world-1 || pend <pstart || pstart<0) - { - _comm_interface.groupFree(&group_world); - throw INTERP_KERNEL::Exception("invalid argument in MPIProcessorGroup constructor (comm,pfirst,plast)"); - } - int nprocs=pend-pstart+1; - int* ranks=new int[nprocs]; - for (int i=pstart; i<=pend;i++) - { - ranks[i-pstart]=i; - } - - _comm_interface.groupIncl(group_world, nprocs, ranks, &_group); - - _comm_interface.commCreate(_world_comm, _group, &_comm); - - // clean-up - delete[] ranks; - _comm_interface.groupFree(&group_world); // MPI_Group is a C structured and won't get de-allocated automatically? - } - - MPIProcessorGroup::MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids) : - ProcessorGroup(proc_group.getCommInterface()), - _world_comm(MPI_COMM_WORLD), _group(MPI_GROUP_NULL), _comm(MPI_COMM_NULL) - { - cout << "MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids)" <<endl; - cout << "Not implemented yet !"<<endl; - exit(1); - } - - MPIProcessorGroup::MPIProcessorGroup(const MPIProcessorGroup& other): - ProcessorGroup(other),_world_comm(other._world_comm) - { - updateMPISpecificAttributes(); - } - - MPIProcessorGroup::~MPIProcessorGroup() - { - _comm_interface.groupFree(&_group); - if (_comm!=_world_comm && _comm !=MPI_COMM_NULL) - _comm_interface.commFree(&_comm); - - } - - /*! Translation of the rank id between two processor groups. This method translates rank \a rank - on the current processor group to the rank on group pointed by \a group. - \param group group from which the rank is expected - \param rank rank on group \a group of the processor which is to be translated - \return rank on local group - */ - int MPIProcessorGroup::translateRank(const ProcessorGroup* group, int rank) const - { - const MPIProcessorGroup* targetgroup=dynamic_cast<const MPIProcessorGroup*>(group); - int local_rank; - MPI_Group_translate_ranks(targetgroup->_group, 1, &rank, _group, &local_rank); - return local_rank; - } - - /*!Creates a processor group that is the complement of the current group - inside MPI_COMM_WORLD - \return pointer to the new ProcessorGroup structure. - */ - ProcessorGroup* MPIProcessorGroup::createComplementProcGroup() const - { - set <int> procs; - int world_size=_comm_interface.worldSize(); - for (int i=0; i<world_size; i++) - procs.insert(i); - for (set<int>::const_iterator iter=_proc_ids.begin(); iter!= _proc_ids.end(); iter++) - procs.erase(*iter); - - return new MPIProcessorGroup(_comm_interface, procs, _world_comm); - - } - - ProcessorGroup *MPIProcessorGroup::deepCpy() const - { - return new MPIProcessorGroup(*this); - } - - /*!Adding processors of group \a group to local group. - \param group group that is to be fused with current group - \return new group formed by the fusion of local group and \a group. - */ - ProcessorGroup* MPIProcessorGroup::fuse (const ProcessorGroup& group) const - { - set <int> procs = _proc_ids; - const set<int>& distant_proc_ids = group.getProcIDs(); - for (set<int>::const_iterator iter=distant_proc_ids.begin(); iter!=distant_proc_ids.end(); iter++) - { - procs.insert(*iter); - } - return new MPIProcessorGroup(_comm_interface, procs, _world_comm); - } - - int MPIProcessorGroup::myRank() const - { - int rank; - MPI_Comm_rank(_comm,&rank); - return rank; - } - - ProcessorGroup* MPIProcessorGroup::createProcGroup() const - { - set <int> procs; - for (set<int>::const_iterator iter=_proc_ids.begin(); iter!= _proc_ids.end(); iter++) - procs.insert(*iter); - - return new MPIProcessorGroup(_comm_interface, procs, _world_comm); - - } -} diff --git a/medtool/src/ParaMEDMEM/MPIProcessorGroup.hxx b/medtool/src/ParaMEDMEM/MPIProcessorGroup.hxx deleted file mode 100644 index 7c39ed26d..000000000 --- a/medtool/src/ParaMEDMEM/MPIProcessorGroup.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MPIPROCESSORGROUP_HXX__ -#define __MPIPROCESSORGROUP_HXX__ - -#include "ProcessorGroup.hxx" - -#include <set> -#include <mpi.h> - -namespace ParaMEDMEM -{ - class CommInterface; - - class MPIProcessorGroup : public ProcessorGroup - { - public: - MPIProcessorGroup(const CommInterface& interface); - MPIProcessorGroup(const CommInterface& interface, std::set<int> proc_ids, const MPI_Comm& world_comm=MPI_COMM_WORLD); - MPIProcessorGroup (const ProcessorGroup& proc_group, std::set<int> proc_ids); - MPIProcessorGroup(const CommInterface& interface,int pstart, int pend, const MPI_Comm& world_comm=MPI_COMM_WORLD); - MPIProcessorGroup(const MPIProcessorGroup& other); - virtual ~MPIProcessorGroup(); - virtual ProcessorGroup *deepCpy() const; - virtual ProcessorGroup* fuse (const ProcessorGroup&) const; - void intersect (ProcessorGroup&) { } - int myRank() const; - bool containsMyRank() const { int rank; MPI_Group_rank(_group, &rank); return (rank!=MPI_UNDEFINED); } - int translateRank(const ProcessorGroup* group, int rank) const; - const MPI_Comm* getComm() const { return &_comm; } - ProcessorGroup* createComplementProcGroup() const; - ProcessorGroup* createProcGroup() const; - MPI_Comm getWorldComm() { return _world_comm; } - private: - void updateMPISpecificAttributes(); - private: - const MPI_Comm _world_comm; // just an observer - current instance is not responsible for the management of this comm - MPI_Group _group; - MPI_Comm _comm; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/MxN_Mapping.cxx b/medtool/src/ParaMEDMEM/MxN_Mapping.cxx deleted file mode 100644 index a6a0bcba3..000000000 --- a/medtool/src/ParaMEDMEM/MxN_Mapping.cxx +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "MPIAccessDEC.hxx" -#include "MxN_Mapping.hxx" - -using namespace std; - -namespace ParaMEDMEM -{ - - MxN_Mapping::MxN_Mapping(const ProcessorGroup& source_group, const ProcessorGroup& target_group,const DECOptions& dec_options) - : DECOptions(dec_options), - _union_group(source_group.fuse(target_group)), - _nb_comps(0), _sending_ids(), _recv_ids() - { - _access_DEC = new MPIAccessDEC(source_group,target_group,getAsynchronous()); - _access_DEC->setTimeInterpolator(getTimeInterpolationMethod()); - _send_proc_offsets.resize(_union_group->size()+1,0); - _recv_proc_offsets.resize(_union_group->size()+1,0); - - } - - MxN_Mapping::~MxN_Mapping() - { - delete _union_group; - delete _access_DEC; - } - - - /*! - Method registering a new element for correspondence with a distant element - \param distant_proc proc rank of the distant processor (in terms of the union group) - \param distant_element id of the element on the distant processor - */ - void MxN_Mapping::addElementFromSource(int distant_proc, int distant_element) - { - _sending_ids.push_back(make_pair(distant_proc,distant_element)); - for (int i=distant_proc; i<_union_group->size(); i++) - _send_proc_offsets[i+1]++; - } - - void MxN_Mapping::initialize() - { - _sending_ids.clear(); - std::fill(_send_proc_offsets.begin(),_send_proc_offsets.end(),0); - } - - void MxN_Mapping::prepareSendRecv() - { - CommInterface comm_interface=_union_group->getCommInterface(); - // sending count pattern - int* nbsend=new int[_union_group->size()]; - int* nbrecv=new int[_union_group->size()]; - for (int i=0; i<_union_group->size(); i++) - { - nbsend[i]=_send_proc_offsets[i+1]-_send_proc_offsets[i]; - } - - MPIProcessorGroup* group = static_cast<MPIProcessorGroup*>(_union_group); - const MPI_Comm* comm=group->getComm(); - comm_interface.allToAll(nbsend, 1, MPI_INT, - nbrecv, 1, MPI_INT, - *comm); - - for (int i=0; i<_union_group->size(); i++) - { - for (int j=i+1;j<_union_group->size()+1; j++) - _recv_proc_offsets[j]+=nbrecv[i]; - - } - - delete[] nbsend; - delete[] nbrecv; - - _recv_ids.resize(_recv_proc_offsets[_union_group->size()]); - int* isendbuf=0; - int* irecvbuf=0; - if (_sending_ids.size()>0) - isendbuf = new int[_sending_ids.size()]; - if (_recv_ids.size()>0) - irecvbuf = new int[_recv_ids.size()]; - int* sendcounts = new int[_union_group->size()]; - int* senddispls=new int[_union_group->size()]; - int* recvcounts=new int[_union_group->size()]; - int* recvdispls=new int[_union_group->size()]; - for (int i=0; i< _union_group->size(); i++) - { - sendcounts[i]=_send_proc_offsets[i+1]-_send_proc_offsets[i]; - senddispls[i]=_send_proc_offsets[i]; - recvcounts[i]=_recv_proc_offsets[i+1]-_recv_proc_offsets[i]; - recvdispls[i]=_recv_proc_offsets[i]; - } - vector<int> offsets = _send_proc_offsets; - for (int i=0; i<(int)_sending_ids.size();i++) - { - int iproc = _sending_ids[i].first; - isendbuf[offsets[iproc]]=_sending_ids[i].second; - offsets[iproc]++; - } - comm_interface.allToAllV(isendbuf, sendcounts, senddispls, MPI_INT, - irecvbuf, recvcounts, recvdispls, MPI_INT, - *comm); - - for (int i=0; i< _recv_proc_offsets[_union_group->size()]; i++) - _recv_ids[i]=irecvbuf[i]; - - if (_sending_ids.size()>0) - delete[] isendbuf; - if (_recv_ids.size()>0) - delete[] irecvbuf; - delete[] sendcounts; - delete[]recvcounts; - delete[]senddispls; - delete[] recvdispls; - } - - /*! Exchanging field data between two groups of processes - * - * \param field MEDCoupling field containing the values to be sent - * - * The ids that were defined by addElementFromSource method - * are sent. - */ - void MxN_Mapping::sendRecv(double* sendfield, MEDCouplingFieldDouble& field) const - { - CommInterface comm_interface=_union_group->getCommInterface(); - const MPIProcessorGroup* group = static_cast<const MPIProcessorGroup*>(_union_group); - - int nbcomp=field.getArray()->getNumberOfComponents(); - double* sendbuf=0; - double* recvbuf=0; - if (_sending_ids.size() >0) - sendbuf = new double[_sending_ids.size()*nbcomp]; - if (_recv_ids.size()>0) - recvbuf = new double[_recv_ids.size()*nbcomp]; - - int* sendcounts = new int[_union_group->size()]; - int* senddispls=new int[_union_group->size()]; - int* recvcounts=new int[_union_group->size()]; - int* recvdispls=new int[_union_group->size()]; - - for (int i=0; i< _union_group->size(); i++) - { - sendcounts[i]=nbcomp*(_send_proc_offsets[i+1]-_send_proc_offsets[i]); - senddispls[i]=nbcomp*(_send_proc_offsets[i]); - recvcounts[i]=nbcomp*(_recv_proc_offsets[i+1]-_recv_proc_offsets[i]); - recvdispls[i]=nbcomp*(_recv_proc_offsets[i]); - } - //building the buffer of the elements to be sent - vector<int> offsets = _send_proc_offsets; - - for (int i=0; i<(int)_sending_ids.size();i++) - { - int iproc = _sending_ids[i].first; - for (int icomp=0; icomp<nbcomp; icomp++) - sendbuf[offsets[iproc]*nbcomp+icomp]=sendfield[i*nbcomp+icomp]; - offsets[iproc]++; - } - - //communication phase - switch (getAllToAllMethod()) - { - case Native: - { - const MPI_Comm* comm = group->getComm(); - comm_interface.allToAllV(sendbuf, sendcounts, senddispls, MPI_DOUBLE, - recvbuf, recvcounts, recvdispls, MPI_DOUBLE, - *comm); - } - break; - case PointToPoint: - _access_DEC->allToAllv(sendbuf, sendcounts, senddispls, MPI_DOUBLE, - recvbuf, recvcounts, recvdispls, MPI_DOUBLE); - break; - } - - //setting the received values in the field - DataArrayDouble *fieldArr=field.getArray(); - double* recvptr=recvbuf; - for (int i=0; i< _recv_proc_offsets[_union_group->size()]; i++) - { - for (int icomp=0; icomp<nbcomp; icomp++) - { - double temp = fieldArr->getIJ(_recv_ids[i],icomp); - fieldArr->setIJ(_recv_ids[i],icomp,temp+*recvptr); - recvptr++; - } - } - if (sendbuf!=0 && getAllToAllMethod()== Native) - delete[] sendbuf; - if (recvbuf !=0) - delete[] recvbuf; - delete[] sendcounts; - delete[] recvcounts; - delete[] senddispls; - delete[] recvdispls; - - } - - /*! Exchanging field data between two groups of processes - * - * \param field MEDCoupling field containing the values to be sent - * - * The ids that were defined by addElementFromSource method - * are sent. - */ - void MxN_Mapping::reverseSendRecv(double* recvfield, MEDCouplingFieldDouble& field) const - { - CommInterface comm_interface=_union_group->getCommInterface(); - const MPIProcessorGroup* group = static_cast<const MPIProcessorGroup*>(_union_group); - - int nbcomp=field.getArray()->getNumberOfComponents(); - double* sendbuf=0; - double* recvbuf=0; - if (_recv_ids.size() >0) - sendbuf = new double[_recv_ids.size()*nbcomp]; - if (_sending_ids.size()>0) - recvbuf = new double[_sending_ids.size()*nbcomp]; - - int* sendcounts = new int[_union_group->size()]; - int* senddispls=new int[_union_group->size()]; - int* recvcounts=new int[_union_group->size()]; - int* recvdispls=new int[_union_group->size()]; - - for (int i=0; i< _union_group->size(); i++) - { - sendcounts[i]=nbcomp*(_recv_proc_offsets[i+1]-_recv_proc_offsets[i]); - senddispls[i]=nbcomp*(_recv_proc_offsets[i]); - recvcounts[i]=nbcomp*(_send_proc_offsets[i+1]-_send_proc_offsets[i]); - recvdispls[i]=nbcomp*(_send_proc_offsets[i]); - } - //building the buffer of the elements to be sent - vector<int> offsets = _recv_proc_offsets; - DataArrayDouble *fieldArr=field.getArray(); - for (int iproc=0; iproc<_union_group->size();iproc++) - for (int i=_recv_proc_offsets[iproc]; i<_recv_proc_offsets[iproc+1]; i++) - { - for (int icomp=0; icomp<nbcomp; icomp++) - sendbuf[i*nbcomp+icomp]=fieldArr->getIJ(_recv_ids[i],icomp); - } - - //communication phase - switch (getAllToAllMethod()) - { - case Native: - { - const MPI_Comm* comm = group->getComm(); - comm_interface.allToAllV(sendbuf, sendcounts, senddispls, MPI_DOUBLE, - recvbuf, recvcounts, recvdispls, MPI_DOUBLE, - *comm); - } - break; - case PointToPoint: - _access_DEC->allToAllv(sendbuf, sendcounts, senddispls, MPI_DOUBLE, - recvbuf, recvcounts, recvdispls, MPI_DOUBLE); - break; - } - - //setting the received values in the field - double* recvptr=recvbuf; - for (int i=0; i< _send_proc_offsets[_union_group->size()]; i++) - { - for (int icomp=0; icomp<nbcomp; icomp++) - { - recvfield[i*nbcomp+icomp]=*recvptr; - recvptr++; - } - } - if (sendbuf!=0 && getAllToAllMethod() == Native) - delete[] sendbuf; - if (recvbuf!=0) - delete[] recvbuf; - delete[] sendcounts; - delete[] recvcounts; - delete[] senddispls; - delete[] recvdispls; - } - - ostream & operator<< (ostream & f ,const AllToAllMethod & alltoallmethod ) - { - switch (alltoallmethod) - { - case Native : - f << " Native "; - break; - case PointToPoint : - f << " PointToPoint "; - break; - default : - f << " UnknownAllToAllMethod "; - break; - } - return f; - } -} diff --git a/medtool/src/ParaMEDMEM/MxN_Mapping.hxx b/medtool/src/ParaMEDMEM/MxN_Mapping.hxx deleted file mode 100644 index cd613a8eb..000000000 --- a/medtool/src/ParaMEDMEM/MxN_Mapping.hxx +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MXN_MAPPING_HXX__ -#define __MXN_MAPPING_HXX__ - -#include "MEDCouplingFieldDouble.hxx" -#include "MPIAccessDEC.hxx" -#include "DECOptions.hxx" - -#include <vector> - -namespace ParaMEDMEM -{ - - class ProcessorGroup; - - /*! - * Internal class, not part of the public API. - * - * Used by InterpolationMatrix. This class manages the mapping between a given processor and part - * of the mesh (cell ids). - */ - class MxN_Mapping : public DECOptions - { - public: - MxN_Mapping(const ProcessorGroup& source_group, const ProcessorGroup& target_group, const DECOptions& dec_options); - virtual ~MxN_Mapping(); - void addElementFromSource(int distant_proc, int distant_elem); - void prepareSendRecv(); - void sendRecv(MEDCouplingFieldDouble& field); - void sendRecv(double* sendfield, MEDCouplingFieldDouble& field) const ; - void reverseSendRecv(double* recvfield, MEDCouplingFieldDouble& field) const ; - - // - const std::vector<std::pair<int,int> >& getSendingIds() const { return _sending_ids; } - const std::vector<int>& getSendProcsOffsets() const { return _send_proc_offsets; } - void initialize(); - - MPIAccessDEC* getAccessDEC(){ return _access_DEC; } - private : - ProcessorGroup* _union_group; - MPIAccessDEC * _access_DEC; - int _nb_comps; - std::vector<std::pair<int,int> > _sending_ids; - std::vector<int> _recv_ids; - std::vector<int> _send_proc_offsets; - std::vector<int> _recv_proc_offsets; - }; - - std::ostream & operator<< (std::ostream &,const AllToAllMethod &); - -} - -#endif diff --git a/medtool/src/ParaMEDMEM/NonCoincidentDEC.cxx b/medtool/src/ParaMEDMEM/NonCoincidentDEC.cxx deleted file mode 100644 index 95b9d6acd..000000000 --- a/medtool/src/ParaMEDMEM/NonCoincidentDEC.cxx +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <mpi.h> -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "MPIProcessorGroup.hxx" -#include "DEC.hxx" -#include "NonCoincidentDEC.hxx" - -extern "C" { -#include <fvm_parall.h> -#include <fvm_nodal.h> -#include <fvm_nodal_append.h> -#include <fvm_locator.h> -} - -namespace ParaMEDMEM -{ - - /*! - \anchor NonCoincidentDEC-det - \class NonCoincidentDEC - - \c NonCoincidentDEC enables non-conservative remapping of fields - between two parallel codes. - The computation is possible for 3D meshes and 2D meshes. - It is not available for 3D surfaces. - - The computation enables fast parallel localization, and is based on a point in element search, followed - by a field evaluation at the point location. Thus, it is typically - faster than the \ref InterpKernelDEC-det "InterpKernelDEC" which uses a - \ref InterpKerRemapGlobal "conservative remapping" (i.e. the same algorithms of volume - intersection as in the \ref remapper "sequential remapper") - It is particularly true for the initialisation phase (synchronize() method) - which has a significant computation cost in \ref InterpKernelDEC-det. - - In the present version, only fields lying on elements ("P0") are considered. - The value is estimated by locating the barycenter of the target - side cell in a source cell and sending the value of this source cell - as the value of the target cell. - - \image html NonCoincident_small.png "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. The triangle barycenters are computed and located in the quadrangles. In a P0-P0 interpolation, the value on the quadrangle is then applied to the triangles whose barycenter lies within." - - \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. The triangle barycenters are computed and located in the quadrangles. In a P0-P0 interpolation, the value on the quadrangle is then applied to the triangles whose barycenter lies within." - - A typical use of NonCoincidentDEC encompasses two distinct phases : - - A setup phase during which the intersection volumes are computed and the communication structures are setup. This corresponds to calling the NonCoincidentDEC::synchronize() method. - - A use phase during which the remappings are actually performed. This corresponds to the calls to sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous in the current version of the library so that recvData() and sendData() calls must be synchronized on code A and code B processor groups. - - The following code excerpt illutrates a typical use of the NonCoincidentDEC class. - - \code - ... - NonCoincidentDEC dec(groupA, groupB); - dec.attachLocalField(field); - dec.synchronize(); - if (groupA.containsMyRank()) - dec.recvData(); - else if (groupB.containsMyRank()) - dec.sendData(); - ... - \endcode - - Computing the field on the receiving side can be expressed in terms - of a matrix-vector product : \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t - \f$ the field on the target side and \f$ \phi_s \f$ the field on - the source side. - In the P0-P0 case, this matrix is a plain rectangular matrix with one - non-zero element per row (with value 1). For instance, in the above figure, the matrix is : - \f[ - - \begin{tabular}{|cccc|} - 1 & 0 & 0 & 0\\ - 0 & 0 & 1 & 0\\ - 1 & 0 & 0 & 0\\ - 0 & 0 & 1 & 0\\ - \end{tabular} - \f] - */ - - fvm_nodal_t* medmemMeshToFVMMesh(const MEDMEM::MESH* mesh) - { - // create an FVM structure from the paramesh structure - std::string meshName(mesh->getName());//this line avoid that mesh->getName() object killed before fvm_nodal_create read the const char *. - fvm_nodal_t * fvm_nodal = fvm_nodal_create(meshName.c_str(),mesh->getMeshDimension()); - - //loop on cell types - int nbtypes = mesh->getNumberOfTypes(MED_EN::MED_CELL); - const MED_EN::medGeometryElement* types = mesh->getTypes(MED_EN::MED_CELL); - for (int itype=0; itype<nbtypes; itype++) - { - fvm_element_t fvm_type; - switch (types[itype]) - { - case MED_EN::MED_TRIA3 : - fvm_type=FVM_FACE_TRIA; - break; - case MED_EN::MED_QUAD4 : - fvm_type=FVM_FACE_QUAD; - break; - case MED_EN::MED_TETRA4 : - fvm_type=FVM_CELL_TETRA; - break; - case MED_EN::MED_HEXA8 : - fvm_type=FVM_CELL_HEXA; - break; - default: - throw MEDEXCEPTION(" MED type conversion to fvm is not handled yet."); - break; - - } - - fvm_lnum_t nbelems = mesh->getNumberOfElements(MED_EN::MED_CELL, types[itype]); - fvm_lnum_t* conn = new fvm_lnum_t[nbelems*(types[itype]%100)]; - const int* mesh_conn =mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL, MED_EN::MED_CELL, types[itype]); - for (int i=0; i<nbelems*(types[itype]%100); i++) - conn[i]=mesh_conn[i]; - //swapping trias - if (types[itype]==MED_EN::MED_TRIA3) - { - for (int i=0; i<nbelems;i++) - { - int tmp=conn[3*i]; - conn[3*i]=mesh_conn[3*i+1]; - conn[3*i+1]=tmp; - } - } - //swapping tetras - if (types[itype]==MED_EN::MED_TETRA4) - { - for (int i=0; i<nbelems;i++) - { - int tmp=conn[4*i]; - conn[4*i]=mesh_conn[4*i+1]; - conn[4*i+1]=tmp; - } - } - fvm_nodal_append_by_transfer(fvm_nodal, nbelems, fvm_type,0,0,0,conn,0); - - int nbnodes= mesh->getNumberOfNodes(); - int spacedim=mesh->getSpaceDimension(); - fvm_coord_t* coords = new fvm_coord_t[nbnodes*spacedim]; - const double* mesh_coords=mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE); - for (int i=0; i<nbnodes*spacedim; i++) - coords[i]=mesh_coords[i]; - fvm_nodal_transfer_vertices(fvm_nodal,coords); - } - return fvm_nodal; - } - - fvm_nodal_t* medmemSupportToFVMMesh(const MEDMEM::SUPPORT* support) - { - - // create an FVM structure from the paramesh structure - std::string supportName(support->getName());//this line avoid that support->getName() object killed before fvm_nodal_create read the const char *. - fvm_nodal_t * fvm_nodal = fvm_nodal_create(supportName.c_str(),1); - - const MEDMEM::MESH* mesh= support->getMesh(); - - //loop on cell types - MED_EN::medEntityMesh entity = support->getEntity(); - - int nbtypes = support->getNumberOfTypes(); - const MED_EN::medGeometryElement* types = support->getTypes(); - int ioffset=0; - const int* type_offset = support->getNumberIndex(); - - //browsing through all types - for (int itype=0; itype<nbtypes; itype++) - { - fvm_element_t fvm_type; - switch (types[itype]) - { - case MED_EN::MED_TRIA3 : - fvm_type=FVM_FACE_TRIA; - break; - case MED_EN::MED_QUAD4 : - fvm_type=FVM_FACE_QUAD; - break; - case MED_EN::MED_TETRA4 : - fvm_type=FVM_CELL_TETRA; - break; - case MED_EN::MED_HEXA8 : - fvm_type=FVM_CELL_HEXA; - break; - default: - throw MEDEXCEPTION(" MED type conversion to fvm is not handled yet."); - break; - - } - fvm_lnum_t nbelems = support->getNumberOfElements(types[itype]); - - //for a partial support, defining the element numbers that are taken into - //account in the support - fvm_lnum_t* elem_numbers=0; - if (!support->isOnAllElements()) - { - elem_numbers = const_cast<fvm_lnum_t*> (support->getNumber(types[itype])); - - //creating work arrays to store list of elems for partial suports - if (itype>0) - { - fvm_lnum_t* temp = new int[nbelems]; - for (int i=0; i< nbelems; i++) - temp[i] = elem_numbers [i]-ioffset; - ioffset+=type_offset[itype]; - elem_numbers = temp; - } - } - //retrieving original mesh connectivity - fvm_lnum_t* conn = const_cast<fvm_lnum_t*> (mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,entity, types[itype])); - - // adding the elements to the FVM structure - fvm_nodal_append_by_transfer(fvm_nodal, nbelems, fvm_type,0,0,0,conn,elem_numbers); - - //cleaning work arrays (for partial supports) - if (!support->isOnAllElements() && itype>0) - delete[] elem_numbers; - - } - return fvm_nodal; - } - - NonCoincidentDEC::NonCoincidentDEC() - { - } - - /*! Constructor of a non coincident \ref para-dec "DEC" with - * a source group on which lies a field lying on a mesh and a - * target group on which lies a mesh. - * - * \param source_group ProcessorGroup on the source side - * \param target_group ProcessorGroup on the target side - */ - - NonCoincidentDEC::NonCoincidentDEC(ProcessorGroup& source_group, - ProcessorGroup& target_group) - :DEC(source_group, target_group) - {} - - NonCoincidentDEC::~NonCoincidentDEC() - { - } - - /*! Synchronization process. Calling this method - * synchronizes the topologies so that the target side - * gets the information which enable it to fetch the field value - * from the source side. - * A typical call is : - \verbatim - NonCoincidentDEC dec(source_group,target_group); - dec.attachLocalField(field); - dec.synchronize(); - \endverbatim - */ - void NonCoincidentDEC::synchronize() - { - - //initializing FVM parallel environment - const MPI_Comm* comm=dynamic_cast<const MPIProcessorGroup*> (_union_group)->getComm(); - fvm_parall_set_mpi_comm(*const_cast<MPI_Comm*> (comm)); - - - //setting up the communication DEC on both sides - - if (_source_group->containsMyRank()) - { - MEDMEM::MESH* mesh = _local_field->getField()->getSupport()->getMesh(); - fvm_nodal_t* source_nodal = ParaMEDMEM::medmemMeshToFVMMesh(mesh); - - int target_size = _target_group->size() ; - int start_rank= _source_group->size(); - const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*> (_union_group))->getComm(); - - _locator = fvm_locator_create(1e-6, - *comm, - target_size, - start_rank); - - fvm_locator_set_nodal(_locator, - source_nodal, - mesh->getSpaceDimension(), - 0, - NULL, - 0); - - - _nb_distant_points = fvm_locator_get_n_dist_points(_locator); - _distant_coords = fvm_locator_get_dist_coords(_locator); - _distant_locations = fvm_locator_get_dist_locations(_locator); - - } - if (_target_group->containsMyRank()) - { - MEDMEM::MESH* mesh = _local_field->getField()->getSupport()->getMesh(); - - fvm_nodal_t* target_nodal = ParaMEDMEM::medmemMeshToFVMMesh(mesh); - int source_size = _source_group->size(); - int start_rank= 0 ; - const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*> (_union_group))->getComm(); - - _locator = fvm_locator_create(1e-6, - *comm, - source_size, - start_rank); - int nbcells = mesh->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); - const MEDMEM::SUPPORT* support=_local_field->getField()->getSupport(); - MEDMEM::FIELD<double>* barycenter_coords = mesh->getBarycenter(support); - const double* coords = barycenter_coords->getValue(); - fvm_locator_set_nodal(_locator, - target_nodal, - mesh->getSpaceDimension(), - nbcells, - NULL, - coords); - delete barycenter_coords; - } - } - - - /*! This method is called on the target group in order to - * trigger the retrieveal of field data. It must - * be called synchronously with a sendData() call on - * the source group. - */ - void NonCoincidentDEC::recvData() - { - int nbelems = _local_field->getField()->getSupport()->getMesh()->getNumberOfElements(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - int nbcomp = _local_field->getField()->getNumberOfComponents(); - double* values = new double [nbelems*nbcomp]; - fvm_locator_exchange_point_var(_locator, - 0, - values, - 0, - sizeof(double), - nbcomp, - 0); - _local_field->getField()->setValue(values); - if (_forced_renormalization_flag) - renormalizeTargetField(); - delete[]values; - } - - /*! This method is called on the source group in order to - * send field data. It must be called synchronously with - * a recvData() call on - * the target group. - */ - void NonCoincidentDEC::sendData() - { - const double* values=_local_field->getField()->getValue(); - int nbcomp = _local_field->getField()->getNumberOfComponents(); - double* distant_values = new double [_nb_distant_points*nbcomp]; - - //cheap interpolation : the value of the cell is transfered to the point - for (int i=0; i<_nb_distant_points; i++) - for (int j=0; j <nbcomp; j++) - distant_values[i*nbcomp+j]=values[(_distant_locations[i]-1)*nbcomp+j]; - - fvm_locator_exchange_point_var(_locator, - distant_values, - 0, - 0, - sizeof(double), - nbcomp, - 0); - - delete [] distant_values; - if (_forced_renormalization_flag) - renormalizeTargetField(); - - } -} diff --git a/medtool/src/ParaMEDMEM/NonCoincidentDEC.hxx b/medtool/src/ParaMEDMEM/NonCoincidentDEC.hxx deleted file mode 100644 index 6691336b7..000000000 --- a/medtool/src/ParaMEDMEM/NonCoincidentDEC.hxx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __NONCOINCIDENTDEC_HXX__ -#define __NONCOINCIDENTDEC_HXX__ - -#include "DEC.hxx" - -struct _fvm_locator_t; - -typedef enum {NN} InterpolationMethod; - -namespace ParaMEDMEM -{ - class NonCoincidentDEC : public DEC - { - public: - NonCoincidentDEC(); - NonCoincidentDEC(ProcessorGroup& , ProcessorGroup&); - - virtual ~NonCoincidentDEC(); - - void synchronize(); - - void recvData(); - - void sendData(); - - void prepareSourceDE() { } - void prepareTargetDE() { } - - void setInterpolationMethod(InterpolationMethod method) { _method=method; } - - private : - // Structure for computing the localization - // of remote nodes on local mesh - _fvm_locator_t* _locator; - - //Number of distant points to be located locally - int _nb_distant_points; - - //coordinates of distant points - const double* _distant_coords; - - //local element number containing the distant points - const int* _distant_locations; - - //inerpolation method - InterpolationMethod _method; - }; -} - - -#endif diff --git a/medtool/src/ParaMEDMEM/OverlapDEC.cxx b/medtool/src/ParaMEDMEM/OverlapDEC.cxx deleted file mode 100644 index af842fb9d..000000000 --- a/medtool/src/ParaMEDMEM/OverlapDEC.cxx +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "OverlapDEC.hxx" -#include "CommInterface.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "MPIProcessorGroup.hxx" -#include "OverlapElementLocator.hxx" -#include "OverlapInterpolationMatrix.hxx" - -namespace ParaMEDMEM -{ -/*! - \anchor OverlapDEC-det - \class OverlapDEC - - \section OverlapDEC-over Overview - - The \c OverlapDEC enables the \ref InterpKerRemapGlobal "conservative remapping" of fields between - two parallel codes. This remapping is based on the computation of intersection volumes on - a \b single \b processor \b group. On this processor group are defined two field-templates called A - and B. The computation is possible for 3D meshes, 2D meshes, 3D-surface meshes, 1D meshes and - 2D-curve meshes. Dimensions must be similar for the distribution templates A and B. - - The main difference with \ref InterpKernelDEC-det "InterpKernelDEC" is that this - \ref para-dec "DEC" works with a *single* processor group, in which processors will share the work. - Consequently each processor manages two \ref MEDCouplingFieldTemplatesPage "field templates" (A and B) - called source and target. - Furthermore all processors in the processor group cooperate in the global interpolation matrix - computation. In this respect \c InterpKernelDEC is a specialization of \c OverlapDEC. - - \section ParaMEDMEMOverlapDECAlgorithmDescription Algorithm description - - Let's consider the following use case that is ran in ParaMEDMEMTest_OverlapDEC.cxx to describes - the different steps of the computation. The processor group contains 3 processors. - \anchor ParaMEDMEMOverlapDECImgTest1 - \image html OverlapDEC1.png "Example split of the source and target mesh among the 3 procs" - - \subsection ParaMEDMEMOverlapDECAlgoStep1 Step 1 : Bounding box exchange and global interaction between procs computation. - - In order to reduce as much as possible the amount of communications between distant processors, - every processor computes a bounding box for A and B. Then a AllToAll communication is performed - so that - every processor can compute the \b global interactions between processor. - This computation leads every processor to compute the same global TODO list expressed as a list - of pair. A pair ( x, y ) means that proc \b x fieldtemplate A can interact with fieltemplate B of - proc \b y because the two bounding boxes interact. - In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" this computation leads to the following - a \b global TODO list : - - \b (0,0),(0,1),(1,0),(1,2),(2,0),(2,1),(2,2) - - Here the pair (0,2) does not appear because the bounding box of fieldtemplateA of proc#2 does - not intersect that of fieldtemplate B on proc#0. - - Stage performed by ParaMEDMEM::OverlapElementLocator::computeBoundingBoxes. - - \subsection ParaMEDMEMOverlapDECAlgoStep2 Step 2 : Computation of local TODO list - - Starting from the global interaction previously computed in \ref ParaMEDMEMOverlapDECAlgoStep1 - "Step 1", each proc computes the TODO list per proc. - The following rules is chosen : a pair (x,y) can be treated by either proc \#x or proc \#y, - in order to reduce the amount of data transfert among - processors. The algorithm chosen for load balancing is the following : Each processor has - an empty \b local TODO list at the beginning. Then for each pair (k,m) in - \b global TODO list, if proc\#k has less temporary local list than proc\#m pair, (k,m) is added - to temparary local TODO list of proc\#k. - If proc\#m has less temporary local TODO list than proc\#k pair, (k,m) is added to temporary - local TODO list of proc\#m. - If proc\#k and proc\#m have the same amount of temporary local TODO list pair, (k,m) is added to - temporary local TODO list of proc\#k. - - In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" this computation leads to the following - local TODO list : - - - proc\#0 : (0,0) - - proc\#1 : (0,1),(1,0) - - proc\#2 : (1,2),(2,0),(2,1),(2,2) - - The algorithm described here is not perfect for this use case, we hope to enhance it soon. - - At this stage each proc knows precisely its \b local TODO list (with regard to interpolation). - The \b local TODO list of other procs than local - is kept for future computations. - - \subsection ParaMEDMEMOverlapDECAlgoStep3 Step 3 : Matrix echange between procs - - Knowing the \b local TODO list, the aim now is to exchange field-templates between procs. - Each proc computes knowing TODO list per - proc computed in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step 2" the exchange TODO list : - - In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" the exchange TODO list gives the - following results : - - Sending TODO list per proc : - - - proc \#0 : Send fieldtemplate A to Proc\#1, Send fieldtemplate B to Proc\#1, Send fieldtemplate - B to Proc\#2 - - Proc \#1 : Send fieldtemplate A to Proc\#2, Send fieldtemplate B to Proc\#2 - - Proc \#2 : No send. - - Receiving TODO list per proc : - - - proc \#0 : No receiving - - proc \#1 : receiving fieldtemplate A from Proc\#0, receiving fieldtemplate B from Proc\#0 - - proc \#2 : receiving fieldtemplate B from Proc\#0, receiving fieldtemplate A from Proc\#1, - receiving fieldtemplate B from Proc\#1 - - To avoid as much as possible large volumes of transfers between procs, only relevant parts of - meshes are sent. In order for proc\#k to send fieldtemplate A to fieldtemplate B - of proc \#m., proc\#k computes the part of mesh A contained in the boundingbox B of proc\#m. It - implies that the corresponding cellIds or nodeIds of the - corresponding part are sent to proc \#m too. - - Let's consider the couple (k,m) in the TODO list. This couple is treated by either k or m as - seen in \ref ParaMEDMEMOverlapDECAlgoStep2 "here in Step2". - - As will be dealt in Step 6, for final matrix-vector computations, the resulting matrix of the - couple (k,m) whereever it is computed (proc \#k or proc \#m) - will be stored in \b proc\#m. - - - If proc \#k is in charge (performs the matrix computation) for this couple (k,m), target ids - (cells or nodes) of the mesh in proc \#m are renumbered, because proc \#m has seelected a sub mesh - of the target mesh to avoid large amounts of data to transfer. In this case as proc \#m is ultimately - in charge of the matrix, proc \#k must keep preciously the - source ids needed to be sent to proc\#m. No problem will appear for matrix assembling in proc m - for source ids because no restriction was done. - Concerning source ids to be sent for the matrix-vector computation, proc k will know precisely - which source ids field values to send to proc \#m. - This is embodied by OverlapMapping::keepTracksOfTargetIds in proc m. - - - If proc \#m is in charge (performs matrix computation) for this couple (k,m), source ids (cells - or nodes) of the mesh in proc \#k are renumbered, because proc \#k has selected a sub mesh of the - source mesh to avoid large amounts of data to transfer. In this case as proc \#k is ultimately - in charge of the matrix, proc \#m receives the source ids - from remote proc \#k, and thus the matrix is directly correct, no need for renumbering as - in \ref ParaMEDMEMOverlapDECAlgoStep5 "Step 5". However proc \#k must - keep track of the ids sent to proc \#m for te matrix-vector computation. - This is incarnated by OverlapMapping::keepTracksOfSourceIds in proc k. - - This step is performed in ParaMEDMEM::OverlapElementLocator::exchangeMeshes method. - - \subsection ParaMEDMEMOverlapDECAlgoStep4 Step 4 : Computation of the interpolation matrix - - After mesh exchange in \ref ParaMEDMEMOverlapDECAlgoStep3 "Step3" each processor has all the - required information to treat its \b local TODO list computed in - \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". This step is potentially CPU costly, which is why - the \b local TODO list per proc is expected to - be as well balanced as possible. - - The interpolation is performed as the \ref ParaMEDMEM::MEDCouplingRemapper "remapper" does. - - This operation is performed by OverlapInterpolationMatrix::addContribution method. - - \subsection ParaMEDMEMOverlapDECAlgoStep5 Step 5 : Global matrix construction. - - After having performed the TODO list at the end of \ref ParaMEDMEMOverlapDECAlgoStep4 "Step4" - we need to assemble the final matrix. - - The final aim is to have a distributed matrix \f$ M_k \f$ on each proc\#k. In order to reduce - data exchange during the matrix product process, - \f$ M_k \f$ is built using sizeof(Proc group) \c std::vector< \c std::map<int,double> \c >. - - For a proc\#k, it is necessary to fetch info of all matrices built in - \ref ParaMEDMEMOverlapDECAlgoStep4 "Step4" where the first element in pair (i,j) - is equal to k. - - After this step, the matrix repartition is the following after a call to - ParaMEDMEM::OverlapMapping::prepare : - - - proc\#0 : (0,0),(1,0),(2,0) - - proc\#1 : (0,1),(2,1) - - proc\#2 : (1,2),(2,2) - - Tuple (2,1) computed on proc 2 is stored in proc 1 after execution of the function - "prepare". This is an example of item 0 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". - Tuple (0,1) computed on proc 1 is stored in proc 1 too. This is an example of item 1 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". - - In the end ParaMEDMEM::OverlapMapping::_proc_ids_to_send_vector_st will contain : - - - Proc\#0 : 0,1 - - Proc\#1 : 0,2 - - Proc\#2 : 0,1,2 - - In the end ParaMEDMEM::OverlapMapping::_proc_ids_to_recv_vector_st will contain : - - - Proc\#0 : 0,1,2 - - Proc\#1 : 0,2 - - Proc\#2 : 1,2 - - The method in charge to perform this is : ParaMEDMEM::OverlapMapping::prepare. -*/ - OverlapDEC::OverlapDEC(const std::set<int>& procIds, const MPI_Comm& world_comm): - _load_balancing_algo(1), - _own_group(true),_interpolation_matrix(0), _locator(0), - _source_field(0),_own_source_field(false), - _target_field(0),_own_target_field(false), - _default_field_value(0.0), - _comm(MPI_COMM_NULL) - { - ParaMEDMEM::CommInterface comm; - int *ranks_world=new int[procIds.size()]; // ranks of sources and targets in world_comm - std::copy(procIds.begin(),procIds.end(),ranks_world); - MPI_Group group,world_group; - comm.commGroup(world_comm,&world_group); - comm.groupIncl(world_group,procIds.size(),ranks_world,&group); - delete [] ranks_world; - comm.commCreate(world_comm,group,&_comm); - comm.groupFree(&group); - comm.groupFree(&world_group); - if(_comm==MPI_COMM_NULL) - { - _group=0; - return ; - } - std::set<int> idsUnion; - for(std::size_t i=0;i<procIds.size();i++) - idsUnion.insert(i); - _group=new MPIProcessorGroup(comm,idsUnion,_comm); - } - - OverlapDEC::~OverlapDEC() - { - if(_own_group) - delete _group; - if(_own_source_field) - delete _source_field; - if(_own_target_field) - delete _target_field; - delete _interpolation_matrix; - delete _locator; - if (_comm != MPI_COMM_NULL) - { - ParaMEDMEM::CommInterface comm; - comm.commFree(&_comm); - } - } - - void OverlapDEC::sendRecvData(bool way) - { - if(way) - sendData(); - else - recvData(); - } - - void OverlapDEC::sendData() - { - _interpolation_matrix->multiply(_default_field_value); - } - - void OverlapDEC::recvData() - { - throw INTERP_KERNEL::Exception("Not implemented yet !!!!"); - //_interpolation_matrix->transposeMultiply(); - } - - void OverlapDEC::synchronize() - { - if(!isInGroup()) - return ; - // Check number of components of field on both side (for now allowing void field/mesh on one proc is not allowed) - if (!_source_field || !_source_field->getField()) - throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void source field on a proc is not allowed!"); - if (!_target_field || !_target_field->getField()) - throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): currently, having a void target field on a proc is not allowed!"); - if (_target_field->getField()->getNumberOfComponents() != _source_field->getField()->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): source and target field have different number of components!"); - delete _interpolation_matrix; - _locator = new OverlapElementLocator(_source_field,_target_field,*_group, getBoundingBoxAdjustmentAbs(), _load_balancing_algo); - _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this, *_locator); - _locator->copyOptions(*this); - _locator->exchangeMeshes(*_interpolation_matrix); - std::vector< std::pair<int,int> > jobs=_locator->getToDoList(); - std::string srcMeth=_locator->getSourceMethod(); - std::string trgMeth=_locator->getTargetMethod(); - for(std::vector< std::pair<int,int> >::const_iterator it=jobs.begin();it!=jobs.end();it++) - { - const MEDCouplingPointSet *src=_locator->getSourceMesh((*it).first); - const DataArrayInt *srcIds=_locator->getSourceIds((*it).first); - const MEDCouplingPointSet *trg=_locator->getTargetMesh((*it).second); - const DataArrayInt *trgIds=_locator->getTargetIds((*it).second); - _interpolation_matrix->computeLocalIntersection(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second); - } - _interpolation_matrix->prepare(_locator->getProcsToSendFieldData()); - _interpolation_matrix->computeSurfacesAndDeno(); - } - - void OverlapDEC::attachSourceLocalField(ParaFIELD *field, bool ownPt) - { - if(!isInGroup()) - return ; - if(_own_source_field) - delete _source_field; - _source_field=field; - _own_source_field=ownPt; - } - - void OverlapDEC::attachTargetLocalField(ParaFIELD *field, bool ownPt) - { - if(!isInGroup()) - return ; - if(_own_target_field) - delete _target_field; - _target_field=field; - _own_target_field=ownPt; - } - - void OverlapDEC::attachSourceLocalField(MEDCouplingFieldDouble *field) - { - if(!isInGroup()) - return ; - - ParaMESH *paramesh = new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())), - *_group,field->getMesh()->getName()); - ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group); - tmpField->setOwnSupport(true); - attachSourceLocalField(tmpField,true); - } - - void OverlapDEC::attachTargetLocalField(MEDCouplingFieldDouble *field) - { - if(!isInGroup()) - return ; - - ParaMESH *paramesh = new ParaMESH(static_cast<MEDCouplingPointSet *>(const_cast<MEDCouplingMesh *>(field->getMesh())), - *_group,field->getMesh()->getName()); - ParaFIELD *tmpField=new ParaFIELD(field, paramesh, *_group); - tmpField->setOwnSupport(true); - attachTargetLocalField(tmpField,true); - } - - bool OverlapDEC::isInGroup() const - { - if(!_group) - return false; - return _group->containsMyRank(); - } - - void OverlapDEC::debugPrintWorkSharing(std::ostream & ostr) const - { - _locator->debugPrintWorkSharing(ostr); - } -} diff --git a/medtool/src/ParaMEDMEM/OverlapDEC.hxx b/medtool/src/ParaMEDMEM/OverlapDEC.hxx deleted file mode 100644 index 2d63789b7..000000000 --- a/medtool/src/ParaMEDMEM/OverlapDEC.hxx +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __OVERLAPDEC_HXX__ -#define __OVERLAPDEC_HXX__ - -#include "DEC.hxx" -#include "InterpolationOptions.hxx" - -#include <mpi.h> -#include <string> - -namespace ParaMEDMEM -{ - class OverlapInterpolationMatrix; - class OverlapElementLocator; - class ProcessorGroup; - class ParaFIELD; - - class OverlapDEC : public DEC, public INTERP_KERNEL::InterpolationOptions - { - public: - OverlapDEC(const std::set<int>& procIds,const MPI_Comm& world_comm=MPI_COMM_WORLD); - virtual ~OverlapDEC(); - void sendRecvData(bool way=true); - void sendData(); - void recvData(); - void synchronize(); - void attachSourceLocalField(ParaFIELD *field, bool ownPt=false); - void attachTargetLocalField(ParaFIELD *field, bool ownPt=false); - void attachSourceLocalField(MEDCouplingFieldDouble *field); - void attachTargetLocalField(MEDCouplingFieldDouble *field); - ProcessorGroup *getGroup() { return _group; } - bool isInGroup() const; - - void setDefaultValue(double val) {_default_field_value = val;} - //! 0 means initial algo from Antho, 1 or 2 means Adrien's algo (2 should be better). Make your choice :-)) - void setWorkSharingAlgo(int method) { _load_balancing_algo = method; } - - void debugPrintWorkSharing(std::ostream & ostr) const; - private: - int _load_balancing_algo; - - bool _own_group; - OverlapInterpolationMatrix* _interpolation_matrix; - OverlapElementLocator* _locator; - ProcessorGroup *_group; - - double _default_field_value; - - ParaFIELD *_source_field; - bool _own_source_field; - ParaFIELD *_target_field; - bool _own_target_field; - MPI_Comm _comm; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/OverlapElementLocator.cxx b/medtool/src/ParaMEDMEM/OverlapElementLocator.cxx deleted file mode 100644 index 81cb987db..000000000 --- a/medtool/src/ParaMEDMEM/OverlapElementLocator.cxx +++ /dev/null @@ -1,552 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "OverlapElementLocator.hxx" - -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ParaFIELD.hxx" -#include "ParaMESH.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "OverlapInterpolationMatrix.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "DirectedBoundingBox.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include <limits> - -using namespace std; - -namespace ParaMEDMEM -{ - const int OverlapElementLocator::START_TAG_MESH_XCH = 1140; - - OverlapElementLocator::OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField, - const ProcessorGroup& group, double epsAbs, int workSharingAlgo) - : _local_source_field(sourceField), - _local_target_field(targetField), - _local_source_mesh(0), - _local_target_mesh(0), - _domain_bounding_boxes(0), - _group(group), - _epsAbs(epsAbs) - { - if(_local_source_field) - _local_source_mesh=_local_source_field->getSupport()->getCellMesh(); - if(_local_target_field) - _local_target_mesh=_local_target_field->getSupport()->getCellMesh(); - _comm=getCommunicator(); - - computeBoundingBoxesAndInteractionList(); - switch(workSharingAlgo) - { - case 0: - computeTodoList_original(); break; - case 1: - computeTodoList_new(false); break; - case 2: - computeTodoList_new(true); break; - default: - throw INTERP_KERNEL::Exception("OverlapElementLocator::OverlapElementLocator(): invalid algorithm selected!"); - } - - fillProcToSend(); - } - - OverlapElementLocator::~OverlapElementLocator() - { - delete [] _domain_bounding_boxes; - } - - const MPI_Comm *OverlapElementLocator::getCommunicator() const - { - const MPIProcessorGroup* group=static_cast<const MPIProcessorGroup*>(&_group); - return group->getComm(); - } - - void OverlapElementLocator::computeBoundingBoxesAndInteractionList() - { - CommInterface comm_interface=_group.getCommInterface(); - const MPIProcessorGroup* group=static_cast<const MPIProcessorGroup*> (&_group); - _local_space_dim=0; - if(_local_source_mesh) - _local_space_dim=_local_source_mesh->getSpaceDimension(); - else - _local_space_dim=_local_target_mesh->getSpaceDimension(); - // - const MPI_Comm* comm = group->getComm(); - int bbSize=2*2*_local_space_dim;//2 (for source/target) 2 (min/max) - _domain_bounding_boxes=new double[bbSize*_group.size()]; - INTERP_KERNEL::AutoPtr<double> minmax=new double[bbSize]; - //Format minmax : Xmin_src,Xmax_src,Ymin_src,Ymax_src,Zmin_src,Zmax_src,Xmin_trg,Xmax_trg,Ymin_trg,Ymax_trg,Zmin_trg,Zmax_trg - if(_local_source_mesh) - _local_source_mesh->getBoundingBox(minmax); - else - { - for(int i=0;i<_local_space_dim;i++) - { - minmax[i*2]=std::numeric_limits<double>::max(); - minmax[i*2+1]=-std::numeric_limits<double>::max(); - } - } - if(_local_target_mesh) - _local_target_mesh->getBoundingBox(minmax+2*_local_space_dim); - else - { - for(int i=0;i<_local_space_dim;i++) - { - minmax[i*2+2*_local_space_dim]=std::numeric_limits<double>::max(); - minmax[i*2+1+2*_local_space_dim]=-std::numeric_limits<double>::max(); - } - } - comm_interface.allGather(minmax, bbSize, MPI_DOUBLE, - _domain_bounding_boxes,bbSize, MPI_DOUBLE, - *comm); - - // Computation of all pairs needing an interpolation pairs are duplicated now ! - - _proc_pairs.clear();//first is source second is target - _proc_pairs.resize(_group.size()); - for(int i=0;i<_group.size();i++) - for(int j=0;j<_group.size();j++) - if(intersectsBoundingBox(i,j)) - _proc_pairs[i].push_back(j); - } - - void OverlapElementLocator::computeTodoList_original() - { - // OK now let's assigning as balanced as possible, job to each proc of group - _all_todo_lists.resize(_group.size()); - int i=0; - for(std::vector< std::vector< int > >::const_iterator it1=_proc_pairs.begin();it1!=_proc_pairs.end();it1++,i++) - for(std::vector< int >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - { - if(_all_todo_lists[i].size()<=_all_todo_lists[*it2].size())//it includes the fact that i==*it2 - _all_todo_lists[i].push_back(ProcCouple(i,*it2)); - else - _all_todo_lists[*it2].push_back(ProcCouple(i,*it2)); - } - //Keeping todo list of current proc. _to_do_list contains a set of pair where at least _group.myRank() appears once. - //This proc will be in charge to perform interpolation of any of element of '_to_do_list' - //If _group.myRank()==myPair.first, current proc should fetch target mesh of myPair.second (if different from _group.myRank()). - //If _group.myRank()==myPair.second, current proc should fetch source mesh of myPair.second. - - int myProcId=_group.myRank(); - _to_do_list=_all_todo_lists[myProcId]; - -#ifdef DEC_DEBUG - std::stringstream scout; - scout << "(" << myProcId << ") my TODO list is: "; - for (std::vector< ProcCouple >::const_iterator itdbg=_to_do_list.begin(); itdbg!=_to_do_list.end(); itdbg++) - scout << "(" << (*itdbg).first << "," << (*itdbg).second << ")"; - std::cout << scout.str() << "\n"; -#endif - } - - /* More efficient (?) work sharing algorithm: a job (i,j) is initially assigned twice: to proc#i and to proc#j. - * Then try to reduce as much as possible the variance of the num of jobs per proc by selecting the right duplicate - * to remove: - * - take the most loaded proc i, - * + select the job (i,j) for which proc#j is the less loaded - * + remove this job from proc#i, and mark it as 'unremovable' from proc#j - * - repeat until no more duplicates are found - */ - void OverlapElementLocator::computeTodoList_new(bool revertIter) - { - using namespace std; - int infinity = std::numeric_limits<int>::max(); - // Initialisation - int grp_size = _group.size(); - vector < map<ProcCouple, int> > full_set(grp_size ); - int srcProcID = 0; - for(vector< vector< int > >::const_iterator it = _proc_pairs.begin(); it != _proc_pairs.end(); it++, srcProcID++) - for (vector< int >::const_iterator it2=(*it).begin(); it2 != (*it).end(); it2++) - { - // Here a pair of the form (i,i) is added only once! - int tgtProcID = *it2; - ProcCouple cpl = make_pair(srcProcID, tgtProcID); - full_set[srcProcID][cpl] = -1; - full_set[tgtProcID][cpl] = -1; - } - int procID = 0; - vector < map<ProcCouple, int> > ::iterator itVector; - map<ProcCouple, int>::iterator itMap; - for(itVector = full_set.begin(); itVector != full_set.end(); itVector++, procID++) - for (itMap=(*itVector).begin(); itMap != (*itVector).end(); itMap++) - { - const ProcCouple & cpl = (*itMap).first; - if (cpl.first == cpl.second) - // special case - this couple can not be removed in the future - (*itMap).second = infinity; - else - { - if(cpl.first == procID) - (*itMap).second = full_set[cpl.second].size(); - else // cpl.second == srcProcID - (*itMap).second = full_set[cpl.first].size(); - } - } - INTERP_KERNEL::AutoPtr<bool> proc_valid = new bool[grp_size]; - fill((bool *)proc_valid, proc_valid+grp_size, true); - - // Now the algo: - while (find((bool *)proc_valid, proc_valid+grp_size, true) != proc_valid+grp_size) - { - // Most loaded proc: - int max_sz = -1, max_id = -1; - for(itVector = full_set.begin(), procID=0; itVector != full_set.end(); itVector++, procID++) - { - int sz = (*itVector).size(); - if (proc_valid[procID] && sz > max_sz) - { - max_sz = sz; - max_id = procID; - } - } - - // Nothing more to do: - if (max_sz == -1) - break; - // For this proc, job with less loaded second proc: - int min_sz = infinity; - map<ProcCouple, int> & max_map = full_set[max_id]; - ProcCouple hit_cpl = make_pair(-1,-1); - if(revertIter) - { - // Use a reverse iterator here increases our chances to hit a couple of the form (i, myProcId) - // meaning that the final matrix computed won't have to be sent: save some comm. - map<ProcCouple, int> ::const_reverse_iterator ritMap; - for(ritMap=max_map.rbegin(); ritMap != max_map.rend(); ritMap++) - if ((*ritMap).second < min_sz) - hit_cpl = (*ritMap).first; - } - else - { - for(itMap=max_map.begin(); itMap != max_map.end(); itMap++) - if ((*itMap).second < min_sz) - hit_cpl = (*itMap).first; - } - if (hit_cpl.first == -1) - { - // Plouf. Current proc 'max_id' can not be reduced. Invalid it: - proc_valid[max_id] = false; - continue; - } - // Remove item from proc 'max_id' - full_set[max_id].erase(hit_cpl); - // And mark it as not removable on the other side: - if (hit_cpl.first == max_id) - full_set[hit_cpl.second][hit_cpl] = infinity; - else // hit_cpl.second == max_id - full_set[hit_cpl.first][hit_cpl] = infinity; - - // Now update all counts of valid maps: - procID = 0; - for(itVector = full_set.begin(); itVector != full_set.end(); itVector++, procID++) - if(proc_valid[procID] && procID != max_id) - for(itMap = (*itVector).begin(); itMap != (*itVector).end(); itMap++) - { - const ProcCouple & cpl = (*itMap).first; - // Unremovable item: - if ((*itMap).second == infinity) - continue; - if (cpl.first == max_id || cpl.second == max_id) - (*itMap).second--; - } - } - // Final formatting - extract remaining keys in each map: - int myProcId=_group.myRank(); - _all_todo_lists.resize(grp_size); - procID = 0; - for(itVector = full_set.begin(); itVector != full_set.end(); itVector++, procID++) - for(itMap = (*itVector).begin(); itMap != (*itVector).end(); itMap++) - _all_todo_lists[procID].push_back((*itMap).first); - _to_do_list=_all_todo_lists[myProcId]; - -#ifdef DEC_DEBUG - std::stringstream scout; - scout << "(" << myProcId << ") my TODO list is: "; - for (std::vector< ProcCouple >::const_iterator itdbg=_to_do_list.begin(); itdbg!=_to_do_list.end(); itdbg++) - scout << "(" << (*itdbg).first << "," << (*itdbg).second << ")"; - std::cout << scout.str() << "\n"; -#endif - } - - void OverlapElementLocator::debugPrintWorkSharing(std::ostream & ostr) const - { - std::vector< std::vector< ProcCouple > >::const_iterator it = _all_todo_lists.begin(); - ostr << "TODO list lengths: "; - for(; it != _all_todo_lists.end(); ++it) - ostr << (*it).size() << " "; - ostr << "\n"; - } - - void OverlapElementLocator::fillProcToSend() - { - // Feeding now '_procs_to_send*'. A same id can appears twice. The second parameter in pair means what - // to send true=source, false=target - int myProcId=_group.myRank(); - _procs_to_send_mesh.clear(); - _procs_to_send_field.clear(); - for(int i=_group.size()-1;i>=0;i--) - { - const std::vector< ProcCouple >& anRemoteProcToDoList=_all_todo_lists[i]; - for(std::vector< ProcCouple >::const_iterator it=anRemoteProcToDoList.begin();it!=anRemoteProcToDoList.end();it++) - { - if((*it).first==myProcId) - { - if(i!=myProcId) - _procs_to_send_mesh.push_back(Proc_SrcOrTgt(i,true)); - _procs_to_send_field.push_back((*it).second); - } - if((*it).second==myProcId) - if(i!=myProcId) - _procs_to_send_mesh.push_back(Proc_SrcOrTgt(i,false)); - } - } - } - - - /*! - * The aim of this method is to perform the communication to get data corresponding to '_to_do_list' attribute. - * The principle is the following : if proc n1 and n2 need to perform a cross sending with n1<n2, then n1 will send first and receive then. - */ - void OverlapElementLocator::exchangeMeshes(OverlapInterpolationMatrix& matrix) - { - int myProcId=_group.myRank(); - //starting to receive every procs whose id is lower than myProcId. - std::vector< ProcCouple > toDoListForFetchRemaining; - for(std::vector< ProcCouple >::const_iterator it=_to_do_list.begin();it!=_to_do_list.end();it++) - { - int first = (*it).first, second = (*it).second; - if(first!=second) - { - if(first==myProcId) - { - if(second<myProcId) - receiveRemoteMeshFrom(second,false); - else - toDoListForFetchRemaining.push_back(ProcCouple(first,second)); - } - else - {//(*it).second==myProcId - if(first<myProcId) - receiveRemoteMeshFrom(first,true); - else - toDoListForFetchRemaining.push_back(ProcCouple(first,second)); - } - } - } - //sending source or target mesh to remote procs - for(std::vector< Proc_SrcOrTgt >::const_iterator it2=_procs_to_send_mesh.begin();it2!=_procs_to_send_mesh.end();it2++) - sendLocalMeshTo((*it2).first,(*it2).second,matrix); - //fetching remaining meshes - for(std::vector< ProcCouple >::const_iterator it=toDoListForFetchRemaining.begin();it!=toDoListForFetchRemaining.end();it++) - { - if((*it).first!=(*it).second) - { - if((*it).first==myProcId) - receiveRemoteMeshFrom((*it).second,false); - else//(*it).second==myProcId - receiveRemoteMeshFrom((*it).first,true); - } - } - } - - std::string OverlapElementLocator::getSourceMethod() const - { - return _local_source_field->getField()->getDiscretization()->getStringRepr(); - } - - std::string OverlapElementLocator::getTargetMethod() const - { - return _local_target_field->getField()->getDiscretization()->getStringRepr(); - } - - const MEDCouplingPointSet *OverlapElementLocator::getSourceMesh(int procId) const - { - int myProcId=_group.myRank(); - if(myProcId==procId) - return _local_source_mesh; - Proc_SrcOrTgt p(procId,true); - std::map<Proc_SrcOrTgt, AutoMCPointSet >::const_iterator it=_remote_meshes.find(p); - return (*it).second; - } - - const DataArrayInt *OverlapElementLocator::getSourceIds(int procId) const - { - int myProcId=_group.myRank(); - if(myProcId==procId) - return 0; - Proc_SrcOrTgt p(procId,true); - std::map<Proc_SrcOrTgt, AutoDAInt >::const_iterator it=_remote_elems.find(p); - return (*it).second; - } - - const MEDCouplingPointSet *OverlapElementLocator::getTargetMesh(int procId) const - { - int myProcId=_group.myRank(); - if(myProcId==procId) - return _local_target_mesh; - Proc_SrcOrTgt p(procId,false); - std::map<Proc_SrcOrTgt, AutoMCPointSet >::const_iterator it=_remote_meshes.find(p); - return (*it).second; - } - - const DataArrayInt *OverlapElementLocator::getTargetIds(int procId) const - { - int myProcId=_group.myRank(); - if(myProcId==procId) - return 0; - Proc_SrcOrTgt p(procId,false); - std::map<Proc_SrcOrTgt, AutoDAInt >::const_iterator it=_remote_elems.find(p); - return (*it).second; - } - - bool OverlapElementLocator::isInMyTodoList(int i, int j) const - { - ProcCouple cpl = std::make_pair(i, j); - return std::find(_to_do_list.begin(), _to_do_list.end(), cpl)!=_to_do_list.end(); - } - - bool OverlapElementLocator::intersectsBoundingBox(int isource, int itarget) const - { - const double *source_bb=_domain_bounding_boxes+isource*2*2*_local_space_dim; - const double *target_bb=_domain_bounding_boxes+itarget*2*2*_local_space_dim+2*_local_space_dim; - - for (int idim=0; idim < _local_space_dim; idim++) - { - bool intersects = (target_bb[idim*2]<source_bb[idim*2+1]+_epsAbs) - && (source_bb[idim*2]<target_bb[idim*2+1]+_epsAbs); - if (!intersects) - return false; - } - return true; - } - - /*! - * This methods sends (part of) local source if 'sourceOrTarget'==True to proc 'procId'. - * This methods sends (part of) local target if 'sourceOrTarget'==False to proc 'procId'. - * - * This method prepares the matrix too, for matrix assembling and future matrix-vector computation. - */ - void OverlapElementLocator::sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const - { - //int myProcId=_group.myRank(); - const double *distant_bb=0; - MEDCouplingPointSet *local_mesh=0; - const ParaFIELD *field=0; - if(sourceOrTarget)//source for local mesh but target for distant mesh - { - distant_bb=_domain_bounding_boxes+procId*2*2*_local_space_dim+2*_local_space_dim; - local_mesh=_local_source_mesh; - field=_local_source_field; - } - else//target for local but source for distant - { - distant_bb=_domain_bounding_boxes+procId*2*2*_local_space_dim; - local_mesh=_local_target_mesh; - field=_local_target_field; - } - AutoDAInt elems=local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment()); - DataArrayInt *old2new_map; - MEDCouplingPointSet *send_mesh=static_cast<MEDCouplingPointSet *>(field->getField()->buildSubMeshData(elems->begin(),elems->end(),old2new_map)); - if(sourceOrTarget) - matrix.keepTracksOfSourceIds(procId,old2new_map); - else - matrix.keepTracksOfTargetIds(procId,old2new_map); - sendMesh(procId,send_mesh,old2new_map); - send_mesh->decrRef(); - old2new_map->decrRef(); - } - - /*! - * This method recieves source remote mesh on proc 'procId' if sourceOrTarget==True - * This method recieves target remote mesh on proc 'procId' if sourceOrTarget==False - */ - void OverlapElementLocator::receiveRemoteMeshFrom(int procId, bool sourceOrTarget) - { - DataArrayInt *old2new_map=0; - MEDCouplingPointSet *m=0; - receiveMesh(procId,m,old2new_map); - Proc_SrcOrTgt p(procId,sourceOrTarget); - _remote_meshes[p]=m; - _remote_elems[p]=old2new_map; - } - - void OverlapElementLocator::sendMesh(int procId, const MEDCouplingPointSet *mesh, const DataArrayInt *idsToSend) const - { - CommInterface comInterface=_group.getCommInterface(); - - // First stage : exchanging sizes - vector<double> tinyInfoLocalD;//tinyInfoLocalD not used for the moment - vector<int> tinyInfoLocal; - vector<string> tinyInfoLocalS; - mesh->getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS); - const MPI_Comm *comm=getCommunicator(); - // - int lgth[2]; - lgth[0]=tinyInfoLocal.size(); - lgth[1]=idsToSend->getNbOfElems(); - comInterface.send(&lgth,2,MPI_INT,procId,START_TAG_MESH_XCH,*_comm); - comInterface.send(&tinyInfoLocal[0],tinyInfoLocal.size(),MPI_INT,procId,START_TAG_MESH_XCH+1,*comm); - // - DataArrayInt *v1Local=0; - DataArrayDouble *v2Local=0; - mesh->serialize(v1Local,v2Local); - comInterface.send(v1Local->getPointer(),v1Local->getNbOfElems(),MPI_INT,procId,START_TAG_MESH_XCH+2,*comm); - comInterface.send(v2Local->getPointer(),v2Local->getNbOfElems(),MPI_DOUBLE,procId,START_TAG_MESH_XCH+3,*comm); - //finished for mesh, ids now - comInterface.send(const_cast<int *>(idsToSend->getConstPointer()),lgth[1],MPI_INT,procId,START_TAG_MESH_XCH+4,*comm); - // - v1Local->decrRef(); - v2Local->decrRef(); - } - - void OverlapElementLocator::receiveMesh(int procId, MEDCouplingPointSet* &mesh, DataArrayInt *&ids) const - { - int lgth[2]; - MPI_Status status; - const MPI_Comm *comm=getCommunicator(); - CommInterface comInterface=_group.getCommInterface(); - comInterface.recv(lgth,2,MPI_INT,procId,START_TAG_MESH_XCH,*_comm,&status); - std::vector<int> tinyInfoDistant(lgth[0]); - ids=DataArrayInt::New(); - ids->alloc(lgth[1],1); - comInterface.recv(&tinyInfoDistant[0],lgth[0],MPI_INT,procId,START_TAG_MESH_XCH+1,*comm,&status); - mesh=MEDCouplingPointSet::BuildInstanceFromMeshType((MEDCouplingMeshType)tinyInfoDistant[0]); - std::vector<std::string> unusedTinyDistantSts; - vector<double> tinyInfoDistantD(1);//tinyInfoDistantD not used for the moment - DataArrayInt *v1Distant=DataArrayInt::New(); - DataArrayDouble *v2Distant=DataArrayDouble::New(); - mesh->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - comInterface.recv(v1Distant->getPointer(),v1Distant->getNbOfElems(),MPI_INT,procId,START_TAG_MESH_XCH+2,*comm,&status); - comInterface.recv(v2Distant->getPointer(),v2Distant->getNbOfElems(),MPI_DOUBLE,procId,START_TAG_MESH_XCH+3,*comm,&status); - mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - //finished for mesh, ids now - comInterface.recv(ids->getPointer(),lgth[1],MPI_INT,procId,1144,*comm,&status); - // - v1Distant->decrRef(); - v2Distant->decrRef(); - } -} diff --git a/medtool/src/ParaMEDMEM/OverlapElementLocator.hxx b/medtool/src/ParaMEDMEM/OverlapElementLocator.hxx deleted file mode 100644 index 3ffd028db..000000000 --- a/medtool/src/ParaMEDMEM/OverlapElementLocator.hxx +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __OVERLAPELEMENTLOCATOR_HXX__ -#define __OVERLAPELEMENTLOCATOR_HXX__ - -#include "InterpolationOptions.hxx" -#include "MEDCouplingNatureOfField.hxx" -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include <mpi.h> -#include <vector> -#include <map> -#include <set> - -//#define DEC_DEBUG - -namespace ParaMEDMEM -{ - class ParaFIELD; - class ProcessorGroup; - class OverlapInterpolationMatrix; - - typedef std::pair<int,int> ProcCouple; // a couple of proc IDs, typically used to define a exchange betw 2 procs - - class OverlapElementLocator : public INTERP_KERNEL::InterpolationOptions - { - public: - OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField, const ProcessorGroup& group, - double epsAbs, int workSharingAlgo); - virtual ~OverlapElementLocator(); - const MPI_Comm *getCommunicator() const; - void exchangeMeshes(OverlapInterpolationMatrix& matrix); - std::vector< std::pair<int,int> > getToDoList() const { return _to_do_list; } - std::vector< int > getProcsToSendFieldData() const { return _procs_to_send_field; } // same set as the set of procs we sent mesh data to - std::string getSourceMethod() const; - std::string getTargetMethod() const; - const MEDCouplingPointSet *getSourceMesh(int procId) const; - const DataArrayInt *getSourceIds(int procId) const; - const MEDCouplingPointSet *getTargetMesh(int procId) const; - const DataArrayInt *getTargetIds(int procId) const; - bool isInMyTodoList(int i, int j) const; - void debugPrintWorkSharing(std::ostream & ostr) const; - private: - void computeBoundingBoxesAndInteractionList(); - void computeTodoList_original(); - void computeTodoList_new(bool revertIter); - void fillProcToSend(); - bool intersectsBoundingBox(int i, int j) const; - void sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const; - void receiveRemoteMeshFrom(int procId, bool sourceOrTarget); - void sendMesh(int procId, const MEDCouplingPointSet *mesh, const DataArrayInt *idsToSend) const; - void receiveMesh(int procId, MEDCouplingPointSet* &mesh, DataArrayInt *&ids) const; - private: - typedef MEDCouplingAutoRefCountObjectPtr< MEDCouplingPointSet > AutoMCPointSet; - typedef MEDCouplingAutoRefCountObjectPtr< DataArrayInt > AutoDAInt; - typedef std::pair<int,bool> Proc_SrcOrTgt; // a key indicating a proc ID and whether the data is for source mesh/field or target mesh/field - - static const int START_TAG_MESH_XCH; - - const ParaFIELD *_local_source_field; - const ParaFIELD *_local_target_field; - - int _local_space_dim; - MEDCouplingPointSet *_local_source_mesh; - MEDCouplingPointSet *_local_target_mesh; - - /*! of size _group.size(). Contains for each source proc i, the ids of proc j the targets interact with. - This vector is common for all procs in _group. This is the full list of jobs to do the interp. */ - std::vector< std::vector< int > > _proc_pairs; - //! todo lists per proc - std::vector< std::vector< ProcCouple > > _all_todo_lists; - //! list of interpolation couples to be done by this proc only. This is a simple extraction of the member above _all_todo_lists - std::vector< ProcCouple > _to_do_list; - //! list of procs the local proc will have to send mesh data to: - std::vector< Proc_SrcOrTgt > _procs_to_send_mesh; -// /*! list of procs the local proc will have to send field data to for the final matrix-vector computation: -// * This can be different from _procs_to_send_mesh (restricted to Source) because interpolation matrix bits are computed on a potentially -// * different proc than the target one. */ - std::vector< int > _procs_to_send_field; - //! Set of distant meshes - std::map< Proc_SrcOrTgt, AutoMCPointSet > _remote_meshes; - //! Set of cell ID mappings for the above distant meshes (because only part of the meshes are exchanged) - std::map< Proc_SrcOrTgt, AutoDAInt > _remote_elems; - double* _domain_bounding_boxes; - //! bounding box absolute adjustment - double _epsAbs; - - std::vector<int> _distant_proc_ids; - - const ProcessorGroup& _group; - const MPI_Comm *_comm; - }; - -} - -#endif diff --git a/medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx b/medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx deleted file mode 100644 index 060783833..000000000 --- a/medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "OverlapInterpolationMatrix.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ProcessorGroup.hxx" -#include "TranslationRotationMatrix.hxx" -#include "Interpolation.hxx" -#include "Interpolation1D.txx" -#include "Interpolation2DCurve.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3DSurf.hxx" -#include "Interpolation3D.txx" -#include "Interpolation3D2D.txx" -#include "Interpolation2D1D.txx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "InterpolationOptions.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "ElementLocator.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include <algorithm> - -using namespace std; - -namespace ParaMEDMEM -{ - OverlapInterpolationMatrix::OverlapInterpolationMatrix(ParaFIELD *source_field, - ParaFIELD *target_field, - const ProcessorGroup& group, - const DECOptions& dec_options, - const INTERP_KERNEL::InterpolationOptions& i_opt, - const OverlapElementLocator & locator): - INTERP_KERNEL::InterpolationOptions(i_opt), - DECOptions(dec_options), - _source_field(source_field), - _target_field(target_field), - _source_support(source_field->getSupport()->getCellMesh()), - _target_support(target_field->getSupport()->getCellMesh()), - _mapping(group, locator), - _group(group) - { - } - - void OverlapInterpolationMatrix::keepTracksOfSourceIds(int procId, DataArrayInt *ids) - { - _mapping.keepTracksOfSourceIds(procId,ids); - } - - void OverlapInterpolationMatrix::keepTracksOfTargetIds(int procId, DataArrayInt *ids) - { - _mapping.keepTracksOfTargetIds(procId,ids); - } - - OverlapInterpolationMatrix::~OverlapInterpolationMatrix() - { - } - - // TODO? Merge with MEDCouplingRemapper::prepareInterpKernelOnlyUU() ? - /**! - * Local run (on this proc) of the sequential interpolation algorithm. - * - * @param srcIds is null if the source mesh is on the local proc - * @param trgIds is null if the source mesh is on the local proc - * - * One of the 2 is necessarily null (the two can be null together) - */ - void OverlapInterpolationMatrix::computeLocalIntersection(const MEDCouplingPointSet *src, const DataArrayInt *srcIds, const std::string& srcMeth, int srcProcId, - const MEDCouplingPointSet *trg, const DataArrayInt *trgIds, const std::string& trgMeth, int trgProcId) - { - std::string interpMethod(srcMeth); - interpMethod+=trgMeth; - //creating the interpolator structure - vector<SparseDoubleVec > sparse_matrix_part; - int colSize=0; - //computation of the intersection volumes between source and target elements - const MEDCouplingUMesh *trgC=dynamic_cast<const MEDCouplingUMesh *>(trg); - const MEDCouplingUMesh *srcC=dynamic_cast<const MEDCouplingUMesh *>(src); - if ( src->getMeshDimension() == -1 ) - { - if(trgC->getMeshDimension()==2 && trgC->getSpaceDimension()==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(trgC); - INTERP_KERNEL::Interpolation2D interpolation(*this); - colSize=interpolation.fromIntegralUniform(target_mesh_wrapper,sparse_matrix_part,trgMeth); - } - else if(trgC->getMeshDimension()==3 && trgC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(trgC); - INTERP_KERNEL::Interpolation3D interpolation(*this); - colSize=interpolation.fromIntegralUniform(target_mesh_wrapper,sparse_matrix_part,trgMeth); - } - else if(trgC->getMeshDimension()==2 && trgC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(trgC); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - colSize=interpolation.fromIntegralUniform(target_mesh_wrapper,sparse_matrix_part,trgMeth); - } - else - throw INTERP_KERNEL::Exception("No para interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); - } - else if ( trg->getMeshDimension() == -1 ) - { - if(srcC->getMeshDimension()==2 && srcC->getSpaceDimension()==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> local_mesh_wrapper(srcC); - INTERP_KERNEL::Interpolation2D interpolation(*this); - colSize=interpolation.toIntegralUniform(local_mesh_wrapper,sparse_matrix_part,srcMeth); - } - else if(srcC->getMeshDimension()==3 && srcC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> local_mesh_wrapper(srcC); - INTERP_KERNEL::Interpolation3D interpolation(*this); - colSize=interpolation.toIntegralUniform(local_mesh_wrapper,sparse_matrix_part,srcMeth); - } - else if(srcC->getMeshDimension()==2 && srcC->getSpaceDimension()==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> local_mesh_wrapper(srcC); - INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - colSize=interpolation.toIntegralUniform(local_mesh_wrapper,sparse_matrix_part,srcMeth); - } - else - throw INTERP_KERNEL::Exception("No para interpolation available for the given mesh and space dimension of distant mesh to -1D sourceMesh"); - } - else if ( src->getMeshDimension() == 2 && trg->getMeshDimension() == 3 - && trg->getSpaceDimension() == 3 && src->getSpaceDimension() == 3 ) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation3D2D interpolator (*this); - colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else if ( src->getMeshDimension() == 3 && trg->getMeshDimension() == 2 - && trg->getSpaceDimension() == 3 && src->getSpaceDimension() == 3 ) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation3D2D interpolator (*this); - vector<SparseDoubleVec > matrixTranspose; - colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,sparse_matrix_part,interpMethod);//not a bug target in source. - TransposeMatrix(matrixTranspose,colSize,sparse_matrix_part); - colSize=matrixTranspose.size(); - } - else if ( src->getMeshDimension() == 1 && trg->getMeshDimension() == 2 - && trg->getSpaceDimension() == 2 && src->getSpaceDimension() == 2 ) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation2D1D interpolator (*this); - colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else if ( src->getMeshDimension() == 2 && trg->getMeshDimension() == 1 - && trg->getSpaceDimension() == 2 && src->getSpaceDimension() == 2 ) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation2D1D interpolator (*this); - vector<SparseDoubleVec > matrixTranspose; - colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,matrixTranspose,interpMethod);//not a bug target in source. - TransposeMatrix(matrixTranspose,colSize,sparse_matrix_part); - colSize=matrixTranspose.size(); - } - else if (trg->getMeshDimension() != _source_support->getMeshDimension()) - { - throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions"); - } - else if( src->getMeshDimension() == 1 - && src->getSpaceDimension() == 1 ) - { - MEDCouplingNormalizedUnstructuredMesh<1,1> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<1,1> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation1D interpolation(*this); - colSize=interpolation.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else if( trg->getMeshDimension() == 1 - && trg->getSpaceDimension() == 2 ) - { - MEDCouplingNormalizedUnstructuredMesh<2,1> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<2,1> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation2DCurve interpolation(*this); - colSize=interpolation.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else if ( trg->getMeshDimension() == 2 - && trg->getSpaceDimension() == 3 ) - { - MEDCouplingNormalizedUnstructuredMesh<3,2> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<3,2> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation3DSurf interpolator (*this); - colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else if ( trg->getMeshDimension() == 2 - && trg->getSpaceDimension() == 2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation2D interpolator (*this); - colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else if ( trg->getMeshDimension() == 3 - && trg->getSpaceDimension() == 3 ) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(trgC); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(srcC); - - INTERP_KERNEL::Interpolation3D interpolator (*this); - colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,sparse_matrix_part,interpMethod); - } - else - { - throw INTERP_KERNEL::Exception("No interpolator exists for these mesh and space dimensions!"); - } - /* Fill distributed matrix: - In sparse_matrix_part rows refer to target, and columns (=first param of map in SparseDoubleVec) - refer to source. - */ - _mapping.addContributionST(sparse_matrix_part,srcIds,srcProcId,trgIds,trgProcId); - } - - /*! - * 'procsToSendField' gives the list of procs field data has to be sent to. - * See OverlapElementLocator::computeBoundingBoxesAndTodoList() - */ - void OverlapInterpolationMatrix::prepare(const std::vector< int >& procsToSendField) - { - if(_source_support) - _mapping.prepare(procsToSendField,_target_field->getField()->getNumberOfTuplesExpected()); - else - _mapping.prepare(procsToSendField,0); - } - - void OverlapInterpolationMatrix::computeSurfacesAndDeno() - { - if(_target_field->getField()->getNature()==ConservativeVolumic) - _mapping.computeDenoConservativeVolumic(_target_field->getField()->getNumberOfTuplesExpected()); - else - throw INTERP_KERNEL::Exception("OverlapDEC: Policy not implemented yet: only ConservativeVolumic!"); -// { -// if(_target_field->getField()->getNature()==RevIntegral) -// { -// MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f; -// int orient = getOrientation(); // From InterpolationOptions inheritance -// if(orient == 2) // absolute areas -// f = _target_support->getMeasureField(true); -// else -// if(orient == 0) // relative areas -// f = _target_support->getMeasureField(false); -// else -// throw INTERP_KERNEL::Exception("OverlapDEC: orientation policy not impl. yet!"); -// _mapping.computeDenoRevIntegral(*f->getArray()); -// } -// else -// throw INTERP_KERNEL::Exception("OverlapDEC: Policy not implemented yet: only ConservativeVolumic and RevIntegral defined!"); -// } - } - - void OverlapInterpolationMatrix::multiply(double default_val) - { - _mapping.multiply(_source_field->getField(),_target_field->getField(), default_val); - } - - void OverlapInterpolationMatrix::transposeMultiply() - { - _mapping.transposeMultiply(_target_field->getField(),_source_field->getField()); - } - - void OverlapInterpolationMatrix::TransposeMatrix(const std::vector<SparseDoubleVec >& matIn, - int nbColsMatIn, std::vector<SparseDoubleVec >& matOut) - { - matOut.resize(nbColsMatIn); - int id=0; - for(std::vector<SparseDoubleVec >::const_iterator iter1=matIn.begin();iter1!=matIn.end();iter1++,id++) - for(SparseDoubleVec::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - matOut[(*iter2).first][id]=(*iter2).second; - } -} diff --git a/medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx b/medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx deleted file mode 100644 index d652ad024..000000000 --- a/medtool/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __OVERLAPINTERPOLATIONMATRIX_HXX__ -#define __OVERLAPINTERPOLATIONMATRIX_HXX__ - -#include "MPIAccessDEC.hxx" -#include "OverlapMapping.hxx" -#include "InterpolationOptions.hxx" -#include "DECOptions.hxx" - -namespace ParaMEDMEM -{ - class ParaFIELD; - class MEDCouplingPointSet; - - /*! - * Internal class, not part of the public API. - * - * Similar to InterpolationMatrix, but for the OverlapDEC instead of the InterpKernelDEC. - */ - class OverlapInterpolationMatrix : public INTERP_KERNEL::InterpolationOptions, - public DECOptions - { - public: - - OverlapInterpolationMatrix(ParaFIELD *source_field, - ParaFIELD *target_field, - const ProcessorGroup& group, - const DECOptions& dec_opt, - const InterpolationOptions& i_opt, - const OverlapElementLocator & loc); - - void keepTracksOfSourceIds(int procId, DataArrayInt *ids); - - void keepTracksOfTargetIds(int procId, DataArrayInt *ids); - - void computeLocalIntersection(const MEDCouplingPointSet *src, const DataArrayInt *srcIds, const std::string& srcMeth, int srcProcId, - const MEDCouplingPointSet *trg, const DataArrayInt *trgIds, const std::string& trgMeth, int trgProcId); - - void prepare(const std::vector< int > & procsToSendField); - - void computeSurfacesAndDeno(); - - void multiply(double default_val); - - void transposeMultiply(); - - virtual ~OverlapInterpolationMatrix(); - private: - - static void TransposeMatrix(const std::vector<SparseDoubleVec>& matIn, int nbColsMatIn, - std::vector<SparseDoubleVec>& matOut); - private: - ParaFIELD *_source_field; - ParaFIELD *_target_field; - MEDCouplingPointSet *_source_support; - MEDCouplingPointSet *_target_support; - OverlapMapping _mapping; - - const ProcessorGroup& _group; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/OverlapMapping.cxx b/medtool/src/ParaMEDMEM/OverlapMapping.cxx deleted file mode 100644 index f66dee02c..000000000 --- a/medtool/src/ParaMEDMEM/OverlapMapping.cxx +++ /dev/null @@ -1,885 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#include "OverlapMapping.hxx" -#include "MPIProcessorGroup.hxx" - -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include <numeric> -#include <algorithm> - -using namespace ParaMEDMEM; - -OverlapMapping::OverlapMapping(const ProcessorGroup& group, const OverlapElementLocator & loc): - _group(group),_locator(loc) -{ -} - -/*! - * Keeps the link between a given a proc holding source mesh data, and the corresponding cell IDs. - */ -void OverlapMapping::keepTracksOfSourceIds(int procId, DataArrayInt *ids) -{ - ids->incrRef(); - _sent_src_ids[procId] = ids; -} - -/*! - * Same as keepTracksOfSourceIds() but for target mesh data. -*/ -void OverlapMapping::keepTracksOfTargetIds(int procId, DataArrayInt *ids) -{ - ids->incrRef(); - _sent_trg_ids[procId] = ids; -} - -/*! - * This method stores in the local members the contribution coming from a matrix in format - * Target(rows)/Source(cols) for a source procId 'srcProcId' and for a target procId 'trgProcId'. - * All IDs received here (source and target) are in the format of local IDs. - * - * @param srcIds is null if the source mesh is on the local proc - * @param trgIds is null if the source mesh is on the local proc - * - * One of the 2 is necessarily null (the two can be null together) - */ -void OverlapMapping::addContributionST(const std::vector< SparseDoubleVec >& matrixST, const DataArrayInt *srcIds, int srcProcId, const DataArrayInt *trgIds, int trgProcId) -{ - _matrixes_st.push_back(matrixST); - _source_proc_id_st.push_back(srcProcId); - _target_proc_id_st.push_back(trgProcId); - if(srcIds) // source mesh part is remote <=> srcProcId != myRank - _nb_of_rcv_src_ids[srcProcId] = srcIds->getNumberOfTuples(); - else // source mesh part is local - { - std::set<int> s; - // For all source IDs (=col indices) in the sparse matrix: - for(std::vector< SparseDoubleVec >::const_iterator it1=matrixST.begin();it1!=matrixST.end();it1++) - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - s.insert((*it2).first); - vector<int> v(s.begin(), s.end()); // turn set into vector - _src_ids_zip_comp[trgProcId] = v; - } -} - -/*! - * This method is in charge to send matrices in AlltoAll mode. - * - * 'procsToSendField' gives the list of procs field data has to be sent to. - * See OverlapElementLocator::computeBoundingBoxesAndTodoList() - * - * After the call of this method, 'this' contains the matrixST for all source cells of the current proc - */ -void OverlapMapping::prepare(const std::vector< int >& procsToSendField, int nbOfTrgElems) -{ -#ifdef DEC_DEBUG - printMatrixesST(); -#endif - - CommInterface commInterface=_group.getCommInterface(); - const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group); - const MPI_Comm *comm=group->getComm(); - int grpSize=_group.size(); - INTERP_KERNEL::AutoPtr<int> nbsend=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbsend2=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbsend3=new int[grpSize]; - std::fill<int *>(nbsend,nbsend+grpSize,0); - int myProcId=_group.myRank(); - for(std::size_t i=0;i<_matrixes_st.size();i++) - if(_source_proc_id_st[i]==myProcId) - nbsend[_target_proc_id_st[i]]=_matrixes_st[i].size(); - INTERP_KERNEL::AutoPtr<int> nbrecv=new int[grpSize]; - commInterface.allToAll(nbsend,1,MPI_INT,nbrecv,1,MPI_INT,*comm); - //exchanging matrix - //first exchanging offsets+ids_source - INTERP_KERNEL::AutoPtr<int> nbrecv1=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbrecv2=new int[grpSize]; - // - int *tmp=0; - serializeMatrixStep0ST(nbrecv, - tmp,nbsend2,nbsend3, - nbrecv1,nbrecv2); - INTERP_KERNEL::AutoPtr<int> bigArr=tmp; - INTERP_KERNEL::AutoPtr<int> bigArrRecv=new int[nbrecv2[grpSize-1]+nbrecv1[grpSize-1]]; - commInterface.allToAllV(bigArr,nbsend2,nbsend3,MPI_INT, - bigArrRecv,nbrecv1,nbrecv2,MPI_INT, - *comm);// sending ids of sparse matrix (n+1 elems) - //second phase echange target ids - std::fill<int *>(nbsend2,nbsend2+grpSize,0); - INTERP_KERNEL::AutoPtr<int> nbrecv3=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbrecv4=new int[grpSize]; - double *tmp2=0; - int lgthOfArr=serializeMatrixStep1ST(nbrecv,bigArrRecv,nbrecv1,nbrecv2, - tmp,tmp2, - nbsend2,nbsend3,nbrecv3,nbrecv4); - INTERP_KERNEL::AutoPtr<int> bigArr2=tmp; - INTERP_KERNEL::AutoPtr<double> bigArrD2=tmp2; - INTERP_KERNEL::AutoPtr<int> bigArrRecv2=new int[lgthOfArr]; - INTERP_KERNEL::AutoPtr<double> bigArrDRecv2=new double[lgthOfArr]; - commInterface.allToAllV(bigArr2,nbsend2,nbsend3,MPI_INT, - bigArrRecv2,nbrecv3,nbrecv4,MPI_INT, - *comm); - commInterface.allToAllV(bigArrD2,nbsend2,nbsend3,MPI_DOUBLE, - bigArrDRecv2,nbrecv3,nbrecv4,MPI_DOUBLE, - *comm); - //finishing - unserializationST(nbOfTrgElems,nbrecv,bigArrRecv,nbrecv1,nbrecv2, - bigArrRecv2,bigArrDRecv2,nbrecv3,nbrecv4); - - //finish to fill _the_matrix_st with already in place matrix in _matrixes_st (local computation) - finishToFillFinalMatrixST(); - - //updating _src_ids_zip_st2 and _src_ids_zip_st2 with received matrix. - fillSourceIdsZipReceivedForMultiply(); - // Prepare proc list for future field data exchange (mutliply()): - _proc_ids_to_send_vector_st = procsToSendField; - // Make some space on local proc: - _matrixes_st.clear(); - -#ifdef DEC_DEBUG - printTheMatrix(); -#endif -} - -///*! -// * Compute denominators for IntegralGlobConstraint interp. -// * TO BE REVISED: needs another communication since some bits are held non locally -// */ -//void OverlapMapping::computeDenoGlobConstraint() -//{ -// _the_deno_st.clear(); -// std::size_t sz1=_the_matrix_st.size(); -// _the_deno_st.resize(sz1); -// for(std::size_t i=0;i<sz1;i++) -// { -// std::size_t sz2=_the_matrix_st[i].size(); -// _the_deno_st[i].resize(sz2); -// for(std::size_t j=0;j<sz2;j++) -// { -// double sum=0; -// SparseDoubleVec& mToFill=_the_deno_st[i][j]; -// const SparseDoubleVec& m=_the_matrix_st[i][j]; -// for(SparseDoubleVec::const_iterator it=m.begin();it!=m.end();it++) -// sum+=(*it).second; -// for(SparseDoubleVec::const_iterator it=m.begin();it!=m.end();it++) -// mToFill[(*it).first]=sum; -// } -// } -// printDenoMatrix(); -//} - -///*! Compute integral denominators -// * TO BE REVISED: needs another communication since some source areas are held non locally -// */ -//void OverlapMapping::computeDenoIntegral() -//{ -// _the_deno_st.clear(); -// std::size_t sz1=_the_matrix_st.size(); -// _the_deno_st.resize(sz1); -// for(std::size_t i=0;i<sz1;i++) -// { -// std::size_t sz2=_the_matrix_st[i].size(); -// _the_deno_st[i].resize(sz2); -// for(std::size_t j=0;j<sz2;j++) -// { -// SparseDoubleVec& mToFill=_the_deno_st[i][j]; -// for(SparseDoubleVec::const_iterator it=mToFill.begin();it!=mToFill.end();it++) -// mToFill[(*it).first] = sourceAreas; -// } -// } -// printDenoMatrix(); -//} - -/*! Compute rev integral denominators - */ -void OverlapMapping::computeDenoRevIntegral(const DataArrayDouble & targetAreas) -{ - _the_deno_st.clear(); - std::size_t sz1=_the_matrix_st.size(); - _the_deno_st.resize(sz1); - const double * targetAreasP = targetAreas.getConstPointer(); - for(std::size_t i=0;i<sz1;i++) - { - std::size_t sz2=_the_matrix_st[i].size(); - _the_deno_st[i].resize(sz2); - for(std::size_t j=0;j<sz2;j++) - { - SparseDoubleVec& mToFill=_the_deno_st[i][j]; - SparseDoubleVec& mToIterate=_the_matrix_st[i][j]; - for(SparseDoubleVec::const_iterator it=mToIterate.begin();it!=mToIterate.end();it++) - mToFill[(*it).first] = targetAreasP[j]; - } - } -// printDenoMatrix(); -} - - -/*! - * Compute denominators for ConvervativeVolumic interp. - */ -void OverlapMapping::computeDenoConservativeVolumic(int nbOfTuplesTrg) -{ - int myProcId=_group.myRank(); - // - _the_deno_st.clear(); - std::size_t sz1=_the_matrix_st.size(); - _the_deno_st.resize(sz1); - std::vector<double> deno(nbOfTuplesTrg); - // Fills in the vector indexed by target cell ID: - for(std::size_t i=0;i<sz1;i++) - { - const std::vector< SparseDoubleVec >& mat=_the_matrix_st[i]; - int curSrcId=_the_matrix_st_source_proc_id[i]; - map < int, MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator isItem1 = _sent_trg_ids.find(curSrcId); - int rowId=0; - if(isItem1==_sent_trg_ids.end() || curSrcId==myProcId) // Local computation: simple, because rowId of mat are directly target cell ids. - { - for(std::vector< SparseDoubleVec >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - deno[rowId]+=(*it2).second; - } - else // matrix was received, remote computation - { - const DataArrayInt *trgIds = (*isItem1).second; - const int *trgIds2=trgIds->getConstPointer(); - for(std::vector< SparseDoubleVec >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - deno[trgIds2[rowId]]+=(*it2).second; - } - } - // Broadcast the vector into a structure similar to the initial sparse matrix of numerators: - for(std::size_t i=0;i<sz1;i++) - { - int rowId=0; - const std::vector< SparseDoubleVec >& mat=_the_matrix_st[i]; - int curSrcId=_the_matrix_st_source_proc_id[i]; - map < int, MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator isItem1 = _sent_trg_ids.find(curSrcId); - std::vector< SparseDoubleVec >& denoM=_the_deno_st[i]; - denoM.resize(mat.size()); - if(isItem1==_sent_trg_ids.end() || curSrcId==myProcId)//item1 of step2 main algo. Simple, because rowId of mat are directly target ids. - { - int rowId=0; - for(std::vector< SparseDoubleVec >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - denoM[rowId][(*it2).first]=deno[rowId]; - } - else - { - const DataArrayInt *trgIds = (*isItem1).second; - const int *trgIds2=trgIds->getConstPointer(); - for(std::vector< SparseDoubleVec >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - denoM[rowId][(*it2).first]=deno[trgIds2[rowId]]; - } - } -// printDenoMatrix(); -} - -/*! - * This method performs step #0/3 in serialization process. - * \param count tells specifies nb of elems to send to corresponding proc id. size equal to _group.size(). - * \param offsets tells for a proc i where to start serialize#0 matrix. size equal to _group.size(). - * \param nbOfElemsSrc of size _group.size(). Comes from previous all2all call. tells how many srcIds per proc contains matrix for current proc. - */ -void OverlapMapping::serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigArr, int *count, int *offsets, - int *countForRecv, int *offsetsForRecv) const -{ - int grpSize=_group.size(); - std::fill<int *>(count,count+grpSize,0); - int szz=0; - int myProcId=_group.myRank(); - for(std::size_t i=0;i<_matrixes_st.size();i++) - { - if(_source_proc_id_st[i]==myProcId)// && _target_proc_id_st[i]!=myProcId - { - count[_target_proc_id_st[i]]=_matrixes_st[i].size()+1; - szz+=_matrixes_st[i].size()+1; - } - } - bigArr=new int[szz]; - offsets[0]=0; - for(int i=1;i<grpSize;i++) - offsets[i]=offsets[i-1]+count[i-1]; - for(std::size_t i=0;i<_matrixes_st.size();i++) - { - if(_source_proc_id_st[i]==myProcId) - { - int start=offsets[_target_proc_id_st[i]]; - int *work=bigArr+start; - *work=0; - const std::vector< SparseDoubleVec >& mat=_matrixes_st[i]; - for(std::vector< SparseDoubleVec >::const_iterator it=mat.begin();it!=mat.end();it++,work++) - work[1]=work[0]+(*it).size(); - } - } - // - offsetsForRecv[0]=0; - for(int i=0;i<grpSize;i++) - { - if(nbOfElemsSrc[i]>0) - countForRecv[i]=nbOfElemsSrc[i]+1; - else - countForRecv[i]=0; - if(i>0) - offsetsForRecv[i]=offsetsForRecv[i-1]+countForRecv[i-1]; - } -} - -/*! - * This method performs step#1 and step#2/3. It returns the size of expected array to get allToAllV. - * It is where the locally computed matrices are serialized to be sent to adequate final proc. - */ -int OverlapMapping::serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *recvStep0, const int *countStep0, const int *offsStep0, - int *&bigArrI, double *&bigArrD, int *count, int *offsets, - int *countForRecv, int *offsForRecv) const -{ - int grpSize=_group.size(); - int myProcId=_group.myRank(); - offsForRecv[0]=0; - int szz=0; - for(int i=0;i<grpSize;i++) - { - if(nbOfElemsSrc[i]!=0) - countForRecv[i]=recvStep0[offsStep0[i]+nbOfElemsSrc[i]]; - else - countForRecv[i]=0; - szz+=countForRecv[i]; - if(i>0) - offsForRecv[i]=offsForRecv[i-1]+countForRecv[i-1]; - } - // - std::fill(count,count+grpSize,0); - offsets[0]=0; - int fullLgth=0; - for(std::size_t i=0;i<_matrixes_st.size();i++) - { - if(_source_proc_id_st[i]==myProcId) - { - const std::vector< SparseDoubleVec >& mat=_matrixes_st[i]; - int lgthToSend=0; - for(std::vector< SparseDoubleVec >::const_iterator it=mat.begin();it!=mat.end();it++) - lgthToSend+=(*it).size(); - count[_target_proc_id_st[i]]=lgthToSend; - fullLgth+=lgthToSend; - } - } - for(int i=1;i<grpSize;i++) - offsets[i]=offsets[i-1]+count[i-1]; - // - bigArrI=new int[fullLgth]; - bigArrD=new double[fullLgth]; - // feeding arrays - fullLgth=0; - for(std::size_t i=0;i<_matrixes_st.size();i++) - { - if(_source_proc_id_st[i]==myProcId) - { - const std::vector< SparseDoubleVec >& mat=_matrixes_st[i]; - for(std::vector< SparseDoubleVec >::const_iterator it1=mat.begin();it1!=mat.end();it1++) - { - int j=0; - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,j++) - { - bigArrI[fullLgth+j]=(*it2).first; - bigArrD[fullLgth+j]=(*it2).second; - } - fullLgth+=(*it1).size(); - } - } - } - return szz; -} - -/*! - * This is the last step after all2Alls for matrix exchange. - * _the_matrix_st is the final matrix : - * - The first entry is srcId in current proc. - * - The second is the pseudo id of source proc (correspondance with true id is in attribute _the_matrix_st_source_proc_id and _the_matrix_st_source_ids) - * - the third is the srcId in the pseudo source proc - */ -void OverlapMapping::unserializationST(int nbOfTrgElems, - const int *nbOfElemsSrcPerProc,//first all2all - const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs,//2nd all2all - const int *bigArrRecv2, const double *bigArrDRecv2, const int *bigArrRecv2Count, const int *bigArrRecv2Offs)//3rd and 4th all2alls -{ - _the_matrix_st.clear(); - _the_matrix_st_source_proc_id.clear(); - // - int grpSize=_group.size(); - for(int i=0;i<grpSize;i++) - if(nbOfElemsSrcPerProc[i]!=0) - _the_matrix_st_source_proc_id.push_back(i); - int nbOfPseudoProcs=_the_matrix_st_source_proc_id.size();//_the_matrix_st_target_proc_id.size() contains number of matrix fetched remotely whose sourceProcId==myProcId - _the_matrix_st.resize(nbOfPseudoProcs); - // - int j=0; - for(int i=0;i<grpSize;i++) - if(nbOfElemsSrcPerProc[i]!=0) - { - _the_matrix_st[j].resize(nbOfElemsSrcPerProc[i]); - for(int k=0;k<nbOfElemsSrcPerProc[i];k++) - { - int offs=bigArrRecv[bigArrRecvOffs[i]+k]; - int lgthOfMap=bigArrRecv[bigArrRecvOffs[i]+k+1]-offs; - for(int l=0;l<lgthOfMap;l++) - _the_matrix_st[j][k][bigArrRecv2[bigArrRecv2Offs[i]+offs+l]]=bigArrDRecv2[bigArrRecv2Offs[i]+offs+l]; - } - j++; - } -} - -/*! - * This method should be called when all remote matrix with sourceProcId==thisProcId have been retrieved and are - * in 'this->_the_matrix_st' and 'this->_the_matrix_st_target_proc_id' and 'this->_the_matrix_st_target_ids'. - * This method finish the job of filling 'this->_the_matrix_st' and 'this->_the_matrix_st_target_proc_id' - * by putting candidates in 'this->_matrixes_st' into them (i.e. local computation result). - */ -void OverlapMapping::finishToFillFinalMatrixST() -{ - int myProcId=_group.myRank(); - int sz=_matrixes_st.size(); - int nbOfEntryToAdd=0; - for(int i=0;i<sz;i++) - if(_source_proc_id_st[i]!=myProcId) - nbOfEntryToAdd++; - if(nbOfEntryToAdd==0) - return ; - int oldNbOfEntry=_the_matrix_st.size(); - int newNbOfEntry=oldNbOfEntry+nbOfEntryToAdd; - _the_matrix_st.resize(newNbOfEntry); - int j=oldNbOfEntry; - for(int i=0;i<sz;i++) - if(_source_proc_id_st[i]!=myProcId) - { - const std::vector<SparseDoubleVec >& mat=_matrixes_st[i]; - _the_matrix_st[j]=mat; - _the_matrix_st_source_proc_id.push_back(_source_proc_id_st[i]); - j++; - } -} - - -/*! - * This method performs a transpose multiply of 'fieldInput' and put the result into 'fieldOutput'. - * 'fieldInput' is expected to be the sourcefield and 'fieldOutput' the targetfield. - */ -void OverlapMapping::multiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput, double default_val) const -{ - using namespace std; - - int nbOfCompo=fieldInput->getNumberOfComponents();//to improve same number of components to test - CommInterface commInterface=_group.getCommInterface(); - const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group); - const MPI_Comm *comm=group->getComm(); - int grpSize=_group.size(); - int myProcID=_group.myRank(); - // - INTERP_KERNEL::AutoPtr<int> nbsend=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbsend2=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbrecv=new int[grpSize]; - INTERP_KERNEL::AutoPtr<int> nbrecv2=new int[grpSize]; - fill<int *>(nbsend,nbsend+grpSize,0); - fill<int *>(nbrecv,nbrecv+grpSize,0); - nbsend2[0]=0; - nbrecv2[0]=0; - vector<double> valsToSend; - - /* - * FIELD VALUE XCHGE: - * We call the 'BB source IDs' (bounding box source IDs) the set of source cell IDs transmitted just based on the bounding box information. - * This is potentially bigger than what is finally in the interp matrix and this is stored in _sent_src_ids. - * We call 'interp source IDs' the set of source cell IDs with non null entries in the interp matrix. This is a sub-set of the above. - */ - for(int procID=0;procID<grpSize;procID++) - { - /* SENDING part: compute field values to be SENT (and how many of them) - * - for all proc 'procID' in group - * * if procID == myProcID, send nothing - * * elif 'procID' in _proc_ids_to_send_vector_st (computed from the BB intersection) - * % if myProcID computed the job (myProcID, procID) - * => send only 'interp source IDs' field values (i.e. IDs stored in _src_ids_zip_comp) - * % else (=we just sent mesh data to procID, but have never seen the matrix, i.e. matrix was computed remotely by procID) - * => send 'BB source IDs' set of field values (i.e. IDs stored in _sent_src_ids) - */ - if (procID == myProcID) - nbsend[procID] = 0; - else - if(find(_proc_ids_to_send_vector_st.begin(),_proc_ids_to_send_vector_st.end(),procID)!=_proc_ids_to_send_vector_st.end()) - { - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> vals; - if(_locator.isInMyTodoList(myProcID, procID)) - { - map<int, vector<int> >::const_iterator isItem11 = _src_ids_zip_comp.find(procID); - if (isItem11 == _src_ids_zip_comp.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: SEND: unexpected end iterator in _src_ids_zip_comp!"); - const vector<int> & v = (*isItem11).second; - int sz = v.size(); - vals=fieldInput->getArray()->selectByTupleId(&(v[0]),&(v[0])+sz); - } - else - { - map < int, MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator isItem11 = _sent_src_ids.find( procID ); - if (isItem11 == _sent_src_ids.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: SEND: unexpected end iterator in _sent_src_ids!"); - vals=fieldInput->getArray()->selectByTupleId(*(*isItem11).second); - } - nbsend[procID] = vals->getNbOfElems(); - valsToSend.insert(valsToSend.end(),vals->getConstPointer(),vals->getConstPointer()+nbsend[procID]); - } - - /* RECEIVE: compute number of field values to be RECEIVED - * - for all proc 'procID' in group - * * if procID == myProcID, rcv nothing - * * elif 'procID' in _proc_ids_to_recv_vector_st (computed from BB intersec) - * % if myProcID computed the job (procID, myProcID) - * => receive full set ('BB source IDs') of field data from proc #procID which has never seen the matrix - * i.e. prepare to receive the numb in _nb_of_rcv_src_ids - * % else (=we did NOT compute the job, hence procID has, and knows the matrix) - * => receive 'interp source IDs' set of field values - */ - const std::vector< int > & _proc_ids_to_recv_vector_st = _the_matrix_st_source_proc_id; - if (procID == myProcID) - nbrecv[procID] = 0; - else - if(find(_proc_ids_to_recv_vector_st.begin(),_proc_ids_to_recv_vector_st.end(),procID)!=_proc_ids_to_recv_vector_st.end()) - { - if(_locator.isInMyTodoList(procID, myProcID)) - { - map <int,int>::const_iterator isItem11 = _nb_of_rcv_src_ids.find(procID); - if (isItem11 == _nb_of_rcv_src_ids.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: RCV: unexpected end iterator in _nb_of_rcv_src_ids!"); - nbrecv[procID] = (*isItem11).second; - } - else - { - map<int, vector<int> >::const_iterator isItem11 = _src_ids_zip_recv.find(procID); - if (isItem11 == _src_ids_zip_recv.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: RCV: unexpected end iterator in _src_ids_zip_recv!"); - nbrecv[procID] = (*isItem11).second.size()*nbOfCompo; - } - } - } - // Compute offsets in the sending/receiving array. - for(int i=1;i<grpSize;i++) - { - nbsend2[i]=nbsend2[i-1]+nbsend[i-1]; - nbrecv2[i]=nbrecv2[i-1]+nbrecv[i-1]; - } - INTERP_KERNEL::AutoPtr<double> bigArr=new double[nbrecv2[grpSize-1]+nbrecv[grpSize-1]]; - -#ifdef DEC_DEBUG - stringstream scout; - scout << "(" << myProcID << ") nbsend :" << nbsend[0] << "," << nbsend[1] << "," << nbsend[2] << "\n"; - scout << "(" << myProcID << ") nbrecv :" << nbrecv[0] << "," << nbrecv[1] << "," << nbrecv[2] << "\n"; - scout << "(" << myProcID << ") valsToSend: "; - for (int iii=0; iii<valsToSend.size(); iii++) - scout << ", " << valsToSend[iii]; - cout << scout.str() << "\n"; -#endif - - /* - * *********************** ALL-TO-ALL - */ - commInterface.allToAllV(&valsToSend[0],nbsend,nbsend2,MPI_DOUBLE, - bigArr,nbrecv,nbrecv2,MPI_DOUBLE,*comm); -#ifdef DEC_DEBUG - MPI_Barrier(MPI_COMM_WORLD); - scout << "(" << myProcID << ") bigArray: "; - for (int iii=0; iii<nbrecv2[grpSize-1]+nbrecv[grpSize-1]; iii++) - scout << ", " << bigArr[iii]; - cout << scout.str() << "\n"; -#endif - - /* - * TARGET FIELD COMPUTATION (matrix-vec computation) - */ - fieldOutput->getArray()->fillWithZero(); - INTERP_KERNEL::AutoPtr<double> tmp=new double[nbOfCompo]; - - // By default field value set to default value - so mark which cells are hit - INTERP_KERNEL::AutoPtr<bool> hit_cells = new bool[fieldOutput->getNumberOfTuples()]; - - for(vector<int>::const_iterator itProc=_the_matrix_st_source_proc_id.begin(); itProc != _the_matrix_st_source_proc_id.end();itProc++) - // For each source processor corresponding to a locally held matrix: - { - int srcProcID = *itProc; - int id = distance(_the_matrix_st_source_proc_id.begin(),itProc); - const vector< SparseDoubleVec >& mat =_the_matrix_st[id]; - const vector< SparseDoubleVec >& deno = _the_deno_st[id]; - - /* FINAL MULTIPLICATION - * * if srcProcID == myProcID, local multiplication without any mapping - * => for all target cell ID 'tgtCellID' - * => for all src cell ID 'srcCellID' in the sparse vector - * => tgtFieldLocal[tgtCellID] += srcFieldLocal[srcCellID] * matrix[tgtCellID][srcCellID] / deno[tgtCellID][srcCellID] - */ - if (srcProcID == myProcID) - { - int nbOfTrgTuples=mat.size(); - double * targetBase = fieldOutput->getArray()->getPointer(); - for(int j=0; j<nbOfTrgTuples; j++) - { - const SparseDoubleVec& mat1=mat[j]; - const SparseDoubleVec& deno1=deno[j]; - SparseDoubleVec::const_iterator it5=deno1.begin(); - const double * localSrcField = fieldInput->getArray()->getConstPointer(); - double * targetPt = targetBase+j*nbOfCompo; - for(SparseDoubleVec::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it5++) - { - // Apply the multiplication for all components: - double ratio = (*it3).second/(*it5).second; - transform(localSrcField+((*it3).first)*nbOfCompo, - localSrcField+((*it3).first+1)*nbOfCompo, - (double *)tmp, - bind2nd(multiplies<double>(),ratio) ); - // Accumulate with current value: - transform((double *)tmp,(double *)tmp+nbOfCompo,targetPt,targetPt,plus<double>()); - hit_cells[j] = true; - } - } - } - - if(nbrecv[srcProcID]<=0) // also covers the preceding 'if' - continue; - - /* * if something was received - * % if received matrix (=we didn't compute the job), this means that : - * 1. we sent part of our targetIDs to srcProcID before, so that srcProcId can do the computation. - * 2. srcProcID has sent us only the 'interp source IDs' field values - * => invert _src_ids_zip_recv -> 'revert_zip' - * => for all target cell ID 'tgtCellID' - * => mappedTgtID = _sent_trg_ids[srcProcID][tgtCellID] - * => for all src cell ID 'srcCellID' in the sparse vector - * => idx = revert_zip[srcCellID] - * => tgtFieldLocal[mappedTgtID] += rcvValue[srcProcID][idx] * matrix[tgtCellID][srcCellID] / deno[tgtCellID][srcCellID] - */ - if(!_locator.isInMyTodoList(srcProcID, myProcID)) - { - // invert _src_ids_zip_recv - map<int,int> revert_zip; - map<int, vector<int> >::const_iterator it11= _src_ids_zip_recv.find(srcProcID); - if (it11 == _src_ids_zip_recv.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: MULTIPLY: unexpected end iterator in _src_ids_zip_recv!"); - const vector<int> & vec = (*it11).second; - int newId=0; - for(vector<int>::const_iterator it=vec.begin();it!=vec.end();it++,newId++) - revert_zip[*it]=newId; - map < int, MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator isItem24 = _sent_trg_ids.find(srcProcID); - if (isItem24 == _sent_trg_ids.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: MULTIPLY: unexpected end iterator in _sent_trg_ids!"); - const DataArrayInt *tgrIdsDA = (*isItem24).second; - const int *tgrIds = tgrIdsDA->getConstPointer(); - - int nbOfTrgTuples=mat.size(); - double * targetBase = fieldOutput->getArray()->getPointer(); - for(int j=0;j<nbOfTrgTuples;j++) - { - const SparseDoubleVec& mat1=mat[j]; - const SparseDoubleVec& deno1=deno[j]; - SparseDoubleVec::const_iterator it5=deno1.begin(); - double * targetPt = targetBase+tgrIds[j]*nbOfCompo; - for(SparseDoubleVec::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it5++) - { - map<int,int>::const_iterator it4=revert_zip.find((*it3).first); - if(it4==revert_zip.end()) - throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: MULTIPLY: unexpected end iterator in revert_zip!"); - double ratio = (*it3).second/(*it5).second; - transform(bigArr+nbrecv2[srcProcID]+((*it4).second)*nbOfCompo, - bigArr+nbrecv2[srcProcID]+((*it4).second+1)*nbOfCompo, - (double *)tmp, - bind2nd(multiplies<double>(),ratio) ); - transform((double *)tmp,(double *)tmp+nbOfCompo,targetPt,targetPt,plus<double>()); - hit_cells[tgrIds[j]] = true; - } - } - } - else - /* % else (=we computed the job and we received the 'BB source IDs' set of source field values) - * => for all target cell ID 'tgtCellID' - * => for all src cell ID 'srcCellID' in the sparse vector - * => tgtFieldLocal[tgtCellID] += rcvValue[srcProcID][srcCellID] * matrix[tgtCellID][srcCellID] / deno[tgtCellID][srcCellID] - */ - { - // Same loop as in the case srcProcID == myProcID, except that instead of working on local field data, we work on bigArr - int nbOfTrgTuples=mat.size(); - double * targetBase = fieldOutput->getArray()->getPointer(); - for(int j=0;j<nbOfTrgTuples;j++) - { - const SparseDoubleVec& mat1=mat[j]; - const SparseDoubleVec& deno1=deno[j]; - SparseDoubleVec::const_iterator it5=deno1.begin(); - double * targetPt = targetBase+j*nbOfCompo; - for(SparseDoubleVec::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it5++) - { - // Apply the multiplication for all components: - double ratio = (*it3).second/(*it5).second; - transform(bigArr+nbrecv2[srcProcID]+((*it3).first)*nbOfCompo, - bigArr+nbrecv2[srcProcID]+((*it3).first+1)*nbOfCompo, - (double *)tmp, - bind2nd(multiplies<double>(),ratio)); - // Accumulate with current value: - transform((double *)tmp,(double *)tmp+nbOfCompo,targetPt,targetPt,plus<double>()); - hit_cells[j] = true; - } - } - } - } - - // Fill in default values for cells which haven't been hit: - int i = 0; - for(bool * hit_cells_ptr=hit_cells; i< fieldOutput->getNumberOfTuples(); hit_cells_ptr++,i++) - if (!(*hit_cells_ptr)) - { - double * targetPt=fieldOutput->getArray()->getPointer(); - fill(targetPt+i*nbOfCompo, targetPt+(i+1)*nbOfCompo, default_val); - } -} - -/*! - * This method performs a transpose multiply of 'fieldInput' and put the result into 'fieldOutput'. - * 'fieldInput' is expected to be the targetfield and 'fieldOutput' the sourcefield. - */ -void OverlapMapping::transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) -{ -} - -/*! - * This method should be called immediately after _the_matrix_st has been filled with remote computed matrix - * put in this proc for Matrix-Vector. - * It fills _src_ids_zip_recv (see member doc) - */ -void OverlapMapping::fillSourceIdsZipReceivedForMultiply() -{ - /* When it is called, only the bits received from other processors (i.e. the remotely executed jobs) are in the - big matrix _the_matrix_st. */ - - CommInterface commInterface=_group.getCommInterface(); - int myProcId=_group.myRank(); - int nbOfMatrixRecveived=_the_matrix_st_source_proc_id.size(); - for(int i=0;i<nbOfMatrixRecveived;i++) - { - int curSrcProcId=_the_matrix_st_source_proc_id[i]; - if(curSrcProcId!=myProcId) // if =, data has been populated by addContributionST() - { - const std::vector< SparseDoubleVec >& mat=_the_matrix_st[i]; - std::set<int> s; - for(std::vector< SparseDoubleVec >::const_iterator it1=mat.begin();it1!=mat.end();it1++) - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - s.insert((*it2).first); - vector<int> vec(s.begin(),s.end()); - _src_ids_zip_recv[curSrcProcId] = vec; - } - } -} - -#ifdef DEC_DEBUG - void OverlapMapping::printTheMatrix() const - { - CommInterface commInterface=_group.getCommInterface(); - const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group); - const MPI_Comm *comm=group->getComm(); - int grpSize=_group.size(); - int myProcId=_group.myRank(); - std::stringstream oscerr; - int nbOfMat=_the_matrix_st.size(); - oscerr << "(" << myProcId << ") I hold " << nbOfMat << " matrix(ces) : "<< std::endl; - for(int i=0;i<nbOfMat;i++) - { - oscerr << " - Matrix #" << i << " coming from source proc #" << _the_matrix_st_source_proc_id[i] << ":\n "; - const std::vector< SparseDoubleVec >& locMat=_the_matrix_st[i]; - int j = 0; - for(std::vector< SparseDoubleVec >::const_iterator it1=locMat.begin();it1!=locMat.end();it1++, j++) - { - oscerr << " Target Cell #" << j; - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - oscerr << " (" << (*it2).first << "," << (*it2).second << "), "; - oscerr << std::endl; - } - } - oscerr << "*********" << std::endl; - - // Hope this will be flushed in one go: - std::cerr << oscerr.str() << std::endl; -// if(myProcId != 0) -// MPI_Barrier(MPI_COMM_WORLD); - } - - void OverlapMapping::printMatrixesST() const - { - CommInterface commInterface=_group.getCommInterface(); - const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group); - const MPI_Comm *comm=group->getComm(); - int grpSize=_group.size(); - int myProcId=_group.myRank(); - std::stringstream oscerr; - int nbOfMat=_matrixes_st.size(); - oscerr << "(" << myProcId << ") I hold " << nbOfMat << " LOCAL matrix(ces) : "<< std::endl; - for(int i=0;i<nbOfMat;i++) - { - oscerr << " - Matrix #" << i << ": (source proc #" << _source_proc_id_st[i] << " / tgt proc#" << _target_proc_id_st[i] << "): \n"; - const std::vector< SparseDoubleVec >& locMat=_matrixes_st[i]; - int j = 0; - for(std::vector< SparseDoubleVec >::const_iterator it1=locMat.begin();it1!=locMat.end();it1++, j++) - { - oscerr << " Target Cell #" << j; - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - oscerr << " (" << (*it2).first << "," << (*it2).second << "), "; - oscerr << std::endl; - } - } - oscerr << "*********" << std::endl; - - // Hope this will be flushed in one go: - std::cerr << oscerr.str() << std::endl; - } - - void OverlapMapping::printDenoMatrix() const - { - CommInterface commInterface=_group.getCommInterface(); - const MPIProcessorGroup *group=static_cast<const MPIProcessorGroup*>(&_group); - const MPI_Comm *comm=group->getComm(); - int grpSize=_group.size(); - int myProcId=_group.myRank(); - std::stringstream oscerr; - int nbOfMat=_the_deno_st.size(); - oscerr << "(" << myProcId << ") I hold " << nbOfMat << " DENOMINATOR matrix(ces) : "<< std::endl; - for(int i=0;i<nbOfMat;i++) - { - oscerr << " - Matrix #" << i << " coming from source proc #" << _the_matrix_st_source_proc_id[i] << ": \n"; - const std::vector< SparseDoubleVec >& locMat=_the_deno_st[i]; - int j = 0; - for(std::vector< SparseDoubleVec >::const_iterator it1=locMat.begin();it1!=locMat.end();it1++, j++) - { - oscerr << " Target Cell #" << j; - for(SparseDoubleVec::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - oscerr << " (" << (*it2).first << "," << (*it2).second << "), "; - oscerr << std::endl; - } - } - oscerr << "*********" << std::endl; - - // Hope this will be flushed in one go: - std::cerr << oscerr.str() << std::endl; - } -#endif diff --git a/medtool/src/ParaMEDMEM/OverlapMapping.hxx b/medtool/src/ParaMEDMEM/OverlapMapping.hxx deleted file mode 100644 index ab9cb3139..000000000 --- a/medtool/src/ParaMEDMEM/OverlapMapping.hxx +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -#ifndef __OVERLAPMAPPING_HXX__ -#define __OVERLAPMAPPING_HXX__ - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "OverlapElementLocator.hxx" - -#include <vector> -#include <map> -//#define DEC_DEBUG - -namespace ParaMEDMEM -{ - class ProcessorGroup; - class DataArrayInt; - class MEDCouplingFieldDouble; - - using namespace std; - typedef map<int,double> SparseDoubleVec; - - /*! - * Internal class, not part of the public API. - * - * Used by the impl of OverlapInterpolationMatrix, plays an equivalent role than what the NxM_Mapping - * does for the InterpolationMatrix. - */ - class OverlapMapping - { - public: - - OverlapMapping(const ProcessorGroup& group, const OverlapElementLocator& locator); - void keepTracksOfSourceIds(int procId, DataArrayInt *ids); - void keepTracksOfTargetIds(int procId, DataArrayInt *ids); - void addContributionST(const vector< SparseDoubleVec >& matrixST, const DataArrayInt *srcIds, int srcProcId, const DataArrayInt *trgIds, int trgProcId); - void prepare(const vector< int >& procsToSendField, int nbOfTrgElems); - void computeDenoConservativeVolumic(int nbOfTuplesTrg); -// void computeDenoIntegralGlobConstraint(); -// void computeDenoIntegral(); - void computeDenoRevIntegral(const DataArrayDouble & targetAreas); - // - void multiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput, double default_val) const; - void transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput); - private: - void serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigArr, int *count, int *offsets, - int *countForRecv, int *offsetsForRecv) const; - int serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *recvStep0, const int *countStep0, const int *offsStep0, - int *&bigArrI, double *&bigArrD, int *count, int *offsets, - int *countForRecv, int *offsForRecv) const; - void unserializationST(int nbOfTrgElems, const int *nbOfElemsSrcPerProc, const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs, - const int *bigArrRecv2, const double *bigArrDRecv2, const int *bigArrRecv2Count, const int *bigArrRecv2Offs); - void finishToFillFinalMatrixST(); - void fillSourceIdsZipReceivedForMultiply(); - -#ifdef DEC_DEBUG - void printMatrixesST() const; - void printTheMatrix() const; - void printDenoMatrix() const; -#endif - private: - const ProcessorGroup &_group; - const OverlapElementLocator& _locator; - - /**! Map of DAInt of cell identifiers. For a proc ID i, - * gives an old2new map for the local part of the source mesh that has been sent to proc#i, just based on the - * bounding box computation (this is potentially a larger set than what is finally in the interp matrix). - * Second member gives proc ID. */ - map < int, MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > _sent_src_ids; - - //! See _sent_src_ids. Same for target mesh. - map < int, MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > _sent_trg_ids; - - /**! Vector of matrixes (partial interpolation ratios), result of the LOCAL interpolator run. - * Indexing shared with _source_proc_id_st, and _target_proc_id_st. */ - vector< vector< SparseDoubleVec > > _matrixes_st; - //! See _matrixes_st - vec of source proc IDs - vector< int > _source_proc_id_st; - //! See _matrixes_st - vec of target proc IDs - vector< int > _target_proc_id_st; - - /**! Number of received source mesh IDs at mesh data exchange. - Counting the number of IDs suffices, as we just need this to prepare the receive side, when doing the final vector matrix multiplication. - First dimension is the remote proc ID from which we received. */ - map <int, int > _nb_of_rcv_src_ids; - - /**! Specifies for each (target) remote proc ID (first dim of the map) the corresponding - * source cell IDs to use. - * This information is stored from the *locally* COMPuted matrices, and corresponds hence to field value that will need to - * sent later on, if this matrix bit itself is sent aways. */ - map<int, vector<int> > _src_ids_zip_comp; - - /**! Same idea as _src_ids_zip_comp above, but for RECEIVED matrix. */ - map<int, vector<int> > _src_ids_zip_recv; - - /**! THE matrix for matrix-vector product. The first dimension is indexed in the set of target procs - * that interacts with local source mesh. The second dim is the target cell ID. - * Same indexing as _the_matrix_st_source_proc_id and _the_deno_st. - * We don't use a map here to be more efficient in the final matrix-vector computation which requires the joint - * taversal of _the_matrix_st and _the_deno_st. - * This matrix is filled after receival from other procs, contrary to _matrixes_st which contains local computations.*/ - vector< vector< SparseDoubleVec > > _the_matrix_st; - //! See _the_matrix_st above. List of source proc IDs contributing to _the_matrix_st - vector< int > _the_matrix_st_source_proc_id; - // Denominators (computed from the numerator matrix). As for _the_matrix_st it is paired with _the_matrix_st_source_proc_id - vector< vector< SparseDoubleVec > > _the_deno_st; - - //! Proc IDs to which data will be sent (originating this current proc) for matrix-vector computation - vector< int > _proc_ids_to_send_vector_st; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ParaFIELD.cxx b/medtool/src/ParaMEDMEM/ParaFIELD.cxx deleted file mode 100644 index e8e31e4ee..000000000 --- a/medtool/src/ParaMEDMEM/ParaFIELD.cxx +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ExplicitCoincidentDEC.hxx" -#include "StructuredCoincidentDEC.hxx" -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "ParaFIELD.hxx" -#include "ParaMESH.hxx" -#include "InterpKernelUtilities.hxx" -#include "InterpolationMatrix.hxx" - -#include <numeric> - -namespace ParaMEDMEM -{ - /*! - \anchor ParaFIELD-det - \class ParaFIELD - - This class encapsulates parallel fields. - - It gathers a \ref fields "MEDCouplingField" with some extra information related to the parallel - topology. - - It is most conveniently created by giving a pointer to a MEDCouplingFieldDouble - object and a ProcessorGroup. - By default, a ParaFIELD object will be constructed with all field components - located on the same processors. In some specific cases, it might be necessary to scatter components over - several processors. In this case, the constructor using a ComponentTopology is required. - - */ - - /*! - - \brief Constructing a \c ParaFIELD from a \c ParaMESH and a \c ComponentTopology. - - This constructor creates an empty field based on the ParaMESH description - and the partitioning of components described in \a component_topology. - It takes ownership over the \c _field object that it creates. - - Here come the three ComponentTopology constructors : - \verbatim - ComponentTopology c; // one component in the field - ComponentTopology c(6); //six components, all of them on the same processor - ComponentTopology c(6, proc_group); // six components, evenly distributed over the processors of procgroup - \endverbatim - - */ - ParaFIELD::ParaFIELD(TypeOfField type, TypeOfTimeDiscretization td, ParaMESH* para_support, const ComponentTopology& component_topology) - :_field(0), - _component_topology(component_topology),_topology(0),_own_support(false), - _support(para_support) - { - if (para_support->isStructured() || (para_support->getTopology()->getProcGroup()->size()==1 && component_topology.nbBlocks()!=1)) - { - const BlockTopology* source_topo = dynamic_cast<const BlockTopology*>(para_support->getTopology()); - _topology=new BlockTopology(*source_topo,component_topology); - } - else - { - if (component_topology.nbBlocks()!=1 && para_support->getTopology()->getProcGroup()->size()!=1) - throw INTERP_KERNEL::Exception(LOCALIZED("ParaFIELD constructor : Unstructured Support not taken into account with component topology yet")); - else - { - const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (para_support->getTopology()); - int nb_local_comp=component_topology.nbLocalComponents(); - _topology=new BlockTopology(*source_topo,nb_local_comp); - } - } - int nb_components = component_topology.nbLocalComponents(); - if (nb_components!=0) - { - _field=MEDCouplingFieldDouble::New(type,td); - _field->setMesh(_support->getCellMesh()); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(_field->getNumberOfTuples(),nb_components); - _field->setArray(array); - array->decrRef(); - } - else return; - - _field->setName("Default ParaFIELD name"); - _field->setDescription("Default ParaFIELD description"); - } - - /*! \brief Constructor creating the ParaFIELD - from a given FIELD and a processor group. - - This constructor supposes that support underlying \a subdomain_field has no ParaMESH - attached and it therefore recreates one. It therefore takes ownership over _support. The component topology associated with the field is a basic one (all components on the same processor). - */ - ParaFIELD::ParaFIELD(MEDCouplingFieldDouble* subdomain_field, ParaMESH *sup, const ProcessorGroup& proc_group): - _field(subdomain_field), - _component_topology(ComponentTopology(_field->getNumberOfComponents())),_topology(0),_own_support(false), - _support(sup) - { - if(_field) - _field->incrRef(); - const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (_support->getTopology()); - _topology=new BlockTopology(*source_topo,_component_topology.nbLocalComponents()); - } - - ParaFIELD::~ParaFIELD() - { - if(_field) - _field->decrRef(); - if(_own_support) - delete _support; - delete _topology; - } - - void ParaFIELD::synchronizeTarget(ParaFIELD* source_field) - { - DisjointDEC* data_channel; - if (dynamic_cast<BlockTopology*>(_topology)!=0) - { - data_channel=new StructuredCoincidentDEC; - } - else - { - data_channel=new ExplicitCoincidentDEC; - } - data_channel->attachLocalField(this); - data_channel->synchronize(); - data_channel->prepareTargetDE(); - data_channel->recvData(); - - delete data_channel; - } - - void ParaFIELD::synchronizeSource(ParaFIELD* target_field) - { - DisjointDEC* data_channel; - if (dynamic_cast<BlockTopology*>(_topology)!=0) - { - data_channel=new StructuredCoincidentDEC; - } - else - { - data_channel=new ExplicitCoincidentDEC; - } - data_channel->attachLocalField(this); - data_channel->synchronize(); - data_channel->prepareSourceDE(); - data_channel->sendData(); - - delete data_channel; - } - - /*! - * This method returns, if it exists, an array with only one component and as many as tuples as _field has. - * This array gives for every element on which this->_field lies, its global number, if this->_field is nodal. - * For example if _field is a nodal field : returned array will be the nodal global numbers. - * The content of this method is used to inform Working side to accumulate data recieved by lazy side. - */ - DataArrayInt* ParaFIELD::returnCumulativeGlobalNumbering() const - { - if(!_field) - return 0; - TypeOfField type=_field->getTypeOfField(); - switch(type) - { - case ON_CELLS: - return 0; - case ON_NODES: - return _support->getGlobalNumberingNodeDA(); - default: - return 0; - } - } - - DataArrayInt* ParaFIELD::returnGlobalNumbering() const - { - if(!_field) - return 0; - TypeOfField type=_field->getTypeOfField(); - switch(type) - { - case ON_CELLS: - return _support->getGlobalNumberingCellDA(); - case ON_NODES: - return _support->getGlobalNumberingNodeDA(); - default: - return 0; - } - } - - int ParaFIELD::nbComponents() const - { - return _component_topology.nbComponents(); - } - - - /*! This method retrieves the integral of component \a icomp - over the all domain. */ - double ParaFIELD::getVolumeIntegral(int icomp, bool isWAbs) const - { - CommInterface comm_interface = _topology->getProcGroup()->getCommInterface(); - double integral=_field->integral(icomp,isWAbs); - double total=0.; - const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*>(_topology->getProcGroup()))->getComm(); - comm_interface.allReduce(&integral, &total, 1, MPI_DOUBLE, MPI_SUM, *comm); - - return total; - } -} diff --git a/medtool/src/ParaMEDMEM/ParaFIELD.hxx b/medtool/src/ParaMEDMEM/ParaFIELD.hxx deleted file mode 100644 index fe0a6f9d7..000000000 --- a/medtool/src/ParaMEDMEM/ParaFIELD.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __PARAFIELD_HXX__ -#define __PARAFIELD_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "ComponentTopology.hxx" - -namespace ParaMEDMEM -{ - class DataArrayInt; - class ParaMESH; - class ProcessorGroup; - class MEDCouplingFieldDouble; - class ComponentTopology; - class Topology; - - class ParaFIELD - { - public: - ParaFIELD(TypeOfField type, TypeOfTimeDiscretization td, ParaMESH* mesh, const ComponentTopology& component_topology); - ParaFIELD(MEDCouplingFieldDouble* field, ParaMESH *sup, const ProcessorGroup& group); - virtual ~ParaFIELD(); - - void synchronizeTarget( ParaMEDMEM::ParaFIELD* source_field); - void synchronizeSource( ParaMEDMEM::ParaFIELD* target_field); - MEDCouplingFieldDouble* getField() const { return _field; } - void setOwnSupport(bool v) const { _own_support=v; } - DataArrayInt* returnCumulativeGlobalNumbering() const; - DataArrayInt* returnGlobalNumbering() const; - Topology* getTopology() const { return _topology; } - ParaMESH* getSupport() const { return _support; } - int nbComponents() const; - double getVolumeIntegral(int icomp, bool isWAbs) const; - double getL2Norm()const { return -1; } - - private: - MEDCouplingFieldDouble* _field; - ParaMEDMEM::ComponentTopology _component_topology; - Topology* _topology; - mutable bool _own_support; - ParaMESH* _support; - }; - -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ParaGRID.cxx b/medtool/src/ParaMEDMEM/ParaGRID.cxx deleted file mode 100644 index 8b26bd5f9..000000000 --- a/medtool/src/ParaMEDMEM/ParaGRID.cxx +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaGRID.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingCMesh.hxx" -#include "InterpKernelUtilities.hxx" - -#include <iostream> - -using namespace std; - -namespace ParaMEDMEM -{ - - ParaGRID::ParaGRID(MEDCouplingCMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception) : - _global_axis(), _my_domain_id(0) - { - _block_topology = dynamic_cast<BlockTopology*>(topology); - if(_block_topology==0) - throw INTERP_KERNEL::Exception(LOCALIZED("ParaGRID::ParaGRID topology must be block topology")); - - if (!_block_topology->getProcGroup()->containsMyRank()) - return; - - int dimension=_block_topology->getDimension() ; - if (dimension != global_grid->getSpaceDimension()) - throw INTERP_KERNEL::Exception(LOCALIZED("ParaGrid::ParaGrid incompatible topology")); - _grid=global_grid; - _grid->incrRef(); - /*vector<vector<double> > xyz_array(dimension); - vector<pair<int,int> > local_indices = _block_topology->getLocalArrayMinMax(); - vector <string> coordinates_names; - vector <string> coordinates_units; - for (int idim=0; idim<dimension ; idim++) - { - DataArrayDouble *array=global_grid->getCoordsAt(idim); - double *arrayC=array->getPointer(); - cout << " Indices "<< local_indices[idim].first <<" "<<local_indices[idim].second<<endl; - for (int i=(local_indices)[idim].first; i<(local_indices)[idim].second; i++) - xyz_array[idim].push_back(arrayC[i]); - coordinates_names.push_back(array->getName()); - coordinates_units.push_back(array->getInfoOnComponentAt(0)); - } - _grid=MEDCouplingCMesh::New(); - _grid->set(xyz_array, coordinates_names,coordinates_units); - _grid->setName(global_grid->getName()); - _grid->setDescription(global_grid->getDescription());*/ - } - - ParaGRID::~ParaGRID() - { - if(_grid) - _grid->decrRef(); - } -} diff --git a/medtool/src/ParaMEDMEM/ParaGRID.hxx b/medtool/src/ParaMEDMEM/ParaGRID.hxx deleted file mode 100644 index 72a0109ec..000000000 --- a/medtool/src/ParaMEDMEM/ParaGRID.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __PARAGRID_HXX__ -#define __PARAGRID_HXX__ - -#include "InterpolationUtils.hxx" - -#include <vector> - -namespace ParaMEDMEM -{ - class Topology; - class BlockTopology; - class MEDCouplingCMesh; - - /*! - * This class - * Equivalent of a ParaMESH for a structured mesh - */ - class ParaGRID - { - public: - ParaGRID(MEDCouplingCMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception); - BlockTopology * getBlockTopology() const { return _block_topology; } - virtual ~ParaGRID(); - MEDCouplingCMesh* getGrid() const { return _grid; } - private: - MEDCouplingCMesh* _grid; - // structured grid topology - ParaMEDMEM::BlockTopology* _block_topology; - // stores the x,y,z axes on the global grid - std::vector<std::vector<double> > _global_axis; - //id of the local grid - int _my_domain_id; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ParaMESH.cxx b/medtool/src/ParaMEDMEM/ParaMESH.cxx deleted file mode 100644 index 70b1ffff7..000000000 --- a/medtool/src/ParaMEDMEM/ParaMESH.cxx +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMESH.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "MEDCouplingMemArray.hxx" - -#include <fstream> -#include <vector> - -//inclusion for the namespaces -using namespace std; - -namespace ParaMEDMEM -{ - ParaMESH::ParaMESH( MEDCouplingPointSet *subdomain_mesh, MEDCouplingPointSet *subdomain_face, - DataArrayInt *CorrespElt_local2global, DataArrayInt *CorrespFace_local2global, - DataArrayInt *CorrespNod_local2global, const ProcessorGroup& proc_group ): - _cell_mesh(subdomain_mesh), - _face_mesh(subdomain_face), - _my_domain_id(proc_group.myRank()), - _block_topology (new BlockTopology(proc_group, subdomain_mesh->getNumberOfCells())), - _explicit_topology(0), - _node_global(CorrespNod_local2global), - _face_global(CorrespFace_local2global), - _cell_global(CorrespElt_local2global) - { - if(_cell_mesh) - _cell_mesh->incrRef(); - if(_face_mesh) - _face_mesh->incrRef(); - if(CorrespElt_local2global) - CorrespElt_local2global->incrRef(); - if(CorrespFace_local2global) - CorrespFace_local2global->incrRef(); - if(CorrespNod_local2global) - CorrespNod_local2global->incrRef(); - } - - ParaMESH::ParaMESH( MEDCouplingPointSet *mesh, const ProcessorGroup& proc_group, const std::string& name): - _cell_mesh(mesh), - _face_mesh(0), - _my_domain_id(proc_group.myRank()), - _block_topology (new BlockTopology(proc_group, mesh->getNumberOfCells())), - _node_global(0), - _face_global(0) - { - if(_cell_mesh) - _cell_mesh->incrRef(); - int nb_elem=mesh->getNumberOfCells(); - _explicit_topology=new BlockTopology(proc_group,nb_elem); - int nbOfCells=mesh->getNumberOfCells(); - _cell_global = DataArrayInt::New(); - _cell_global->alloc(nbOfCells,1); - int *cellglobal=_cell_global->getPointer(); - int offset = _block_topology->localToGlobal(make_pair(_my_domain_id,0)); - for (int i=0; i<nbOfCells; i++) - { - cellglobal[i]=offset+i; - } - } - - void ParaMESH::setNodeGlobal(DataArrayInt *nodeGlobal) - { - if(nodeGlobal!=_node_global) - { - if(_node_global) - _node_global->decrRef(); - _node_global=nodeGlobal; - if(_node_global) - _node_global->incrRef(); - } - } - - void ParaMESH::setCellGlobal(DataArrayInt *cellGlobal) - { - if(cellGlobal!=_cell_global) - { - if(_cell_global) - _cell_global->decrRef(); - _cell_global=cellGlobal; - if(_cell_global) - _cell_global->incrRef(); - } - } - - ParaMESH::~ParaMESH() - { - if(_cell_mesh) - _cell_mesh->decrRef(); - if(_face_mesh) - _face_mesh->decrRef(); - delete _block_topology; - if(_node_global) - _node_global->decrRef(); - if(_cell_global) - _cell_global->decrRef(); - if(_face_global) - _face_global->decrRef(); - delete _explicit_topology; - } - -} diff --git a/medtool/src/ParaMEDMEM/ParaMESH.hxx b/medtool/src/ParaMEDMEM/ParaMESH.hxx deleted file mode 100644 index 06c6d754a..000000000 --- a/medtool/src/ParaMEDMEM/ParaMESH.hxx +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __PARAMESH_HXX__ -#define __PARAMESH_HXX__ - -#include "MEDCouplingPointSet.hxx" -#include "ProcessorGroup.hxx" -#include "MEDCouplingMemArray.hxx" - -#include <string> -#include <vector> - -namespace ParaMEDMEM -{ - class Topology; - class BlockTopology; - class DataArrayInt; - - /*! - * \anchor ParaMESH-det - * - * Parallel representation of an unstructured mesh. - * - * This class is very specific to the requirement of parallel code computations. - * Two main constructors are available: - * - the most simple one, taking directly a \ref meshes "MEDCoupling mesh" object - * - the second one (for an advanced usage), which can be used to specify an explicit topology - * in a parallel computation. - */ - class ParaMESH - { - public: - ParaMESH( MEDCouplingPointSet *mesh, - const ProcessorGroup& proc_group, const std::string& name); - ParaMESH( MEDCouplingPointSet *subdomain_mesh, - MEDCouplingPointSet *subdomain_face, - DataArrayInt *CorrespElt_local2global, - DataArrayInt *CorrespFace_local2global, - DataArrayInt *CorrespNod_local2global, - const ProcessorGroup& proc_group ) ; - - virtual ~ParaMESH(); - void setNodeGlobal(DataArrayInt *nodeGlobal); - void setCellGlobal(DataArrayInt *cellGlobal); - Topology* getTopology() const { return _explicit_topology; } - bool isStructured() const { return _cell_mesh->isStructured(); } - MEDCouplingPointSet *getCellMesh() const { return _cell_mesh; } - MEDCouplingPointSet *getFaceMesh() const { return _face_mesh; } - BlockTopology* getBlockTopology() const { return _block_topology; } - - DataArrayInt* getGlobalNumberingNodeDA() const { if(_node_global) _node_global->incrRef(); return _node_global; } - DataArrayInt* getGlobalNumberingFaceDA() const { if(_face_global) _face_global->incrRef(); return _face_global; } - DataArrayInt* getGlobalNumberingCellDA() const { if(_cell_global) _cell_global->incrRef(); return _cell_global; } - const int* getGlobalNumberingNode() const { if(_node_global) return _node_global->getConstPointer(); return 0; } - const int* getGlobalNumberingFace() const { if(_face_global) return _face_global->getConstPointer(); return 0; } - const int* getGlobalNumberingCell() const { if(_cell_global) return _cell_global->getConstPointer(); return 0; } - - private: - //mesh object underlying the ParaMESH object - MEDCouplingPointSet *_cell_mesh ; - MEDCouplingPointSet *_face_mesh ; - - //id of the local grid - int _my_domain_id; - - //global topology of the cells - ParaMEDMEM::BlockTopology* _block_topology; - Topology* _explicit_topology; - // pointers to global numberings - DataArrayInt* _node_global; - DataArrayInt* _face_global; - DataArrayInt* _cell_global; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/ProcessorGroup.cxx b/medtool/src/ParaMEDMEM/ProcessorGroup.cxx deleted file mode 100644 index 011695016..000000000 --- a/medtool/src/ParaMEDMEM/ProcessorGroup.cxx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ProcessorGroup.hxx" -#include "InterpolationUtils.hxx" - -namespace ParaMEDMEM -{ - ProcessorGroup::ProcessorGroup (const CommInterface& interface, int start, int end):_comm_interface(interface) - { - if (start>end) - throw INTERP_KERNEL::Exception("wrong call to Processor group constructor"); - for (int i=start; i<=end;i++) - _proc_ids.insert(i); - } -} diff --git a/medtool/src/ParaMEDMEM/ProcessorGroup.hxx b/medtool/src/ParaMEDMEM/ProcessorGroup.hxx deleted file mode 100644 index 972219b9e..000000000 --- a/medtool/src/ParaMEDMEM/ProcessorGroup.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __PROCESSORGROUP_HXX__ -#define __PROCESSORGROUP_HXX__ - -#include "CommInterface.hxx" - -#include <set> - -namespace ParaMEDMEM -{ - /*! - * Abstract class defining a group of processors (computation nodes) in a parallel run of a code. - * - * See the non-abstract child \ref MPIProcessorGroup-det "MPIProcessorGroup" - */ - class ProcessorGroup - { - public: - - ProcessorGroup(const CommInterface& interface):_comm_interface(interface) { } - ProcessorGroup(const CommInterface& interface, std::set<int> proc_ids): - _comm_interface(interface),_proc_ids(proc_ids) { } - ProcessorGroup (const ProcessorGroup& proc_group, std::set<int> proc_ids): - _comm_interface(proc_group.getCommInterface()),_proc_ids(proc_ids) { } - ProcessorGroup (const ProcessorGroup& other): - _comm_interface(other.getCommInterface()),_proc_ids(other._proc_ids) { } - ProcessorGroup (const CommInterface& interface, int start, int end); - virtual ~ProcessorGroup() { } - virtual ProcessorGroup *deepCpy() const = 0; - virtual ProcessorGroup* fuse (const ProcessorGroup&) const = 0; - virtual void intersect (ProcessorGroup&) = 0; - bool contains(int rank) const { return _proc_ids.find(rank)!=_proc_ids.end(); } - virtual bool containsMyRank() const = 0; - int size() const { return _proc_ids.size(); } - const CommInterface& getCommInterface()const { return _comm_interface; } - virtual int myRank() const = 0; - virtual int translateRank(const ProcessorGroup*, int) const = 0; - virtual ProcessorGroup* createComplementProcGroup() const = 0; - virtual ProcessorGroup* createProcGroup() const = 0; - virtual const std::set<int>& getProcIDs()const { return _proc_ids; } - protected: - const CommInterface _comm_interface; - std::set<int> _proc_ids; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/README b/medtool/src/ParaMEDMEM/README deleted file mode 100644 index 8a72f3971..000000000 --- a/medtool/src/ParaMEDMEM/README +++ /dev/null @@ -1,194 +0,0 @@ -Tests avec CPPUNIT -================== - -L'appel a MPI_Init n'est fait qu'une seule fois pour chaque suite de test -(voir TestMPIAccessDEC.cxx, TestMPIAccess.cxx, TestParaMEDMEM.cxx qui inclut -tous MPIMainTest.hxx) -Il est suivi par l'execution de toute la suite des tests regroupes -dans les trois headers MPIAccess.hxx, MPIAccessDEC.hxx, ParaMEDMEMTest.hxx -On a enfin un seul appel a MPI_Finalize. - -Si un des tests d'une suite de tests comporte une anomalie cela -peut avoir des implications sur l'execution des tests suivants. - -[ABN-2015] Lancement des tests avec valgrind -============================================ - -Exemple avec MPICH : - -rm tmp_log* ; mpirun -np 3 valgrind --leak-check=full --show-reachable=yes --log-file=tmp_log%p src/ParaMEDMEMTest/TestParaMEDMEM && cat tmp_log* - -[ABN-2015] Lancement des tests avec gdb -======================================= - -Exemple avec MPICH : - -mpirun -np 2 xterm -e gdb src/ParaMEDMEMTest/TestMPIAccess - - - - - -************************************************************************************************************* -*********************** ce qui suit est obsolète ?? ************************************** -************************************************************************************************************* - -Lancement des tests de TestParaMEDMEM avec CPPUNIT et TotalView (option -tv) : -============================================================================== - -mpirun -np 5 -ssi rpi tcp C -tv -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM - -Il arrive qu'on ne puisse pas utiliser totalview par manque de -license. - - - -Lancement des tests de TestParaMEDMEM avec CPPUNIT et Valgrind avec "memory leaks" : -==================================================================================== - -mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestParaMEDMEM - - -Lancement des tests fonctionnels de MPI_AccessDEC avec CPPUNIT : -================================================================ - -mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestMPIAccessDEC - - -Lancement des tests unitaires de MPI_Access avec CPPUNIT : -========================================================== - -mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestMPIAccess - - -TestMPIAccess/TestMPIAccessDEC/TestParaMEDMEM et gcov : -======================================================= - -Les resultats sont dans les repertoires suivants de $MED_BUILD_DIR/src/ParaMEDMEM/Test : -------------- - - TestParaMEDMEM-gcov/ - TestMPIAccessDEC-gcov/ - TestMPIAccess-gcov/ - -Je n'y ai pas trouve d'anomalies. - -compilation : -fprofile-arcs -ftest-coverage -------------- - -$MED_BUILD_DIR/src/ParaMEDMEM/makefile.in : LIB=libparamedar.a \ -------------------------------------------- libparamed.la - -$MED_BUILD_DIR/src/ParaMEDMEM/Test/makefile.in : LIB = libParaMEDMEMTestar.a \ ------------------------------------------------- libParaMEDMEMTest.la - -execution et gcov : -------------------- - -Pour pouvoir traiter les .cxx de ${MED_BUILD_DIR}/src/ParaMEDMEM et de -${MED_BUILD_DIR}/src/ParaMEDMEM/Test, on execute deux fois gcov. - -cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test - -mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestMPIAccess - -gcov TestMPIAccess.cxx test_MPI_Access_Send_Recv.cxx \ - test_MPI_Access_Cyclic_Send_Recv.cxx \ - test_MPI_Access_SendRecv.cxx \ - test_MPI_Access_ISend_IRecv.cxx \ - test_MPI_Access_Cyclic_ISend_IRecv.cxx \ - test_MPI_Access_ISendRecv.cxx \ - test_MPI_Access_Probe.cxx \ - test_MPI_Access_IProbe.cxx \ - test_MPI_Access_Cancel.cxx \ - test_MPI_Access_Send_Recv_Length.cxx \ - test_MPI_Access_ISend_IRecv_Length.cxx \ - test_MPI_Access_ISend_IRecv_Length_1.cxx \ - test_MPI_Access_Time.cxx \ - test_MPI_Access_Time_0.cxx \ - test_MPI_Access_ISend_IRecv_BottleNeck.cxx \ - ../MPI_Access.cxx -gcov -o ../ TestMPIAccess.cxx test_MPI_Access_Send_Recv.cxx \ - test_MPI_Access_Cyclic_Send_Recv.cxx \ - test_MPI_Access_SendRecv.cxx \ - test_MPI_Access_ISend_IRecv.cxx \ - test_MPI_Access_Cyclic_ISend_IRecv.cxx \ - test_MPI_Access_ISendRecv.cxx \ - test_MPI_Access_Probe.cxx \ - test_MPI_Access_IProbe.cxx \ - test_MPI_Access_Cancel.cxx \ - test_MPI_Access_Send_Recv_Length.cxx \ - test_MPI_Access_ISend_IRecv_Length.cxx \ - test_MPI_Access_ISend_IRecv_Length_1.cxx \ - test_MPI_Access_Time.cxx \ - test_MPI_Access_Time_0.cxx \ - test_MPI_Access_ISend_IRecv_BottleNeck.cxx \ - ../MPI_Access.cxx - - -cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test -mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestMPIAccessDEC - -gcov TestMPIAccessDEC.cxx test_AllToAllDEC.cxx \ - test_AllToAllvDEC.cxx \ - test_AllToAllTimeDEC.cxx \ - test_AllToAllvTimeDEC.cxx \ - test_AllToAllvTimeDoubleDEC.cxx \ - ../TimeInterpolator.cxx \ - ../LinearTimeInterpolator.cxx \ - ../MPI_Access.cxx \ - ../MPI_AccessDEC.cxx -gcov -o ../ TestMPIAccessDEC.cxx test_AllToAllDEC.cxx \ - test_AllToAllvDEC.cxx \ - test_AllToAllTimeDEC.cxx \ - test_AllToAllvTimeDEC.cxx \ - test_AllToAllvTimeDoubleDEC.cxx \ - ../TimeInterpolator.cxx \ - ../LinearTimeInterpolator.cxx \ - ../MPI_Access.cxx \ - ../MPI_AccessDEC.cxx - -cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test -mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM - -gcov TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ - ParaMEDMEMTest_MPIProcessorGroup.cxx \ - ParaMEDMEMTest_BlockTopology.cxx \ - ParaMEDMEMTest_InterpKernelDEC.cxx \ - ../BlockTopology.cxx \ - ../ComponentTopology.cxx \ - ../DEC.cxx \ - ../ElementLocator.cxx \ - ../InterpolationMatrix.cxx \ - ../InterpKernelDEC.cxx \ - ../MPIProcessorGroup.cxx \ - ../MxN_Mapping.cxx \ - ../ParaFIELD.cxx \ - ../ParaMESH.cxx \ - ../ParaSUPPORT.cxx \ - ../ProcessorGroup.cxx \ - ../TimeInterpolator.cxx \ - ../LinearTimeInterpolator.cxx \ - ../MPI_Access.cxx \ - ../MPI_AccessDEC.cxx - -gcov -o ../ TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ - ParaMEDMEMTest_MPIProcessorGroup.cxx \ - ParaMEDMEMTest_BlockTopology.cxx \ - ParaMEDMEMTest_InterpKernelDEC.cxx \ - ../BlockTopology.cxx \ - ../ComponentTopology.cxx \ - ../DEC.cxx \ - ../ElementLocator.cxx \ - ../InterpolationMatrix.cxx \ - ../InterpKernelDEC.cxx \ - ../MPIProcessorGroup.cxx \ - ../MxN_Mapping.cxx \ - ../ParaFIELD.cxx \ - ../ParaMESH.cxx \ - ../ParaSUPPORT.cxx \ - ../ProcessorGroup.cxx \ - ../TimeInterpolator.cxx \ - ../LinearTimeInterpolator.cxx \ - ../MPI_Access.cxx \ - ../MPI_AccessDEC.cxx diff --git a/medtool/src/ParaMEDMEM/StructuredCoincidentDEC.cxx b/medtool/src/ParaMEDMEM/StructuredCoincidentDEC.cxx deleted file mode 100644 index 9620ba135..000000000 --- a/medtool/src/ParaMEDMEM/StructuredCoincidentDEC.cxx +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <mpi.h> -#include "CommInterface.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" -#include "ComponentTopology.hxx" -#include "ParaFIELD.hxx" -#include "MPIProcessorGroup.hxx" -#include "StructuredCoincidentDEC.hxx" -#include "InterpKernelUtilities.hxx" - -#include <iostream> - -using namespace std; - -namespace ParaMEDMEM -{ - - /*! - \anchor StructuredCoincidentDEC-det - \class StructuredCoincidentDEC - - This class aims at \ref interpolation "remapping fields" that have identical - structured supports (=the same underlying mesh) but different parallel topologies - (=different sub-domains in the structured mesh). It can be used to couple - together multi-physics codes that operate on the same domain - with different partitioning. This can be useful for example if one of - the computation is much faster than the other. It can also be used - to couple together codes that share an interface that was generated - in the same manner (with identical global ids). - Also, this \ref para-dec "DEC" can be used for fields that have component topologies, - i.e., components that are scattered over several processors. - - The remapping between the two supports is based on identity of global - ids, instead of geometrical considerations (as it is the case for - \ref InterpKernelDEC-det "InterpKernelDEC"). - Therefore, beware that this \ref para-dec "DEC" can not be used - for coincident meshes if they do *not* have the exact same numbering. - - With this %DEC no projection, and no interpolation of the field data is done, contrary - to what happens in \ref InterpKernelDEC-det "InterpKernelDEC". It is just - a matter of allocating the values from one side to the other, using directly the cell - identifiers. - - As all the other DECs, its usage requires two phases : - - a setup phase during which the topologies are exchanged so that - the target side knows from which processors it should expect - the data. - - a send/recv phase during which the field data is actually transferred. - - This example illustrates the sending of a field with - the \c StructuredCoincidentDEC : - \code - ... - StructuredCoincidentDEC dec(groupA, groupB); - dec.attachLocalField(field); - dec.synchronize(); - if (groupA.containsMyRank()) - dec.recvData(); - else if (groupB.containsMyRank()) - dec.sendData(); - ... - \endcode - - Creating a ParaFIELD to be attached to the %DEC is done in exactly the same way as for - the other DECs, if only the partitioning of the support mesh differs. - In the case where the - fields have also different *component* topologies, creating the ParaFIELD - requires some more effort. See the \ref para-over "parallelism" section for more details. - */ - - - StructuredCoincidentDEC::StructuredCoincidentDEC():_topo_source(0),_topo_target(0), - _send_counts(0),_recv_counts(0), - _send_displs(0),_recv_displs(0), - _recv_buffer(0),_send_buffer(0) - { - } - - - StructuredCoincidentDEC::~StructuredCoincidentDEC() - { - delete [] _send_buffer; - delete [] _recv_buffer; - delete []_send_displs; - delete [] _recv_displs; - delete [] _send_counts; - delete [] _recv_counts; - if (! _source_group->containsMyRank()) - delete _topo_source; - if(!_target_group->containsMyRank()) - delete _topo_target; - } - - StructuredCoincidentDEC::StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group): - DisjointDEC(local_group,distant_group), - _topo_source(0),_topo_target(0), - _send_counts(0),_recv_counts(0), - _send_displs(0),_recv_displs(0), - _recv_buffer(0),_send_buffer(0) - { - } - - /*! Synchronization process for exchanging topologies - */ - void StructuredCoincidentDEC::synchronizeTopology() - { - if (_source_group->containsMyRank()) - _topo_source = dynamic_cast<BlockTopology*>(_local_field->getTopology()); - if (_target_group->containsMyRank()) - _topo_target = dynamic_cast<BlockTopology*>(_local_field->getTopology()); - - // Transmitting source topology to target code - broadcastTopology(_topo_source,1000); - // Transmitting target topology to source code - broadcastTopology(_topo_target,2000); - if (_topo_source->getNbElements() != _topo_target->getNbElements()) - throw INTERP_KERNEL::Exception("Incompatible dimensions for target and source topologies"); - - } - - /*! Creates the arrays necessary for the data transfer - * and fills the send array with the values of the - * source field - * */ - void StructuredCoincidentDEC::prepareSourceDE() - { - //////////////////////////////////// - //Step 1 : _buffer array creation - - if (!_topo_source->getProcGroup()->containsMyRank()) - return; - MPIProcessorGroup* group=new MPIProcessorGroup(_topo_source->getProcGroup()->getCommInterface()); - - int myranksource = _topo_source->getProcGroup()->myRank(); - - vector <int>* target_arrays=new vector<int>[_topo_target->getProcGroup()->size()]; - - //cout<<" topotarget size"<< _topo_target->getProcGroup()->size()<<endl; - - int nb_local = _topo_source-> getNbLocalElements(); - for (int ielem=0; ielem< nb_local ; ielem++) - { - // cout <<"source local :"<<myranksource<<","<<ielem<<endl; - int global = _topo_source->localToGlobal(make_pair(myranksource, ielem)); - // cout << "global "<<global<<endl; - pair<int,int> target_local =_topo_target->globalToLocal(global); - // cout << "target local : "<<target_local.first<<","<<target_local.second<<endl; - target_arrays[target_local.first].push_back(target_local.second); - } - - int union_size=group->size(); - - _send_counts=new int[union_size]; - _send_displs=new int[union_size]; - _recv_counts=new int[union_size]; - _recv_displs=new int[union_size]; - - for (int i=0; i< union_size; i++) - { - _send_counts[i]=0; - _recv_counts[i]=0; - _recv_displs[i]=0; - } - _send_displs[0]=0; - - for (int iproc=0; iproc < _topo_target->getProcGroup()->size(); iproc++) - { - //converts the rank in target to the rank in union communicator - int unionrank=group->translateRank(_topo_target->getProcGroup(),iproc); - _send_counts[unionrank]=target_arrays[iproc].size(); - } - - for (int iproc=1; iproc<group->size();iproc++) - _send_displs[iproc]=_send_displs[iproc-1]+_send_counts[iproc-1]; - - _send_buffer = new double [nb_local ]; - - ///////////////////////////////////////////////////////////// - //Step 2 : filling the _buffers with the source field values - - int* counter=new int [_topo_target->getProcGroup()->size()]; - counter[0]=0; - for (int i=1; i<_topo_target->getProcGroup()->size(); i++) - counter[i]=counter[i-1]+target_arrays[i-1].size(); - - - const double* value = _local_field->getField()->getArray()->getPointer(); - //cout << "Nb local " << nb_local<<endl; - for (int ielem=0; ielem<nb_local ; ielem++) - { - int global = _topo_source->localToGlobal(make_pair(myranksource, ielem)); - pair<int,int> target_local =_topo_target->globalToLocal(global); - //cout <<"global : "<< global<<" local :"<<target_local.first<<" "<<target_local.second; - //cout <<"counter[]"<<counter[target_local.first]<<endl; - _send_buffer[counter[target_local.first]++]=value[ielem]; - - } - delete[] target_arrays; - delete[] counter; - delete group; - } - - /*! - * Creates the buffers for receiving the fields on the target side - */ - void StructuredCoincidentDEC::prepareTargetDE() - { - if (!_topo_target->getProcGroup()->containsMyRank()) - return; - MPIProcessorGroup* group=new MPIProcessorGroup(_topo_source->getProcGroup()->getCommInterface()); - - int myranktarget = _topo_target->getProcGroup()->myRank(); - - vector < vector <int> > source_arrays(_topo_source->getProcGroup()->size()); - int nb_local = _topo_target-> getNbLocalElements(); - for (int ielem=0; ielem< nb_local ; ielem++) - { - // cout <<"TS target local :"<<myranktarget<<","<<ielem<<endl; - int global = _topo_target->localToGlobal(make_pair(myranktarget, ielem)); - //cout << "TS global "<<global<<endl; - pair<int,int> source_local =_topo_source->globalToLocal(global); - // cout << "TS source local : "<<source_local.first<<","<<source_local.second<<endl; - source_arrays[source_local.first].push_back(source_local.second); - } - int union_size=group->size(); - _recv_counts=new int[union_size]; - _recv_displs=new int[union_size]; - _send_counts=new int[union_size]; - _send_displs=new int[union_size]; - - for (int i=0; i< union_size; i++) - { - _send_counts[i]=0; - _recv_counts[i]=0; - _recv_displs[i]=0; - } - for (int iproc=0; iproc < _topo_source->getProcGroup()->size(); iproc++) - { - //converts the rank in target to the rank in union communicator - int unionrank=group->translateRank(_topo_source->getProcGroup(),iproc); - _recv_counts[unionrank]=source_arrays[iproc].size(); - } - for (int i=1; i<union_size; i++) - _recv_displs[i]=_recv_displs[i-1]+_recv_counts[i-1]; - _recv_buffer=new double[nb_local]; - - delete group; - } - - - /*! - * Synchronizing a topology so that all the - * group possesses it. - * - * \param topo Topology that is transmitted. It is read on processes where it already exists, and it is created and filled on others. - * \param tag Communication tag associated with this operation. - */ - void StructuredCoincidentDEC::broadcastTopology(BlockTopology*& topo, int tag) - { - MPI_Status status; - - int* serializer=0; - int size; - - MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); - - // The master proc creates a send buffer containing - // a serialized topology - int rank_master; - - if (topo!=0 && topo->getProcGroup()->myRank()==0) - { - MESSAGE ("Master rank"); - topo->serialize(serializer, size); - rank_master = group->translateRank(topo->getProcGroup(),0); - MESSAGE("Master rank world number is "<<rank_master); - MESSAGE("World Size is "<<group->size()); - for (int i=0; i< group->size(); i++) - { - if (i!= rank_master) - _comm_interface->send(&rank_master,1,MPI_INT, i,tag+i,*(group->getComm())); - } - } - else - { - MESSAGE(" rank "<<group->myRank()<< " waiting ..."); - _comm_interface->recv(&rank_master, 1,MPI_INT, MPI_ANY_SOURCE, tag+group->myRank(), *(group->getComm()),&status); - MESSAGE(" rank "<<group->myRank()<< "received master rank"<<rank_master); - } - // The topology is broadcasted to all processsors in the group - _comm_interface->broadcast(&size, 1,MPI_INT,rank_master,*(group->getComm())); - - int* buffer=new int[size]; - if (topo!=0 && topo->getProcGroup()->myRank()==0) - copy(serializer, serializer+size, buffer); - _comm_interface->broadcast(buffer,size,MPI_INT,rank_master,*(group->getComm())); - - // Processors which did not possess the source topology - // unserialize it - - BlockTopology* topotemp=new BlockTopology(); - topotemp->unserialize(buffer, *_comm_interface); - - if (topo==0) - topo=topotemp; - else - delete topotemp; - - // Memory cleaning - delete[] buffer; - if (serializer!=0) - delete[] serializer; - MESSAGE (" rank "<<group->myRank()<< " unserialize is over"); - delete group; - } - - - - void StructuredCoincidentDEC::recvData() - { - //MPI_COMM_WORLD is used instead of group because there is no - //mechanism for creating the union group yet - MESSAGE("recvData"); - for (int i=0; i< 4; i++) - cout << _recv_counts[i]<<" "; - cout <<endl; - for (int i=0; i< 4; i++) - cout << _recv_displs[i]<<" "; - cout <<endl; - - cout<<"start AllToAll"<<endl; - MPI_Comm comm = *(dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); - _comm_interface->allToAllV(_send_buffer, _send_counts, _send_displs, MPI_DOUBLE, - _recv_buffer, _recv_counts, _recv_displs, MPI_DOUBLE,comm); - cout<<"end AllToAll"<<endl; - - int nb_local = _topo_target->getNbLocalElements(); - //double* value=new double[nb_local]; - double* value=const_cast<double*>(_local_field->getField()->getArray()->getPointer()); - - int myranktarget=_topo_target->getProcGroup()->myRank(); - vector<int> counters(_topo_source->getProcGroup()->size()); - counters[0]=0; - for (int i=0; i<_topo_source->getProcGroup()->size()-1; i++) - { - MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); - int worldrank=group->translateRank(_topo_source->getProcGroup(),i); - counters[i+1]=counters[i]+_recv_counts[worldrank]; - delete group; - } - - for (int ielem=0; ielem<nb_local ; ielem++) - { - int global = _topo_target->localToGlobal(make_pair(myranktarget, ielem)); - pair<int,int> source_local =_topo_source->globalToLocal(global); - value[ielem]=_recv_buffer[counters[source_local.first]++]; - } - - - //_local_field->getField()->setValue(value); - } - - void StructuredCoincidentDEC::sendData() - { - MESSAGE ("sendData"); - for (int i=0; i< 4; i++) - cout << _send_counts[i]<<" "; - cout <<endl; - for (int i=0; i< 4; i++) - cout << _send_displs[i]<<" "; - cout <<endl; - cout <<"start AllToAll"<<endl; - MPI_Comm comm = *(dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); - _comm_interface->allToAllV(_send_buffer, _send_counts, _send_displs, MPI_DOUBLE, - _recv_buffer, _recv_counts, _recv_displs, MPI_DOUBLE,comm); - cout<<"end AllToAll"<<endl; - } - - /*! Prepares a DEC for data exchange - - This method broadcasts the topologies from source to target - so that the target side can analyse from which processors it - is expected to receive data. - */ - - void StructuredCoincidentDEC::synchronize() - { - if (_source_group->containsMyRank()) - { - synchronizeTopology(); - prepareSourceDE(); - } - else if (_target_group->containsMyRank()) - { - synchronizeTopology(); - prepareTargetDE(); - } - } -} - diff --git a/medtool/src/ParaMEDMEM/StructuredCoincidentDEC.hxx b/medtool/src/ParaMEDMEM/StructuredCoincidentDEC.hxx deleted file mode 100644 index 1653467b1..000000000 --- a/medtool/src/ParaMEDMEM/StructuredCoincidentDEC.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __STRUCTUREDCOINCIDENTDEC_HXX__ -#define __STRUCTUREDCOINCIDENTDEC_HXX__ - -#include "DisjointDEC.hxx" -#include "BlockTopology.hxx" - - -namespace ParaMEDMEM -{ - class DEC; - class BlockTopology; - - class StructuredCoincidentDEC : public DisjointDEC - { - public: - StructuredCoincidentDEC(); - StructuredCoincidentDEC( ProcessorGroup& source, ProcessorGroup& target); - virtual ~StructuredCoincidentDEC(); - void synchronize(); - void recvData(); - void sendData(); - void prepareSourceDE(); - void prepareTargetDE(); - - private : - void synchronizeTopology(); - void broadcastTopology(BlockTopology*&, int tag); - - BlockTopology* _topo_source; - BlockTopology* _topo_target; - int* _send_counts; - int* _recv_counts; - int* _send_displs; - int* _recv_displs; - double* _recv_buffer; - double* _send_buffer; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/TODO_JR b/medtool/src/ParaMEDMEM/TODO_JR deleted file mode 100644 index de2318d54..000000000 --- a/medtool/src/ParaMEDMEM/TODO_JR +++ /dev/null @@ -1,50 +0,0 @@ - -MPI_Access : -============ - -. Creer des methodes [I]SendRecv en point a point avec un "target" - pour le Send et un "target" pour le Recv comme le SendRecv MPI. - -. Ne pas creer de structure RequestStruct en mode synchrone. - - -MPI_AccessDEC : -=============== - -. AllToAll, AllToAllv, AllToAllTime et AllToAllvTime comportent - des sequences de code semblables qui pourraient etre regroupees - sans que cela nuise a la lisibilite du code. - -. En mode asynchrone, il n'y a pas de controle d'engorgement des - messages envoyes dans CheckSent(). Il est vrai qu'en pratique - une synchronisation des temps est faite dans AllToAllTime et - AllToAllvTime. Mais ce probleme pourrait se produire avec - AllToAll et AllToAllv. Il serait possible de fixer un nombre - maximum de messages envoyes et "en cours" et de le comparer avec - le nombre de requetes rendu par MPI_Access. En cas de depassement - de ?n?*UnionGroupSize par exemple, CheckSent pourrait fonctionner - en mode "WithWait". Ce qui ferait qu'on apellerait Wait au lieu de Test. - -. Meme si le prototype d'interpolateur comporte des parametres - int nStepBefore et int nStepAfter, le codage actuel considere - qu'on n'a que nStepBefore=1 et nStepAfter=1. - Ainsi on a (*_TimeMessages)[target][0] et (*_TimeMessages)[target][1] - ainsi que &(*_DataMessages)[target][0] et &(*_DataMessages)[target][1]. - -. Les champs nStepBefore et nStepAfter correspondent a un maximum - requis. On devrait avoir les champs correspondants qui valent les - nombres disponibles a un moment donne. - -. Il existe un champs OutOfTime qui n'est pas utilise actuellement. - Il faudrait definir son usage et le transmettre sans doute à - l'interpolateur. Actuellement, L'interpolateur lineaire effectue une - extrapolation si OutOfTime vaut true. - -. Dans CheckTime, on alloue et detruit les (*_DataMessages)[target][] - alors qu'on pourrait considerer que pour un "target" donne, les - recvcount sont constants pendant toute la boucle de temps. Ainsi - on n'allouerait les buffers qu'une fois au depart et ils ne seraient - liberes qu'a la fin. - - - diff --git a/medtool/src/ParaMEDMEM/TimeInterpolator.cxx b/medtool/src/ParaMEDMEM/TimeInterpolator.cxx deleted file mode 100644 index 86c3bfb74..000000000 --- a/medtool/src/ParaMEDMEM/TimeInterpolator.cxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TimeInterpolator.hxx" - -namespace ParaMEDMEM -{ - TimeInterpolator::TimeInterpolator( double InterpPrecision, int nStepBefore, int nStepAfter ) - { - _interp_precision=InterpPrecision; - _n_step_before=nStepBefore; - _n_step_after=nStepAfter; - } - - TimeInterpolator::~TimeInterpolator() - { - } -} diff --git a/medtool/src/ParaMEDMEM/TimeInterpolator.hxx b/medtool/src/ParaMEDMEM/TimeInterpolator.hxx deleted file mode 100644 index e284acc8e..000000000 --- a/medtool/src/ParaMEDMEM/TimeInterpolator.hxx +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TIMEINTERPOLATOR_HXX__ -#define __TIMEINTERPOLATOR_HXX__ - -#include "ProcessorGroup.hxx" - -#include <map> -#include <iostream> - -namespace ParaMEDMEM -{ - - /*! - * Internal class, not part of the public API. - * - * Abstract class for all time-related interpolation in a parallel context. - */ - class TimeInterpolator - { - public: - TimeInterpolator( double InterpPrecision, int nStepBefore=1, int nStepAfter=1 ); - virtual ~TimeInterpolator(); - - void setInterpParams( double InterpPrecision, int nStepBefore=1, int nStepAfter=1 ) { _interp_precision=InterpPrecision; _n_step_before=nStepBefore; _n_step_after=nStepAfter; } - void steps( int &nStepBefore, int &nStepAfter ) { nStepBefore=_n_step_before; nStepAfter=_n_step_after ; } - virtual void doInterp( double time0, double time1, double time, int recvcount , - int nbuff0, int nbuff1, - int **recvbuff0, int **recvbuff1, int *result ) = 0; - virtual void doInterp( double time0, double time1, double time, int recvcount , - int nbuff0, int nbuff1, - double **recvbuff0, double **recvbuff1, double *result ) = 0; - protected : - double _interp_precision; - int _n_step_before; - int _n_step_after; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEM/Topology.cxx b/medtool/src/ParaMEDMEM/Topology.cxx deleted file mode 100644 index 49a7fc20d..000000000 --- a/medtool/src/ParaMEDMEM/Topology.cxx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Topology.hxx" - -namespace ParaMEDMEM -{ - Topology::Topology() - { - } - - Topology::~Topology() - { - } -} diff --git a/medtool/src/ParaMEDMEM/Topology.hxx b/medtool/src/ParaMEDMEM/Topology.hxx deleted file mode 100644 index 19ce03458..000000000 --- a/medtool/src/ParaMEDMEM/Topology.hxx +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __TOPOLOGY_HXX__ -#define __TOPOLOGY_HXX__ - -namespace ParaMEDMEM -{ - class ProcessorGroup; - - /*! - * Topology of a group of processors within a processor group. Abstract class, see derivations. - * - * \sa BlockTopology - * \sa ExplicitTopology - * \sa MPIProcessorGroup - */ - class Topology - { - public: - Topology() { } - virtual ~Topology() { } - virtual int getNbElements() const = 0; - virtual int getNbLocalElements() const = 0; - virtual const ProcessorGroup* getProcGroup()const = 0; - }; -} - -#endif diff --git a/medtool/src/ParaMEDMEMTest/CMakeLists.txt b/medtool/src/ParaMEDMEMTest/CMakeLists.txt deleted file mode 100644 index 90d84290d..000000000 --- a/medtool/src/ParaMEDMEMTest/CMakeLists.txt +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_DEFINITIONS(${MPI_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${MPI_INCLUDE_DIRS} - ${CPPUNIT_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ) - -SET(ParaMEDMEMTest_SOURCES - ParaMEDMEMTest.cxx - ParaMEDMEMTest_MPIProcessorGroup.cxx - ParaMEDMEMTest_BlockTopology.cxx - ParaMEDMEMTest_InterpKernelDEC.cxx - ParaMEDMEMTest_StructuredCoincidentDEC.cxx - ParaMEDMEMTest_ICoco.cxx - ParaMEDMEMTest_Gauthier1.cxx - ParaMEDMEMTest_FabienAPI.cxx - ParaMEDMEMTest_NonCoincidentDEC.cxx - ParaMEDMEMTest_OverlapDEC.cxx - MPIAccessDECTest.cxx - test_AllToAllDEC.cxx - test_AllToAllvDEC.cxx - test_AllToAllTimeDEC.cxx - test_AllToAllvTimeDEC.cxx - test_AllToAllvTimeDoubleDEC.cxx - MPIAccessTest.cxx - test_MPI_Access_Send_Recv.cxx - test_MPI_Access_Cyclic_Send_Recv.cxx - test_MPI_Access_SendRecv.cxx - test_MPI_Access_ISend_IRecv.cxx - test_MPI_Access_Cyclic_ISend_IRecv.cxx - test_MPI_Access_ISendRecv.cxx - test_MPI_Access_Probe.cxx - test_MPI_Access_IProbe.cxx - test_MPI_Access_Cancel.cxx - test_MPI_Access_Send_Recv_Length.cxx - test_MPI_Access_ISend_IRecv_Length.cxx - test_MPI_Access_ISend_IRecv_Length_1.cxx - test_MPI_Access_Time.cxx - test_MPI_Access_Time_0.cxx - test_MPI_Access_ISend_IRecv_BottleNeck.cxx - ) - -ADD_LIBRARY(ParaMEDMEMTest SHARED ${ParaMEDMEMTest_SOURCES}) -SET_TARGET_PROPERTIES(ParaMEDMEMTest PROPERTIES COMPILE_FLAGS "") -TARGET_LINK_LIBRARIES(ParaMEDMEMTest paramedmem paramedloader medcouplingremapper ${CPPUNIT_LIBRARIES}) -INSTALL(TARGETS ParaMEDMEMTest DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -SET(TESTSParaMEDMEM) -SET(TestParaMEDMEM_SOURCES - TestParaMEDMEM.cxx - ) -SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestParaMEDMEM) - -SET(TestMPIAccessDEC_SOURCES - TestMPIAccessDEC.cxx - ) -SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestMPIAccessDEC) - -SET(TestMPIAccess_SOURCES - TestMPIAccess.cxx - ) -SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestMPIAccess) - -SET(test_perf_SOURCES - test_perf.cxx - ) -SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} test_perf) - -IF(MPI2_IS_OK) - SET(ParaMEDMEMTestMPI2_1_SOURCES - MPI2Connector.cxx - ParaMEDMEMTestMPI2_1.cxx - ) - SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} ParaMEDMEMTestMPI2_1) - - SET(ParaMEDMEMTestMPI2_2_SOURCES - MPI2Connector.cxx - ParaMEDMEMTestMPI2_2.cxx - ) - SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} ParaMEDMEMTestMPI2_2) -ENDIF(MPI2_IS_OK) - -FOREACH(bintestparamem ${TESTSParaMEDMEM}) - ADD_EXECUTABLE(${bintestparamem} ${${bintestparamem}_SOURCES}) - TARGET_LINK_LIBRARIES(${bintestparamem} ParaMEDMEMTest) -ENDFOREACH(bintestparamem ${TESTSParaMEDMEM}) - -# Now add CMake tests - test_perf, ParaMEDMEMTestMPI2_1 and ParaMEDMEMTestMPI2_2 -# are left aside, as they are too specific -# -# -- some tests require 2, 3, 4 or 5 procs -- -ADD_TEST(NAME TestParaMEDMEM_Proc2 COMMAND ${MPIEXEC} -np 2 $<TARGET_FILE:TestParaMEDMEM>) -ADD_TEST(NAME TestParaMEDMEM_Proc3 COMMAND ${MPIEXEC} -np 3 $<TARGET_FILE:TestParaMEDMEM>) -ADD_TEST(NAME TestParaMEDMEM_Proc4 COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:TestParaMEDMEM>) -ADD_TEST(NAME TestParaMEDMEM_Proc5 COMMAND ${MPIEXEC} -np 5 $<TARGET_FILE:TestParaMEDMEM>) - -ADD_TEST(NAME TestMPIAccess_Proc2 COMMAND ${MPIEXEC} -np 2 $<TARGET_FILE:TestMPIAccess>) -ADD_TEST(NAME TestMPIAccess_Proc3 COMMAND ${MPIEXEC} -np 3 $<TARGET_FILE:TestMPIAccess>) - -ADD_TEST(NAME TestMPIAccessDEC_Proc4 COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:TestMPIAccessDEC>) - -# Installation rules -INSTALL(TARGETS ${TESTSParaMEDMEM} DESTINATION ${MEDCOUPLING_INSTALL_BINS}) -SET(COMMON_HEADERS_HXX - MPIMainTest.hxx - MPIAccessDECTest.hxx - MPIAccessTest.hxx - ParaMEDMEMTest.hxx - MPI2Connector.hxx -) -INSTALL(FILES ${COMMON_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) diff --git a/medtool/src/ParaMEDMEMTest/MPI2Connector.cxx b/medtool/src/ParaMEDMEMTest/MPI2Connector.cxx deleted file mode 100644 index 616ac138f..000000000 --- a/medtool/src/ParaMEDMEMTest/MPI2Connector.cxx +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MPI2Connector.hxx" - -#include <iostream> -#include <cstring> - -#ifndef WIN32 -#include <unistd.h> -#endif - -MPI2Connector::MPI2Connector() -{ - MPI_Comm_size( MPI_COMM_WORLD, &_nb_proc ); - MPI_Comm_rank( MPI_COMM_WORLD, &_num_proc ); -} - -MPI2Connector::~MPI2Connector() -{ -} - -MPI_Comm MPI2Connector::remoteMPI2Connect(const std::string& service) -{ - int i; - char port_name[MPI_MAX_PORT_NAME]; - char port_name_clt[MPI_MAX_PORT_NAME]; - std::ostringstream msg; - MPI_Comm icom; - - if( service.size() == 0 ) - { - msg << "[" << _num_proc << "] You have to give a service name !"; - std::cerr << msg.str().c_str() << std::endl; - throw std::exception(); - } - - _srv = false; - - MPI_Barrier(MPI_COMM_WORLD); - - MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); - if( _num_proc == 0 ) - { - /* rank 0 try to be a server. If service is already published, try to be a cient */ - MPI_Open_port(MPI_INFO_NULL, port_name); - if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ) - { - std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl; - MPI_Close_port( port_name ); - } - else if ( MPI_Publish_name((char*)service.c_str(), MPI_INFO_NULL, port_name) == MPI_SUCCESS ) - { - _srv = true; - _port_name = port_name; - std::cerr << "[" << _num_proc << "] service " << service << " available at " << port_name << std::endl; - } - else if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ) - { - std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl; - MPI_Close_port( port_name ); - } - else - { - msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt; - std::cerr << msg.str().c_str() << std::endl; - throw std::exception(); - } - } - else - { - i=0; - /* Waiting rank 0 publish name and try to be a client */ - while ( i != TIMEOUT ) - { - sleep(1); - if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ) - { - std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl; - break; - } - i++; - } - if(i==TIMEOUT) - { - msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt; - std::cerr << msg.str().c_str() << std::endl; - throw std::exception(); - } - } - MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL); - - /* If rank 0 is server, all processes call MPI_Comm_accept */ - /* If rank 0 is not server, all processes call MPI_Comm_connect */ - int srv = (int)_srv; - MPI_Bcast(&srv,1,MPI_INT,0,MPI_COMM_WORLD); - _srv = (bool)srv; - if ( _srv ) - MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom ); - else - MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom ); - - /* create global communicator: servers have low index in global communicator*/ - MPI_Intercomm_merge(icom,!_srv,&_gcom); - - /* only rank 0 can be server for unpublish name */ - if(_num_proc != 0) _srv = false; - - return _gcom; - -} - -void MPI2Connector::remoteMPI2Disconnect(const std::string& service) -{ - std::ostringstream msg; - - if( service.size() == 0 ) - { - msg << "[" << _num_proc << "] You have to give a service name !"; - std::cerr << msg.str().c_str() << std::endl; - throw std::exception(); - } - - MPI_Comm_disconnect( &_gcom ); - if ( _srv ) - { - - char port_name[MPI_MAX_PORT_NAME]; - strcpy(port_name,_port_name.c_str()); - - MPI_Unpublish_name((char*)service.c_str(), MPI_INFO_NULL, port_name); - std::cerr << "[" << _num_proc << "] " << service << ": close port " << _port_name << std::endl; - MPI_Close_port( port_name ); - } - -} - diff --git a/medtool/src/ParaMEDMEMTest/MPI2Connector.hxx b/medtool/src/ParaMEDMEMTest/MPI2Connector.hxx deleted file mode 100644 index 57680b2c3..000000000 --- a/medtool/src/ParaMEDMEMTest/MPI2Connector.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MPI2CONNECTOR_HXX__ -#define __MPI2CONNECTOR_HXX__ - -#include <mpi.h> -#include <string> -#include <sstream> - -class MPI2Connector -{ -public: - MPI2Connector(); - ~MPI2Connector(); - // MPI2 connection - MPI_Comm remoteMPI2Connect(const std::string& service); - // MPI2 disconnection - void remoteMPI2Disconnect(const std::string& service); -private: - // Processus id - int _num_proc; - // Processus size - int _nb_proc; - MPI_Comm _gcom; - bool _srv; - std::string _port_name; -private: - static const int TIMEOUT=5; -}; - -#endif diff --git a/medtool/src/ParaMEDMEMTest/MPIAccessDECTest.cxx b/medtool/src/ParaMEDMEMTest/MPIAccessDECTest.cxx deleted file mode 100644 index c757e6e4f..000000000 --- a/medtool/src/ParaMEDMEMTest/MPIAccessDECTest.cxx +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MPIAccessDECTest.hxx" -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> - -#ifndef WIN32 -#include <unistd.h> -#endif - -using namespace std; - - - -/*! - * Tool to remove temporary files. - * Allows automatique removal of temporary files in case of test failure. - */ -MPIAccessDECTest_TmpFilesRemover::~MPIAccessDECTest_TmpFilesRemover() -{ - set<string>::iterator it = myTmpFiles.begin(); - for (; it != myTmpFiles.end(); it++) { - if (access((*it).data(), F_OK) == 0) - remove((*it).data()); - } - myTmpFiles.clear(); - //cout << "~MPIAccessTest_TmpFilesRemover()" << endl; -} - -bool MPIAccessDECTest_TmpFilesRemover::Register(const string theTmpFile) -{ - return (myTmpFiles.insert(theTmpFile)).second; -} diff --git a/medtool/src/ParaMEDMEMTest/MPIAccessDECTest.hxx b/medtool/src/ParaMEDMEMTest/MPIAccessDECTest.hxx deleted file mode 100644 index 5afb6e5d7..000000000 --- a/medtool/src/ParaMEDMEMTest/MPIAccessDECTest.hxx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _MPIACCESSDECTEST_HXX_ -#define _MPIACCESSDECTEST_HXX_ - -#include <cppunit/extensions/HelperMacros.h> - -#include <set> -#include <string> -#include <iostream> -#include "mpi.h" - -// (ABN]: too many text output in the MPIAccesTest - this renders -// the analysis complicated: -#define MPI_ACCESS_VERBOSE 0 -#define debugStream \ - if (!MPI_ACCESS_VERBOSE) {} \ - else std::cout - -class MPIAccessDECTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MPIAccessDECTest ); - // CPPUNIT_TEST( test_AllToAllDECSynchronousPointToPoint ) ; - CPPUNIT_TEST( test_AllToAllDECAsynchronousPointToPoint ) ; - //CPPUNIT_TEST( test_AllToAllvDECSynchronousPointToPoint ) ; - CPPUNIT_TEST( test_AllToAllvDECAsynchronousPointToPoint ) ; - //CPPUNIT_TEST( test_AllToAllTimeDECSynchronousPointToPoint ) ; - CPPUNIT_TEST( test_AllToAllTimeDECAsynchronousPointToPoint ) ; - CPPUNIT_TEST( test_AllToAllvTimeDECSynchronousNative ) ; - //CPPUNIT_TEST( test_AllToAllvTimeDECSynchronousPointToPoint ) ; - CPPUNIT_TEST( test_AllToAllvTimeDECAsynchronousPointToPoint ) ; - //CPPUNIT_TEST( test_AllToAllvTimeDoubleDECSynchronousPointToPoint ) ; - CPPUNIT_TEST( test_AllToAllvTimeDoubleDECAsynchronousPointToPoint ) ; - CPPUNIT_TEST_SUITE_END(); - - -public: - - MPIAccessDECTest():CppUnit::TestFixture(){} - ~MPIAccessDECTest(){} - void setUp(){} - void tearDown(){} - void test_AllToAllDECSynchronousPointToPoint() ; - void test_AllToAllDECAsynchronousPointToPoint() ; - void test_AllToAllvDECSynchronousPointToPoint() ; - void test_AllToAllvDECAsynchronousPointToPoint() ; - void test_AllToAllTimeDECSynchronousPointToPoint() ; - void test_AllToAllTimeDECAsynchronousPointToPoint() ; - void test_AllToAllvTimeDECSynchronousNative() ; - void test_AllToAllvTimeDECSynchronousPointToPoint() ; - void test_AllToAllvTimeDECAsynchronousPointToPoint() ; - void test_AllToAllvTimeDoubleDECSynchronousPointToPoint() ; - void test_AllToAllvTimeDoubleDECAsynchronousPointToPoint() ; - -private: - void test_AllToAllDEC( bool Asynchronous ) ; - void test_AllToAllvDEC( bool Asynchronous ) ; - void test_AllToAllTimeDEC( bool Asynchronous ) ; - void test_AllToAllvTimeDEC( bool Asynchronous , bool UseMPINative ) ; - void test_AllToAllvTimeDoubleDEC( bool Asynchronous ) ; - }; - -// to automatically remove temporary files from disk -class MPIAccessDECTest_TmpFilesRemover -{ -public: - MPIAccessDECTest_TmpFilesRemover() {} - ~MPIAccessDECTest_TmpFilesRemover(); - bool Register(const std::string theTmpFile); - -private: - std::set<std::string> myTmpFiles; -}; - -/*! - * Tool to print array to stream. - */ -template<class T> -void MPIAccessDECTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) -{ - stream << text << ": {"; - if (length > 0) { - stream << array[0]; - for (int i = 1; i < length; i++) { - stream << ", " << array[i]; - } - } - stream << "}" << std::endl; -}; - -#endif diff --git a/medtool/src/ParaMEDMEMTest/MPIAccessTest.cxx b/medtool/src/ParaMEDMEMTest/MPIAccessTest.cxx deleted file mode 100644 index a9714f841..000000000 --- a/medtool/src/ParaMEDMEMTest/MPIAccessTest.cxx +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> - -#ifndef WIN32 -#include <unistd.h> -#endif - -using namespace std; - - - -/*! - * Tool to remove temporary files. - * Allows automatique removal of temporary files in case of test failure. - */ -MPIAccessTest_TmpFilesRemover::~MPIAccessTest_TmpFilesRemover() -{ - set<string>::iterator it = myTmpFiles.begin(); - for (; it != myTmpFiles.end(); it++) { - if (access((*it).data(), F_OK) == 0) - remove((*it).data()); - } - myTmpFiles.clear(); - //cout << "~MPIAccessTest_TmpFilesRemover()" << endl; -} - -bool MPIAccessTest_TmpFilesRemover::Register(const string theTmpFile) -{ - return (myTmpFiles.insert(theTmpFile)).second; -} diff --git a/medtool/src/ParaMEDMEMTest/MPIAccessTest.hxx b/medtool/src/ParaMEDMEMTest/MPIAccessTest.hxx deleted file mode 100644 index f98fb5578..000000000 --- a/medtool/src/ParaMEDMEMTest/MPIAccessTest.hxx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _MPIACCESSTEST_HXX_ -#define _MPIACCESSTEST_HXX_ - -#include <cppunit/extensions/HelperMacros.h> - -#include <set> -#include <string> -#include <iostream> -#include "mpi.h" - -// (ABN]: too many text output in the MPIAccesTest - this renders -// the analysis complicated: -#define MPI_ACCESS_VERBOSE 0 -#define debugStream \ - if (!MPI_ACCESS_VERBOSE) {} \ - else std::cout - -class MPIAccessTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MPIAccessTest ); - CPPUNIT_TEST( test_MPI_Access_Send_Recv ) ; - CPPUNIT_TEST( test_MPI_Access_Cyclic_Send_Recv ) ; - CPPUNIT_TEST( test_MPI_Access_SendRecv ) ; - CPPUNIT_TEST( test_MPI_Access_ISend_IRecv ) ; - CPPUNIT_TEST( test_MPI_Access_Cyclic_ISend_IRecv ) ; - CPPUNIT_TEST( test_MPI_Access_ISendRecv ) ; - CPPUNIT_TEST( test_MPI_Access_Probe ) ; - CPPUNIT_TEST( test_MPI_Access_IProbe ) ; - CPPUNIT_TEST( test_MPI_Access_Cancel ) ; - CPPUNIT_TEST( test_MPI_Access_Send_Recv_Length ) ; - CPPUNIT_TEST( test_MPI_Access_ISend_IRecv_Length ) ; - CPPUNIT_TEST( test_MPI_Access_ISend_IRecv_Length_1 ) ; - CPPUNIT_TEST( test_MPI_Access_Time ) ; - CPPUNIT_TEST( test_MPI_Access_Time_0 ) ; - CPPUNIT_TEST( test_MPI_Access_ISend_IRecv_BottleNeck ) ; - CPPUNIT_TEST_SUITE_END(); - - -public: - - MPIAccessTest():CppUnit::TestFixture(){} - ~MPIAccessTest(){} - void setUp(){} - void tearDown(){} - void test_MPI_Access_Send_Recv() ; - void test_MPI_Access_Cyclic_Send_Recv() ; - void test_MPI_Access_SendRecv() ; - void test_MPI_Access_ISend_IRecv() ; - void test_MPI_Access_Cyclic_ISend_IRecv() ; - void test_MPI_Access_ISendRecv() ; - void test_MPI_Access_Probe() ; - void test_MPI_Access_IProbe() ; - void test_MPI_Access_Cancel() ; - void test_MPI_Access_Send_Recv_Length() ; - void test_MPI_Access_ISend_IRecv_Length() ; - void test_MPI_Access_ISend_IRecv_Length_1() ; - void test_MPI_Access_Time() ; - void test_MPI_Access_Time_0() ; - void test_MPI_Access_ISend_IRecv_BottleNeck() ; - -private: - }; - -// to automatically remove temporary files from disk -class MPIAccessTest_TmpFilesRemover -{ -public: - MPIAccessTest_TmpFilesRemover() {} - ~MPIAccessTest_TmpFilesRemover(); - bool Register(const std::string theTmpFile); - -private: - std::set<std::string> myTmpFiles; -}; - -/*! - * Tool to print array to stream. - */ -template<class T> -void MPIAccessTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) -{ - stream << text << ": {"; - if (length > 0) { - stream << array[0]; - for (int i = 1; i < length; i++) { - stream << ", " << array[i]; - } - } - stream << "}" << std::endl; -} - -#endif diff --git a/medtool/src/ParaMEDMEMTest/MPIMainTest.hxx b/medtool/src/ParaMEDMEMTest/MPIMainTest.hxx deleted file mode 100644 index eec6e5a6f..000000000 --- a/medtool/src/ParaMEDMEMTest/MPIMainTest.hxx +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _MPIMAINTEST_HXX_ -#define _MPIMAINTEST_HXX_ - -#include <cppunit/CompilerOutputter.h> -#include <cppunit/TestResult.h> -#include <cppunit/TestResultCollector.h> -#include <cppunit/TextTestProgressListener.h> -#include <cppunit/BriefTestProgressListener.h> -#include <cppunit/extensions/TestFactoryRegistry.h> -#include <cppunit/TestRunner.h> -#include <stdexcept> - -#include <mpi.h> - -#include <iostream> -#include <fstream> -#ifndef WIN32 -#include <fpu_control.h> -#endif - -// ============================================================================ -/*! - * Main program source for Unit Tests with cppunit package does not depend - * on actual tests, so we use the same for all partial unit tests. - */ -// ============================================================================ - -int main(int argc, char* argv[]) -{ -#ifndef WIN32 - fpu_control_t cw = _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM); - _FPU_SETCW(cw); -#endif - MPI_Init(&argc,&argv); - int rank; - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - // --- Create the event manager and test controller - CPPUNIT_NS::TestResult controller; - - // --- Add a listener that colllects test result - CPPUNIT_NS::TestResultCollector result; - controller.addListener( &result ); - - // --- Add a listener that print dots as test run. -#ifdef WIN32 - CPPUNIT_NS::TextTestProgressListener progress; -#else - CPPUNIT_NS::BriefTestProgressListener progress; -#endif - controller.addListener( &progress ); - - // --- Get the top level suite from the registry - - CPPUNIT_NS::Test *suite = - CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); - - // --- Adds the test to the list of test to run - - CPPUNIT_NS::TestRunner runner; - runner.addTest( suite ); - runner.run( controller); - - // --- Print test in a compiler compatible format. - - std::ostringstream testFileName; - testFileName<<"UnitTestsResult"<<rank; - std::ofstream testFile; - testFile.open(testFileName.str().c_str(), std::ios::out | std::ios::trunc); - //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); - CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); - outputter.write(); - - // --- Run the tests. - - bool wasSucessful = result.wasSuccessful(); - testFile.close(); - - // --- Return error code 1 if the one of test failed. - - MPI_Finalize(); - - return wasSucessful ? 0 : 1; -} - -#endif diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.cxx deleted file mode 100644 index dab88ab1d..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.cxx +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> -#include <list> -#include <stdexcept> -#include <stdlib.h> - -#ifndef WIN32 -#include <unistd.h> -#endif - -std::string ParaMEDMEMTest::getResourceFile( const std::string& filename ) -{ - std::string resourceFile = ""; - - if ( getenv("MEDCOUPLING_ROOT_DIR") ) { - // use MEDCOUPLING_ROOT_DIR env.var - resourceFile = getenv("MEDCOUPLING_ROOT_DIR"); - resourceFile += "/share/resources/med/"; - } - else { - resourceFile = get_current_dir_name(); - resourceFile += "/../../resources/"; - } - - resourceFile += filename; - return resourceFile; -} - - -//================================================================================ -/*! - * \brief Returns writable temporary directory - * \return full path to the temporary directory - */ -//================================================================================ - -std::string ParaMEDMEMTest::getTmpDirectory() -{ - std::string path; - - std::list<std::string> dirs; - if ( getenv("TMP") ) dirs.push_back( getenv("TMP" )); - if ( getenv("TMPDIR") ) dirs.push_back( getenv("TMPDIR" )); - dirs.push_back( "/tmp" ); - - std::string tmpd = ""; - for ( std::list<std::string>::iterator dir = dirs.begin(); dir != dirs.end() && tmpd == "" ; ++dir ) { - if ( access( dir->data(), W_OK ) == 0 ) { - tmpd = dir->data(); - } - } - - if ( tmpd == "" ) - throw std::runtime_error("Can't find writable temporary directory. Set TMP environment variable"); - - return tmpd; -} - -//================================================================================ -/*! - * \brief Creates a copy of source file (if source file is specified) - * in the temporary directory and returns a path to the tmp file - * - * \param tmpfile name of the temporary file (without path) - * \param srcfile source file - * \return path to the temporary file - */ -//================================================================================ -std::string ParaMEDMEMTest::makeTmpFile( const std::string& tmpfile, const std::string& srcfile ) -{ - std::string tmpf = getTmpDirectory() + "/" + tmpfile; - if ( srcfile != "" ) { - std::string cmd = "cp " + srcfile + " " + tmpf + " ; chmod +w " + tmpf; - system( cmd.c_str() ); - } - return tmpf; -} - - -/*! - * Tool to remove temporary files. - * Allows automatique removal of temporary files in case of test failure. - */ -ParaMEDMEMTest_TmpFilesRemover::~ParaMEDMEMTest_TmpFilesRemover() -{ - std::set<std::string>::iterator it = myTmpFiles.begin(); - for (; it != myTmpFiles.end(); it++) { - if (access((*it).data(), F_OK) == 0) - remove((*it).data()); - } - myTmpFiles.clear(); - //cout << "~ParaMEDMEMTest_TmpFilesRemover()" << endl; -} - -bool ParaMEDMEMTest_TmpFilesRemover::Register(const std::string theTmpFile) -{ - return (myTmpFiles.insert(theTmpFile)).second; -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx deleted file mode 100644 index 7deb11dca..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _ParaMEDMEMTEST_HXX_ -#define _ParaMEDMEMTEST_HXX_ - -#include <cppunit/extensions/HelperMacros.h> - -#include <set> -#include <string> -#include <iostream> -#include "mpi.h" - - -class ParaMEDMEMTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( ParaMEDMEMTest ); - CPPUNIT_TEST(testMPIProcessorGroup_constructor); // 1 and 2 procs - CPPUNIT_TEST(testMPIProcessorGroup_boolean); // 1 and 2 procs - CPPUNIT_TEST(testMPIProcessorGroup_rank); // >=2 procs - CPPUNIT_TEST(testBlockTopology_constructor); // >=2 procs - CPPUNIT_TEST(testBlockTopology_serialize); // 1 proc - CPPUNIT_TEST(testInterpKernelDEC_1D); // 5 procs - CPPUNIT_TEST(testInterpKernelDEC_2DCurve); // 5 procs - CPPUNIT_TEST(testInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testInterpKernelDEC2_2D); // 5 procs - CPPUNIT_TEST(testInterpKernelDEC_2DP0P1); // Not impl. - CPPUNIT_TEST(testInterpKernelDEC_3D); // 3 procs - CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P0); // 5 procs - CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0); // 5 procs - CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0); // 3 procs - CPPUNIT_TEST(testInterpKernelDECPartialProcs); // 3 procs - CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox); // 3 procs - CPPUNIT_TEST(testOverlapDEC1); // 3 procs - CPPUNIT_TEST(testOverlapDEC1_bis); // 3 procs - CPPUNIT_TEST(testOverlapDEC1_ter); // 3 procs - CPPUNIT_TEST(testOverlapDEC2); // 3 procs - CPPUNIT_TEST(testOverlapDEC2_bis); // 3 procs - CPPUNIT_TEST(testOverlapDEC2_ter); // 3 procs - CPPUNIT_TEST(testOverlapDEC3); // 2 procs - CPPUNIT_TEST(testOverlapDEC4); // 2 procs - - CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D);// 5 procs - CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D); // 5 procs - CPPUNIT_TEST(testSynchronousEqualInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testSynchronousFasterSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testSynchronousSlowerSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testSynchronousSlowSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testSynchronousFastSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testAsynchronousEqualInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testAsynchronousFasterSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testAsynchronousSlowerSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testAsynchronousSlowSourceInterpKernelDEC_2D); // 5 procs - CPPUNIT_TEST(testAsynchronousFastSourceInterpKernelDEC_2D); // 5 procs -#ifdef MED_ENABLE_FVM - //can be added again after FVM correction for 2D - // CPPUNIT_TEST(testNonCoincidentDEC_2D); - CPPUNIT_TEST(testNonCoincidentDEC_3D); -#endif - CPPUNIT_TEST(testStructuredCoincidentDEC); // 5 procs - CPPUNIT_TEST(testICoco1); // 2 procs - CPPUNIT_TEST(testGauthier1); // 4 procs - CPPUNIT_TEST(testGauthier2); // >= 2 procs - CPPUNIT_TEST(testGauthier3); // 4 procs - CPPUNIT_TEST(testGauthier4); // 3 procs - CPPUNIT_TEST(testFabienAPI1); // 3 procs - CPPUNIT_TEST(testFabienAPI2); // 3 procs - - CPPUNIT_TEST_SUITE_END(); - -public: - - ParaMEDMEMTest():CppUnit::TestFixture(){} - ~ParaMEDMEMTest(){} - void setUp(){} - void tearDown(){} - void testMPIProcessorGroup_constructor(); - void testMPIProcessorGroup_boolean(); - void testMPIProcessorGroup_rank(); - void testBlockTopology_constructor(); - void testBlockTopology_serialize(); - void testInterpKernelDEC_1D(); - void testInterpKernelDEC_2DCurve(); - void testInterpKernelDEC_2D(); - void testInterpKernelDEC2_2D(); - void testInterpKernelDEC_2DP0P1(); - void testInterpKernelDEC_3D(); - void testInterpKernelDECNonOverlapp_2D_P0P0(); - void testInterpKernelDECNonOverlapp_2D_P0P1P1P0(); - void testInterpKernelDEC2DM1D_P0P0(); - void testInterpKernelDECPartialProcs(); - void testInterpKernelDEC3DSurfEmptyBBox(); - void testOverlapDEC1(); - void testOverlapDEC1_bis(); - void testOverlapDEC1_ter(); - void testOverlapDEC2(); - void testOverlapDEC2_bis(); - void testOverlapDEC2_ter(); - void testOverlapDEC3(); -// void testOverlapDEC3_bis(); - void testOverlapDEC4(); -#ifdef MED_ENABLE_FVM - void testNonCoincidentDEC_2D(); - void testNonCoincidentDEC_3D(); -#endif - void testStructuredCoincidentDEC(); - void testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D(); - void testSynchronousEqualInterpKernelWithoutInterpDEC_2D(); - void testSynchronousEqualInterpKernelDEC_2D(); - void testSynchronousFasterSourceInterpKernelDEC_2D(); - void testSynchronousSlowerSourceInterpKernelDEC_2D(); - void testSynchronousSlowSourceInterpKernelDEC_2D(); - void testSynchronousFastSourceInterpKernelDEC_2D(); - - void testAsynchronousEqualInterpKernelDEC_2D(); - void testAsynchronousFasterSourceInterpKernelDEC_2D(); - void testAsynchronousSlowerSourceInterpKernelDEC_2D(); - void testAsynchronousSlowSourceInterpKernelDEC_2D(); - void testAsynchronousFastSourceInterpKernelDEC_2D(); - // - void testICoco1(); - void testGauthier1(); - void testGauthier2(); - void testGauthier3(); - void testGauthier4(); - void testFabienAPI1(); - void testFabienAPI2(); - - std::string getResourceFile( const std::string& ); - std::string getTmpDirectory(); - std::string makeTmpFile( const std::string&, const std::string& = "" ); - -private: -#ifdef MED_ENABLE_FVM - void testNonCoincidentDEC(const std::string& filename1, - const std::string& meshname1, - const std::string& filename2, - const std::string& meshname2, - int nbprocsource, double epsilon); -#endif - void testAsynchronousInterpKernelDEC_2D(double dtA, double tmaxA, - double dtB, double tmaxB, - bool WithPointToPoint, bool Asynchronous, bool WithInterp, const char *srcMeth, const char *targetMeth); - void testInterpKernelDEC_2D_(const char *srcMeth, const char *targetMeth); - void testInterpKernelDEC2_2D_(const char *srcMeth, const char *targetMeth); - void testInterpKernelDEC_3D_(const char *srcMeth, const char *targetMeth); - -}; - -// to automatically remove temporary files from disk -class ParaMEDMEMTest_TmpFilesRemover -{ -public: - ParaMEDMEMTest_TmpFilesRemover() {} - ~ParaMEDMEMTest_TmpFilesRemover(); - bool Register(const std::string theTmpFile); - -private: - std::set<std::string> myTmpFiles; -}; - -/*! - * Tool to print array to stream. - */ -template<class T> -void ParaMEDMEMTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) -{ - stream << text << ": {"; - if (length > 0) { - stream << array[0]; - for (int i = 1; i < length; i++) { - stream << ", " << array[i]; - } - } - stream << "}" << std::endl; -} - -#endif diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx deleted file mode 100644 index e56972116..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <cppunit/extensions/HelperMacros.h> - -#include "MPI2Connector.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "InterpKernelDEC.hxx" -#include "MPIProcessorGroup.hxx" -#include "CommInterface.hxx" - -#include <mpi.h> -#include <iostream> -#include <stdlib.h> - -class MPI2ParaMEDMEMTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MPI2ParaMEDMEMTest ); - CPPUNIT_TEST( testBasicMPI2_1 ); - CPPUNIT_TEST_SUITE_END(); -public: - void testBasicMPI2_1(); -}; - -using namespace ParaMEDMEM; - -void MPI2ParaMEDMEMTest::testBasicMPI2_1() -{ - int lsize, lrank, gsize, grank; - MPI_Comm gcom; - std::string service = "SERVICE"; - std::ostringstream meshfilename, meshname; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::MEDCouplingUMesh *mesh; - ParaMEDMEM::ParaFIELD *parafield=0; - ParaMEDMEM::CommInterface *interface; - ParaMEDMEM::MPIProcessorGroup *source, *target; - - MPI_Comm_size( MPI_COMM_WORLD, &lsize ); - MPI_Comm_rank( MPI_COMM_WORLD, &lrank ); - if(lsize!=2) - { - CPPUNIT_ASSERT(false); - return; - } - - /* Connection to remote programm */ - MPI2Connector *mpio = new MPI2Connector; - gcom = mpio->remoteMPI2Connect(service); - MPI_Comm_size( gcom, &gsize ); - MPI_Comm_rank( gcom, &grank ); - if(gsize!=5) - { - CPPUNIT_ASSERT(false); - return; - } - interface = new ParaMEDMEM::CommInterface; - source = new ParaMEDMEM::MPIProcessorGroup(*interface,0,lsize-1,gcom); - target = new ParaMEDMEM::MPIProcessorGroup(*interface,lsize,gsize-1,gcom); - - const double sourceCoordsAll[2][8]={{0.4,0.5,0.4,1.5,1.6,1.5,1.6,0.5}, - {0.3,-0.5,1.6,-0.5,1.6,-1.5,0.3,-1.5}}; - - int conn4All[8]={0,1,2,3,4,5,6,7}; - - std::ostringstream stream; stream << "sourcemesh2D proc " << grank; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - const double *sourceCoords=sourceCoordsAll[grank]; - std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*source,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - double *value=parafield->getField()->getArray()->getPointer(); - value[0]=34+13*((double)grank); - - ParaMEDMEM::InterpKernelDEC dec(*source,*target); - parafield->getField()->setNature(ConservativeVolumic); - - - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - /* Deconnection of remote programm */ - mpio->remoteMPI2Disconnect(service); - /* clean-up */ - delete mpio; - delete parafield; - mesh->decrRef(); - delete paramesh; - delete source; - delete target; - delete interface; -} - -CPPUNIT_TEST_SUITE_REGISTRATION( MPI2ParaMEDMEMTest ); - -#include "MPIMainTest.hxx" diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx deleted file mode 100644 index 102443ef0..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <cppunit/extensions/HelperMacros.h> - -#include "MPI2Connector.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "InterpKernelDEC.hxx" -#include "MPIProcessorGroup.hxx" -#include "CommInterface.hxx" - -#include <mpi.h> -#include <iostream> -#include <stdlib.h> - -class MPI2ParaMEDMEMTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MPI2ParaMEDMEMTest ); - CPPUNIT_TEST( testBasicMPI2_1 ); - CPPUNIT_TEST_SUITE_END(); -public: - void testBasicMPI2_1(); -}; - -using namespace ParaMEDMEM; - -void MPI2ParaMEDMEMTest::testBasicMPI2_1() -{ - int lsize, lrank, gsize, grank; - MPI_Comm gcom; - std::string service = "SERVICE"; - std::ostringstream meshfilename, meshname; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::ParaFIELD *parafield=0; - ParaMEDMEM::CommInterface* interface; - ParaMEDMEM::MPIProcessorGroup* source, *target; - - MPI_Comm_size( MPI_COMM_WORLD, &lsize ); - MPI_Comm_rank( MPI_COMM_WORLD, &lrank ); - if(lsize!=3) - { - CPPUNIT_ASSERT(false); - return; - } - - /* Connection to remote programm */ - MPI2Connector *mpio = new MPI2Connector; - gcom = mpio->remoteMPI2Connect(service); - - MPI_Comm_size( gcom, &gsize ); - MPI_Comm_rank( gcom, &grank ); - if(gsize!=5) - { - CPPUNIT_ASSERT(false); - return; - } - - interface = new ParaMEDMEM::CommInterface; - source = new ParaMEDMEM::MPIProcessorGroup(*interface,0,gsize-lsize-1,gcom); - target = new ParaMEDMEM::MPIProcessorGroup(*interface,gsize-lsize,gsize-1,gcom); - - const double targetCoordsAll[3][16]={{0.7,1.45,0.7,1.65,0.9,1.65,0.9,1.45, 1.1,1.4,1.1,1.6,1.3,1.6,1.3,1.4}, - {0.7,-0.6,0.7,0.7,0.9,0.7,0.9,-0.6, 1.1,-0.7,1.1,0.6,1.3,0.6,1.3,-0.7}, - {0.7,-1.55,0.7,-1.35,0.9,-1.35,0.9,-1.55, 1.1,-1.65,1.1,-1.45,1.3,-1.45,1.3,-1.65}}; - int conn4All[8]={0,1,2,3,4,5,6,7}; - double targetResults[3][2]={{34.,34.},{38.333333333333336,42.666666666666664},{47.,47.}}; - - std::ostringstream stream; stream << "targetmesh2D proc " << grank-(gsize-lsize); - mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(8,2); - const double *targetCoords=targetCoordsAll[grank-(gsize-lsize)]; - std::copy(targetCoords,targetCoords+16,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH (mesh,*target,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - - ParaMEDMEM::InterpKernelDEC dec(*source,*target); - parafield->getField()->setNature(ConservativeVolumic); - - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults[grank-(gsize-lsize)]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - /* Deconnection of remote programm */ - mpio->remoteMPI2Disconnect(service); - /* clean-up */ - delete mpio; - delete parafield; - mesh->decrRef(); - delete paramesh; - delete source; - delete target; - delete interface; -} - -CPPUNIT_TEST_SUITE_REGISTRATION( MPI2ParaMEDMEMTest ); - -#include "MPIMainTest.hxx" diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_BlockTopology.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_BlockTopology.cxx deleted file mode 100644 index dc129ccf1..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_BlockTopology.cxx +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "InterpolationUtils.hxx" -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "BlockTopology.hxx" - -#include <string> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - - -using namespace std; -using namespace ParaMEDMEM; - -/* - * Check methods defined in BlockTopology.hxx - * - BlockTopology(){}; - BlockTopology(const ProcessorGroup& group, const MEDMEM::GRID& grid); - BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo); - (+) BlockTopology(const ProcessorGroup& group, int nb_elem); - virtual ~BlockTopology(); - (+) inline int getNbElements()const; - (+) inline int getNbLocalElements() const; - const ProcessorGroup* getProcGroup()const {return _proc_group;}; - (+) inline std::pair<int,int> globalToLocal (const int) const ; - (+) inline int localToGlobal (const std::pair<int,int>) const; - (+) std::vector<std::pair<int,int> > getLocalArrayMinMax() const ; - (+) int getDimension() const {return _dimension;}; - (+) void serialize(int* & serializer, int& size) const ; - (+) void unserialize(const int* serializer, const CommInterface& comm_interface); - - */ - -void ParaMEDMEMTest::testBlockTopology_constructor() -{ - //test constructor - int size; - MPI_Comm_size(MPI_COMM_WORLD,&size); - int rank; - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - CommInterface interface; - MPIProcessorGroup group(interface); - BlockTopology blocktopo(group,1); - CPPUNIT_ASSERT_EQUAL(1,blocktopo.getNbLocalElements()); - CPPUNIT_ASSERT_EQUAL(size,blocktopo.getNbElements()); - CPPUNIT_ASSERT_EQUAL(1,blocktopo.getDimension()); - - //checking access methods - BlockTopology blocktopo2(group,2); - std::pair<int,int> local= blocktopo2.globalToLocal(0); - CPPUNIT_ASSERT_EQUAL(local.first,0); - CPPUNIT_ASSERT_EQUAL(local.second,0); - int global=blocktopo2.localToGlobal(local); - CPPUNIT_ASSERT_EQUAL(global,0); - - local = blocktopo2.globalToLocal(1); - CPPUNIT_ASSERT_EQUAL(local.first,0); - CPPUNIT_ASSERT_EQUAL(local.second,1); - global=blocktopo2.localToGlobal(local); - CPPUNIT_ASSERT_EQUAL(global,1); - - local = blocktopo2.globalToLocal(2*size-1); - CPPUNIT_ASSERT_EQUAL(local.first,size-1); - CPPUNIT_ASSERT_EQUAL(local.second,1); - global=blocktopo2.localToGlobal(local); - CPPUNIT_ASSERT_EQUAL(global,2*size-1); - - std::vector<std::pair<int,int> > bounds = blocktopo2.getLocalArrayMinMax(); - int vecsize = bounds.size(); - CPPUNIT_ASSERT_EQUAL(1,vecsize); - CPPUNIT_ASSERT_EQUAL(2*rank, (bounds[0]).first); - CPPUNIT_ASSERT_EQUAL(2*rank+2, (bounds[0]).second); - } - -void ParaMEDMEMTest::testBlockTopology_serialize() -{ - - int size; - MPI_Comm_size(MPI_COMM_WORLD,&size); - int rank; - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - CommInterface interface; - MPIProcessorGroup group(interface); - BlockTopology blocktopo(group,3); - -//testing the serialization process that is used to transfer a -//block topology via a MPI_Send/Recv comm - BlockTopology blocktopo_recv; - int* serializer; - int sersize; - blocktopo.serialize(serializer,sersize); - blocktopo_recv.unserialize(serializer,interface); - CPPUNIT_ASSERT_EQUAL(blocktopo.getNbElements(),blocktopo_recv.getNbElements()); - delete [] serializer; -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx deleted file mode 100644 index 341ed7c4e..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "InterpKernelDEC.hxx" -#include "MEDCouplingUMesh.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" - -#include <set> - -using namespace ParaMEDMEM; - -void ParaMEDMEMTest::testFabienAPI1() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=3) - return ; - int procs_source_c[1]={0}; - std::set<int> procs_source(procs_source_c,procs_source_c+1); - int procs_target_c[1]={1}; - std::set<int> procs_target(procs_target_c,procs_target_c+1); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafield=0; - // - ParaMEDMEM::CommInterface interface; - // - MPI_Barrier(MPI_COMM_WORLD); - double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. }; - CommInterface comm; - // - ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_target); - if(dec->isInSourceSide()) - { - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - int targetConn[4]={0,2,3,1}; - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - mesh->finishInsertingCells(); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*dec->getSourceGrp(),"source mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - double *vals=parafield->getField()->getArray()->getPointer(); - vals[0]=7.; - } - if(dec->isInTargetSide()) - { - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - int targetConn[6]={0,2,1,2,3,1}; - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - mesh->finishInsertingCells(); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*dec->getTargetGrp(),"target mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - dec->attachLocalField(parafield); - dec->synchronize(); - dec->sendRecvData(); - if(dec->isInTargetSide()) - { - const double *valsToTest=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[0],7.,1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[1],7.,1e-14); - } - // - delete parafield; - delete paramesh; - if(mesh) - mesh->decrRef(); - delete dec; - MPI_Barrier(MPI_COMM_WORLD); -} - -/*! - * Idem testFabienAPI1 except that procs are shuffled. Test of the good management of group translation in newly created communicator. - */ -void ParaMEDMEMTest::testFabienAPI2() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=3) - return ; - int procs_source_c[1]={2};//difference with testFabienAPI1 - std::set<int> procs_source(procs_source_c,procs_source_c+1); - int procs_target_c[1]={1}; - std::set<int> procs_target(procs_target_c,procs_target_c+1); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafield=0; - // - ParaMEDMEM::CommInterface interface; - // - MPI_Barrier(MPI_COMM_WORLD); - double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. }; - CommInterface comm; - // - ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_target); - if(dec->isInSourceSide()) - { - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - int targetConn[4]={0,2,3,1}; - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - mesh->finishInsertingCells(); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*dec->getSourceGrp(),"source mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - double *vals=parafield->getField()->getArray()->getPointer(); - vals[0]=7.; - } - if(dec->isInTargetSide()) - { - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - int targetConn[6]={0,2,1,2,3,1}; - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - mesh->finishInsertingCells(); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*dec->getTargetGrp(),"target mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - dec->attachLocalField(parafield); - dec->synchronize(); - dec->sendRecvData(); - if(dec->isInTargetSide()) - { - const double *valsToTest=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[0],7.,1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[1],7.,1e-14); - } - // - delete parafield; - delete paramesh; - if(mesh) - mesh->decrRef(); - delete dec; - MPI_Barrier(MPI_COMM_WORLD); -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx deleted file mode 100644 index e11b5a944..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx +++ /dev/null @@ -1,666 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "DEC.hxx" -#include "InterpKernelDEC.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" -#include "BlockTopology.hxx" - -#include <set> -#include <time.h> -#include <iostream> -#include <assert.h> -#include <string> -#include <math.h> - -using namespace std; -using namespace ParaMEDMEM; -using namespace ICoCo; - -void afficheGauthier1(const ParaFIELD& field, const double *vals, int lgth) -{ - const DataArrayDouble *valsOfField(field.getField()->getArray()); - CPPUNIT_ASSERT_EQUAL(lgth,valsOfField->getNumberOfTuples()); - for (int ele=0;ele<valsOfField->getNumberOfTuples();ele++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(vals[ele],valsOfField->getIJ(ele,0),1e-12); -} - -MEDCouplingUMesh *init_quadGauthier1(int is_master) -{ - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m(MEDCouplingUMesh::New("champ_quad",2)); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::New()); - if(is_master) - { - const double dataCoo[24]={0,0,0,1,0,0,0,0,1,1,0,1,0,1,0,1,1,0,0,1,1,1,1,1}; - coo->alloc(8,3); - std::copy(dataCoo,dataCoo+24,coo->getPointer()); - const int conn[8]={0,1,3,2,4,5,7,6}; - m->allocateCells(2); - m->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - m->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - } - else - { - coo->alloc(0,3); - m->allocateCells(0); - } - m->setCoords(coo); - return m.retn(); -} - -MEDCouplingUMesh *init_triangleGauthier1(int is_master) -{ - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m(MEDCouplingUMesh::New("champ_triangle",2)); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::New()); - if(is_master) - { - const double dataCoo[24]={0,0,0,1,0,0,0,0,1,1,0,1,0,1,0,1,1,0,0,1,1,1,1,1}; - coo->alloc(8,3); - std::copy(dataCoo,dataCoo+24,coo->getPointer()); - const int conn[12]={0,1,2,1,2,3,4,5,7,4,6,7}; - m->allocateCells(2); - for(int i=0;i<4;i++) - m->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+3*i); - } - else - { - coo->alloc(0,3); - m->allocateCells(0); - } - m->setCoords(coo); - return m.retn(); -} - - -void ParaMEDMEMTest::testGauthier1() -{ - int num_cas=0; - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - MPI_Comm_size(MPI_COMM_WORLD,&size); - - int is_master=0; - - CommInterface comm; - set<int> emetteur_ids; - set<int> recepteur_ids; - emetteur_ids.insert(0); - if(size!=4) - return; - recepteur_ids.insert(1); - if (size >2) - recepteur_ids.insert(2); - if (size >2) - emetteur_ids.insert(3); - if ((rank==0)||(rank==1)) - is_master=1; - - MPIProcessorGroup recepteur_group(comm,recepteur_ids); - MPIProcessorGroup emetteur_group(comm,emetteur_ids); - - string cas; - if (recepteur_group.containsMyRank()) - { - cas="recepteur"; - //freopen("recpeteur.out","w",stdout); - //freopen("recepteur.err","w",stderr); - } - else - { - cas="emetteur"; - // freopen("emetteur.out","w",stdout); - //freopen("emetteur.err","w",stderr); - } - double expected[8][4]={ - {1.,1.,1.,1.}, - {40., 40., 1., 1.}, - {1.,1.,1e200,1e200}, - {40.,1.,1e200,1e200}, - {1.,1.,1.,1.}, - {40.,1.,1.,1.}, - {1.,1.,1e200,1e200}, - {20.5,1.,1e200,1e200} - }; - int expectedLgth[8]={4,4,2,2,4,4,2,2}; - - for (int send=0;send<2;send++) - for (int rec=0;rec<2;rec++) - { - InterpKernelDEC dec_emetteur(emetteur_group, recepteur_group); - ParaMEDMEM::ParaFIELD *champ_emetteur(0),*champ_recepteur(0); - ParaMEDMEM::ParaMESH *paramesh(0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh; - dec_emetteur.setOrientation(2); - if (send==0) - { - mesh=init_quadGauthier1(is_master); - } - else - { - mesh=init_triangleGauthier1(is_master); - } - paramesh=new ParaMEDMEM::ParaMESH(mesh,recepteur_group.containsMyRank()?recepteur_group:emetteur_group,"emetteur mesh"); - ParaMEDMEM::ComponentTopology comptopo; - champ_emetteur=new ParaMEDMEM::ParaFIELD(ON_CELLS,ONE_TIME,paramesh,comptopo); - champ_emetteur->getField()->setNature(ConservativeVolumic); - champ_emetteur->setOwnSupport(true); - if (rec==0) - { - mesh=init_triangleGauthier1(is_master); - } - else - { - mesh=init_quadGauthier1(is_master); - } - paramesh=new ParaMEDMEM::ParaMESH(mesh,recepteur_group.containsMyRank()?recepteur_group:emetteur_group,"recepteur mesh"); - champ_recepteur=new ParaMEDMEM::ParaFIELD(ON_CELLS,ONE_TIME,paramesh,comptopo); - champ_recepteur->getField()->setNature(ConservativeVolumic); - champ_recepteur->setOwnSupport(true); - if (cas=="emetteur") - { - champ_emetteur->getField()->getArray()->fillWithValue(1.); - } - - - MPI_Barrier(MPI_COMM_WORLD); - - //clock_t clock0= clock (); - int compti=0; - - bool init=true; // first time step ?? - bool stop=false; - //boucle sur les pas de quads - while (!stop) { - - compti++; - //clock_t clocki= clock (); - //cout << compti << " CLOCK " << (clocki-clock0)*1.e-6 << endl; - for (int non_unif=0;non_unif<2;non_unif++) - { - if (cas=="emetteur") - { - if (non_unif) - if(rank!=3) - champ_emetteur->getField()->getArray()->setIJ(0,0,40); - } - //bool ok=false; // Is the time interval successfully solved ? - - // Loop on the time interval tries - if(1) { - - - if (cas=="emetteur") - dec_emetteur.attachLocalField(champ_emetteur); - else - dec_emetteur.attachLocalField(champ_recepteur); - - - if(init) dec_emetteur.synchronize(); - init=false; - - if (cas=="emetteur") { - // affiche(champ_emetteur); - dec_emetteur.sendData(); - } - else if (cas=="recepteur") - { - dec_emetteur.recvData(); - if (is_master) - afficheGauthier1(*champ_recepteur,expected[num_cas],expectedLgth[num_cas]); - } - else - throw 0; - MPI_Barrier(MPI_COMM_WORLD); - } - stop=true; - num_cas++; - } - } - delete champ_emetteur; - delete champ_recepteur; - } -} - -void ParaMEDMEMTest::testGauthier2() -{ - std::cout << "testGauthier2\n"; - double valuesExpected1[2]={0.,0.}; - double valuesExpected2[2]={0.95,0.970625}; - - double valuesExpected30[]={0., 0., 0.05, 0., 0., 0.15, 0., 0., 0.25, 0., 0., 0.35, 0., 0., 0.45, 0., 0., 0.55, 0., 0., 0.65, 0., 0., 0.75, 0., 0., 0.85, 0., 0., 0.95}; - double valuesExpected31[]={0., 0., 0.029375, 0., 0., 0.029375, 0., 0., 0.1, 0., 0., 0.1, 0., 0., 0.2, 0., 0., 0.2, 0., 0., 0.3, 0., 0., 0.3, 0., 0., 0.4, 0., 0., 0.4, 0., 0., 0.5, 0., 0., 0.5, 0., 0., 0.6, 0., 0., 0.6, 0., 0., 0.7, 0., 0., 0.7, 0., 0., 0.8, 0., 0., 0.8, 0., 0., 0.9, 0., 0., 0.9, 0., 0., 0.970625, 0., 0., 0.970625 }; - - double *valuesExpected3[2]={valuesExpected30,valuesExpected31}; - - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - MPI_Comm_size(MPI_COMM_WORLD,&size); - if (size <2) - return ; - CommInterface comm; - set<int> Genepi_ids; - set<int> entree_chaude_ids; - Genepi_ids.insert(0); - for (int i=1;i<size;i++) - entree_chaude_ids.insert(i); - for (int type=0;type<2;type++) - { - MPIProcessorGroup entree_chaude_group(comm,entree_chaude_ids); - MPIProcessorGroup Genepi_group(comm,Genepi_ids); - - ParaMEDMEM::ParaFIELD *vitesse(0); - InterpKernelDEC dec_vit_in_chaude(entree_chaude_group, Genepi_group); - - if ( entree_chaude_group.containsMyRank()) - { - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(MEDCouplingUMesh::New("mesh",2)); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(63,3); - const double cooData[189]={0.,0.,0.,0.5,0.,0.,0.5,0.05,0.,0.,0.1,0.,0.5,0.1,0.,0.5,0.15,0.,0.,0.2,0.,0.5,0.2,0.,0.5,0.25,0.,0.,0.3,0.,0.5,0.3,0.,0.5,0.35,0.,0.,0.4,0.,0.5,0.4,0.,0.5,0.45,0.,0.,0.5,0.,0.5,0.5,0.,0.5,0.55,0.,0.,0.6,0.,0.5,0.6,0.,0.5,0.65,0.,0.,0.7,0.,0.5,0.7,0.,0.5,0.75,0.,0.,0.8,0.,0.5,0.8,0.,0.5,0.85,0.,0.,0.9,0.,0.5,0.9,0.,0.5,0.95,0.,1.,0.,0.,1.,0.1,0.,1.,0.2,0.,1.,0.3,0.,1.,0.4,0.,1.,0.5,0.,1.,0.6,0.,1.,0.7,0.,1.,0.8,0.,1.,0.9,0.,1.,0.05,0.,1.,0.15,0.,1.,0.25,0.,1.,0.35,0.,1.,0.45,0.,1.,0.55,0.,1.,0.65,0.,1.,0.75,0.,1.,0.85,0.,1.,0.95,0.,1.,1.,0.,0.,1.,0.,0.5,1.,0.,0.,0.05,0.,0.,0.15,0.,0.,0.25,0.,0.,0.35,0.,0.,0.45,0.,0.,0.55,0.,0.,0.65,0.,0.,0.75,0.,0.,0.85,0.,0.,0.95,0.}; - std::copy(cooData,cooData+189,arr->getPointer()); - mesh->setCoords(arr); - mesh->allocateCells(80); - const int conn[240]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,2,1,31,5,4,32,8,7,33,11,10,34,14,13,35,17,16,36,20,19,37,23,22,38,26,25,39,29,28,30,40,2,31,41,5,32,42,8,33,43,11,34,44,14,35,45,17,36,46,20,37,47,23,38,48,26,39,49,29,31,2,40,32,5,41,33,8,42,34,11,43,35,14,44,36,17,45,37,20,46,38,23,47,39,26,48,50,29,49,3,2,4,6,5,7,9,8,10,12,11,13,15,14,16,18,17,19,21,20,22,24,23,25,27,26,28,51,29,52,31,4,2,32,7,5,33,10,8,34,13,11,35,16,14,36,19,17,37,22,20,38,25,23,39,28,26,50,52,29,0,2,53,3,5,54,6,8,55,9,11,56,12,14,57,15,17,58,18,20,59,21,23,60,24,26,61,27,29,62,3,53,2,6,54,5,9,55,8,12,56,11,15,57,14,18,58,17,21,59,20,24,60,23,27,61,26,51,62,29}; - for(int i=0;i<80;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+3*i); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME)); - const double valsOfField[189]={0.,0.,0.,0.,0.,0.,0.,0.,0.05,0.,0.,0.1,0.,0.,0.1,0.,0.,0.15,0.,0.,0.2,0.,0.,0.2,0.,0.,0.25,0.,0.,0.3,0.,0.,0.3,0.,0.,0.35,0.,0.,0.4,0.,0.,0.4,0.,0.,0.45,0.,0.,0.5,0.,0.,0.5,0.,0.,0.55,0.,0.,0.6,0.,0.,0.6,0.,0.,0.65,0.,0.,0.7,0.,0.,0.7,0.,0.,0.75,0.,0.,0.8,0.,0.,0.8,0.,0.,0.85,0.,0.,0.9,0.,0.,0.9,0.,0.,0.95,0.,0.,0.,0.,0.,0.1,0.,0.,0.2,0.,0.,0.3,0.,0.,0.4,0.,0.,0.5,0.,0.,0.6,0.,0.,0.7,0.,0.,0.8,0.,0.,0.9,0.,0.,0.05,0.,0.,0.15,0.,0.,0.25,0.,0.,0.35,0.,0.,0.45,0.,0.,0.55,0.,0.,0.65,0.,0.,0.75,0.,0.,0.85,0.,0.,0.95,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,0.05,0.,0.,0.15,0.,0.,0.25,0.,0.,0.35,0.,0.,0.45,0.,0.,0.55,0.,0.,0.65,0.,0.,0.75,0.,0.,0.85,0.,0.,0.95}; - f->setMesh(mesh); f->setName("VITESSE_P1_OUT"); - arr=DataArrayDouble::New(); arr->alloc(63,3); - std::copy(valsOfField,valsOfField+189,arr->getPointer()); - f->setArray(arr); f->setNature(ConservativeVolumic); - ParaMEDMEM::ParaMESH *paramesh(new ParaMEDMEM::ParaMESH(mesh,entree_chaude_group,"emetteur mesh")); - vitesse=new ParaMEDMEM::ParaFIELD(f,paramesh,entree_chaude_group); - vitesse->setOwnSupport(true); - dec_vit_in_chaude.setMethod("P1"); - } - else - { - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(MEDCouplingUMesh::New("mesh",2)); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(22,3); - const double cooData[66]={0,0,0,1,0,0,0,0.1,0,1,0.1,0,0,0.2,0,1,0.2,0,0,0.3,0,1,0.3,0,0,0.4,0,1,0.4,0,0,0.5,0,1,0.5,0,0,0.6,0,1,0.6,0,0,0.7,0,1,0.7,0,0,0.8,0,1,0.8,0,0,0.9,0,1,0.9,0,0,1,0,1,1,0}; - std::copy(cooData,cooData+66,arr->getPointer()); - mesh->setCoords(arr); - mesh->allocateCells(10); - const int conn[40]={0,1,3,2,2,3,5,4,4,5,7,6,6,7,9,8,8,9,11,10,10,11,13,12,12,13,15,14,14,15,17,16,16,17,19,18,18,19,21,20}; - for(int i=0;i<10;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4*i); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(type==0?ON_CELLS:ON_NODES,ONE_TIME)); - f->setMesh(mesh); f->setName("vitesse_in_chaude"); - arr=DataArrayDouble::New(); arr->alloc(f->getNumberOfTuplesExpected()*3); arr->fillWithZero(); arr->rearrange(3); - f->setArray(arr); f->setNature(ConservativeVolumic); - ParaMEDMEM::ParaMESH *paramesh(new ParaMEDMEM::ParaMESH(mesh,Genepi_group,"recepteur mesh")); - vitesse=new ParaMEDMEM::ParaFIELD(f,paramesh,Genepi_group); - vitesse->setOwnSupport(true); - dec_vit_in_chaude.setMethod(f->getDiscretization()->getRepr()); - } - - dec_vit_in_chaude.attachLocalField(vitesse); - - dec_vit_in_chaude.synchronize(); - - - // Envois - receptions - if (entree_chaude_group.containsMyRank()) - { - dec_vit_in_chaude.sendData(); - } - else - { - dec_vit_in_chaude.recvData(); - } - if ( !entree_chaude_group.containsMyRank() ) - { - double pmin=1e38, pmax=-1e38; - const double *p(vitesse->getField()->getArray()->begin()); - for(std::size_t i=0;i<vitesse->getField()->getArray()->getNbOfElems();i++,p++) - { - if (*p<pmin) pmin=*p; - if (*p>pmax) pmax=*p; - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[type],pmin,1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[type],pmax,1e-12); - - int nbCompo(vitesse->getField()->getNumberOfComponents()); - p=vitesse->getField()->getArray()->begin(); - for(int i=0;i<vitesse->getField()->getNumberOfTuples();i++) - for(int c=0;c<nbCompo;c++,p++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[type][i*nbCompo+c],*p,1e-12); - } - delete vitesse; - } -} - -/*! - * Non regression test testing copy constructor of InterpKernelDEC. - */ -void ParaMEDMEMTest::testGauthier3() -{ - int num_cas=0; - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - MPI_Comm_size(MPI_COMM_WORLD,&size); - - int is_master=0; - - CommInterface comm; - set<int> emetteur_ids; - set<int> recepteur_ids; - emetteur_ids.insert(0); - if(size!=4) - return; - recepteur_ids.insert(1); - if (size >2) - recepteur_ids.insert(2); - if (size >2) - emetteur_ids.insert(3); - if ((rank==0)||(rank==1)) - is_master=1; - - MPIProcessorGroup recepteur_group(comm,recepteur_ids); - MPIProcessorGroup emetteur_group(comm,emetteur_ids); - - string cas; - if (recepteur_group.containsMyRank()) - { - cas="recepteur"; - //freopen("recpeteur.out","w",stdout); - //freopen("recepteur.err","w",stderr); - } - else - { - cas="emetteur"; - // freopen("emetteur.out","w",stdout); - //freopen("emetteur.err","w",stderr); - } - double expected[8][4]={ - {1.,1.,1.,1.}, - {40., 40., 1., 1.}, - {1.,1.,1e200,1e200}, - {40.,1.,1e200,1e200}, - {1.,1.,1.,1.}, - {40.,1.,1.,1.}, - {1.,1.,1e200,1e200}, - {20.5,1.,1e200,1e200} - }; - int expectedLgth[8]={4,4,2,2,4,4,2,2}; - - for (int send=0;send<2;send++) - for (int rec=0;rec<2;rec++) - { - std::vector<InterpKernelDEC> decu(1); - decu[0]=InterpKernelDEC(emetteur_group,recepteur_group); - InterpKernelDEC& dec_emetteur=decu[0]; - ParaMEDMEM::ParaFIELD *champ_emetteur(0),*champ_recepteur(0); - ParaMEDMEM::ParaMESH *paramesh(0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh; - dec_emetteur.setOrientation(2); - if (send==0) - { - mesh=init_quadGauthier1(is_master); - } - else - { - mesh=init_triangleGauthier1(is_master); - } - paramesh=new ParaMEDMEM::ParaMESH(mesh,recepteur_group.containsMyRank()?recepteur_group:emetteur_group,"emetteur mesh"); - ParaMEDMEM::ComponentTopology comptopo; - champ_emetteur=new ParaMEDMEM::ParaFIELD(ON_CELLS,ONE_TIME,paramesh,comptopo); - champ_emetteur->getField()->setNature(ConservativeVolumic); - champ_emetteur->setOwnSupport(true); - if (rec==0) - { - mesh=init_triangleGauthier1(is_master); - } - else - { - mesh=init_quadGauthier1(is_master); - } - paramesh=new ParaMEDMEM::ParaMESH(mesh,recepteur_group.containsMyRank()?recepteur_group:emetteur_group,"recepteur mesh"); - champ_recepteur=new ParaMEDMEM::ParaFIELD(ON_CELLS,ONE_TIME,paramesh,comptopo); - champ_recepteur->getField()->setNature(ConservativeVolumic); - champ_recepteur->setOwnSupport(true); - if (cas=="emetteur") - { - champ_emetteur->getField()->getArray()->fillWithValue(1.); - } - - - MPI_Barrier(MPI_COMM_WORLD); - - //clock_t clock0= clock (); - int compti=0; - - bool init=true; // first time step ?? - bool stop=false; - //boucle sur les pas de quads - while (!stop) { - - compti++; - //clock_t clocki= clock (); - //cout << compti << " CLOCK " << (clocki-clock0)*1.e-6 << endl; - for (int non_unif=0;non_unif<2;non_unif++) - { - if (cas=="emetteur") - { - if (non_unif) - if(rank!=3) - champ_emetteur->getField()->getArray()->setIJ(0,0,40); - } - //bool ok=false; // Is the time interval successfully solved ? - - // Loop on the time interval tries - if(1) { - - - if (cas=="emetteur") - dec_emetteur.attachLocalField(champ_emetteur); - else - dec_emetteur.attachLocalField(champ_recepteur); - - - if(init) dec_emetteur.synchronize(); - init=false; - - if (cas=="emetteur") { - // affiche(champ_emetteur); - dec_emetteur.sendData(); - } - else if (cas=="recepteur") - { - dec_emetteur.recvData(); - if (is_master) - afficheGauthier1(*champ_recepteur,expected[num_cas],expectedLgth[num_cas]); - } - else - throw 0; - MPI_Barrier(MPI_COMM_WORLD); - } - stop=true; - num_cas++; - } - } - delete champ_emetteur; - delete champ_recepteur; - } -} - -/*! - * This test is the parallel version of MEDCouplingBasicsTest.test3D1DOnP1P0_1 test. - */ -void ParaMEDMEMTest::testGauthier4() -{ - // - const double sourceCoords[19*3]={0.5,0.5,0.1,0.5,0.5,1.2,0.5,0.5,1.6,0.5,0.5,1.8,0.5,0.5,2.43,0.5,0.5,2.55,0.5,0.5,4.1,0.5,0.5,4.4,0.5,0.5,4.9,0.5,0.5,5.1,0.5,0.5,7.6,0.5,0.5,7.7,0.5,0.5,8.2,0.5,0.5,8.4,0.5,0.5,8.6,0.5,0.5,8.8,0.5,0.5,9.2,0.5,0.5,9.6,0.5,0.5,11.5}; - const int sourceConn[18*2]={0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18}; - const double sourceVals[19]={0.49,2.8899999999999997,7.29,13.69,22.09,32.49,44.89,59.29,75.69,94.09, 114.49,136.89,161.29,187.69,216.09,246.49,278.89,313.29,349.69}; - const double targetCoords0[20*3]={0.,0.,0.,1.,0.,0.,0.,1.,0.,1.,1.,0.,0.,0.,1.,1.,0.,1.,0.,1.,1.,1.,1.,1.,0.,0.,2.,1.,0.,2.,0.,1.,2.,1.,1.,2.,0.,0.,3.,1.,0.,3.,0.,1.,3.,1.,1.,3.,0.,0.,4.,1.,0.,4.,0.,1.,4.,1.,1.,4.}; - const int targetConn0[8*4]={1,0,2,3,5,4,6,7,5,4,6,7,9,8,10,11,9,8,10,11,13,12,14,15,13,12,14,15,17,16,18,19}; - const double targetCoords1[28*3]={0.,0.,4.,1.,0.,4.,0.,1.,4.,1.,1.,4.,0.,0.,5.,1.,0.,5.,0.,1.,5.,1.,1.,5.,0.,0.,6.,1.,0.,6.,0.,1.,6.,1.,1.,6.,0.,0.,7.,1.,0.,7.,0.,1.,7.,1.,1.,7.,0.,0.,8.,1.,0.,8.,0.,1.,8.,1.,1.,8.,0.,0.,9.,1.,0.,9.,0.,1.,9.,1.,1.,9.,0.,0.,10.,1.,0.,10.,0.,1.,10.,1.,1.,10.}; - const int targetConn1[8*6]={1,0,2,3,5,4,6,7,5,4,6,7,9,8,10,11,9,8,10,11,13,12,14,15,13,12,14,15,17,16,18,19,17,16,18,19,21,20,22,23,21,20,22,23,25,24,26,27}; - // - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=3) - return ; - int nproc_source = 1; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD* parafield=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - std::ostringstream stream; stream << "sourcemesh2D proc " << rank; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),1); - mesh->allocateCells(); - for(int i=0;i<18;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+2*i); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(19,3); - std::copy(sourceCoords,sourceCoords+19*3,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh,comptopo); - double *value=parafield->getField()->getArray()->getPointer(); - std::copy(sourceVals,sourceVals+19,value); - } - else - { - if(rank==1) - { - std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),3); - mesh->allocateCells(); - for(int i=0;i<4;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn0+8*i); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(20,3); - std::copy(targetCoords0,targetCoords0+20*3,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - } - else if(rank==2) - { - std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),3); - mesh->allocateCells(); - for(int i=0;i<6;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn1+8*i); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(28,3); - std::copy(targetCoords1,targetCoords1+28*3,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - } - } - //test 1 - primaire -> secondaire - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - dec.setIntersectionType(INTERP_KERNEL::PointLocator); - parafield->getField()->setNature(ConservativeVolumic);//very important - if (source_group->containsMyRank()) - { - dec.setMethod("P1"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res(parafield->getField()->getArray()->getConstPointer()); - if(rank==1) - { - const double expected0[4]={0.49,7.956666666666667,27.29,0.}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],res[i],1e-13); - } - else - { - const double expected1[6]={59.95666666666667,94.09,0.,125.69,202.89,296.09}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],res[i],1e-13); - } - } - MPI_Barrier(MPI_COMM_WORLD); - if (source_group->containsMyRank()) - { - dec.recvData(); - const double expected2[19]={0.49,7.956666666666667,7.956666666666667,7.956666666666667,27.29,27.29,59.95666666666667,59.95666666666667,59.95666666666667,94.09,125.69,125.69,202.89,202.89,202.89,202.89,296.09,296.09,0.}; - const double *res(parafield->getField()->getArray()->getConstPointer()); - for(int i=0;i<19;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],res[i],1e-13); - } - else - { - dec.sendData(); - } - delete parafield; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_ICoco.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_ICoco.cxx deleted file mode 100644 index f46c76749..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_ICoco.cxx +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "ComponentTopology.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "InterpKernelDEC.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include <set> -#include <string> -#include <time.h> -#include <iostream> -#include <assert.h> - -using namespace std; -using namespace ParaMEDMEM; -using namespace ICoCo; - -typedef enum {sync_and,sync_or} synctype; -void synchronize_bool(bool& stop, synctype s) -{ - int my_stop; - int my_stop_temp = stop?1:0; - if (s==sync_and) - MPI_Allreduce(&my_stop_temp,&my_stop,1,MPI_INTEGER,MPI_MIN,MPI_COMM_WORLD); - else if (s==sync_or) - MPI_Allreduce(&my_stop_temp,&my_stop,1,MPI_INTEGER,MPI_MAX,MPI_COMM_WORLD); - stop =(my_stop==1); -} - -void synchronize_dt(double& dt) -{ - double dttemp=dt; - MPI_Allreduce(&dttemp,&dt,1,MPI_DOUBLE,MPI_MIN,MPI_COMM_WORLD); -} - - -void affiche(const ParaFIELD& field) -{ - cout <<field.getField()->getName()<<endl; - const double *vals(field.getField()->getArray()->begin()); - for(int ele=0;ele<field.getField()->getNumberOfTuples();ele++) - cout << ele <<": "<< vals[ele] << endl; -} - -MEDCouplingUMesh *init_quad() -{ - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m(MEDCouplingUMesh::New("champ_quad",2)); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::New()); - const double dataCoo[24]={0.,0.,0.,1.,0.,0.,0.,0.,1.,1.,0.,1.,0.,1e-05,0.,1.,1e-05,0.,0.,1e-05,1.,1.,1e-05,1.}; - coo->alloc(8,3); - std::copy(dataCoo,dataCoo+24,coo->getPointer()); - const int conn[8]={0,1,3,2,4,5,7,6}; - m->allocateCells(2); - m->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - m->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - m->setCoords(coo); - return m.retn(); -} - -MEDCouplingUMesh *init_triangle() -{ - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m(MEDCouplingUMesh::New("champ_triangle",2)); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::New()); - const double dataCoo[24]={0.,0.,0.,1.,0.,0.,0.,0.,1.,1.,0.,1.,0.,1e-05,0.,1.,1e-05,0.,0.,1e-05,1.,1.,1e-05,1.}; - coo->alloc(8,3); - std::copy(dataCoo,dataCoo+24,coo->getPointer()); - const int conn[12]={0,1,2,1,2,3,4,5,7,4,6,7}; - m->allocateCells(4); - for(int i=0;i<4;i++) - m->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+3*i); - m->setCoords(coo); - return m.retn(); -} - -void ParaMEDMEMTest::testICoco1() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on 2 processors - if (size !=2) return ; - - CommInterface comm; - set<int> emetteur_ids; - set<int> recepteur_ids; - emetteur_ids.insert(0); - recepteur_ids.insert(1); - - MPIProcessorGroup recepteur_group(comm,recepteur_ids); - MPIProcessorGroup emetteur_group(comm,emetteur_ids); - - string cas; - if (recepteur_group.containsMyRank()) - cas="recepteur"; - else - cas="emetteur"; - - InterpKernelDEC dec_emetteur(emetteur_group,recepteur_group); - dec_emetteur.setOrientation(2); - ParaMEDMEM::ParaFIELD *champ_emetteur(0),*champ_recepteur(0); - ParaMEDMEM::ParaMESH *paramesh(0); - if (cas=="emetteur") - { - MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> mesh_emetteur(init_triangle()); - paramesh=new ParaMEDMEM::ParaMESH(mesh_emetteur,emetteur_group,"emetteur mesh"); - ParaMEDMEM::ComponentTopology comptopo; - champ_emetteur=new ParaMEDMEM::ParaFIELD(ON_CELLS,ONE_TIME,paramesh,comptopo); - champ_emetteur->getField()->setNature(ConservativeVolumic); - champ_emetteur->setOwnSupport(true); - champ_emetteur->getField()->getArray()->fillWithValue(1.); - } - else - { - MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> mesh_recepteur(init_quad()); - paramesh=new ParaMEDMEM::ParaMESH(mesh_recepteur,recepteur_group,"recepteur mesh"); - ParaMEDMEM::ComponentTopology comptopo; - champ_recepteur=new ParaMEDMEM::ParaFIELD(ON_CELLS,ONE_TIME,paramesh,comptopo); - champ_recepteur->getField()->setNature(ConservativeVolumic); - champ_recepteur->setOwnSupport(true); - } - - - MPI_Barrier(MPI_COMM_WORLD); - - clock_t clock0(clock()); - int compti=0; - - bool init(true),stop(false); - //boucle sur les pas de quads - while(!stop) - { - compti++; - clock_t clocki= clock (); - cout << compti << " CLOCK " << (clocki-clock0)*1.e-6 << endl; - for (int non_unif=0;non_unif<2;non_unif++) - { - if (cas=="emetteur") - if (non_unif) - champ_emetteur->getField()->getArray()->setIJ(0,0,40.); - //bool ok=false; // Is the time interval successfully solved ? - - // Loop on the time interval tries - if (cas=="emetteur") - dec_emetteur.attachLocalField(champ_emetteur); - else - dec_emetteur.attachLocalField(champ_recepteur); - - if(init) - dec_emetteur.synchronize(); - init=false; - - if (cas=="emetteur") - { - dec_emetteur.sendData(); - affiche(*champ_emetteur); - } - else if (cas=="recepteur") - { - dec_emetteur.recvData(); - affiche(*champ_recepteur); - } - else - throw 0; - } - stop=true; - } - delete champ_recepteur; - delete champ_emetteur; -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx deleted file mode 100644 index 9ca93d3d6..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx +++ /dev/null @@ -1,2293 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "DEC.hxx" -#include "MxN_Mapping.hxx" -#include "InterpKernelDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" -#include "ICoCoMEDField.hxx" -#include "ParaMEDLoader.hxx" -#include "MEDLoader.hxx" - - -#include <string> -#include <iterator> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - - -using namespace std; -using namespace ParaMEDMEM; - -void ParaMEDMEMTest::testInterpKernelDEC_2D() -{ - testInterpKernelDEC_2D_("P0","P0"); -} - -void ParaMEDMEMTest::testInterpKernelDEC2_2D() -{ - testInterpKernelDEC2_2D_("P0","P0"); -} - -void ParaMEDMEMTest::testInterpKernelDEC_3D() -{ - testInterpKernelDEC_3D_("P0","P0"); -} - -void ParaMEDMEMTest::testInterpKernelDEC_2DP0P1() -{ - //testInterpKernelDEC_2D_("P0","P1"); -} - -void ParaMEDMEMTest::testInterpKernelDEC_1D() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=5) - return ; - int nproc_source = 3; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafieldP0=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - if(rank==0) - { - double coords[4]={0.3,0.7, 0.9,1.0}; - int conn[4]={0,1,2,3}; - mesh=MEDCouplingUMesh::New("Source mesh Proc0",1); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,1); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - if(rank==1) - { - double coords[2]={0.7,0.9}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Source mesh Proc1",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,1); - std::copy(coords,coords+2,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - if(rank==2) - { - double coords[2]={1.,1.12}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Source mesh Proc2",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,1); - std::copy(coords,coords+2,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - parafieldP0->getField()->setNature(ConservativeVolumic); - if(rank==0) - { - valueP0[0]=7.; valueP0[1]=8.; - } - if(rank==1) - { - valueP0[0]=9.; - } - if(rank==2) - { - valueP0[0]=10.; - } - } - else - { - const char targetMeshName[]="target mesh"; - if(rank==3) - { - double coords[2]={0.5,0.75}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Target mesh Proc3",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,1); - std::copy(coords,coords+2,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - } - if(rank==4) - { - double coords[2]={0.75,1.2}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Target mesh Proc4",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,1); - std::copy(coords,coords+2,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - } - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP0->getField()->setNature(ConservativeVolumic); - } - // test 1 - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - dec.recvData(); - const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7); - } - if(rank==1) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7); - } - if(rank==2) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7); - } - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafieldP0->getField()->getArray()->getConstPointer(); - if(rank==3) - { - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12); - } - if(rank==4) - { - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12); - } - dec.sendData(); - } - // - delete parafieldP0; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -void ParaMEDMEMTest::testInterpKernelDEC_2DCurve() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=5) - return ; - int nproc_source = 3; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafieldP0=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - if(rank==0) - { - double coords[8]={0.3,0.3,0.7,0.7, 0.9,0.9,1.0,1.0}; - int conn[4]={0,1,2,3}; - mesh=MEDCouplingUMesh::New("Source mesh Proc0",1); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(coords,coords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - if(rank==1) - { - double coords[4]={0.7,0.7,0.9,0.9}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Source mesh Proc1",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,2); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - if(rank==2) - { - double coords[4]={1.,1.,1.12,1.12}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Source mesh Proc2",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,2); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - parafieldP0->getField()->setNature(ConservativeVolumic); - if(rank==0) - { - valueP0[0]=7.; valueP0[1]=8.; - } - if(rank==1) - { - valueP0[0]=9.; - } - if(rank==2) - { - valueP0[0]=10.; - } - } - else - { - const char targetMeshName[]="target mesh"; - if(rank==3) - { - double coords[4]={0.5,0.5,0.75,0.75}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Target mesh Proc3",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,2); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - } - if(rank==4) - { - double coords[4]={0.75,0.75,1.2,1.2}; - int conn[2]={0,1}; - mesh=MEDCouplingUMesh::New("Target mesh Proc4",1); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(2,2); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - } - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP0->getField()->setNature(ConservativeVolumic); - } - // test 1 - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - dec.recvData(); - const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7); - } - if(rank==1) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7); - } - if(rank==2) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7); - } - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafieldP0->getField()->getArray()->getConstPointer(); - if(rank==3) - { - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12); - } - if(rank==4) - { - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12); - } - dec.sendData(); - } - // - delete parafieldP0; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - - -/* - * Check methods defined in InterpKernelDEC.hxx - * - InterpKernelDEC(); - InterpKernelDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); - virtual ~InterpKernelDEC(); - void synchronize(); - void recvData(); - void sendData(); -*/ - -void ParaMEDMEMTest::testInterpKernelDEC_2D_(const char *srcMeth, const char *targetMeth) -{ - std::string srcM(srcMeth); - std::string targetM(targetMeth); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on five processors - if (size !=5) return ; - - int nproc_source = 3; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - - //loading the geometry for the source group - - ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); - - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::ParaMESH* paramesh; - ParaMEDMEM::ParaFIELD* parafield; - ICoCo::MEDField* icocofield ; - - string filename_xml1 = getResourceFile("square1_split"); - string filename_xml2 = getResourceFile("square2_split"); - //string filename_seq_wr = makeTmpFile(""); - //string filename_seq_med = makeTmpFile("myWrField_seq_pointe221.med"); - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - - MPI_Barrier(MPI_COMM_WORLD); - if (source_group->containsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <<master<<rank+1<<".med"; - ostringstream meshname ; - meshname<< "Mesh_2_"<< rank+1; - - mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - - paramesh=new ParaMESH (mesh,*source_group,"source mesh"); - - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group); - ParaMEDMEM::ComponentTopology comptopo; - if(srcM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=1.0; - - // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); - icocofield=new ICoCo::MEDField(parafield->getField()); - dec.setMethod(srcMeth); - dec.attachLocalField(icocofield); - } - - //loading the geometry for the target group - if (target_group->containsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - meshname<< "Mesh_3_"<<rank-nproc_source+1; - mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); - ParaMEDMEM::ComponentTopology comptopo; - if(targetM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); - icocofield=new ICoCo::MEDField(parafield->getField()); - dec.setMethod(targetMeth); - dec.attachLocalField(icocofield); - } - - - //attaching a DEC to the source group - double field_before_int; - double field_after_int; - - if (source_group->containsMyRank()) - { - field_before_int = parafield->getVolumeIntegral(0,true); - dec.synchronize(); - cout<<"DEC usage"<<endl; - dec.setForcedRenormalization(false); - - dec.sendData(); - ParaMEDLoader::WriteParaMesh("./sourcesquareb",paramesh); - if (source_group->myRank()==0) - aRemover.Register("./sourcesquareb"); - ostringstream filename; - filename<<"./sourcesquareb_"<<source_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - //MEDLoader::WriteField("./sourcesquareb",parafield->getField()); - - dec.recvData(); - cout <<"writing"<<endl; - ParaMEDLoader::WriteParaMesh("./sourcesquare",paramesh); - if (source_group->myRank()==0) - aRemover.Register("./sourcesquare"); - //MEDLoader::WriteField("./sourcesquare",parafield->getField()); - - - filename<<"./sourcesquare_"<<source_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - field_after_int = parafield->getVolumeIntegral(0,true); - - - // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); - - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - dec.synchronize(); - dec.setForcedRenormalization(false); - - dec.recvData(); - ParaMEDLoader::WriteParaMesh("./targetsquareb",paramesh); - //MEDLoader::WriteField("./targetsquareb",parafield->getField()); - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - ostringstream filename; - filename<<"./targetsquareb_"<<target_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - dec.sendData(); - ParaMEDLoader::WriteParaMesh("./targetsquare",paramesh); - //MEDLoader::WriteField("./targetsquare",parafield->getField()); - - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - - filename<<"./targetsquareb_"<<target_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - // double field_before_int, field_after_int; - // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - - // CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); - - } - - delete source_group; - delete target_group; - delete self_group; - delete parafield; - delete paramesh; - mesh->decrRef(); - - delete icocofield; - - MPI_Barrier(MPI_COMM_WORLD); - cout << "end of InterpKernelDEC_2D test"<<endl; -} - -void ParaMEDMEMTest::testInterpKernelDEC2_2D_(const char *srcMeth, const char *targetMeth) -{ - std::string srcM(srcMeth); - std::string targetM(targetMeth); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on five processors - if (size !=5) return ; - - int nproc_source = 3; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - - //loading the geometry for the source group - - ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); - - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::MEDCouplingFieldDouble* mcfield; - - string filename_xml1 = getResourceFile("square1_split"); - string filename_xml2 = getResourceFile("square2_split"); - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - - MPI_Barrier(MPI_COMM_WORLD); - if (source_group->containsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <<master<<rank+1<<".med"; - ostringstream meshname ; - meshname<< "Mesh_2_"<< rank+1; - - mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - ParaMEDMEM::ComponentTopology comptopo; - if(srcM=="P0") - { - mcfield = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - mcfield->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mcfield->getNumberOfTuples(),1); - mcfield->setArray(array); - array->decrRef(); - mcfield->setNature(ConservativeVolumic); - } - else - { - mcfield = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - mcfield->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mcfield->getNumberOfTuples(),1); - mcfield->setArray(array); - array->decrRef(); - } - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - double *value=mcfield->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=1.0; - dec.setMethod(srcMeth); - dec.attachLocalField(mcfield); - dec.attachLocalField(mcfield); - } - - //loading the geometry for the target group - if (target_group->containsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - meshname<< "Mesh_3_"<<rank-nproc_source+1; - mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - ParaMEDMEM::ComponentTopology comptopo; - if(targetM=="P0") - { - mcfield = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - mcfield->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mcfield->getNumberOfTuples(),1); - mcfield->setArray(array); - array->decrRef(); - mcfield->setNature(ConservativeVolumic); - } - else - { - mcfield = MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - mcfield->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mcfield->getNumberOfTuples(),1); - mcfield->setArray(array); - array->decrRef(); - } - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - double *value=mcfield->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - dec.setMethod(targetMeth); - dec.attachLocalField(mcfield); - dec.attachLocalField(mcfield); - } - - - //attaching a DEC to the source group - - if (source_group->containsMyRank()) - { - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - dec.recvData(); - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - dec.sendData(); - } - delete source_group; - delete target_group; - delete self_group; - mcfield->decrRef(); - mesh->decrRef(); - - MPI_Barrier(MPI_COMM_WORLD); - cout << "end of InterpKernelDEC2_2D test"<<endl; -} - -void ParaMEDMEMTest::testInterpKernelDEC_3D_(const char *srcMeth, const char *targetMeth) -{ - std::string srcM(srcMeth); - std::string targetM(targetMeth); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on five processors - if (size !=3) return ; - - int nproc_source = 2; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - - //loading the geometry for the source group - - ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); - - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::ParaMESH* paramesh; - ParaMEDMEM::ParaFIELD* parafield; - ICoCo::MEDField* icocofield ; - - char * tmp_dir_c = getenv("TMP"); - string tmp_dir; - if (tmp_dir_c != NULL) - tmp_dir = string(tmp_dir_c); - else - tmp_dir = "/tmp"; - string filename_xml1 = getResourceFile("Mesh3D_10_2d"); - string filename_xml2 = getResourceFile("Mesh3D_11"); - //string filename_seq_wr = makeTmpFile(""); - //string filename_seq_med = makeTmpFile("myWrField_seq_pointe221.med"); - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - - MPI_Barrier(MPI_COMM_WORLD); - if (source_group->containsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <<master<<rank+1<<".med"; - ostringstream meshname ; - meshname<< "Mesh_3_"<< rank+1; - - mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - - paramesh=new ParaMESH (mesh,*source_group,"source mesh"); - - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group); - ParaMEDMEM::ComponentTopology comptopo; - if(srcM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=1.0; - - // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); - icocofield=new ICoCo::MEDField(parafield->getField()); - dec.setMethod(srcMeth); - dec.attachLocalField(icocofield); - } - - //loading the geometry for the target group - if (target_group->containsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master << ".med"; - ostringstream meshname ; - meshname<< "Mesh_6"; - mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); - ParaMEDMEM::ComponentTopology comptopo; - if(targetM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); - icocofield=new ICoCo::MEDField(parafield->getField()); - dec.setMethod(targetMeth); - dec.attachLocalField(icocofield); - } - //attaching a DEC to the source group - double field_before_int; - double field_after_int; - - if (source_group->containsMyRank()) - { - field_before_int = parafield->getVolumeIntegral(0,true); - dec.synchronize(); - cout<<"DEC usage"<<endl; - dec.setForcedRenormalization(false); - - dec.sendData(); - ParaMEDLoader::WriteParaMesh("./sourcesquareb",paramesh); - if (source_group->myRank()==0) - aRemover.Register("./sourcesquareb"); - ostringstream filename; - filename<<"./sourcesquareb_"<<source_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - //MEDLoader::WriteField("./sourcesquareb",parafield->getField()); - - dec.recvData(); - cout <<"writing"<<endl; - ParaMEDLoader::WriteParaMesh("./sourcesquare",paramesh); - if (source_group->myRank()==0) - aRemover.Register("./sourcesquare"); - //MEDLoader::WriteField("./sourcesquare",parafield->getField()); - - - filename<<"./sourcesquare_"<<source_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - field_after_int = parafield->getVolumeIntegral(0,true); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); - - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - dec.synchronize(); - dec.setForcedRenormalization(false); - - dec.recvData(); - ParaMEDLoader::WriteParaMesh("./targetsquareb",paramesh); - //MEDLoader::WriteField("./targetsquareb",parafield->getField()); - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - ostringstream filename; - filename<<"./targetsquareb_"<<target_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - dec.sendData(); - ParaMEDLoader::WriteParaMesh("./targetsquare",paramesh); - //MEDLoader::WriteField("./targetsquare",parafield->getField()); - - if (target_group->myRank()==0) - aRemover.Register("./targetsquareb"); - - filename<<"./targetsquareb_"<<target_group->myRank()+1; - aRemover.Register(filename.str().c_str()); - } - delete source_group; - delete target_group; - delete self_group; - delete parafield; - delete paramesh; - mesh->decrRef(); - - delete icocofield; - - MPI_Barrier(MPI_COMM_WORLD); - cout << "end of InterpKernelDEC_3D test"<<endl; -} - -//Synchronous tests without interpolation with native mode (AllToAll(v) from lam/MPI: -void ParaMEDMEMTest::testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.1,1,0.1,1,false,false,false,"P0","P0"); -} - -//Synchronous tests without interpolation : -void ParaMEDMEMTest::testSynchronousEqualInterpKernelWithoutInterpDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.1,1,0.1,1,true,false,false,"P0","P0"); -} - -//Synchronous tests with interpolation : -void ParaMEDMEMTest::testSynchronousEqualInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.1,1,0.1,1,true,false,true,"P0","P0"); -} -void ParaMEDMEMTest::testSynchronousFasterSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.09,1,0.1,1,true,false,true,"P0","P0"); -} -void ParaMEDMEMTest::testSynchronousSlowerSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.11,1,0.1,1,true,false,true,"P0","P0"); -} -void ParaMEDMEMTest::testSynchronousSlowSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.11,1,0.01,1,true,false,true,"P0","P0"); -} -void ParaMEDMEMTest::testSynchronousFastSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.01,1,0.11,1,true,false,true,"P0","P0"); -} - -//Asynchronous tests with interpolation : -void ParaMEDMEMTest::testAsynchronousEqualInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.1,1,0.1,1,true,true,true,"P0","P0"); -} -void ParaMEDMEMTest::testAsynchronousFasterSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.09,1,0.1,1,true,true,true,"P0","P0"); -} -void ParaMEDMEMTest::testAsynchronousSlowerSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.11,1,0.1,1,true,true,true,"P0","P0"); -} -void ParaMEDMEMTest::testAsynchronousSlowSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.11,1,0.01,1,true,true,true,"P0","P0"); -} -void ParaMEDMEMTest::testAsynchronousFastSourceInterpKernelDEC_2D() -{ - testAsynchronousInterpKernelDEC_2D(0.01,1,0.11,1,true,true,true,"P0","P0"); -} - -void ParaMEDMEMTest::testInterpKernelDECNonOverlapp_2D_P0P0() -{ - // - const double sourceCoordsAll[2][8]={{0.4,0.5,0.4,1.5,1.6,1.5,1.6,0.5}, - {0.3,-0.5,1.6,-0.5,1.6,-1.5,0.3,-1.5}}; - const double targetCoordsAll[3][16]={{0.7,1.45,0.7,1.65,0.9,1.65,0.9,1.45, 1.1,1.4,1.1,1.6,1.3,1.6,1.3,1.4}, - {0.7,-0.6,0.7,0.7,0.9,0.7,0.9,-0.6, 1.1,-0.7,1.1,0.6,1.3,0.6,1.3,-0.7}, - {0.7,-1.55,0.7,-1.35,0.9,-1.35,0.9,-1.55, 1.1,-1.65,1.1,-1.45,1.3,-1.45,1.3,-1.65}}; - int conn4All[8]={0,1,2,3,4,5,6,7}; - double targetResults[3][2]={{34.,34.},{38.333333333333336,42.666666666666664},{47.,47.}}; - double targetResults2[3][2]={{0.28333333333333344,0.56666666666666687},{1.8564102564102569,2.0128205128205132},{1.0846153846153845,0.36153846153846159}}; - double targetResults3[3][2]={{3.7777777777777781,7.5555555555555562},{24.511111111111113,26.355555555555558},{14.1,4.7}}; - double targetResults4[3][2]={{8.5,17},{8.8461538461538431, 9.8461538461538449},{35.25,11.75}}; - // - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=5) - return ; - int nproc_source = 2; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD* parafield=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - std::ostringstream stream; stream << "sourcemesh2D proc " << rank; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - const double *sourceCoords=sourceCoordsAll[rank]; - std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - double *value=parafield->getField()->getArray()->getPointer(); - value[0]=34+13*((double)rank); - } - else - { - std::ostringstream stream; stream << "targetmesh2D proc " << rank-nproc_source; - mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(8,2); - const double *targetCoords=targetCoordsAll[rank-nproc_source]; - std::copy(targetCoords,targetCoords+16,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - } - //test 1 - Conservative volumic - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - parafield->getField()->setNature(ConservativeVolumic); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 2 - Integral - ParaMEDMEM::InterpKernelDEC dec2(*source_group,*target_group); - parafield->getField()->setNature(Integral); - if (source_group->containsMyRank()) - { - dec2.setMethod("P0"); - dec2.attachLocalField(parafield); - dec2.synchronize(); - dec2.setForcedRenormalization(false); - dec2.sendData(); - } - else - { - dec2.setMethod("P0"); - dec2.attachLocalField(parafield); - dec2.synchronize(); - dec2.setForcedRenormalization(false); - dec2.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults2[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 3 - Integral with global constraint - ParaMEDMEM::InterpKernelDEC dec3(*source_group,*target_group); - parafield->getField()->setNature(IntegralGlobConstraint); - if (source_group->containsMyRank()) - { - dec3.setMethod("P0"); - dec3.attachLocalField(parafield); - dec3.synchronize(); - dec3.setForcedRenormalization(false); - dec3.sendData(); - } - else - { - dec3.setMethod("P0"); - dec3.attachLocalField(parafield); - dec3.synchronize(); - dec3.setForcedRenormalization(false); - dec3.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults3[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 4 - RevIntegral - ParaMEDMEM::InterpKernelDEC dec4(*source_group,*target_group); - parafield->getField()->setNature(RevIntegral); - if (source_group->containsMyRank()) - { - dec4.setMethod("P0"); - dec4.attachLocalField(parafield); - dec4.synchronize(); - dec4.setForcedRenormalization(false); - dec4.sendData(); - } - else - { - dec4.setMethod("P0"); - dec4.attachLocalField(parafield); - dec4.synchronize(); - dec4.setForcedRenormalization(false); - dec4.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - const double *expected=targetResults4[rank-nproc_source]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); - } - //test 5 - Conservative volumic reversed - ParaMEDMEM::InterpKernelDEC dec5(*source_group,*target_group); - parafield->getField()->setNature(ConservativeVolumic); - if (source_group->containsMyRank()) - { - dec5.setMethod("P0"); - dec5.attachLocalField(parafield); - dec5.synchronize(); - dec5.setForcedRenormalization(false); - dec5.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={37.8518518518519,43.5333333333333}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec5.setMethod("P0"); - dec5.attachLocalField(parafield); - dec5.synchronize(); - dec5.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec5.sendData(); - } - //test 6 - Integral reversed - ParaMEDMEM::InterpKernelDEC dec6(*source_group,*target_group); - parafield->getField()->setNature(Integral); - if (source_group->containsMyRank()) - { - dec6.setMethod("P0"); - dec6.attachLocalField(parafield); - dec6.synchronize(); - dec6.setForcedRenormalization(false); - dec6.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={0.794600591715977,1.35631163708087}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec6.setMethod("P0"); - dec6.attachLocalField(parafield); - dec6.synchronize(); - dec6.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults2[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec6.sendData(); - } - //test 7 - Integral with global constraint reversed - ParaMEDMEM::InterpKernelDEC dec7(*source_group,*target_group); - parafield->getField()->setNature(IntegralGlobConstraint); - if (source_group->containsMyRank()) - { - dec7.setMethod("P0"); - dec7.attachLocalField(parafield); - dec7.synchronize(); - dec7.setForcedRenormalization(false); - dec7.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={36.4592592592593,44.5407407407407}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec7.setMethod("P0"); - dec7.attachLocalField(parafield); - dec7.synchronize(); - dec7.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults3[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec7.sendData(); - } - //test 8 - Integral with RevIntegral reversed - ParaMEDMEM::InterpKernelDEC dec8(*source_group,*target_group); - parafield->getField()->setNature(RevIntegral); - if (source_group->containsMyRank()) - { - dec8.setMethod("P0"); - dec8.attachLocalField(parafield); - dec8.synchronize(); - dec8.setForcedRenormalization(false); - dec8.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,parafield->getField()->getNumberOfTuples()); - const double expected[]={0.81314102564102553,1.3428994082840233}; - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[rank],res[0],1e-13); - } - else - { - dec8.setMethod("P0"); - dec8.attachLocalField(parafield); - dec8.synchronize(); - dec8.setForcedRenormalization(false); - double *res=parafield->getField()->getArray()->getPointer(); - const double *toSet=targetResults4[rank-nproc_source]; - res[0]=toSet[0]; - res[1]=toSet[1]; - dec8.sendData(); - } - // - delete parafield; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -void ParaMEDMEMTest::testInterpKernelDECNonOverlapp_2D_P0P1P1P0() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=5) - return ; - int nproc_source = 2; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafieldP0=0,*parafieldP1=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - if(rank==0) - { - double coords[6]={-0.3,-0.3, 0.7,0.7, 0.7,-0.3}; - int conn[3]={0,1,2}; - //int globalNode[3]={1,2,0}; - mesh=MEDCouplingUMesh::New("Source mesh Proc0",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - if(rank==1) - { - double coords[6]={-0.3,-0.3, -0.3,0.7, 0.7,0.7}; - int conn[3]={0,1,2}; - //int globalNode[3]={1,3,2}; - mesh=MEDCouplingUMesh::New("Source mesh Proc1",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - } - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP1 = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - double *valueP1=parafieldP1->getField()->getArray()->getPointer(); - parafieldP0->getField()->setNature(ConservativeVolumic); - parafieldP1->getField()->setNature(ConservativeVolumic); - if(rank==0) - { - valueP0[0]=31.; - valueP1[0]=34.; valueP1[1]=77.; valueP1[2]=53.; - } - if(rank==1) - { - valueP0[0]=47.; - valueP1[0]=34.; valueP1[1]=57.; valueP1[2]=77.; - } - } - else - { - const char targetMeshName[]="target mesh"; - if(rank==2) - { - double coords[10]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; - int conn[7]={0,3,4,1, 1,4,2}; - //int globalNode[5]={4,3,0,2,1}; - mesh=MEDCouplingUMesh::New("Target mesh Proc2",2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coords,coords+10,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - DataArrayInt *da=DataArrayInt::New(); - const int globalNumberingP2[5]={0,1,2,3,4}; - da->useArray(globalNumberingP2,false,CPP_DEALLOC,5,1); - paramesh->setNodeGlobal(da); - da->decrRef(); - } - if(rank==3) - { - double coords[6]={0.2,0.2, 0.7,-0.3, 0.7,0.2}; - int conn[3]={0,2,1}; - //int globalNode[3]={1,0,5}; - mesh=MEDCouplingUMesh::New("Target mesh Proc3",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - DataArrayInt *da=DataArrayInt::New(); - const int globalNumberingP3[3]={4,2,5}; - da->useArray(globalNumberingP3,false,CPP_DEALLOC,3,1); - paramesh->setNodeGlobal(da); - da->decrRef(); - } - if(rank==4) - { - double coords[12]={-0.3,0.2, -0.3,0.7, 0.2,0.7, 0.2,0.2, 0.7,0.7, 0.7,0.2}; - int conn[8]={0,1,2,3, 3,2,4,5}; - //int globalNode[6]={2,6,7,1,8,5}; - mesh=MEDCouplingUMesh::New("Target mesh Proc4",2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(6,2); - std::copy(coords,coords+12,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - DataArrayInt *da=DataArrayInt::New(); - const int globalNumberingP4[6]={3,6,7,4,8,5}; - da->useArray(globalNumberingP4,false,CPP_DEALLOC,6,1); - paramesh->setNodeGlobal(da); - da->decrRef(); - } - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP1 = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - parafieldP0->getField()->setNature(ConservativeVolumic); - parafieldP1->getField()->setNature(ConservativeVolumic); - } - // test 1 - P0 P1 - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - dec.recvData(); - const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(34.42857143,valueP0[0],1e-7); - } - if(rank==1) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(44.,valueP0[0],1e-7); - } - } - else - { - dec.setMethod("P1"); - dec.attachLocalField(parafieldP1); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafieldP1->getField()->getArray()->getConstPointer(); - if(rank==2) - { - const double expectP2[5]={39.0, 31.0, 31.0, 47.0, 39.0}; - CPPUNIT_ASSERT_EQUAL(5,parafieldP1->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); - for(int kk=0;kk<5;kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP2[kk],res[kk],1e-12); - } - if(rank==3) - { - const double expectP3[3]={39.0, 31.0, 31.0}; - CPPUNIT_ASSERT_EQUAL(3,parafieldP1->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); - for(int kk=0;kk<3;kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP3[kk],res[kk],1e-12); - } - if(rank==4) - { - const double expectP4[6]={47.0, 47.0, 47.0, 39.0, 39.0, 31.0}; - CPPUNIT_ASSERT_EQUAL(6,parafieldP1->getField()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,parafieldP1->getField()->getNumberOfComponents()); - for(int kk=0;kk<6;kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expectP4[kk],res[kk],1e-12); - } - dec.sendData(); - } - // - delete parafieldP0; - delete parafieldP1; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -void ParaMEDMEMTest::testInterpKernelDEC2DM1D_P0P0() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=3) - return ; - int nproc_source=2; - set<int> procs_source; - set<int> procs_target; - // - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source;i<size; i++) - procs_target.insert(i); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafield=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - if(rank==0) - { - int targetConn[7]={0,3,4,1, 1,4,2}; - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - mesh->finishInsertingCells(); - } - else - { - int targetConn[11]={4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->allocateCells(3); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+3); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+7); - mesh->finishInsertingCells(); - } - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - double *vals=parafield->getField()->getArray()->getPointer(); - if(rank==0) - { vals[0]=7.; vals[1]=8.; } - else - { vals[0]=9.; vals[1]=10.; vals[2]=11.; } - } - else - { - mesh=MEDCouplingUMesh::New("an example of -1 D mesh",-1); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*target_group,"target mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - } - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - if(source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.sendData(); - dec.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[1],1e-12); - } - else - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[2],1e-12); - } - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafield); - dec.synchronize(); - dec.setForcedRenormalization(false); - dec.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[0],1e-12); - dec.sendData(); - } - ParaMEDMEM::InterpKernelDEC dec2(*source_group,*target_group); - dec2.setMethod("P0"); - parafield->getField()->setNature(IntegralGlobConstraint); - if(source_group->containsMyRank()) - { - double *vals=parafield->getField()->getArray()->getPointer(); - if(rank==0) - { vals[0]=7.; vals[1]=8.; } - else - { vals[0]=9.; vals[1]=10.; vals[2]=11.; } - dec2.attachLocalField(parafield); - dec2.synchronize(); - dec2.sendData(); - dec2.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.25,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.625,res[1],1e-12); - } - else - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.625,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.25,res[1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.25,res[2],1e-12); - } - } - else - { - dec2.attachLocalField(parafield); - dec2.synchronize(); - dec2.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(45.,res[0],1e-12); - dec2.sendData(); - } - // - ParaMEDMEM::InterpKernelDEC dec3(*source_group,*target_group); - dec3.setMethod("P0"); - parafield->getField()->setNature(Integral); - if(source_group->containsMyRank()) - { - double *vals=parafield->getField()->getArray()->getPointer(); - if(rank==0) - { vals[0]=7.; vals[1]=8.; } - else - { vals[0]=9.; vals[1]=10.; vals[2]=11.; } - dec3.attachLocalField(parafield); - dec3.synchronize(); - dec3.sendData(); - dec3.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.25,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.625,res[1],1e-12); - } - else - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.625,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.25,res[1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.25,res[2],1e-12); - } - } - else - { - dec3.attachLocalField(parafield); - dec3.synchronize(); - dec3.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(45.,res[0],1e-12); - dec3.sendData(); - } - // - ParaMEDMEM::InterpKernelDEC dec4(*source_group,*target_group); - dec4.setMethod("P0"); - parafield->getField()->setNature(RevIntegral); - if(source_group->containsMyRank()) - { - double *vals=parafield->getField()->getArray()->getPointer(); - if(rank==0) - { vals[0]=7.; vals[1]=8.; } - else - { vals[0]=9.; vals[1]=10.; vals[2]=11.; } - dec4.attachLocalField(parafield); - dec4.synchronize(); - dec4.sendData(); - dec4.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[1],1e-12); - } - else - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[2],1e-12); - } - } - else - { - dec4.attachLocalField(parafield); - dec4.synchronize(); - dec4.recvData(); - const double *res=parafield->getField()->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,res[0],1e-12); - dec4.sendData(); - } - delete parafield; - delete paramesh; - mesh->decrRef(); - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -void ParaMEDMEMTest::testInterpKernelDECPartialProcs() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=3) - return ; - set<int> procs_source; - set<int> procs_target; - // - procs_source.insert(0); - procs_target.insert(1); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafield=0; - // - ParaMEDMEM::CommInterface interface; - // - MPI_Barrier(MPI_COMM_WORLD); - double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. }; - CommInterface comm; - int grpIds[2]={0,1}; - MPI_Group grp,group_world; - comm.commGroup(MPI_COMM_WORLD,&group_world); - comm.groupIncl(group_world,2,grpIds,&grp); - MPI_Comm partialComm; - comm.commCreate(MPI_COMM_WORLD,grp,&partialComm); - // - ProcessorGroup* target_group=0; - ProcessorGroup* source_group=0; - // - ParaMEDMEM::InterpKernelDEC *dec=0; - if(rank==0 || rank==1) - { - target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target,partialComm); - source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source,partialComm); - if(source_group->containsMyRank()) - { - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - int targetConn[4]={0,2,3,1}; - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - mesh->finishInsertingCells(); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - double *vals=parafield->getField()->getArray()->getPointer(); - vals[0]=7.; - dec=new ParaMEDMEM::InterpKernelDEC(*source_group,*target_group); - dec->attachLocalField(parafield); - dec->synchronize(); - dec->sendData(); - dec->recvData(); - } - else - { - mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - int targetConn[6]={0,2,1,2,3,1}; - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - mesh->finishInsertingCells(); - ParaMEDMEM::ComponentTopology comptopo; - paramesh=new ParaMESH(mesh,*target_group,"target mesh"); - parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic); - dec=new ParaMEDMEM::InterpKernelDEC(*source_group,*target_group); - dec->attachLocalField(parafield); - dec->synchronize(); - dec->recvData(); - dec->sendData(); - } - } - delete parafield; - delete paramesh; - if(mesh) - mesh->decrRef(); - delete target_group; - delete source_group; - delete dec; - if(partialComm != MPI_COMM_NULL) - comm.commFree(&partialComm); - comm.groupFree(&grp); - comm.groupFree(&group_world); - MPI_Barrier(MPI_COMM_WORLD); -} - -/*! - * This test reproduces bug of Gauthier on 13/9/2010 concerning 3DSurf meshes. - * It is possible to lead to dead lock in InterpKernelDEC when 3DSurfMeshes global bounding boxes intersects whereas cell bounding box intersecting only on one side. - */ -void ParaMEDMEMTest::testInterpKernelDEC3DSurfEmptyBBox() -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // - if(size!=3) - return ; - int nproc_source = 1; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - // - ParaMEDMEM::MEDCouplingUMesh *mesh=0; - ParaMEDMEM::ParaMESH *paramesh=0; - ParaMEDMEM::ParaFIELD *parafieldP0=0; - // - ParaMEDMEM::CommInterface interface; - // - ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - // - MPI_Barrier(MPI_COMM_WORLD); - if(source_group->containsMyRank()) - { - double coords[15]={1.,0.,0., 2.,0.,0., 2.,2.,0., 0.,2.,0., 0.5,0.5,1.}; - int conn[7]={0,1,2,3,0,3,4}; - mesh=MEDCouplingUMesh::New("Source mesh Proc0",2); - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,3); - std::copy(coords,coords+15,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - // - paramesh=new ParaMESH(mesh,*source_group,"source mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - parafieldP0->getField()->setNature(ConservativeVolumic); - valueP0[0]=7.; valueP0[1]=8.; - } - else - { - const char targetMeshName[]="target mesh"; - if(rank==1) - { - double coords[12]={0.25,0.25,0.5, 0.,0.25,0.5, 0.,0.,0.5, 0.25,0.,0.5}; - int conn[4]={0,1,2,3}; - mesh=MEDCouplingUMesh::New("Target mesh Proc1",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(coords,coords+12,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - } - if(rank==2) - { - double coords[12]={0.,0.25,0.5, 0.,0.,0.5, -1.,0.,0.5, -1.,0.25,0.5}; - int conn[4]={0,1,2,3}; - mesh=MEDCouplingUMesh::New("Target mesh Proc2",2); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(coords,coords+12,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - paramesh=new ParaMESH(mesh,*target_group,targetMeshName); - } - ParaMEDMEM::ComponentTopology comptopo; - parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafieldP0->getField()->setNature(ConservativeVolumic); - } - // test 1 - ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); - if (source_group->containsMyRank()) - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - // dec.setForcedRenormalization(false); - // dec.sendData(); - // dec.recvData(); - // const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); - // if(rank==0) - // { - // CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7); - // CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7); - // } - // if(rank==1) - // { - // CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7); - // } - // if(rank==2) - // { - // CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7); - // } - } - else - { - dec.setMethod("P0"); - dec.attachLocalField(parafieldP0); - dec.synchronize(); - // dec.setForcedRenormalization(false); - // dec.recvData(); - // const double *res=parafieldP0->getField()->getArray()->getConstPointer(); - // if(rank==3) - // { - // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); - // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); - // CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12); - // } - // if(rank==4) - // { - // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); - // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); - // CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12); - // } - // dec.sendData(); - } - // - delete parafieldP0; - mesh->decrRef(); - delete paramesh; - delete self_group; - delete target_group; - delete source_group; - // - MPI_Barrier(MPI_COMM_WORLD); -} - -/*! - * Tests an asynchronous exchange between two codes - * one sends data with dtA as an interval, the max time being tmaxA - * the other one receives with dtB as an interval, the max time being tmaxB - */ -void ParaMEDMEMTest::testAsynchronousInterpKernelDEC_2D(double dtA, double tmaxA, - double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous, - bool WithInterp, const char *srcMeth, const char *targetMeth) -{ - std::string srcM(srcMeth); - std::string targetM(targetMeth); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - //the test is meant to run on five processors - if (size !=5) return ; - - int nproc_source = 3; - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - - //loading the geometry for the source group - - ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); - - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::ParaMESH* paramesh; - ParaMEDMEM::ParaFIELD* parafield; - - ICoCo::MEDField* icocofield ; - - char * tmp_dir_c = getenv("TMP"); - string tmp_dir; - if (tmp_dir_c != NULL) - tmp_dir = string(tmp_dir_c); - else - tmp_dir = "/tmp"; - string filename_xml1 = getResourceFile("square1_split"); - string filename_xml2 = getResourceFile("square2_split"); - //string filename_seq_wr = makeTmpFile(""); - //string filename_seq_med = makeTmpFile("myWrField_seq_pointe221.med"); - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - - MPI_Barrier(MPI_COMM_WORLD); - - if (source_group->containsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <<master<<rank+1<<".med"; - ostringstream meshname ; - meshname<< "Mesh_2_"<< rank+1; - - mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - paramesh=new ParaMESH (mesh,*source_group,"source mesh"); - - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group); - ParaMEDMEM::ComponentTopology comptopo; - if(srcM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - - int nb_local; - if(srcM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - // double * value= new double[nb_local]; - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - - // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); - icocofield=new ICoCo::MEDField(parafield->getField()); - - dec.attachLocalField(icocofield); - - - } - - //loading the geometry for the target group - if (target_group->containsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - meshname<< "Mesh_3_"<<rank-nproc_source+1; - - mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); - ParaMEDMEM::ComponentTopology comptopo; - if(targetM=="P0") - { - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - parafield->getField()->setNature(ConservativeVolumic);//InvertIntegral);//ConservativeVolumic); - } - else - parafield = new ParaFIELD(ON_NODES,NO_TIME,paramesh, comptopo); - - int nb_local; - if(targetM=="P0") - nb_local=mesh->getNumberOfCells(); - else - nb_local=mesh->getNumberOfNodes(); - - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); - icocofield=new ICoCo::MEDField(parafield->getField()); - - dec.attachLocalField(icocofield); - } - - - //attaching a DEC to the source group - - if (source_group->containsMyRank()) - { - cout<<"DEC usage"<<endl; - dec.setAsynchronous(Asynchronous); - if ( WithInterp ) { - dec.setTimeInterpolationMethod(LinearTimeInterp); - } - if ( WithPointToPoint ) { - dec.setAllToAllMethod(PointToPoint); - } - else { - dec.setAllToAllMethod(Native); - } - dec.synchronize(); - dec.setForcedRenormalization(false); - for (double time=0; time<tmaxA+1e-10; time+=dtA) - { - cout << "testAsynchronousInterpKernelDEC_2D" << rank << " time " << time - << " dtA " << dtA << " tmaxA " << tmaxA << endl ; - if ( time+dtA < tmaxA+1e-7 ) { - dec.sendData( time , dtA ); - } - else { - dec.sendData( time , 0 ); - } - double* value = parafield->getField()->getArray()->getPointer(); - int nb_local=parafield->getField()->getMesh()->getNumberOfCells(); - for (int i=0; i<nb_local;i++) - value[i]= time+dtA; - - - } - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - cout<<"DEC usage"<<endl; - dec.setAsynchronous(Asynchronous); - if ( WithInterp ) { - dec.setTimeInterpolationMethod(LinearTimeInterp); - } - if ( WithPointToPoint ) { - dec.setAllToAllMethod(PointToPoint); - } - else { - dec.setAllToAllMethod(Native); - } - dec.synchronize(); - dec.setForcedRenormalization(false); - vector<double> times; - for (double time=0; time<tmaxB+1e-10; time+=dtB) - { - cout << "testAsynchronousInterpKernelDEC_2D" << rank << " time " << time - << " dtB " << dtB << " tmaxB " << tmaxB << endl ; - dec.recvData( time ); - double vi = parafield->getVolumeIntegral(0,true); - cout << "testAsynchronousInterpKernelDEC_2D" << rank << " time " << time - << " VolumeIntegral " << vi - << " time*10000 " << time*10000 << endl ; - - CPPUNIT_ASSERT_DOUBLES_EQUAL(vi,time*10000,0.001); - } - - } - - delete source_group; - delete target_group; - delete self_group; - delete parafield ; - delete paramesh ; - mesh->decrRef() ; - delete icocofield ; - - cout << "testAsynchronousInterpKernelDEC_2D" << rank << " MPI_Barrier " << endl ; - - if (Asynchronous) MPI_Barrier(MPI_COMM_WORLD); - cout << "end of InterpKernelDEC_2D test"<<endl; -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx deleted file mode 100644 index 01dc8227c..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include "MEDLoader.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include <cppunit/TestAssert.h> - -#include <algorithm> -#include <numeric> -#include <iostream> -#include <iterator> - -using namespace std; -using namespace INTERP_KERNEL; -using namespace ParaMEDMEM; - diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MPIProcessorGroup.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MPIProcessorGroup.cxx deleted file mode 100644 index 91ef8bb8a..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_MPIProcessorGroup.cxx +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "InterpolationUtils.hxx" - -#include <string> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - - -using namespace std; -using namespace ParaMEDMEM; - -/* - * Check methods defined in MPPIProcessorGroup.hxx - * - (+) MPIProcessorGroup(const CommInterface& interface); - (+) MPIProcessorGroup(const CommInterface& interface, set<int> proc_ids); - (u) MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids); - (+) MPIProcessorGroup(const CommInterface& interface,int pstart, int pend); - (+) virtual ~MPIProcessorGroup(); - (+) virtual ProcessorGroup* fuse (const ProcessorGroup&) const; - (u) void intersect (ProcessorGroup&){}; - (+) int myRank() const {int rank; MPI_Comm_rank(_comm,&rank); return rank;} - (+) bool containsMyRank() const { int rank; MPI_Group_rank(_group, &rank); return (rank!=MPI_UNDEFINED);} - (+) int translateRank(const ProcessorGroup* group, int rank) const; - (+) const MPI_Comm* getComm() const {return &_comm;} - (+) ProcessorGroup* createComplementProcGroup() const; - (o) ProcessorGroup* createProcGroup() const; - -*/ - -void ParaMEDMEMTest::testMPIProcessorGroup_constructor() -{ - CommInterface comm_interface; - MPIProcessorGroup* group = new MPIProcessorGroup(comm_interface);; - int size; - MPI_Comm_size(MPI_COMM_WORLD, &size); - CPPUNIT_ASSERT_EQUAL(size,group->size()); - int size2; - const MPI_Comm* communicator=group->getComm(); - MPI_Comm_size(*communicator, &size2); - CPPUNIT_ASSERT_EQUAL(size,size2); - delete group; - - set <int> procs; - - procs.insert(0); - procs.insert(1); - if (size==1) - CPPUNIT_ASSERT_THROW(group=new MPIProcessorGroup(comm_interface,procs),INTERP_KERNEL::Exception); - else - { - CPPUNIT_ASSERT_NO_THROW( group=new MPIProcessorGroup(comm_interface,procs)); - CPPUNIT_ASSERT_EQUAL (group->size(),2); - delete group; - } - - //throws because plast<pfirst - CPPUNIT_ASSERT_THROW(group=new MPIProcessorGroup(comm_interface,1,0),INTERP_KERNEL::Exception); - //throws because plast is beyond size-1 - CPPUNIT_ASSERT_THROW(group=new MPIProcessorGroup(comm_interface,0,size),INTERP_KERNEL::Exception); - if (size>1) - { - group=new MPIProcessorGroup(comm_interface,0,size-2); - CPPUNIT_ASSERT_EQUAL(group->size(),size-1); - delete group; - } - -} - -void ParaMEDMEMTest::testMPIProcessorGroup_boolean() -{ - int size; - MPI_Comm_size(MPI_COMM_WORLD, &size); - - CommInterface comm_interface; - MPIProcessorGroup group(comm_interface,0,0); - MPIProcessorGroup group2(comm_interface,size-1,size-1); - ProcessorGroup* group_fuse=group.fuse(group2); - int group_fuse_size=(size==1)?1:2; - CPPUNIT_ASSERT_EQUAL(group_fuse_size,group_fuse->size()); - - ProcessorGroup* group_complement=((MPIProcessorGroup*)group_fuse)->createComplementProcGroup(); - CPPUNIT_ASSERT_EQUAL(group_complement->size(),size-group_fuse_size); - - delete group_fuse; - delete group_complement; - - //intersect not implemented yet - // if (size>1) - // { - // MPIProcessorGroup group3(comm_interface,0,size-2); - // MPIProcessorGroup group4(comm_interface,1,size-1); - // group3.intersect(group4); - // CPPUNIT_ASSERT_EQUAL(group3.size(),size-2); - // } -} - -void ParaMEDMEMTest::testMPIProcessorGroup_rank() -{ - int size; - MPI_Comm_size(MPI_COMM_WORLD, &size); - int rank; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - CommInterface comm_interface; - MPIProcessorGroup group(comm_interface,0,0); - MPIProcessorGroup group2(comm_interface,size-1,size-1); - ProcessorGroup* group_fuse=group2.fuse(group); - - if (group.containsMyRank()) - CPPUNIT_ASSERT_EQUAL (group.myRank(), rank); - - if (group2.containsMyRank()) - { - int trank=group_fuse->translateRank(&group2,0); - if (size==1) - CPPUNIT_ASSERT_EQUAL(trank,0); - else - CPPUNIT_ASSERT_EQUAL(trank,1); - } - delete group_fuse; -} diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx deleted file mode 100644 index 0648200b4..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifdef MED_ENABLE_FVM - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Exception.hxx" -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "DEC.hxx" -#include "NonCoincidentDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "UnstructuredParaSUPPORT.hxx" -#include "ICoCoMEDField.hxx" - -#include <string> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - - -using namespace std; -using namespace ParaMEDMEM; -using namespace MEDMEM; - -/* - * Check methods defined in InterpKernelDEC.hxx - * - InterpKernelDEC(); - InterpKernelDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); - virtual ~InterpKernelDEC(); - void synchronize(); - void recvData(); - void sendData(); -*/ - -void ParaMEDMEMTest::testNonCoincidentDEC_2D() -{ - - int size; - MPI_Comm_size(MPI_COMM_WORLD,&size); - - //the test is meant to run on five processors - if (size !=5) return ; - - testNonCoincidentDEC( "square1_split", - "Mesh_2", - "square2_split", - "Mesh_3", - 3, - 1e-6); -} - -void ParaMEDMEMTest::testNonCoincidentDEC_3D() -{ - int size; - MPI_Comm_size(MPI_COMM_WORLD,&size); - - //the test is meant to run on five processors - if (size !=4) return ; - - testNonCoincidentDEC( "blade_12000_split2", - "Mesh_1", - "blade_3000_split2", - "Mesh_1", - 2, - 1e4); -} - -void ParaMEDMEMTest::testNonCoincidentDEC(const string& filename1, - const string& meshname1, - const string& filename2, - const string& meshname2, - int nproc_source, - double epsilon) -{ - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - - ParaMEDMEM::ParaMESH* source_mesh=0; - ParaMEDMEM::ParaMESH* target_mesh=0; - ParaMEDMEM::ParaSUPPORT* parasupport=0; - //loading the geometry for the source group - - ParaMEDMEM::NonCoincidentDEC dec (*source_group,*target_group); - - MEDMEM::MESH* mesh; - MEDMEM::SUPPORT* support; - MEDMEM::FIELD<double>* field; - ParaMEDMEM::ParaMESH* paramesh; - ParaMEDMEM::ParaFIELD* parafield; - - string filename_xml1 = getResourceFile(filename1); - string filename_xml2 = getResourceFile(filename2); - //string filename_seq_wr = makeTmpFile(""); - //string filename_seq_med = makeTmpFile("myWrField_seq_pointe221.med"); - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - //aRemover.Register(filename_seq_wr); - //aRemover.Register(filename_seq_med); - MPI_Barrier(MPI_COMM_WORLD); - ICoCo::Field* icocofield; - if (source_group->containsMyRank()) - { - string master = filename_xml1; - - ostringstream strstream; - strstream <<master<<rank+1<<".med"; - ostringstream meshname ; - meshname<< meshname1<<"_"<< rank+1; - - CPPUNIT_ASSERT_NO_THROW(mesh = new MESH(MED_DRIVER,strstream.str(),meshname.str())); - support=new MEDMEM::SUPPORT(mesh,"all elements",MED_EN::MED_CELL); - - paramesh=new ParaMESH (*mesh,*source_group,"source mesh"); - - parasupport=new UnstructuredParaSUPPORT( support,*source_group); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(parasupport, comptopo); - - - int nb_local=support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); - double * value= new double[nb_local]; - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=1.0; - parafield->getField()->setValue(value); - - icocofield=new ICoCo::MEDField(paramesh,parafield); - - dec.attachLocalField(icocofield); - delete [] value; - } - - //loading the geometry for the target group - if (target_group->containsMyRank()) - { - string master= filename_xml2; - ostringstream strstream; - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - meshname<< meshname2<<"_"<<rank-nproc_source+1; - - CPPUNIT_ASSERT_NO_THROW(mesh = new MESH(MED_DRIVER,strstream.str(),meshname.str())); - support=new MEDMEM::SUPPORT(mesh,"all elements",MED_EN::MED_CELL); - - paramesh=new ParaMESH (*mesh,*target_group,"target mesh"); - parasupport=new UnstructuredParaSUPPORT(support,*target_group); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(parasupport, comptopo); - - - int nb_local=support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); - double * value= new double[nb_local]; - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - parafield->getField()->setValue(value); - icocofield=new ICoCo::MEDField(paramesh,parafield); - - dec.attachLocalField(icocofield); - delete [] value; - } - - - //attaching a DEC to the source group - double field_before_int; - double field_after_int; - - if (source_group->containsMyRank()) - { - field_before_int = parafield->getVolumeIntegral(1); - MPI_Bcast(&field_before_int, 1,MPI_DOUBLE, 0,MPI_COMM_WORLD); - dec.synchronize(); - cout<<"DEC usage"<<endl; - dec.setOption("ForcedRenormalization",false); - - dec.sendData(); - // paramesh->write(MED_DRIVER,"./sourcesquarenc"); - //parafield->write(MED_DRIVER,"./sourcesquarenc","boundary"); - - - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()) - { - MPI_Bcast(&field_before_int, 1,MPI_DOUBLE, 0,MPI_COMM_WORLD); - - dec.synchronize(); - dec.setOption("ForcedRenormalization",false); - dec.recvData(); - //paramesh->write(MED_DRIVER, "./targetsquarenc"); - //parafield->write(MED_DRIVER, "./targetsquarenc", "boundary"); - field_after_int = parafield->getVolumeIntegral(1); - - } - MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); - MPI_Bcast(&field_after_int, 1,MPI_DOUBLE, size-1,MPI_COMM_WORLD); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, epsilon); - - delete source_group; - delete target_group; - delete self_group; - delete icocofield; - delete paramesh; - delete parafield; - delete support; - delete parasupport; - delete mesh; - MPI_Barrier(MPI_COMM_WORLD); - -} -#endif diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx deleted file mode 100644 index f6b14cf49..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx +++ /dev/null @@ -1,704 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "OverlapDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include <set> - -using namespace std; - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingRemapper.hxx" - -using namespace ParaMEDMEM; - -typedef MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> MUMesh; -typedef MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> MFDouble; -typedef MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> DADouble; - -//void ParaMEDMEMTest::testOverlapDEC_LMEC_seq() -//{ -// // T_SC_Trio_src.med -- "SupportOf_" -// // T_SC_Trio_dst.med -- "SupportOf_T_SC_Trio" -// // h_TH_Trio_src.med -- "SupportOf_" -// // h_TH_Trio_dst.med -- "SupportOf_h_TH_Trio" -// string rep("/export/home/adrien/support/antoine_LMEC/"); -// string src_mesh_nam(rep + string("T_SC_Trio_src.med")); -// string tgt_mesh_nam(rep + string("T_SC_Trio_dst.med")); -//// string src_mesh_nam(rep + string("h_TH_Trio_src.med")); -//// string tgt_mesh_nam(rep + string("h_TH_Trio_dst.med")); -// MUMesh src_mesh=MEDLoader::ReadUMeshFromFile(src_mesh_nam,"SupportOf_",0); -// MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_T_SC_Trio",0); -//// MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_h_TH_Trio",0); -// -// MFDouble srcField = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME); -// srcField->setMesh(src_mesh); -// DataArrayDouble * dad = DataArrayDouble::New(); dad->alloc(src_mesh->getNumberOfCells(),1); -// dad->fillWithValue(1.0); -// srcField->setArray(dad); -// srcField->setNature(ConservativeVolumic); -// -// MEDCouplingRemapper remap; -// remap.setOrientation(2); // always consider surface intersections as absolute areas. -// remap.prepare(src_mesh, tgt_mesh, "P0P0"); -// MFDouble tgtField = remap.transferField(srcField, 1.0e+300); -// tgtField->setName("result"); -// string out_nam(rep + string("adrien.med")); -// MEDLoader::WriteField(out_nam,tgtField, true); -// cout << "wrote: " << out_nam << "\n"; -// double integ1 = 0.0, integ2 = 0.0; -// srcField->integral(true, &integ1); -// tgtField->integral(true, &integ2); -//// tgtField->reprQuickOverview(cout); -// CPPUNIT_ASSERT_DOUBLES_EQUAL(integ1,integ2,1e-8); -// -// dad->decrRef(); -//} -// -//void ParaMEDMEMTest::testOverlapDEC_LMEC_para() -//{ -// using namespace ParaMEDMEM; -// -// int size; -// int rank; -// MPI_Comm_size(MPI_COMM_WORLD,&size); -// MPI_Comm_rank(MPI_COMM_WORLD,&rank); -// -// if (size != 1) return ; -// -// int nproc = 1; -// std::set<int> procs; -// -// for (int i=0; i<nproc; i++) -// procs.insert(i); -// -// CommInterface interface; -// OverlapDEC dec(procs); -// -// ParaMESH* parameshS=0; -// ParaMESH* parameshT=0; -// ParaFIELD* parafieldS=0; -// ParaFIELD* parafieldT=0; -// MFDouble srcField; -// -// // **** FILE LOADING -// // T_SC_Trio_src.med -- "SupportOf_" -// // T_SC_Trio_dst.med -- "SupportOf_T_SC_Trio" -// // h_TH_Trio_src.med -- "SupportOf_" -// // h_TH_Trio_dst.med -- "SupportOf_h_TH_Trio" -// string rep("/export/home/adrien/support/antoine_LMEC/"); -// string src_mesh_nam(rep + string("T_SC_Trio_src.med")); -// string tgt_mesh_nam(rep + string("T_SC_Trio_dst.med")); -// -// -// MPI_Barrier(MPI_COMM_WORLD); -// if(rank==0) -// { -// // string src_mesh_nam(rep + string("h_TH_Trio_src.med")); -// // string tgt_mesh_nam(rep + string("h_TH_Trio_dst.med")); -// MUMesh src_mesh=MEDLoader::ReadUMeshFromFile(src_mesh_nam,"SupportOf_",0); -// MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_T_SC_Trio",0); -// // MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_h_TH_Trio",0); -// -// // **** SOURCE -// srcField = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME); -// srcField->setMesh(src_mesh); -// DataArrayDouble * dad = DataArrayDouble::New(); dad->alloc(src_mesh->getNumberOfCells(),1); -// dad->fillWithValue(1.0); -// srcField->setArray(dad); -// srcField->setNature(ConservativeVolumic); -// -// ComponentTopology comptopo; -// parameshS = new ParaMESH(src_mesh,*dec.getGroup(),"source mesh"); -// parafieldS = new ParaFIELD(ON_CELLS,ONE_TIME,parameshS,comptopo); -// parafieldS->getField()->setNature(ConservativeVolumic);//IntegralGlobConstraint -// parafieldS->getField()->setArray(dad); -// -// // **** TARGET -// parameshT=new ParaMESH(tgt_mesh,*dec.getGroup(),"target mesh"); -// parafieldT=new ParaFIELD(ON_CELLS,ONE_TIME,parameshT,comptopo); -// parafieldT->getField()->setNature(ConservativeVolumic);//IntegralGlobConstraint -// parafieldT->getField()->getArray()->fillWithValue(1.0e300); -//// valsT[0]=7.; -// } -// dec.setOrientation(2); -// dec.attachSourceLocalField(parafieldS); -// dec.attachTargetLocalField(parafieldT); -// dec.synchronize(); -// dec.sendRecvData(true); -// // -// if(rank==0) -// { -// double integ1 = 0.0, integ2 = 0.0; -// MEDCouplingFieldDouble * tgtField; -// -// srcField->integral(true, &integ1); -// tgtField = parafieldT->getField(); -//// tgtField->reprQuickOverview(cout); -// tgtField->integral(true, &integ2); -// tgtField->setName("result"); -// string out_nam(rep + string("adrien_para.med")); -// MEDLoader::WriteField(out_nam,tgtField, true); -// cout << "wrote: " << out_nam << "\n"; -// CPPUNIT_ASSERT_DOUBLES_EQUAL(integ1,integ2,1e-8); -// } -// delete parafieldS; -// delete parafieldT; -// delete parameshS; -// delete parameshT; -// -// MPI_Barrier(MPI_COMM_WORLD); -//} -// -void prepareData1(int rank, NatureOfField nature, - MEDCouplingFieldDouble *& fieldS, MEDCouplingFieldDouble *& fieldT) -{ - if(rank==0) - { - const double coordsS[10]={0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5}; - const double coordsT[6]={0.,0.,1.,0.,1.,1.}; - MUMesh meshS=MEDCouplingUMesh::New(); - meshS->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coordsS,coordsS+10,myCoords->getPointer()); - meshS->setCoords(myCoords); - myCoords->decrRef(); - int connS[7]={0,3,4,1, 1,4,2}; - meshS->allocateCells(2); - meshS->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS); - meshS->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connS+4); - meshS->finishInsertingCells(); - fieldS = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DADouble arr = DataArrayDouble::New(); arr->alloc(meshS->getNumberOfCells(), 1); - fieldS->setMesh(meshS); fieldS->setArray(arr); - fieldS->setNature(nature); - double *valsS=fieldS->getArray()->getPointer(); - valsS[0]=7.; valsS[1]=8.; - // - MUMesh meshT=MEDCouplingUMesh::New(); - meshT->setMeshDimension(2); - myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coordsT,coordsT+6,myCoords->getPointer()); - meshT->setCoords(myCoords); - myCoords->decrRef(); - int connT[3]={0,2,1}; - meshT->allocateCells(1); - meshT->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT); - meshT->finishInsertingCells(); - fieldT = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DADouble arr2 = DataArrayDouble::New(); arr2->alloc(meshT->getNumberOfCells(), 1); - fieldT->setMesh(meshT); fieldT->setArray(arr2); - fieldT->setNature(nature); - double *valsT=fieldT->getArray()->getPointer(); - valsT[0]=7.; - } - // - if(rank==1) - { - const double coordsS[10]={1.,0.,0.5,0.5,1.,0.5,0.5,1.,1.,1.}; - const double coordsT[6]={0.,0.,0.5,0.5,0.,1.}; - MUMesh meshS=MEDCouplingUMesh::New(); - meshS->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coordsS,coordsS+10,myCoords->getPointer()); - meshS->setCoords(myCoords); - myCoords->decrRef(); - int connS[7]={0,1,2, 1,3,4,2}; - meshS->allocateCells(2); - meshS->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connS); - meshS->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS+3); - meshS->finishInsertingCells(); - fieldS = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DADouble arr = DataArrayDouble::New(); arr->alloc(meshS->getNumberOfCells(), 1); - fieldS->setMesh(meshS); fieldS->setArray(arr); - fieldS->setNature(nature); - double *valsS=fieldS->getArray()->getPointer(); - valsS[0]=9.; valsS[1]=11.; - // - MUMesh meshT=MEDCouplingUMesh::New(); - meshT->setMeshDimension(2); - myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coordsT,coordsT+6,myCoords->getPointer()); - meshT->setCoords(myCoords); - myCoords->decrRef(); - int connT[3]={0,2,1}; - meshT->allocateCells(1); - meshT->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT); - meshT->finishInsertingCells(); - fieldT = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DADouble arr2 = DataArrayDouble::New(); arr2->alloc(meshT->getNumberOfCells(), 1); - fieldT->setMesh(meshT); fieldT->setArray(arr2); - fieldT->setNature(nature); - double *valsT=fieldT->getArray()->getPointer(); - valsT[0]=8.; - } - // - if(rank==2) - { - const double coordsS[8]={0.,0.5, 0.5,0.5, 0.,1., 0.5,1.}; - const double coordsT[6]={0.5,0.5,0.,1.,1.,1.}; - MUMesh meshS=MEDCouplingUMesh::New(); - meshS->setMeshDimension(2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(coordsS,coordsS+8,myCoords->getPointer()); - meshS->setCoords(myCoords); - myCoords->decrRef(); - int connS[4]={0,2,3,1}; - meshS->allocateCells(1); - meshS->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS); - meshS->finishInsertingCells(); - fieldS = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DADouble arr = DataArrayDouble::New(); arr->alloc(meshS->getNumberOfCells(), 1); - fieldS->setMesh(meshS); fieldS->setArray(arr); - fieldS->setNature(nature); - double *valsS=fieldS->getArray()->getPointer(); - valsS[0]=10.; - // - MUMesh meshT=MEDCouplingUMesh::New(); - meshT->setMeshDimension(2); - myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coordsT,coordsT+6,myCoords->getPointer()); - meshT->setCoords(myCoords); - myCoords->decrRef(); - int connT[3]={0,1,2}; - meshT->allocateCells(1); - meshT->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT); - meshT->finishInsertingCells(); - fieldT = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DADouble arr2 = DataArrayDouble::New(); arr2->alloc(meshT->getNumberOfCells(), 1); - fieldT->setMesh(meshT); fieldT->setArray(arr2); - fieldT->setNature(nature); - double *valsT=fieldT->getArray()->getPointer(); - valsT[0]=9.; - } -} - -void prepareData2_buildOneSquare(MEDCouplingUMesh* & meshS_0, MEDCouplingUMesh* & meshT_0) -{ - const double coords[10] = {0.0,0.0, 0.0,1.0, 1.0,1.0, 1.0,0.0, 0.5,0.5}; - meshS_0 = MEDCouplingUMesh::New("source", 2); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coords,coords+10,myCoords->getPointer()); - meshS_0->setCoords(myCoords); myCoords->decrRef(); - int connS[4]={0,1,2,3}; - meshS_0->allocateCells(2); - meshS_0->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS); - // - meshT_0 = MEDCouplingUMesh::New("target", 2); - myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coords,coords+10,myCoords->getPointer()); - meshT_0->setCoords(myCoords); - myCoords->decrRef(); - int connT[12]={0,1,4, 1,2,4, 2,3,4, 3,0,4}; - meshT_0->allocateCells(4); - meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT); - meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT+3); - meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT+6); - meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT+9); -} - -/** - * Prepare five (detached) QUAD4 disposed like this: - * (0) (1) (2) - * (3) (4) - * - * On the target side the global mesh is identical except that each QUAD4 is split in 4 TRI3 (along the diagonals). - * This is a case for two procs: - * - proc #0 has source squares 0,1,2 and target squares 0,3 (well, sets of TRI3s actually) - * - proc #1 has source squares 3,4 and target squares 1,2,4 - */ -void prepareData2(int rank, ProcessorGroup * grp, NatureOfField nature, - MEDCouplingUMesh *& meshS, MEDCouplingUMesh *& meshT, - ParaMESH*& parameshS, ParaMESH*& parameshT, - ParaFIELD*& parafieldS, ParaFIELD*& parafieldT, - bool stripPartOfSource=false, - int fieldCompoNum=1) -{ - MEDCouplingUMesh *meshS_0 = 0, *meshT_0 = 0; - prepareData2_buildOneSquare(meshS_0, meshT_0); - - if(rank==0) - { - const double tr1[] = {1.5, 0.0}; - MEDCouplingUMesh *meshS_1 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy()); - meshS_1->translate(tr1); - const double tr2[] = {3.0, 0.0}; - MEDCouplingUMesh *meshS_2 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy()); - meshS_2->translate(tr2); - - std::vector<const MEDCouplingUMesh*> vec; - vec.push_back(meshS_0);vec.push_back(meshS_1); - if (!stripPartOfSource) - vec.push_back(meshS_2); - meshS = MEDCouplingUMesh::MergeUMeshes(vec); - meshS_1->decrRef(); meshS_2->decrRef(); - - ComponentTopology comptopo(fieldCompoNum); - parameshS=new ParaMESH(meshS, *grp,"source mesh"); - parafieldS=new ParaFIELD(ON_CELLS,ONE_TIME,parameshS,comptopo); - parafieldS->getField()->setNature(nature); - double *valsS=parafieldS->getField()->getArray()->getPointer(); - for(int i=0; i < fieldCompoNum; i++) - { - valsS[i] = 1. * (10^i); - valsS[fieldCompoNum+i] = 2. * (10^i); - if (!stripPartOfSource) - { - valsS[2*fieldCompoNum+i] = 3. * (10^i); - } - } - - // - const double tr3[] = {0.0, -1.5}; - MEDCouplingUMesh *meshT_3 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy()); - meshT_3->translate(tr3); - vec.clear(); - vec.push_back(meshT_0);vec.push_back(meshT_3); - meshT = MEDCouplingUMesh::MergeUMeshes(vec); - meshT_3->decrRef(); - - parameshT=new ParaMESH(meshT,*grp,"target mesh"); - parafieldT=new ParaFIELD(ON_CELLS,ONE_TIME,parameshT,comptopo); - parafieldT->getField()->setNature(nature); - } - // - if(rank==1) - { - const double tr3[] = {0.0, -1.5}; - MEDCouplingUMesh *meshS_3 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy()); - meshS_3->translate(tr3); - const double tr4[] = {1.5, -1.5}; - MEDCouplingUMesh *meshS_4 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy()); - meshS_4->translate(tr4); - - std::vector<const MEDCouplingUMesh*> vec; - vec.push_back(meshS_3);vec.push_back(meshS_4); - meshS = MEDCouplingUMesh::MergeUMeshes(vec); - meshS_3->decrRef(); meshS_4->decrRef(); - - ComponentTopology comptopo(fieldCompoNum); - parameshS=new ParaMESH(meshS, *grp,"source mesh"); - parafieldS=new ParaFIELD(ON_CELLS,ONE_TIME,parameshS,comptopo); - parafieldS->getField()->setNature(nature); - double *valsS=parafieldS->getField()->getArray()->getPointer(); - for(int i=0; i < fieldCompoNum; i++) - { - valsS[i] = 4. * (10^i); - valsS[fieldCompoNum+i] = 5. * (10^i); - } - - // - const double tr5[] = {1.5, 0.0}; - MEDCouplingUMesh *meshT_1 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy()); - meshT_1->translate(tr5); - const double tr6[] = {3.0, 0.0}; - MEDCouplingUMesh *meshT_2 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy()); - meshT_2->translate(tr6); - const double tr7[] = {1.5, -1.5}; - MEDCouplingUMesh *meshT_4 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy()); - meshT_4->translate(tr7); - - vec.clear(); - vec.push_back(meshT_1);vec.push_back(meshT_2);vec.push_back(meshT_4); - meshT = MEDCouplingUMesh::MergeUMeshes(vec); - meshT_1->decrRef(); meshT_2->decrRef(); meshT_4->decrRef(); - - parameshT=new ParaMESH(meshT,*grp,"target mesh"); - parafieldT=new ParaFIELD(ON_CELLS,ONE_TIME,parameshT,comptopo); - parafieldT->getField()->setNature(nature); - } - meshS_0->decrRef(); - meshT_0->decrRef(); -} - -/*! Test case from the official doc of the OverlapDEC. - * WARNING: bounding boxes might be tweaked here to make the case more interesting (i.e. to avoid an all to all exchange - * between all procs). - */ -void testOverlapDEC_generic(int workSharingAlgo, double bbAdj) -{ - int size, rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - // char hostname[256]; - // printf("(%d) PID %d on localhost ready for attach\n", rank, getpid()); - // fflush(stdout); - -// if (rank == 0) -// { -// int i=1, j=0; -// while (i!=0) -// j=2; -// } - - if (size != 3) return ; - int nproc = 3; - std::set<int> procs; - for (int i=0; i<nproc; i++) - procs.insert(i); - - CommInterface interface; - OverlapDEC dec(procs); - MEDCouplingFieldDouble * mcfieldS=0, *mcfieldT=0; - - prepareData1(rank, ConservativeVolumic, mcfieldS, mcfieldT); - - // See comment in the caller: - dec.setBoundingBoxAdjustmentAbs(bbAdj); - dec.setWorkSharingAlgo(workSharingAlgo); // just to ease debugging - - dec.attachSourceLocalField(mcfieldS); - dec.attachTargetLocalField(mcfieldT); - dec.synchronize(); -// dec.debugPrintWorkSharing(std::cout); - dec.sendRecvData(true); - // - MPI_Barrier(MPI_COMM_WORLD); - if(rank==0) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.75,mcfieldT->getArray()->getIJ(0,0),1e-12); - } - if(rank==1) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,mcfieldT->getArray()->getIJ(0,0),1e-12); - } - if(rank==2) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.5,mcfieldT->getArray()->getIJ(0,0),1e-12); - } - - mcfieldS->decrRef(); - mcfieldT->decrRef(); - - MPI_Barrier(MPI_COMM_WORLD); -} - -void ParaMEDMEMTest::testOverlapDEC1() -{ - /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * HACK ON BOUNDING BOX TO MAKE THIS CASE SIMPLE AND USABLE IN DEBUG - * Bounding boxes are slightly smaller than should be, thus localizing the work to be done - * and avoiding every proc talking to everyone else. - * Obviously this is NOT a good idea to do this in production code :-) - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - testOverlapDEC_generic(0,-1.0e-12); -} - -void ParaMEDMEMTest::testOverlapDEC1_bis() -{ - // Same BB hack as above - testOverlapDEC_generic(1,-1.0e-12); -} - -void ParaMEDMEMTest::testOverlapDEC1_ter() -{ - // Same BB hack as above - testOverlapDEC_generic(2, -1.0e-12); -} - - -/*! - * Same as testOverlapDEC1() but with regular bounding boxes. If you're looking for a nice debug case, - * testOverlapDEC1() is identical in terms of geometry and field values, and more appropriate. - */ -void ParaMEDMEMTest::testOverlapDEC2() -{ - testOverlapDEC_generic(0,1.0e-12); -} - -void ParaMEDMEMTest::testOverlapDEC2_bis() -{ - testOverlapDEC_generic(1,1.0e-12); -} - -void ParaMEDMEMTest::testOverlapDEC2_ter() -{ - testOverlapDEC_generic(2,1.0e-12); -} - - -/*! Test focused on the mapping of cell IDs. - * (i.e. when only part of the source/target mesh is transmitted) - */ -void ParaMEDMEMTest::testOverlapDEC3() -{ - int size, rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - int nproc = 2; - if (size != nproc) return ; - std::set<int> procs; - for (int i=0; i<nproc; i++) - procs.insert(i); - - CommInterface interface; - OverlapDEC dec(procs); - ProcessorGroup * grp = dec.getGroup(); - MEDCouplingUMesh* meshS=0, *meshT=0; - ParaMESH* parameshS=0, *parameshT=0; - ParaFIELD* parafieldS=0, *parafieldT=0; - - prepareData2(rank, grp, ConservativeVolumic, meshS, meshT, parameshS, parameshT, parafieldS, parafieldT); - - dec.attachSourceLocalField(parafieldS); - dec.attachTargetLocalField(parafieldT); - dec.synchronize(); - dec.sendRecvData(true); - // - MEDCouplingFieldDouble * resField = parafieldT->getField(); - if(rank==0) - { - CPPUNIT_ASSERT_EQUAL(8, resField->getNumberOfTuples()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0,resField->getArray()->getIJ(i,0),1e-12); - for(int i=4;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0,resField->getArray()->getIJ(i,0),1e-12); - } - if(rank==1) - { - CPPUNIT_ASSERT_EQUAL(12, resField->getNumberOfTuples()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0,resField->getArray()->getIJ(i,0),1e-12); - for(int i=4;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0,resField->getArray()->getIJ(i,0),1e-12); - for(int i=8;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0,resField->getArray()->getIJ(i,0),1e-12); - } - delete parafieldS; - delete parafieldT; - delete parameshS; - delete parameshT; - meshS->decrRef(); - meshT->decrRef(); - - MPI_Barrier(MPI_COMM_WORLD); -} - -/*! - * Tests: - * - default value - * - multi-component fields - */ -void ParaMEDMEMTest::testOverlapDEC4() -{ - int size, rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - int nproc = 2; - if (size != nproc) return ; - std::set<int> procs; - for (int i=0; i<nproc; i++) - procs.insert(i); - - CommInterface interface; - OverlapDEC dec(procs); - ProcessorGroup * grp = dec.getGroup(); - MEDCouplingUMesh* meshS=0, *meshT=0; - ParaMESH* parameshS=0, *parameshT=0; - ParaFIELD* parafieldS=0, *parafieldT=0; - - // As before, except than one of the source cell is removed, and that the field now has 2 components - prepareData2(rank, grp, ConservativeVolumic, meshS, meshT, parameshS, parameshT, parafieldS, parafieldT, - true, 2); -// if (rank == 1) -// { -// int i=1, j=0; -// while (i!=0) -// j=2; -// } - - dec.attachSourceLocalField(parafieldS); - dec.attachTargetLocalField(parafieldT); - double defVal = -300.0; - dec.setDefaultValue(defVal); - dec.synchronize(); - dec.sendRecvData(true); - // - MEDCouplingFieldDouble * resField = parafieldT->getField(); - if(rank==0) - { - CPPUNIT_ASSERT_EQUAL(8, resField->getNumberOfTuples()); - for(int i=0;i<4;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0,resField->getArray()->getIJ(i*2,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0,resField->getArray()->getIJ(i*2+1,0),1e-12); - } - for(int i=4;i<8;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0,resField->getArray()->getIJ(i*2,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(40.0,resField->getArray()->getIJ(i*2+1,0),1e-12); - } - } - if(rank==1) - { - CPPUNIT_ASSERT_EQUAL(12, resField->getNumberOfTuples()); - for(int i=0;i<4;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0,resField->getArray()->getIJ(i*2,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20.0,resField->getArray()->getIJ(i*2+1,0),1e-12); - } - // Default value should be here: - for(int i=4;i<8;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(defVal,resField->getArray()->getIJ(i*2,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(defVal,resField->getArray()->getIJ(i*2+1,0),1e-12); - } - for(int i=8;i<12;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0,resField->getArray()->getIJ(i*2,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(50.0,resField->getArray()->getIJ(i*2+1,0),1e-12); - } - } - delete parafieldS; - delete parafieldT; - delete parameshS; - delete parameshT; - meshS->decrRef(); - meshT->decrRef(); - - MPI_Barrier(MPI_COMM_WORLD); -} - diff --git a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_StructuredCoincidentDEC.cxx b/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_StructuredCoincidentDEC.cxx deleted file mode 100644 index 491bbf9e9..000000000 --- a/medtool/src/ParaMEDMEMTest/ParaMEDMEMTest_StructuredCoincidentDEC.cxx +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "DEC.hxx" -#include "StructuredCoincidentDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" -#include "ICoCoMEDField.hxx" -#include "MEDLoader.hxx" - -#include <string> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -/* - * Check methods defined in StructuredCoincidentDEC.hxx - * - StructuredCoincidentDEC(); - StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); - virtual ~StructuredCoincidentDEC(); - void synchronize(); - void recvData(); - void sendData(); -*/ - -void ParaMEDMEMTest::testStructuredCoincidentDEC() { - string testname="ParaMEDMEM - testStructured CoincidentDEC"; - // MPI_Init(&argc, &argv); - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD, &size); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (size<4) { - return; - } - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::MPIProcessorGroup self_group (interface,rank,rank); - ParaMEDMEM::MPIProcessorGroup target_group(interface,3,size-1); - ParaMEDMEM::MPIProcessorGroup source_group (interface,0,2); - - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::ParaMESH* paramesh; - ParaMEDMEM::ParaFIELD* parafield; - - string filename_xml1 = getResourceFile("square1_split"); - string filename_2 = getResourceFile("square1.med"); - //string filename_seq_wr = makeTmpFile(""); - //string filename_seq_med = makeTmpFile("myWrField_seq_pointe221.med"); - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - - //loading the geometry for the source group - - ParaMEDMEM::StructuredCoincidentDEC dec(source_group, target_group); - - MPI_Barrier(MPI_COMM_WORLD); - if (source_group.containsMyRank()) { - string master = filename_xml1; - - ostringstream strstream; - strstream <<master<<rank+1<<".med"; - ostringstream meshname; - meshname<< "Mesh_2_"<< rank+1; - - mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - - - paramesh=new ParaMESH (mesh,source_group,"source mesh"); - - ParaMEDMEM::ComponentTopology comptopo(6); - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - - int nb_local=mesh->getNumberOfCells(); - const int* global_numbering = paramesh->getGlobalNumberingCell(); - - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - for (int icomp=0; icomp<6; icomp++) - value[ielem*6+icomp]=global_numbering[ielem]*6+icomp; - - //ICoCo::Field* icocofield=new ICoCo::MEDField((MEDCouplingUMesh *)paramesh->getCellMesh(),parafield->getField()); - - dec.attachLocalField(parafield); - dec.synchronize(); - dec.sendData(); - //delete icocofield; - } - - //loading the geometry for the target group - if (target_group.containsMyRank()) { - - string meshname2("Mesh_2"); - mesh = MEDLoader::ReadUMeshFromFile(filename_2.c_str(),meshname2.c_str(),0); - - paramesh=new ParaMESH (mesh,self_group,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo(6, &target_group); - - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - - int nb_local=mesh->getNumberOfCells(); - double *value=parafield->getField()->getArray()->getPointer(); - for (int ielem=0; ielem<nb_local; ielem++) - for (int icomp=0; icomp<comptopo.nbLocalComponents(); icomp++) - value[ielem*comptopo.nbLocalComponents()+icomp]=0.0; - //ICoCo::Field* icocofield=new ICoCo::MEDField((MEDCouplingUMesh *)paramesh->getCellMesh(),parafield->getField()); - - dec.attachLocalField(parafield); - dec.synchronize(); - dec.recvData(); - - //checking validity of field - const double* recv_value = parafield->getField()->getArray()->getPointer(); - for (int i=0; i< nb_local; i++) { - int first = comptopo.firstLocalComponent(); - for (int icomp = 0; icomp < comptopo.nbLocalComponents(); icomp++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(recv_value[i*comptopo.nbLocalComponents()+icomp],(double)(i*6+icomp+first),1e-12); - } - //delete icocofield; - } - delete parafield; - delete paramesh; - mesh->decrRef(); - - // MPI_Barrier(MPI_COMM_WORLD); - -} diff --git a/medtool/src/ParaMEDMEMTest/TestMPIAccess.cxx b/medtool/src/ParaMEDMEMTest/TestMPIAccess.cxx deleted file mode 100644 index 3b456a52e..000000000 --- a/medtool/src/ParaMEDMEMTest/TestMPIAccess.cxx +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// --- include all MPIAccess Test -// -#include "MPIAccessTest.hxx" - -// --- Registers the fixture into the 'registry' - -CPPUNIT_TEST_SUITE_REGISTRATION( MPIAccessTest ); - -// --- generic Main program from KERNEL_SRC/src/Basics/Test - -#include "MPIMainTest.hxx" diff --git a/medtool/src/ParaMEDMEMTest/TestMPIAccessDEC.cxx b/medtool/src/ParaMEDMEMTest/TestMPIAccessDEC.cxx deleted file mode 100644 index 15ed2081d..000000000 --- a/medtool/src/ParaMEDMEMTest/TestMPIAccessDEC.cxx +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// --- include all MPIAccessDEC Test -// -#include "MPIAccessDECTest.hxx" - -// --- Registers the fixture into the 'registry' - -CPPUNIT_TEST_SUITE_REGISTRATION( MPIAccessDECTest ); - -// --- generic Main program from KERNEL_SRC/src/Basics/Test - -#include "MPIMainTest.hxx" diff --git a/medtool/src/ParaMEDMEMTest/TestParaMEDMEM.cxx b/medtool/src/ParaMEDMEMTest/TestParaMEDMEM.cxx deleted file mode 100644 index e1b804c9a..000000000 --- a/medtool/src/ParaMEDMEMTest/TestParaMEDMEM.cxx +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// --- include all MEDMEM Test -// -#include "ParaMEDMEMTest.hxx" - -// --- Registers the fixture into the 'registry' - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEMTest ); - -// --- generic Main program from KERNEL_SRC/src/Basics/Test - -#include "MPIMainTest.hxx" diff --git a/medtool/src/ParaMEDMEMTest/test_AllToAllDEC.cxx b/medtool/src/ParaMEDMEMTest/test_AllToAllDEC.cxx deleted file mode 100644 index 7b0825607..000000000 --- a/medtool/src/ParaMEDMEMTest/test_AllToAllDEC.cxx +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessDECTest.hxx" -#include <cppunit/TestAssert.h> -#include "MPIAccessDEC.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessDECTest::test_AllToAllDECSynchronousPointToPoint() { - test_AllToAllDEC( false ) ; -} -void MPIAccessDECTest::test_AllToAllDECAsynchronousPointToPoint() { - test_AllToAllDEC( true ) ; -} - -static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess mpi_access ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - if ( sts != MPI_SUCCESS ) { - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - ostringstream strstream ; - strstream << "===========================================================" << endl - << "test_AllToAllDEC" << myrank << " KO" << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - return ; -} - -void MPIAccessDECTest::test_AllToAllDEC( bool Asynchronous ) { - - debugStream << "test_AllToAllDEC" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 || size > 11 ) { - ostringstream strstream ; - strstream << "usage :" << endl - << "mpirun -np <nbprocs> test_AllToAllDEC" << endl - << " (nbprocs >=2)" << endl - << "test must be runned with more than 1 proc and less than 12 procs" - << endl ; - cerr << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - debugStream << "test_AllToAllDEC" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - std::set<int> sourceprocs; - std::set<int> targetprocs; - int i ; - for ( i = 0 ; i < size/2 ; i++ ) { - sourceprocs.insert(i); - } - for ( i = size/2 ; i < size ; i++ ) { - targetprocs.insert(i); - } - - ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; - ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; - - MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , - Asynchronous ) ; - - MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; - -#define maxreq 100 -#define datamsglength 10 - - // int sts ; - int sendcount = datamsglength ; - int recvcount = datamsglength ; - int * recvbuf = new int[datamsglength*size] ; - - int ireq ; - for ( ireq = 0 ; ireq < maxreq ; ireq++ ) { - int * sendbuf = new int[datamsglength*size] ; - int j ; - for ( j = 0 ; j < datamsglength*size ; j++ ) { - sendbuf[j] = myrank*1000000 + ireq*1000 + j ; - recvbuf[j] = -1 ; - } - - MyMPIAccessDEC->allToAll( sendbuf, sendcount , MPI_INT , - recvbuf, recvcount , MPI_INT ) ; - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - int *ArrayOfRecvRequests = new int[nRecvReq] ; - int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; - mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; - mpi_access->deleteRequests( nReq , ArrayOfRecvRequests ) ; - delete [] ArrayOfRecvRequests ; - } - - int nSendReq = mpi_access->sendRequestIdsSize() ; - debugStream << "test_AllToAllDEC" << myrank << " final SendRequestIds " << nSendReq << " SendRequests" - << endl ; - if ( nSendReq ) { - int *ArrayOfSendRequests = new int[nSendReq] ; - int nReq = mpi_access->sendRequestIds( nSendReq, ArrayOfSendRequests ) ; - mpi_access->waitAll( nReq , ArrayOfSendRequests ) ; - delete [] ArrayOfSendRequests ; - } - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq ) { - ostringstream strstream ; - strstream << "test_AllToAllDEC" << myrank << " final RecvRequestIds " << nRecvReq - << " RecvRequests # 0 Error" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "test_AllToAllDEC" << myrank << " final RecvRequestIds " << nRecvReq - << " RecvRequests = 0 OK" << endl ; - } - - mpi_access->barrier() ; - - delete sourcegroup ; - delete targetgroup ; - delete MyMPIAccessDEC ; - delete [] recvbuf ; - - // MPI_Finalize(); - - debugStream << "test_AllToAllDEC" << myrank << " OK" << endl ; - - return ; -} diff --git a/medtool/src/ParaMEDMEMTest/test_AllToAllTimeDEC.cxx b/medtool/src/ParaMEDMEMTest/test_AllToAllTimeDEC.cxx deleted file mode 100644 index 2f50e66a0..000000000 --- a/medtool/src/ParaMEDMEMTest/test_AllToAllTimeDEC.cxx +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessDECTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccessDEC.hxx" -#include "LinearTimeInterpolator.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessDECTest::test_AllToAllTimeDECSynchronousPointToPoint() { - test_AllToAllTimeDEC( false ) ; -} -void MPIAccessDECTest::test_AllToAllTimeDECAsynchronousPointToPoint() { - test_AllToAllTimeDEC( true ) ; -} - -static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - if ( sts != MPI_SUCCESS ) { - mpi_access->errorString(sts, msgerr, &lenerr) ; - debugStream << "test_AllToAllTimeDEC" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - ostringstream strstream ; - strstream << "===========================================================" - << "test_AllToAllTimeDEC" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - return ; -} - -void MPIAccessDECTest::test_AllToAllTimeDEC( bool Asynchronous ) { - - debugStream << "test_AllToAllTimeDEC" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 || size > 11 ) { - ostringstream strstream ; - strstream << "usage :" << endl - << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl - << " (nbprocs >=2)" << endl - << "test must be runned with more than 1 proc and less than 12 procs" - << endl ; - cerr << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - // int Asynchronous = atoi(argv[1]); - - debugStream << "test_AllToAllTimeDEC" << myrank << " Asynchronous " << Asynchronous << endl ; - - ParaMEDMEM::CommInterface interface ; - std::set<int> sourceprocs; - std::set<int> targetprocs; - int i ; - for ( i = 0 ; i < size/2 ; i++ ) { - sourceprocs.insert(i); - } - for ( i = size/2 ; i < size ; i++ ) { - targetprocs.insert(i); - } - - ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; - ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; - - // LinearTimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0.5 ) ; - MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , - Asynchronous ) ; - // Asynchronous , LinearInterp , 0.5 ) ; - MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp ) ; - MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; - - debugStream << "test_AllToAllTimeDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - debugStream << "test_AllToAllTimeDEC" << myrank << " Barrier done" << endl ; - -#define maxproc 11 -#define maxreq 10000 -#define datamsglength 10 - - int sts ; - int sendcount = datamsglength ; - int recvcount = datamsglength ; - - double time = 0 ; - // double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ; - double deltatime[maxproc] = {1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.} ; - double maxtime = maxreq ; - double nextdeltatime = deltatime[myrank] ; - // MyMPIAccessDEC->InitTime( time , deltatime[myrank] , maxtime ) ; - // for ( time = 0 ; time <= maxtime ; time+=deltatime[myrank] ) { - for ( time = 0 ; time <= maxtime && nextdeltatime != 0 ; time+=nextdeltatime ) { - if ( time != 0 ) { - nextdeltatime = deltatime[myrank] ; - if ( time+nextdeltatime > maxtime ) { - nextdeltatime = 0 ; - } - // MyMPIAccessDEC->NextTime( nextdeltatime ) ; - } - MyMPIAccessDEC->setTime( time , nextdeltatime ) ; - debugStream << "test_AllToAllTimeDEC" << myrank << "=====TIME " << time << "=====DELTATIME " - << nextdeltatime << "=====MAXTIME " << maxtime << " ======" << endl ; - int * sendbuf = new int[datamsglength*size] ; - // int * sendbuf = (int *) malloc(sizeof(int)*datamsglength*size) ; - int * recvbuf = new int[datamsglength*size] ; - int j ; - for ( j = 0 ; j < datamsglength*size ; j++ ) { - sendbuf[j] = myrank*1000000 + (j/datamsglength)*1000 + j ; - recvbuf[j] = -1 ; - } - - int sts = MyMPIAccessDEC->allToAllTime( sendbuf, sendcount , MPI_INT , - recvbuf, recvcount , MPI_INT ) ; - chksts( sts , myrank , mpi_access ) ; - - // debugStream << "test_AllToAllTimeDEC" << myrank << " recvbuf before CheckSent" ; - // for ( i = 0 ; i < datamsglength*size ; i++ ) { - // debugStream << " " << recvbuf[i] ; - // } - // debugStream << endl ; - - // debugStream << "test_AllToAllTimeDEC" << myrank << " sendbuf " << sendbuf << endl ; - // MyMPIAccessDEC->CheckSent() ; - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq != 0 ) { - ostringstream strstream ; - strstream << "=============================================================" << endl - << "test_AllToAllTimeDEC" << myrank << " WaitAllRecv " << nRecvReq << " Requests # 0 ERROR" - << endl << "=============================================================" - << endl ; - int *ArrayOfRecvRequests = new int[nRecvReq] ; - int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; - mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; - delete [] ArrayOfRecvRequests ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - // debugStream << "test_AllToAllTimeDEC" << myrank << " recvbuf" << endl ; - bool badrecvbuf = false ; - for ( i = 0 ; i < datamsglength*size ; i++ ) { - if ( recvbuf[i] != (i/datamsglength)*1000000 + myrank*1000 + - myrank*datamsglength+(i%datamsglength) ) { - badrecvbuf = true ; - debugStream << "test_AllToAllTimeDEC" << myrank << " recvbuf[" << i << "] " - << recvbuf[i] << " # " << (i/datamsglength)*1000000 + myrank*1000 + - myrank*datamsglength+(i%datamsglength) << endl ; - } - else if ( badrecvbuf ) { - debugStream << "test_AllToAllTimeDEC" << myrank << " recvbuf[" << i << "] " - << recvbuf[i] << " == " << (i/datamsglength)*1000000 + myrank*1000 + - myrank*datamsglength+(i%datamsglength) << endl ; - } - } - if ( badrecvbuf ) { - ostringstream strstream ; - strstream << "==============================================================" << endl - << "test_AllToAllTimeDEC" << myrank << " badrecvbuf" - << endl << "=============================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - delete [] recvbuf ; - } - - debugStream << "test_AllToAllTimeDEC" << myrank << " final CheckSent" << endl ; - sts = MyMPIAccessDEC->checkSent() ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "================================================================" << endl - << "test_AllToAllTimeDEC" << myrank << " final CheckSent ERROR" - << endl << "================================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - int nSendReq = mpi_access->sendRequestIdsSize() ; - debugStream << "test_AllToAllTimeDEC" << myrank << " final SendRequestIds " << nSendReq << " SendRequests" - << endl ; - if ( nSendReq ) { - int *ArrayOfSendRequests = new int[nSendReq] ; - int nReq = mpi_access->sendRequestIds( nSendReq, ArrayOfSendRequests ) ; - mpi_access->waitAll( nReq , ArrayOfSendRequests ) ; - delete [] ArrayOfSendRequests ; - } - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq ) { - ostringstream strstream ; - strstream << "===============================================================" << endl - << "test_AllToAllTimeDEC" << myrank << " RecvRequestIds " << nRecvReq - << " RecvRequests # 0 Error" - << endl << "===============================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "test_AllToAllTimeDEC" << myrank << " RecvRequestIds " << nRecvReq - << " RecvRequests = 0 OK" << endl ; - } - - debugStream << "test_AllToAllTimeDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - debugStream << "test_AllToAllTimeDEC" << myrank << " Barrier done" << endl ; - - delete sourcegroup ; - delete targetgroup ; - // delete aLinearInterpDEC ; - delete MyMPIAccessDEC ; - - // MPI_Finalize(); - - debugStream << "test_AllToAllTimeDEC" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_AllToAllvDEC.cxx b/medtool/src/ParaMEDMEMTest/test_AllToAllvDEC.cxx deleted file mode 100644 index 490b40437..000000000 --- a/medtool/src/ParaMEDMEMTest/test_AllToAllvDEC.cxx +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessDECTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccessDEC.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessDECTest::test_AllToAllvDECSynchronousPointToPoint() { - test_AllToAllvDEC( false ) ; -} -void MPIAccessDECTest::test_AllToAllvDECAsynchronousPointToPoint() { - test_AllToAllvDEC( true ) ; -} - -static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess mpi_access ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - if ( sts != MPI_SUCCESS ) { - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test_AllToAllvDEC" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - ostringstream strstream ; - strstream << "===========================================================" - << "test_AllToAllvDEC" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - return ; -} - -void MPIAccessDECTest::test_AllToAllvDEC( bool Asynchronous ) { - - debugStream << "test_AllToAllvDEC" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 || size > 11 ) { - ostringstream strstream ; - strstream << "usage :" << endl - << "mpirun -np <nbprocs> test_AllToAllvDEC" << endl - << " (nbprocs >=2)" << endl - << "test must be runned with more than 1 proc and less than 12 procs" - << endl ; - cerr << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - // int Asynchronous = atoi(argv[1]); - - debugStream << "test_AllToAllvDEC" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - std::set<int> sourceprocs; - std::set<int> targetprocs; - int i ; - for ( i = 0 ; i < size/2 ; i++ ) { - sourceprocs.insert(i); - } - for ( i = size/2 ; i < size ; i++ ) { - targetprocs.insert(i); - } - - ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; - ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; - - MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , - Asynchronous ) ; - - MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; - -#define maxreq 100 -#define datamsglength 10 - - // int sts ; - int *sendcounts = new int[size] ; - int *sdispls = new int[size] ; - int *recvcounts = new int[size] ; - int *rdispls = new int[size] ; - for ( i = 0 ; i < size ; i++ ) { - sendcounts[i] = datamsglength-i; - sdispls[i] = i*datamsglength ; - recvcounts[i] = datamsglength-myrank; - rdispls[i] = i*datamsglength ; - } - int * recvbuf = new int[datamsglength*size] ; - - int ireq ; - for ( ireq = 0 ; ireq < maxreq ; ireq++ ) { - int * sendbuf = new int[datamsglength*size] ; - // int * sendbuf = (int *) malloc( sizeof(int)*datamsglength*size) ; - int j ; - for ( j = 0 ; j < datamsglength*size ; j++ ) { - sendbuf[j] = myrank*1000000 + ireq*1000 + j ; - recvbuf[j] = -1 ; - } - - MyMPIAccessDEC->allToAllv( sendbuf, sendcounts , sdispls , MPI_INT , - recvbuf, recvcounts , rdispls , MPI_INT ) ; - - // debugStream << "test_AllToAllvDEC" << myrank << " recvbuf before CheckSent" ; - // for ( i = 0 ; i < datamsglength*size ; i++ ) { - // debugStream << " " << recvbuf[i] ; - // } - // debugStream << endl ; - - // debugStream << "test_AllToAllvDEC" << myrank << " sendbuf " << sendbuf << endl ; - // MyMPIAccessDEC->CheckSent() ; - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - // debugStream << "test_AllToAllvDEC" << myrank << " WaitAllRecv " << nRecvReq << " Requests" << endl ; - int *ArrayOfRecvRequests = new int[nRecvReq] ; - int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; - mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; - mpi_access->deleteRequests( nReq , ArrayOfRecvRequests ) ; - delete [] ArrayOfRecvRequests ; - - // debugStream << "test_AllToAllvDEC" << myrank << " recvbuf" ; - // for ( i = 0 ; i < datamsglength*size ; i++ ) { - // debugStream << " " << recvbuf[i] ; - // } - // debugStream << endl ; - } - - // debugStream << "test_AllToAllvDEC" << myrank << " final CheckSent" << endl ; - // MyMPIAccessDEC->CheckSent() ; - - int nSendReq = mpi_access->sendRequestIdsSize() ; - debugStream << "test_AllToAllvDEC" << myrank << " final SendRequestIds " << nSendReq << " SendRequests" - << endl ; - if ( nSendReq ) { - int *ArrayOfSendRequests = new int[nSendReq] ; - int nReq = mpi_access->sendRequestIds( nSendReq, ArrayOfSendRequests ) ; - mpi_access->waitAll( nReq , ArrayOfSendRequests ) ; - delete [] ArrayOfSendRequests ; - } - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq ) { - ostringstream strstream ; - strstream << "test_AllToAllvDEC" << myrank << " final RecvRequestIds " << nRecvReq - << " RecvRequests # 0 Error" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "test_AllToAllvDEC" << myrank << " final RecvRequestIds " << nRecvReq - << " RecvRequests = 0 OK" << endl ; - } - - mpi_access->barrier() ; - - delete sourcegroup ; - delete targetgroup ; - delete MyMPIAccessDEC ; - delete [] sendcounts ; - delete [] sdispls ; - delete [] recvcounts ; - delete [] rdispls ; - delete [] recvbuf ; - - // MPI_Finalize(); - - debugStream << "test_AllToAllvDEC" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_AllToAllvTimeDEC.cxx b/medtool/src/ParaMEDMEMTest/test_AllToAllvTimeDEC.cxx deleted file mode 100644 index bd6f4b541..000000000 --- a/medtool/src/ParaMEDMEMTest/test_AllToAllvTimeDEC.cxx +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> -#include <ctime> - -#include "MPIAccessDECTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccessDEC.hxx" -#include "LinearTimeInterpolator.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessDECTest::test_AllToAllvTimeDECSynchronousNative() { - test_AllToAllvTimeDEC( false , true ) ; -} -void MPIAccessDECTest::test_AllToAllvTimeDECSynchronousPointToPoint() { - test_AllToAllvTimeDEC( false , false ) ; -} -void MPIAccessDECTest::test_AllToAllvTimeDECAsynchronousPointToPoint() { - test_AllToAllvTimeDEC( true , false ) ; -} - -static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - if ( sts != MPI_SUCCESS ) { - mpi_access->errorString(sts, msgerr, &lenerr) ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - ostringstream strstream ; - strstream << "===========================================================" - << "test_AllToAllvTimeDEC" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - return ; -} - -void MPIAccessDECTest::test_AllToAllvTimeDEC( bool Asynchronous , bool UseMPINative ) { - - debugStream << "test_AllToAllvTimeDEC" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 || size > 11 ) { - ostringstream strstream ; - strstream << "usage :" << endl - << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl - << " (nbprocs >=2)" << endl - << "test must be runned with more than 1 proc and less than 12 procs" - << endl ; - cerr << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - // int Asynchronous = atoi(argv[1]) ; - int UseMPI_Alltoallv = UseMPINative ; - // if ( argc == 3 ) { - // UseMPI_Alltoallv = atoi(argv[2]) ; - // } - - debugStream << "test_AllToAllvTimeDEC" << myrank << " Asynchronous " << Asynchronous - << " UseMPI_Alltoallv " << UseMPI_Alltoallv << endl ; - - ParaMEDMEM::CommInterface interface ; - std::set<int> sourceprocs; - std::set<int> targetprocs; - int i ; - for ( i = 0 ; i < size/2 ; i++ ) { - sourceprocs.insert(i); - } - for ( i = size/2 ; i < size ; i++ ) { - targetprocs.insert(i); - } - - ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; - ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; - - // TimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0.5 ) ; - MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , - Asynchronous ) ; - // Asynchronous , LinearInterp , 0.5 ) ; - MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp , 0.5 ) ; - MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; - - debugStream << "test_AllToAllvTimeDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " Barrier done" << endl ; - -#define maxproc 11 -#define maxreq 10000 -#define datamsglength 10 - - int sts ; - int *sendcounts = new int[size] ; - int *sdispls = new int[size] ; - int *recvcounts = new int[size] ; - int *rdispls = new int[size] ; - int *sendtimecounts = new int[size] ; - int *stimedispls = new int[size] ; - int *recvtimecounts = new int[size] ; - int *rtimedispls = new int[size] ; - for ( i = 0 ; i < size ; i++ ) { - sendcounts[i] = datamsglength-i ; - sdispls[i] = i*datamsglength ; - recvcounts[i] = datamsglength-myrank ; - rdispls[i] = i*datamsglength ; - sendtimecounts[i] = 1 ; - stimedispls[i] = 0 ; - recvtimecounts[i] = 1 ; - rtimedispls[i] = i ; - //rtimedispls[i] = i*mpi_access->TimeExtent() ; - } - - double timeLoc = 0 ; - double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ; - double maxtime ; - double nextdeltatime = deltatime[myrank] ; - if ( UseMPI_Alltoallv ) { - maxtime = maxreq*nextdeltatime - 0.1 ; - } - else { - maxtime = maxreq ; - // MyMPIAccessDEC->InitTime( time , nextdeltatime , maxtime ) ; - } - time_t begintime = time(NULL) ; - // for ( time = 0 ; time <= maxtime ; time+=deltatime[myrank] ) { - for ( timeLoc = 0 ; timeLoc <= maxtime && nextdeltatime != 0 ; timeLoc+=nextdeltatime ) { - nextdeltatime = deltatime[myrank] ; - if ( timeLoc != 0 ) { - nextdeltatime = deltatime[myrank] ; - if ( timeLoc+nextdeltatime > maxtime ) { - nextdeltatime = 0 ; - } - // MyMPIAccessDEC->NextTime( nextdeltatime ) ; - } - MyMPIAccessDEC->setTime( timeLoc , nextdeltatime ) ; - debugStream << "test_AllToAllvTimeDEC" << myrank << "=====TIME " << time << "=====DELTATIME " - << nextdeltatime << "=====MAXTIME " << maxtime << " ======" << endl ; - int * sendbuf = new int[datamsglength*size] ; - // int * sendbuf = (int *) malloc(sizeof(int)*datamsglength*size) ; - int * recvbuf = new int[datamsglength*size] ; - int j ; - for ( j = 0 ; j < datamsglength*size ; j++ ) { - sendbuf[j] = myrank*1000000 + (j/datamsglength)*1000 + j ; - recvbuf[j] = -1 ; - } - - if ( UseMPI_Alltoallv ) { - const MPI_Comm* comm = MyMPIAccessDEC->getComm(); - TimeMessage * aSendTimeMessage = new TimeMessage ; - aSendTimeMessage->time = timeLoc ; - // aSendTimeMessage->deltatime = deltatime[myrank] ; - aSendTimeMessage->deltatime = nextdeltatime ; - // aSendTimeMessage->maxtime = maxtime ; - aSendTimeMessage->tag = (int ) (timeLoc/deltatime[myrank]) ; - TimeMessage * aRecvTimeMessage = new TimeMessage[size] ; - interface.allToAllV(aSendTimeMessage, sendtimecounts , stimedispls , - mpi_access->timeType() , - aRecvTimeMessage, recvtimecounts , rtimedispls , - mpi_access->timeType() , *comm ) ; - // for ( j = 0 ; j < size ; j++ ) { - // debugStream << "test_AllToAllvTimeDEC" << myrank << " TimeMessage received " << j << " " - // << aRecvTimeMessage[j] << endl ; - // } - delete aSendTimeMessage ; - delete [] aRecvTimeMessage ; - interface.allToAllV(sendbuf, sendcounts , sdispls , MPI_INT , - recvbuf, recvcounts , rdispls , MPI_INT , *comm ) ; - // free(sendbuf) ; - delete [] sendbuf ; - } - else { - int sts = MyMPIAccessDEC->allToAllvTime( sendbuf, sendcounts , sdispls , MPI_INT , - recvbuf, recvcounts , rdispls , MPI_INT ) ; - chksts( sts , myrank , mpi_access ) ; - } - - // debugStream << "test_AllToAllvTimeDEC" << myrank << " recvbuf before CheckSent" ; - // for ( i = 0 ; i < datamsglength*size ; i++ ) { - // debugStream << " " << recvbuf[i] ; - // } - // debugStream << endl ; - - // debugStream << "test_AllToAllvTimeDEC" << myrank << " sendbuf " << sendbuf << endl ; - // MyMPIAccessDEC->CheckSent() ; - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq != 0 ) { - ostringstream strstream ; - strstream << "=============================================================" << endl - << "test_AllToAllvTimeDEC" << myrank << " WaitAllRecv " << nRecvReq << " Requests # 0 ERROR" - << endl << "=============================================================" - << endl ; - int *ArrayOfRecvRequests = new int[nRecvReq] ; - int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; - mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; - delete [] ArrayOfRecvRequests ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - // debugStream << "test_AllToAllvTimeDEC" << myrank << " check of recvbuf" << endl ; - bool badrecvbuf = false ; - for ( i = 0 ; i < size ; i++ ) { - int j ; - for ( j = 0 ; j < datamsglength ; j++ ) { - int index = i*datamsglength+j ; - if ( j < recvcounts[i] ) { - if ( recvbuf[index] != (index/datamsglength)*1000000 + myrank*1000 + - myrank*datamsglength+(index%datamsglength) ) { - badrecvbuf = true ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " recvbuf[" << index << "] " - << recvbuf[index] << " # " << (index/datamsglength)*1000000 + - myrank*1000 + - myrank*datamsglength+(index%datamsglength) << endl ; - } - else if ( badrecvbuf ) { - debugStream << "test_AllToAllvTimeDEC" << myrank << " recvbuf[" << index << "] " - << recvbuf[index] << " == " << (index/datamsglength)*1000000 + - myrank*1000 + - myrank*datamsglength+(index%datamsglength) << endl ; - } - } - else if ( recvbuf[index] != -1 ) { - badrecvbuf = true ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " recvbuf[" << index << "] " - << recvbuf[index] << " # -1" << endl ; - } - } - } - if ( badrecvbuf ) { - ostringstream strstream ; - strstream << "==============================================================" << endl - << "test_AllToAllvTimeDEC" << myrank << " badrecvbuf" - << endl << "=============================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - delete [] recvbuf ; - } - - debugStream << "test_AllToAllvTimeDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " Barrier done" << endl ; - - debugStream << "test_AllToAllvTimeDEC" << myrank << " CheckFinalSent" << endl ; - sts = MyMPIAccessDEC->checkFinalSent() ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "================================================================" << endl - << "test_AllToAllvTimeDEC" << myrank << " final CheckSent ERROR" - << endl << "================================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - debugStream << "test_AllToAllvTimeDEC" << myrank << " CheckFinalRecv" << endl ; - sts = MyMPIAccessDEC->checkFinalRecv() ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "================================================================" << endl - << "test_AllToAllvTimeDEC" << myrank << " CheckFinalRecv ERROR" - << endl << "================================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq ) { - ostringstream strstream ; - strstream << "===============================================================" << endl - << "test_AllToAllvTimeDEC" << myrank << " RecvRequestIds " << nRecvReq - << " RecvRequests # 0 Error" - << endl << "===============================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "test_AllToAllvTimeDEC" << myrank << " RecvRequestIds " << nRecvReq - << " RecvRequests = 0 OK" << endl ; - } - - time_t endtime = time(NULL) ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " begintime " << begintime << " endtime " << endtime - << " elapse " << endtime-begintime << " " << maxtime/deltatime[myrank] - << " calls to AllToAll" << endl ; - - debugStream << "test_AllToAllvTimeDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - debugStream << "test_AllToAllvTimeDEC" << myrank << " Barrier done" << endl ; - - delete sourcegroup ; - delete targetgroup ; - delete MyMPIAccessDEC ; - // delete aLinearInterpDEC ; - - delete [] sendcounts ; - delete [] sdispls ; - delete [] recvcounts ; - delete [] rdispls ; - delete [] sendtimecounts ; - delete [] stimedispls ; - delete [] recvtimecounts ; - delete [] rtimedispls ; - - // MPI_Finalize(); - - endtime = time(NULL) ; - - debugStream << "test_AllToAllvTimeDEC" << myrank << " OK begintime " << begintime << " endtime " << endtime - << " elapse " << endtime-begintime << " " << maxtime/deltatime[myrank] - << " calls to AllToAll" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_AllToAllvTimeDoubleDEC.cxx b/medtool/src/ParaMEDMEMTest/test_AllToAllvTimeDoubleDEC.cxx deleted file mode 100644 index 01b7bd685..000000000 --- a/medtool/src/ParaMEDMEMTest/test_AllToAllvTimeDoubleDEC.cxx +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <math.h> -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> -#include <ctime> - -#include "MPIAccessDECTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccessDEC.hxx" -#include "LinearTimeInterpolator.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessDECTest::test_AllToAllvTimeDoubleDECSynchronousPointToPoint() { - test_AllToAllvTimeDoubleDEC( false ) ; -} -void MPIAccessDECTest::test_AllToAllvTimeDoubleDECAsynchronousPointToPoint() { - test_AllToAllvTimeDoubleDEC( true ) ; -} - -static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - if ( sts != MPI_SUCCESS ) { - mpi_access->errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - return ; -} - -void MPIAccessDECTest::test_AllToAllvTimeDoubleDEC( bool Asynchronous ) { - - debugStream << "test_AllToAllvTimeDoubleDEC" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 || size > 11 ) { - ostringstream strstream ; - strstream << "usage :" << endl - << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl - << " (nbprocs >=2)" << endl - << "test must be runned with more than 1 proc and less than 12 procs" - << endl ; - cerr << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - -// int Asynchronous = atoi(argv[1]) ; - - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " Asynchronous " << Asynchronous << endl ; - - ParaMEDMEM::CommInterface interface ; - std::set<int> sourceprocs; - std::set<int> targetprocs; - int i ; - for ( i = 0 ; i < size/2 ; i++ ) { - sourceprocs.insert(i); - } - for ( i = size/2 ; i < size ; i++ ) { - targetprocs.insert(i); - } - - ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; - ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; - -// TimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0 ) ; - MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , - Asynchronous ) ; -// Asynchronous , LinearInterp , 0.5 ) ; - MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp ) ; - MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; - - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - -#define maxproc 11 -#define maxreq 100 -#define datamsglength 10 - - int sts ; - int *sendcounts = new int[size] ; - int *sdispls = new int[size] ; - int *recvcounts = new int[size] ; - int *rdispls = new int[size] ; - int *sendtimecounts = new int[size] ; - int *stimedispls = new int[size] ; - int *recvtimecounts = new int[size] ; - int *rtimedispls = new int[size] ; - for ( i = 0 ; i < size ; i++ ) { - sendcounts[i] = datamsglength-i ; - sdispls[i] = i*datamsglength ; - recvcounts[i] = datamsglength-myrank ; - rdispls[i] = i*datamsglength ; - sendtimecounts[i] = 1 ; - stimedispls[i] = 0 ; - recvtimecounts[i] = 1 ; - rtimedispls[i] = i ; - } - - double timeLoc[maxproc] ; - double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ; - double maxtime[maxproc] ; - double nextdeltatime[maxproc] ; - for ( i = 0 ; i < size ; i++ ) { - timeLoc[i] = 0 ; - maxtime[i] = maxreq ; - nextdeltatime[i] = deltatime[i] ; - } - time_t begintime = time(NULL) ; - for ( timeLoc[myrank] = 0 ; timeLoc[myrank] <= maxtime[myrank] && nextdeltatime[myrank] != 0 ; - timeLoc[myrank]+=nextdeltatime[myrank] ) { -//local and target times - int target ; - for ( target = 0 ; target < size ; target++ ) { - nextdeltatime[target] = deltatime[target] ; - if ( timeLoc[target] != 0 ) { - if ( timeLoc[target]+nextdeltatime[target] > maxtime[target] ) { - nextdeltatime[target] = 0 ; - } - } - if ( target != myrank ) { - while ( timeLoc[myrank] >= timeLoc[target] ) { - timeLoc[target] += deltatime[target] ; - } - } - } - MyMPIAccessDEC->setTime( timeLoc[myrank] , nextdeltatime[myrank] ) ; - debugStream << "test" << myrank << "=====TIME " << timeLoc[myrank] << "=====DELTATIME " - << nextdeltatime[myrank] << "=====MAXTIME " << maxtime[myrank] << " ======" - << endl ; - double * sendbuf = new double[datamsglength*size] ; -// double * sendbuf = (double *) malloc(sizeof(double)*datamsglength*size) ; - double * recvbuf = new double[datamsglength*size] ; - int j ; - //debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " sendbuf" ; - for ( target = 0 ; target < size ; target++ ) { - for ( j = 0 ; j < datamsglength ; j++ ) { - //sendbuf[j] = myrank*10000 + (j/datamsglength)*100 + j ; - sendbuf[target*datamsglength+j] = myrank*1000000 + target*10000 + - (timeLoc[myrank]/deltatime[myrank])*100 + j ; - //debugStream << " " << (int ) sendbuf[target*datamsglength+j] ; - recvbuf[target*datamsglength+j] = -1 ; - } - //debugStream << endl ; - } - - int sts = MyMPIAccessDEC->allToAllvTime( sendbuf, sendcounts , sdispls , MPI_DOUBLE , - recvbuf, recvcounts , rdispls , MPI_DOUBLE ) ; - chksts( sts , myrank , mpi_access ) ; - -// debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf before CheckSent" ; -// for ( i = 0 ; i < datamsglength*size ; i++ ) { -// debugStream << " " << recvbuf[i] ; -// } -// debugStream << endl ; - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq != 0 ) { - ostringstream strstream ; - strstream << "=============================================================" << endl - << "test_AllToAllvTimeDoubleDEC" << myrank << " WaitAllRecv " - << nRecvReq << " Requests # 0 ERROR" - << endl << "============================================================" - << endl ; - int *ArrayOfRecvRequests = new int[nRecvReq] ; - int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; - mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; - delete [] ArrayOfRecvRequests ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - -// debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " check of recvbuf" << endl ; - bool badrecvbuf = false ; - for ( target = 0 ; target < size ; target++ ) { - int j ; - for ( j = 0 ; j < datamsglength ; j++ ) { - int index = target*datamsglength+j ; - if ( j < recvcounts[target] ) { - if ( fabs(recvbuf[index] - (target*1000000 + myrank*10000 + - (timeLoc[target]/deltatime[target])*100 + j)) > 101) { - badrecvbuf = true ; - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " target " << target << " timeLoc[target] " - << timeLoc[target] << " recvbuf[" << index << "] " << (int ) recvbuf[index] - << " # " << (int ) (target*1000000 + - myrank*10000 + (timeLoc[target]/deltatime[target])*100 + j) - << endl ; - } - else if ( badrecvbuf ) { - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf[" << index << "] " - << recvbuf[index] << " ~= " << (int ) (target*1000000 + - myrank*10000 + (timeLoc[target]/deltatime[target])*100 + j) << endl ; - } - } - else if ( recvbuf[index] != -1 ) { - badrecvbuf = true ; - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf[" << index << "] " - << recvbuf[index] << " # -1" << endl ; - } - } - } - if ( badrecvbuf ) { - ostringstream strstream ; - strstream << "==================================================================" << endl - << "test_AllToAllvTimeDoubleDEC" << myrank << " badrecvbuf" - << endl << "==================================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - delete [] recvbuf ; - } - - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalSent" << endl ; - sts = MyMPIAccessDEC->checkFinalSent() ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "=================================================================" << endl - << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalSent ERROR" - << endl << "=================================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalRecv" << endl ; - sts = MyMPIAccessDEC->checkFinalRecv() ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "=================================================================" << endl - << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalRecv ERROR" - << endl << "================================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - int nRecvReq = mpi_access->recvRequestIdsSize() ; - if ( nRecvReq ) { - ostringstream strstream ; - strstream << "===============================================================" << endl - << "test_AllToAllvTimeDoubleDEC" << myrank << " RecvRequestIds " << nRecvReq - << " RecvRequests # 0 Error" - << endl << "===============================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " RecvRequestIds " << nRecvReq - << " RecvRequests = 0 OK" << endl ; - } - - time_t endtime = time(NULL) ; - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " begintime " << begintime << " endtime " << endtime - << " elapse " << endtime-begintime << " " << maxtime[myrank]/deltatime[myrank] - << " calls to AllToAll" << endl ; - - debugStream << "test" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - - delete sourcegroup ; - delete targetgroup ; - delete MyMPIAccessDEC ; -// delete aLinearInterpDEC ; - - delete [] sendcounts ; - delete [] sdispls ; - delete [] recvcounts ; - delete [] rdispls ; - delete [] sendtimecounts ; - delete [] stimedispls ; - delete [] recvtimecounts ; - delete [] rtimedispls ; - -// MPI_Finalize(); - - endtime = time(NULL) ; - - debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " OK begintime " << begintime << " endtime " << endtime - << " elapse " << endtime-begintime << " " << maxtime[myrank]/deltatime[myrank] - << " calls to AllToAll" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cancel.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cancel.cxx deleted file mode 100644 index 8b26823f6..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cancel.cxx +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <time.h> -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#ifndef WIN32 -#include <unistd.h> -#endif - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Cancel() { - - debugStream << "test_MPI_Access_Cancel" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_Cancel must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_Cancel" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int intsendbuf[5] ; - double doublesendbuf[10] ; - int RequestId[10] ; - int sts ; - int i , j ; - for ( j = 0 ; j < 3 ; j++ ) { - for ( i = 0 ; i < 10 ; i++ ) { - debugStream << "test" << myrank << " ============================ i " << i - << "============================" << endl ; - if ( myrank == 0 ) { - if ( i < 5 ) { - intsendbuf[i] = i ; - sts = mpi_access.ISend(&intsendbuf[i],1,MPI_INT,target, RequestId[i]) ; - debugStream << "test" << myrank << " Send MPI_INT RequestId " << RequestId[i] - << endl ; - } - else { - doublesendbuf[i] = i ; - sts = mpi_access.ISend(&doublesendbuf[i],1,MPI_DOUBLE,target, - RequestId[i]) ; - debugStream << "test" << myrank << " Send MPI_DOUBLE RequestId " << RequestId[i] - << endl ; - } - } - else { - int flag = false ; - while ( !flag ) { - int source, tag, outcount ; - MPI_Datatype datatype ; - sts = mpi_access.IProbe(target, source, tag, datatype, outcount, - flag ) ; - if ( flag ) { - debugStream << "test" << myrank << " " << i << " IProbe target " << target - << " source " << source << " tag " << tag - << " outcount " << outcount << " flag " << flag << endl ; - } - else { - debugStream << "test" << myrank << " flag " << flag << endl ; - sleep( 1 ) ; - } - if ( flag ) { - int recvbuf ; - sts = mpi_access.IRecv(&recvbuf,outcount,MPI_INT,source, - RequestId[i] ) ; - if ( datatype == MPI_INT ) { - int source, tag, error, outcount ; - mpi_access.wait( RequestId[i] ) ; - mpi_access.status( RequestId[i], source, tag, error, outcount, - true ) ; - if ( (outcount != 1) | (recvbuf != i) ) { - ostringstream strstream ; - strstream << "======================================================" - << endl << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " KO" << endl - << "======================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - debugStream << "========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " OK" << endl - << "========================================================" - << endl ; - } - } - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - - if ( myrank != 0 ) { - int iprobe ; - for ( iprobe = 5 ; iprobe < 10 ; iprobe++ ) { - debugStream << "test" << myrank << " ============================ iprobe " - << iprobe << "============================" << endl ; - int source, tag, outcount ; - MPI_Datatype datatype ; - int probeflag = false ; - while ( !probeflag ) { - sts = mpi_access.IProbe( target, source, tag, datatype, outcount, - probeflag ) ; - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " IProbe iprobe " << iprobe - << " target " << target << " probeflag " << probeflag - << " tag " << tag << " outcount " << outcount << " datatype " - << datatype << " lenerr " << lenerr << " " << msgerr << endl ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "==========================================================" - << endl << "test" << myrank << " IProbe KO iprobe " << iprobe - << endl - << "==========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if ( !probeflag ) { - //debugStream << "========================================================" - // << endl << "test" << myrank << " IProbe KO(OK) iprobe " << iprobe - // << " probeflag " << probeflag << endl - // << "========================================================" - // << endl ; - } - else { - debugStream << "test" << myrank << " " << iprobe << " IProbe target " - << target << " source " << source << " tag " << tag - << " outcount " << outcount << " probeflag " << probeflag - << endl ; - if ( datatype != MPI_DOUBLE ) { - ostringstream strstream ; - strstream << "========================================================" - << endl << "test" << myrank << " MPI_DOUBLE KO" << endl - << "========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - int flag ; - sts = mpi_access.cancel( source, tag, datatype, outcount, flag ) ; - if ( sts != MPI_SUCCESS || !flag ) { - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "======================================================" - << endl << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl << "test" << myrank - << " Cancel PendingIrecv KO flag " << flag << " iprobe " - << iprobe << " Irecv completed" << endl - << "======================================================" - << endl ; - //return 1 ; - } - else { - debugStream << "======================================================" - << endl << "test" << myrank - << " Cancel PendingIrecv OK RequestId " << " flag " - << flag << " iprobe " << iprobe << endl - << "======================================================" - << endl ; - } - } - int Reqtarget, Reqtag, Reqerror, Reqoutcount ; - mpi_access.status( RequestId[iprobe], Reqtarget, Reqtag, Reqerror, - Reqoutcount, true ) ; - debugStream << "test" << myrank << " Status Reqtarget "<< Reqtarget - << " Reqtag " << Reqtag << " Reqoutcount " << Reqoutcount - << endl ; - int Reqflag ; - sts = mpi_access.cancel( RequestId[iprobe] , Reqflag ) ; - debugStream << "test" << myrank << " " << iprobe - << " Cancel Irecv done Reqtarget " << Reqtarget - << " Reqtag " << Reqtag << " Reqoutcount " << Reqoutcount - << " Reqflag " << Reqflag << endl ; - if ( sts != MPI_SUCCESS || !Reqflag ) { - mpi_access.errorString(sts, msgerr, &lenerr) ; - ostringstream strstream ; - strstream << "========================================================" - << endl << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl << "test" << myrank - << " Cancel Irecv KO Reqflag " << Reqflag << " iprobe " - << iprobe << endl - << "========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "========================================================" - << endl << "test" << myrank - << " Cancel Irecv OK RequestId " << RequestId[iprobe] - << " Reqflag " << Reqflag << " iprobe " << iprobe << endl - << "========================================================" - << endl ; - probeflag = Reqflag ; - } - } - } - } - } - mpi_access.waitAll(10,RequestId) ; - mpi_access.deleteRequests(10,RequestId) ; - } - - int source, tag, outcount, flag ; - MPI_Datatype datatype ; - sts = mpi_access.IProbe(target, source, tag, datatype, outcount, flag ) ; - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - if ( sts != MPI_SUCCESS || flag ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " IProbe KO flag " << flag - << " remaining unread/cancelled message :" << endl - << " source " << source << " tag " << tag << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - mpi_access.testAll(10,RequestId,flag) ; - mpi_access.waitAll(10,RequestId) ; - mpi_access.deleteRequests(10,RequestId) ; - mpi_access.testAll(10,RequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cyclic_ISend_IRecv.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cyclic_ISend_IRecv.cxx deleted file mode 100644 index 00ce3e69c..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cyclic_ISend_IRecv.cxx +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Cyclic_ISend_IRecv() { - - debugStream << "test_MPI_Access_Cyclic_ISend_IRecv" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 3 ) { - cerr << "test_MPI_Access_Cyclic_ISend_IRecv must be runned with 3 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_Cyclic_ISend_IRecv must be runned with 3 procs") ; - return; - } - - debugStream << "test_MPI_Access_Cyclic_ISend_IRecv" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - -#define maxsend 100 - - if ( myrank >= 3 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int alltarget[3] = {1 , 2 , 0 } ; - int allsource[3] = {2 , 0 , 1 } ; - int SendRequestId[maxsend] ; - int RecvRequestId[maxsend] ; - int sendbuf[maxsend] ; - int recvbuf[maxsend] ; - int sts ; - int i = 0 ; - if ( myrank == 0 ) { - sendbuf[i] = i ; - sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,alltarget[myrank], - SendRequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; - } - for ( i = 0 ; i < maxsend ; i++ ) { - recvbuf[i] = -1 ; - sts = mpi_access.IRecv(&recvbuf[i],1,MPI_INT,allsource[myrank], - RecvRequestId[i]) ; - debugStream << "test" << myrank << " Recv RequestId " << RecvRequestId[i] - << " tag " << mpi_access.recvMPITag(allsource[myrank]) << endl ; - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr - << " " << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - int j ; - for (j = 0 ; j <= i ; j++) { - int flag ; - if ( j < i ) { - debugStream << "test" << myrank << " " << j << " -> Test-Send("<< SendRequestId[j] - << ")" << endl ; - mpi_access.test( SendRequestId[j], flag ) ; - if ( flag ) { - int target, tag, error, outcount ; - mpi_access.status( SendRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Send RequestId " << SendRequestId[j] - << " target " << target << " tag " << tag << " error " << error - << endl ; - mpi_access.deleteRequest( SendRequestId[j] ) ; - } - } - debugStream << "test" << myrank << " " << j << " -> Test-Recv("<< SendRequestId[j] - << ")" << endl ; - mpi_access.test( RecvRequestId[j], flag ) ; - if ( flag ) { - int source, tag, error, outcount ; - mpi_access.status( RecvRequestId[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Recv RequestId" << j << " " - << RecvRequestId[j] << " source " << source << " tag " << tag - << " error " << error << " outcount " << outcount << endl ; - if ( (outcount != 1) | (recvbuf[j] != j) ) { - ostringstream strstream ; - strstream << "=====================================================" - << endl << "test" << myrank << " outcount " - << outcount << " recvbuf[ " << j << " ] " << recvbuf[j] << " KO" - << endl << "=====================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - } - if ( myrank == 0 ) { - if ( i != maxsend-1 ) { - sendbuf[i+1] = i + 1 ; - sts = mpi_access.ISend(&sendbuf[i+1],1,MPI_INT,alltarget[myrank], - SendRequestId[i+1]) ; - debugStream << "test" << myrank << " Send RequestId " << SendRequestId[i+1] - << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; - } - } - else { - sendbuf[i] = i ; - sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,alltarget[myrank], - SendRequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; - } - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr - << " " << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - - int flag ; - mpi_access.testAll(maxsend,SendRequestId,flag) ; - mpi_access.testAll(maxsend,RecvRequestId,flag) ; - mpi_access.waitAll(maxsend,SendRequestId) ; - mpi_access.deleteRequests(maxsend,SendRequestId) ; - mpi_access.waitAll(maxsend,RecvRequestId) ; - mpi_access.deleteRequests(maxsend,RecvRequestId) ; - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - mpi_access.testAll(maxsend,SendRequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " TestAllSendflag " << flag << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " TestAllSendflag " << flag << " OK" << endl - << "=========================================================" << endl ; - } - mpi_access.testAll(maxsend,RecvRequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " TestAllRecvflag " << flag << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " TestAllRecvflag " << flag << " OK" << endl - << "=========================================================" << endl ; - } - - int sendrequests[maxsend] ; - int sendreqsize = mpi_access.sendRequestIds( alltarget[myrank] , maxsend , - sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - int source, tag, error, outcount ; - mpi_access.status(sendrequests[0], source, tag, error, outcount, true) ; - debugStream << "test" << myrank << " RequestId " << sendrequests[0] - << " source " << source << " tag " << tag << " error " << error - << " outcount " << outcount << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - int recvrequests[maxsend] ; - int recvreqsize = mpi_access.sendRequestIds( allsource[myrank] , maxsend , - recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cyclic_Send_Recv.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cyclic_Send_Recv.cxx deleted file mode 100644 index 67c687f54..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Cyclic_Send_Recv.cxx +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Cyclic_Send_Recv() { - - debugStream << "test_MPI_Access_Cyclic_Send_Recv" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 3 ) { - cerr << "test_MPI_Access_Send_Recv must be runned with 3 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_Send_Recv must be runned with 3 procs") ; - return; - } - - debugStream << "test_MPI_Access_Cyclic_Send_Recv" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 3 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int alltarget[3] = {1 , 2 , 0 } ; - int allsource[3] = {2 , 0 , 1 } ; - int RequestId[10] ; - int sts ; - int i = 0 ; - if ( myrank == 0 ) { - sts = mpi_access.send(&i,1,MPI_INT,alltarget[myrank], RequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; - } - for ( i = 0 ; i < 10 ; i++ ) { - int recvbuf ; - int outcount ; - if ( i & 1 ) { - outcount = 0 ; - sts = mpi_access.recv(&recvbuf,1,MPI_INT,allsource[myrank], RequestId[i], - &outcount) ; - } - else { - sts = mpi_access.recv(&recvbuf,1,MPI_INT,allsource[myrank], RequestId[i]) ; - outcount = 1 ; - } - //int source, tag, error, outcount ; - //mpi_access.Status( RequestId[i], source, tag, error, outcount, true) ; - debugStream << "test" << myrank << " Recv RequestId " << RequestId[i] - << " tag " << mpi_access.recvMPITag(allsource[myrank]) - << " outcount " << outcount << endl ; - if ( (outcount != 1) | (recvbuf != i) ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " outcount " - << outcount << " recvbuf " << recvbuf << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if ( myrank == 0 ) { - if ( i != 9 ) { - int ii = i + 1 ; - sts = mpi_access.send(&ii,1,MPI_INT,alltarget[myrank], RequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; - } - } - else { - sts = mpi_access.send(&i,1,MPI_INT,alltarget[myrank], RequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr - << " " << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - - int flag ; - mpi_access.testAll(10,RequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - mpi_access.waitAll(10,RequestId) ; - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - int sendrequests[10] ; - int sendreqsize = mpi_access.sendRequestIds( alltarget[myrank] , 10 , - sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - int recvrequests[10] ; - int recvreqsize = mpi_access.sendRequestIds( allsource[myrank] , 10 , - recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_IProbe.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_IProbe.cxx deleted file mode 100644 index 5fd4c2d0c..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_IProbe.cxx +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <time.h> -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#ifndef WIN32 -#include <unistd.h> -#endif - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_IProbe() { - - debugStream << "test_MPI_Access_IProbe" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_IProbe must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_IProbe" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int sendbuf[10] ; - int RequestId[10] ; - int sts ; - int i ; - for ( i = 0 ; i < 10 ; i++ ) { - if ( myrank == 0 ) { - sendbuf[i] = i ; - sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,target, RequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << endl ; - } - else { - int flag = false ; - while ( !flag ) { - int source, tag, outcount ; - MPI_Datatype datatype ; - sts = mpi_access.IProbe(target, source, tag, datatype, outcount, flag ) ; - if ( flag ) { - debugStream << "test" << myrank << " " << i << " IProbe target " << target - << " source " << source << " tag " << tag - << " outcount " << outcount << " flag " << flag << endl ; - } - else { - debugStream << "test" << myrank << " IProbe flag " << flag << endl ; - sleep( 1 ) ; - } - if ( flag ) { - int recvbuf ; - sts = mpi_access.recv(&recvbuf,outcount,datatype,source, RequestId[i], - &outcount) ; - if ( (outcount != 1) | (recvbuf != i) ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " KO" << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - debugStream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " OK" << endl - << "===========================================================" - << endl ; - } - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - int flag ; - mpi_access.testAll(10,RequestId,flag) ; - mpi_access.waitAll(10,RequestId) ; - mpi_access.deleteRequests(10,RequestId) ; - mpi_access.testAll(10,RequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISendRecv.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISendRecv.cxx deleted file mode 100644 index 126cc8eb7..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISendRecv.cxx +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_ISendRecv() { - - debugStream << "test_MPI_Access_ISendRecv" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - cerr << "test_MPI_Access_ISendRecv must be runned with 2 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_ISendRecv must be runned with 2 procs") ; - return; - } - - debugStream << "test_MPI_Access_ISendRecv" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int SendRequestId[10] ; - int RecvRequestId[10] ; - int sendbuf[10] ; - int recvbuf[10] ; - int sts ; - int i ; - for ( i = 0 ; i < 10 ; i++ ) { - sendbuf[i] = i ; - sts = mpi_access.ISendRecv(&sendbuf[i],1,MPI_INT,target, SendRequestId[i], - &recvbuf[i],1,MPI_INT,target, RecvRequestId[i]) ; - debugStream << "test" << myrank << " Send sendRequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) - << " recvRequestId " << RecvRequestId[i] - << " tag " << mpi_access.recvMPITag(target) << endl ; - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr - << " " << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - int j ; - for (j = 0 ; j <= i ; j++) { - int flag ; - if ( j < i ) { - debugStream << "test" << myrank << " " << j << " -> Test-Send("<< SendRequestId[j] - << ")" << endl ; - mpi_access.test( SendRequestId[j], flag ) ; - if ( flag ) { - int target, tag, error, outcount ; - mpi_access.status( SendRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Send RequestId " << SendRequestId[j] - << " target " << target << " tag " << tag << " error " << error - << endl ; - mpi_access.deleteRequest( SendRequestId[j] ) ; - } - } - debugStream << "test" << myrank << " " << j << " -> Test-Recv("<< SendRequestId[j] - << ")" << endl ; - mpi_access.test( RecvRequestId[j], flag ) ; - if ( flag ) { - int source, tag, error, outcount ; - mpi_access.status( RecvRequestId[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Recv RequestId" << j << " " - << RecvRequestId[j] << " source " << source << " tag " << tag - << " error " << error << " outcount " << outcount << endl ; - if ( (outcount != 1) | (recvbuf[j] != j) ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " outcount " - << outcount << " recvbuf[ " << j << " ] " << recvbuf[j] << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - } - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - - int flag ; - mpi_access.testAll(10,SendRequestId,flag) ; - mpi_access.waitAll(10,SendRequestId) ; - mpi_access.deleteRequests(10,SendRequestId) ; - mpi_access.testAll(10,SendRequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - mpi_access.testAll(10,RecvRequestId,flag) ; - mpi_access.waitAll(10,RecvRequestId) ; - mpi_access.deleteRequests(10,RecvRequestId) ; - mpi_access.testAll(10,RecvRequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - int sendrequests[10] ; - int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - int recvrequests[10] ; - int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv.cxx deleted file mode 100644 index baa3572c1..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv.cxx +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_ISend_IRecv() { - - debugStream << "test_MPI_Access_ISend_IRecv" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - cerr << "test_MPI_Access_ISend_IRecv must be runned with 2 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_ISend_IRecv must be runned with 2 procs") ; - return; - } - - debugStream << "test_MPI_Access_ISend_IRecv" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - -#define maxreq 100 - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int SendRequestId[maxreq] ; - int RecvRequestId[maxreq] ; - int sts ; - int sendbuf[maxreq] ; - int recvbuf[maxreq] ; - int i ; - for ( i = 0 ; i < maxreq ; i++ ) { - if ( myrank == 0 ) { - sendbuf[i] = i ; - sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,target, SendRequestId[i]) ; - debugStream << "test" << myrank << " ISend RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - else { - sts = mpi_access.IRecv(&recvbuf[i],1,MPI_INT,target, RecvRequestId[i]) ; - debugStream << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] - << " tag " << mpi_access.recvMPITag(target) << endl ; - } - int j ; - for (j = 0 ; j <= i ; j++) { - int flag ; - if ( myrank == 0 ) { - mpi_access.test( SendRequestId[j], flag ) ; - } - else { - mpi_access.test( RecvRequestId[j], flag ) ; - } - if ( flag ) { - int target,source, tag, error, outcount ; - if ( myrank == 0 ) { - mpi_access.status( SendRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] - << ") : target " << target << " tag " << tag << " error " << error - << " flag " << flag << endl ; - } - else { - mpi_access.status( RecvRequestId[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Recv RequestId " - << RecvRequestId[j] << ") : source " << source << " tag " << tag - << " error " << error << " outcount " << outcount - << " flag " << flag << endl ; - if ( (outcount != 1) | (recvbuf[j] != j) ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " outcount " - << outcount << " recvbuf " << recvbuf[j] << " KO" << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - //else { - // debugStream << "===========================================================" - // << endl << "test" << myrank << " outcount " << outcount - // << " RequestId " << RecvRequestId[j] << " recvbuf " - // << recvbuf[j] << " OK" << endl - // << "===========================================================" - // << endl ; - //} - } - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - if ( myrank == 0 ) { - mpi_access.waitAll(maxreq, SendRequestId) ; - mpi_access.deleteRequests(maxreq, SendRequestId) ; - } - else { - mpi_access.waitAll(maxreq, RecvRequestId) ; - mpi_access.deleteRequests(maxreq, RecvRequestId) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - if ( myrank == 0 ) { - int sendrequests[maxreq] ; - int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; - int i ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - for ( i = 0 ; i < sendreqsize ; i++ ) { - debugStream << "test" << myrank << " sendrequests[ " << i << " ] = " - << sendrequests[i] << endl ; - } - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - else { - int recvrequests[maxreq] ; - int recvreqsize = mpi_access.sendRequestIds( target , maxreq , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - - mpi_access.barrier() ; - - delete group ; - - // MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_BottleNeck.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_BottleNeck.cxx deleted file mode 100644 index 820340197..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_BottleNeck.cxx +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <time.h> -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_ISend_IRecv_BottleNeck() { - - debugStream << "test_MPI_Access_ISend_IRecv_BottleNeck" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_ISend_IRecv_BottleNeck must be runned with 2 procs" - << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_ISend_IRecv_BottleNeck" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - -#define maxreq 10000 - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int SendRequestId[maxreq] ; - int RecvRequestId[maxreq] ; - int sts ; - int sendbuf[maxreq] ; - int recvbuf[maxreq] ; - int i ; - for ( i = 0 ; i < maxreq ; i++ ) { - if ( myrank == 0 ) { - sendbuf[i] = i ; - sts = mpi_access.ISend(sendbuf,i,MPI_INT,target, SendRequestId[i]) ; - debugStream << "test" << myrank << " ISend RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - else { - //sleep( 1 ) ; - sts = mpi_access.IRecv(recvbuf,i,MPI_INT,target, RecvRequestId[i]) ; - debugStream << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] - << " tag " << mpi_access.recvMPITag(target) << endl ; - int recvreqsize = mpi_access.recvRequestIdsSize() ; - int * recvrequests = new int[ recvreqsize ] ; - recvreqsize = mpi_access.recvRequestIds( target , recvreqsize , recvrequests ) ; - int j ; - for (j = 0 ; j < recvreqsize ; j++) { - int flag ; - mpi_access.test( recvrequests[j], flag ) ; - if ( flag ) { - int source, tag, error, outcount ; - mpi_access.status( recvrequests[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Recv RequestId " - << recvrequests[j] << ") : source " << source << " tag " << tag - << " error " << error << " outcount " << outcount - << " flag " << flag << " : DeleteRequest" << endl ; - mpi_access.deleteRequest( recvrequests[j] ) ; - } - else { -// debugStream << "test" << myrank << " Test(Recv RequestId " -// << recvrequests[j] << ") flag " << flag << endl ; - } - } - delete [] recvrequests ; - } - if ( sts != MPI_SUCCESS ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - } - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - if ( myrank == 0 ) { - int size = mpi_access.sendRequestIdsSize() ; - debugStream << "test" << myrank << " before WaitAll sendreqsize " << size << endl ; - mpi_access.waitAll(maxreq, SendRequestId) ; - size = mpi_access.sendRequestIdsSize() ; - debugStream << "test" << myrank << " after WaitAll sendreqsize " << size << endl ; - int * ArrayOfSendRequests = new int[ size ] ; - int nSendRequest = mpi_access.sendRequestIds( size , ArrayOfSendRequests ) ; - int i ; - for ( i = 0 ; i < nSendRequest ; i++ ) { - mpi_access.deleteRequest( ArrayOfSendRequests[i] ) ; - } - delete [] ArrayOfSendRequests ; - } - else { - int size = mpi_access.recvRequestIdsSize() ; - debugStream << "test" << myrank << " before WaitAll recvreqsize " << size << endl ; - mpi_access.waitAll(maxreq, RecvRequestId) ; - size = mpi_access.recvRequestIdsSize() ; - debugStream << "test" << myrank << " after WaitAll recvreqsize " << size << endl ; - int * ArrayOfRecvRequests = new int[ size ] ; - int nRecvRequest = mpi_access.recvRequestIds( size , ArrayOfRecvRequests ) ; - int i ; - for ( i = 0 ; i < nRecvRequest ; i++ ) { - mpi_access.deleteRequest( ArrayOfRecvRequests[i] ) ; - } - delete [] ArrayOfRecvRequests ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - if ( myrank == 0 ) { - int sendrequests[maxreq] ; - int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; - int i ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - for ( i = 0 ; i < sendreqsize ; i++ ) { - debugStream << "test" << myrank << " sendrequests[ " << i << " ] = " - << sendrequests[i] << endl ; - } - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - else { - int recvrequests[maxreq] ; - int recvreqsize = mpi_access.recvRequestIds( target , maxreq , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_Length.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_Length.cxx deleted file mode 100644 index d1b556c3d..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_Length.cxx +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_ISend_IRecv_Length() { - - debugStream << "test_MPI_Access_ISend_IRecv_Length" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_ISend_IRecv_Length must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_ISend_IRecv_Length" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - -#define maxreq 10 - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int SendRequestId[maxreq] ; - int RecvRequestId[maxreq] ; - int sts ; - int sendbuf[1000*(maxreq-1)] ; - int recvbuf[maxreq][1000*(maxreq-1)] ; - int i ; - for ( i = 0 ; i < 1000*(maxreq-1) ; i++ ) { - sendbuf[i] = i ; - } - for ( i = 0 ; i < maxreq ; i++ ) { - if ( myrank == 0 ) { - sts = mpi_access.ISend( sendbuf, 1000*i, MPI_INT, target, SendRequestId[i] ) ; - debugStream << "test" << myrank << " ISend RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - else { - sts = mpi_access.IRecv( recvbuf[i], 1000*i, MPI_INT, target, - RecvRequestId[i] ) ; - debugStream << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] - << " tag " << mpi_access.recvMPITag(target) << endl ; - } - int j ; - for (j = 0 ; j <= i ; j++) { - int flag ; - if ( myrank == 0 ) { - mpi_access.test( SendRequestId[j], flag ) ; - } - else { - mpi_access.test( RecvRequestId[j], flag ) ; - } - if ( flag ) { - int target,source, tag, error, outcount ; - if ( myrank == 0 ) { - mpi_access.status( SendRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] - << ") : target " << target << " tag " << tag << " error " << error - << " flag " << flag << endl ; - } - else { - mpi_access.status( RecvRequestId[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Recv RequestId " - << RecvRequestId[j] << ") : source " << source << " tag " << tag - << " error " << error << " outcount " << outcount - << " flag " << flag << endl ; - if ( outcount != 0 ) { - if ( (outcount != 1000*j) | - (recvbuf[j][outcount-1] != (outcount-1)) ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " outcount " - << outcount << " recvbuf " << recvbuf[j][outcount-1] << " KO" - << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " RequestId " << RecvRequestId[j] << " recvbuf " - << recvbuf[j][outcount-1] << " OK" << endl - << "===========================================================" - << endl ; - } - } - else { - debugStream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " RequestId " << RecvRequestId[j] << " OK" << endl - << "===========================================================" - << endl ; - } - } - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - debugStream << "test" << myrank << " WaitAll" << endl ; - if ( myrank == 0 ) { - mpi_access.waitAll(maxreq, SendRequestId) ; - mpi_access.deleteRequests(maxreq, SendRequestId) ; - } - else { - mpi_access.waitAll(maxreq, RecvRequestId) ; - mpi_access.deleteRequests(maxreq, RecvRequestId) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - if ( myrank == 0 ) { - int sendrequests[maxreq] ; - int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - else { - int recvrequests[maxreq] ; - int recvreqsize = mpi_access.recvRequestIds( target , maxreq , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - - mpi_access.barrier() ; - - delete group ; - - // MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_Length_1.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_Length_1.cxx deleted file mode 100644 index 966bfc457..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_ISend_IRecv_Length_1.cxx +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_ISend_IRecv_Length_1() { - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_ISend_IRecv_Length_1 must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_ISend_IRecv_Length_1" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - -#define maxreq 10 - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int SendRequestId[maxreq] ; - int RecvRequestId[maxreq] ; - int sts ; - int sendbuf[1000*(maxreq-1)] ; - int recvbuf[maxreq][1000*(maxreq-1)] ; - int maxirecv = 1 ; - int i ; - RecvRequestId[0] = -1 ; - for ( i = 0 ; i < 1000*(maxreq-1) ; i++ ) { - sendbuf[i] = i ; - } - for ( i = 0 ; i < maxreq ; i++ ) { - sts = MPI_SUCCESS ; - if ( myrank == 0 ) { - sts = mpi_access.ISend( sendbuf, 1000*i, MPI_INT, target, SendRequestId[i] ) ; - debugStream << "test" << myrank << " ISend RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - int j ; - for (j = 1 ; j <= i ; j++) { - int source ; - MPI_Datatype datatype ; - int outcount ; - int flag ; - if ( myrank == 0 ) { - mpi_access.test( SendRequestId[j], flag ) ; - } - else { - int MPITag ; - sts = mpi_access.IProbe( target , source, MPITag, datatype, - outcount, flag) ; - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " IProbe lenerr " << lenerr << " " - << msgerr << endl ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " IProbe KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - debugStream << "test" << myrank << " IProbe i/j " << i << "/" << j - << " MPITag " << MPITag << " datatype " << datatype - << " outcount " << outcount << " flag " << flag << endl ; - } - if ( flag ) { - if ( myrank == 0 ) { - int target, tag, error, outcount ; - mpi_access.status( SendRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] - << ") : target " << target << " tag " << tag << " error " << error - << " flag " << flag << endl ; - } - else { - sts = mpi_access.IRecv( recvbuf[maxirecv], outcount, datatype, source, - RecvRequestId[maxirecv] ) ; - debugStream << "test" << myrank << " maxirecv " << maxirecv << " IRecv RequestId " - << RecvRequestId[maxirecv] << " source " << source - << " outcount " << outcount << " tag " - << mpi_access.recvMPITag(target) << endl ; - maxirecv = maxirecv + 1 ; - } - } - else if ( myrank == 1 && i == maxreq-1 && j >= maxirecv ) { - sts = mpi_access.IRecv( recvbuf[j], 1000*j, MPI_INT, target, - RecvRequestId[j] ) ; - debugStream << "test" << myrank << " maxirecv " << maxirecv << " IRecv RequestId " - << RecvRequestId[j] << " target " << target << " length " << 1000*j - << " tag " << mpi_access.recvMPITag(target) << endl ; - maxirecv = maxirecv + 1 ; - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " KO" << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - int flag ; - if ( myrank == 0 ) { - mpi_access.testAll( maxreq, SendRequestId, flag ) ; - debugStream << "test" << myrank << " TestAll SendRequest flag " << flag << endl ; - } - else { - int i ; - int source ; - int outcount ; - int flag ; - if ( maxirecv != maxreq ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " KO" << " maxirecv " << maxirecv - << " != maxreq " << maxreq << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - while ( maxirecv > 0 ) { - for ( i = 1 ; i < maxreq ; i++ ) { - debugStream << "test" << myrank << " IProbe : " << endl ; - sts = mpi_access.test( RecvRequestId[i] , flag ) ; - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " flag " << flag << " lenerr " - << lenerr << " " << msgerr << " maxirecv " << maxirecv << endl ; - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - debugStream << "test" << myrank << " Test flag " << flag << endl ; - if ( flag ) { - int tag, error ; - mpi_access.status( RecvRequestId[i] , source , tag , error , - outcount ) ; - if ( i != 0 ) { - if ( outcount != 1000*i | - (recvbuf[i][outcount-1] != (outcount-1)) ) { - ostringstream strstream ; - strstream << "========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " KO" << " i " << i - << " recvbuf " << recvbuf[i][outcount-1] << endl - << "========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - else if ( outcount != 0 ) { - ostringstream strstream ; - strstream << "========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " KO" << " i " << i << endl - << "========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - maxirecv = maxirecv - 1 ; - } - } - } - mpi_access.testAll( maxreq, RecvRequestId, flag ) ; - debugStream << "test" << myrank << " TestAll RecvRequest flag " << flag << endl ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - debugStream << "test" << myrank << " WaitAll :" << endl ; - if ( myrank == 0 ) { - mpi_access.waitAll( maxreq, SendRequestId ) ; - mpi_access.deleteRequests( maxreq, SendRequestId ) ; - } - else { - mpi_access.waitAll( maxreq, RecvRequestId ) ; - mpi_access.deleteRequests( maxreq, RecvRequestId ) ; - } - - if ( myrank == 0 ) { - int sendrequests[maxreq] ; - int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; - sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - else { - int recvrequests[maxreq] ; - int recvreqsize = mpi_access.sendRequestIds( target , maxreq , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - - mpi_access.barrier() ; - - delete group ; - - // MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Probe.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Probe.cxx deleted file mode 100644 index 632c5d2b1..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Probe.cxx +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Probe() { - - debugStream << "test_MPI_Access_Probe" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - cerr << "test_MPI_Access_Probe must be runned with 2 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_Probe must be runned with 2 procs") ; - return; - } - - debugStream << "test_MPI_Access_Probe" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int RequestId[10] ; - int sts ; - int i ; - for ( i = 0 ; i < 10 ; i++ ) { - if ( myrank == 0 ) { - sts = mpi_access.send(&i,1,MPI_INT,target, RequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << endl ; - } - else { - int source, tag, outcount ; - MPI_Datatype datatype ; - sts = mpi_access.probe(target, source, tag, datatype, outcount ) ; - debugStream << "test" << myrank << " Probe target " << target << " source " << source - << " tag " << tag << " outcount " << outcount << endl ; - int recvbuf ; - sts = mpi_access.recv(&recvbuf,outcount,datatype,source, RequestId[i], - &outcount) ; - if ( (outcount != 1) | (recvbuf != i) ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - int flag ; - mpi_access.testAll(10,RequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - mpi_access.waitAll(10,RequestId) ; - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_SendRecv.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_SendRecv.cxx deleted file mode 100644 index c7cbf7d05..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_SendRecv.cxx +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_SendRecv() { - - debugStream << "MPIAccessTest::test_MPI_Access_SendRecv" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - cerr << "MPIAccessTest::test_MPI_Access_SendRecv must be runned with 2 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_SendRecv must be runned with 2 procs") ; - return; - } - - debugStream << "MPIAccessTest::test_MPI_Access_SendRecv" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int sendRequestId[10] ; - int recvRequestId[10] ; - int sts ; - int i ; - for ( i = 0 ; i < 10 ; i++ ) { - int recvbuf ; - int outcount ; - if ( i & 1 ) { - outcount = -1 ; - sts = mpi_access.sendRecv(&i,1,MPI_INT,target, sendRequestId[i], - &recvbuf,1,MPI_INT,target, recvRequestId[i], - &outcount) ; - } - else { - sts = mpi_access.sendRecv(&i,1,MPI_INT,target, sendRequestId[i], - &recvbuf,1,MPI_INT,target, recvRequestId[i]) ; -// outcount = mpi_access.MPIOutCount( recvRequestId[i] ) ; - outcount = 1 ; - } - debugStream << "test" << myrank << " Send sendRequestId " << sendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) - << " recvRequestId " << recvRequestId[i] - << " tag " << mpi_access.recvMPITag(target) - << " outcount " << outcount << " MPIOutCount " - << mpi_access.MPIOutCount( recvRequestId[i] ) << endl ; - if ( (outcount != 1) | (recvbuf != i) ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - - int flag ; - mpi_access.testAll(10,sendRequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - mpi_access.waitAll(10,sendRequestId) ; - mpi_access.testAll(10,recvRequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - mpi_access.waitAll(10,recvRequestId) ; - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - int sendrequests[10] ; - int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - int recvrequests[10] ; - int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Send_Recv.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Send_Recv.cxx deleted file mode 100644 index cdaaabf30..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Send_Recv.cxx +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Send_Recv() { - - debugStream << "test_MPI_Access_Send_Recv" << endl ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - cerr << "test_MPI_Access_Send_Recv must be runned with 2 procs" << endl ; - //CPPUNIT_FAIL("test_MPI_Access_Send_Recv must be runned with 2 procs") ; - return; - } - - debugStream << "test_MPI_Access_Send_Recv" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int RequestId[10] ; - int sts ; - int i ; - for ( i = 0 ; i < 10 ; i++ ) { - if ( myrank == 0 ) { - sts = mpi_access.send(&i,1,MPI_INT,target, RequestId[i]) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - else { - int recvbuf ; - int outcount ; - sts = mpi_access.recv(&recvbuf,1,MPI_INT,target, RequestId[i],&outcount) ; - //int source, tag, error, outcount ; - //mpi_access.Status( RequestId[i], source, tag, error, outcount, true) ; - debugStream << "test" << myrank << " Recv RequestId " << RequestId[i] - << " tag " << mpi_access.recvMPITag(target) - << " outcount " << outcount << endl ; - if ( (outcount != 1) | (recvbuf != i) ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check(); - } - int flag ; - mpi_access.testAll(10,RequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - mpi_access.waitAll(10,RequestId) ; - if(MPI_ACCESS_VERBOSE) mpi_access.check(); - - if ( myrank == 0 ) { - int sendrequests[10] ; - int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - else { - int recvrequests[10] ; - int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Send_Recv_Length.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Send_Recv_Length.cxx deleted file mode 100644 index d3385cf15..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Send_Recv_Length.cxx +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Send_Recv_Length() { - - debugStream << "test_MPI_Access_Send_Recv_Length" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_Send_Recv_Length must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_Send_Recv_Length" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - - if ( myrank >= 2 ) { - mpi_access.barrier() ; - delete group ; - return ; - } - - int target = 1 - myrank ; - int RequestId[10] ; - int sendbuf[9000] ; - int recvbuf[9000] ; - bool recvbufok ; - int sts ; - int i , j ; - for ( i = 0 ; i < 9000 ; i++ ) { - sendbuf[i] = i ; - } - for ( i = 0 ; i < 10 ; i++ ) { - if ( myrank == 0 ) { - sts = mpi_access.send( sendbuf, 1000*i, MPI_INT, target, RequestId[i] ) ; - debugStream << "test" << myrank << " Send RequestId " << RequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - else { - sts = MPI_SUCCESS ; - RequestId[i] = -1 ; - int outcount = 0 ; - if ( i != 0 ) { - sts = mpi_access.recv( recvbuf,1000*i+1,MPI_INT,target, RequestId[i], - &outcount ) ; - } - //int source, tag, error, outcount ; - //mpi_access.Status( RequestId[i], source, tag, error, outcount, true) ; - debugStream << "test" << myrank << " Recv RequestId " << RequestId[i] - << " tag " << mpi_access.recvMPITag(target) - << " outcount " << outcount << endl ; - recvbufok = true ; - for ( j = 0 ; j < outcount ; j++ ) { - if ( recvbuf[j] != j ) { - debugStream << "test" << myrank << " recvbuf[ " << j << " ] = " << recvbuf[j] - << endl ; - recvbufok = false ; - break ; - } - } - if ( (outcount != 1000*i) | !recvbufok ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " recvbuf " << recvbuf << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - } - int flag ; - mpi_access.testAll(10,RequestId,flag) ; - if ( !flag ) { - ostringstream strstream ; - strstream << "test" << myrank << " flag " << flag << " KO" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - mpi_access.waitAll(10,RequestId) ; - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - if ( myrank == 0 ) { - int sendrequests[10] ; - int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - else { - int recvrequests[10] ; - int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - } - - mpi_access.barrier() ; - - delete group ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Time.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Time.cxx deleted file mode 100644 index 166af2e74..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Time.cxx +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void MPIAccessTest::test_MPI_Access_Time() { - - debugStream << "test_MPI_Access_Time" << endl ; - - // MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "test_MPI_Access_Time must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - - debugStream << "test_MPI_Access_Time" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess mpi_access( group ) ; - -#define maxreq 10 - - if ( myrank >= 2 ) { - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->Barrier" << endl ; - mpi_access.barrier() ; - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->Barrier" << endl ; - delete group ; - debugStream << "test_MPI_Access_Time" << myrank << " OK" << endl ; - return ; - } - - int target = 1 - myrank ; - int SendTimeRequestId[maxreq] ; - int RecvTimeRequestId[maxreq] ; - int SendRequestId[maxreq] ; - int RecvRequestId[maxreq] ; - int sts ; - int sendbuf[maxreq] ; - int recvbuf[maxreq] ; - int i = 0 ; - ParaMEDMEM::TimeMessage aSendTimeMsg[maxreq] ; - ParaMEDMEM::TimeMessage aRecvTimeMsg[maxreq] ; - double t ; - double dt = 1. ; - double maxt = 10. ; - for ( t = 0 ; t < maxt ; t = t+dt ) { - if ( myrank == 0 ) { - aSendTimeMsg[i].time = t ; - aSendTimeMsg[i].deltatime = dt ; - //aSendTimeMsg[i].maxtime = maxt ; - //sts = mpi_access.ISend( &aSendTimeMsg , mpi_access.timeExtent() , - sts = mpi_access.ISend( &aSendTimeMsg[i] , 1 , - mpi_access.timeType() , target , - SendTimeRequestId[i]) ; - debugStream << "test" << myrank << " ISend RequestId " << SendTimeRequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - sendbuf[i] = i ; - sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,target, SendRequestId[i]) ; - debugStream << "test" << myrank << " ISend RequestId " << SendRequestId[i] - << " tag " << mpi_access.sendMPITag(target) << endl ; - } - else { - //sts = mpi_access.IRecv( &aRecvTimeMsg , mpi_access.timeExtent() , - sts = mpi_access.IRecv( &aRecvTimeMsg[i] , 1 , - mpi_access.timeType() , target , - RecvTimeRequestId[i]) ; - debugStream << "test" << myrank << " IRecv RequestId " << RecvTimeRequestId[i] - << " tag " << mpi_access.recvMPITag(target) << endl ; - sts = mpi_access.IRecv(&recvbuf[i],1,MPI_INT,target, RecvRequestId[i]) ; - debugStream << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] - << " tag " << mpi_access.recvMPITag(target) << endl ; - } - int j ; - for (j = 0 ; j <= i ; j++) { - int flag ; - if ( myrank == 0 ) { - mpi_access.test( SendTimeRequestId[j], flag ) ; - } - else { - mpi_access.test( RecvTimeRequestId[j], flag ) ; - } - if ( flag ) { - int target,source, tag, error, outcount ; - if ( myrank == 0 ) { - mpi_access.status( SendTimeRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Send TimeRequestId " << SendTimeRequestId[j] - << ") : target " << target << " tag " << tag << " error " << error - << " flag " << flag << aSendTimeMsg[j] << endl ; - } - else { - mpi_access.status( RecvTimeRequestId[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Recv TimeRequestId " - << RecvTimeRequestId[j] << ") : source " << source << " tag " << tag - << " error " << error << " outcount " << outcount - << " flag " << flag << aRecvTimeMsg[j] << endl ; - if ( (outcount != 1) | (aRecvTimeMsg[j].time != j) ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount << " KO" - << " RecvTimeRequestId " << RecvTimeRequestId[j] << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " RecvTimeRequestId " << RecvTimeRequestId[j] << " OK" << endl - << "===========================================================" - << endl ; - } - } - } - if ( myrank == 0 ) { - mpi_access.test( SendRequestId[j], flag ) ; - } - else { - mpi_access.test( RecvRequestId[j], flag ) ; - } - if ( flag ) { - int target,source, tag, error, outcount ; - if ( myrank == 0 ) { - mpi_access.status( SendRequestId[j], target, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] - << ") : target " << target << " tag " << tag << " error " << error - << " flag " << flag << endl ; - } - else { - mpi_access.status( RecvRequestId[j], source, tag, error, outcount, - true ) ; - debugStream << "test" << myrank << " Test(Recv RequestId " - << RecvRequestId[j] << ") : source " << source << " tag " << tag - << " error " << error << " outcount " << outcount - << " flag " << flag << endl ; - if ( (outcount != 1) | (recvbuf[j] != j) ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " outcount " - << outcount << " recvbuf " << recvbuf[j] << " KO" << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "===========================================================" - << endl << "test" << myrank << " outcount " << outcount - << " RequestId " << RecvRequestId[j] << " OK" << endl - << "===========================================================" - << endl ; - } - } - } - } - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - mpi_access.errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - - if ( sts != MPI_SUCCESS ) { - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - i = i + 1 ; - } - - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - if ( myrank == 0 ) { - mpi_access.waitAll(maxreq, SendTimeRequestId) ; - mpi_access.deleteRequests(maxreq, SendTimeRequestId) ; - mpi_access.waitAll(maxreq, SendRequestId) ; - mpi_access.deleteRequests(maxreq, SendRequestId) ; - } - else { - mpi_access.waitAll(maxreq, RecvTimeRequestId) ; - mpi_access.deleteRequests(maxreq, RecvTimeRequestId) ; - mpi_access.waitAll(maxreq, RecvRequestId) ; - mpi_access.deleteRequests(maxreq, RecvRequestId) ; - } - if(MPI_ACCESS_VERBOSE) mpi_access.check() ; - - if ( myrank == 0 ) { - int sendrequests[2*maxreq] ; - int sendreqsize = mpi_access.sendRequestIds( target , 2*maxreq , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - else { - int recvrequests[2*maxreq] ; - int recvreqsize = mpi_access.sendRequestIds( target , 2*maxreq , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->Barrier" << endl ; - mpi_access.barrier() ; - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->Barrier" << endl ; - - delete group ; - - // MPI_Finalize(); - - debugStream << "test_MPI_Access_Time" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Time_0.cxx b/medtool/src/ParaMEDMEMTest/test_MPI_Access_Time_0.cxx deleted file mode 100644 index 9000e57ea..000000000 --- a/medtool/src/ParaMEDMEMTest/test_MPI_Access_Time_0.cxx +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <string> -#include <vector> -#include <map> -#include <iostream> -#include <mpi.h> - -#include "MPIAccessTest.hxx" -#include <cppunit/TestAssert.h> - -//#include "CommInterface.hxx" -//#include "ProcessorGroup.hxx" -//#include "MPIProcessorGroup.hxx" -#include "MPIAccess.hxx" - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace ParaMEDMEM; - -void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { - char msgerr[MPI_MAX_ERROR_STRING] ; - int lenerr ; - if ( sts != MPI_SUCCESS ) { - mpi_access->errorString(sts, msgerr, &lenerr) ; - debugStream << "test" << myrank << " lenerr " << lenerr << " " - << msgerr << endl ; - ostringstream strstream ; - strstream << "===========================================================" - << "test" << myrank << " KO" - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } -return ; -} - -void MPIAccessTest::test_MPI_Access_Time_0() { - - debugStream << "test_MPI_Access_Time_0" << endl ; - -// MPI_Init(&argc, &argv) ; - - int size ; - int myrank ; - MPI_Comm_size(MPI_COMM_WORLD,&size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; - - if ( size < 2 ) { - ostringstream strstream ; - strstream << "usage :" << endl - << "mpirun -np <nbprocs> test_MPI_Access_Time_0" <<endl - << " nbprocs =2" << endl - << "test must be runned with 2 procs" << endl ; - cerr << strstream.str() << endl ; - //CPPUNIT_FAIL( strstream.str() ) ; - return; - } - -#define maxreq 100 - - double t ; - double dt[2] = {2., 1.} ; - double maxt = maxreq/dt[myrank] ; - - debugStream << "test_MPI_Access_Time_0 rank" << myrank << endl ; - - ParaMEDMEM::CommInterface interface ; - - ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; - - ParaMEDMEM::MPIAccess * mpi_access = new ParaMEDMEM::MPIAccess( group ) ; - - if ( myrank >= 2 ) { - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ; - mpi_access->barrier() ; - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ; - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ; - mpi_access->barrier() ; - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ; - delete group ; - delete mpi_access ; - debugStream << "test_MPI_Access_Time" << myrank << " OK" << endl ; - return ; - } - - int target = 1 - myrank ; - int SendTimeRequestId[maxreq] ; - int RecvTimeRequestId[maxreq] ; - int SendRequestId[maxreq] ; - int RecvRequestId[maxreq] ; - int sts ; - int sendbuf[maxreq] ; - int recvbuf[maxreq] ; - ParaMEDMEM::TimeMessage aSendTimeMsg[maxreq] ; - int lasttime = -1 ; - ParaMEDMEM::TimeMessage RecvTimeMessages[maxreq+1] ; - ParaMEDMEM::TimeMessage *aRecvTimeMsg = &RecvTimeMessages[1] ; -// mpi_access->Trace() ; - int istep = 0 ; - for ( t = 0 ; t < maxt ; t = t+dt[myrank] ) { - debugStream << "test" << myrank << " ==========================TIME " << t - << " ==========================" << endl ; - if ( myrank == 0 ) { - aSendTimeMsg[istep].time = t ; - aSendTimeMsg[istep].deltatime = dt[myrank] ; - //aSendTimeMsg[istep].maxtime = maxt ; - if ( t+dt[myrank] >= maxt ) { - aSendTimeMsg[istep].deltatime = 0 ; - } - sts = mpi_access->ISend( &aSendTimeMsg[istep] , 1 , - mpi_access->timeType() , target , - SendTimeRequestId[istep]) ; - debugStream << "test" << myrank << " ISend TimeRequestId " << SendTimeRequestId[istep] - << " tag " << mpi_access->MPITag(SendTimeRequestId[istep]) << endl ; - chksts( sts , myrank , mpi_access ) ; - sendbuf[istep] = istep ; - sts = mpi_access->ISend(&sendbuf[istep],1,MPI_INT,target, SendRequestId[istep]) ; - debugStream << "test" << myrank << " ISend Data RequestId " << SendRequestId[istep] - << " tag " << mpi_access->MPITag(SendRequestId[istep]) << endl ; - chksts( sts , myrank , mpi_access ) ; -//CheckSent -//========= - int sendrequests[2*maxreq] ; - int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , - sendrequests ) ; - int j , flag ; - for ( j = 0 ; j < sendreqsize ; j++ ) { - sts = mpi_access->test( sendrequests[j] , flag ) ; - chksts( sts , myrank , mpi_access ) ; - if ( flag ) { - mpi_access->deleteRequest( sendrequests[j] ) ; - debugStream << "test" << myrank << " " << j << ". " << sendrequests[j] - << " sendrequest deleted" << endl ; - } - } - } - else { -//InitRecv -//======== - if ( t == 0 ) { - aRecvTimeMsg[lasttime].time = 0 ; - sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 , - mpi_access->timeType() , - target , RecvTimeRequestId[lasttime+1]) ; - debugStream << "test" << myrank << " t == 0 IRecv TimeRequestId " - << RecvTimeRequestId[lasttime+1] - << " MPITag " << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] ) - << " MPICompleted " - << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) << endl ; - chksts( sts , myrank , mpi_access ) ; - } - else { - debugStream << "test" << myrank << " t # 0 lasttime " << lasttime << endl ; -//InitialOutTime -//============== - bool outtime = false ; - if ( lasttime != -1 ) { - if ( t <= aRecvTimeMsg[lasttime-1].time ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " t " << t << " <= " - << "aRecvTimeMsg[ " << lasttime << "-1 ].time " - << aRecvTimeMsg[lasttime-1].time << " KO" << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "===========================================================" - << endl << "test" << myrank << " t " << t << " > " - << "aRecvTimeMsg[ " << lasttime << "-1 ].time " - << aRecvTimeMsg[lasttime-1].time << " OK" << endl - << "===========================================================" - << endl ; - } - //outtime = ((aRecvTimeMsg[lasttime].time + - // aRecvTimeMsg[lasttime].deltatime) >= - // aRecvTimeMsg[lasttime].maxtime) ; - outtime = aRecvTimeMsg[lasttime].deltatime == 0 ; - } -// CheckRecv - CheckTime -// On a lasttime tel que : -// aRecvTimeMsg[ lasttime-1 ].time < T(i-1) <= aRecvTimeMsg[ lasttime ].time -// On cherche lasttime tel que : -// aRecvTimeMsg[ lasttime-1 ].time < T(i) <= aRecvTimeMsg[ lasttime ].time - if ( t <= aRecvTimeMsg[lasttime].time ) { - outtime = false ; - } - debugStream << "test" << myrank << " while outtime( " << outtime << " && t " << t - << " > aRecvTimeMsg[ " << lasttime << " ] " - << aRecvTimeMsg[lasttime].time << " )" << endl ; - while ( !outtime && (t > aRecvTimeMsg[lasttime].time) ) { - lasttime += 1 ; -//TimeMessage -//=========== - sts = mpi_access->wait( RecvTimeRequestId[lasttime] ) ; - chksts( sts , myrank , mpi_access ) ; - debugStream << "test" << myrank << " Wait done RecvTimeRequestId " - << RecvTimeRequestId[lasttime] << " lasttime " << lasttime - << " tag " << mpi_access->MPITag(RecvTimeRequestId[lasttime]) - << aRecvTimeMsg[lasttime] << endl ; - if ( lasttime == 0 ) { - aRecvTimeMsg[lasttime-1] = aRecvTimeMsg[lasttime] ; - } - mpi_access->deleteRequest( RecvTimeRequestId[lasttime] ) ; - - double deltatime = aRecvTimeMsg[lasttime].deltatime ; - //double maxtime = aRecvTimeMsg[lasttime].maxtime ; - double nexttime = aRecvTimeMsg[lasttime].time + deltatime ; - debugStream << "test" << myrank << " t " << t << " lasttime " << lasttime - << " deltatime " << deltatime - << " nexttime " << nexttime << endl ; - //if ( nexttime < maxtime && t > nexttime ) { - if ( deltatime != 0 && t > nexttime ) { -//CheckRecv : -//========= - //while ( nexttime < maxtime && t > nexttime ) { - while ( deltatime != 0 && t > nexttime ) { - int source, MPITag, outcount ; - MPI_Datatype datatype ; - sts = mpi_access->probe( target , source, MPITag, datatype, - outcount ) ; - chksts( sts , myrank , mpi_access ) ; -// Cancel DataMessages jusqu'a un TimeMessage - int cancelflag ; - while ( !mpi_access->isTimeMessage( MPITag ) ) { - sts = mpi_access->cancel( source, MPITag, datatype, outcount , - //sts = mpi_access->cancel( source, datatype, outcount , - //RecvRequestId[lasttime] , - cancelflag ) ; - debugStream << "test" << myrank << " Recv TO CANCEL RequestId " - << RecvRequestId[lasttime] - << " tag " << mpi_access->recvMPITag( target ) - << " cancelflag " << cancelflag << endl ; - chksts( sts , myrank , mpi_access ) ; - sts = mpi_access->probe( target , source, MPITag, datatype, - outcount ) ; - chksts( sts , myrank , mpi_access ) ; - } -//On peut avancer en temps - nexttime += deltatime ; - //if ( nexttime < maxtime && t > nexttime ) { - if ( deltatime != 0 && t > nexttime ) { -// Cancel du TimeMessage - sts = mpi_access->cancel( source, MPITag, datatype, outcount , - //sts = mpi_access->cancel( source, datatype, outcount , - //RecvRequestId[lasttime] , - cancelflag ) ; - debugStream << "test" << myrank << " Time TO CANCEL RequestId " - << RecvRequestId[lasttime] - << " tag " << mpi_access->recvMPITag( target ) - << " cancelflag " << cancelflag << endl ; - chksts( sts , myrank , mpi_access ) ; - } - } - } - else { -//DoRecv -//====== - debugStream << "test" << myrank << " Recv target " << target - << " lasttime " << lasttime - << " lasttime-1 " << aRecvTimeMsg[lasttime-1] - << " lasttime " << aRecvTimeMsg[lasttime] - << endl ; - sts = mpi_access->recv(&recvbuf[lasttime],1,MPI_INT,target, - RecvRequestId[lasttime]) ; - debugStream << "test" << myrank << " Recv RequestId " - << RecvRequestId[lasttime] - << " tag " << mpi_access->recvMPITag( target ) - << endl ; - chksts( sts , myrank , mpi_access ) ; - } - //outtime = ((aRecvTimeMsg[lasttime].time + - // aRecvTimeMsg[lasttime].deltatime) >= - // aRecvTimeMsg[lasttime].maxtime) ; - outtime = aRecvTimeMsg[lasttime].deltatime == 0 ; - if ( !outtime ) { -// Une lecture asynchrone d'un message temps a l'avance - sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 , - mpi_access->timeType() , target , - RecvTimeRequestId[lasttime+1]) ; - debugStream << "test" << myrank << " IRecv TimeRequestId " - << RecvTimeRequestId[lasttime+1] << " MPITag " - << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] ) - << " MPICompleted " - << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) - << endl ; - chksts( sts , myrank , mpi_access ) ; - } - else if ( t <= aRecvTimeMsg[lasttime].time ) { - outtime = false ; - } - } - - //printf("DEBUG t %.15f Msg[lasttime-1] %.15f Msg[lasttime] %.15f \n",t, - // aRecvTimeMsg[lasttime-1].time,aRecvTimeMsg[lasttime].time) ; - if ( ((t <= aRecvTimeMsg[lasttime-1].time) || - (t > aRecvTimeMsg[lasttime].time)) && !outtime ) { - ostringstream strstream ; - strstream << "===========================================================" - << endl << "test" << myrank << " t " << t << " <= " - << "aRecvTimeMsg[ " << lasttime << "-1 ].time " - << aRecvTimeMsg[lasttime-1].time << " ou t " << t << " > " - << "aRecvTimeMsg[ " << lasttime << " ].time " - << aRecvTimeMsg[lasttime].time << endl - << " ou bien outtime " << outtime << " KO RequestTimeIds " - << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime] - << " RequestIds " - << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl - << "===========================================================" - << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "===========================================================" - << endl << "test" << myrank - << " aRecvTimeMsg[ " << lasttime << "-1 ].time " - << aRecvTimeMsg[lasttime-1].time << " < t " << t << " <= " - << "aRecvTimeMsg[ " << lasttime << " ].time " - << aRecvTimeMsg[lasttime].time << endl - << " ou bien outtime " << outtime << " OK RequestTimeIds " - << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime] - << " RequestIds " - << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl - << "===========================================================" - << endl ; - } - } - } - chksts( sts , myrank , mpi_access ) ; - istep = istep + 1 ; - } - - debugStream << "test" << myrank << " Barrier :" << endl ; - mpi_access->barrier() ; - - if (MPI_ACCESS_VERBOSE) mpi_access->check() ; - - if ( myrank == 0 ) { -//CheckFinalSent -//============== - debugStream << "test" << myrank << " CheckFinalSent :" << endl ; - int sendrequests[2*maxreq] ; - int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ; - int j ; - for ( j = 0 ; j < sendreqsize ; j++ ) { - sts = mpi_access->wait( sendrequests[j] ) ; - chksts( sts , myrank , mpi_access ) ; - mpi_access->deleteRequest( sendrequests[j] ) ; - debugStream << "test" << myrank << " " << j << ". " << sendrequests[j] << " deleted" - << endl ; - } - } - else { - debugStream << "test" << myrank << " CheckFinalRecv :" << endl ; - int recvrequests[2*maxreq] ; - int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ; - int cancelflag ; - int j ; - for ( j = 0 ; j < recvreqsize ; j++ ) { - sts = mpi_access->cancel( recvrequests[j] , cancelflag ) ; - chksts( sts , myrank , mpi_access ) ; - mpi_access->deleteRequest( recvrequests[j] ) ; - debugStream << "test" << myrank << " " << j << ". " << recvrequests[j] << " deleted" - << " cancelflag " << cancelflag << endl ; - } - int source, MPITag, outcount , flag ; - MPI_Datatype datatype ; - sts = mpi_access->IProbe( target , source, MPITag, datatype, - outcount , flag ) ; - chksts( sts , myrank , mpi_access ) ; - while ( flag ) { - sts = mpi_access->cancel( source, MPITag, datatype, outcount , - //sts = mpi_access->cancel( source, datatype, outcount , - //RecvRequestId[lasttime] , - cancelflag ) ; - debugStream << "test" << myrank << " TO CANCEL RequestId " - << RecvRequestId[lasttime] - << " tag " << mpi_access->recvMPITag( target ) - << " cancelflag " << cancelflag << endl ; - chksts( sts , myrank , mpi_access ) ; - sts = mpi_access->IProbe( target , source, MPITag, datatype, - outcount , flag ) ; - chksts( sts , myrank , mpi_access ) ; - } - } - if(MPI_ACCESS_VERBOSE) mpi_access->check() ; - - if ( myrank == 0 ) { - int sendrequests[2*maxreq] ; - int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ; - if ( sendreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - else { - int recvrequests[2*maxreq] ; - int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ; - if ( recvreqsize != 0 ) { - ostringstream strstream ; - strstream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl - << "=========================================================" << endl ; - debugStream << strstream.str() << endl ; - CPPUNIT_FAIL( strstream.str() ) ; - } - else { - debugStream << "=========================================================" << endl - << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl - << "=========================================================" << endl ; - } - } - - int i ; - for ( i = 0 ; i <= lasttime ; i++ ) { - debugStream << "test" << myrank << " " << i << ". RecvTimeMsg " - << aRecvTimeMsg[i].time << " recvbuf " << recvbuf[i] << endl ; - } - - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ; - mpi_access->barrier() ; - debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ; - - delete group ; - delete mpi_access ; - -// MPI_Finalize(); - - debugStream << "test" << myrank << " OK" << endl ; - - return ; -} - - - - diff --git a/medtool/src/ParaMEDMEMTest/test_perf.cxx b/medtool/src/ParaMEDMEMTest/test_perf.cxx deleted file mode 100644 index 2250280c0..000000000 --- a/medtool/src/ParaMEDMEMTest/test_perf.cxx +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include <time.h> -#include <sys/times.h> -#include <sys/time.h> -#include "ParaMEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "MPIProcessorGroup.hxx" -#include "Topology.hxx" -#include "DEC.hxx" -#include "MxN_Mapping.hxx" -#include "InterpKernelDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ComponentTopology.hxx" -#include "ICoCoMEDField.hxx" -#include "MEDLoader.hxx" - -#include <string> -#include <cstring> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -#ifndef CLK_TCK -#include <unistd.h> -#define CLK_TCK sysconf(_SC_CLK_TCK); -#endif - -using namespace std; -using namespace ParaMEDMEM; - -void testInterpKernelDEC_2D(const string& filename1, const string& meshname1, - const string& filename2, const string& meshname2, - int nproc_source, double epsilon, bool tri, bool all); -void get_time( float *telps, float *tuser, float *tsys, float *tcpu ); - -int main(int argc, char *argv[]) -{ - string filename1, filename2; - string meshname1, meshname2; - int nproc_source=1, rank; - double epsilon=1.e-6; - int count=0; - bool tri=false; - bool all=false; - - MPI_Init(&argc,&argv); - - for(int i=1;i<argc;i++){ - if( strcmp(argv[i],"-f1") == 0 ){ - filename1 = argv[++i]; - count++; - } - else if( strcmp(argv[i],"-f2") == 0 ){ - filename2 = argv[++i]; - count++; - } - else if( strcmp(argv[i],"-m1") == 0 ){ - meshname1 = argv[++i]; - count++; - } - else if( strcmp(argv[i],"-m2") == 0 ){ - meshname2 = argv[++i]; - count++; - } - else if( strcmp(argv[i],"-ns") == 0 ){ - nproc_source = atoi(argv[++i]); - } - else if( strcmp(argv[i],"-eps") == 0 ){ - epsilon = atof(argv[++i]); - } - else if( strcmp(argv[i],"-tri") == 0 ){ - tri = true; - } - else if( strcmp(argv[i],"-all") == 0 ){ - all = true; - } - } - - if( count != 4 ){ - cout << "usage test_perf -f1 filename1 -m1 meshname1 -f2 filename2 -m2 meshname2 (-ns nproc_source -eps epsilon -tri -all)" << endl; - exit(0); - } - - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - testInterpKernelDEC_2D(filename1,meshname1,filename2,meshname2,nproc_source,epsilon,tri,all); - - MPI_Finalize(); -} - -void testInterpKernelDEC_2D(const string& filename_xml1, const string& meshname1, - const string& filename_xml2, const string& meshname2, - int nproc_source, double epsilon, bool tri, bool all) -{ - float tcpu, tcpu_u, tcpu_s, telps; - int size; - int rank; - MPI_Comm_size(MPI_COMM_WORLD,&size); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - - set<int> self_procs; - set<int> procs_source; - set<int> procs_target; - - for (int i=0; i<nproc_source; i++) - procs_source.insert(i); - for (int i=nproc_source; i<size; i++) - procs_target.insert(i); - self_procs.insert(rank); - - ParaMEDMEM::CommInterface interface; - - ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); - ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); - ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); - - //loading the geometry for the source group - - ParaMEDMEM::InterpKernelDEC dec (*source_group,*target_group); - if(tri) - dec.setIntersectionType(INTERP_KERNEL::Triangulation); - else - dec.setIntersectionType(INTERP_KERNEL::Convex); - - ParaMEDMEM::MEDCouplingUMesh* mesh; - ParaMEDMEM::ParaMESH* paramesh; - ParaMEDMEM::ParaFIELD* parafield; - ICoCo::MEDField* icocofield ; - - // To remove tmp files from disk - ParaMEDMEMTest_TmpFilesRemover aRemover; - - MPI_Barrier(MPI_COMM_WORLD); - if (source_group->containsMyRank()){ - string master = filename_xml1; - - ostringstream strstream; - if( nproc_source == 1 ) - strstream <<master<<".med"; - else - strstream <<master<<rank+1<<".med"; - - ostringstream meshname ; - if( nproc_source == 1 ) - meshname<< meshname1; - else - meshname<< meshname1<<"_"<< rank+1; - - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - if( rank == 0 ) - cout << "IO : Telapse = " << telps << " TuserCPU = " << tcpu_u << " TsysCPU = " << tcpu_s << " TCPU = " << tcpu << endl; - mesh->incrRef(); - - paramesh=new ParaMESH (mesh,*source_group,"source mesh"); - - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS, NO_TIME, paramesh, comptopo); - - int nb_local=mesh->getNumberOfCells(); - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=1.0; - - icocofield=new ICoCo::MEDField(parafield->getField()); - - dec.attachLocalField(icocofield); - } - - //loading the geometry for the target group - if (target_group->containsMyRank()){ - string master= filename_xml2; - ostringstream strstream; - if( (size-nproc_source) == 1 ) - strstream << master<<".med"; - else - strstream << master<<(rank-nproc_source+1)<<".med"; - ostringstream meshname ; - if( (size-nproc_source) == 1 ) - meshname<< meshname2; - else - meshname<< meshname2<<"_"<<rank-nproc_source+1; - - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - mesh->incrRef(); - - paramesh=new ParaMESH (mesh,*target_group,"target mesh"); - ParaMEDMEM::ComponentTopology comptopo; - parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); - - int nb_local=mesh->getNumberOfCells(); - double *value=parafield->getField()->getArray()->getPointer(); - for(int ielem=0; ielem<nb_local;ielem++) - value[ielem]=0.0; - icocofield=new ICoCo::MEDField(parafield->getField()); - - dec.attachLocalField(icocofield); - } - - - //attaching a DEC to the source group - double field_before_int; - double field_after_int; - - if (source_group->containsMyRank()){ - field_before_int = parafield->getVolumeIntegral(0,true); - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - dec.synchronize(); - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - if( rank == 0 ) - cout << "SYNCHRONIZE : Telapse = " << telps << " TuserCPU = " << tcpu_u << " TsysCPU = " << tcpu_s << " TCPU = " << tcpu << endl; - cout<<"DEC usage"<<endl; - dec.setForcedRenormalization(false); - if(all) - dec.setAllToAllMethod(PointToPoint); - - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - dec.sendData(); - - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - if( rank == 0 ) - cout << "SEND DATA : Telapse = " << telps << " TuserCPU = " << tcpu_u << " TsysCPU = " << tcpu_s << " TCPU = " << tcpu << endl; - dec.recvData(); - - field_after_int = parafield->getVolumeIntegral(0,true); -// CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, epsilon); - - } - - //attaching a DEC to the target group - if (target_group->containsMyRank()){ - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - dec.synchronize(); - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - dec.setForcedRenormalization(false); - if(all) - dec.setAllToAllMethod(PointToPoint); - - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - dec.recvData(); - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - dec.sendData(); - } - - get_time( &telps, &tcpu_u, &tcpu_s, &tcpu ); - if( rank == 0 ) - cout << "RECV DATA : Telapse = " << telps << " TuserCPU = " << tcpu_u << " TsysCPU = " << tcpu_s << " TCPU = " << tcpu << endl; - - delete source_group; - delete target_group; - delete self_group; - delete paramesh; - delete parafield; - mesh->decrRef() ; - delete icocofield; - - MPI_Barrier(MPI_COMM_WORLD); - cout << "end of InterpKernelDEC_2D test"<<endl; -} - -void get_time( float *telps, float *tuser, float *tsys, float *tcpu ) -{ - - /* Variables declaration */ - static time_t zsec = 0; - static long zusec = 0; - time_t nsec; - long nusec; - static clock_t zclock = 0; - clock_t nclock; - static clock_t zuser = 0; - static clock_t zsys = 0; - clock_t nuser, nsys; - - struct timeval tp; - struct timezone tzp; - struct tms local; - - MPI_Barrier(MPI_COMM_WORLD); - - /* Elapsed time reading */ - - gettimeofday(&tp,&tzp); - nsec = tp.tv_sec; - nusec = tp.tv_usec; - *telps = (float)(nsec-zsec) + (float)(nusec-zusec)/(float)CLOCKS_PER_SEC; - - zsec = nsec; - zusec = nusec; - - /* User and system CPU time reading */ - - times(&local); - nuser = local.tms_utime; - nsys = local.tms_stime; - *tuser = (float)(nuser-zuser) / (float)CLK_TCK; - *tsys = (float)(nsys-zsys) / (float)CLK_TCK; - - zuser = nuser; - zsys = nsys; - - /* CPU time reading */ - - nclock = clock(); - *tcpu = (float)(nclock-zclock) / (float)CLOCKS_PER_SEC; - zclock = nclock; - -} - - diff --git a/medtool/src/ParaMEDMEM_Swig/CMakeLists.txt b/medtool/src/ParaMEDMEM_Swig/CMakeLists.txt deleted file mode 100644 index 855847681..000000000 --- a/medtool/src/ParaMEDMEM_Swig/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -FIND_PACKAGE(SWIG REQUIRED) -INCLUDE(${SWIG_USE_FILE}) - -SET_SOURCE_FILES_PROPERTIES(ParaMEDMEM.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(ParaMEDMEM.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_ParaMEDMEM_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -SET (ParaMEDMEM_SWIG_DPYS_FILES - ParaMEDMEM.typemap) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MPI_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader/Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ) - -SET (SWIG_MODULE_ParaMEDMEM_EXTRA_DEPS ${ParaMEDMEM_SWIG_DPYS_FILES} - ${paramedmem_HEADERS_HXX} - ${medloader_HEADERS_HXX} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -SWIG_ADD_MODULE(ParaMEDMEM python ParaMEDMEM.i) -SWIG_LINK_LIBRARIES(ParaMEDMEM ${PYTHON_LIBRARIES} paramedmem medloader) - -SET_SOURCE_FILES_PROPERTIES(ParaMEDMEM.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(ParaMEDMEM.i PROPERTIES SWIG_DEFINITIONS "-shadow") - -INSTALL(TARGETS _ParaMEDMEM DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) -INSTALL(FILES ParaMEDMEM.i DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ParaMEDMEM.py test_InterpKernelDEC.py test_NonCoincidentDEC.py test_StructuredCoincidentDEC.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) diff --git a/medtool/src/ParaMEDMEM_Swig/ParaMEDMEM.i b/medtool/src/ParaMEDMEM_Swig/ParaMEDMEM.i deleted file mode 100644 index 38f4c4751..000000000 --- a/medtool/src/ParaMEDMEM_Swig/ParaMEDMEM.i +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%module ParaMEDMEM - -%include "ParaMEDMEM.typemap" -%include "MEDLoaderCommon.i" - -%{ -#include "CommInterface.hxx" -#include "ProcessorGroup.hxx" -#include "Topology.hxx" -#include "MPIProcessorGroup.hxx" -#include "DEC.hxx" -#include "InterpKernelDEC.hxx" -#include "NonCoincidentDEC.hxx" -#include "StructuredCoincidentDEC.hxx" -#include "ParaMESH.hxx" -#include "ParaFIELD.hxx" -#include "ICoCoMEDField.hxx" -#include "ComponentTopology.hxx" - -#include <mpi.h> - -using namespace ParaMEDMEM; -using namespace ICoCo; - -enum mpi_constants { mpi_comm_world, mpi_comm_self, mpi_double, mpi_int }; -%} - -%include "CommInterface.hxx" -%include "ProcessorGroup.hxx" -%include "DECOptions.hxx" -%include "ParaMESH.hxx" -%include "ParaFIELD.hxx" -%include "MPIProcessorGroup.hxx" -%include "ComponentTopology.hxx" -%include "DEC.hxx" -%include "InterpKernelDEC.hxx" -%include "StructuredCoincidentDEC.hxx" - -%rename(ICoCoMEDField) ICoCo::MEDField; -%include "ICoCoMEDField.hxx" - -%nodefaultctor; - -/* This object can be used only if MED_ENABLE_FVM is defined*/ -#ifdef MED_ENABLE_FVM -class NonCoincidentDEC : public DEC -{ -public: - NonCoincidentDEC(ProcessorGroup& source, ProcessorGroup& target); -}; -#endif - -%extend ParaMEDMEM::ParaMESH -{ - PyObject *getGlobalNumberingCell2() const - { - const int *tmp=self->getGlobalNumberingCell(); - int size=self->getCellMesh()->getNumberOfCells(); - PyObject *ret=PyList_New(size); - for(int i=0;i<size;i++) - PyList_SetItem(ret,i,PyInt_FromLong(tmp[i])); - return ret; - } - - PyObject *getGlobalNumberingFace2() const - { - const int *tmp=self->getGlobalNumberingFace(); - int size=self->getFaceMesh()->getNumberOfCells(); - PyObject *ret=PyList_New(size); - for(int i=0;i<size;i++) - PyList_SetItem(ret,i,PyInt_FromLong(tmp[i])); - return ret; - } - - PyObject *getGlobalNumberingNode2() const - { - const int *tmp=self->getGlobalNumberingNode(); - int size=self->getCellMesh()->getNumberOfNodes(); - PyObject *ret=PyList_New(size); - for(int i=0;i<size;i++) - PyList_SetItem(ret,i,PyInt_FromLong(tmp[i])); - return ret; - } -} - -//============================================================================================= -// Interface for MPI-realization-specific constants like MPI_COMM_WORLD. -// -// Type and values of constants like MPI_COMM_WORLD depends on MPI realization -// and usually such constants actually are macros. To have such symbols in python -// and translate them into correct values we use the following technique. -// We define some constants (enum mpi_constants) and map them into real MPI values -// using typemaps, and we create needed python symbols equal to 'mpi_constants' -// via %pythoncode directive. - -// Constants corresponding to similar MPI definitions -enum mpi_constants { mpi_comm_world, mpi_comm_self, mpi_double, mpi_int }; - -// Map mpi_comm_world and mpi_comm_self -> MPI_COMM_WORLD and MPI_COMM_SELF -%typemap(in) MPI_Comm -{ - switch (PyInt_AsLong($input)) - { - case mpi_comm_world: $1 = MPI_COMM_WORLD; break; - case mpi_comm_self: $1 = MPI_COMM_SELF; break; - default: - PyErr_SetString(PyExc_TypeError,"unexpected value of MPI_Comm"); - return NULL; - } -} -// Map mpi_double and mpi_int -> MPI_DOUBLE and MPI_INT -%typemap(in) MPI_Datatype -{ - switch (PyInt_AsLong($input)) - { - case mpi_double: $1 = MPI_DOUBLE; break; - case mpi_int: $1 = MPI_INT; break; - default: - PyErr_SetString(PyExc_TypeError,"unexpected value of MPI_Datatype"); - return NULL; - } -} -// The following code gets inserted into the result python file: -// create needed python symbols -%pythoncode %{ -MPI_COMM_WORLD = mpi_comm_world -MPI_COMM_SELF = mpi_comm_self -MPI_DOUBLE = mpi_double -MPI_INT = mpi_int -%} -//============================================================================================= - -// ============== -// MPI_Comm_size -// ============== -%inline %{ PyObject* MPI_Comm_size(MPI_Comm comm) - { - int res = 0; - int err = MPI_Comm_size(comm, &res); - if ( err != MPI_SUCCESS ) - { - PyErr_SetString(PyExc_RuntimeError,"Erorr in MPI_Comm_size()"); - return NULL; - } - return PyInt_FromLong( res ); - } %} - -// ============== -// MPI_Comm_rank -// ============== -%inline %{ PyObject* MPI_Comm_rank(MPI_Comm comm) - { - int res = 0; - int err = MPI_Comm_rank(comm, &res); - if ( err != MPI_SUCCESS ) - { - PyErr_SetString(PyExc_RuntimeError,"Erorr in MPI_Comm_rank()"); - return NULL; - } - return PyInt_FromLong( res ); - } - %} - -int MPI_Init(int *argc, char ***argv ); -int MPI_Barrier(MPI_Comm comm); -int MPI_Finalize(); - -// ========== -// MPI_Bcast -// ========== - -%inline %{ PyObject* MPI_Bcast(PyObject* buffer, int nb, MPI_Datatype type, int root, MPI_Comm c) - { - // buffer must be a list - if (!PyList_Check(buffer)) - { - PyErr_SetString(PyExc_TypeError, "buffer is expected to be a list"); - return NULL; - } - // check list size - int aSize = PyList_Size(buffer); - if ( aSize != nb ) - { - std::ostringstream stream; stream << "buffer is expected to be of size " << nb; - PyErr_SetString(PyExc_ValueError, stream.str().c_str()); - return NULL; - } - // allocate and fill a buffer - void* aBuf = 0; - int* intBuf = 0; - double* dblBuf = 0; - if ( type == MPI_DOUBLE ) - { - aBuf = (void*) ( dblBuf = new double[ nb ] ); - for ( int i = 0; i < aSize; ++i ) - dblBuf[i] = PyFloat_AS_DOUBLE( PyList_GetItem( buffer, i )); - } - else if ( type == MPI_INT ) - { - aBuf = (void*) ( intBuf = new int[ nb ] ); - for ( int i = 0; i < aSize; ++i ) - intBuf[i] = int( PyInt_AS_LONG( PyList_GetItem( buffer, i ))); - } - else - { - PyErr_SetString(PyExc_TypeError, "Only MPI_DOUBLE and MPI_INT supported"); - return NULL; - } - // call MPI_Bcast - int err = MPI_Bcast(aBuf, nb, type, root, c); - // treat error - if ( err != MPI_SUCCESS ) - { - PyErr_SetString(PyExc_RuntimeError,"Erorr in MPI_Bcast()"); - delete [] intBuf; delete [] dblBuf; - return NULL; - } - // put recieved data into the list - int pyerr = 0; - if ( type == MPI_DOUBLE ) - { - for ( int i = 0; i < aSize && !pyerr; ++i ) - pyerr = PyList_SetItem(buffer, i, PyFloat_FromDouble( dblBuf[i] )); - delete [] dblBuf; - } - else - { - for ( int i = 0; i < aSize && !pyerr; ++i ) - pyerr = PyList_SetItem(buffer, i, PyInt_FromLong( intBuf[i] )); - delete [] intBuf; - } - if ( pyerr ) - { - PyErr_SetString(PyExc_RuntimeError, "Error of PyList_SetItem()"); - return NULL; - } - return PyInt_FromLong( err ); - - } - %} - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _ParaMEDMEM - return _ParaMEDMEM.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _ParaMEDMEM - return _ParaMEDMEM.DataArrayIntTuple____imod___(self, self, *args) -%} - -%include "MEDCouplingFinalize.i" diff --git a/medtool/src/ParaMEDMEM_Swig/ParaMEDMEM.typemap b/medtool/src/ParaMEDMEM_Swig/ParaMEDMEM.typemap deleted file mode 100644 index 80eb7259c..000000000 --- a/medtool/src/ParaMEDMEM_Swig/ParaMEDMEM.typemap +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include std_set.i -%include std_string.i - -%template() std::set<int>; - -// Creates "int *argc, char ***argv" parameters from input list -%typemap(in) (int *argc, char ***argv) { - int i; - if (!PyList_Check($input)) { - PyErr_SetString(PyExc_ValueError, "Expecting a list"); - return NULL; - } - int aSize = PyList_Size($input); - $1 = &aSize; - char** aStrs = (char **) malloc((aSize+1)*sizeof(char *)); - for (i = 0; i < aSize; i++) { - PyObject *s = PyList_GetItem($input,i); - if (!PyString_Check(s)) { - free(aStrs); - PyErr_SetString(PyExc_ValueError, "List items must be strings"); - return NULL; - } - aStrs[i] = PyString_AsString(s); - } - aStrs[i] = 0; - $2 = &aStrs; -} - -%typemap(freearg) (int *argc, char ***argv) { - if ($2) free(*($2)); -} - -/* MACRO: IN typemap for std::set<TYPE> C++ object */ -%define TYPEMAP_INPUT_SET_BY_VALUE( TYPE ) -{ - /* typemap in for set<TYPE> */ - /* Check if is a list */ - if (PyList_Check($input)) - { - int size = PyList_Size($input); - std::set< TYPE > tmpSet; - - for (int i=0; i < size; i++) - { - PyObject * tmp = PyList_GetItem($input,i); - TYPE elem = PyInt_AsLong(tmp); - tmpSet.insert(elem); - } - $1 = tmpSet; - } - else - { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } -} -%enddef - -%typemap(in) std::set<int> -{ - TYPEMAP_INPUT_SET_BY_VALUE( int ) -} -%typecheck(SWIG_TYPECHECK_POINTER) std::set<int> { - $1 = PyList_Check($input) ? 1 : 0; -} diff --git a/medtool/src/ParaMEDMEM_Swig/test_InterpKernelDEC.py b/medtool/src/ParaMEDMEM_Swig/test_InterpKernelDEC.py deleted file mode 100755 index 27e4551de..000000000 --- a/medtool/src/ParaMEDMEM_Swig/test_InterpKernelDEC.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from ParaMEDMEM import * -import sys, os -import unittest -import math - -class ParaMEDMEMBasicsTest(unittest.TestCase): - def testInterpKernelDEC_2D(self): - MPI_Init(sys.argv) - size = MPI_Comm_size(MPI_COMM_WORLD) - rank = MPI_Comm_rank(MPI_COMM_WORLD) - if size != 5: - raise RuntimeError, "Expect MPI_COMM_WORLD size == 5" - print rank - nproc_source = 3 - procs_source = range( nproc_source ) - procs_target = range( size - nproc_source + 1, size) - - interface = CommInterface() - target_group = MPIProcessorGroup(interface, procs_target) - source_group = MPIProcessorGroup(interface, procs_source) - dec = InterpKernelDEC(source_group, target_group) - - mesh =0 - support =0 - paramesh =0 - parafield =0 - icocofield =0 - data_dir = os.environ['MEDCOUPLING_ROOT_DIR'] - tmp_dir = os.environ['TMP'] - - if not tmp_dir or len(tmp_dir)==0: - tmp_dir = "/tmp" - pass - - filename_xml1 = os.path.join(data_dir, "share/resources/med/square1_split") - filename_xml2 = os.path.join(data_dir, "share/resources/med/square2_split") - - MPI_Barrier(MPI_COMM_WORLD) - if source_group.containsMyRank(): - filename = filename_xml1 + str(rank+1) + ".med" - meshname = "Mesh_2_" + str(rank+1) - mesh=MEDLoader.ReadUMeshFromFile(filename,meshname,0) - paramesh=ParaMESH(mesh,source_group,"source mesh") - comptopo = ComponentTopology() - parafield = ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo) - parafield.getField().setNature(ConservativeVolumic) - nb_local=mesh.getNumberOfCells() - value = [1.0]*nb_local - parafield.getField().setValues(value) - icocofield = ICoCoMEDField(mesh,parafield.getField()) - dec.setMethod("P0") - dec.attachLocalField(icocofield) - pass - else: - filename = filename_xml2 + str(rank - nproc_source + 1) + ".med" - meshname = "Mesh_3_" + str(rank - nproc_source + 1) - mesh=MEDLoader.ReadUMeshFromFile(filename,meshname,0) - paramesh=ParaMESH(mesh,target_group,"target mesh") - comptopo = ComponentTopology() - parafield = ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo) - parafield.getField().setNature(ConservativeVolumic) - nb_local=mesh.getNumberOfCells() - value = [0.0]*nb_local - parafield.getField().setValues(value) - icocofield = ICoCoMEDField(mesh,parafield.getField()) - dec.setMethod("P0") - dec.attachLocalField(icocofield) - pass - - if source_group.containsMyRank(): - field_before_int = parafield.getVolumeIntegral(0,True) - dec.synchronize() - dec.setForcedRenormalization(False) - dec.sendData() - dec.recvData() - field_after_int=parafield.getVolumeIntegral(0,True); - self.failUnless(math.fabs(field_after_int-field_before_int)<1e-8) - pass - else: - dec.synchronize() - dec.setForcedRenormalization(False) - dec.recvData() - dec.sendData() - pass - ## end - interface = 0 - target_group = 0 - source_group = 0 - dec = 0 - mesh =0 - support =0 - paramesh =0 - parafield =0 - icocofield =0 - MPI_Barrier(MPI_COMM_WORLD) - MPI_Finalize() - pass - pass - -unittest.main() diff --git a/medtool/src/ParaMEDMEM_Swig/test_NonCoincidentDEC.py b/medtool/src/ParaMEDMEM_Swig/test_NonCoincidentDEC.py deleted file mode 100755 index 42d2c1c5d..000000000 --- a/medtool/src/ParaMEDMEM_Swig/test_NonCoincidentDEC.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from ParaMEDMEM import * -import sys, os - -MPI_Init(sys.argv) - -size = MPI_Comm_size(MPI_COMM_WORLD) -rank = MPI_Comm_rank(MPI_COMM_WORLD) -if size != 5: - raise RuntimeError, "Expect MPI_COMM_WORLD size == 5" - -nproc_source = 3 -procs_source = range( nproc_source ) -procs_target = range( size - nproc_source + 1, size) - -interface = CommInterface() - -target_group = MPIProcessorGroup(interface, procs_target) -source_group = MPIProcessorGroup(interface, procs_source) - -source_mesh= 0 -target_mesh= 0 -parasupport= 0 -mesh = 0 -support = 0 -field = 0 -paramesh = 0 -parafield = 0 -icocofield = 0 - -dec = NonCoincidentDEC(source_group, target_group) - -data_dir = os.environ['MEDCOUPLING_ROOT_DIR'] -tmp_dir = os.environ['TMP'] -if tmp_dir == '': - tmp_dir = "/tmp" - pass - -filename_xml1 = data_dir + "/share/resources/med/square1_split" -filename_xml2 = data_dir + "/share/resources/med/square2_split" - -MPI_Barrier(MPI_COMM_WORLD) - -if source_group.containsMyRank(): - - filename = filename_xml1 + str(rank+1) + ".med" - meshname = "Mesh_2_" + str(rank+1) - - mesh = MESH(MED_DRIVER, filename, meshname) - support = SUPPORT(mesh, "all elements", MED_CELL) - paramesh = ParaMESH(mesh, source_group, "source mesh") - - parasupport = UnstructuredParaSUPPORT( support, source_group) - comptopo = ComponentTopology() - - parafield = ParaFIELD(parasupport, comptopo) - - nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS); - - value = [1.0]*nb_local - - parafield.getField().setValue(value) - icocofield = ICoCo_MEDField(paramesh,parafield) - dec.attachLocalField(icocofield,'P0') - pass - -if target_group.containsMyRank(): - - filename = filename_xml2 + str(rank - nproc_source + 1) + ".med" - meshname = "Mesh_3_" + str(rank - nproc_source + 1) - - mesh = MESH(MED_DRIVER, filename, meshname) - support = SUPPORT(mesh, "all elements", MED_CELL) - paramesh = ParaMESH(mesh, target_group, "target mesh") - - parasupport = UnstructuredParaSUPPORT( support, target_group) - comptopo = ComponentTopology() - parafield = ParaFIELD(parasupport, comptopo) - - nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS) - value = [0.0]*nb_local - - parafield.getField().setValue(value) - icocofield = ICoCo_MEDField(paramesh,parafield) - - dec.attachLocalField(icocofield, 'P0') - pass - -field_before_int = [0.0] -field_after_int = [0.0] - -if source_group.containsMyRank(): - - field_before_int = [parafield.getVolumeIntegral(1)] - MPI_Bcast(field_before_int, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - dec.synchronize() - print "DEC usage" - dec.setForcedRenormalization(False) - - dec.sendData() - pass - -if target_group.containsMyRank(): - - MPI_Bcast(field_before_int, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD) - dec.synchronize() - dec.setForcedRenormalization(False) - dec.recvData() - field_after_int = [parafield.getVolumeIntegral(1)] - pass - -MPI_Bcast(field_before_int, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD) -MPI_Bcast(field_after_int , 1, MPI_DOUBLE, size-1, MPI_COMM_WORLD) - -epsilon = 1e-6 -if abs(field_before_int[0] - field_after_int[0]) > epsilon: - print "Field before is not equal field after: %s != %s"%\ - (field_before_int[0],field_after_int[0]) - pass - - -MPI_Barrier(MPI_COMM_WORLD) -MPI_Finalize() -print "# End of testNonCoincidentDEC" diff --git a/medtool/src/ParaMEDMEM_Swig/test_StructuredCoincidentDEC.py b/medtool/src/ParaMEDMEM_Swig/test_StructuredCoincidentDEC.py deleted file mode 100755 index 1ab8fac21..000000000 --- a/medtool/src/ParaMEDMEM_Swig/test_StructuredCoincidentDEC.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from ParaMEDMEM import * -import sys, os -import unittest -import math - -class ParaMEDMEMBasicsTest2(unittest.TestCase): - def testStructuredCoincidentDEC(self): - MPI_Init(sys.argv) - # - size = MPI_Comm_size(MPI_COMM_WORLD) - rank = MPI_Comm_rank(MPI_COMM_WORLD) - # - if size < 4: - raise RuntimeError, "Expect MPI_COMM_WORLD size >= 4" - # - interface = CommInterface() - # - self_group = MPIProcessorGroup(interface, rank, rank) - target_group = MPIProcessorGroup(interface, 3, size-1) - source_group = MPIProcessorGroup(interface, 0, 2) - # - mesh = 0 - support = 0 - paramesh = 0 - parafield = 0 - comptopo = 0 - icocofield= 0 - # - data_dir = os.environ['MEDCOUPLING_ROOT_DIR'] - tmp_dir = os.environ['TMP'] - if tmp_dir == '': - tmp_dir = "/tmp" - pass - - filename_xml1 = data_dir + "/share/resources/med/square1_split" - filename_2 = data_dir + "/share/resources/med/square1.med" - filename_seq_wr = tmp_dir + "/" - filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med" - - dec = StructuredCoincidentDEC(source_group, target_group) - MPI_Barrier(MPI_COMM_WORLD) - if source_group.containsMyRank(): - filename = filename_xml1 + str(rank+1) + ".med" - meshname = "Mesh_2_" + str(rank+1) - mesh=MEDLoader.ReadUMeshFromFile(filename,meshname,0) - paramesh=ParaMESH(mesh,source_group,"source mesh") - comptopo=ComponentTopology(6) - parafield=ParaFIELD(ON_CELLS,NO_TIME,paramesh,comptopo) - parafield.getField().setNature(ConservativeVolumic) - nb_local=mesh.getNumberOfCells() - global_numbering=paramesh.getGlobalNumberingCell2() - value = [] - for ielem in range(nb_local): - for icomp in range(6): - value.append(global_numbering[ielem]*6.0+icomp); - pass - pass - parafield.getField().setValues(value) - icocofield = ICoCoMEDField(mesh,parafield.getField()) - dec.setMethod("P0") - dec.attachLocalField(parafield) - dec.synchronize() - dec.sendData() - pass - - if target_group.containsMyRank(): - meshname2 = "Mesh_2" - mesh=MEDLoader.ReadUMeshFromFile(filename_2, meshname2,0) - paramesh=ParaMESH(mesh, self_group, "target mesh") - comptopo=ComponentTopology(6,target_group) - parafield=ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo) - parafield.getField().setNature(ConservativeVolumic) - nb_local=mesh.getNumberOfCells() - value = [0.0]*(nb_local*comptopo.nbLocalComponents()) - parafield.getField().setValues(value) - icocofield = ICoCoMEDField(mesh,parafield.getField()) - dec.setMethod("P0") - dec.attachLocalField(parafield) - dec.synchronize() - dec.recvData() - recv_value = parafield.getField().getArray().getValues() - for i in range(nb_local): - first=comptopo.firstLocalComponent() - for icomp in range(comptopo.nbLocalComponents()): - self.failUnless(math.fabs(recv_value[i*comptopo.nbLocalComponents()+icomp]- - (float)(i*6+icomp+first))<1e-12) - pass - pass - pass - comptopo=0 - interface = 0 - mesh =0 - support =0 - paramesh =0 - parafield =0 - icocofield =0 - dec=0 - self_group =0 - target_group = 0 - source_group = 0 - MPI_Barrier(MPI_COMM_WORLD) - MPI_Finalize() - print "End of test StructuredCoincidentDEC" - pass - - -unittest.main() diff --git a/medtool/src/RENUMBER/CMakeLists.txt b/medtool/src/RENUMBER/CMakeLists.txt deleted file mode 100644 index 52ef7c7f3..000000000 --- a/medtool/src/RENUMBER/CMakeLists.txt +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${BOOST_DEFINITIONS} ${MEDFILE_DEFINITIONS}) - -IF(Boost_FOUND) - ADD_DEFINITIONS("-DENABLE_BOOST") -ENDIF(Boost_FOUND) - -# Include directories -INCLUDE_DIRECTORIES( - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -IF(MEDCOUPLING_USE_MPI) - ADD_DEFINITIONS(${MPI_DEFINITIONS}) - INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) -ENDIF(MEDCOUPLING_USE_MPI) - -SET(renumbercpp_HEADERS_HXX - RENUMBER_Renumbering.hxx - RenumberingFactory.hxx - RENUMBERDefines.hxx - ) - -SET(renumbercpp_SOURCES - RENUMBER_Renumbering.cxx - RenumberingFactory.cxx - ) - -SET(renumber_SOURCES - renumbering.cxx - ) - -SET(renumbercpp_LDFLAGS medloader) - -IF(PARMETIS_FOUND) - INCLUDE_DIRECTORIES(${PARMETIS_INCLUDE_DIRS}) -ENDIF(PARMETIS_FOUND) - -IF(METIS_FOUND) - INCLUDE_DIRECTORIES(${METIS_INCLUDE_DIRS}) - - SET(renumbercpp_SOURCES ${renumbercpp_SOURCES} RENUMBER_METISRenumbering.cxx) - SET(renumbercpp_HEADERS_HXX ${renumbercpp_HEADERS_HXX} RENUMBER_METISRenumbering.hxx) - SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${METIS_LIBRARIES}) - SET(renumber_DEFINITIONS "${renumber_DEFINITIONS} ${METIS_DEFINITIONS}") -ENDIF(METIS_FOUND) - -IF(Boost_FOUND) - INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) - - SET(renumbercpp_SOURCES ${renumbercpp_SOURCES} RENUMBER_BOOSTRenumbering.cxx) - SET(renumbercpp_HEADERS_HXX ${renumbercpp_HEADERS_HXX} RENUMBER_BOOSTRenumbering.hxx) - SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${BOOST_LIBRARIES}) -ENDIF(Boost_FOUND) - -IF(MEDCOUPLING_USE_MPI) - SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${MPI_LIBRARIES}) -ENDIF(MEDCOUPLING_USE_MPI) - -ADD_EXECUTABLE(renumber ${renumber_SOURCES}) -SET_TARGET_PROPERTIES(renumber PROPERTIES COMPILE_FLAGS "${renumber_DEFINITIONS}") -TARGET_LINK_LIBRARIES(renumber renumbercpp) -INSTALL(TARGETS renumber DESTINATION ${MEDCOUPLING_INSTALL_BINS}) - -ADD_LIBRARY(renumbercpp SHARED ${renumbercpp_SOURCES}) -SET_TARGET_PROPERTIES(renumbercpp PROPERTIES COMPILE_FLAGS "${renumber_DEFINITIONS}") -TARGET_LINK_LIBRARIES(renumbercpp ${renumbercpp_LDFLAGS}) -INSTALL(TARGETS renumbercpp DESTINATION ${MEDCOUPLING_INSTALL_LIBS}) - -INSTALL(FILES ${renumbercpp_HEADERS_HXX} DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) diff --git a/medtool/src/RENUMBER/RENUMBERDefines.hxx b/medtool/src/RENUMBER/RENUMBERDefines.hxx deleted file mode 100755 index 144284283..000000000 --- a/medtool/src/RENUMBER/RENUMBERDefines.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __RENUMBERDEFINES_HXX__ -#define __RENUMBERDEFINES_HXX__ - -//export symbols -#ifdef WIN32 -# if defined RENUMBERCPP_EXPORTS || defined renumbercpp_EXPORTS -# define RENUMBER_EXPORT __declspec(dllexport) -# else -# define RENUMBER_EXPORT __declspec(dllimport) -# endif -#else -# define RENUMBER_EXPORT -#endif - -#endif // __RENUMBERDEFINES_HXX__ diff --git a/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx b/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx deleted file mode 100644 index 8b0f45885..000000000 --- a/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "RENUMBER_BOOSTRenumbering.hxx" - -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include <boost/config.hpp> -#include <boost/graph/adjacency_list.hpp> -#include <boost/graph/cuthill_mckee_ordering.hpp> -#include <boost/graph/properties.hpp> -#include <boost/graph/bandwidth.hpp> - -void BOOSTRenumbering::renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) -{ - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> out0(ParaMEDMEM::DataArrayInt::New()),out1(ParaMEDMEM::DataArrayInt::New()); - out0->alloc(nbCell,1); out1->alloc(nbCell,1); - out0->fillWithZero(); out1->fillWithZero(); - // - typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, - boost::property<boost::vertex_color_t, boost::default_color_type, - boost::property<boost::vertex_degree_t,int> > > Graph; - typedef boost::graph_traits<Graph>::vertex_descriptor Vertex; - typedef boost::graph_traits<Graph>::vertices_size_type size_type; - Graph G(nbCell); - for (int i=0;i<nbCell;++i) - for (int j=index_graph[i];j<index_graph[i+1];++j) - add_edge(i,graph[j],G); - boost::property_map<Graph, boost::vertex_index_t>::type - index_map = boost::get(boost::vertex_index, G); - boost::cuthill_mckee_ordering(G, out0->getPointer(), boost::get(boost::vertex_color, G), - boost::make_degree_map(G)); - int *out0Ptr(out0->getPointer()),*out1Ptr(out1->getPointer()); - for(int c=0;c!=nbCell;++c) - out1Ptr[index_map[out0Ptr[nbCell-c-1]]]=c; - out0->reverse(); - iperm=out0.retn(); perm=out1.retn(); -} diff --git a/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx b/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx deleted file mode 100644 index 31e7d1eba..000000000 --- a/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __BOOSTRENUMBERING_HXX__ -#define __BOOSTRENUMBERING_HXX__ - -#include "RENUMBERDefines.hxx" -#include "RENUMBER_Renumbering.hxx" - -class RENUMBER_EXPORT BOOSTRenumbering:public Renumbering -{ -public: - void renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm); -}; - -#endif /*BOOSTRENUMBERING_HXX_*/ diff --git a/medtool/src/RENUMBER/RENUMBER_METISRenumbering.cxx b/medtool/src/RENUMBER/RENUMBER_METISRenumbering.cxx deleted file mode 100644 index 66820b686..000000000 --- a/medtool/src/RENUMBER/RENUMBER_METISRenumbering.cxx +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifdef MED_ENABLE_PARMETIS -// include parmetis.h even if it is not needed here -// to avoid inclusion of c++ definitions within extern "C" -// from metis.h from parmetis.h from mpi.h(openmpi) from mpicxx.h -#include <parmetis.h> -#endif -extern "C" -{ -#include "metis.h" -} - -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "RENUMBER_METISRenumbering.hxx" - -void METISRenumbering::renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) -{ - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> out0(ParaMEDMEM::DataArrayInt::New()),out1(ParaMEDMEM::DataArrayInt::New()); - out0->alloc(nbCell,1); out1->alloc(nbCell,1); - out0->fillWithZero(); out1->fillWithZero(); - int num_flag=1; - int options=0; - METIS_NodeND(&nbCell,(int*)index_graph,(int*)graph,&num_flag,&options,out0->getPointer(),out1->getPointer()); - iperm=out0.retn(); perm=out1.retn(); -} diff --git a/medtool/src/RENUMBER/RENUMBER_METISRenumbering.hxx b/medtool/src/RENUMBER/RENUMBER_METISRenumbering.hxx deleted file mode 100644 index ca20175eb..000000000 --- a/medtool/src/RENUMBER/RENUMBER_METISRenumbering.hxx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __METISRENUMBERING_HXX__ -#define __METISRENUMBERING_HXX__ - -#include "RENUMBERDefines.hxx" -#include "RENUMBER_Renumbering.hxx" - -class RENUMBER_EXPORT METISRenumbering:public Renumbering -{ -public: - virtual void renumber(const int *graph, const int *index_graph, int nb_cell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm); -}; - -#endif /*METISRENUMBERING_HXX_*/ diff --git a/medtool/src/RENUMBER/RENUMBER_Renumbering.cxx b/medtool/src/RENUMBER/RENUMBER_Renumbering.cxx deleted file mode 100644 index 84fa3bfae..000000000 --- a/medtool/src/RENUMBER/RENUMBER_Renumbering.cxx +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - diff --git a/medtool/src/RENUMBER/RENUMBER_Renumbering.hxx b/medtool/src/RENUMBER/RENUMBER_Renumbering.hxx deleted file mode 100644 index 6c21ee45c..000000000 --- a/medtool/src/RENUMBER/RENUMBER_Renumbering.hxx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef RENUMBERING_HXX_ -#define RENUMBERING_HXX_ -#include "RENUMBERDefines.hxx" -#include <vector> - -namespace ParaMEDMEM -{ - class DataArrayInt; -} - -class RENUMBER_EXPORT Renumbering -{ -public: - virtual void renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) = 0; - virtual ~Renumbering() { } -}; - -#endif /*RENUMBERING_HXX_*/ diff --git a/medtool/src/RENUMBER/RenumberingFactory.cxx b/medtool/src/RENUMBER/RenumberingFactory.cxx deleted file mode 100644 index 50cb5d146..000000000 --- a/medtool/src/RENUMBER/RenumberingFactory.cxx +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "RenumberingFactory.hxx" -#include "RENUMBER_Renumbering.hxx" -#ifdef MED_ENABLE_METIS -#include "RENUMBER_METISRenumbering.hxx" -#endif -#ifdef ENABLE_BOOST -#include "RENUMBER_BOOSTRenumbering.hxx" -#endif - -#include <iostream> - -using namespace std; - -namespace MED_RENUMBER -{ - Renumbering* RenumberingFactory(const string &s) - { -#ifdef MED_ENABLE_METIS -#ifdef ENABLE_BOOST - if (s=="METIS") - { - return new METISRenumbering; - } - else if(s=="BOOST") - { - return new BOOSTRenumbering; - } - else - { - std::cerr << "The method has to be METIS or BOOST" << std::endl; - return 0; - } -#endif -#ifndef ENABLE_BOOST - if (s=="METIS") - { - return new METISRenumbering; - } - else - { - std::cerr << "The method has to be METIS!" << std::endl; - return 0; - } -#endif -#endif -#ifndef MED_ENABLE_METIS -#ifdef ENABLE_BOOST - if (s=="BOOST") - { - return new BOOSTRenumbering; - } - else - { - std::cerr << "The method has to be BOOST!" << std::endl; - return 0; - } -#endif -#ifndef ENABLE_BOOST - std::cerr << "Error, no method compiled" << std::endl; - return 0; -#endif -#endif - } -} diff --git a/medtool/src/RENUMBER/RenumberingFactory.hxx b/medtool/src/RENUMBER/RenumberingFactory.hxx deleted file mode 100644 index 0ba3d5578..000000000 --- a/medtool/src/RENUMBER/RenumberingFactory.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __RENUMBERINGFACTORY_HXX__ -#define __RENUMBERINGFACTORY_HXX__ - -#include "RENUMBERDefines.hxx" -#include "RENUMBER_Renumbering.hxx" - -#include <string> - -namespace MED_RENUMBER -{ - RENUMBER_EXPORT Renumbering* RenumberingFactory(const std::string& s); -} - -#endif /*RENUMBERINGFACTORY_HXX_*/ diff --git a/medtool/src/RENUMBER/renumbering.cxx b/medtool/src/RENUMBER/renumbering.cxx deleted file mode 100644 index 1fd4e3b73..000000000 --- a/medtool/src/RENUMBER/renumbering.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDFileData.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "RenumberingFactory.hxx" - -#include <time.h> -#include <string> -#include <cstdlib> -#include <fstream> -#include <iostream> - -using namespace std; -using namespace ParaMEDMEM; -using namespace MED_RENUMBER; - -int main(int argc, char** argv) -{ - double t_begin,t_read_st,t_compute_graph,t_family,t_field; - t_begin=clock(); - if (argc <5) - { - cerr << "Usage : " << argv[0] - << " filename_in meshname method[BOOST/METIS] filename_out" << endl << endl; - return -1; - } - string filename_in = argv[1]; - string meshname = argv[2]; - string type_renum = argv[3]; - string filename_out = argv[4]; - - if(type_renum!="METIS" && type_renum!="BOOST") - { - cout << "The method has to be METIS or BOOST!" << endl; - return -1; - } - // Reading file structure - cout << "Reading : " << flush; - MEDCouplingAutoRefCountObjectPtr<MEDFileData> fd(MEDFileData::New(filename_in)); - MEDFileMesh *m=fd->getMeshes()->getMeshWithName(meshname); - MEDFileUMesh *mc=dynamic_cast<MEDFileUMesh *>(m); - if(!mc) - { - std::ostringstream oss; oss << "In file \"" << filename_in << "\" the mesh name \"" << meshname<< "\" exists but is not unstructured !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - t_read_st=clock(); - cout << (t_read_st-t_begin)/(double) CLOCKS_PER_SEC << "s" << endl << flush; - // Reading mesh - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> workMesh=mc->getMeshAtLevel(0); - std::vector<int> code=workMesh->getDistributionOfTypes(); - cout << "Building the graph : " << flush; - DataArrayInt *neighb=0,*neighbI=0; - workMesh->computeNeighborsOfCells(neighb,neighbI); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighbSafe(neighb),neighbISafe(neighbI),ipermSafe,permSafe; - const int *graph=neighbSafe->begin(); - const int *graph_index=neighbISafe->begin(); - // Compute permutation iperm->new2old perm->old2new - DataArrayInt *iperm(0),*perm(0); - Renumbering *renumb=RenumberingFactory(type_renum); - renumb->renumber(graph,graph_index,workMesh->getNumberOfCells(),iperm,perm); - ipermSafe=iperm; permSafe=perm; - delete renumb; - ipermSafe=0;//erase new2old, we are using only old 2 new - t_compute_graph=clock(); - cout << " : " << (t_compute_graph-t_read_st)/(double) CLOCKS_PER_SEC << "s" << endl; - cout.flush(); - // Connectivity - cout << "Reordering connectivity & families and writing : " << flush; - workMesh->renumberCells(perm->begin(),false); - mc->setMeshAtLevel(0,workMesh); - const DataArrayInt *famField=mc->getFamilyFieldAtLevel(0); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2=famField->renumber(perm->begin()); - mc->setFamilyFieldArr(0,famField2); - } - mc->write(filename_out,2); - t_family=clock(); - cout << " : " << (t_family-t_compute_graph)/(double) CLOCKS_PER_SEC << "s" << endl << flush; - // Fields - cout << "Reordering fields and writing : " << flush; - MEDFileFields *fs=fd->getFields(); - if(fs) - { - for(int i=0;i<fs->getNumberOfFields();i++) - { - MEDFileFieldMultiTS *fmts=dynamic_cast<MEDFileFieldMultiTS *>(fs->getFieldAtPos(i)); - if(!fmts) continue; - if(fmts->getMeshName()==meshname) - { - for(int j=0;j<fmts->getNumberOfTS();j++) - { - MEDFileField1TS *f1ts=dynamic_cast<MEDFileField1TS*>(fmts->getTimeStepAtPos(j)); - if(!f1ts) continue; - DataArrayDouble *arr=f1ts->getUndergroundDataArray(); - arr->renumberInPlace(perm->begin()); - } - } - } - fs->write(filename_out,0); - //fs->renumberEntitiesLyingOnMesh(meshname,code,code,o2n); bugged - } - t_field=clock(); - cout << " : " << (t_field-t_family)/(double) CLOCKS_PER_SEC << "s" << endl << flush; - return 0; -} diff --git a/medtool/src/RENUMBER/testRenumbering.py b/medtool/src/RENUMBER/testRenumbering.py deleted file mode 100755 index 63e6438a8..000000000 --- a/medtool/src/RENUMBER/testRenumbering.py +++ /dev/null @@ -1,198 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDLoader import * -import os -import sys -import unittest - -class RenumberingTest(unittest.TestCase): - def testBoost2D(self): - filename="Test2D.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - ff=MEDFileField1TS(self.dir_mesh+"/out_"+filename,"Test field") - field_ini=DataArrayDouble([(2,3),(12,13),(14,15),(4,5),(6,7),(8,9),(16,17),(0,1),(10,11)]) - ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - f=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - field=f.getArray().isEqual(field_ini,1e-15) - connectivite=[4,1,5,12,10,4,10,12,13,11,4,5,4,14,12,4,11,13,9,3,4,12,14,15,13,4,4,0,6,14,4,13,15,8,9,4,14,6,7,15,4,15,7,2,8] - connectivite_index=[0,5,10,15,20,25,30,35,40,45] - Boost2D=m.getNodalConnectivity().getValues()==connectivite and m.getNodalConnectivityIndex().getValues()==connectivite_index and field - self.assertTrue(Boost2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessMetis2D(self):#not activated yet - filename="Test2D.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell2dmetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[12,14,10,4,2,6,13,11,11,13,14,12,16,8,3,9,5,1,7,15,15,7,8,16,14,16,9,10,6,5,15,13,13,15,16,14] - connectivite_index=[1,5,9,13,17,21,25,29,33,37] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_QUAD4) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); - conn2dmetis=(list(conn)==connectivite) - conn_index2dmetis=(list(conn_index)==connectivite_index) - Metis2D=conn2dmetis and conn_index2dmetis and (nbcell2dmetis==9) - self.assertTrue(Metis2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def testBoost2DPolygon(self): - filename="Test2Dpoly.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - nbcell2dpolyboost=m.getNumberOfCells() - connectivite=[5,1,4,8,9,5,10,9,8,11,5,4,5,7,8,5,3,10,11,15,5,11,8,7,12,5,5,0,6,7,5,15,11,12,14,5,12,7,6,13,5,14,12,13,2] - connectivite_index=[0,5,10,15,20,25,30,35,40,45] - conn=m.getNodalConnectivity().getValues() - conn_index=m.getNodalConnectivityIndex().getValues() - conn2dpolyboost=(list(conn)==connectivite) - conn_index2dpolyboost=(list(conn_index)==connectivite_index) - PolyBoost2D=conn2dpolyboost and conn_index2dpolyboost and (nbcell2dpolyboost==9) - self.assertTrue(PolyBoost2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessMetis2DPolygon(self):#not activated yet - filename="Test2Dpoly.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell2dpolymetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[6,1,7,8,2,5,9,10,5,6,8,9,15,13,14,3,4,11,12,16,16,12,13,15,11,10,9,12,12,9,8,13,13,8,7,14] - connectivite_index=[1,5,9,13,17,21,25,29,33,37] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_POLYGON) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL) - conn2dpolymetis=(list(conn)==connectivite) - conn_index2dpolymetis=(list(conn_index)==connectivite_index) - PolyMetis2D=conn2dpolymetis and conn_index2dpolymetis and (nbcell2dpolymetis==9) - self.assertTrue(PolyMetis2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def testBoost3D(self): - filename="Test3D.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - nbcell3dboost=m.getNumberOfCells() - connectivite=[18,22,12,4,17,26,21,13,25,18,16,5,12,22,24,15,21,26,18,26,21,13,25,23,14,6,19,18,8,22,17,0,20,26,25,9,18,24,15,21,26,18,7,14,23,18,1,16,22,8,11,24,26,20,18,20,26,25,9,10,23,19,2,18,11,24,26,20,3,18,23,10] - connectivite_index=[0,9,18,27,36,45,54,63,72] - conn=m.getNodalConnectivity().getValues() - conn_index=m.getNodalConnectivityIndex().getValues() - conn3dboost=(list(conn)==connectivite) - conn_index3dboost=(list(conn_index)==connectivite_index) - Boost3D=conn3dboost and conn_index3dboost and (nbcell3dboost==8) - self.assertTrue(Boost3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessMetis3D(self):#not activated yet - filename="Test3D.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell3dmetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[12,25,27,21,4,19,24,11,27,22,14,26,24,15,7,20,17,6,13,23,25,16,22,27,9,23,18,1,21,27,26,10,23,13,5,18,27,22,14,26,25,16,22,27,19,8,15,24,2,17,23,9,12,25,27,21,21,27,26,10,11,24,20,3] - connectivite_index=[1,9,17,25,33,41,49,57,65] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_HEXA8) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); - conn3dmetis=(list(conn)==connectivite) - conn_index3dmetis=(list(conn_index)==connectivite_index) - Metis3D=conn3dmetis&conn_index3dmetis&(nbcell3dmetis==8) - self.assertTrue(Metis3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def testBoost3DPoly(self): - filename="Test3Dpoly.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - nbcell3dpolyboost=m.getNumberOfCells() - connectivite=[31,22,12,4,17,-1,26,25,13,21,-1,22,26,21,12,-1,12,21,13,4,-1,4,13,25,17,-1,17,25,26,22,31,16,5,12,22,-1,24,26,21,15,-1,16,24,15,5,-1,5,15,21,12,-1,12,21,26,22,-1,22,26,24,16,31,26,21,13,25,-1,23,19,6,14,-1,26,23,14,21,-1,21,14,6,13,-1,13,6,19,25,-1,25,19,23,26,31,8,22,17,0,-1,20,9,25,26,-1,8,20,26,22,-1,22,26,25,17,-1,17,25,9,0,-1,0,9,20,8,31,24,15,21,26,-1,18,23,14,7,-1,24,18,7,15,-1,15,7,14,21,-1,21,14,23,26,-1,26,23,18,24,31,1,16,22,8,-1,11,20,26,24,-1,1,11,24,16,-1,16,24,26,22,-1,22,26,20,8,-1,8,20,11,1,31,20,26,25,9,-1,10,2,19,23,-1,20,10,23,26,-1,26,23,19,25,-1,25,19,2,9,-1,9,2,10,20,31,11,24,26,20,-1,3,10,23,18,-1,11,3,18,24,-1,24,18,23,26,-1,26,23,10,20,-1,20,10,3,11] - connectivite_index=[0,30,60,90,120,150,180,210,240] - conn=m.getNodalConnectivity().getValues() - conn_index=m.getNodalConnectivityIndex().getValues() - conn3dpolyboost=(connectivite==list(conn)) - conn_index3dpolyboost=(connectivite_index==list(conn_index)) - PolyBoost3D=(conn3dpolyboost and conn_index3dpolyboost and (nbcell3dpolyboost==8)) - self.assertTrue(PolyBoost3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessBoost3DPoly(self):#not activated yet - filename="Test3Dpoly.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell3dpolymetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[12,25,27,21,-1,4,11,24,19,-1,12,4,19,25,-1,25,19,24,27,-1,27,24,11,21,-1,21,11,4,12, - 27,22,14,26,-1,24,20,7,15,-1,27,24,15,22,-1,22,15,7,14,-1,14,7,20,26,-1,26,20,24,27, - 17,6,13,23,-1,25,27,22,16,-1,17,25,16,6,-1,6,16,22,13,-1,13,22,27,23,-1,23,27,25,17, - 9,23,18,1,-1,21,10,26,27,-1,9,21,27,23,-1,23,27,26,18,-1,18,26,10,1,-1,1,10,21,9, - 23,13,5,18,-1,27,26,14,22,-1,23,27,22,13,-1,13,22,14,5,-1,5,14,26,18,-1,18,26,27,23, - 25,16,22,27,-1,19,24,15,8,-1,25,19,8,16,-1,16,8,15,22,-1,22,15,24,27,-1,27,24,19,25, - 2,17,23,9,-1,12,21,27,25,-1,2,12,25,17,-1,17,25,27,23,-1,23,27,21,9,-1,9,21,12,2, - 21,27,26,10,-1,11,3,20,24,-1,21,11,24,27,-1,27,24,20,26,-1,26,20,3,10,-1,10,3,11,21] - connectivite_index=[1, 30, 59, 88, 117, 146, 175, 204, 233] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_POLYHEDRA) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); - conn3dpolymetis=(list(conn)==connectivite) - conn_index3dpolymetis=(list(conn_index)==connectivite_index) - PolyMetis3D=(conn3dpolymetis and conn_index3dpolymetis and (nbcell3dpolymetis==8)) - self.assertTrue(PolyMetis3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def setUp(self): - med_root_dir=os.getenv("MEDCOUPLING_ROOT_DIR") - self.dir_renumber=os.path.join(med_root_dir, "bin/renumber") - self.dir_mesh=os.path.join(med_root_dir, "share","resources","med") - pass - pass - -unittest.main() diff --git a/medtool/src/RENUMBER_Swig/CMakeLists.txt b/medtool/src/RENUMBER_Swig/CMakeLists.txt deleted file mode 100644 index 5f7d64ac2..000000000 --- a/medtool/src/RENUMBER_Swig/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -SET_SOURCE_FILES_PROPERTIES(MEDRenumber.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDRenumber.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD") - -IF(Boost_FOUND) - SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS -DHAS_BOOST ${SWIG_MODULE_MEDRenumber_EXTRA_FLAGS}) -ENDIF(Boost_FOUND) - -IF(METIS_FOUND) - SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS -DHAS_METIS ${SWIG_MODULE_MEDRenumber_EXTRA_FLAGS}) -ENDIF(METIS_FOUND) - -SET (MEDRenumber_SWIG_DPYS_FILES - MEDRenumberCommon.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../RENUMBER - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SWIG_ADD_MODULE(MEDRenumber python MEDRenumber.i) -SWIG_LINK_LIBRARIES(MEDRenumber ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} renumbercpp) - -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDRenumber PROPERTIES DEBUG_OUTPUT_NAME _MEDRenumber_d) -ENDIF(WIN32) -INSTALL(TARGETS ${SWIG_MODULE_MEDRenumber_REAL_NAME} DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) - -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDRenumber.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) - -INSTALL(FILES MEDRenumber.i MEDRenumberCommon.i DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) -INSTALL(FILES MEDRenumberTest.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) - -ADD_TEST(MEDRenumberTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDRenumberTest.py) -SET(MEDRenumberTest_PYTHONPATH "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/../MEDCoupling_Swig") -SET_TESTS_PROPERTIES(MEDRenumberTest PROPERTIES ENVIRONMENT "${MEDRenumberTest_PYTHONPATH}") - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/RENUMBER_Swig) -INSTALL(FILES MEDRenumberTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/medtool/src/RENUMBER_Swig/CTestTestfileInstall.cmake b/medtool/src/RENUMBER_Swig/CTestTestfileInstall.cmake deleted file mode 100644 index aeaaf7124..000000000 --- a/medtool/src/RENUMBER_Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -ADD_TEST(MEDRenumberTest python MEDRenumberTest.py) -SET_TESTS_PROPERTIES(MEDRenumberTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/medtool/src/RENUMBER_Swig/MEDRenumber.i b/medtool/src/RENUMBER_Swig/MEDRenumber.i deleted file mode 100644 index 9ba28d274..000000000 --- a/medtool/src/RENUMBER_Swig/MEDRenumber.i +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include "MEDRenumberCommon.i" - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____imod___(self, self, *args) -%} - - -%pythoncode %{ -InterpKernelException.__reduce__=INTERPKERNELExceptionReduce -DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) -DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd -DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub -DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul -DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv -DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow - -DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) -DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd -DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub -DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul -DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv -DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod -DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow - -DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd -DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub -DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul -DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv - -DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd -DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub -DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul -DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv -DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod - -del INTERPKERNELExceptionReduce -del ParaMEDMEMDataArrayDoublenew -del ParaMEDMEMDataArrayDoubleIadd -del ParaMEDMEMDataArrayDoubleIsub -del ParaMEDMEMDataArrayDoubleImul -del ParaMEDMEMDataArrayDoubleIdiv -del ParaMEDMEMDataArrayIntnew -del ParaMEDMEMDataArrayIntIadd -del ParaMEDMEMDataArrayIntIsub -del ParaMEDMEMDataArrayIntImul -del ParaMEDMEMDataArrayIntIdiv -del ParaMEDMEMDataArrayIntImod -del ParaMEDMEMDataArrayDoubleTupleIadd -del ParaMEDMEMDataArrayDoubleTupleIsub -del ParaMEDMEMDataArrayDoubleTupleImul -del ParaMEDMEMDataArrayDoubleTupleIdiv -del ParaMEDMEMDataArrayIntTupleIadd -del ParaMEDMEMDataArrayIntTupleIsub -del ParaMEDMEMDataArrayIntTupleImul -del ParaMEDMEMDataArrayIntTupleIdiv -del ParaMEDMEMDataArrayIntTupleImod -%} diff --git a/medtool/src/RENUMBER_Swig/MEDRenumberCommon.i b/medtool/src/RENUMBER_Swig/MEDRenumberCommon.i deleted file mode 100644 index 85f5d7e7c..000000000 --- a/medtool/src/RENUMBER_Swig/MEDRenumberCommon.i +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// Author : Anthony Geay (CEA/DEN) - -%module MEDRenumber - -%include std_vector.i -%include std_string.i - -%{ -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingDataArrayTypemaps.i" - -#include "RenumberingFactory.hxx" -#include "RENUMBER_Renumbering.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - using namespace MED_RENUMBER; -%} - -%template(ivec) std::vector<int>; -%template(dvec) std::vector<double>; -%template(svec) std::vector<std::string>; - -#ifdef WITH_NUMPY -%init %{ import_array(); %} -#endif - -%feature("autodoc", "1"); -%feature("docstring"); - -%newobject MED_RENUMBER::RenumberingFactory; - -%nodefaultctor; - -%rename (InterpKernelException) INTERP_KERNEL::Exception; - -%include "MEDCouplingRefCountObject.i" -%include "MEDCouplingMemArray.i" - -class Renumbering -{ -public: - %extend - { - virtual PyObject *renumber(const ParaMEDMEM::DataArrayInt *graph, const ParaMEDMEM::DataArrayInt *index_graph) throw(INTERP_KERNEL::Exception) - { - if(!graph || !index_graph) - throw INTERP_KERNEL::Exception("wrap of Renumbering::renumber : One of the input arrays is NULL !"); - if(!graph->isAllocated() || !index_graph->isAllocated()) - throw INTERP_KERNEL::Exception("wrap of Renumbering::renumber : One of the input arrays is not allocated !"); - ParaMEDMEM::DataArrayInt *out0(0),*out1(0); - self->renumber(graph->begin(),index_graph->begin(),index_graph->getNumberOfTuples()-1,out0,out1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(out0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(out1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - } - virtual ~Renumbering(); -}; - -namespace MED_RENUMBER -{ - Renumbering *RenumberingFactory(const std::string& s) throw(INTERP_KERNEL::Exception); -} - -%inline -{ - std::vector<std::string> RenumberAvailableMethods()throw(INTERP_KERNEL::Exception) - { - std::vector<std::string> ret; -#ifdef HAS_BOOST - ret.push_back(std::string("BOOST")); -#endif -#ifdef HAS_METIS - ret.push_back(std::string("METIS")); -#endif - return ret; - } -} - -%pythoncode %{ -import os -__filename=os.environ.get('PYTHONSTARTUP') -if __filename and os.path.isfile(__filename): - execfile(__filename) - pass -%} diff --git a/medtool/src/RENUMBER_Swig/MEDRenumberTest.py b/medtool/src/RENUMBER_Swig/MEDRenumberTest.py deleted file mode 100644 index 15199faa0..000000000 --- a/medtool/src/RENUMBER_Swig/MEDRenumberTest.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -from MEDRenumber import * -import unittest - -class MEDRenumberTest(unittest.TestCase): - - @unittest.skipUnless("BOOST" in RenumberAvailableMethods(),"requires BOOST prerequisite !") - def test1(self): - from MEDCoupling import MEDCouplingCMesh - ren=RenumberingFactory("BOOST") - arr=DataArrayDouble(10) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - a,b=m.computeNeighborsOfCells() - n2o,o2n=ren.renumber(a,b) - self.assertTrue(o2n.isEqual(DataArrayInt([0,2,5,9,14,20,27,35,44,1,4,8,13,19,26,34,43,52,3,7,12,18,25,33,42,51,59,6,11,17,24,32,41,50,58,65,10,16,23,31,40,49,57,64,70,15,22,30,39,48,56,63,69,74,21,29,38,47,55,62,68,73,77,28,37,46,54,61,67,72,76,79,36,45,53,60,66,71,75,78,80]))) - pass - - def setUp(self): - pass - pass - -unittest.main()